]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
target-mips: redefine Integer Multiply and Divide instructions
[mirror_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),
238};
239
e9c71dd1
TS
240/* Multiplication variants of the vr54xx. */
241#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
242
243enum {
244 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
245 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
246 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
247 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
248 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
249 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
250 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
251 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
252 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
253 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
254 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
255 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
256 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
257 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
258};
259
7a387fff
TS
260/* REGIMM (rt field) opcodes */
261#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
262
263enum {
264 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
265 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
266 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
267 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
268 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
3c824109 269 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
7a387fff
TS
270 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
271 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
3c824109 272 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
7a387fff
TS
273 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
274 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
275 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
276 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
277 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
278 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
279 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
280 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
e37e863f
FB
281};
282
7a387fff
TS
283/* Special2 opcodes */
284#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
285
e37e863f 286enum {
7a387fff
TS
287 /* Multiply & xxx operations */
288 OPC_MADD = 0x00 | OPC_SPECIAL2,
289 OPC_MADDU = 0x01 | OPC_SPECIAL2,
290 OPC_MUL = 0x02 | OPC_SPECIAL2,
291 OPC_MSUB = 0x04 | OPC_SPECIAL2,
292 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
293 /* Loongson 2F */
294 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
295 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
296 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
297 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
298 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
299 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
300 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
301 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
302 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
303 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
304 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
305 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 306 /* Misc */
7a387fff
TS
307 OPC_CLZ = 0x20 | OPC_SPECIAL2,
308 OPC_CLO = 0x21 | OPC_SPECIAL2,
309 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
310 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 311 /* Special */
7a387fff
TS
312 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
313};
314
315/* Special3 opcodes */
316#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
317
318enum {
319 OPC_EXT = 0x00 | OPC_SPECIAL3,
320 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
321 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
322 OPC_DEXT = 0x03 | OPC_SPECIAL3,
323 OPC_INS = 0x04 | OPC_SPECIAL3,
324 OPC_DINSM = 0x05 | OPC_SPECIAL3,
325 OPC_DINSU = 0x06 | OPC_SPECIAL3,
326 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
327 OPC_FORK = 0x08 | OPC_SPECIAL3,
328 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
329 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
330 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
331 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
332
333 /* Loongson 2E */
334 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
335 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
336 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
337 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
338 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
339 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
340 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
341 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
342 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
343 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
344 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
345 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
346
347 /* MIPS DSP Load */
348 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
349 /* MIPS DSP Arithmetic */
350 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 351 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 352 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 353 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
354 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
355 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
356 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 357 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
358 /* MIPS DSP GPR-Based Shift Sub-class */
359 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 360 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
361 /* MIPS DSP Multiply Sub-class insns */
362 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
363 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
364 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 365 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
366 /* DSP Bit/Manipulation Sub-class */
367 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 368 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 369 /* MIPS DSP Append Sub-class */
26690560 370 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 371 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
372 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
373 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 374 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
375
376 /* R6 */
bf7910c6
LA
377 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
378 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
379 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
380 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
381 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
382 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
383};
384
7a387fff
TS
385/* BSHFL opcodes */
386#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
387
e37e863f 388enum {
7a387fff
TS
389 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
390 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
391 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
e37e863f
FB
392};
393
7a387fff
TS
394/* DBSHFL opcodes */
395#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
396
e37e863f 397enum {
7a387fff
TS
398 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
399 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
e37e863f
FB
400};
401
e45a93e2
JL
402/* MIPS DSP REGIMM opcodes */
403enum {
404 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 405 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
406};
407
9b1a1d68
JL
408#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
409/* MIPS DSP Load */
410enum {
411 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
412 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
413 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 414 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
415};
416
461c08df
JL
417#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
418enum {
419 /* MIPS DSP Arithmetic Sub-class */
420 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
421 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
422 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
423 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
424 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
425 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
426 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
427 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
428 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
429 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
430 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
431 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
432 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
433 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
434 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
435 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
436 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
437 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
438 /* MIPS DSP Multiply Sub-class insns */
439 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
440 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
441 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
442 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
443 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
444 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
445};
446
447#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
448#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
449enum {
450 /* MIPS DSP Arithmetic Sub-class */
451 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
452 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
453 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
454 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
455 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
456 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
457 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
458 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
459 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
460 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
461 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
462 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
463 /* MIPS DSP Multiply Sub-class insns */
464 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
465 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
466 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
467 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
468};
469
470#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
471enum {
472 /* MIPS DSP Arithmetic Sub-class */
473 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
474 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
475 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
476 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
477 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
478 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
479 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
480 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
481 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
482 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
483 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
484 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
485 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
486 /* DSP Bit/Manipulation Sub-class */
487 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
488 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
489 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
490 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
491 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
492};
493
494#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
495enum {
496 /* MIPS DSP Arithmetic Sub-class */
497 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
498 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
499 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
500 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
501 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
502 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
503 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
504 /* DSP Compare-Pick Sub-class */
505 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
506 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
507 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
508 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
509 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
510 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
511 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
512 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
513 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
514 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
515 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
516 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
517 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
518 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
519 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 520};
a22260ae 521
77c5fa8b
JL
522#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
523enum {
524 /* MIPS DSP GPR-Based Shift Sub-class */
525 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
526 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
527 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
528 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
529 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
530 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
531 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
532 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
533 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
534 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
535 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
536 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
537 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
538 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
539 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
540 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
541 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
542 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
543 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
544 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
545 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
546 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
547};
461c08df 548
a22260ae
JL
549#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
550enum {
551 /* MIPS DSP Multiply Sub-class insns */
552 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
553 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
554 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
555 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
556 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
557 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
558 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
559 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
560 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
561 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
562 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
563 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
564 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
565 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
566 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
567 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
568 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
569 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
570 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
571 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
572 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
573 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
574};
575
1cb6686c
JL
576#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
577enum {
578 /* DSP Bit/Manipulation Sub-class */
579 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
580};
581
26690560
JL
582#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583enum {
df6126a7 584 /* MIPS DSP Append Sub-class */
26690560
JL
585 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
586 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
587 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
588};
589
b53371ed
JL
590#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
591enum {
592 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
593 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
594 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
595 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
596 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
597 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
598 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
599 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
600 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
601 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
602 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
603 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
604 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
605 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
606 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
607 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
608 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
609 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
610};
611
461c08df
JL
612#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
613enum {
614 /* MIPS DSP Arithmetic Sub-class */
615 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
616 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
617 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
618 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
619 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
620 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
621 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
622 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
623 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
624 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
625 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
626 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
627 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
628 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
629 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
630 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
631 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
632 /* DSP Bit/Manipulation Sub-class */
633 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
634 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
635 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
636 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
637 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
638 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 639};
461c08df 640
461c08df
JL
641#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
642enum {
a22260ae
JL
643 /* MIPS DSP Multiply Sub-class insns */
644 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
645 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
646 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
647 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
648 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
649 /* MIPS DSP Arithmetic Sub-class */
650 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
651 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
652 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
653 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
654 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
655 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
656 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
657 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
658 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
659 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
660 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
661 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
662 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
663 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
664 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
665 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
666 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
667 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
668 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
669 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
670 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
671};
461c08df 672
461c08df
JL
673#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
674enum {
26690560
JL
675 /* DSP Compare-Pick Sub-class */
676 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
677 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
678 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
679 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
680 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
681 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
682 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
683 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
684 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
685 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
686 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
687 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
688 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
689 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
690 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
691 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
692 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
693 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
694 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
695 /* MIPS DSP Arithmetic Sub-class */
696 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
697 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
698 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
699 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
700 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
701 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
702 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
703 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
704};
461c08df 705
26690560
JL
706#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
707enum {
df6126a7 708 /* DSP Append Sub-class */
26690560
JL
709 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
710 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
711 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
712 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
713};
26690560 714
b53371ed
JL
715#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
716enum {
717 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
718 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
719 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
720 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
721 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
722 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
723 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
724 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
725 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
726 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
727 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
728 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
729 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
730 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
731 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
732 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
733 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
734 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
735 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
736 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
737 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
738 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
739};
740
1cb6686c
JL
741#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742enum {
743 /* DSP Bit/Manipulation Sub-class */
744 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
745};
1cb6686c 746
a22260ae
JL
747#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
748enum {
749 /* MIPS DSP Multiply Sub-class insns */
750 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
751 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
752 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
753 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
754 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
755 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
756 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
757 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
758 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
759 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
760 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
761 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
762 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
763 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
764 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
765 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
766 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
767 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
768 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
769 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
770 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
771 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
772 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
773 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
774 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
775 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
776};
a22260ae 777
77c5fa8b
JL
778#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
779enum {
780 /* MIPS DSP GPR-Based Shift Sub-class */
781 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
782 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
783 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
784 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
785 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
786 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
787 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
788 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
789 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
790 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
791 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
792 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
793 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
794 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
795 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
796 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
797 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
798 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
799 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
800 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
801 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
802 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
803 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
804 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
805 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
806 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
807};
77c5fa8b 808
7a387fff
TS
809/* Coprocessor 0 (rs field) */
810#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
811
6ea83fed 812enum {
7a387fff
TS
813 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
814 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
815 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
816 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 817 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
818 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
819 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 820 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
821 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
822 OPC_C0 = (0x10 << 21) | OPC_CP0,
823 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
824 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 825};
7a387fff
TS
826
827/* MFMC0 opcodes */
b48cfdff 828#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
829
830enum {
ead9360e
TS
831 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
832 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
833 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
834 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
835 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
836 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
837};
838
839/* Coprocessor 0 (with rs == C0) */
840#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
841
842enum {
843 OPC_TLBR = 0x01 | OPC_C0,
844 OPC_TLBWI = 0x02 | OPC_C0,
845 OPC_TLBWR = 0x06 | OPC_C0,
846 OPC_TLBP = 0x08 | OPC_C0,
847 OPC_RFE = 0x10 | OPC_C0,
848 OPC_ERET = 0x18 | OPC_C0,
849 OPC_DERET = 0x1F | OPC_C0,
850 OPC_WAIT = 0x20 | OPC_C0,
851};
852
853/* Coprocessor 1 (rs field) */
854#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
855
bf4120ad
NF
856/* Values for the fmt field in FP instructions */
857enum {
858 /* 0 - 15 are reserved */
e459440a
AJ
859 FMT_S = 16, /* single fp */
860 FMT_D = 17, /* double fp */
861 FMT_E = 18, /* extended fp */
862 FMT_Q = 19, /* quad fp */
863 FMT_W = 20, /* 32-bit fixed */
864 FMT_L = 21, /* 64-bit fixed */
865 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
866 /* 23 - 31 are reserved */
867};
868
7a387fff
TS
869enum {
870 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
871 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
872 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 873 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
874 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
875 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
876 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 877 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 878 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
879 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
880 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
e459440a
AJ
881 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
882 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
883 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
884 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
885 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
886 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
887 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
7a387fff
TS
888};
889
5a5012ec
TS
890#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
891#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
892
7a387fff
TS
893enum {
894 OPC_BC1F = (0x00 << 16) | OPC_BC1,
895 OPC_BC1T = (0x01 << 16) | OPC_BC1,
896 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
897 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
898};
899
5a5012ec
TS
900enum {
901 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
902 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
903};
904
905enum {
906 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
907 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
908};
7a387fff
TS
909
910#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
911
912enum {
913 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
914 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
915 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
916 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
917 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
918 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
919 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
920 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
921 OPC_BC2 = (0x08 << 21) | OPC_CP2,
922};
923
bd277fa1
RH
924#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
925
926enum {
927 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
928 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
929 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
930 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
931 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
932 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
933 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
934 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
935
936 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
937 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
938 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
939 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
940 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
941 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
942 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
943 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
944
945 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
946 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
947 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
948 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
949 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
950 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
951 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
952 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
953
954 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
955 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
956 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
957 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
958 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
959 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
960 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
961 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
962
963 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
964 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
965 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
966 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
967 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
968 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
969
970 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
971 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
972 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
973 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
974 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
975 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
976
977 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
978 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
979 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
980 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
981 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
982 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
983
984 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
985 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
986 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
987 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
988 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
989 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
990
991 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
992 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
993 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
994 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
995 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
996 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
997
998 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
999 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1000 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1001 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1002 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1003 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1004
1005 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1006 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1007 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1008 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1009 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1010 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1011
1012 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1013 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1014 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1015 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1016 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1017 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1018};
1019
1020
e0c84da7
TS
1021#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1022
1023enum {
1024 OPC_LWXC1 = 0x00 | OPC_CP3,
1025 OPC_LDXC1 = 0x01 | OPC_CP3,
1026 OPC_LUXC1 = 0x05 | OPC_CP3,
1027 OPC_SWXC1 = 0x08 | OPC_CP3,
1028 OPC_SDXC1 = 0x09 | OPC_CP3,
1029 OPC_SUXC1 = 0x0D | OPC_CP3,
1030 OPC_PREFX = 0x0F | OPC_CP3,
1031 OPC_ALNV_PS = 0x1E | OPC_CP3,
1032 OPC_MADD_S = 0x20 | OPC_CP3,
1033 OPC_MADD_D = 0x21 | OPC_CP3,
1034 OPC_MADD_PS = 0x26 | OPC_CP3,
1035 OPC_MSUB_S = 0x28 | OPC_CP3,
1036 OPC_MSUB_D = 0x29 | OPC_CP3,
1037 OPC_MSUB_PS = 0x2E | OPC_CP3,
1038 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1039 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1040 OPC_NMADD_PS= 0x36 | OPC_CP3,
1041 OPC_NMSUB_S = 0x38 | OPC_CP3,
1042 OPC_NMSUB_D = 0x39 | OPC_CP3,
1043 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1044};
1045
39454628 1046/* global register indices */
a7812ae4
PB
1047static TCGv_ptr cpu_env;
1048static TCGv cpu_gpr[32], cpu_PC;
4b2eb8d2 1049static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
41db4607
AJ
1050static TCGv cpu_dspctrl, btarget, bcond;
1051static TCGv_i32 hflags;
a7812ae4 1052static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1053static TCGv_i64 fpu_f64[32];
aa0bf00b 1054
1a7ff922 1055static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1056static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1057
022c62cb 1058#include "exec/gen-icount.h"
2e70f6ef 1059
895c2d04 1060#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1061 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1062 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1063 tcg_temp_free_i32(helper_tmp); \
1064 } while(0)
be24bb4f 1065
895c2d04 1066#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1067 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1068 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1069 tcg_temp_free_i32(helper_tmp); \
1070 } while(0)
be24bb4f 1071
895c2d04
BS
1072#define gen_helper_1e0i(name, ret, arg1) do { \
1073 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1074 gen_helper_##name(ret, cpu_env, helper_tmp); \
1075 tcg_temp_free_i32(helper_tmp); \
1076 } while(0)
1077
1078#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1079 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1080 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1081 tcg_temp_free_i32(helper_tmp); \
1082 } while(0)
1083
1084#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1085 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1086 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1087 tcg_temp_free_i32(helper_tmp); \
1088 } while(0)
1089
1090#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1091 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1092 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1093 tcg_temp_free_i32(helper_tmp); \
1094 } while(0)
be24bb4f 1095
895c2d04 1096#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1097 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1098 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1099 tcg_temp_free_i32(helper_tmp); \
1100 } while(0)
c239529e 1101
8e9ade68
TS
1102typedef struct DisasContext {
1103 struct TranslationBlock *tb;
1104 target_ulong pc, saved_pc;
1105 uint32_t opcode;
7b270ef2 1106 int singlestep_enabled;
d75c135e 1107 int insn_flags;
5ab5c041 1108 int32_t CP0_Config1;
8e9ade68
TS
1109 /* Routine used to access memory */
1110 int mem_idx;
1111 uint32_t hflags, saved_hflags;
1112 int bstate;
1113 target_ulong btarget;
d279279e 1114 bool ulri;
8e9ade68
TS
1115} DisasContext;
1116
1117enum {
1118 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1119 * exception condition */
8e9ade68
TS
1120 BS_STOP = 1, /* We want to stop translation for any reason */
1121 BS_BRANCH = 2, /* We reached a branch condition */
1122 BS_EXCP = 3, /* We reached an exception condition */
1123};
1124
d73ee8a2
RH
1125static const char * const regnames[] = {
1126 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1127 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1128 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1129 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1130};
6af0bf9c 1131
d73ee8a2
RH
1132static const char * const regnames_HI[] = {
1133 "HI0", "HI1", "HI2", "HI3",
1134};
4b2eb8d2 1135
d73ee8a2
RH
1136static const char * const regnames_LO[] = {
1137 "LO0", "LO1", "LO2", "LO3",
1138};
4b2eb8d2 1139
d73ee8a2
RH
1140static const char * const regnames_ACX[] = {
1141 "ACX0", "ACX1", "ACX2", "ACX3",
1142};
4b2eb8d2 1143
d73ee8a2
RH
1144static const char * const fregnames[] = {
1145 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1146 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1147 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1148 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1149};
958fb4a9 1150
fb7729e2
RH
1151#define MIPS_DEBUG(fmt, ...) \
1152 do { \
1153 if (MIPS_DEBUG_DISAS) { \
1154 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1155 TARGET_FMT_lx ": %08x " fmt "\n", \
1156 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1157 } \
1158 } while (0)
1159
1160#define LOG_DISAS(...) \
1161 do { \
1162 if (MIPS_DEBUG_DISAS) { \
1163 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1164 } \
1165 } while (0)
958fb4a9 1166
8e9ade68 1167#define MIPS_INVAL(op) \
8e9ade68 1168 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1169 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1170
8e9ade68
TS
1171/* General purpose registers moves. */
1172static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1173{
8e9ade68
TS
1174 if (reg == 0)
1175 tcg_gen_movi_tl(t, 0);
1176 else
4b2eb8d2 1177 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1178}
1179
8e9ade68 1180static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1181{
8e9ade68 1182 if (reg != 0)
4b2eb8d2 1183 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1184}
1185
b10fa3c9 1186/* Moves to/from ACX register. */
4b2eb8d2 1187static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1188{
4b2eb8d2 1189 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1190}
1191
4b2eb8d2 1192static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1193{
4b2eb8d2 1194 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1195}
1196
8e9ade68 1197/* Moves to/from shadow registers. */
be24bb4f 1198static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1199{
d9bea114 1200 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1201
1202 if (from == 0)
d9bea114 1203 tcg_gen_movi_tl(t0, 0);
8e9ade68 1204 else {
d9bea114 1205 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1206 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1207
7db13fae 1208 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1209 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1210 tcg_gen_andi_i32(t2, t2, 0xf);
1211 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1212 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1213 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1214
d9bea114 1215 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1216 tcg_temp_free_ptr(addr);
d9bea114 1217 tcg_temp_free_i32(t2);
8e9ade68 1218 }
d9bea114
AJ
1219 gen_store_gpr(t0, to);
1220 tcg_temp_free(t0);
aaa9128a
TS
1221}
1222
be24bb4f 1223static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1224{
be24bb4f 1225 if (to != 0) {
d9bea114
AJ
1226 TCGv t0 = tcg_temp_new();
1227 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1228 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1229
d9bea114 1230 gen_load_gpr(t0, from);
7db13fae 1231 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1232 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1233 tcg_gen_andi_i32(t2, t2, 0xf);
1234 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1235 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1236 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1237
d9bea114 1238 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1239 tcg_temp_free_ptr(addr);
d9bea114
AJ
1240 tcg_temp_free_i32(t2);
1241 tcg_temp_free(t0);
8e9ade68 1242 }
aaa9128a
TS
1243}
1244
aaa9128a 1245/* Floating point register moves. */
d73ee8a2 1246static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1247{
d73ee8a2 1248 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1249}
1250
d73ee8a2 1251static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1252{
d73ee8a2
RH
1253 TCGv_i64 t64 = tcg_temp_new_i64();
1254 tcg_gen_extu_i32_i64(t64, t);
1255 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1256 tcg_temp_free_i64(t64);
6d066274
AJ
1257}
1258
7f6613ce 1259static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1260{
7f6613ce
PJ
1261 if (ctx->hflags & MIPS_HFLAG_F64) {
1262 TCGv_i64 t64 = tcg_temp_new_i64();
1263 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1264 tcg_gen_trunc_i64_i32(t, t64);
1265 tcg_temp_free_i64(t64);
1266 } else {
1267 gen_load_fpr32(t, reg | 1);
1268 }
6d066274
AJ
1269}
1270
7f6613ce 1271static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1272{
7f6613ce
PJ
1273 if (ctx->hflags & MIPS_HFLAG_F64) {
1274 TCGv_i64 t64 = tcg_temp_new_i64();
1275 tcg_gen_extu_i32_i64(t64, t);
1276 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1277 tcg_temp_free_i64(t64);
1278 } else {
1279 gen_store_fpr32(t, reg | 1);
1280 }
aa0bf00b 1281}
6ea83fed 1282
d73ee8a2 1283static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1284{
f364515c 1285 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1286 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1287 } else {
d73ee8a2 1288 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1289 }
1290}
6ea83fed 1291
d73ee8a2 1292static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1293{
f364515c 1294 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1295 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1296 } else {
d73ee8a2
RH
1297 TCGv_i64 t0;
1298 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1299 t0 = tcg_temp_new_i64();
6d066274 1300 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1301 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1302 tcg_temp_free_i64(t0);
aa0bf00b
TS
1303 }
1304}
6ea83fed 1305
d94536f4 1306static inline int get_fp_bit (int cc)
a16336e4 1307{
d94536f4
AJ
1308 if (cc)
1309 return 24 + cc;
1310 else
1311 return 23;
a16336e4
TS
1312}
1313
30898801 1314/* Tests */
8e9ade68
TS
1315static inline void gen_save_pc(target_ulong pc)
1316{
1eb75d4a 1317 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1318}
30898801 1319
356265ae 1320static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1321{
d12d51d5 1322 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1323 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1324 gen_save_pc(ctx->pc);
6af0bf9c
FB
1325 ctx->saved_pc = ctx->pc;
1326 }
1327 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1328 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1329 ctx->saved_hflags = ctx->hflags;
364d4831 1330 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1331 case MIPS_HFLAG_BR:
5a5012ec
TS
1332 break;
1333 case MIPS_HFLAG_BC:
5a5012ec 1334 case MIPS_HFLAG_BL:
5a5012ec 1335 case MIPS_HFLAG_B:
d077b6f7 1336 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1337 break;
6af0bf9c
FB
1338 }
1339 }
1340}
1341
7db13fae 1342static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1343{
fd4a04eb 1344 ctx->saved_hflags = ctx->hflags;
364d4831 1345 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1346 case MIPS_HFLAG_BR:
fd4a04eb
TS
1347 break;
1348 case MIPS_HFLAG_BC:
1349 case MIPS_HFLAG_BL:
39454628 1350 case MIPS_HFLAG_B:
fd4a04eb 1351 ctx->btarget = env->btarget;
fd4a04eb 1352 break;
5a5012ec
TS
1353 }
1354}
1355
356265ae 1356static inline void
48d38ca5 1357generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1358{
a7812ae4
PB
1359 TCGv_i32 texcp = tcg_const_i32(excp);
1360 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1361 save_cpu_state(ctx, 1);
895c2d04 1362 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1363 tcg_temp_free_i32(terr);
1364 tcg_temp_free_i32(texcp);
aaa9128a
TS
1365}
1366
356265ae 1367static inline void
48d38ca5 1368generate_exception (DisasContext *ctx, int excp)
aaa9128a 1369{
6af0bf9c 1370 save_cpu_state(ctx, 1);
895c2d04 1371 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1372}
1373
48d38ca5 1374/* Addresses computation */
941694d0 1375static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1376{
941694d0 1377 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1378
1379#if defined(TARGET_MIPS64)
1380 /* For compatibility with 32-bit code, data reference in user mode
1381 with Status_UX = 0 should be casted to 32-bit and sign extended.
1382 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1383 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1384 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1385 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1386 }
1387#endif
4ad40f36
FB
1388}
1389
356265ae 1390static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1391{
fe253235 1392 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1393 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1394}
1395
356265ae 1396static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1397{
fe253235 1398 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1399 generate_exception_err(ctx, EXCP_CpU, 1);
1400}
1401
b8aa4598
TS
1402/* Verify that the processor is running with COP1X instructions enabled.
1403 This is associated with the nabla symbol in the MIPS32 and MIPS64
1404 opcode tables. */
1405
356265ae 1406static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1407{
1408 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1409 generate_exception(ctx, EXCP_RI);
1410}
1411
1412/* Verify that the processor is running with 64-bit floating-point
1413 operations enabled. */
1414
356265ae 1415static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1416{
b8aa4598 1417 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1418 generate_exception(ctx, EXCP_RI);
1419}
1420
1421/*
1422 * Verify if floating point register is valid; an operation is not defined
1423 * if bit 0 of any register specification is set and the FR bit in the
1424 * Status register equals zero, since the register numbers specify an
1425 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1426 * in the Status register equals one, both even and odd register numbers
1427 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1428 *
1429 * Multiple 64 bit wide registers can be checked by calling
1430 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1431 */
356265ae 1432static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1433{
fe253235 1434 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1435 generate_exception(ctx, EXCP_RI);
1436}
1437
853c3240
JL
1438/* Verify that the processor is running with DSP instructions enabled.
1439 This is enabled by CP0 Status register MX(24) bit.
1440 */
1441
1442static inline void check_dsp(DisasContext *ctx)
1443{
1444 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1445 if (ctx->insn_flags & ASE_DSP) {
1446 generate_exception(ctx, EXCP_DSPDIS);
1447 } else {
1448 generate_exception(ctx, EXCP_RI);
1449 }
853c3240
JL
1450 }
1451}
1452
1453static inline void check_dspr2(DisasContext *ctx)
1454{
1455 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1456 if (ctx->insn_flags & ASE_DSP) {
1457 generate_exception(ctx, EXCP_DSPDIS);
1458 } else {
1459 generate_exception(ctx, EXCP_RI);
1460 }
853c3240
JL
1461 }
1462}
1463
3a95e3a7 1464/* This code generates a "reserved instruction" exception if the
e189e748 1465 CPU does not support the instruction set corresponding to flags. */
d75c135e 1466static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1467{
d75c135e 1468 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1469 generate_exception(ctx, EXCP_RI);
d75c135e 1470 }
3a95e3a7
TS
1471}
1472
fecd2646
LA
1473/* This code generates a "reserved instruction" exception if the
1474 CPU has corresponding flag set which indicates that the instruction
1475 has been removed. */
1476static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1477{
1478 if (unlikely(ctx->insn_flags & flags)) {
1479 generate_exception(ctx, EXCP_RI);
1480 }
1481}
1482
e189e748
TS
1483/* This code generates a "reserved instruction" exception if 64-bit
1484 instructions are not enabled. */
356265ae 1485static inline void check_mips_64(DisasContext *ctx)
e189e748 1486{
fe253235 1487 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1488 generate_exception(ctx, EXCP_RI);
1489}
1490
8153667c
NF
1491/* Define small wrappers for gen_load_fpr* so that we have a uniform
1492 calling interface for 32 and 64-bit FPRs. No sense in changing
1493 all callers for gen_load_fpr32 when we need the CTX parameter for
1494 this one use. */
1495#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1496#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1497#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1498static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1499 int ft, int fs, int cc) \
1500{ \
1501 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1502 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1503 switch (ifmt) { \
1504 case FMT_PS: \
1505 check_cp1_64bitmode(ctx); \
1506 break; \
1507 case FMT_D: \
1508 if (abs) { \
1509 check_cop1x(ctx); \
1510 } \
1511 check_cp1_registers(ctx, fs | ft); \
1512 break; \
1513 case FMT_S: \
1514 if (abs) { \
1515 check_cop1x(ctx); \
1516 } \
1517 break; \
1518 } \
1519 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1520 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1521 switch (n) { \
895c2d04
BS
1522 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1523 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1524 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1525 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1526 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1527 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1528 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1529 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1530 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1531 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1532 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1533 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1534 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1535 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1536 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1537 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1538 default: abort(); \
1539 } \
1540 tcg_temp_free_i##bits (fp0); \
1541 tcg_temp_free_i##bits (fp1); \
1542}
1543
1544FOP_CONDS(, 0, d, FMT_D, 64)
1545FOP_CONDS(abs, 1, d, FMT_D, 64)
1546FOP_CONDS(, 0, s, FMT_S, 32)
1547FOP_CONDS(abs, 1, s, FMT_S, 32)
1548FOP_CONDS(, 0, ps, FMT_PS, 64)
1549FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1550#undef FOP_CONDS
1551#undef gen_ldcmp_fpr32
1552#undef gen_ldcmp_fpr64
1553
958fb4a9 1554/* load/store instructions. */
e7139c44 1555#ifdef CONFIG_USER_ONLY
d9bea114 1556#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1557static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1558{ \
1559 TCGv t0 = tcg_temp_new(); \
1560 tcg_gen_mov_tl(t0, arg1); \
1561 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1562 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1563 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1564 tcg_temp_free(t0); \
aaa9128a 1565}
e7139c44
AJ
1566#else
1567#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1568static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1569{ \
895c2d04 1570 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1571}
1572#endif
aaa9128a
TS
1573OP_LD_ATOMIC(ll,ld32s);
1574#if defined(TARGET_MIPS64)
1575OP_LD_ATOMIC(lld,ld64);
1576#endif
1577#undef OP_LD_ATOMIC
1578
590bc601
PB
1579#ifdef CONFIG_USER_ONLY
1580#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1581static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1582{ \
1583 TCGv t0 = tcg_temp_new(); \
1584 int l1 = gen_new_label(); \
1585 int l2 = gen_new_label(); \
1586 \
1587 tcg_gen_andi_tl(t0, arg2, almask); \
1588 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1589 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1590 generate_exception(ctx, EXCP_AdES); \
1591 gen_set_label(l1); \
7db13fae 1592 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1593 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1594 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1595 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1596 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1597 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1598 gen_set_label(l2); \
1599 tcg_gen_movi_tl(t0, 0); \
1600 gen_store_gpr(t0, rt); \
1601 tcg_temp_free(t0); \
1602}
1603#else
1604#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1605static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1606{ \
1607 TCGv t0 = tcg_temp_new(); \
895c2d04 1608 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1609 gen_store_gpr(t0, rt); \
590bc601
PB
1610 tcg_temp_free(t0); \
1611}
1612#endif
590bc601 1613OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1614#if defined(TARGET_MIPS64)
590bc601 1615OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1616#endif
1617#undef OP_ST_ATOMIC
1618
662d7485
NF
1619static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1620 int base, int16_t offset)
1621{
1622 if (base == 0) {
1623 tcg_gen_movi_tl(addr, offset);
1624 } else if (offset == 0) {
1625 gen_load_gpr(addr, base);
1626 } else {
1627 tcg_gen_movi_tl(addr, offset);
1628 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1629 }
1630}
1631
364d4831
NF
1632static target_ulong pc_relative_pc (DisasContext *ctx)
1633{
1634 target_ulong pc = ctx->pc;
1635
1636 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1637 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1638
1639 pc -= branch_bytes;
1640 }
1641
1642 pc &= ~(target_ulong)3;
1643 return pc;
1644}
1645
5c13fdfd 1646/* Load */
d75c135e
AJ
1647static void gen_ld(DisasContext *ctx, uint32_t opc,
1648 int rt, int base, int16_t offset)
6af0bf9c 1649{
5c13fdfd 1650 const char *opn = "ld";
fc40787a 1651 TCGv t0, t1, t2;
afa88c3a 1652
d75c135e 1653 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1654 /* Loongson CPU uses a load to zero register for prefetch.
1655 We emulate it as a NOP. On other CPU we must perform the
1656 actual memory access. */
1657 MIPS_DEBUG("NOP");
1658 return;
1659 }
6af0bf9c 1660
afa88c3a 1661 t0 = tcg_temp_new();
662d7485 1662 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1663
6af0bf9c 1664 switch (opc) {
d26bc211 1665#if defined(TARGET_MIPS64)
6e473128 1666 case OPC_LWU:
5f68f5ae 1667 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 1668 gen_store_gpr(t0, rt);
6e473128
TS
1669 opn = "lwu";
1670 break;
6af0bf9c 1671 case OPC_LD:
5f68f5ae 1672 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 1673 gen_store_gpr(t0, rt);
6af0bf9c
FB
1674 opn = "ld";
1675 break;
7a387fff 1676 case OPC_LLD:
bf7910c6 1677 case R6_OPC_LLD:
b835e919 1678 save_cpu_state(ctx, 1);
5c13fdfd 1679 op_ld_lld(t0, t0, ctx);
78723684 1680 gen_store_gpr(t0, rt);
7a387fff
TS
1681 opn = "lld";
1682 break;
6af0bf9c 1683 case OPC_LDL:
3cee3050 1684 t1 = tcg_temp_new();
fc40787a
AJ
1685 tcg_gen_andi_tl(t1, t0, 7);
1686#ifndef TARGET_WORDS_BIGENDIAN
1687 tcg_gen_xori_tl(t1, t1, 7);
1688#endif
1689 tcg_gen_shli_tl(t1, t1, 3);
1690 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1691 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1692 tcg_gen_shl_tl(t0, t0, t1);
1693 tcg_gen_xori_tl(t1, t1, 63);
1694 t2 = tcg_const_tl(0x7fffffffffffffffull);
1695 tcg_gen_shr_tl(t2, t2, t1);
78723684 1696 gen_load_gpr(t1, rt);
fc40787a
AJ
1697 tcg_gen_and_tl(t1, t1, t2);
1698 tcg_temp_free(t2);
1699 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1700 tcg_temp_free(t1);
fc40787a 1701 gen_store_gpr(t0, rt);
6af0bf9c
FB
1702 opn = "ldl";
1703 break;
6af0bf9c 1704 case OPC_LDR:
3cee3050 1705 t1 = tcg_temp_new();
fc40787a
AJ
1706 tcg_gen_andi_tl(t1, t0, 7);
1707#ifdef TARGET_WORDS_BIGENDIAN
1708 tcg_gen_xori_tl(t1, t1, 7);
1709#endif
1710 tcg_gen_shli_tl(t1, t1, 3);
1711 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1712 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1713 tcg_gen_shr_tl(t0, t0, t1);
1714 tcg_gen_xori_tl(t1, t1, 63);
1715 t2 = tcg_const_tl(0xfffffffffffffffeull);
1716 tcg_gen_shl_tl(t2, t2, t1);
78723684 1717 gen_load_gpr(t1, rt);
fc40787a
AJ
1718 tcg_gen_and_tl(t1, t1, t2);
1719 tcg_temp_free(t2);
1720 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1721 tcg_temp_free(t1);
fc40787a 1722 gen_store_gpr(t0, rt);
6af0bf9c
FB
1723 opn = "ldr";
1724 break;
364d4831 1725 case OPC_LDPC:
3cee3050 1726 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1727 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1728 tcg_temp_free(t1);
5f68f5ae 1729 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 1730 gen_store_gpr(t0, rt);
5c13fdfd 1731 opn = "ldpc";
364d4831 1732 break;
6af0bf9c 1733#endif
364d4831 1734 case OPC_LWPC:
3cee3050 1735 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1736 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1737 tcg_temp_free(t1);
5f68f5ae 1738 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 1739 gen_store_gpr(t0, rt);
5c13fdfd 1740 opn = "lwpc";
364d4831 1741 break;
6af0bf9c 1742 case OPC_LW:
5f68f5ae 1743 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 1744 gen_store_gpr(t0, rt);
6af0bf9c
FB
1745 opn = "lw";
1746 break;
6af0bf9c 1747 case OPC_LH:
5f68f5ae 1748 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 1749 gen_store_gpr(t0, rt);
6af0bf9c
FB
1750 opn = "lh";
1751 break;
6af0bf9c 1752 case OPC_LHU:
5f68f5ae 1753 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 1754 gen_store_gpr(t0, rt);
6af0bf9c
FB
1755 opn = "lhu";
1756 break;
1757 case OPC_LB:
5f68f5ae 1758 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 1759 gen_store_gpr(t0, rt);
6af0bf9c
FB
1760 opn = "lb";
1761 break;
6af0bf9c 1762 case OPC_LBU:
5f68f5ae 1763 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 1764 gen_store_gpr(t0, rt);
6af0bf9c
FB
1765 opn = "lbu";
1766 break;
1767 case OPC_LWL:
3cee3050 1768 t1 = tcg_temp_new();
fc40787a
AJ
1769 tcg_gen_andi_tl(t1, t0, 3);
1770#ifndef TARGET_WORDS_BIGENDIAN
1771 tcg_gen_xori_tl(t1, t1, 3);
1772#endif
1773 tcg_gen_shli_tl(t1, t1, 3);
1774 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1775 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1776 tcg_gen_shl_tl(t0, t0, t1);
1777 tcg_gen_xori_tl(t1, t1, 31);
1778 t2 = tcg_const_tl(0x7fffffffull);
1779 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1780 gen_load_gpr(t1, rt);
fc40787a
AJ
1781 tcg_gen_and_tl(t1, t1, t2);
1782 tcg_temp_free(t2);
1783 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1784 tcg_temp_free(t1);
fc40787a
AJ
1785 tcg_gen_ext32s_tl(t0, t0);
1786 gen_store_gpr(t0, rt);
6af0bf9c
FB
1787 opn = "lwl";
1788 break;
6af0bf9c 1789 case OPC_LWR:
3cee3050 1790 t1 = tcg_temp_new();
fc40787a
AJ
1791 tcg_gen_andi_tl(t1, t0, 3);
1792#ifdef TARGET_WORDS_BIGENDIAN
1793 tcg_gen_xori_tl(t1, t1, 3);
1794#endif
1795 tcg_gen_shli_tl(t1, t1, 3);
1796 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1797 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1798 tcg_gen_shr_tl(t0, t0, t1);
1799 tcg_gen_xori_tl(t1, t1, 31);
1800 t2 = tcg_const_tl(0xfffffffeull);
1801 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1802 gen_load_gpr(t1, rt);
fc40787a
AJ
1803 tcg_gen_and_tl(t1, t1, t2);
1804 tcg_temp_free(t2);
1805 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1806 tcg_temp_free(t1);
c728154b 1807 tcg_gen_ext32s_tl(t0, t0);
fc40787a 1808 gen_store_gpr(t0, rt);
6af0bf9c
FB
1809 opn = "lwr";
1810 break;
6af0bf9c 1811 case OPC_LL:
4368b29a 1812 case R6_OPC_LL:
e7139c44 1813 save_cpu_state(ctx, 1);
5c13fdfd 1814 op_ld_ll(t0, t0, ctx);
78723684 1815 gen_store_gpr(t0, rt);
6af0bf9c
FB
1816 opn = "ll";
1817 break;
d66c7132 1818 }
2abf314d 1819 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1820 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1821 tcg_temp_free(t0);
d66c7132
AJ
1822}
1823
5c13fdfd
AJ
1824/* Store */
1825static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1826 int base, int16_t offset)
1827{
1828 const char *opn = "st";
1829 TCGv t0 = tcg_temp_new();
1830 TCGv t1 = tcg_temp_new();
1831
1832 gen_base_offset_addr(ctx, t0, base, offset);
1833 gen_load_gpr(t1, rt);
1834 switch (opc) {
1835#if defined(TARGET_MIPS64)
1836 case OPC_SD:
5f68f5ae 1837 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
1838 opn = "sd";
1839 break;
1840 case OPC_SDL:
1841 save_cpu_state(ctx, 1);
895c2d04 1842 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1843 opn = "sdl";
1844 break;
1845 case OPC_SDR:
1846 save_cpu_state(ctx, 1);
895c2d04 1847 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1848 opn = "sdr";
1849 break;
1850#endif
1851 case OPC_SW:
5f68f5ae 1852 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
1853 opn = "sw";
1854 break;
1855 case OPC_SH:
5f68f5ae 1856 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
1857 opn = "sh";
1858 break;
1859 case OPC_SB:
5f68f5ae 1860 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
1861 opn = "sb";
1862 break;
1863 case OPC_SWL:
1864 save_cpu_state(ctx, 1);
895c2d04 1865 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1866 opn = "swl";
1867 break;
1868 case OPC_SWR:
1869 save_cpu_state(ctx, 1);
895c2d04 1870 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1871 opn = "swr";
1872 break;
1873 }
2abf314d 1874 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1875 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1876 tcg_temp_free(t0);
1877 tcg_temp_free(t1);
1878}
1879
1880
d66c7132
AJ
1881/* Store conditional */
1882static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1883 int base, int16_t offset)
1884{
1885 const char *opn = "st_cond";
1886 TCGv t0, t1;
1887
2d2826b9 1888#ifdef CONFIG_USER_ONLY
d66c7132 1889 t0 = tcg_temp_local_new();
d66c7132 1890 t1 = tcg_temp_local_new();
2d2826b9
AJ
1891#else
1892 t0 = tcg_temp_new();
1893 t1 = tcg_temp_new();
1894#endif
1895 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1896 gen_load_gpr(t1, rt);
1897 switch (opc) {
1898#if defined(TARGET_MIPS64)
1899 case OPC_SCD:
bf7910c6 1900 case R6_OPC_SCD:
b835e919 1901 save_cpu_state(ctx, 1);
5c13fdfd 1902 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1903 opn = "scd";
1904 break;
1905#endif
6af0bf9c 1906 case OPC_SC:
4368b29a 1907 case R6_OPC_SC:
e7139c44 1908 save_cpu_state(ctx, 1);
5c13fdfd 1909 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1910 opn = "sc";
1911 break;
6af0bf9c 1912 }
2abf314d 1913 (void)opn; /* avoid a compiler warning */
6af0bf9c 1914 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1915 tcg_temp_free(t1);
d66c7132 1916 tcg_temp_free(t0);
6af0bf9c
FB
1917}
1918
6ea83fed 1919/* Load and store */
7a387fff 1920static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1921 int base, int16_t offset)
6ea83fed 1922{
923617a3 1923 const char *opn = "flt_ldst";
4e2474d6 1924 TCGv t0 = tcg_temp_new();
6ea83fed 1925
662d7485 1926 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1927 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1928 memory access. */
6ea83fed
FB
1929 switch (opc) {
1930 case OPC_LWC1:
b6d96bed 1931 {
a7812ae4 1932 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 1933 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 1934 gen_store_fpr32(fp0, ft);
a7812ae4 1935 tcg_temp_free_i32(fp0);
b6d96bed 1936 }
6ea83fed
FB
1937 opn = "lwc1";
1938 break;
1939 case OPC_SWC1:
b6d96bed 1940 {
a7812ae4 1941 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1942 gen_load_fpr32(fp0, ft);
5f68f5ae 1943 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 1944 tcg_temp_free_i32(fp0);
b6d96bed 1945 }
6ea83fed
FB
1946 opn = "swc1";
1947 break;
1948 case OPC_LDC1:
b6d96bed 1949 {
a7812ae4 1950 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 1951 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 1952 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1953 tcg_temp_free_i64(fp0);
b6d96bed 1954 }
6ea83fed
FB
1955 opn = "ldc1";
1956 break;
1957 case OPC_SDC1:
b6d96bed 1958 {
a7812ae4 1959 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 1960 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 1961 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 1962 tcg_temp_free_i64(fp0);
b6d96bed 1963 }
6ea83fed
FB
1964 opn = "sdc1";
1965 break;
1966 default:
923617a3 1967 MIPS_INVAL(opn);
e397ee33 1968 generate_exception(ctx, EXCP_RI);
78723684 1969 goto out;
6ea83fed 1970 }
2abf314d 1971 (void)opn; /* avoid a compiler warning */
6ea83fed 1972 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1973 out:
1974 tcg_temp_free(t0);
6ea83fed 1975}
6ea83fed 1976
5ab5c041
AJ
1977static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
1978 int rs, int16_t imm)
26ebe468 1979{
5ab5c041 1980 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468
NF
1981 check_cp1_enabled(ctx);
1982 gen_flt_ldst(ctx, op, rt, rs, imm);
1983 } else {
1984 generate_exception_err(ctx, EXCP_CpU, 1);
1985 }
1986}
1987
6af0bf9c 1988/* Arithmetic with immediate operand */
d75c135e
AJ
1989static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1990 int rt, int rs, int16_t imm)
6af0bf9c 1991{
324d9e32 1992 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1993 const char *opn = "imm arith";
6af0bf9c 1994
7a387fff 1995 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1996 /* If no destination, treat it as a NOP.
1997 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1998 MIPS_DEBUG("NOP");
324d9e32 1999 return;
6af0bf9c
FB
2000 }
2001 switch (opc) {
2002 case OPC_ADDI:
48d38ca5 2003 {
324d9e32
AJ
2004 TCGv t0 = tcg_temp_local_new();
2005 TCGv t1 = tcg_temp_new();
2006 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2007 int l1 = gen_new_label();
2008
324d9e32
AJ
2009 gen_load_gpr(t1, rs);
2010 tcg_gen_addi_tl(t0, t1, uimm);
2011 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2012
324d9e32
AJ
2013 tcg_gen_xori_tl(t1, t1, ~uimm);
2014 tcg_gen_xori_tl(t2, t0, uimm);
2015 tcg_gen_and_tl(t1, t1, t2);
2016 tcg_temp_free(t2);
2017 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2018 tcg_temp_free(t1);
48d38ca5
TS
2019 /* operands of same sign, result different sign */
2020 generate_exception(ctx, EXCP_OVERFLOW);
2021 gen_set_label(l1);
78723684 2022 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2023 gen_store_gpr(t0, rt);
2024 tcg_temp_free(t0);
48d38ca5 2025 }
6af0bf9c
FB
2026 opn = "addi";
2027 break;
2028 case OPC_ADDIU:
324d9e32
AJ
2029 if (rs != 0) {
2030 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2031 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2032 } else {
2033 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2034 }
6af0bf9c
FB
2035 opn = "addiu";
2036 break;
d26bc211 2037#if defined(TARGET_MIPS64)
7a387fff 2038 case OPC_DADDI:
48d38ca5 2039 {
324d9e32
AJ
2040 TCGv t0 = tcg_temp_local_new();
2041 TCGv t1 = tcg_temp_new();
2042 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2043 int l1 = gen_new_label();
2044
324d9e32
AJ
2045 gen_load_gpr(t1, rs);
2046 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2047
324d9e32
AJ
2048 tcg_gen_xori_tl(t1, t1, ~uimm);
2049 tcg_gen_xori_tl(t2, t0, uimm);
2050 tcg_gen_and_tl(t1, t1, t2);
2051 tcg_temp_free(t2);
2052 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2053 tcg_temp_free(t1);
48d38ca5
TS
2054 /* operands of same sign, result different sign */
2055 generate_exception(ctx, EXCP_OVERFLOW);
2056 gen_set_label(l1);
324d9e32
AJ
2057 gen_store_gpr(t0, rt);
2058 tcg_temp_free(t0);
48d38ca5 2059 }
7a387fff
TS
2060 opn = "daddi";
2061 break;
2062 case OPC_DADDIU:
324d9e32
AJ
2063 if (rs != 0) {
2064 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2065 } else {
2066 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2067 }
7a387fff
TS
2068 opn = "daddiu";
2069 break;
2070#endif
324d9e32 2071 }
2abf314d 2072 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2073 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2074}
2075
2076/* Logic with immediate operand */
d75c135e 2077static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2078 int rt, int rs, int16_t imm)
324d9e32
AJ
2079{
2080 target_ulong uimm;
324d9e32
AJ
2081
2082 if (rt == 0) {
2083 /* If no destination, treat it as a NOP. */
2084 MIPS_DEBUG("NOP");
2085 return;
2086 }
2087 uimm = (uint16_t)imm;
2088 switch (opc) {
6af0bf9c 2089 case OPC_ANDI:
324d9e32
AJ
2090 if (likely(rs != 0))
2091 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2092 else
2093 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2094 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2095 regnames[rs], uimm);
6af0bf9c
FB
2096 break;
2097 case OPC_ORI:
324d9e32
AJ
2098 if (rs != 0)
2099 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2100 else
2101 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2102 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2103 regnames[rs], uimm);
6af0bf9c
FB
2104 break;
2105 case OPC_XORI:
324d9e32
AJ
2106 if (likely(rs != 0))
2107 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2108 else
2109 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2110 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2111 regnames[rs], uimm);
6af0bf9c
FB
2112 break;
2113 case OPC_LUI:
324d9e32 2114 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2115 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2116 break;
2117
2118 default:
2119 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2120 break;
324d9e32 2121 }
324d9e32
AJ
2122}
2123
2124/* Set on less than with immediate operand */
d75c135e 2125static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2126 int rt, int rs, int16_t imm)
324d9e32
AJ
2127{
2128 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2129 const char *opn = "imm arith";
2130 TCGv t0;
2131
2132 if (rt == 0) {
2133 /* If no destination, treat it as a NOP. */
2134 MIPS_DEBUG("NOP");
2135 return;
2136 }
2137 t0 = tcg_temp_new();
2138 gen_load_gpr(t0, rs);
2139 switch (opc) {
2140 case OPC_SLTI:
e68dd28f 2141 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2142 opn = "slti";
2143 break;
2144 case OPC_SLTIU:
e68dd28f 2145 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2146 opn = "sltiu";
2147 break;
2148 }
2abf314d 2149 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2150 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2151 tcg_temp_free(t0);
2152}
2153
2154/* Shifts with immediate operand */
d75c135e 2155static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2156 int rt, int rs, int16_t imm)
2157{
2158 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2159 const char *opn = "imm shift";
2160 TCGv t0;
2161
2162 if (rt == 0) {
2163 /* If no destination, treat it as a NOP. */
2164 MIPS_DEBUG("NOP");
2165 return;
2166 }
2167
2168 t0 = tcg_temp_new();
2169 gen_load_gpr(t0, rs);
2170 switch (opc) {
6af0bf9c 2171 case OPC_SLL:
78723684 2172 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2173 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2174 opn = "sll";
2175 break;
2176 case OPC_SRA:
324d9e32 2177 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2178 opn = "sra";
2179 break;
2180 case OPC_SRL:
ea63e2c3
NF
2181 if (uimm != 0) {
2182 tcg_gen_ext32u_tl(t0, t0);
2183 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2184 } else {
2185 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2186 }
ea63e2c3
NF
2187 opn = "srl";
2188 break;
2189 case OPC_ROTR:
2190 if (uimm != 0) {
2191 TCGv_i32 t1 = tcg_temp_new_i32();
2192
2193 tcg_gen_trunc_tl_i32(t1, t0);
2194 tcg_gen_rotri_i32(t1, t1, uimm);
2195 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2196 tcg_temp_free_i32(t1);
3399e30f
NF
2197 } else {
2198 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2199 }
2200 opn = "rotr";
7a387fff 2201 break;
d26bc211 2202#if defined(TARGET_MIPS64)
7a387fff 2203 case OPC_DSLL:
324d9e32 2204 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2205 opn = "dsll";
2206 break;
2207 case OPC_DSRA:
324d9e32 2208 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2209 opn = "dsra";
2210 break;
2211 case OPC_DSRL:
ea63e2c3
NF
2212 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2213 opn = "dsrl";
2214 break;
2215 case OPC_DROTR:
2216 if (uimm != 0) {
2217 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2218 } else {
2219 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2220 }
ea63e2c3 2221 opn = "drotr";
7a387fff
TS
2222 break;
2223 case OPC_DSLL32:
324d9e32 2224 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2225 opn = "dsll32";
2226 break;
2227 case OPC_DSRA32:
324d9e32 2228 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2229 opn = "dsra32";
2230 break;
2231 case OPC_DSRL32:
ea63e2c3
NF
2232 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2233 opn = "dsrl32";
2234 break;
2235 case OPC_DROTR32:
2236 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2237 opn = "drotr32";
6af0bf9c 2238 break;
7a387fff 2239#endif
6af0bf9c 2240 }
2abf314d 2241 (void)opn; /* avoid a compiler warning */
93b12ccc 2242 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2243 tcg_temp_free(t0);
6af0bf9c
FB
2244}
2245
2246/* Arithmetic */
d75c135e
AJ
2247static void gen_arith(DisasContext *ctx, uint32_t opc,
2248 int rd, int rs, int rt)
6af0bf9c 2249{
923617a3 2250 const char *opn = "arith";
6af0bf9c 2251
7a387fff
TS
2252 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2253 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2254 /* If no destination, treat it as a NOP.
2255 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2256 MIPS_DEBUG("NOP");
460f00c4 2257 return;
185f0762 2258 }
460f00c4 2259
6af0bf9c
FB
2260 switch (opc) {
2261 case OPC_ADD:
48d38ca5 2262 {
460f00c4
AJ
2263 TCGv t0 = tcg_temp_local_new();
2264 TCGv t1 = tcg_temp_new();
2265 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2266 int l1 = gen_new_label();
2267
460f00c4
AJ
2268 gen_load_gpr(t1, rs);
2269 gen_load_gpr(t2, rt);
2270 tcg_gen_add_tl(t0, t1, t2);
2271 tcg_gen_ext32s_tl(t0, t0);
2272 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2273 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2274 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2275 tcg_temp_free(t2);
2276 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2277 tcg_temp_free(t1);
48d38ca5
TS
2278 /* operands of same sign, result different sign */
2279 generate_exception(ctx, EXCP_OVERFLOW);
2280 gen_set_label(l1);
460f00c4
AJ
2281 gen_store_gpr(t0, rd);
2282 tcg_temp_free(t0);
48d38ca5 2283 }
6af0bf9c
FB
2284 opn = "add";
2285 break;
2286 case OPC_ADDU:
460f00c4
AJ
2287 if (rs != 0 && rt != 0) {
2288 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2289 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2290 } else if (rs == 0 && rt != 0) {
2291 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2292 } else if (rs != 0 && rt == 0) {
2293 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2294 } else {
2295 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2296 }
6af0bf9c
FB
2297 opn = "addu";
2298 break;
2299 case OPC_SUB:
48d38ca5 2300 {
460f00c4
AJ
2301 TCGv t0 = tcg_temp_local_new();
2302 TCGv t1 = tcg_temp_new();
2303 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2304 int l1 = gen_new_label();
2305
460f00c4
AJ
2306 gen_load_gpr(t1, rs);
2307 gen_load_gpr(t2, rt);
2308 tcg_gen_sub_tl(t0, t1, t2);
2309 tcg_gen_ext32s_tl(t0, t0);
2310 tcg_gen_xor_tl(t2, t1, t2);
2311 tcg_gen_xor_tl(t1, t0, t1);
2312 tcg_gen_and_tl(t1, t1, t2);
2313 tcg_temp_free(t2);
2314 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2315 tcg_temp_free(t1);
31e3104f 2316 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2317 generate_exception(ctx, EXCP_OVERFLOW);
2318 gen_set_label(l1);
460f00c4
AJ
2319 gen_store_gpr(t0, rd);
2320 tcg_temp_free(t0);
48d38ca5 2321 }
6af0bf9c
FB
2322 opn = "sub";
2323 break;
2324 case OPC_SUBU:
460f00c4
AJ
2325 if (rs != 0 && rt != 0) {
2326 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2327 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2328 } else if (rs == 0 && rt != 0) {
2329 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2330 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2331 } else if (rs != 0 && rt == 0) {
2332 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2333 } else {
2334 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2335 }
6af0bf9c
FB
2336 opn = "subu";
2337 break;
d26bc211 2338#if defined(TARGET_MIPS64)
7a387fff 2339 case OPC_DADD:
48d38ca5 2340 {
460f00c4
AJ
2341 TCGv t0 = tcg_temp_local_new();
2342 TCGv t1 = tcg_temp_new();
2343 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2344 int l1 = gen_new_label();
2345
460f00c4
AJ
2346 gen_load_gpr(t1, rs);
2347 gen_load_gpr(t2, rt);
2348 tcg_gen_add_tl(t0, t1, t2);
2349 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2350 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2351 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2352 tcg_temp_free(t2);
2353 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2354 tcg_temp_free(t1);
48d38ca5
TS
2355 /* operands of same sign, result different sign */
2356 generate_exception(ctx, EXCP_OVERFLOW);
2357 gen_set_label(l1);
460f00c4
AJ
2358 gen_store_gpr(t0, rd);
2359 tcg_temp_free(t0);
48d38ca5 2360 }
7a387fff
TS
2361 opn = "dadd";
2362 break;
2363 case OPC_DADDU:
460f00c4
AJ
2364 if (rs != 0 && rt != 0) {
2365 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2366 } else if (rs == 0 && rt != 0) {
2367 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2368 } else if (rs != 0 && rt == 0) {
2369 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2370 } else {
2371 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2372 }
7a387fff
TS
2373 opn = "daddu";
2374 break;
2375 case OPC_DSUB:
48d38ca5 2376 {
460f00c4
AJ
2377 TCGv t0 = tcg_temp_local_new();
2378 TCGv t1 = tcg_temp_new();
2379 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2380 int l1 = gen_new_label();
2381
460f00c4
AJ
2382 gen_load_gpr(t1, rs);
2383 gen_load_gpr(t2, rt);
2384 tcg_gen_sub_tl(t0, t1, t2);
2385 tcg_gen_xor_tl(t2, t1, t2);
2386 tcg_gen_xor_tl(t1, t0, t1);
2387 tcg_gen_and_tl(t1, t1, t2);
2388 tcg_temp_free(t2);
2389 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2390 tcg_temp_free(t1);
31e3104f 2391 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2392 generate_exception(ctx, EXCP_OVERFLOW);
2393 gen_set_label(l1);
460f00c4
AJ
2394 gen_store_gpr(t0, rd);
2395 tcg_temp_free(t0);
48d38ca5 2396 }
7a387fff
TS
2397 opn = "dsub";
2398 break;
2399 case OPC_DSUBU:
460f00c4
AJ
2400 if (rs != 0 && rt != 0) {
2401 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2402 } else if (rs == 0 && rt != 0) {
2403 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2404 } else if (rs != 0 && rt == 0) {
2405 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2406 } else {
2407 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2408 }
7a387fff
TS
2409 opn = "dsubu";
2410 break;
2411#endif
460f00c4
AJ
2412 case OPC_MUL:
2413 if (likely(rs != 0 && rt != 0)) {
2414 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2415 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2416 } else {
2417 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2418 }
2419 opn = "mul";
6af0bf9c 2420 break;
460f00c4 2421 }
2abf314d 2422 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2423 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2424}
2425
2426/* Conditional move */
d75c135e 2427static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2428 int rd, int rs, int rt)
460f00c4
AJ
2429{
2430 const char *opn = "cond move";
acf12465 2431 TCGv t0, t1, t2;
460f00c4
AJ
2432
2433 if (rd == 0) {
acf12465 2434 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2435 MIPS_DEBUG("NOP");
2436 return;
2437 }
2438
acf12465
AJ
2439 t0 = tcg_temp_new();
2440 gen_load_gpr(t0, rt);
2441 t1 = tcg_const_tl(0);
2442 t2 = tcg_temp_new();
2443 gen_load_gpr(t2, rs);
460f00c4
AJ
2444 switch (opc) {
2445 case OPC_MOVN:
acf12465 2446 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2447 opn = "movn";
6af0bf9c 2448 break;
460f00c4 2449 case OPC_MOVZ:
acf12465 2450 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2451 opn = "movz";
2452 break;
b691d9d2
LA
2453 case OPC_SELNEZ:
2454 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2455 opn = "selnez";
2456 break;
2457 case OPC_SELEQZ:
2458 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2459 opn = "seleqz";
2460 break;
460f00c4 2461 }
acf12465
AJ
2462 tcg_temp_free(t2);
2463 tcg_temp_free(t1);
2464 tcg_temp_free(t0);
460f00c4 2465
2abf314d 2466 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2467 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2468}
2469
2470/* Logic */
d75c135e 2471static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2472 int rd, int rs, int rt)
460f00c4
AJ
2473{
2474 const char *opn = "logic";
2475
2476 if (rd == 0) {
2477 /* If no destination, treat it as a NOP. */
2478 MIPS_DEBUG("NOP");
2479 return;
2480 }
2481
2482 switch (opc) {
6af0bf9c 2483 case OPC_AND:
460f00c4
AJ
2484 if (likely(rs != 0 && rt != 0)) {
2485 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2486 } else {
2487 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2488 }
6af0bf9c
FB
2489 opn = "and";
2490 break;
2491 case OPC_NOR:
460f00c4
AJ
2492 if (rs != 0 && rt != 0) {
2493 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2494 } else if (rs == 0 && rt != 0) {
2495 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2496 } else if (rs != 0 && rt == 0) {
2497 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2498 } else {
2499 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2500 }
6af0bf9c
FB
2501 opn = "nor";
2502 break;
2503 case OPC_OR:
460f00c4
AJ
2504 if (likely(rs != 0 && rt != 0)) {
2505 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2506 } else if (rs == 0 && rt != 0) {
2507 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2508 } else if (rs != 0 && rt == 0) {
2509 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2510 } else {
2511 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2512 }
6af0bf9c
FB
2513 opn = "or";
2514 break;
2515 case OPC_XOR:
460f00c4
AJ
2516 if (likely(rs != 0 && rt != 0)) {
2517 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2518 } else if (rs == 0 && rt != 0) {
2519 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2520 } else if (rs != 0 && rt == 0) {
2521 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2522 } else {
2523 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2524 }
6af0bf9c
FB
2525 opn = "xor";
2526 break;
460f00c4 2527 }
2abf314d 2528 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2529 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2530}
2531
2532/* Set on lower than */
d75c135e 2533static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2534 int rd, int rs, int rt)
460f00c4
AJ
2535{
2536 const char *opn = "slt";
2537 TCGv t0, t1;
2538
2539 if (rd == 0) {
2540 /* If no destination, treat it as a NOP. */
2541 MIPS_DEBUG("NOP");
2542 return;
2543 }
2544
2545 t0 = tcg_temp_new();
2546 t1 = tcg_temp_new();
2547 gen_load_gpr(t0, rs);
2548 gen_load_gpr(t1, rt);
2549 switch (opc) {
2550 case OPC_SLT:
e68dd28f 2551 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2552 opn = "slt";
6af0bf9c 2553 break;
460f00c4 2554 case OPC_SLTU:
e68dd28f 2555 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2556 opn = "sltu";
2557 break;
2558 }
2abf314d 2559 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2560 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2561 tcg_temp_free(t0);
2562 tcg_temp_free(t1);
2563}
20c4c97c 2564
460f00c4 2565/* Shifts */
d75c135e
AJ
2566static void gen_shift(DisasContext *ctx, uint32_t opc,
2567 int rd, int rs, int rt)
460f00c4
AJ
2568{
2569 const char *opn = "shifts";
2570 TCGv t0, t1;
20c4c97c 2571
460f00c4
AJ
2572 if (rd == 0) {
2573 /* If no destination, treat it as a NOP.
2574 For add & sub, we must generate the overflow exception when needed. */
2575 MIPS_DEBUG("NOP");
2576 return;
2577 }
2578
2579 t0 = tcg_temp_new();
2580 t1 = tcg_temp_new();
2581 gen_load_gpr(t0, rs);
2582 gen_load_gpr(t1, rt);
2583 switch (opc) {
6af0bf9c 2584 case OPC_SLLV:
78723684
TS
2585 tcg_gen_andi_tl(t0, t0, 0x1f);
2586 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2587 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2588 opn = "sllv";
2589 break;
2590 case OPC_SRAV:
78723684 2591 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2592 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2593 opn = "srav";
2594 break;
2595 case OPC_SRLV:
ea63e2c3
NF
2596 tcg_gen_ext32u_tl(t1, t1);
2597 tcg_gen_andi_tl(t0, t0, 0x1f);
2598 tcg_gen_shr_tl(t0, t1, t0);
2599 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2600 opn = "srlv";
2601 break;
2602 case OPC_ROTRV:
2603 {
2604 TCGv_i32 t2 = tcg_temp_new_i32();
2605 TCGv_i32 t3 = tcg_temp_new_i32();
2606
2607 tcg_gen_trunc_tl_i32(t2, t0);
2608 tcg_gen_trunc_tl_i32(t3, t1);
2609 tcg_gen_andi_i32(t2, t2, 0x1f);
2610 tcg_gen_rotr_i32(t2, t3, t2);
2611 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2612 tcg_temp_free_i32(t2);
2613 tcg_temp_free_i32(t3);
2614 opn = "rotrv";
5a63bcb2 2615 }
7a387fff 2616 break;
d26bc211 2617#if defined(TARGET_MIPS64)
7a387fff 2618 case OPC_DSLLV:
78723684 2619 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2620 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2621 opn = "dsllv";
2622 break;
2623 case OPC_DSRAV:
78723684 2624 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2625 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2626 opn = "dsrav";
2627 break;
2628 case OPC_DSRLV:
ea63e2c3
NF
2629 tcg_gen_andi_tl(t0, t0, 0x3f);
2630 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2631 opn = "dsrlv";
2632 break;
2633 case OPC_DROTRV:
2634 tcg_gen_andi_tl(t0, t0, 0x3f);
2635 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2636 opn = "drotrv";
6af0bf9c 2637 break;
7a387fff 2638#endif
6af0bf9c 2639 }
2abf314d 2640 (void)opn; /* avoid a compiler warning */
6af0bf9c 2641 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2642 tcg_temp_free(t0);
2643 tcg_temp_free(t1);
6af0bf9c
FB
2644}
2645
2646/* Arithmetic on HI/LO registers */
26135ead 2647static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 2648{
923617a3 2649 const char *opn = "hilo";
6af0bf9c
FB
2650
2651 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2652 /* Treat as NOP. */
6af0bf9c 2653 MIPS_DEBUG("NOP");
a1f6684d 2654 return;
6af0bf9c 2655 }
4133498f 2656
4133498f
JL
2657 if (acc != 0) {
2658 check_dsp(ctx);
2659 }
2660
6af0bf9c
FB
2661 switch (opc) {
2662 case OPC_MFHI:
4133498f
JL
2663#if defined(TARGET_MIPS64)
2664 if (acc != 0) {
2665 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2666 } else
2667#endif
2668 {
2669 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2670 }
6af0bf9c
FB
2671 opn = "mfhi";
2672 break;
2673 case OPC_MFLO:
4133498f
JL
2674#if defined(TARGET_MIPS64)
2675 if (acc != 0) {
2676 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2677 } else
2678#endif
2679 {
2680 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2681 }
6af0bf9c
FB
2682 opn = "mflo";
2683 break;
2684 case OPC_MTHI:
4133498f
JL
2685 if (reg != 0) {
2686#if defined(TARGET_MIPS64)
2687 if (acc != 0) {
2688 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2689 } else
2690#endif
2691 {
2692 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2693 }
2694 } else {
2695 tcg_gen_movi_tl(cpu_HI[acc], 0);
2696 }
6af0bf9c
FB
2697 opn = "mthi";
2698 break;
2699 case OPC_MTLO:
4133498f
JL
2700 if (reg != 0) {
2701#if defined(TARGET_MIPS64)
2702 if (acc != 0) {
2703 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2704 } else
2705#endif
2706 {
2707 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2708 }
2709 } else {
2710 tcg_gen_movi_tl(cpu_LO[acc], 0);
2711 }
6af0bf9c
FB
2712 opn = "mtlo";
2713 break;
6af0bf9c 2714 }
2abf314d 2715 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2716 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2717}
2718
b42ee5e1
LA
2719static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
2720{
2721 const char *opn = "r6 mul/div";
2722 TCGv t0, t1;
2723
2724 if (rd == 0) {
2725 /* Treat as NOP. */
2726 MIPS_DEBUG("NOP");
2727 return;
2728 }
2729
2730 t0 = tcg_temp_new();
2731 t1 = tcg_temp_new();
2732
2733 gen_load_gpr(t0, rs);
2734 gen_load_gpr(t1, rt);
2735
2736 switch (opc) {
2737 case R6_OPC_DIV:
2738 {
2739 TCGv t2 = tcg_temp_new();
2740 TCGv t3 = tcg_temp_new();
2741 tcg_gen_ext32s_tl(t0, t0);
2742 tcg_gen_ext32s_tl(t1, t1);
2743 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2744 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2745 tcg_gen_and_tl(t2, t2, t3);
2746 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2747 tcg_gen_or_tl(t2, t2, t3);
2748 tcg_gen_movi_tl(t3, 0);
2749 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2750 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2751 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2752 tcg_temp_free(t3);
2753 tcg_temp_free(t2);
2754 }
2755 opn = "div";
2756 break;
2757 case R6_OPC_MOD:
2758 {
2759 TCGv t2 = tcg_temp_new();
2760 TCGv t3 = tcg_temp_new();
2761 tcg_gen_ext32s_tl(t0, t0);
2762 tcg_gen_ext32s_tl(t1, t1);
2763 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2764 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2765 tcg_gen_and_tl(t2, t2, t3);
2766 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2767 tcg_gen_or_tl(t2, t2, t3);
2768 tcg_gen_movi_tl(t3, 0);
2769 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2770 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2771 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2772 tcg_temp_free(t3);
2773 tcg_temp_free(t2);
2774 }
2775 opn = "mod";
2776 break;
2777 case R6_OPC_DIVU:
2778 {
2779 TCGv t2 = tcg_const_tl(0);
2780 TCGv t3 = tcg_const_tl(1);
2781 tcg_gen_ext32u_tl(t0, t0);
2782 tcg_gen_ext32u_tl(t1, t1);
2783 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2784 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2785 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2786 tcg_temp_free(t3);
2787 tcg_temp_free(t2);
2788 }
2789 opn = "divu";
2790 break;
2791 case R6_OPC_MODU:
2792 {
2793 TCGv t2 = tcg_const_tl(0);
2794 TCGv t3 = tcg_const_tl(1);
2795 tcg_gen_ext32u_tl(t0, t0);
2796 tcg_gen_ext32u_tl(t1, t1);
2797 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2798 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2799 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2800 tcg_temp_free(t3);
2801 tcg_temp_free(t2);
2802 }
2803 opn = "modu";
2804 break;
2805 case R6_OPC_MUL:
2806 {
2807 TCGv_i32 t2 = tcg_temp_new_i32();
2808 TCGv_i32 t3 = tcg_temp_new_i32();
2809 tcg_gen_trunc_tl_i32(t2, t0);
2810 tcg_gen_trunc_tl_i32(t3, t1);
2811 tcg_gen_mul_i32(t2, t2, t3);
2812 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2813 tcg_temp_free_i32(t2);
2814 tcg_temp_free_i32(t3);
2815 }
2816 opn = "mul";
2817 break;
2818 case R6_OPC_MUH:
2819 {
2820 TCGv_i32 t2 = tcg_temp_new_i32();
2821 TCGv_i32 t3 = tcg_temp_new_i32();
2822 tcg_gen_trunc_tl_i32(t2, t0);
2823 tcg_gen_trunc_tl_i32(t3, t1);
2824 tcg_gen_muls2_i32(t2, t3, t2, t3);
2825 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
2826 tcg_temp_free_i32(t2);
2827 tcg_temp_free_i32(t3);
2828 }
2829 opn = "muh";
2830 break;
2831 case R6_OPC_MULU:
2832 {
2833 TCGv_i32 t2 = tcg_temp_new_i32();
2834 TCGv_i32 t3 = tcg_temp_new_i32();
2835 tcg_gen_trunc_tl_i32(t2, t0);
2836 tcg_gen_trunc_tl_i32(t3, t1);
2837 tcg_gen_mul_i32(t2, t2, t3);
2838 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2839 tcg_temp_free_i32(t2);
2840 tcg_temp_free_i32(t3);
2841 }
2842 opn = "mulu";
2843 break;
2844 case R6_OPC_MUHU:
2845 {
2846 TCGv_i32 t2 = tcg_temp_new_i32();
2847 TCGv_i32 t3 = tcg_temp_new_i32();
2848 tcg_gen_trunc_tl_i32(t2, t0);
2849 tcg_gen_trunc_tl_i32(t3, t1);
2850 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2851 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
2852 tcg_temp_free_i32(t2);
2853 tcg_temp_free_i32(t3);
2854 }
2855 opn = "muhu";
2856 break;
2857#if defined(TARGET_MIPS64)
2858 case R6_OPC_DDIV:
2859 {
2860 TCGv t2 = tcg_temp_new();
2861 TCGv t3 = tcg_temp_new();
2862 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2863 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2864 tcg_gen_and_tl(t2, t2, t3);
2865 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2866 tcg_gen_or_tl(t2, t2, t3);
2867 tcg_gen_movi_tl(t3, 0);
2868 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2869 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2870 tcg_temp_free(t3);
2871 tcg_temp_free(t2);
2872 }
2873 opn = "ddiv";
2874 break;
2875 case R6_OPC_DMOD:
2876 {
2877 TCGv t2 = tcg_temp_new();
2878 TCGv t3 = tcg_temp_new();
2879 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2880 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2881 tcg_gen_and_tl(t2, t2, t3);
2882 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2883 tcg_gen_or_tl(t2, t2, t3);
2884 tcg_gen_movi_tl(t3, 0);
2885 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2886 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2887 tcg_temp_free(t3);
2888 tcg_temp_free(t2);
2889 }
2890 opn = "dmod";
2891 break;
2892 case R6_OPC_DDIVU:
2893 {
2894 TCGv t2 = tcg_const_tl(0);
2895 TCGv t3 = tcg_const_tl(1);
2896 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2897 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
2898 tcg_temp_free(t3);
2899 tcg_temp_free(t2);
2900 }
2901 opn = "ddivu";
2902 break;
2903 case R6_OPC_DMODU:
2904 {
2905 TCGv t2 = tcg_const_tl(0);
2906 TCGv t3 = tcg_const_tl(1);
2907 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2908 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
2909 tcg_temp_free(t3);
2910 tcg_temp_free(t2);
2911 }
2912 opn = "dmodu";
2913 break;
2914 case R6_OPC_DMUL:
2915 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
2916 opn = "dmul";
2917 break;
2918 case R6_OPC_DMUH:
2919 {
2920 TCGv t2 = tcg_temp_new();
2921 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
2922 tcg_temp_free(t2);
2923 }
2924 opn = "dmuh";
2925 break;
2926 case R6_OPC_DMULU:
2927 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
2928 opn = "dmulu";
2929 break;
2930 case R6_OPC_DMUHU:
2931 {
2932 TCGv t2 = tcg_temp_new();
2933 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
2934 tcg_temp_free(t2);
2935 }
2936 opn = "dmuhu";
2937 break;
2938#endif
2939 default:
2940 MIPS_INVAL(opn);
2941 generate_exception(ctx, EXCP_RI);
2942 goto out;
2943 }
2944 (void)opn; /* avoid a compiler warning */
2945 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2946 out:
2947 tcg_temp_free(t0);
2948 tcg_temp_free(t1);
2949}
2950
26135ead
RS
2951static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2952 int acc, int rs, int rt)
6af0bf9c 2953{
923617a3 2954 const char *opn = "mul/div";
d45f89f4
AJ
2955 TCGv t0, t1;
2956
51127181
AJ
2957 t0 = tcg_temp_new();
2958 t1 = tcg_temp_new();
6af0bf9c 2959
78723684
TS
2960 gen_load_gpr(t0, rs);
2961 gen_load_gpr(t1, rt);
51127181 2962
26135ead
RS
2963 if (acc != 0) {
2964 check_dsp(ctx);
2965 }
2966
6af0bf9c
FB
2967 switch (opc) {
2968 case OPC_DIV:
48d38ca5 2969 {
51127181
AJ
2970 TCGv t2 = tcg_temp_new();
2971 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2972 tcg_gen_ext32s_tl(t0, t0);
2973 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2974 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2975 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2976 tcg_gen_and_tl(t2, t2, t3);
2977 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2978 tcg_gen_or_tl(t2, t2, t3);
2979 tcg_gen_movi_tl(t3, 0);
2980 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2981 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2982 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2983 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2984 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2985 tcg_temp_free(t3);
2986 tcg_temp_free(t2);
48d38ca5 2987 }
6af0bf9c
FB
2988 opn = "div";
2989 break;
2990 case OPC_DIVU:
48d38ca5 2991 {
51127181
AJ
2992 TCGv t2 = tcg_const_tl(0);
2993 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
2994 tcg_gen_ext32u_tl(t0, t0);
2995 tcg_gen_ext32u_tl(t1, t1);
51127181 2996 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2997 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2998 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2999 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3000 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3001 tcg_temp_free(t3);
3002 tcg_temp_free(t2);
48d38ca5 3003 }
6af0bf9c
FB
3004 opn = "divu";
3005 break;
3006 case OPC_MULT:
214c465f 3007 {
ce1dd5d1
RH
3008 TCGv_i32 t2 = tcg_temp_new_i32();
3009 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3010 tcg_gen_trunc_tl_i32(t2, t0);
3011 tcg_gen_trunc_tl_i32(t3, t1);
3012 tcg_gen_muls2_i32(t2, t3, t2, t3);
3013 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3014 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3015 tcg_temp_free_i32(t2);
3016 tcg_temp_free_i32(t3);
214c465f 3017 }
6af0bf9c
FB
3018 opn = "mult";
3019 break;
3020 case OPC_MULTU:
214c465f 3021 {
ce1dd5d1
RH
3022 TCGv_i32 t2 = tcg_temp_new_i32();
3023 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3024 tcg_gen_trunc_tl_i32(t2, t0);
3025 tcg_gen_trunc_tl_i32(t3, t1);
3026 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3027 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3028 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3029 tcg_temp_free_i32(t2);
3030 tcg_temp_free_i32(t3);
214c465f 3031 }
6af0bf9c
FB
3032 opn = "multu";
3033 break;
d26bc211 3034#if defined(TARGET_MIPS64)
7a387fff 3035 case OPC_DDIV:
48d38ca5 3036 {
51127181
AJ
3037 TCGv t2 = tcg_temp_new();
3038 TCGv t3 = tcg_temp_new();
3039 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3040 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3041 tcg_gen_and_tl(t2, t2, t3);
3042 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3043 tcg_gen_or_tl(t2, t2, t3);
3044 tcg_gen_movi_tl(t3, 0);
3045 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3046 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3047 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3048 tcg_temp_free(t3);
3049 tcg_temp_free(t2);
48d38ca5 3050 }
7a387fff
TS
3051 opn = "ddiv";
3052 break;
3053 case OPC_DDIVU:
48d38ca5 3054 {
51127181
AJ
3055 TCGv t2 = tcg_const_tl(0);
3056 TCGv t3 = tcg_const_tl(1);
3057 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3058 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3059 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3060 tcg_temp_free(t3);
3061 tcg_temp_free(t2);
48d38ca5 3062 }
7a387fff
TS
3063 opn = "ddivu";
3064 break;
3065 case OPC_DMULT:
26135ead 3066 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3067 opn = "dmult";
3068 break;
3069 case OPC_DMULTU:
26135ead 3070 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3071 opn = "dmultu";
3072 break;
3073#endif
6af0bf9c 3074 case OPC_MADD:
214c465f 3075 {
d45f89f4
AJ
3076 TCGv_i64 t2 = tcg_temp_new_i64();
3077 TCGv_i64 t3 = tcg_temp_new_i64();
3078
3079 tcg_gen_ext_tl_i64(t2, t0);
3080 tcg_gen_ext_tl_i64(t3, t1);
3081 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3082 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3083 tcg_gen_add_i64(t2, t2, t3);
3084 tcg_temp_free_i64(t3);
3085 tcg_gen_trunc_i64_tl(t0, t2);
3086 tcg_gen_shri_i64(t2, t2, 32);
3087 tcg_gen_trunc_i64_tl(t1, t2);
3088 tcg_temp_free_i64(t2);
4133498f
JL
3089 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3090 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3091 }
6af0bf9c
FB
3092 opn = "madd";
3093 break;
3094 case OPC_MADDU:
4133498f 3095 {
d45f89f4
AJ
3096 TCGv_i64 t2 = tcg_temp_new_i64();
3097 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3098
78723684
TS
3099 tcg_gen_ext32u_tl(t0, t0);
3100 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3101 tcg_gen_extu_tl_i64(t2, t0);
3102 tcg_gen_extu_tl_i64(t3, t1);
3103 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3104 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3105 tcg_gen_add_i64(t2, t2, t3);
3106 tcg_temp_free_i64(t3);
3107 tcg_gen_trunc_i64_tl(t0, t2);
3108 tcg_gen_shri_i64(t2, t2, 32);
3109 tcg_gen_trunc_i64_tl(t1, t2);
3110 tcg_temp_free_i64(t2);
4133498f
JL
3111 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3112 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3113 }
6af0bf9c
FB
3114 opn = "maddu";
3115 break;
3116 case OPC_MSUB:
214c465f 3117 {
d45f89f4
AJ
3118 TCGv_i64 t2 = tcg_temp_new_i64();
3119 TCGv_i64 t3 = tcg_temp_new_i64();
3120
3121 tcg_gen_ext_tl_i64(t2, t0);
3122 tcg_gen_ext_tl_i64(t3, t1);
3123 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3124 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3125 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3126 tcg_temp_free_i64(t3);
3127 tcg_gen_trunc_i64_tl(t0, t2);
3128 tcg_gen_shri_i64(t2, t2, 32);
3129 tcg_gen_trunc_i64_tl(t1, t2);
3130 tcg_temp_free_i64(t2);
4133498f
JL
3131 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3132 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3133 }
6af0bf9c
FB
3134 opn = "msub";
3135 break;
3136 case OPC_MSUBU:
214c465f 3137 {
d45f89f4
AJ
3138 TCGv_i64 t2 = tcg_temp_new_i64();
3139 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3140
78723684
TS
3141 tcg_gen_ext32u_tl(t0, t0);
3142 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3143 tcg_gen_extu_tl_i64(t2, t0);
3144 tcg_gen_extu_tl_i64(t3, t1);
3145 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3146 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3147 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3148 tcg_temp_free_i64(t3);
3149 tcg_gen_trunc_i64_tl(t0, t2);
3150 tcg_gen_shri_i64(t2, t2, 32);
3151 tcg_gen_trunc_i64_tl(t1, t2);
3152 tcg_temp_free_i64(t2);
4133498f
JL
3153 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3154 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3155 }
6af0bf9c
FB
3156 opn = "msubu";
3157 break;
3158 default:
923617a3 3159 MIPS_INVAL(opn);
6af0bf9c 3160 generate_exception(ctx, EXCP_RI);
78723684 3161 goto out;
6af0bf9c 3162 }
2abf314d 3163 (void)opn; /* avoid a compiler warning */
6af0bf9c 3164 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3165 out:
3166 tcg_temp_free(t0);
3167 tcg_temp_free(t1);
6af0bf9c
FB
3168}
3169
e9c71dd1
TS
3170static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3171 int rd, int rs, int rt)
3172{
3173 const char *opn = "mul vr54xx";
f157bfe1
AJ
3174 TCGv t0 = tcg_temp_new();
3175 TCGv t1 = tcg_temp_new();
e9c71dd1 3176
6c5c1e20
TS
3177 gen_load_gpr(t0, rs);
3178 gen_load_gpr(t1, rt);
e9c71dd1
TS
3179
3180 switch (opc) {
3181 case OPC_VR54XX_MULS:
895c2d04 3182 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3183 opn = "muls";
6958549d 3184 break;
e9c71dd1 3185 case OPC_VR54XX_MULSU:
895c2d04 3186 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3187 opn = "mulsu";
6958549d 3188 break;
e9c71dd1 3189 case OPC_VR54XX_MACC:
895c2d04 3190 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3191 opn = "macc";
6958549d 3192 break;
e9c71dd1 3193 case OPC_VR54XX_MACCU:
895c2d04 3194 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3195 opn = "maccu";
6958549d 3196 break;
e9c71dd1 3197 case OPC_VR54XX_MSAC:
895c2d04 3198 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3199 opn = "msac";
6958549d 3200 break;
e9c71dd1 3201 case OPC_VR54XX_MSACU:
895c2d04 3202 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3203 opn = "msacu";
6958549d 3204 break;
e9c71dd1 3205 case OPC_VR54XX_MULHI:
895c2d04 3206 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3207 opn = "mulhi";
6958549d 3208 break;
e9c71dd1 3209 case OPC_VR54XX_MULHIU:
895c2d04 3210 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3211 opn = "mulhiu";
6958549d 3212 break;
e9c71dd1 3213 case OPC_VR54XX_MULSHI:
895c2d04 3214 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3215 opn = "mulshi";
6958549d 3216 break;
e9c71dd1 3217 case OPC_VR54XX_MULSHIU:
895c2d04 3218 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3219 opn = "mulshiu";
6958549d 3220 break;
e9c71dd1 3221 case OPC_VR54XX_MACCHI:
895c2d04 3222 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3223 opn = "macchi";
6958549d 3224 break;
e9c71dd1 3225 case OPC_VR54XX_MACCHIU:
895c2d04 3226 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3227 opn = "macchiu";
6958549d 3228 break;
e9c71dd1 3229 case OPC_VR54XX_MSACHI:
895c2d04 3230 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3231 opn = "msachi";
6958549d 3232 break;
e9c71dd1 3233 case OPC_VR54XX_MSACHIU:
895c2d04 3234 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3235 opn = "msachiu";
6958549d 3236 break;
e9c71dd1
TS
3237 default:
3238 MIPS_INVAL("mul vr54xx");
3239 generate_exception(ctx, EXCP_RI);
6c5c1e20 3240 goto out;
e9c71dd1 3241 }
6c5c1e20 3242 gen_store_gpr(t0, rd);
2abf314d 3243 (void)opn; /* avoid a compiler warning */
e9c71dd1 3244 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3245
3246 out:
3247 tcg_temp_free(t0);
3248 tcg_temp_free(t1);
e9c71dd1
TS
3249}
3250
7a387fff 3251static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3252 int rd, int rs)
3253{
923617a3 3254 const char *opn = "CLx";
20e1fb52 3255 TCGv t0;
6c5c1e20 3256
6af0bf9c 3257 if (rd == 0) {
ead9360e 3258 /* Treat as NOP. */
6af0bf9c 3259 MIPS_DEBUG("NOP");
20e1fb52 3260 return;
6af0bf9c 3261 }
20e1fb52 3262 t0 = tcg_temp_new();
6c5c1e20 3263 gen_load_gpr(t0, rs);
6af0bf9c
FB
3264 switch (opc) {
3265 case OPC_CLO:
20e1fb52 3266 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3267 opn = "clo";
3268 break;
3269 case OPC_CLZ:
20e1fb52 3270 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3271 opn = "clz";
3272 break;
d26bc211 3273#if defined(TARGET_MIPS64)
7a387fff 3274 case OPC_DCLO:
20e1fb52 3275 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3276 opn = "dclo";
3277 break;
3278 case OPC_DCLZ:
20e1fb52 3279 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3280 opn = "dclz";
3281 break;
3282#endif
6af0bf9c 3283 }
2abf314d 3284 (void)opn; /* avoid a compiler warning */
6af0bf9c 3285 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3286 tcg_temp_free(t0);
6af0bf9c
FB
3287}
3288
161f85e6 3289/* Godson integer instructions */
bd277fa1
RH
3290static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3291 int rd, int rs, int rt)
161f85e6
AJ
3292{
3293 const char *opn = "loongson";
3294 TCGv t0, t1;
3295
3296 if (rd == 0) {
3297 /* Treat as NOP. */
3298 MIPS_DEBUG("NOP");
3299 return;
3300 }
3301
3302 switch (opc) {
3303 case OPC_MULT_G_2E:
3304 case OPC_MULT_G_2F:
3305 case OPC_MULTU_G_2E:
3306 case OPC_MULTU_G_2F:
3307#if defined(TARGET_MIPS64)
3308 case OPC_DMULT_G_2E:
3309 case OPC_DMULT_G_2F:
3310 case OPC_DMULTU_G_2E:
3311 case OPC_DMULTU_G_2F:
3312#endif
3313 t0 = tcg_temp_new();
3314 t1 = tcg_temp_new();
3315 break;
3316 default:
3317 t0 = tcg_temp_local_new();
3318 t1 = tcg_temp_local_new();
3319 break;
3320 }
3321
3322 gen_load_gpr(t0, rs);
3323 gen_load_gpr(t1, rt);
3324
3325 switch (opc) {
3326 case OPC_MULT_G_2E:
3327 case OPC_MULT_G_2F:
3328 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3329 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3330 opn = "mult.g";
3331 break;
3332 case OPC_MULTU_G_2E:
3333 case OPC_MULTU_G_2F:
3334 tcg_gen_ext32u_tl(t0, t0);
3335 tcg_gen_ext32u_tl(t1, t1);
3336 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3337 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3338 opn = "multu.g";
3339 break;
3340 case OPC_DIV_G_2E:
3341 case OPC_DIV_G_2F:
3342 {
3343 int l1 = gen_new_label();
3344 int l2 = gen_new_label();
3345 int l3 = gen_new_label();
3346 tcg_gen_ext32s_tl(t0, t0);
3347 tcg_gen_ext32s_tl(t1, t1);
3348 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3349 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3350 tcg_gen_br(l3);
3351 gen_set_label(l1);
3352 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3353 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3354 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3355 tcg_gen_br(l3);
3356 gen_set_label(l2);
3357 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3358 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3359 gen_set_label(l3);
3360 }
3361 opn = "div.g";
3362 break;
3363 case OPC_DIVU_G_2E:
3364 case OPC_DIVU_G_2F:
3365 {
3366 int l1 = gen_new_label();
3367 int l2 = gen_new_label();
3368 tcg_gen_ext32u_tl(t0, t0);
3369 tcg_gen_ext32u_tl(t1, t1);
3370 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3371 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3372 tcg_gen_br(l2);
3373 gen_set_label(l1);
3374 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3375 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3376 gen_set_label(l2);
3377 }
3378 opn = "divu.g";
3379 break;
3380 case OPC_MOD_G_2E:
3381 case OPC_MOD_G_2F:
3382 {
3383 int l1 = gen_new_label();
3384 int l2 = gen_new_label();
3385 int l3 = gen_new_label();
3386 tcg_gen_ext32u_tl(t0, t0);
3387 tcg_gen_ext32u_tl(t1, t1);
3388 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3389 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3390 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3391 gen_set_label(l1);
3392 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3393 tcg_gen_br(l3);
3394 gen_set_label(l2);
3395 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3396 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3397 gen_set_label(l3);
3398 }
3399 opn = "mod.g";
3400 break;
3401 case OPC_MODU_G_2E:
3402 case OPC_MODU_G_2F:
3403 {
3404 int l1 = gen_new_label();
3405 int l2 = gen_new_label();
3406 tcg_gen_ext32u_tl(t0, t0);
3407 tcg_gen_ext32u_tl(t1, t1);
3408 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3409 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3410 tcg_gen_br(l2);
3411 gen_set_label(l1);
3412 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3413 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3414 gen_set_label(l2);
3415 }
3416 opn = "modu.g";
3417 break;
3418#if defined(TARGET_MIPS64)
3419 case OPC_DMULT_G_2E:
3420 case OPC_DMULT_G_2F:
3421 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3422 opn = "dmult.g";
3423 break;
3424 case OPC_DMULTU_G_2E:
3425 case OPC_DMULTU_G_2F:
3426 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3427 opn = "dmultu.g";
3428 break;
3429 case OPC_DDIV_G_2E:
3430 case OPC_DDIV_G_2F:
3431 {
3432 int l1 = gen_new_label();
3433 int l2 = gen_new_label();
3434 int l3 = gen_new_label();
3435 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3436 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3437 tcg_gen_br(l3);
3438 gen_set_label(l1);
3439 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3440 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3441 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3442 tcg_gen_br(l3);
3443 gen_set_label(l2);
3444 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3445 gen_set_label(l3);
3446 }
3447 opn = "ddiv.g";
3448 break;
3449 case OPC_DDIVU_G_2E:
3450 case OPC_DDIVU_G_2F:
3451 {
3452 int l1 = gen_new_label();
3453 int l2 = gen_new_label();
3454 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3455 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3456 tcg_gen_br(l2);
3457 gen_set_label(l1);
3458 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3459 gen_set_label(l2);
3460 }
3461 opn = "ddivu.g";
3462 break;
3463 case OPC_DMOD_G_2E:
3464 case OPC_DMOD_G_2F:
3465 {
3466 int l1 = gen_new_label();
3467 int l2 = gen_new_label();
3468 int l3 = gen_new_label();
3469 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3470 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3471 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3472 gen_set_label(l1);
3473 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3474 tcg_gen_br(l3);
3475 gen_set_label(l2);
3476 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3477 gen_set_label(l3);
3478 }
3479 opn = "dmod.g";
3480 break;
3481 case OPC_DMODU_G_2E:
3482 case OPC_DMODU_G_2F:
3483 {
3484 int l1 = gen_new_label();
3485 int l2 = gen_new_label();
3486 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3487 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3488 tcg_gen_br(l2);
3489 gen_set_label(l1);
3490 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3491 gen_set_label(l2);
3492 }
3493 opn = "dmodu.g";
3494 break;
3495#endif
3496 }
3497
2abf314d 3498 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3499 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3500 tcg_temp_free(t0);
3501 tcg_temp_free(t1);
3502}
3503
bd277fa1
RH
3504/* Loongson multimedia instructions */
3505static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3506{
3507 const char *opn = "loongson_cp2";
3508 uint32_t opc, shift_max;
3509 TCGv_i64 t0, t1;
3510
3511 opc = MASK_LMI(ctx->opcode);
3512 switch (opc) {
3513 case OPC_ADD_CP2:
3514 case OPC_SUB_CP2:
3515 case OPC_DADD_CP2:
3516 case OPC_DSUB_CP2:
3517 t0 = tcg_temp_local_new_i64();
3518 t1 = tcg_temp_local_new_i64();
3519 break;
3520 default:
3521 t0 = tcg_temp_new_i64();
3522 t1 = tcg_temp_new_i64();
3523 break;
3524 }
3525
3526 gen_load_fpr64(ctx, t0, rs);
3527 gen_load_fpr64(ctx, t1, rt);
3528
3529#define LMI_HELPER(UP, LO) \
3530 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3531#define LMI_HELPER_1(UP, LO) \
3532 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3533#define LMI_DIRECT(UP, LO, OP) \
3534 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3535
3536 switch (opc) {
3537 LMI_HELPER(PADDSH, paddsh);
3538 LMI_HELPER(PADDUSH, paddush);
3539 LMI_HELPER(PADDH, paddh);
3540 LMI_HELPER(PADDW, paddw);
3541 LMI_HELPER(PADDSB, paddsb);
3542 LMI_HELPER(PADDUSB, paddusb);
3543 LMI_HELPER(PADDB, paddb);
3544
3545 LMI_HELPER(PSUBSH, psubsh);
3546 LMI_HELPER(PSUBUSH, psubush);
3547 LMI_HELPER(PSUBH, psubh);
3548 LMI_HELPER(PSUBW, psubw);
3549 LMI_HELPER(PSUBSB, psubsb);
3550 LMI_HELPER(PSUBUSB, psubusb);
3551 LMI_HELPER(PSUBB, psubb);
3552
3553 LMI_HELPER(PSHUFH, pshufh);
3554 LMI_HELPER(PACKSSWH, packsswh);
3555 LMI_HELPER(PACKSSHB, packsshb);
3556 LMI_HELPER(PACKUSHB, packushb);
3557
3558 LMI_HELPER(PUNPCKLHW, punpcklhw);
3559 LMI_HELPER(PUNPCKHHW, punpckhhw);
3560 LMI_HELPER(PUNPCKLBH, punpcklbh);
3561 LMI_HELPER(PUNPCKHBH, punpckhbh);
3562 LMI_HELPER(PUNPCKLWD, punpcklwd);
3563 LMI_HELPER(PUNPCKHWD, punpckhwd);
3564
3565 LMI_HELPER(PAVGH, pavgh);
3566 LMI_HELPER(PAVGB, pavgb);
3567 LMI_HELPER(PMAXSH, pmaxsh);
3568 LMI_HELPER(PMINSH, pminsh);
3569 LMI_HELPER(PMAXUB, pmaxub);
3570 LMI_HELPER(PMINUB, pminub);
3571
3572 LMI_HELPER(PCMPEQW, pcmpeqw);
3573 LMI_HELPER(PCMPGTW, pcmpgtw);
3574 LMI_HELPER(PCMPEQH, pcmpeqh);
3575 LMI_HELPER(PCMPGTH, pcmpgth);
3576 LMI_HELPER(PCMPEQB, pcmpeqb);
3577 LMI_HELPER(PCMPGTB, pcmpgtb);
3578
3579 LMI_HELPER(PSLLW, psllw);
3580 LMI_HELPER(PSLLH, psllh);
3581 LMI_HELPER(PSRLW, psrlw);
3582 LMI_HELPER(PSRLH, psrlh);
3583 LMI_HELPER(PSRAW, psraw);
3584 LMI_HELPER(PSRAH, psrah);
3585
3586 LMI_HELPER(PMULLH, pmullh);
3587 LMI_HELPER(PMULHH, pmulhh);
3588 LMI_HELPER(PMULHUH, pmulhuh);
3589 LMI_HELPER(PMADDHW, pmaddhw);
3590
3591 LMI_HELPER(PASUBUB, pasubub);
3592 LMI_HELPER_1(BIADD, biadd);
3593 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3594
3595 LMI_DIRECT(PADDD, paddd, add);
3596 LMI_DIRECT(PSUBD, psubd, sub);
3597 LMI_DIRECT(XOR_CP2, xor, xor);
3598 LMI_DIRECT(NOR_CP2, nor, nor);
3599 LMI_DIRECT(AND_CP2, and, and);
3600 LMI_DIRECT(PANDN, pandn, andc);
3601 LMI_DIRECT(OR, or, or);
3602
3603 case OPC_PINSRH_0:
3604 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3605 opn = "pinsrh_0";
3606 break;
3607 case OPC_PINSRH_1:
3608 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3609 opn = "pinsrh_1";
3610 break;
3611 case OPC_PINSRH_2:
3612 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3613 opn = "pinsrh_2";
3614 break;
3615 case OPC_PINSRH_3:
3616 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3617 opn = "pinsrh_3";
3618 break;
3619
3620 case OPC_PEXTRH:
3621 tcg_gen_andi_i64(t1, t1, 3);
3622 tcg_gen_shli_i64(t1, t1, 4);
3623 tcg_gen_shr_i64(t0, t0, t1);
3624 tcg_gen_ext16u_i64(t0, t0);
3625 opn = "pextrh";
3626 break;
3627
3628 case OPC_ADDU_CP2:
3629 tcg_gen_add_i64(t0, t0, t1);
3630 tcg_gen_ext32s_i64(t0, t0);
3631 opn = "addu";
3632 break;
3633 case OPC_SUBU_CP2:
3634 tcg_gen_sub_i64(t0, t0, t1);
3635 tcg_gen_ext32s_i64(t0, t0);
3636 opn = "addu";
3637 break;
3638
3639 case OPC_SLL_CP2:
3640 opn = "sll";
3641 shift_max = 32;
3642 goto do_shift;
3643 case OPC_SRL_CP2:
3644 opn = "srl";
3645 shift_max = 32;
3646 goto do_shift;
3647 case OPC_SRA_CP2:
3648 opn = "sra";
3649 shift_max = 32;
3650 goto do_shift;
3651 case OPC_DSLL_CP2:
3652 opn = "dsll";
3653 shift_max = 64;
3654 goto do_shift;
3655 case OPC_DSRL_CP2:
3656 opn = "dsrl";
3657 shift_max = 64;
3658 goto do_shift;
3659 case OPC_DSRA_CP2:
3660 opn = "dsra";
3661 shift_max = 64;
3662 goto do_shift;
3663 do_shift:
3664 /* Make sure shift count isn't TCG undefined behaviour. */
3665 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3666
3667 switch (opc) {
3668 case OPC_SLL_CP2:
3669 case OPC_DSLL_CP2:
3670 tcg_gen_shl_i64(t0, t0, t1);
3671 break;
3672 case OPC_SRA_CP2:
3673 case OPC_DSRA_CP2:
3674 /* Since SRA is UndefinedResult without sign-extended inputs,
3675 we can treat SRA and DSRA the same. */
3676 tcg_gen_sar_i64(t0, t0, t1);
3677 break;
3678 case OPC_SRL_CP2:
3679 /* We want to shift in zeros for SRL; zero-extend first. */
3680 tcg_gen_ext32u_i64(t0, t0);
3681 /* FALLTHRU */
3682 case OPC_DSRL_CP2:
3683 tcg_gen_shr_i64(t0, t0, t1);
3684 break;
3685 }
3686
3687 if (shift_max == 32) {
3688 tcg_gen_ext32s_i64(t0, t0);
3689 }
3690
3691 /* Shifts larger than MAX produce zero. */
3692 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3693 tcg_gen_neg_i64(t1, t1);
3694 tcg_gen_and_i64(t0, t0, t1);
3695 break;
3696
3697 case OPC_ADD_CP2:
3698 case OPC_DADD_CP2:
3699 {
3700 TCGv_i64 t2 = tcg_temp_new_i64();
3701 int lab = gen_new_label();
3702
3703 tcg_gen_mov_i64(t2, t0);
3704 tcg_gen_add_i64(t0, t1, t2);
3705 if (opc == OPC_ADD_CP2) {
3706 tcg_gen_ext32s_i64(t0, t0);
3707 }
3708 tcg_gen_xor_i64(t1, t1, t2);
3709 tcg_gen_xor_i64(t2, t2, t0);
3710 tcg_gen_andc_i64(t1, t2, t1);
3711 tcg_temp_free_i64(t2);
3712 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3713 generate_exception(ctx, EXCP_OVERFLOW);
3714 gen_set_label(lab);
3715
3716 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3717 break;
3718 }
3719
3720 case OPC_SUB_CP2:
3721 case OPC_DSUB_CP2:
3722 {
3723 TCGv_i64 t2 = tcg_temp_new_i64();
3724 int lab = gen_new_label();
3725
3726 tcg_gen_mov_i64(t2, t0);
3727 tcg_gen_sub_i64(t0, t1, t2);
3728 if (opc == OPC_SUB_CP2) {
3729 tcg_gen_ext32s_i64(t0, t0);
3730 }
3731 tcg_gen_xor_i64(t1, t1, t2);
3732 tcg_gen_xor_i64(t2, t2, t0);
3733 tcg_gen_and_i64(t1, t1, t2);
3734 tcg_temp_free_i64(t2);
3735 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3736 generate_exception(ctx, EXCP_OVERFLOW);
3737 gen_set_label(lab);
3738
3739 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3740 break;
3741 }
3742
3743 case OPC_PMULUW:
3744 tcg_gen_ext32u_i64(t0, t0);
3745 tcg_gen_ext32u_i64(t1, t1);
3746 tcg_gen_mul_i64(t0, t0, t1);
3747 opn = "pmuluw";
3748 break;
3749
3750 case OPC_SEQU_CP2:
3751 case OPC_SEQ_CP2:
3752 case OPC_SLTU_CP2:
3753 case OPC_SLT_CP2:
3754 case OPC_SLEU_CP2:
3755 case OPC_SLE_CP2:
3756 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3757 FD field is the CC field? */
3758 default:
3759 MIPS_INVAL(opn);
3760 generate_exception(ctx, EXCP_RI);
3761 return;
3762 }
3763
3764#undef LMI_HELPER
3765#undef LMI_DIRECT
3766
3767 gen_store_fpr64(ctx, t0, rd);
3768
3769 (void)opn; /* avoid a compiler warning */
3770 MIPS_DEBUG("%s %s, %s, %s", opn,
3771 fregnames[rd], fregnames[rs], fregnames[rt]);
3772 tcg_temp_free_i64(t0);
3773 tcg_temp_free_i64(t1);
3774}
3775
6af0bf9c 3776/* Traps */
7a387fff 3777static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3778 int rs, int rt, int16_t imm)
3779{
3780 int cond;
cdc0faa6 3781 TCGv t0 = tcg_temp_new();
1ba74fb8 3782 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3783
3784 cond = 0;
3785 /* Load needed operands */
3786 switch (opc) {
3787 case OPC_TEQ:
3788 case OPC_TGE:
3789 case OPC_TGEU:
3790 case OPC_TLT:
3791 case OPC_TLTU:
3792 case OPC_TNE:
3793 /* Compare two registers */
3794 if (rs != rt) {
be24bb4f
TS
3795 gen_load_gpr(t0, rs);
3796 gen_load_gpr(t1, rt);
6af0bf9c
FB
3797 cond = 1;
3798 }
179e32bb 3799 break;
6af0bf9c
FB
3800 case OPC_TEQI:
3801 case OPC_TGEI:
3802 case OPC_TGEIU:
3803 case OPC_TLTI:
3804 case OPC_TLTIU:
3805 case OPC_TNEI:
3806 /* Compare register to immediate */
3807 if (rs != 0 || imm != 0) {
be24bb4f
TS
3808 gen_load_gpr(t0, rs);
3809 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3810 cond = 1;
3811 }
3812 break;
3813 }
3814 if (cond == 0) {
3815 switch (opc) {
3816 case OPC_TEQ: /* rs == rs */
3817 case OPC_TEQI: /* r0 == 0 */
3818 case OPC_TGE: /* rs >= rs */
3819 case OPC_TGEI: /* r0 >= 0 */
3820 case OPC_TGEU: /* rs >= rs unsigned */
3821 case OPC_TGEIU: /* r0 >= 0 unsigned */
3822 /* Always trap */
cdc0faa6 3823 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3824 break;
3825 case OPC_TLT: /* rs < rs */
3826 case OPC_TLTI: /* r0 < 0 */
3827 case OPC_TLTU: /* rs < rs unsigned */
3828 case OPC_TLTIU: /* r0 < 0 unsigned */
3829 case OPC_TNE: /* rs != rs */
3830 case OPC_TNEI: /* r0 != 0 */
ead9360e 3831 /* Never trap: treat as NOP. */
cdc0faa6 3832 break;
6af0bf9c
FB
3833 }
3834 } else {
cdc0faa6
AJ
3835 int l1 = gen_new_label();
3836
6af0bf9c
FB
3837 switch (opc) {
3838 case OPC_TEQ:
3839 case OPC_TEQI:
cdc0faa6 3840 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3841 break;
3842 case OPC_TGE:
3843 case OPC_TGEI:
cdc0faa6 3844 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3845 break;
3846 case OPC_TGEU:
3847 case OPC_TGEIU:
cdc0faa6 3848 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3849 break;
3850 case OPC_TLT:
3851 case OPC_TLTI:
cdc0faa6 3852 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3853 break;
3854 case OPC_TLTU:
3855 case OPC_TLTIU:
cdc0faa6 3856 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3857 break;
3858 case OPC_TNE:
3859 case OPC_TNEI:
cdc0faa6 3860 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3861 break;
6af0bf9c 3862 }
cdc0faa6 3863 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3864 gen_set_label(l1);
3865 }
be24bb4f
TS
3866 tcg_temp_free(t0);
3867 tcg_temp_free(t1);
6af0bf9c
FB
3868}
3869
356265ae 3870static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3871{
6e256c93
FB
3872 TranslationBlock *tb;
3873 tb = ctx->tb;
7b270ef2
NF
3874 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3875 likely(!ctx->singlestep_enabled)) {
57fec1fe 3876 tcg_gen_goto_tb(n);
9b9e4393 3877 gen_save_pc(dest);
8cfd0495 3878 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 3879 } else {
9b9e4393 3880 gen_save_pc(dest);
7b270ef2
NF
3881 if (ctx->singlestep_enabled) {
3882 save_cpu_state(ctx, 0);
895c2d04 3883 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3884 }
57fec1fe 3885 tcg_gen_exit_tb(0);
6e256c93 3886 }
c53be334
FB
3887}
3888
6af0bf9c 3889/* Branches (before delay slot) */
7a387fff 3890static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3891 int insn_bytes,
6af0bf9c
FB
3892 int rs, int rt, int32_t offset)
3893{
d077b6f7 3894 target_ulong btgt = -1;
3ad4bb2d 3895 int blink = 0;
2fdbad25 3896 int bcond_compute = 0;
1ba74fb8
AJ
3897 TCGv t0 = tcg_temp_new();
3898 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3899
3900 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3901#ifdef MIPS_DEBUG_DISAS
d12d51d5 3902 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3903#endif
3ad4bb2d 3904 generate_exception(ctx, EXCP_RI);
6c5c1e20 3905 goto out;
3ad4bb2d 3906 }
6af0bf9c 3907
6af0bf9c
FB
3908 /* Load needed operands */
3909 switch (opc) {
3910 case OPC_BEQ:
3911 case OPC_BEQL:
3912 case OPC_BNE:
3913 case OPC_BNEL:
3914 /* Compare two registers */
3915 if (rs != rt) {
6c5c1e20
TS
3916 gen_load_gpr(t0, rs);
3917 gen_load_gpr(t1, rt);
2fdbad25 3918 bcond_compute = 1;
6af0bf9c 3919 }
7dca4ad0 3920 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3921 break;
3922 case OPC_BGEZ:
3923 case OPC_BGEZAL:
3c824109 3924 case OPC_BGEZALS:
6af0bf9c
FB
3925 case OPC_BGEZALL:
3926 case OPC_BGEZL:
3927 case OPC_BGTZ:
3928 case OPC_BGTZL:
3929 case OPC_BLEZ:
3930 case OPC_BLEZL:
3931 case OPC_BLTZ:
3932 case OPC_BLTZAL:
3c824109 3933 case OPC_BLTZALS:
6af0bf9c
FB
3934 case OPC_BLTZALL:
3935 case OPC_BLTZL:
3936 /* Compare to zero */
3937 if (rs != 0) {
6c5c1e20 3938 gen_load_gpr(t0, rs);
2fdbad25 3939 bcond_compute = 1;
6af0bf9c 3940 }
7dca4ad0 3941 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3942 break;
e45a93e2
JL
3943 case OPC_BPOSGE32:
3944#if defined(TARGET_MIPS64)
3945 case OPC_BPOSGE64:
3946 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3947#else
3948 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3949#endif
3950 bcond_compute = 1;
3951 btgt = ctx->pc + insn_bytes + offset;
3952 break;
6af0bf9c
FB
3953 case OPC_J:
3954 case OPC_JAL:
364d4831 3955 case OPC_JALX:
620e48f6
NF
3956 case OPC_JALS:
3957 case OPC_JALXS:
6af0bf9c 3958 /* Jump to immediate */
7dca4ad0 3959 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3960 break;
3961 case OPC_JR:
3962 case OPC_JALR:
364d4831 3963 case OPC_JALRC:
620e48f6 3964 case OPC_JALRS:
6af0bf9c 3965 /* Jump to register */
7a387fff
TS
3966 if (offset != 0 && offset != 16) {
3967 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3968 others are reserved. */
923617a3 3969 MIPS_INVAL("jump hint");
6af0bf9c 3970 generate_exception(ctx, EXCP_RI);
6c5c1e20 3971 goto out;
6af0bf9c 3972 }
d077b6f7 3973 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3974 break;
3975 default:
3976 MIPS_INVAL("branch/jump");
3977 generate_exception(ctx, EXCP_RI);
6c5c1e20 3978 goto out;
6af0bf9c 3979 }
2fdbad25 3980 if (bcond_compute == 0) {
6af0bf9c
FB
3981 /* No condition to be computed */
3982 switch (opc) {
3983 case OPC_BEQ: /* rx == rx */
3984 case OPC_BEQL: /* rx == rx likely */
3985 case OPC_BGEZ: /* 0 >= 0 */
3986 case OPC_BGEZL: /* 0 >= 0 likely */
3987 case OPC_BLEZ: /* 0 <= 0 */
3988 case OPC_BLEZL: /* 0 <= 0 likely */
3989 /* Always take */
4ad40f36 3990 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3991 MIPS_DEBUG("balways");
3992 break;
3c824109 3993 case OPC_BGEZALS:
6af0bf9c
FB
3994 case OPC_BGEZAL: /* 0 >= 0 */
3995 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3996 ctx->hflags |= (opc == OPC_BGEZALS
3997 ? MIPS_HFLAG_BDS16
3998 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3999 /* Always take and link */
4000 blink = 31;
4ad40f36 4001 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4002 MIPS_DEBUG("balways and link");
4003 break;
4004 case OPC_BNE: /* rx != rx */
4005 case OPC_BGTZ: /* 0 > 0 */
4006 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4007 /* Treat as NOP. */
6af0bf9c 4008 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4009 goto out;
3c824109 4010 case OPC_BLTZALS:
eeef26cd 4011 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4012 ctx->hflags |= (opc == OPC_BLTZALS
4013 ? MIPS_HFLAG_BDS16
4014 : MIPS_HFLAG_BDS32);
4015 /* Handle as an unconditional branch to get correct delay
4016 slot checking. */
4017 blink = 31;
4018 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
4019 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4020 MIPS_DEBUG("bnever and link");
3c824109 4021 break;
eeef26cd 4022 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4023 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4024 /* Skip the instruction in the delay slot */
4025 MIPS_DEBUG("bnever, link and skip");
4026 ctx->pc += 4;
6c5c1e20 4027 goto out;
6af0bf9c
FB
4028 case OPC_BNEL: /* rx != rx likely */
4029 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4030 case OPC_BLTZL: /* 0 < 0 likely */
4031 /* Skip the instruction in the delay slot */
4032 MIPS_DEBUG("bnever and skip");
9898128f 4033 ctx->pc += 4;
6c5c1e20 4034 goto out;
6af0bf9c 4035 case OPC_J:
4ad40f36 4036 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4037 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4038 break;
620e48f6 4039 case OPC_JALXS:
364d4831
NF
4040 case OPC_JALX:
4041 ctx->hflags |= MIPS_HFLAG_BX;
4042 /* Fallthrough */
620e48f6 4043 case OPC_JALS:
6af0bf9c
FB
4044 case OPC_JAL:
4045 blink = 31;
4ad40f36 4046 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 4047 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
4048 ? MIPS_HFLAG_BDS16
4049 : MIPS_HFLAG_BDS32);
d077b6f7 4050 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4051 break;
4052 case OPC_JR:
4ad40f36 4053 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
4054 if (insn_bytes == 4)
4055 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
4056 MIPS_DEBUG("jr %s", regnames[rs]);
4057 break;
620e48f6 4058 case OPC_JALRS:
6af0bf9c 4059 case OPC_JALR:
364d4831 4060 case OPC_JALRC:
6af0bf9c 4061 blink = rt;
4ad40f36 4062 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
4063 ctx->hflags |= (opc == OPC_JALRS
4064 ? MIPS_HFLAG_BDS16
4065 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
4066 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4067 break;
4068 default:
4069 MIPS_INVAL("branch/jump");
4070 generate_exception(ctx, EXCP_RI);
6c5c1e20 4071 goto out;
6af0bf9c
FB
4072 }
4073 } else {
4074 switch (opc) {
4075 case OPC_BEQ:
e68dd28f 4076 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4077 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4078 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4079 goto not_likely;
4080 case OPC_BEQL:
e68dd28f 4081 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4082 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4083 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4084 goto likely;
4085 case OPC_BNE:
e68dd28f 4086 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4087 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4088 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4089 goto not_likely;
4090 case OPC_BNEL:
e68dd28f 4091 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4092 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4093 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4094 goto likely;
4095 case OPC_BGEZ:
e68dd28f 4096 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4097 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4098 goto not_likely;
4099 case OPC_BGEZL:
e68dd28f 4100 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4101 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4102 goto likely;
3c824109 4103 case OPC_BGEZALS:
6af0bf9c 4104 case OPC_BGEZAL:
3c824109
NF
4105 ctx->hflags |= (opc == OPC_BGEZALS
4106 ? MIPS_HFLAG_BDS16
4107 : MIPS_HFLAG_BDS32);
e68dd28f 4108 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4109 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4110 blink = 31;
4111 goto not_likely;
4112 case OPC_BGEZALL:
e68dd28f 4113 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4114 blink = 31;
d077b6f7 4115 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4116 goto likely;
4117 case OPC_BGTZ:
e68dd28f 4118 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4119 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4120 goto not_likely;
4121 case OPC_BGTZL:
e68dd28f 4122 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4123 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4124 goto likely;
4125 case OPC_BLEZ:
e68dd28f 4126 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4127 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4128 goto not_likely;
4129 case OPC_BLEZL:
e68dd28f 4130 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4131 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4132 goto likely;
4133 case OPC_BLTZ:
e68dd28f 4134 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4135 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4136 goto not_likely;
4137 case OPC_BLTZL:
e68dd28f 4138 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4139 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4140 goto likely;
e45a93e2
JL
4141 case OPC_BPOSGE32:
4142 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4143 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4144 goto not_likely;
4145#if defined(TARGET_MIPS64)
4146 case OPC_BPOSGE64:
4147 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4148 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4149 goto not_likely;
4150#endif
3c824109 4151 case OPC_BLTZALS:
6af0bf9c 4152 case OPC_BLTZAL:
3c824109
NF
4153 ctx->hflags |= (opc == OPC_BLTZALS
4154 ? MIPS_HFLAG_BDS16
4155 : MIPS_HFLAG_BDS32);
e68dd28f 4156 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4157 blink = 31;
d077b6f7 4158 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4159 not_likely:
4ad40f36 4160 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4161 break;
4162 case OPC_BLTZALL:
e68dd28f 4163 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4164 blink = 31;
d077b6f7 4165 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4166 likely:
4ad40f36 4167 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4168 break;
c53f4a62
TS
4169 default:
4170 MIPS_INVAL("conditional branch/jump");
4171 generate_exception(ctx, EXCP_RI);
6c5c1e20 4172 goto out;
6af0bf9c 4173 }
6af0bf9c 4174 }
923617a3 4175 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4176 blink, ctx->hflags, btgt);
9b9e4393 4177
d077b6f7 4178 ctx->btarget = btgt;
6af0bf9c 4179 if (blink > 0) {
364d4831
NF
4180 int post_delay = insn_bytes;
4181 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4182
4183 if (opc != OPC_JALRC)
4184 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
4185
4186 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4187 }
6c5c1e20
TS
4188
4189 out:
364d4831
NF
4190 if (insn_bytes == 2)
4191 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4192 tcg_temp_free(t0);
4193 tcg_temp_free(t1);
6af0bf9c
FB
4194}
4195
7a387fff
TS
4196/* special3 bitfield operations */
4197static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4198 int rs, int lsb, int msb)
7a387fff 4199{
a7812ae4
PB
4200 TCGv t0 = tcg_temp_new();
4201 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4202
4203 gen_load_gpr(t1, rs);
7a387fff
TS
4204 switch (opc) {
4205 case OPC_EXT:
4206 if (lsb + msb > 31)
4207 goto fail;
505ad7c2
AJ
4208 tcg_gen_shri_tl(t0, t1, lsb);
4209 if (msb != 31) {
4210 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4211 } else {
4212 tcg_gen_ext32s_tl(t0, t0);
4213 }
7a387fff 4214 break;
c6d6dd7c 4215#if defined(TARGET_MIPS64)
7a387fff 4216 case OPC_DEXTM:
505ad7c2
AJ
4217 tcg_gen_shri_tl(t0, t1, lsb);
4218 if (msb != 31) {
4219 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4220 }
7a387fff
TS
4221 break;
4222 case OPC_DEXTU:
505ad7c2
AJ
4223 tcg_gen_shri_tl(t0, t1, lsb + 32);
4224 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4225 break;
4226 case OPC_DEXT:
505ad7c2
AJ
4227 tcg_gen_shri_tl(t0, t1, lsb);
4228 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4229 break;
c6d6dd7c 4230#endif
7a387fff
TS
4231 case OPC_INS:
4232 if (lsb > msb)
4233 goto fail;
6c5c1e20 4234 gen_load_gpr(t0, rt);
e0d002f1 4235 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4236 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4237 break;
c6d6dd7c 4238#if defined(TARGET_MIPS64)
7a387fff 4239 case OPC_DINSM:
6c5c1e20 4240 gen_load_gpr(t0, rt);
e0d002f1 4241 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4242 break;
4243 case OPC_DINSU:
6c5c1e20 4244 gen_load_gpr(t0, rt);
e0d002f1 4245 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4246 break;
4247 case OPC_DINS:
6c5c1e20 4248 gen_load_gpr(t0, rt);
e0d002f1 4249 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4250 break;
c6d6dd7c 4251#endif
7a387fff
TS
4252 default:
4253fail:
4254 MIPS_INVAL("bitops");
4255 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4256 tcg_temp_free(t0);
4257 tcg_temp_free(t1);
7a387fff
TS
4258 return;
4259 }
6c5c1e20
TS
4260 gen_store_gpr(t0, rt);
4261 tcg_temp_free(t0);
4262 tcg_temp_free(t1);
7a387fff
TS
4263}
4264
49bcf33c
AJ
4265static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4266{
3a55fa47 4267 TCGv t0;
49bcf33c 4268
3a55fa47
AJ
4269 if (rd == 0) {
4270 /* If no destination, treat it as a NOP. */
4271 MIPS_DEBUG("NOP");
4272 return;
4273 }
4274
4275 t0 = tcg_temp_new();
4276 gen_load_gpr(t0, rt);
49bcf33c
AJ
4277 switch (op2) {
4278 case OPC_WSBH:
3a55fa47
AJ
4279 {
4280 TCGv t1 = tcg_temp_new();
4281
4282 tcg_gen_shri_tl(t1, t0, 8);
4283 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4284 tcg_gen_shli_tl(t0, t0, 8);
4285 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4286 tcg_gen_or_tl(t0, t0, t1);
4287 tcg_temp_free(t1);
4288 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4289 }
49bcf33c
AJ
4290 break;
4291 case OPC_SEB:
3a55fa47 4292 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4293 break;
4294 case OPC_SEH:
3a55fa47 4295 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4296 break;
4297#if defined(TARGET_MIPS64)
4298 case OPC_DSBH:
3a55fa47
AJ
4299 {
4300 TCGv t1 = tcg_temp_new();
4301
4302 tcg_gen_shri_tl(t1, t0, 8);
4303 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4304 tcg_gen_shli_tl(t0, t0, 8);
4305 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4306 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4307 tcg_temp_free(t1);
4308 }
49bcf33c
AJ
4309 break;
4310 case OPC_DSHD:
3a55fa47
AJ
4311 {
4312 TCGv t1 = tcg_temp_new();
4313
4314 tcg_gen_shri_tl(t1, t0, 16);
4315 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4316 tcg_gen_shli_tl(t0, t0, 16);
4317 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4318 tcg_gen_or_tl(t0, t0, t1);
4319 tcg_gen_shri_tl(t1, t0, 32);
4320 tcg_gen_shli_tl(t0, t0, 32);
4321 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4322 tcg_temp_free(t1);
4323 }
49bcf33c
AJ
4324 break;
4325#endif
4326 default:
4327 MIPS_INVAL("bsfhl");
4328 generate_exception(ctx, EXCP_RI);
4329 tcg_temp_free(t0);
49bcf33c
AJ
4330 return;
4331 }
49bcf33c 4332 tcg_temp_free(t0);
49bcf33c
AJ
4333}
4334
f1aa6320 4335#ifndef CONFIG_USER_ONLY
0eaef5aa 4336/* CP0 (MMU and control) */
d9bea114 4337static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4338{
d9bea114 4339 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4340
d9bea114
AJ
4341 tcg_gen_ld_i32(t0, cpu_env, off);
4342 tcg_gen_ext_i32_tl(arg, t0);
4343 tcg_temp_free_i32(t0);
4f57689a
TS
4344}
4345
d9bea114 4346static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4347{
d9bea114
AJ
4348 tcg_gen_ld_tl(arg, cpu_env, off);
4349 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4350}
4351
d9bea114 4352static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4353{
d9bea114 4354 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4355
d9bea114
AJ
4356 tcg_gen_trunc_tl_i32(t0, arg);
4357 tcg_gen_st_i32(t0, cpu_env, off);
4358 tcg_temp_free_i32(t0);
f1aa6320
TS
4359}
4360
d9bea114 4361static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4362{
d9bea114
AJ
4363 tcg_gen_ext32s_tl(arg, arg);
4364 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4365}
4366
d75c135e 4367static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4368{
7a387fff 4369 const char *rn = "invalid";
873eb012 4370
e189e748 4371 if (sel != 0)
d75c135e 4372 check_insn(ctx, ISA_MIPS32);
e189e748 4373
873eb012
TS
4374 switch (reg) {
4375 case 0:
7a387fff
TS
4376 switch (sel) {
4377 case 0:
7db13fae 4378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4379 rn = "Index";
4380 break;
4381 case 1:
d75c135e 4382 check_insn(ctx, ASE_MT);
895c2d04 4383 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4384 rn = "MVPControl";
ead9360e 4385 break;
7a387fff 4386 case 2:
d75c135e 4387 check_insn(ctx, ASE_MT);
895c2d04 4388 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4389 rn = "MVPConf0";
ead9360e 4390 break;
7a387fff 4391 case 3:
d75c135e 4392 check_insn(ctx, ASE_MT);
895c2d04 4393 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4394 rn = "MVPConf1";
ead9360e 4395 break;
7a387fff
TS
4396 default:
4397 goto die;
4398 }
873eb012
TS
4399 break;
4400 case 1:
7a387fff
TS
4401 switch (sel) {
4402 case 0:
895c2d04 4403 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4404 rn = "Random";
2423f660 4405 break;
7a387fff 4406 case 1:
d75c135e 4407 check_insn(ctx, ASE_MT);
7db13fae 4408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4409 rn = "VPEControl";
ead9360e 4410 break;
7a387fff 4411 case 2:
d75c135e 4412 check_insn(ctx, ASE_MT);
7db13fae 4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4414 rn = "VPEConf0";
ead9360e 4415 break;
7a387fff 4416 case 3:
d75c135e 4417 check_insn(ctx, ASE_MT);
7db13fae 4418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4419 rn = "VPEConf1";
ead9360e 4420 break;
7a387fff 4421 case 4:
d75c135e 4422 check_insn(ctx, ASE_MT);
7db13fae 4423 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4424 rn = "YQMask";
ead9360e 4425 break;
7a387fff 4426 case 5:
d75c135e 4427 check_insn(ctx, ASE_MT);
7db13fae 4428 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4429 rn = "VPESchedule";
ead9360e 4430 break;
7a387fff 4431 case 6:
d75c135e 4432 check_insn(ctx, ASE_MT);
7db13fae 4433 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4434 rn = "VPEScheFBack";
ead9360e 4435 break;
7a387fff 4436 case 7:
d75c135e 4437 check_insn(ctx, ASE_MT);
7db13fae 4438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4439 rn = "VPEOpt";
ead9360e 4440 break;
7a387fff
TS
4441 default:
4442 goto die;
4443 }
873eb012
TS
4444 break;
4445 case 2:
7a387fff
TS
4446 switch (sel) {
4447 case 0:
7db13fae 4448 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4449 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4450 rn = "EntryLo0";
4451 break;
7a387fff 4452 case 1:
d75c135e 4453 check_insn(ctx, ASE_MT);
895c2d04 4454 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4455 rn = "TCStatus";
ead9360e 4456 break;
7a387fff 4457 case 2:
d75c135e 4458 check_insn(ctx, ASE_MT);
895c2d04 4459 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4460 rn = "TCBind";
ead9360e 4461 break;
7a387fff 4462 case 3:
d75c135e 4463 check_insn(ctx, ASE_MT);
895c2d04 4464 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4465 rn = "TCRestart";
ead9360e 4466 break;
7a387fff 4467 case 4:
d75c135e 4468 check_insn(ctx, ASE_MT);
895c2d04 4469 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4470 rn = "TCHalt";
ead9360e 4471 break;
7a387fff 4472 case 5:
d75c135e 4473 check_insn(ctx, ASE_MT);
895c2d04 4474 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4475 rn = "TCContext";
ead9360e 4476 break;
7a387fff 4477 case 6:
d75c135e 4478 check_insn(ctx, ASE_MT);
895c2d04 4479 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4480 rn = "TCSchedule";
ead9360e 4481 break;
7a387fff 4482 case 7:
d75c135e 4483 check_insn(ctx, ASE_MT);
895c2d04 4484 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4485 rn = "TCScheFBack";
ead9360e 4486 break;
7a387fff
TS
4487 default:
4488 goto die;
4489 }
873eb012
TS
4490 break;
4491 case 3:
7a387fff
TS
4492 switch (sel) {
4493 case 0:
7db13fae 4494 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4495 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4496 rn = "EntryLo1";
4497 break;
7a387fff
TS
4498 default:
4499 goto die;
1579a72e 4500 }
873eb012
TS
4501 break;
4502 case 4:
7a387fff
TS
4503 switch (sel) {
4504 case 0:
7db13fae 4505 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4506 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4507 rn = "Context";
4508 break;
7a387fff 4509 case 1:
d9bea114 4510// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 4511 rn = "ContextConfig";
d279279e 4512 goto die;
2423f660 4513// break;
d279279e
PJ
4514 case 2:
4515 if (ctx->ulri) {
4516 tcg_gen_ld32s_tl(arg, cpu_env,
4517 offsetof(CPUMIPSState,
4518 active_tc.CP0_UserLocal));
4519 rn = "UserLocal";
4520 } else {
4521 tcg_gen_movi_tl(arg, 0);
4522 }
4523 break;
7a387fff
TS
4524 default:
4525 goto die;
1579a72e 4526 }
873eb012
TS
4527 break;
4528 case 5:
7a387fff
TS
4529 switch (sel) {
4530 case 0:
7db13fae 4531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4532 rn = "PageMask";
4533 break;
7a387fff 4534 case 1:
d75c135e 4535 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4537 rn = "PageGrain";
4538 break;
7a387fff
TS
4539 default:
4540 goto die;
1579a72e 4541 }
873eb012
TS
4542 break;
4543 case 6:
7a387fff
TS
4544 switch (sel) {
4545 case 0:
7db13fae 4546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4547 rn = "Wired";
4548 break;
7a387fff 4549 case 1:
d75c135e 4550 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4552 rn = "SRSConf0";
ead9360e 4553 break;
7a387fff 4554 case 2:
d75c135e 4555 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4557 rn = "SRSConf1";
ead9360e 4558 break;
7a387fff 4559 case 3:
d75c135e 4560 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4561 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4562 rn = "SRSConf2";
ead9360e 4563 break;
7a387fff 4564 case 4:
d75c135e 4565 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4567 rn = "SRSConf3";
ead9360e 4568 break;
7a387fff 4569 case 5:
d75c135e 4570 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4571 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4572 rn = "SRSConf4";
ead9360e 4573 break;
7a387fff
TS
4574 default:
4575 goto die;
1579a72e 4576 }
873eb012 4577 break;
8c0fdd85 4578 case 7:
7a387fff
TS
4579 switch (sel) {
4580 case 0:
d75c135e 4581 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4582 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4583 rn = "HWREna";
4584 break;
7a387fff
TS
4585 default:
4586 goto die;
1579a72e 4587 }
8c0fdd85 4588 break;
873eb012 4589 case 8:
7a387fff
TS
4590 switch (sel) {
4591 case 0:
7db13fae 4592 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4593 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4594 rn = "BadVAddr";
2423f660 4595 break;
7a387fff
TS
4596 default:
4597 goto die;
4598 }
873eb012
TS
4599 break;
4600 case 9:
7a387fff
TS
4601 switch (sel) {
4602 case 0:
2e70f6ef
PB
4603 /* Mark as an IO operation because we read the time. */
4604 if (use_icount)
4605 gen_io_start();
895c2d04 4606 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4607 if (use_icount) {
4608 gen_io_end();
2e70f6ef 4609 }
55807224
EI
4610 /* Break the TB to be able to take timer interrupts immediately
4611 after reading count. */
4612 ctx->bstate = BS_STOP;
2423f660
TS
4613 rn = "Count";
4614 break;
4615 /* 6,7 are implementation dependent */
7a387fff
TS
4616 default:
4617 goto die;
2423f660 4618 }
873eb012
TS
4619 break;
4620 case 10:
7a387fff
TS
4621 switch (sel) {
4622 case 0:
7db13fae 4623 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4624 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4625 rn = "EntryHi";
4626 break;
7a387fff
TS
4627 default:
4628 goto die;
1579a72e 4629 }
873eb012
TS
4630 break;
4631 case 11:
7a387fff
TS
4632 switch (sel) {
4633 case 0:
7db13fae 4634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4635 rn = "Compare";
4636 break;
4637 /* 6,7 are implementation dependent */
7a387fff
TS
4638 default:
4639 goto die;
2423f660 4640 }
873eb012
TS
4641 break;
4642 case 12:
7a387fff
TS
4643 switch (sel) {
4644 case 0:
7db13fae 4645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4646 rn = "Status";
4647 break;
7a387fff 4648 case 1:
d75c135e 4649 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4651 rn = "IntCtl";
4652 break;
7a387fff 4653 case 2:
d75c135e 4654 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4655 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4656 rn = "SRSCtl";
4657 break;
7a387fff 4658 case 3:
d75c135e 4659 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4660 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4661 rn = "SRSMap";
fd88b6ab 4662 break;
7a387fff
TS
4663 default:
4664 goto die;
4665 }
873eb012
TS
4666 break;
4667 case 13:
7a387fff
TS
4668 switch (sel) {
4669 case 0:
7db13fae 4670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4671 rn = "Cause";
4672 break;
7a387fff
TS
4673 default:
4674 goto die;
4675 }
873eb012
TS
4676 break;
4677 case 14:
7a387fff
TS
4678 switch (sel) {
4679 case 0:
7db13fae 4680 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4681 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4682 rn = "EPC";
4683 break;
7a387fff
TS
4684 default:
4685 goto die;
1579a72e 4686 }
873eb012
TS
4687 break;
4688 case 15:
7a387fff
TS
4689 switch (sel) {
4690 case 0:
7db13fae 4691 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4692 rn = "PRid";
4693 break;
7a387fff 4694 case 1:
d75c135e 4695 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4696 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4697 rn = "EBase";
4698 break;
7a387fff
TS
4699 default:
4700 goto die;
4701 }
873eb012
TS
4702 break;
4703 case 16:
4704 switch (sel) {
4705 case 0:
7db13fae 4706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4707 rn = "Config";
4708 break;
4709 case 1:
7db13fae 4710 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4711 rn = "Config1";
4712 break;
7a387fff 4713 case 2:
7db13fae 4714 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4715 rn = "Config2";
4716 break;
4717 case 3:
7db13fae 4718 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4719 rn = "Config3";
4720 break;
b4160af1
PJ
4721 case 4:
4722 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4723 rn = "Config4";
4724 break;
b4dd99a3
PJ
4725 case 5:
4726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4727 rn = "Config5";
4728 break;
e397ee33
TS
4729 /* 6,7 are implementation dependent */
4730 case 6:
7db13fae 4731 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4732 rn = "Config6";
4733 break;
4734 case 7:
7db13fae 4735 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4736 rn = "Config7";
4737 break;
873eb012 4738 default:
873eb012
TS
4739 goto die;
4740 }
4741 break;
4742 case 17:
7a387fff
TS
4743 switch (sel) {
4744 case 0:
895c2d04 4745 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4746 rn = "LLAddr";
4747 break;
7a387fff
TS
4748 default:
4749 goto die;
4750 }
873eb012
TS
4751 break;
4752 case 18:
7a387fff 4753 switch (sel) {
fd88b6ab 4754 case 0 ... 7:
895c2d04 4755 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4756 rn = "WatchLo";
4757 break;
7a387fff
TS
4758 default:
4759 goto die;
4760 }
873eb012
TS
4761 break;
4762 case 19:
7a387fff 4763 switch (sel) {
fd88b6ab 4764 case 0 ...7:
895c2d04 4765 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4766 rn = "WatchHi";
4767 break;
7a387fff
TS
4768 default:
4769 goto die;
4770 }
873eb012 4771 break;
8c0fdd85 4772 case 20:
7a387fff
TS
4773 switch (sel) {
4774 case 0:
d26bc211 4775#if defined(TARGET_MIPS64)
d75c135e 4776 check_insn(ctx, ISA_MIPS3);
7db13fae 4777 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4778 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4779 rn = "XContext";
4780 break;
703eaf37 4781#endif
7a387fff
TS
4782 default:
4783 goto die;
4784 }
8c0fdd85
TS
4785 break;
4786 case 21:
7a387fff
TS
4787 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4788 switch (sel) {
4789 case 0:
7db13fae 4790 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4791 rn = "Framemask";
4792 break;
7a387fff
TS
4793 default:
4794 goto die;
4795 }
8c0fdd85
TS
4796 break;
4797 case 22:
d9bea114 4798 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4799 rn = "'Diagnostic"; /* implementation dependent */
4800 break;
873eb012 4801 case 23:
7a387fff
TS
4802 switch (sel) {
4803 case 0:
895c2d04 4804 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4805 rn = "Debug";
4806 break;
7a387fff 4807 case 1:
d9bea114 4808// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4809 rn = "TraceControl";
4810// break;
7a387fff 4811 case 2:
d9bea114 4812// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4813 rn = "TraceControl2";
4814// break;
7a387fff 4815 case 3:
d9bea114 4816// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4817 rn = "UserTraceData";
4818// break;
7a387fff 4819 case 4:
d9bea114 4820// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4821 rn = "TraceBPC";
4822// break;
7a387fff
TS
4823 default:
4824 goto die;
4825 }
873eb012
TS
4826 break;
4827 case 24:
7a387fff
TS
4828 switch (sel) {
4829 case 0:
f0b3f3ae 4830 /* EJTAG support */
7db13fae 4831 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4832 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4833 rn = "DEPC";
4834 break;
7a387fff
TS
4835 default:
4836 goto die;
4837 }
873eb012 4838 break;
8c0fdd85 4839 case 25:
7a387fff
TS
4840 switch (sel) {
4841 case 0:
7db13fae 4842 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4843 rn = "Performance0";
7a387fff
TS
4844 break;
4845 case 1:
d9bea114 4846// gen_helper_mfc0_performance1(arg);
2423f660
TS
4847 rn = "Performance1";
4848// break;
7a387fff 4849 case 2:
d9bea114 4850// gen_helper_mfc0_performance2(arg);
2423f660
TS
4851 rn = "Performance2";
4852// break;
7a387fff 4853 case 3:
d9bea114 4854// gen_helper_mfc0_performance3(arg);
2423f660
TS
4855 rn = "Performance3";
4856// break;
7a387fff 4857 case 4:
d9bea114 4858// gen_helper_mfc0_performance4(arg);
2423f660
TS
4859 rn = "Performance4";
4860// break;
7a387fff 4861 case 5:
d9bea114 4862// gen_helper_mfc0_performance5(arg);
2423f660
TS
4863 rn = "Performance5";
4864// break;
7a387fff 4865 case 6:
d9bea114 4866// gen_helper_mfc0_performance6(arg);
2423f660
TS
4867 rn = "Performance6";
4868// break;
7a387fff 4869 case 7:
d9bea114 4870// gen_helper_mfc0_performance7(arg);
2423f660
TS
4871 rn = "Performance7";
4872// break;
7a387fff
TS
4873 default:
4874 goto die;
4875 }
8c0fdd85
TS
4876 break;
4877 case 26:
d9bea114 4878 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4879 rn = "ECC";
4880 break;
8c0fdd85 4881 case 27:
7a387fff 4882 switch (sel) {
7a387fff 4883 case 0 ... 3:
d9bea114 4884 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4885 rn = "CacheErr";
4886 break;
7a387fff
TS
4887 default:
4888 goto die;
4889 }
8c0fdd85 4890 break;
873eb012
TS
4891 case 28:
4892 switch (sel) {
4893 case 0:
7a387fff
TS
4894 case 2:
4895 case 4:
4896 case 6:
7db13fae 4897 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4898 rn = "TagLo";
4899 break;
4900 case 1:
7a387fff
TS
4901 case 3:
4902 case 5:
4903 case 7:
7db13fae 4904 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4905 rn = "DataLo";
4906 break;
4907 default:
873eb012
TS
4908 goto die;
4909 }
4910 break;
8c0fdd85 4911 case 29:
7a387fff
TS
4912 switch (sel) {
4913 case 0:
4914 case 2:
4915 case 4:
4916 case 6:
7db13fae 4917 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4918 rn = "TagHi";
4919 break;
4920 case 1:
4921 case 3:
4922 case 5:
4923 case 7:
7db13fae 4924 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4925 rn = "DataHi";
4926 break;
4927 default:
4928 goto die;
4929 }
8c0fdd85 4930 break;
873eb012 4931 case 30:
7a387fff
TS
4932 switch (sel) {
4933 case 0:
7db13fae 4934 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4935 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4936 rn = "ErrorEPC";
4937 break;
7a387fff
TS
4938 default:
4939 goto die;
4940 }
873eb012
TS
4941 break;
4942 case 31:
7a387fff
TS
4943 switch (sel) {
4944 case 0:
f0b3f3ae 4945 /* EJTAG support */
7db13fae 4946 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4947 rn = "DESAVE";
4948 break;
7a387fff
TS
4949 default:
4950 goto die;
4951 }
873eb012
TS
4952 break;
4953 default:
873eb012
TS
4954 goto die;
4955 }
2abf314d 4956 (void)rn; /* avoid a compiler warning */
d12d51d5 4957 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4958 return;
4959
4960die:
d12d51d5 4961 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4962 generate_exception(ctx, EXCP_RI);
4963}
4964
d75c135e 4965static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4966{
7a387fff
TS
4967 const char *rn = "invalid";
4968
e189e748 4969 if (sel != 0)
d75c135e 4970 check_insn(ctx, ISA_MIPS32);
e189e748 4971
2e70f6ef
PB
4972 if (use_icount)
4973 gen_io_start();
4974
8c0fdd85
TS
4975 switch (reg) {
4976 case 0:
7a387fff
TS
4977 switch (sel) {
4978 case 0:
895c2d04 4979 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4980 rn = "Index";
4981 break;
4982 case 1:
d75c135e 4983 check_insn(ctx, ASE_MT);
895c2d04 4984 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4985 rn = "MVPControl";
ead9360e 4986 break;
7a387fff 4987 case 2:
d75c135e 4988 check_insn(ctx, ASE_MT);
ead9360e 4989 /* ignored */
7a387fff 4990 rn = "MVPConf0";
ead9360e 4991 break;
7a387fff 4992 case 3:
d75c135e 4993 check_insn(ctx, ASE_MT);
ead9360e 4994 /* ignored */
7a387fff 4995 rn = "MVPConf1";
ead9360e 4996 break;
7a387fff
TS
4997 default:
4998 goto die;
4999 }
8c0fdd85
TS
5000 break;
5001 case 1:
7a387fff
TS
5002 switch (sel) {
5003 case 0:
2423f660 5004 /* ignored */
7a387fff 5005 rn = "Random";
2423f660 5006 break;
7a387fff 5007 case 1:
d75c135e 5008 check_insn(ctx, ASE_MT);
895c2d04 5009 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5010 rn = "VPEControl";
ead9360e 5011 break;
7a387fff 5012 case 2:
d75c135e 5013 check_insn(ctx, ASE_MT);
895c2d04 5014 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5015 rn = "VPEConf0";
ead9360e 5016 break;
7a387fff 5017 case 3:
d75c135e 5018 check_insn(ctx, ASE_MT);
895c2d04 5019 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5020 rn = "VPEConf1";
ead9360e 5021 break;
7a387fff 5022 case 4:
d75c135e 5023 check_insn(ctx, ASE_MT);
895c2d04 5024 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5025 rn = "YQMask";
ead9360e 5026 break;
7a387fff 5027 case 5:
d75c135e 5028 check_insn(ctx, ASE_MT);
7db13fae 5029 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5030 rn = "VPESchedule";
ead9360e 5031 break;
7a387fff 5032 case 6:
d75c135e 5033 check_insn(ctx, ASE_MT);
7db13fae 5034 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5035 rn = "VPEScheFBack";
ead9360e 5036 break;
7a387fff 5037 case 7:
d75c135e 5038 check_insn(ctx, ASE_MT);
895c2d04 5039 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5040 rn = "VPEOpt";
ead9360e 5041 break;
7a387fff
TS
5042 default:
5043 goto die;
5044 }
8c0fdd85
TS
5045 break;
5046 case 2:
7a387fff
TS
5047 switch (sel) {
5048 case 0:
895c2d04 5049 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5050 rn = "EntryLo0";
5051 break;
7a387fff 5052 case 1:
d75c135e 5053 check_insn(ctx, ASE_MT);
895c2d04 5054 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5055 rn = "TCStatus";
ead9360e 5056 break;
7a387fff 5057 case 2:
d75c135e 5058 check_insn(ctx, ASE_MT);
895c2d04 5059 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5060 rn = "TCBind";
ead9360e 5061 break;
7a387fff 5062 case 3:
d75c135e 5063 check_insn(ctx, ASE_MT);
895c2d04 5064 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5065 rn = "TCRestart";
ead9360e 5066 break;
7a387fff 5067 case 4:
d75c135e 5068 check_insn(ctx, ASE_MT);
895c2d04 5069 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5070 rn = "TCHalt";
ead9360e 5071 break;
7a387fff 5072 case 5:
d75c135e 5073 check_insn(ctx, ASE_MT);
895c2d04 5074 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5075 rn = "TCContext";
ead9360e 5076 break;
7a387fff 5077 case 6:
d75c135e 5078 check_insn(ctx, ASE_MT);
895c2d04 5079 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5080 rn = "TCSchedule";
ead9360e 5081 break;
7a387fff 5082 case 7:
d75c135e 5083 check_insn(ctx, ASE_MT);
895c2d04 5084 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5085 rn = "TCScheFBack";
ead9360e 5086 break;
7a387fff
TS
5087 default:
5088 goto die;
5089 }
8c0fdd85
TS
5090 break;
5091 case 3:
7a387fff
TS
5092 switch (sel) {
5093 case 0:
895c2d04 5094 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5095 rn = "EntryLo1";
5096 break;
7a387fff
TS
5097 default:
5098 goto die;
876d4b07 5099 }
8c0fdd85
TS
5100 break;
5101 case 4:
7a387fff
TS
5102 switch (sel) {
5103 case 0:
895c2d04 5104 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5105 rn = "Context";
5106 break;
7a387fff 5107 case 1:
895c2d04 5108// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5109 rn = "ContextConfig";
d279279e 5110 goto die;
2423f660 5111// break;
d279279e
PJ
5112 case 2:
5113 if (ctx->ulri) {
5114 tcg_gen_st_tl(arg, cpu_env,
5115 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5116 rn = "UserLocal";
5117 }
5118 break;
7a387fff
TS
5119 default:
5120 goto die;
876d4b07 5121 }
8c0fdd85
TS
5122 break;
5123 case 5:
7a387fff
TS
5124 switch (sel) {
5125 case 0:
895c2d04 5126 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5127 rn = "PageMask";
5128 break;
7a387fff 5129 case 1:
d75c135e 5130 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5131 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5132 rn = "PageGrain";
5133 break;
7a387fff
TS
5134 default:
5135 goto die;
876d4b07 5136 }
8c0fdd85
TS
5137 break;
5138 case 6:
7a387fff
TS
5139 switch (sel) {
5140 case 0:
895c2d04 5141 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5142 rn = "Wired";
5143 break;
7a387fff 5144 case 1:
d75c135e 5145 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5146 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5147 rn = "SRSConf0";
ead9360e 5148 break;
7a387fff 5149 case 2:
d75c135e 5150 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5151 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5152 rn = "SRSConf1";
ead9360e 5153 break;
7a387fff 5154 case 3:
d75c135e 5155 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5156 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5157 rn = "SRSConf2";
ead9360e 5158 break;
7a387fff 5159 case 4:
d75c135e 5160 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5161 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5162 rn = "SRSConf3";
ead9360e 5163 break;
7a387fff 5164 case 5:
d75c135e 5165 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5166 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5167 rn = "SRSConf4";
ead9360e 5168 break;
7a387fff
TS
5169 default:
5170 goto die;
876d4b07 5171 }
8c0fdd85
TS
5172 break;
5173 case 7:
7a387fff
TS
5174 switch (sel) {
5175 case 0:
d75c135e 5176 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5177 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5178 ctx->bstate = BS_STOP;
2423f660
TS
5179 rn = "HWREna";
5180 break;
7a387fff
TS
5181 default:
5182 goto die;
876d4b07 5183 }
8c0fdd85
TS
5184 break;
5185 case 8:
7a387fff 5186 /* ignored */
f0b3f3ae 5187 rn = "BadVAddr";
8c0fdd85
TS
5188 break;
5189 case 9:
7a387fff
TS
5190 switch (sel) {
5191 case 0:
895c2d04 5192 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5193 rn = "Count";
5194 break;
876d4b07 5195 /* 6,7 are implementation dependent */
7a387fff
TS
5196 default:
5197 goto die;
876d4b07 5198 }
8c0fdd85
TS
5199 break;
5200 case 10:
7a387fff
TS
5201 switch (sel) {
5202 case 0:
895c2d04 5203 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5204 rn = "EntryHi";
5205 break;
7a387fff
TS
5206 default:
5207 goto die;
876d4b07 5208 }
8c0fdd85
TS
5209 break;
5210 case 11:
7a387fff
TS
5211 switch (sel) {
5212 case 0:
895c2d04 5213 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5214 rn = "Compare";
5215 break;
5216 /* 6,7 are implementation dependent */
7a387fff
TS
5217 default:
5218 goto die;
876d4b07 5219 }
8c0fdd85
TS
5220 break;
5221 case 12:
7a387fff
TS
5222 switch (sel) {
5223 case 0:
867abc7e 5224 save_cpu_state(ctx, 1);
895c2d04 5225 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5226 /* BS_STOP isn't good enough here, hflags may have changed. */
5227 gen_save_pc(ctx->pc + 4);
5228 ctx->bstate = BS_EXCP;
2423f660
TS
5229 rn = "Status";
5230 break;
7a387fff 5231 case 1:
d75c135e 5232 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5233 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5234 /* Stop translation as we may have switched the execution mode */
5235 ctx->bstate = BS_STOP;
2423f660
TS
5236 rn = "IntCtl";
5237 break;
7a387fff 5238 case 2:
d75c135e 5239 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5240 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5241 /* Stop translation as we may have switched the execution mode */
5242 ctx->bstate = BS_STOP;
2423f660
TS
5243 rn = "SRSCtl";
5244 break;
7a387fff 5245 case 3:
d75c135e 5246 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5247 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5248 /* Stop translation as we may have switched the execution mode */
5249 ctx->bstate = BS_STOP;
2423f660 5250 rn = "SRSMap";
fd88b6ab 5251 break;
7a387fff
TS
5252 default:
5253 goto die;
876d4b07 5254 }
8c0fdd85
TS
5255 break;
5256 case 13:
7a387fff
TS
5257 switch (sel) {
5258 case 0:
867abc7e 5259 save_cpu_state(ctx, 1);
895c2d04 5260 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5261 rn = "Cause";
5262 break;
7a387fff
TS
5263 default:
5264 goto die;
876d4b07 5265 }
8c0fdd85
TS
5266 break;
5267 case 14:
7a387fff
TS
5268 switch (sel) {
5269 case 0:
7db13fae 5270 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5271 rn = "EPC";
5272 break;
7a387fff
TS
5273 default:
5274 goto die;
876d4b07 5275 }
8c0fdd85
TS
5276 break;
5277 case 15:
7a387fff
TS
5278 switch (sel) {
5279 case 0:
2423f660
TS
5280 /* ignored */
5281 rn = "PRid";
5282 break;
7a387fff 5283 case 1:
d75c135e 5284 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5285 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5286 rn = "EBase";
5287 break;
7a387fff
TS
5288 default:
5289 goto die;
1579a72e 5290 }
8c0fdd85
TS
5291 break;
5292 case 16:
5293 switch (sel) {
5294 case 0:
895c2d04 5295 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5296 rn = "Config";
2423f660
TS
5297 /* Stop translation as we may have switched the execution mode */
5298 ctx->bstate = BS_STOP;
7a387fff
TS
5299 break;
5300 case 1:
e397ee33 5301 /* ignored, read only */
7a387fff
TS
5302 rn = "Config1";
5303 break;
5304 case 2:
895c2d04 5305 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5306 rn = "Config2";
2423f660
TS
5307 /* Stop translation as we may have switched the execution mode */
5308 ctx->bstate = BS_STOP;
8c0fdd85 5309 break;
7a387fff 5310 case 3:
e397ee33 5311 /* ignored, read only */
7a387fff
TS
5312 rn = "Config3";
5313 break;
b4160af1
PJ
5314 case 4:
5315 gen_helper_mtc0_config4(cpu_env, arg);
5316 rn = "Config4";
5317 ctx->bstate = BS_STOP;
5318 break;
b4dd99a3
PJ
5319 case 5:
5320 gen_helper_mtc0_config5(cpu_env, arg);
5321 rn = "Config5";
5322 /* Stop translation as we may have switched the execution mode */
5323 ctx->bstate = BS_STOP;
5324 break;
e397ee33
TS
5325 /* 6,7 are implementation dependent */
5326 case 6:
5327 /* ignored */
5328 rn = "Config6";
5329 break;
5330 case 7:
5331 /* ignored */
5332 rn = "Config7";
5333 break;
8c0fdd85
TS
5334 default:
5335 rn = "Invalid config selector";
5336 goto die;
5337 }
5338 break;
5339 case 17:
7a387fff
TS
5340 switch (sel) {
5341 case 0:
895c2d04 5342 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5343 rn = "LLAddr";
5344 break;
7a387fff
TS
5345 default:
5346 goto die;
5347 }
8c0fdd85
TS
5348 break;
5349 case 18:
7a387fff 5350 switch (sel) {
fd88b6ab 5351 case 0 ... 7:
895c2d04 5352 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5353 rn = "WatchLo";
5354 break;
7a387fff
TS
5355 default:
5356 goto die;
5357 }
8c0fdd85
TS
5358 break;
5359 case 19:
7a387fff 5360 switch (sel) {
fd88b6ab 5361 case 0 ... 7:
895c2d04 5362 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5363 rn = "WatchHi";
5364 break;
7a387fff
TS
5365 default:
5366 goto die;
5367 }
8c0fdd85
TS
5368 break;
5369 case 20:
7a387fff
TS
5370 switch (sel) {
5371 case 0:
d26bc211 5372#if defined(TARGET_MIPS64)
d75c135e 5373 check_insn(ctx, ISA_MIPS3);
895c2d04 5374 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5375 rn = "XContext";
5376 break;
703eaf37 5377#endif
7a387fff
TS
5378 default:
5379 goto die;
5380 }
8c0fdd85
TS
5381 break;
5382 case 21:
7a387fff
TS
5383 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5384 switch (sel) {
5385 case 0:
895c2d04 5386 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5387 rn = "Framemask";
5388 break;
7a387fff
TS
5389 default:
5390 goto die;
5391 }
5392 break;
8c0fdd85 5393 case 22:
7a387fff
TS
5394 /* ignored */
5395 rn = "Diagnostic"; /* implementation dependent */
2423f660 5396 break;
8c0fdd85 5397 case 23:
7a387fff
TS
5398 switch (sel) {
5399 case 0:
895c2d04 5400 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5401 /* BS_STOP isn't good enough here, hflags may have changed. */
5402 gen_save_pc(ctx->pc + 4);
5403 ctx->bstate = BS_EXCP;
2423f660
TS
5404 rn = "Debug";
5405 break;
7a387fff 5406 case 1:
895c2d04 5407// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5408 rn = "TraceControl";
8487327a
TS
5409 /* Stop translation as we may have switched the execution mode */
5410 ctx->bstate = BS_STOP;
2423f660 5411// break;
7a387fff 5412 case 2:
895c2d04 5413// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5414 rn = "TraceControl2";
8487327a
TS
5415 /* Stop translation as we may have switched the execution mode */
5416 ctx->bstate = BS_STOP;
2423f660 5417// break;
7a387fff 5418 case 3:
8487327a
TS
5419 /* Stop translation as we may have switched the execution mode */
5420 ctx->bstate = BS_STOP;
895c2d04 5421// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5422 rn = "UserTraceData";
8487327a
TS
5423 /* Stop translation as we may have switched the execution mode */
5424 ctx->bstate = BS_STOP;
2423f660 5425// break;
7a387fff 5426 case 4:
895c2d04 5427// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5428 /* Stop translation as we may have switched the execution mode */
5429 ctx->bstate = BS_STOP;
2423f660
TS
5430 rn = "TraceBPC";
5431// break;
7a387fff
TS
5432 default:
5433 goto die;
5434 }
8c0fdd85
TS
5435 break;
5436 case 24:
7a387fff
TS
5437 switch (sel) {
5438 case 0:
f1aa6320 5439 /* EJTAG support */
7db13fae 5440 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5441 rn = "DEPC";
5442 break;
7a387fff
TS
5443 default:
5444 goto die;
5445 }
8c0fdd85
TS
5446 break;
5447 case 25:
7a387fff
TS
5448 switch (sel) {
5449 case 0:
895c2d04 5450 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5451 rn = "Performance0";
5452 break;
7a387fff 5453 case 1:
d9bea114 5454// gen_helper_mtc0_performance1(arg);
2423f660
TS
5455 rn = "Performance1";
5456// break;
7a387fff 5457 case 2:
d9bea114 5458// gen_helper_mtc0_performance2(arg);
2423f660
TS
5459 rn = "Performance2";
5460// break;
7a387fff 5461 case 3:
d9bea114 5462// gen_helper_mtc0_performance3(arg);
2423f660
TS
5463 rn = "Performance3";
5464// break;
7a387fff 5465 case 4:
d9bea114 5466// gen_helper_mtc0_performance4(arg);
2423f660
TS
5467 rn = "Performance4";
5468// break;
7a387fff 5469 case 5:
d9bea114 5470// gen_helper_mtc0_performance5(arg);
2423f660
TS
5471 rn = "Performance5";
5472// break;
7a387fff 5473 case 6:
d9bea114 5474// gen_helper_mtc0_performance6(arg);
2423f660
TS
5475 rn = "Performance6";
5476// break;
7a387fff 5477 case 7:
d9bea114 5478// gen_helper_mtc0_performance7(arg);
2423f660
TS
5479 rn = "Performance7";
5480// break;
7a387fff
TS
5481 default:
5482 goto die;
5483 }
8c0fdd85
TS
5484 break;
5485 case 26:
2423f660 5486 /* ignored */
8c0fdd85 5487 rn = "ECC";
2423f660 5488 break;
8c0fdd85 5489 case 27:
7a387fff
TS
5490 switch (sel) {
5491 case 0 ... 3:
2423f660
TS
5492 /* ignored */
5493 rn = "CacheErr";
5494 break;
7a387fff
TS
5495 default:
5496 goto die;
5497 }
8c0fdd85
TS
5498 break;
5499 case 28:
5500 switch (sel) {
5501 case 0:
7a387fff
TS
5502 case 2:
5503 case 4:
5504 case 6:
895c2d04 5505 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5506 rn = "TagLo";
5507 break;
7a387fff
TS
5508 case 1:
5509 case 3:
5510 case 5:
5511 case 7:
895c2d04 5512 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5513 rn = "DataLo";
5514 break;
8c0fdd85 5515 default:
8c0fdd85
TS
5516 goto die;
5517 }
5518 break;
5519 case 29:
7a387fff
TS
5520 switch (sel) {
5521 case 0:
5522 case 2:
5523 case 4:
5524 case 6:
895c2d04 5525 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5526 rn = "TagHi";
5527 break;
5528 case 1:
5529 case 3:
5530 case 5:
5531 case 7:
895c2d04 5532 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5533 rn = "DataHi";
5534 break;
5535 default:
5536 rn = "invalid sel";
5537 goto die;
5538 }
8c0fdd85
TS
5539 break;
5540 case 30:
7a387fff
TS
5541 switch (sel) {
5542 case 0:
7db13fae 5543 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5544 rn = "ErrorEPC";
5545 break;
7a387fff
TS
5546 default:
5547 goto die;
5548 }
8c0fdd85
TS
5549 break;
5550 case 31:
7a387fff
TS
5551 switch (sel) {
5552 case 0:
f1aa6320 5553 /* EJTAG support */
7db13fae 5554 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5555 rn = "DESAVE";
5556 break;
7a387fff
TS
5557 default:
5558 goto die;
5559 }
2423f660
TS
5560 /* Stop translation as we may have switched the execution mode */
5561 ctx->bstate = BS_STOP;
8c0fdd85
TS
5562 break;
5563 default:
8c0fdd85
TS
5564 goto die;
5565 }
2abf314d 5566 (void)rn; /* avoid a compiler warning */
d12d51d5 5567 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5568 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5569 if (use_icount) {
5570 gen_io_end();
5571 ctx->bstate = BS_STOP;
5572 }
8c0fdd85
TS
5573 return;
5574
5575die:
d12d51d5 5576 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5577 generate_exception(ctx, EXCP_RI);
5578}
5579
d26bc211 5580#if defined(TARGET_MIPS64)
d75c135e 5581static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5582{
5583 const char *rn = "invalid";
5584
e189e748 5585 if (sel != 0)
d75c135e 5586 check_insn(ctx, ISA_MIPS64);
e189e748 5587
9c2149c8
TS
5588 switch (reg) {
5589 case 0:
5590 switch (sel) {
5591 case 0:
7db13fae 5592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5593 rn = "Index";
5594 break;
5595 case 1:
d75c135e 5596 check_insn(ctx, ASE_MT);
895c2d04 5597 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5598 rn = "MVPControl";
ead9360e 5599 break;
9c2149c8 5600 case 2:
d75c135e 5601 check_insn(ctx, ASE_MT);
895c2d04 5602 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5603 rn = "MVPConf0";
ead9360e 5604 break;
9c2149c8 5605 case 3:
d75c135e 5606 check_insn(ctx, ASE_MT);
895c2d04 5607 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5608 rn = "MVPConf1";
ead9360e 5609 break;
9c2149c8
TS
5610 default:
5611 goto die;
5612 }
5613 break;
5614 case 1:
5615 switch (sel) {
5616 case 0:
895c2d04 5617 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5618 rn = "Random";
2423f660 5619 break;
9c2149c8 5620 case 1:
d75c135e 5621 check_insn(ctx, ASE_MT);
7db13fae 5622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5623 rn = "VPEControl";
ead9360e 5624 break;
9c2149c8 5625 case 2:
d75c135e 5626 check_insn(ctx, ASE_MT);
7db13fae 5627 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5628 rn = "VPEConf0";
ead9360e 5629 break;
9c2149c8 5630 case 3:
d75c135e 5631 check_insn(ctx, ASE_MT);
7db13fae 5632 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5633 rn = "VPEConf1";
ead9360e 5634 break;
9c2149c8 5635 case 4:
d75c135e 5636 check_insn(ctx, ASE_MT);
7db13fae 5637 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5638 rn = "YQMask";
ead9360e 5639 break;
9c2149c8 5640 case 5:
d75c135e 5641 check_insn(ctx, ASE_MT);
7db13fae 5642 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5643 rn = "VPESchedule";
ead9360e 5644 break;
9c2149c8 5645 case 6:
d75c135e 5646 check_insn(ctx, ASE_MT);
7db13fae 5647 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5648 rn = "VPEScheFBack";
ead9360e 5649 break;
9c2149c8 5650 case 7:
d75c135e 5651 check_insn(ctx, ASE_MT);
7db13fae 5652 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5653 rn = "VPEOpt";
ead9360e 5654 break;
9c2149c8
TS
5655 default:
5656 goto die;
5657 }
5658 break;
5659 case 2:
5660 switch (sel) {
5661 case 0:
7db13fae 5662 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5663 rn = "EntryLo0";
5664 break;
9c2149c8 5665 case 1:
d75c135e 5666 check_insn(ctx, ASE_MT);
895c2d04 5667 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5668 rn = "TCStatus";
ead9360e 5669 break;
9c2149c8 5670 case 2:
d75c135e 5671 check_insn(ctx, ASE_MT);
895c2d04 5672 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5673 rn = "TCBind";
ead9360e 5674 break;
9c2149c8 5675 case 3:
d75c135e 5676 check_insn(ctx, ASE_MT);
895c2d04 5677 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5678 rn = "TCRestart";
ead9360e 5679 break;
9c2149c8 5680 case 4:
d75c135e 5681 check_insn(ctx, ASE_MT);
895c2d04 5682 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5683 rn = "TCHalt";
ead9360e 5684 break;
9c2149c8 5685 case 5:
d75c135e 5686 check_insn(ctx, ASE_MT);
895c2d04 5687 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5688 rn = "TCContext";
ead9360e 5689 break;
9c2149c8 5690 case 6:
d75c135e 5691 check_insn(ctx, ASE_MT);
895c2d04 5692 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5693 rn = "TCSchedule";
ead9360e 5694 break;
9c2149c8 5695 case 7:
d75c135e 5696 check_insn(ctx, ASE_MT);
895c2d04 5697 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5698 rn = "TCScheFBack";
ead9360e 5699 break;
9c2149c8
TS
5700 default:
5701 goto die;
5702 }
5703 break;
5704 case 3:
5705 switch (sel) {
5706 case 0:
7db13fae 5707 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5708 rn = "EntryLo1";
5709 break;
9c2149c8
TS
5710 default:
5711 goto die;
1579a72e 5712 }
9c2149c8
TS
5713 break;
5714 case 4:
5715 switch (sel) {
5716 case 0:
7db13fae 5717 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5718 rn = "Context";
5719 break;
9c2149c8 5720 case 1:
d9bea114 5721// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5722 rn = "ContextConfig";
d279279e 5723 goto die;
2423f660 5724// break;
d279279e
PJ
5725 case 2:
5726 if (ctx->ulri) {
5727 tcg_gen_ld_tl(arg, cpu_env,
5728 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5729 rn = "UserLocal";
5730 } else {
5731 tcg_gen_movi_tl(arg, 0);
5732 }
5733 break;
9c2149c8
TS
5734 default:
5735 goto die;
876d4b07 5736 }
9c2149c8
TS
5737 break;
5738 case 5:
5739 switch (sel) {
5740 case 0:
7db13fae 5741 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5742 rn = "PageMask";
5743 break;
9c2149c8 5744 case 1:
d75c135e 5745 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5746 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5747 rn = "PageGrain";
5748 break;
9c2149c8
TS
5749 default:
5750 goto die;
876d4b07 5751 }
9c2149c8
TS
5752 break;
5753 case 6:
5754 switch (sel) {
5755 case 0:
7db13fae 5756 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5757 rn = "Wired";
5758 break;
9c2149c8 5759 case 1:
d75c135e 5760 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5761 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5762 rn = "SRSConf0";
ead9360e 5763 break;
9c2149c8 5764 case 2:
d75c135e 5765 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5766 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5767 rn = "SRSConf1";
ead9360e 5768 break;
9c2149c8 5769 case 3:
d75c135e 5770 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5771 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5772 rn = "SRSConf2";
ead9360e 5773 break;
9c2149c8 5774 case 4:
d75c135e 5775 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5776 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5777 rn = "SRSConf3";
ead9360e 5778 break;
9c2149c8 5779 case 5:
d75c135e 5780 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5782 rn = "SRSConf4";
ead9360e 5783 break;
9c2149c8
TS
5784 default:
5785 goto die;
876d4b07 5786 }
9c2149c8
TS
5787 break;
5788 case 7:
5789 switch (sel) {
5790 case 0:
d75c135e 5791 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5792 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5793 rn = "HWREna";
5794 break;
9c2149c8
TS
5795 default:
5796 goto die;
876d4b07 5797 }
9c2149c8
TS
5798 break;
5799 case 8:
5800 switch (sel) {
5801 case 0:
7db13fae 5802 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5803 rn = "BadVAddr";
2423f660 5804 break;
9c2149c8
TS
5805 default:
5806 goto die;
876d4b07 5807 }
9c2149c8
TS
5808 break;
5809 case 9:
5810 switch (sel) {
5811 case 0:
2e70f6ef
PB
5812 /* Mark as an IO operation because we read the time. */
5813 if (use_icount)
5814 gen_io_start();
895c2d04 5815 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5816 if (use_icount) {
5817 gen_io_end();
2e70f6ef 5818 }
55807224
EI
5819 /* Break the TB to be able to take timer interrupts immediately
5820 after reading count. */
5821 ctx->bstate = BS_STOP;
2423f660
TS
5822 rn = "Count";
5823 break;
5824 /* 6,7 are implementation dependent */
9c2149c8
TS
5825 default:
5826 goto die;
876d4b07 5827 }
9c2149c8
TS
5828 break;
5829 case 10:
5830 switch (sel) {
5831 case 0:
7db13fae 5832 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5833 rn = "EntryHi";
5834 break;
9c2149c8
TS
5835 default:
5836 goto die;
876d4b07 5837 }
9c2149c8
TS
5838 break;
5839 case 11:
5840 switch (sel) {
5841 case 0:
7db13fae 5842 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5843 rn = "Compare";
5844 break;
876d4b07 5845 /* 6,7 are implementation dependent */
9c2149c8
TS
5846 default:
5847 goto die;
876d4b07 5848 }
9c2149c8
TS
5849 break;
5850 case 12:
5851 switch (sel) {
5852 case 0:
7db13fae 5853 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5854 rn = "Status";
5855 break;
9c2149c8 5856 case 1:
d75c135e 5857 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5858 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5859 rn = "IntCtl";
5860 break;
9c2149c8 5861 case 2:
d75c135e 5862 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5863 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5864 rn = "SRSCtl";
5865 break;
9c2149c8 5866 case 3:
d75c135e 5867 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5868 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5869 rn = "SRSMap";
5870 break;
9c2149c8
TS
5871 default:
5872 goto die;
876d4b07 5873 }
9c2149c8
TS
5874 break;
5875 case 13:
5876 switch (sel) {
5877 case 0:
7db13fae 5878 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5879 rn = "Cause";
5880 break;
9c2149c8
TS
5881 default:
5882 goto die;
876d4b07 5883 }
9c2149c8
TS
5884 break;
5885 case 14:
5886 switch (sel) {
5887 case 0:
7db13fae 5888 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5889 rn = "EPC";
5890 break;
9c2149c8
TS
5891 default:
5892 goto die;
876d4b07 5893 }
9c2149c8
TS
5894 break;
5895 case 15:
5896 switch (sel) {
5897 case 0:
7db13fae 5898 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5899 rn = "PRid";
5900 break;
9c2149c8 5901 case 1:
d75c135e 5902 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5903 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5904 rn = "EBase";
5905 break;
9c2149c8
TS
5906 default:
5907 goto die;
876d4b07 5908 }
9c2149c8
TS
5909 break;
5910 case 16:
5911 switch (sel) {
5912 case 0:
7db13fae 5913 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5914 rn = "Config";
5915 break;
5916 case 1:
7db13fae 5917 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5918 rn = "Config1";
5919 break;
5920 case 2:
7db13fae 5921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5922 rn = "Config2";
5923 break;
5924 case 3:
7db13fae 5925 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5926 rn = "Config3";
5927 break;
5928 /* 6,7 are implementation dependent */
f0b3f3ae 5929 case 6:
7db13fae 5930 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5931 rn = "Config6";
5932 break;
5933 case 7:
7db13fae 5934 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5935 rn = "Config7";
5936 break;
9c2149c8
TS
5937 default:
5938 goto die;
5939 }
5940 break;
5941 case 17:
5942 switch (sel) {
5943 case 0:
895c2d04 5944 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5945 rn = "LLAddr";
5946 break;
9c2149c8
TS
5947 default:
5948 goto die;
5949 }
5950 break;
5951 case 18:
5952 switch (sel) {
fd88b6ab 5953 case 0 ... 7:
895c2d04 5954 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5955 rn = "WatchLo";
5956 break;
9c2149c8
TS
5957 default:
5958 goto die;
5959 }
5960 break;
5961 case 19:
5962 switch (sel) {
fd88b6ab 5963 case 0 ... 7:
895c2d04 5964 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5965 rn = "WatchHi";
5966 break;
9c2149c8
TS
5967 default:
5968 goto die;
5969 }
5970 break;
5971 case 20:
5972 switch (sel) {
5973 case 0:
d75c135e 5974 check_insn(ctx, ISA_MIPS3);
7db13fae 5975 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5976 rn = "XContext";
5977 break;
9c2149c8
TS
5978 default:
5979 goto die;
5980 }
5981 break;
5982 case 21:
5983 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5984 switch (sel) {
5985 case 0:
7db13fae 5986 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5987 rn = "Framemask";
5988 break;
9c2149c8
TS
5989 default:
5990 goto die;
5991 }
5992 break;
5993 case 22:
d9bea114 5994 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5995 rn = "'Diagnostic"; /* implementation dependent */
5996 break;
9c2149c8
TS
5997 case 23:
5998 switch (sel) {
5999 case 0:
895c2d04 6000 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6001 rn = "Debug";
6002 break;
9c2149c8 6003 case 1:
895c2d04 6004// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6005 rn = "TraceControl";
6006// break;
9c2149c8 6007 case 2:
895c2d04 6008// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6009 rn = "TraceControl2";
6010// break;
9c2149c8 6011 case 3:
895c2d04 6012// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6013 rn = "UserTraceData";
6014// break;
9c2149c8 6015 case 4:
895c2d04 6016// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6017 rn = "TraceBPC";
6018// break;
9c2149c8
TS
6019 default:
6020 goto die;
6021 }
6022 break;
6023 case 24:
6024 switch (sel) {
6025 case 0:
f0b3f3ae 6026 /* EJTAG support */
7db13fae 6027 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6028 rn = "DEPC";
6029 break;
9c2149c8
TS
6030 default:
6031 goto die;
6032 }
6033 break;
6034 case 25:
6035 switch (sel) {
6036 case 0:
7db13fae 6037 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6038 rn = "Performance0";
9c2149c8
TS
6039 break;
6040 case 1:
d9bea114 6041// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6042 rn = "Performance1";
6043// break;
9c2149c8 6044 case 2:
d9bea114 6045// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6046 rn = "Performance2";
6047// break;
9c2149c8 6048 case 3:
d9bea114 6049// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6050 rn = "Performance3";
6051// break;
9c2149c8 6052 case 4:
d9bea114 6053// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6054 rn = "Performance4";
6055// break;
9c2149c8 6056 case 5:
d9bea114 6057// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6058 rn = "Performance5";
6059// break;
9c2149c8 6060 case 6:
d9bea114 6061// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6062 rn = "Performance6";
6063// break;
9c2149c8 6064 case 7:
d9bea114 6065// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6066 rn = "Performance7";
6067// break;
9c2149c8
TS
6068 default:
6069 goto die;
6070 }
6071 break;
6072 case 26:
d9bea114 6073 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6074 rn = "ECC";
6075 break;
9c2149c8
TS
6076 case 27:
6077 switch (sel) {
6078 /* ignored */
6079 case 0 ... 3:
d9bea114 6080 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6081 rn = "CacheErr";
6082 break;
9c2149c8
TS
6083 default:
6084 goto die;
6085 }
6086 break;
6087 case 28:
6088 switch (sel) {
6089 case 0:
6090 case 2:
6091 case 4:
6092 case 6:
7db13fae 6093 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6094 rn = "TagLo";
6095 break;
6096 case 1:
6097 case 3:
6098 case 5:
6099 case 7:
7db13fae 6100 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6101 rn = "DataLo";
6102 break;
6103 default:
6104 goto die;
6105 }
6106 break;
6107 case 29:
6108 switch (sel) {
6109 case 0:
6110 case 2:
6111 case 4:
6112 case 6:
7db13fae 6113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6114 rn = "TagHi";
6115 break;
6116 case 1:
6117 case 3:
6118 case 5:
6119 case 7:
7db13fae 6120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6121 rn = "DataHi";
6122 break;
6123 default:
6124 goto die;
6125 }
6126 break;
6127 case 30:
6128 switch (sel) {
6129 case 0:
7db13fae 6130 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6131 rn = "ErrorEPC";
6132 break;
9c2149c8
TS
6133 default:
6134 goto die;
6135 }
6136 break;
6137 case 31:
6138 switch (sel) {
6139 case 0:
f0b3f3ae 6140 /* EJTAG support */
7db13fae 6141 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6142 rn = "DESAVE";
6143 break;
9c2149c8
TS
6144 default:
6145 goto die;
6146 }
6147 break;
6148 default:
876d4b07 6149 goto die;
9c2149c8 6150 }
2abf314d 6151 (void)rn; /* avoid a compiler warning */
d12d51d5 6152 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6153 return;
6154
6155die:
d12d51d5 6156 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6157 generate_exception(ctx, EXCP_RI);
6158}
6159
d75c135e 6160static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6161{
6162 const char *rn = "invalid";
6163
e189e748 6164 if (sel != 0)
d75c135e 6165 check_insn(ctx, ISA_MIPS64);
e189e748 6166
2e70f6ef
PB
6167 if (use_icount)
6168 gen_io_start();
6169
9c2149c8
TS
6170 switch (reg) {
6171 case 0:
6172 switch (sel) {
6173 case 0:
895c2d04 6174 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6175 rn = "Index";
6176 break;
6177 case 1:
d75c135e 6178 check_insn(ctx, ASE_MT);
895c2d04 6179 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6180 rn = "MVPControl";
ead9360e 6181 break;
9c2149c8 6182 case 2:
d75c135e 6183 check_insn(ctx, ASE_MT);
ead9360e 6184 /* ignored */
9c2149c8 6185 rn = "MVPConf0";
ead9360e 6186 break;
9c2149c8 6187 case 3:
d75c135e 6188 check_insn(ctx, ASE_MT);
ead9360e 6189 /* ignored */
9c2149c8 6190 rn = "MVPConf1";
ead9360e 6191 break;
9c2149c8
TS
6192 default:
6193 goto die;
6194 }
6195 break;
6196 case 1:
6197 switch (sel) {
6198 case 0:
2423f660 6199 /* ignored */
9c2149c8 6200 rn = "Random";
2423f660 6201 break;
9c2149c8 6202 case 1:
d75c135e 6203 check_insn(ctx, ASE_MT);
895c2d04 6204 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6205 rn = "VPEControl";
ead9360e 6206 break;
9c2149c8 6207 case 2:
d75c135e 6208 check_insn(ctx, ASE_MT);
895c2d04 6209 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6210 rn = "VPEConf0";
ead9360e 6211 break;
9c2149c8 6212 case 3:
d75c135e 6213 check_insn(ctx, ASE_MT);
895c2d04 6214 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6215 rn = "VPEConf1";
ead9360e 6216 break;
9c2149c8 6217 case 4:
d75c135e 6218 check_insn(ctx, ASE_MT);
895c2d04 6219 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6220 rn = "YQMask";
ead9360e 6221 break;
9c2149c8 6222 case 5:
d75c135e 6223 check_insn(ctx, ASE_MT);
7db13fae 6224 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6225 rn = "VPESchedule";
ead9360e 6226 break;
9c2149c8 6227 case 6:
d75c135e 6228 check_insn(ctx, ASE_MT);
7db13fae 6229 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6230 rn = "VPEScheFBack";
ead9360e 6231 break;
9c2149c8 6232 case 7:
d75c135e 6233 check_insn(ctx, ASE_MT);
895c2d04 6234 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6235 rn = "VPEOpt";
ead9360e 6236 break;
9c2149c8
TS
6237 default:
6238 goto die;
6239 }
6240 break;
6241 case 2:
6242 switch (sel) {
6243 case 0:
895c2d04 6244 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
6245 rn = "EntryLo0";
6246 break;
9c2149c8 6247 case 1:
d75c135e 6248 check_insn(ctx, ASE_MT);
895c2d04 6249 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6250 rn = "TCStatus";
ead9360e 6251 break;
9c2149c8 6252 case 2:
d75c135e 6253 check_insn(ctx, ASE_MT);
895c2d04 6254 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6255 rn = "TCBind";
ead9360e 6256 break;
9c2149c8 6257 case 3:
d75c135e 6258 check_insn(ctx, ASE_MT);
895c2d04 6259 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6260 rn = "TCRestart";
ead9360e 6261 break;
9c2149c8 6262 case 4:
d75c135e 6263 check_insn(ctx, ASE_MT);
895c2d04 6264 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6265 rn = "TCHalt";
ead9360e 6266 break;
9c2149c8 6267 case 5:
d75c135e 6268 check_insn(ctx, ASE_MT);
895c2d04 6269 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6270 rn = "TCContext";
ead9360e 6271 break;
9c2149c8 6272 case 6:
d75c135e 6273 check_insn(ctx, ASE_MT);
895c2d04 6274 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6275 rn = "TCSchedule";
ead9360e 6276 break;
9c2149c8 6277 case 7:
d75c135e 6278 check_insn(ctx, ASE_MT);
895c2d04 6279 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6280 rn = "TCScheFBack";
ead9360e 6281 break;
9c2149c8
TS
6282 default:
6283 goto die;
6284 }
6285 break;
6286 case 3:
6287 switch (sel) {
6288 case 0:
895c2d04 6289 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
6290 rn = "EntryLo1";
6291 break;
9c2149c8
TS
6292 default:
6293 goto die;
876d4b07 6294 }
9c2149c8
TS
6295 break;
6296 case 4:
6297 switch (sel) {
6298 case 0:
895c2d04 6299 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6300 rn = "Context";
6301 break;
9c2149c8 6302 case 1:
895c2d04 6303// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6304 rn = "ContextConfig";
d279279e 6305 goto die;
2423f660 6306// break;
d279279e
PJ
6307 case 2:
6308 if (ctx->ulri) {
6309 tcg_gen_st_tl(arg, cpu_env,
6310 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6311 rn = "UserLocal";
6312 }
6313 break;
9c2149c8
TS
6314 default:
6315 goto die;
876d4b07 6316 }
9c2149c8
TS
6317 break;
6318 case 5:
6319 switch (sel) {
6320 case 0:
895c2d04 6321 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6322 rn = "PageMask";
6323 break;
9c2149c8 6324 case 1:
d75c135e 6325 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6326 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6327 rn = "PageGrain";
6328 break;
9c2149c8
TS
6329 default:
6330 goto die;
876d4b07 6331 }
9c2149c8
TS
6332 break;
6333 case 6:
6334 switch (sel) {
6335 case 0:
895c2d04 6336 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6337 rn = "Wired";
6338 break;
9c2149c8 6339 case 1:
d75c135e 6340 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6341 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6342 rn = "SRSConf0";
ead9360e 6343 break;
9c2149c8 6344 case 2:
d75c135e 6345 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6346 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6347 rn = "SRSConf1";
ead9360e 6348 break;
9c2149c8 6349 case 3:
d75c135e 6350 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6351 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6352 rn = "SRSConf2";
ead9360e 6353 break;
9c2149c8 6354 case 4:
d75c135e 6355 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6356 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6357 rn = "SRSConf3";
ead9360e 6358 break;
9c2149c8 6359 case 5:
d75c135e 6360 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6361 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6362 rn = "SRSConf4";
ead9360e 6363 break;
9c2149c8
TS
6364 default:
6365 goto die;
876d4b07 6366 }
9c2149c8
TS
6367 break;
6368 case 7:
6369 switch (sel) {
6370 case 0:
d75c135e 6371 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6372 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6373 ctx->bstate = BS_STOP;
2423f660
TS
6374 rn = "HWREna";
6375 break;
9c2149c8
TS
6376 default:
6377 goto die;
876d4b07 6378 }
9c2149c8
TS
6379 break;
6380 case 8:
6381 /* ignored */
f0b3f3ae 6382 rn = "BadVAddr";
9c2149c8
TS
6383 break;
6384 case 9:
6385 switch (sel) {
6386 case 0:
895c2d04 6387 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6388 rn = "Count";
6389 break;
876d4b07 6390 /* 6,7 are implementation dependent */
9c2149c8
TS
6391 default:
6392 goto die;
876d4b07
TS
6393 }
6394 /* Stop translation as we may have switched the execution mode */
6395 ctx->bstate = BS_STOP;
9c2149c8
TS
6396 break;
6397 case 10:
6398 switch (sel) {
6399 case 0:
895c2d04 6400 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6401 rn = "EntryHi";
6402 break;
9c2149c8
TS
6403 default:
6404 goto die;
876d4b07 6405 }
9c2149c8
TS
6406 break;
6407 case 11:
6408 switch (sel) {
6409 case 0:
895c2d04 6410 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6411 rn = "Compare";
6412 break;
876d4b07 6413 /* 6,7 are implementation dependent */
9c2149c8
TS
6414 default:
6415 goto die;
876d4b07 6416 }
de9a95f0
AJ
6417 /* Stop translation as we may have switched the execution mode */
6418 ctx->bstate = BS_STOP;
9c2149c8
TS
6419 break;
6420 case 12:
6421 switch (sel) {
6422 case 0:
867abc7e 6423 save_cpu_state(ctx, 1);
895c2d04 6424 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6425 /* BS_STOP isn't good enough here, hflags may have changed. */
6426 gen_save_pc(ctx->pc + 4);
6427 ctx->bstate = BS_EXCP;
2423f660
TS
6428 rn = "Status";
6429 break;
9c2149c8 6430 case 1:
d75c135e 6431 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6432 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6433 /* Stop translation as we may have switched the execution mode */
6434 ctx->bstate = BS_STOP;
2423f660
TS
6435 rn = "IntCtl";
6436 break;
9c2149c8 6437 case 2:
d75c135e 6438 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6439 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6440 /* Stop translation as we may have switched the execution mode */
6441 ctx->bstate = BS_STOP;
2423f660
TS
6442 rn = "SRSCtl";
6443 break;
9c2149c8 6444 case 3:
d75c135e 6445 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6446 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6447 /* Stop translation as we may have switched the execution mode */
6448 ctx->bstate = BS_STOP;
2423f660
TS
6449 rn = "SRSMap";
6450 break;
6451 default:
9c2149c8 6452 goto die;
876d4b07 6453 }
9c2149c8
TS
6454 break;
6455 case 13:
6456 switch (sel) {
6457 case 0:
867abc7e 6458 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6459 /* Mark as an IO operation because we may trigger a software
6460 interrupt. */
6461 if (use_icount) {
6462 gen_io_start();
6463 }
895c2d04 6464 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6465 if (use_icount) {
6466 gen_io_end();
6467 }
6468 /* Stop translation as we may have triggered an intetrupt */
6469 ctx->bstate = BS_STOP;
2423f660
TS
6470 rn = "Cause";
6471 break;
9c2149c8
TS
6472 default:
6473 goto die;
876d4b07 6474 }
9c2149c8
TS
6475 break;
6476 case 14:
6477 switch (sel) {
6478 case 0:
7db13fae 6479 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6480 rn = "EPC";
6481 break;
9c2149c8
TS
6482 default:
6483 goto die;
876d4b07 6484 }
9c2149c8
TS
6485 break;
6486 case 15:
6487 switch (sel) {
6488 case 0:
2423f660
TS
6489 /* ignored */
6490 rn = "PRid";
6491 break;
9c2149c8 6492 case 1:
d75c135e 6493 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6494 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6495 rn = "EBase";
6496 break;
9c2149c8
TS
6497 default:
6498 goto die;
876d4b07 6499 }
9c2149c8
TS
6500 break;
6501 case 16:
6502 switch (sel) {
6503 case 0:
895c2d04 6504 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6505 rn = "Config";
2423f660
TS
6506 /* Stop translation as we may have switched the execution mode */
6507 ctx->bstate = BS_STOP;
9c2149c8
TS
6508 break;
6509 case 1:
1fc7bf6e 6510 /* ignored, read only */
9c2149c8
TS
6511 rn = "Config1";
6512 break;
6513 case 2:
895c2d04 6514 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6515 rn = "Config2";
2423f660
TS
6516 /* Stop translation as we may have switched the execution mode */
6517 ctx->bstate = BS_STOP;
9c2149c8
TS
6518 break;
6519 case 3:
2423f660 6520 /* ignored */
9c2149c8
TS
6521 rn = "Config3";
6522 break;
6523 /* 6,7 are implementation dependent */
6524 default:
6525 rn = "Invalid config selector";
6526 goto die;
6527 }
9c2149c8
TS
6528 break;
6529 case 17:
6530 switch (sel) {
6531 case 0:
895c2d04 6532 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6533 rn = "LLAddr";
6534 break;
9c2149c8
TS
6535 default:
6536 goto die;
6537 }
6538 break;
6539 case 18:
6540 switch (sel) {
fd88b6ab 6541 case 0 ... 7:
895c2d04 6542 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6543 rn = "WatchLo";
6544 break;
9c2149c8
TS
6545 default:
6546 goto die;
6547 }
6548 break;
6549 case 19:
6550 switch (sel) {
fd88b6ab 6551 case 0 ... 7:
895c2d04 6552 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6553 rn = "WatchHi";
6554 break;
9c2149c8
TS
6555 default:
6556 goto die;
6557 }
6558 break;
6559 case 20:
6560 switch (sel) {
6561 case 0:
d75c135e 6562 check_insn(ctx, ISA_MIPS3);
895c2d04 6563 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6564 rn = "XContext";
6565 break;
9c2149c8
TS
6566 default:
6567 goto die;
6568 }
6569 break;
6570 case 21:
6571 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6572 switch (sel) {
6573 case 0:
895c2d04 6574 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6575 rn = "Framemask";
6576 break;
9c2149c8
TS
6577 default:
6578 goto die;
6579 }
6580 break;
6581 case 22:
6582 /* ignored */
6583 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6584 break;
9c2149c8
TS
6585 case 23:
6586 switch (sel) {
6587 case 0:
895c2d04 6588 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6589 /* BS_STOP isn't good enough here, hflags may have changed. */
6590 gen_save_pc(ctx->pc + 4);
6591 ctx->bstate = BS_EXCP;
2423f660
TS
6592 rn = "Debug";
6593 break;
9c2149c8 6594 case 1:
895c2d04 6595// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6596 /* Stop translation as we may have switched the execution mode */
6597 ctx->bstate = BS_STOP;
2423f660
TS
6598 rn = "TraceControl";
6599// break;
9c2149c8 6600 case 2:
895c2d04 6601// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6602 /* Stop translation as we may have switched the execution mode */
6603 ctx->bstate = BS_STOP;
2423f660
TS
6604 rn = "TraceControl2";
6605// break;
9c2149c8 6606 case 3:
895c2d04 6607// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6608 /* Stop translation as we may have switched the execution mode */
6609 ctx->bstate = BS_STOP;
2423f660
TS
6610 rn = "UserTraceData";
6611// break;
9c2149c8 6612 case 4:
895c2d04 6613// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6614 /* Stop translation as we may have switched the execution mode */
6615 ctx->bstate = BS_STOP;
2423f660
TS
6616 rn = "TraceBPC";
6617// break;
9c2149c8
TS
6618 default:
6619 goto die;
6620 }
9c2149c8
TS
6621 break;
6622 case 24:
6623 switch (sel) {
6624 case 0:
f1aa6320 6625 /* EJTAG support */
7db13fae 6626 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6627 rn = "DEPC";
6628 break;
9c2149c8
TS
6629 default:
6630 goto die;
6631 }
6632 break;
6633 case 25:
6634 switch (sel) {
6635 case 0:
895c2d04 6636 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6637 rn = "Performance0";
6638 break;
9c2149c8 6639 case 1:
895c2d04 6640// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6641 rn = "Performance1";
6642// break;
9c2149c8 6643 case 2:
895c2d04 6644// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6645 rn = "Performance2";
6646// break;
9c2149c8 6647 case 3:
895c2d04 6648// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6649 rn = "Performance3";
6650// break;
9c2149c8 6651 case 4:
895c2d04 6652// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6653 rn = "Performance4";
6654// break;
9c2149c8 6655 case 5:
895c2d04 6656// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6657 rn = "Performance5";
6658// break;
9c2149c8 6659 case 6:
895c2d04 6660// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6661 rn = "Performance6";
6662// break;
9c2149c8 6663 case 7:
895c2d04 6664// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6665 rn = "Performance7";
6666// break;
9c2149c8
TS
6667 default:
6668 goto die;
6669 }
876d4b07 6670 break;
9c2149c8 6671 case 26:
876d4b07 6672 /* ignored */
9c2149c8 6673 rn = "ECC";
876d4b07 6674 break;
9c2149c8
TS
6675 case 27:
6676 switch (sel) {
6677 case 0 ... 3:
2423f660
TS
6678 /* ignored */
6679 rn = "CacheErr";
6680 break;
9c2149c8
TS
6681 default:
6682 goto die;
6683 }
876d4b07 6684 break;
9c2149c8
TS
6685 case 28:
6686 switch (sel) {
6687 case 0:
6688 case 2:
6689 case 4:
6690 case 6:
895c2d04 6691 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6692 rn = "TagLo";
6693 break;
6694 case 1:
6695 case 3:
6696 case 5:
6697 case 7:
895c2d04 6698 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6699 rn = "DataLo";
6700 break;
6701 default:
6702 goto die;
6703 }
6704 break;
6705 case 29:
6706 switch (sel) {
6707 case 0:
6708 case 2:
6709 case 4:
6710 case 6:
895c2d04 6711 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6712 rn = "TagHi";
6713 break;
6714 case 1:
6715 case 3:
6716 case 5:
6717 case 7:
895c2d04 6718 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6719 rn = "DataHi";
6720 break;
6721 default:
6722 rn = "invalid sel";
6723 goto die;
6724 }
876d4b07 6725 break;
9c2149c8
TS
6726 case 30:
6727 switch (sel) {
6728 case 0:
7db13fae 6729 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6730 rn = "ErrorEPC";
6731 break;
9c2149c8
TS
6732 default:
6733 goto die;
6734 }
6735 break;
6736 case 31:
6737 switch (sel) {
6738 case 0:
f1aa6320 6739 /* EJTAG support */
7db13fae 6740 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6741 rn = "DESAVE";
6742 break;
9c2149c8
TS
6743 default:
6744 goto die;
6745 }
876d4b07
TS
6746 /* Stop translation as we may have switched the execution mode */
6747 ctx->bstate = BS_STOP;
9c2149c8
TS
6748 break;
6749 default:
876d4b07 6750 goto die;
9c2149c8 6751 }
2abf314d 6752 (void)rn; /* avoid a compiler warning */
d12d51d5 6753 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6754 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6755 if (use_icount) {
6756 gen_io_end();
6757 ctx->bstate = BS_STOP;
6758 }
9c2149c8
TS
6759 return;
6760
6761die:
d12d51d5 6762 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6763 generate_exception(ctx, EXCP_RI);
6764}
d26bc211 6765#endif /* TARGET_MIPS64 */
9c2149c8 6766
7db13fae 6767static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6768 int u, int sel, int h)
6769{
6770 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6771 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6772
6773 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6774 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6775 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6776 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6777 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6778 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6779 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6780 else if (u == 0) {
6781 switch (rt) {
5a25ce94
EI
6782 case 1:
6783 switch (sel) {
6784 case 1:
895c2d04 6785 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6786 break;
6787 case 2:
895c2d04 6788 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6789 break;
6790 default:
6791 goto die;
6792 break;
6793 }
6794 break;
ead9360e
TS
6795 case 2:
6796 switch (sel) {
6797 case 1:
895c2d04 6798 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6799 break;
6800 case 2:
895c2d04 6801 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6802 break;
6803 case 3:
895c2d04 6804 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6805 break;
6806 case 4:
895c2d04 6807 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6808 break;
6809 case 5:
895c2d04 6810 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6811 break;
6812 case 6:
895c2d04 6813 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6814 break;
6815 case 7:
895c2d04 6816 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6817 break;
6818 default:
d75c135e 6819 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6820 break;
6821 }
6822 break;
6823 case 10:
6824 switch (sel) {
6825 case 0:
895c2d04 6826 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6827 break;
6828 default:
d75c135e 6829 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6830 break;
6831 }
6832 case 12:
6833 switch (sel) {
6834 case 0:
895c2d04 6835 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6836 break;
6837 default:
d75c135e 6838 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6839 break;
6840 }
5a25ce94
EI
6841 case 13:
6842 switch (sel) {
6843 case 0:
895c2d04 6844 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6845 break;
6846 default:
6847 goto die;
6848 break;
6849 }
6850 break;
6851 case 14:
6852 switch (sel) {
6853 case 0:
895c2d04 6854 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6855 break;
6856 default:
6857 goto die;
6858 break;
6859 }
6860 break;
6861 case 15:
6862 switch (sel) {
6863 case 1:
895c2d04 6864 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6865 break;
6866 default:
6867 goto die;
6868 break;
6869 }
6870 break;
6871 case 16:
6872 switch (sel) {
6873 case 0 ... 7:
895c2d04 6874 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6875 break;
6876 default:
6877 goto die;
6878 break;
6879 }
6880 break;
ead9360e
TS
6881 case 23:
6882 switch (sel) {
6883 case 0:
895c2d04 6884 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6885 break;
6886 default:
d75c135e 6887 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6888 break;
6889 }
6890 break;
6891 default:
d75c135e 6892 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6893 }
6894 } else switch (sel) {
6895 /* GPR registers. */
6896 case 0:
895c2d04 6897 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6898 break;
6899 /* Auxiliary CPU registers */
6900 case 1:
6901 switch (rt) {
6902 case 0:
895c2d04 6903 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6904 break;
6905 case 1:
895c2d04 6906 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6907 break;
6908 case 2:
895c2d04 6909 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6910 break;
6911 case 4:
895c2d04 6912 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6913 break;
6914 case 5:
895c2d04 6915 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6916 break;
6917 case 6:
895c2d04 6918 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6919 break;
6920 case 8:
895c2d04 6921 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6922 break;
6923 case 9:
895c2d04 6924 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6925 break;
6926 case 10:
895c2d04 6927 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6928 break;
6929 case 12:
895c2d04 6930 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6931 break;
6932 case 13:
895c2d04 6933 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6934 break;
6935 case 14:
895c2d04 6936 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6937 break;
6938 case 16:
895c2d04 6939 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6940 break;
6941 default:
6942 goto die;
6943 }
6944 break;
6945 /* Floating point (COP1). */
6946 case 2:
6947 /* XXX: For now we support only a single FPU context. */
6948 if (h == 0) {
a7812ae4 6949 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6950
6951 gen_load_fpr32(fp0, rt);
6952 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6953 tcg_temp_free_i32(fp0);
ead9360e 6954 } else {
a7812ae4 6955 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 6956
7f6613ce 6957 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 6958 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6959 tcg_temp_free_i32(fp0);
ead9360e
TS
6960 }
6961 break;
6962 case 3:
6963 /* XXX: For now we support only a single FPU context. */
895c2d04 6964 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6965 break;
6966 /* COP2: Not implemented. */
6967 case 4:
6968 case 5:
6969 /* fall through */
6970 default:
6971 goto die;
6972 }
d12d51d5 6973 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6974 gen_store_gpr(t0, rd);
6975 tcg_temp_free(t0);
ead9360e
TS
6976 return;
6977
6978die:
1a3fd9c3 6979 tcg_temp_free(t0);
d12d51d5 6980 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6981 generate_exception(ctx, EXCP_RI);
6982}
6983
7db13fae 6984static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6985 int u, int sel, int h)
6986{
6987 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6988 TCGv t0 = tcg_temp_local_new();
ead9360e 6989
1a3fd9c3 6990 gen_load_gpr(t0, rt);
ead9360e 6991 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6992 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6993 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6994 /* NOP */ ;
6995 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6996 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6997 /* NOP */ ;
6998 else if (u == 0) {
6999 switch (rd) {
5a25ce94
EI
7000 case 1:
7001 switch (sel) {
7002 case 1:
895c2d04 7003 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7004 break;
7005 case 2:
895c2d04 7006 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7007 break;
7008 default:
7009 goto die;
7010 break;
7011 }
7012 break;
ead9360e
TS
7013 case 2:
7014 switch (sel) {
7015 case 1:
895c2d04 7016 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7017 break;
7018 case 2:
895c2d04 7019 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7020 break;
7021 case 3:
895c2d04 7022 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7023 break;
7024 case 4:
895c2d04 7025 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7026 break;
7027 case 5:
895c2d04 7028 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7029 break;
7030 case 6:
895c2d04 7031 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7032 break;
7033 case 7:
895c2d04 7034 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7035 break;
7036 default:
d75c135e 7037 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7038 break;
7039 }
7040 break;
7041 case 10:
7042 switch (sel) {
7043 case 0:
895c2d04 7044 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7045 break;
7046 default:
d75c135e 7047 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7048 break;
7049 }
7050 case 12:
7051 switch (sel) {
7052 case 0:
895c2d04 7053 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7054 break;
7055 default:
d75c135e 7056 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7057 break;
7058 }
5a25ce94
EI
7059 case 13:
7060 switch (sel) {
7061 case 0:
895c2d04 7062 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7063 break;
7064 default:
7065 goto die;
7066 break;
7067 }
7068 break;
7069 case 15:
7070 switch (sel) {
7071 case 1:
895c2d04 7072 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7073 break;
7074 default:
7075 goto die;
7076 break;
7077 }
7078 break;
ead9360e
TS
7079 case 23:
7080 switch (sel) {
7081 case 0:
895c2d04 7082 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7083 break;
7084 default:
d75c135e 7085 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7086 break;
7087 }
7088 break;
7089 default:
d75c135e 7090 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7091 }
7092 } else switch (sel) {
7093 /* GPR registers. */
7094 case 0:
895c2d04 7095 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7096 break;
7097 /* Auxiliary CPU registers */
7098 case 1:
7099 switch (rd) {
7100 case 0:
895c2d04 7101 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7102 break;
7103 case 1:
895c2d04 7104 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7105 break;
7106 case 2:
895c2d04 7107 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7108 break;
7109 case 4:
895c2d04 7110 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7111 break;
7112 case 5:
895c2d04 7113 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7114 break;
7115 case 6:
895c2d04 7116 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7117 break;
7118 case 8:
895c2d04 7119 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7120 break;
7121 case 9:
895c2d04 7122 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7123 break;
7124 case 10:
895c2d04 7125 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7126 break;
7127 case 12:
895c2d04 7128 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7129 break;
7130 case 13:
895c2d04 7131 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7132 break;
7133 case 14:
895c2d04 7134 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7135 break;
7136 case 16:
895c2d04 7137 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7138 break;
7139 default:
7140 goto die;
7141 }
7142 break;
7143 /* Floating point (COP1). */
7144 case 2:
7145 /* XXX: For now we support only a single FPU context. */
7146 if (h == 0) {
a7812ae4 7147 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7148
7149 tcg_gen_trunc_tl_i32(fp0, t0);
7150 gen_store_fpr32(fp0, rd);
a7812ae4 7151 tcg_temp_free_i32(fp0);
ead9360e 7152 } else {
a7812ae4 7153 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7154
7155 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7156 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7157 tcg_temp_free_i32(fp0);
ead9360e
TS
7158 }
7159 break;
7160 case 3:
7161 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
7162 {
7163 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7164
7165 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7166 tcg_temp_free_i32(fs_tmp);
7167 }
ead9360e
TS
7168 break;
7169 /* COP2: Not implemented. */
7170 case 4:
7171 case 5:
7172 /* fall through */
7173 default:
7174 goto die;
7175 }
d12d51d5 7176 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7177 tcg_temp_free(t0);
ead9360e
TS
7178 return;
7179
7180die:
1a3fd9c3 7181 tcg_temp_free(t0);
d12d51d5 7182 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7183 generate_exception(ctx, EXCP_RI);
7184}
7185
7db13fae 7186static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7187{
287c4b84 7188 const char *opn = "ldst";
6af0bf9c 7189
2e15497c 7190 check_cp0_enabled(ctx);
6af0bf9c
FB
7191 switch (opc) {
7192 case OPC_MFC0:
7193 if (rt == 0) {
ead9360e 7194 /* Treat as NOP. */
6af0bf9c
FB
7195 return;
7196 }
d75c135e 7197 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7198 opn = "mfc0";
7199 break;
7200 case OPC_MTC0:
1a3fd9c3 7201 {
1fc7bf6e 7202 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7203
7204 gen_load_gpr(t0, rt);
d75c135e 7205 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7206 tcg_temp_free(t0);
7207 }
6af0bf9c
FB
7208 opn = "mtc0";
7209 break;
d26bc211 7210#if defined(TARGET_MIPS64)
9c2149c8 7211 case OPC_DMFC0:
d75c135e 7212 check_insn(ctx, ISA_MIPS3);
9c2149c8 7213 if (rt == 0) {
ead9360e 7214 /* Treat as NOP. */
9c2149c8
TS
7215 return;
7216 }
d75c135e 7217 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7218 opn = "dmfc0";
7219 break;
7220 case OPC_DMTC0:
d75c135e 7221 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7222 {
1fc7bf6e 7223 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7224
7225 gen_load_gpr(t0, rt);
d75c135e 7226 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7227 tcg_temp_free(t0);
7228 }
9c2149c8
TS
7229 opn = "dmtc0";
7230 break;
534ce69f 7231#endif
ead9360e 7232 case OPC_MFTR:
d75c135e 7233 check_insn(ctx, ASE_MT);
ead9360e
TS
7234 if (rd == 0) {
7235 /* Treat as NOP. */
7236 return;
7237 }
6c5c1e20 7238 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7239 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7240 opn = "mftr";
7241 break;
7242 case OPC_MTTR:
d75c135e 7243 check_insn(ctx, ASE_MT);
6c5c1e20 7244 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7245 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7246 opn = "mttr";
7247 break;
6af0bf9c 7248 case OPC_TLBWI:
6af0bf9c 7249 opn = "tlbwi";
c01fccd2 7250 if (!env->tlb->helper_tlbwi)
29929e34 7251 goto die;
895c2d04 7252 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
7253 break;
7254 case OPC_TLBWR:
6af0bf9c 7255 opn = "tlbwr";
c01fccd2 7256 if (!env->tlb->helper_tlbwr)
29929e34 7257 goto die;
895c2d04 7258 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7259 break;
7260 case OPC_TLBP:
6af0bf9c 7261 opn = "tlbp";
c01fccd2 7262 if (!env->tlb->helper_tlbp)
29929e34 7263 goto die;
895c2d04 7264 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7265 break;
7266 case OPC_TLBR:
6af0bf9c 7267 opn = "tlbr";
c01fccd2 7268 if (!env->tlb->helper_tlbr)
29929e34 7269 goto die;
895c2d04 7270 gen_helper_tlbr(cpu_env);
6af0bf9c 7271 break;
6af0bf9c
FB
7272 case OPC_ERET:
7273 opn = "eret";
d75c135e 7274 check_insn(ctx, ISA_MIPS2);
895c2d04 7275 gen_helper_eret(cpu_env);
6af0bf9c
FB
7276 ctx->bstate = BS_EXCP;
7277 break;
7278 case OPC_DERET:
7279 opn = "deret";
d75c135e 7280 check_insn(ctx, ISA_MIPS32);
6af0bf9c 7281 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 7282 MIPS_INVAL(opn);
6af0bf9c
FB
7283 generate_exception(ctx, EXCP_RI);
7284 } else {
895c2d04 7285 gen_helper_deret(cpu_env);
6af0bf9c
FB
7286 ctx->bstate = BS_EXCP;
7287 }
7288 break;
4ad40f36
FB
7289 case OPC_WAIT:
7290 opn = "wait";
d75c135e 7291 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
7292 /* If we get an exception, we want to restart at next instruction */
7293 ctx->pc += 4;
7294 save_cpu_state(ctx, 1);
7295 ctx->pc -= 4;
895c2d04 7296 gen_helper_wait(cpu_env);
4ad40f36
FB
7297 ctx->bstate = BS_EXCP;
7298 break;
6af0bf9c 7299 default:
29929e34 7300 die:
923617a3 7301 MIPS_INVAL(opn);
6af0bf9c
FB
7302 generate_exception(ctx, EXCP_RI);
7303 return;
7304 }
2abf314d 7305 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7306 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7307}
f1aa6320 7308#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7309
6ea83fed 7310/* CP1 Branches (before delay slot) */
d75c135e
AJ
7311static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7312 int32_t cc, int32_t offset)
6ea83fed
FB
7313{
7314 target_ulong btarget;
923617a3 7315 const char *opn = "cp1 cond branch";
a7812ae4 7316 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7317
e189e748 7318 if (cc != 0)
d75c135e 7319 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7320
6ea83fed
FB
7321 btarget = ctx->pc + 4 + offset;
7322
7a387fff
TS
7323 switch (op) {
7324 case OPC_BC1F:
d94536f4
AJ
7325 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7326 tcg_gen_not_i32(t0, t0);
7327 tcg_gen_andi_i32(t0, t0, 1);
7328 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7329 opn = "bc1f";
6ea83fed 7330 goto not_likely;
7a387fff 7331 case OPC_BC1FL:
d94536f4
AJ
7332 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7333 tcg_gen_not_i32(t0, t0);
7334 tcg_gen_andi_i32(t0, t0, 1);
7335 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7336 opn = "bc1fl";
6ea83fed 7337 goto likely;
7a387fff 7338 case OPC_BC1T:
d94536f4
AJ
7339 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7340 tcg_gen_andi_i32(t0, t0, 1);
7341 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7342 opn = "bc1t";
5a5012ec 7343 goto not_likely;
7a387fff 7344 case OPC_BC1TL:
d94536f4
AJ
7345 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7346 tcg_gen_andi_i32(t0, t0, 1);
7347 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7348 opn = "bc1tl";
6ea83fed
FB
7349 likely:
7350 ctx->hflags |= MIPS_HFLAG_BL;
7351 break;
5a5012ec 7352 case OPC_BC1FANY2:
a16336e4 7353 {
d94536f4
AJ
7354 TCGv_i32 t1 = tcg_temp_new_i32();
7355 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7356 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7357 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7358 tcg_temp_free_i32(t1);
d94536f4
AJ
7359 tcg_gen_andi_i32(t0, t0, 1);
7360 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7361 }
fd4a04eb 7362 opn = "bc1any2f";
5a5012ec
TS
7363 goto not_likely;
7364 case OPC_BC1TANY2:
a16336e4 7365 {
d94536f4
AJ
7366 TCGv_i32 t1 = tcg_temp_new_i32();
7367 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7368 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7369 tcg_gen_or_i32(t0, t0, t1);
7370 tcg_temp_free_i32(t1);
7371 tcg_gen_andi_i32(t0, t0, 1);
7372 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7373 }
fd4a04eb 7374 opn = "bc1any2t";
5a5012ec
TS
7375 goto not_likely;
7376 case OPC_BC1FANY4:
a16336e4 7377 {
d94536f4
AJ
7378 TCGv_i32 t1 = tcg_temp_new_i32();
7379 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7380 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7381 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7382 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7383 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7384 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7385 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7386 tcg_temp_free_i32(t1);
d94536f4
AJ
7387 tcg_gen_andi_i32(t0, t0, 1);
7388 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7389 }
fd4a04eb 7390 opn = "bc1any4f";
5a5012ec
TS
7391 goto not_likely;
7392 case OPC_BC1TANY4:
a16336e4 7393 {
d94536f4
AJ
7394 TCGv_i32 t1 = tcg_temp_new_i32();
7395 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7396 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7397 tcg_gen_or_i32(t0, t0, t1);
7398 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7399 tcg_gen_or_i32(t0, t0, t1);
7400 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7401 tcg_gen_or_i32(t0, t0, t1);
7402 tcg_temp_free_i32(t1);
7403 tcg_gen_andi_i32(t0, t0, 1);
7404 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7405 }
fd4a04eb 7406 opn = "bc1any4t";
5a5012ec
TS
7407 not_likely:
7408 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7409 break;
7410 default:
923617a3 7411 MIPS_INVAL(opn);
e397ee33 7412 generate_exception (ctx, EXCP_RI);
6c5c1e20 7413 goto out;
6ea83fed 7414 }
2abf314d 7415 (void)opn; /* avoid a compiler warning */
923617a3 7416 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7417 ctx->hflags, btarget);
7418 ctx->btarget = btarget;
6c5c1e20
TS
7419
7420 out:
a7812ae4 7421 tcg_temp_free_i32(t0);
6ea83fed
FB
7422}
7423
6af0bf9c 7424/* Coprocessor 1 (FPU) */
5a5012ec 7425
5a5012ec
TS
7426#define FOP(func, fmt) (((fmt) << 21) | (func))
7427
bf4120ad
NF
7428enum fopcode {
7429 OPC_ADD_S = FOP(0, FMT_S),
7430 OPC_SUB_S = FOP(1, FMT_S),
7431 OPC_MUL_S = FOP(2, FMT_S),
7432 OPC_DIV_S = FOP(3, FMT_S),
7433 OPC_SQRT_S = FOP(4, FMT_S),
7434 OPC_ABS_S = FOP(5, FMT_S),
7435 OPC_MOV_S = FOP(6, FMT_S),
7436 OPC_NEG_S = FOP(7, FMT_S),
7437 OPC_ROUND_L_S = FOP(8, FMT_S),
7438 OPC_TRUNC_L_S = FOP(9, FMT_S),
7439 OPC_CEIL_L_S = FOP(10, FMT_S),
7440 OPC_FLOOR_L_S = FOP(11, FMT_S),
7441 OPC_ROUND_W_S = FOP(12, FMT_S),
7442 OPC_TRUNC_W_S = FOP(13, FMT_S),
7443 OPC_CEIL_W_S = FOP(14, FMT_S),
7444 OPC_FLOOR_W_S = FOP(15, FMT_S),
7445 OPC_MOVCF_S = FOP(17, FMT_S),
7446 OPC_MOVZ_S = FOP(18, FMT_S),
7447 OPC_MOVN_S = FOP(19, FMT_S),
7448 OPC_RECIP_S = FOP(21, FMT_S),
7449 OPC_RSQRT_S = FOP(22, FMT_S),
7450 OPC_RECIP2_S = FOP(28, FMT_S),
7451 OPC_RECIP1_S = FOP(29, FMT_S),
7452 OPC_RSQRT1_S = FOP(30, FMT_S),
7453 OPC_RSQRT2_S = FOP(31, FMT_S),
7454 OPC_CVT_D_S = FOP(33, FMT_S),
7455 OPC_CVT_W_S = FOP(36, FMT_S),
7456 OPC_CVT_L_S = FOP(37, FMT_S),
7457 OPC_CVT_PS_S = FOP(38, FMT_S),
7458 OPC_CMP_F_S = FOP (48, FMT_S),
7459 OPC_CMP_UN_S = FOP (49, FMT_S),
7460 OPC_CMP_EQ_S = FOP (50, FMT_S),
7461 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7462 OPC_CMP_OLT_S = FOP (52, FMT_S),
7463 OPC_CMP_ULT_S = FOP (53, FMT_S),
7464 OPC_CMP_OLE_S = FOP (54, FMT_S),
7465 OPC_CMP_ULE_S = FOP (55, FMT_S),
7466 OPC_CMP_SF_S = FOP (56, FMT_S),
7467 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7468 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7469 OPC_CMP_NGL_S = FOP (59, FMT_S),
7470 OPC_CMP_LT_S = FOP (60, FMT_S),
7471 OPC_CMP_NGE_S = FOP (61, FMT_S),
7472 OPC_CMP_LE_S = FOP (62, FMT_S),
7473 OPC_CMP_NGT_S = FOP (63, FMT_S),
7474
7475 OPC_ADD_D = FOP(0, FMT_D),
7476 OPC_SUB_D = FOP(1, FMT_D),
7477 OPC_MUL_D = FOP(2, FMT_D),
7478 OPC_DIV_D = FOP(3, FMT_D),
7479 OPC_SQRT_D = FOP(4, FMT_D),
7480 OPC_ABS_D = FOP(5, FMT_D),
7481 OPC_MOV_D = FOP(6, FMT_D),
7482 OPC_NEG_D = FOP(7, FMT_D),
7483 OPC_ROUND_L_D = FOP(8, FMT_D),
7484 OPC_TRUNC_L_D = FOP(9, FMT_D),
7485 OPC_CEIL_L_D = FOP(10, FMT_D),
7486 OPC_FLOOR_L_D = FOP(11, FMT_D),
7487 OPC_ROUND_W_D = FOP(12, FMT_D),
7488 OPC_TRUNC_W_D = FOP(13, FMT_D),
7489 OPC_CEIL_W_D = FOP(14, FMT_D),
7490 OPC_FLOOR_W_D = FOP(15, FMT_D),
7491 OPC_MOVCF_D = FOP(17, FMT_D),
7492 OPC_MOVZ_D = FOP(18, FMT_D),
7493 OPC_MOVN_D = FOP(19, FMT_D),
7494 OPC_RECIP_D = FOP(21, FMT_D),
7495 OPC_RSQRT_D = FOP(22, FMT_D),
7496 OPC_RECIP2_D = FOP(28, FMT_D),
7497 OPC_RECIP1_D = FOP(29, FMT_D),
7498 OPC_RSQRT1_D = FOP(30, FMT_D),
7499 OPC_RSQRT2_D = FOP(31, FMT_D),
7500 OPC_CVT_S_D = FOP(32, FMT_D),
7501 OPC_CVT_W_D = FOP(36, FMT_D),
7502 OPC_CVT_L_D = FOP(37, FMT_D),
7503 OPC_CMP_F_D = FOP (48, FMT_D),
7504 OPC_CMP_UN_D = FOP (49, FMT_D),
7505 OPC_CMP_EQ_D = FOP (50, FMT_D),
7506 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7507 OPC_CMP_OLT_D = FOP (52, FMT_D),
7508 OPC_CMP_ULT_D = FOP (53, FMT_D),
7509 OPC_CMP_OLE_D = FOP (54, FMT_D),
7510 OPC_CMP_ULE_D = FOP (55, FMT_D),
7511 OPC_CMP_SF_D = FOP (56, FMT_D),
7512 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7513 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7514 OPC_CMP_NGL_D = FOP (59, FMT_D),
7515 OPC_CMP_LT_D = FOP (60, FMT_D),
7516 OPC_CMP_NGE_D = FOP (61, FMT_D),
7517 OPC_CMP_LE_D = FOP (62, FMT_D),
7518 OPC_CMP_NGT_D = FOP (63, FMT_D),
7519
7520 OPC_CVT_S_W = FOP(32, FMT_W),
7521 OPC_CVT_D_W = FOP(33, FMT_W),
7522 OPC_CVT_S_L = FOP(32, FMT_L),
7523 OPC_CVT_D_L = FOP(33, FMT_L),
7524 OPC_CVT_PS_PW = FOP(38, FMT_W),
7525
7526 OPC_ADD_PS = FOP(0, FMT_PS),
7527 OPC_SUB_PS = FOP(1, FMT_PS),
7528 OPC_MUL_PS = FOP(2, FMT_PS),
7529 OPC_DIV_PS = FOP(3, FMT_PS),
7530 OPC_ABS_PS = FOP(5, FMT_PS),
7531 OPC_MOV_PS = FOP(6, FMT_PS),
7532 OPC_NEG_PS = FOP(7, FMT_PS),
7533 OPC_MOVCF_PS = FOP(17, FMT_PS),
7534 OPC_MOVZ_PS = FOP(18, FMT_PS),
7535 OPC_MOVN_PS = FOP(19, FMT_PS),
7536 OPC_ADDR_PS = FOP(24, FMT_PS),
7537 OPC_MULR_PS = FOP(26, FMT_PS),
7538 OPC_RECIP2_PS = FOP(28, FMT_PS),
7539 OPC_RECIP1_PS = FOP(29, FMT_PS),
7540 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7541 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7542
7543 OPC_CVT_S_PU = FOP(32, FMT_PS),
7544 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7545 OPC_CVT_S_PL = FOP(40, FMT_PS),
7546 OPC_PLL_PS = FOP(44, FMT_PS),
7547 OPC_PLU_PS = FOP(45, FMT_PS),
7548 OPC_PUL_PS = FOP(46, FMT_PS),
7549 OPC_PUU_PS = FOP(47, FMT_PS),
7550 OPC_CMP_F_PS = FOP (48, FMT_PS),
7551 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7552 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7553 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7554 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7555 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7556 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7557 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7558 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7559 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7560 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7561 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7562 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7563 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7564 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7565 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7566};
7567
7a387fff 7568static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7569{
923617a3 7570 const char *opn = "cp1 move";
72c3a3ee 7571 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7572
7573 switch (opc) {
7574 case OPC_MFC1:
b6d96bed 7575 {
a7812ae4 7576 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7577
7578 gen_load_fpr32(fp0, fs);
7579 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7580 tcg_temp_free_i32(fp0);
6958549d 7581 }
6c5c1e20 7582 gen_store_gpr(t0, rt);
6ea83fed
FB
7583 opn = "mfc1";
7584 break;
7585 case OPC_MTC1:
6c5c1e20 7586 gen_load_gpr(t0, rt);
b6d96bed 7587 {
a7812ae4 7588 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7589
7590 tcg_gen_trunc_tl_i32(fp0, t0);
7591 gen_store_fpr32(fp0, fs);
a7812ae4 7592 tcg_temp_free_i32(fp0);
6958549d 7593 }
6ea83fed
FB
7594 opn = "mtc1";
7595 break;
7596 case OPC_CFC1:
895c2d04 7597 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7598 gen_store_gpr(t0, rt);
6ea83fed
FB
7599 opn = "cfc1";
7600 break;
7601 case OPC_CTC1:
6c5c1e20 7602 gen_load_gpr(t0, rt);
736d120a
PJ
7603 {
7604 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7605
7606 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7607 tcg_temp_free_i32(fs_tmp);
7608 }
6ea83fed
FB
7609 opn = "ctc1";
7610 break;
72c3a3ee 7611#if defined(TARGET_MIPS64)
9c2149c8 7612 case OPC_DMFC1:
72c3a3ee 7613 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7614 gen_store_gpr(t0, rt);
5a5012ec
TS
7615 opn = "dmfc1";
7616 break;
9c2149c8 7617 case OPC_DMTC1:
6c5c1e20 7618 gen_load_gpr(t0, rt);
72c3a3ee 7619 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7620 opn = "dmtc1";
7621 break;
72c3a3ee 7622#endif
5a5012ec 7623 case OPC_MFHC1:
b6d96bed 7624 {
a7812ae4 7625 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7626
7f6613ce 7627 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 7628 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7629 tcg_temp_free_i32(fp0);
6958549d 7630 }
6c5c1e20 7631 gen_store_gpr(t0, rt);
5a5012ec
TS
7632 opn = "mfhc1";
7633 break;
7634 case OPC_MTHC1:
6c5c1e20 7635 gen_load_gpr(t0, rt);
b6d96bed 7636 {
a7812ae4 7637 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7638
7639 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7640 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 7641 tcg_temp_free_i32(fp0);
6958549d 7642 }
5a5012ec
TS
7643 opn = "mthc1";
7644 break;
6ea83fed 7645 default:
923617a3 7646 MIPS_INVAL(opn);
e397ee33 7647 generate_exception (ctx, EXCP_RI);
6c5c1e20 7648 goto out;
6ea83fed 7649 }
2abf314d 7650 (void)opn; /* avoid a compiler warning */
6ea83fed 7651 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7652
7653 out:
7654 tcg_temp_free(t0);
6ea83fed
FB
7655}
7656
5a5012ec
TS
7657static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7658{
af58f9ca 7659 int l1;
e214b9bb 7660 TCGCond cond;
af58f9ca
AJ
7661 TCGv_i32 t0;
7662
7663 if (rd == 0) {
7664 /* Treat as NOP. */
7665 return;
7666 }
6ea83fed 7667
e214b9bb 7668 if (tf)
e214b9bb 7669 cond = TCG_COND_EQ;
27848470
TS
7670 else
7671 cond = TCG_COND_NE;
7672
af58f9ca
AJ
7673 l1 = gen_new_label();
7674 t0 = tcg_temp_new_i32();
fa31af0e 7675 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7676 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7677 tcg_temp_free_i32(t0);
af58f9ca
AJ
7678 if (rs == 0) {
7679 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7680 } else {
7681 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7682 }
e214b9bb 7683 gen_set_label(l1);
5a5012ec
TS
7684}
7685
b6d96bed 7686static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7687{
a16336e4 7688 int cond;
cbc37b28 7689 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7690 int l1 = gen_new_label();
7691
a16336e4
TS
7692 if (tf)
7693 cond = TCG_COND_EQ;
7694 else
7695 cond = TCG_COND_NE;
7696
fa31af0e 7697 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7698 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7699 gen_load_fpr32(t0, fs);
7700 gen_store_fpr32(t0, fd);
a16336e4 7701 gen_set_label(l1);
cbc37b28 7702 tcg_temp_free_i32(t0);
5a5012ec 7703}
a16336e4 7704
b6d96bed 7705static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7706{
a16336e4 7707 int cond;
cbc37b28
AJ
7708 TCGv_i32 t0 = tcg_temp_new_i32();
7709 TCGv_i64 fp0;
a16336e4
TS
7710 int l1 = gen_new_label();
7711
a16336e4
TS
7712 if (tf)
7713 cond = TCG_COND_EQ;
7714 else
7715 cond = TCG_COND_NE;
7716
fa31af0e 7717 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7718 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7719 tcg_temp_free_i32(t0);
11f94258 7720 fp0 = tcg_temp_new_i64();
9bf3eb2c 7721 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7722 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7723 tcg_temp_free_i64(fp0);
cbc37b28 7724 gen_set_label(l1);
a16336e4
TS
7725}
7726
7f6613ce
PJ
7727static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
7728 int cc, int tf)
a16336e4
TS
7729{
7730 int cond;
cbc37b28 7731 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7732 int l1 = gen_new_label();
7733 int l2 = gen_new_label();
7734
7735 if (tf)
7736 cond = TCG_COND_EQ;
7737 else
7738 cond = TCG_COND_NE;
7739
fa31af0e 7740 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7741 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7742 gen_load_fpr32(t0, fs);
7743 gen_store_fpr32(t0, fd);
a16336e4 7744 gen_set_label(l1);
9bf3eb2c 7745
fa31af0e 7746 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 7747 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
7748 gen_load_fpr32h(ctx, t0, fs);
7749 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 7750 tcg_temp_free_i32(t0);
a16336e4 7751 gen_set_label(l2);
a16336e4
TS
7752}
7753
6ea83fed 7754
bf4120ad 7755static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7756 int ft, int fs, int fd, int cc)
6ea83fed 7757{
923617a3 7758 const char *opn = "farith";
6ea83fed
FB
7759 const char *condnames[] = {
7760 "c.f",
7761 "c.un",
7762 "c.eq",
7763 "c.ueq",
7764 "c.olt",
7765 "c.ult",
7766 "c.ole",
7767 "c.ule",
7768 "c.sf",
7769 "c.ngle",
7770 "c.seq",
7771 "c.ngl",
7772 "c.lt",
7773 "c.nge",
7774 "c.le",
7775 "c.ngt",
7776 };
5a1e8ffb
TS
7777 const char *condnames_abs[] = {
7778 "cabs.f",
7779 "cabs.un",
7780 "cabs.eq",
7781 "cabs.ueq",
7782 "cabs.olt",
7783 "cabs.ult",
7784 "cabs.ole",
7785 "cabs.ule",
7786 "cabs.sf",
7787 "cabs.ngle",
7788 "cabs.seq",
7789 "cabs.ngl",
7790 "cabs.lt",
7791 "cabs.nge",
7792 "cabs.le",
7793 "cabs.ngt",
7794 };
7795 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7796 uint32_t func = ctx->opcode & 0x3f;
7797
bf4120ad
NF
7798 switch (op1) {
7799 case OPC_ADD_S:
b6d96bed 7800 {
a7812ae4
PB
7801 TCGv_i32 fp0 = tcg_temp_new_i32();
7802 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7803
7804 gen_load_fpr32(fp0, fs);
7805 gen_load_fpr32(fp1, ft);
895c2d04 7806 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7807 tcg_temp_free_i32(fp1);
b6d96bed 7808 gen_store_fpr32(fp0, fd);
a7812ae4 7809 tcg_temp_free_i32(fp0);
b6d96bed 7810 }
5a5012ec 7811 opn = "add.s";
5a1e8ffb 7812 optype = BINOP;
5a5012ec 7813 break;
bf4120ad 7814 case OPC_SUB_S:
b6d96bed 7815 {
a7812ae4
PB
7816 TCGv_i32 fp0 = tcg_temp_new_i32();
7817 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7818
7819 gen_load_fpr32(fp0, fs);
7820 gen_load_fpr32(fp1, ft);
895c2d04 7821 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7822 tcg_temp_free_i32(fp1);
b6d96bed 7823 gen_store_fpr32(fp0, fd);
a7812ae4 7824 tcg_temp_free_i32(fp0);
b6d96bed 7825 }
5a5012ec 7826 opn = "sub.s";
5a1e8ffb 7827 optype = BINOP;
5a5012ec 7828 break;
bf4120ad 7829 case OPC_MUL_S:
b6d96bed 7830 {
a7812ae4
PB
7831 TCGv_i32 fp0 = tcg_temp_new_i32();
7832 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7833
7834 gen_load_fpr32(fp0, fs);
7835 gen_load_fpr32(fp1, ft);
895c2d04 7836 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7837 tcg_temp_free_i32(fp1);
b6d96bed 7838 gen_store_fpr32(fp0, fd);
a7812ae4 7839 tcg_temp_free_i32(fp0);
b6d96bed 7840 }
5a5012ec 7841 opn = "mul.s";
5a1e8ffb 7842 optype = BINOP;
5a5012ec 7843 break;
bf4120ad 7844 case OPC_DIV_S:
b6d96bed 7845 {
a7812ae4
PB
7846 TCGv_i32 fp0 = tcg_temp_new_i32();
7847 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7848
7849 gen_load_fpr32(fp0, fs);
7850 gen_load_fpr32(fp1, ft);
895c2d04 7851 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7852 tcg_temp_free_i32(fp1);
b6d96bed 7853 gen_store_fpr32(fp0, fd);
a7812ae4 7854 tcg_temp_free_i32(fp0);
b6d96bed 7855 }
5a5012ec 7856 opn = "div.s";
5a1e8ffb 7857 optype = BINOP;
5a5012ec 7858 break;
bf4120ad 7859 case OPC_SQRT_S:
b6d96bed 7860 {
a7812ae4 7861 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7862
7863 gen_load_fpr32(fp0, fs);
895c2d04 7864 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7865 gen_store_fpr32(fp0, fd);
a7812ae4 7866 tcg_temp_free_i32(fp0);
b6d96bed 7867 }
5a5012ec
TS
7868 opn = "sqrt.s";
7869 break;
bf4120ad 7870 case OPC_ABS_S:
b6d96bed 7871 {
a7812ae4 7872 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7873
7874 gen_load_fpr32(fp0, fs);
a7812ae4 7875 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7876 gen_store_fpr32(fp0, fd);
a7812ae4 7877 tcg_temp_free_i32(fp0);
b6d96bed 7878 }
5a5012ec
TS
7879 opn = "abs.s";
7880 break;
bf4120ad 7881 case OPC_MOV_S:
b6d96bed 7882 {
a7812ae4 7883 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7884
7885 gen_load_fpr32(fp0, fs);
7886 gen_store_fpr32(fp0, fd);
a7812ae4 7887 tcg_temp_free_i32(fp0);
b6d96bed 7888 }
5a5012ec
TS
7889 opn = "mov.s";
7890 break;
bf4120ad 7891 case OPC_NEG_S:
b6d96bed 7892 {
a7812ae4 7893 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7894
7895 gen_load_fpr32(fp0, fs);
a7812ae4 7896 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7897 gen_store_fpr32(fp0, fd);
a7812ae4 7898 tcg_temp_free_i32(fp0);
b6d96bed 7899 }
5a5012ec
TS
7900 opn = "neg.s";
7901 break;
bf4120ad 7902 case OPC_ROUND_L_S:
5e755519 7903 check_cp1_64bitmode(ctx);
b6d96bed 7904 {
a7812ae4
PB
7905 TCGv_i32 fp32 = tcg_temp_new_i32();
7906 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7907
7908 gen_load_fpr32(fp32, fs);
895c2d04 7909 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7910 tcg_temp_free_i32(fp32);
b6d96bed 7911 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7912 tcg_temp_free_i64(fp64);
b6d96bed 7913 }
5a5012ec
TS
7914 opn = "round.l.s";
7915 break;
bf4120ad 7916 case OPC_TRUNC_L_S:
5e755519 7917 check_cp1_64bitmode(ctx);
b6d96bed 7918 {
a7812ae4
PB
7919 TCGv_i32 fp32 = tcg_temp_new_i32();
7920 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7921
7922 gen_load_fpr32(fp32, fs);
895c2d04 7923 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7924 tcg_temp_free_i32(fp32);
b6d96bed 7925 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7926 tcg_temp_free_i64(fp64);
b6d96bed 7927 }
5a5012ec
TS
7928 opn = "trunc.l.s";
7929 break;
bf4120ad 7930 case OPC_CEIL_L_S:
5e755519 7931 check_cp1_64bitmode(ctx);
b6d96bed 7932 {
a7812ae4
PB
7933 TCGv_i32 fp32 = tcg_temp_new_i32();
7934 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7935
7936 gen_load_fpr32(fp32, fs);
895c2d04 7937 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7938 tcg_temp_free_i32(fp32);
b6d96bed 7939 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7940 tcg_temp_free_i64(fp64);
b6d96bed 7941 }
5a5012ec
TS
7942 opn = "ceil.l.s";
7943 break;
bf4120ad 7944 case OPC_FLOOR_L_S:
5e755519 7945 check_cp1_64bitmode(ctx);
b6d96bed 7946 {
a7812ae4
PB
7947 TCGv_i32 fp32 = tcg_temp_new_i32();
7948 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7949
7950 gen_load_fpr32(fp32, fs);
895c2d04 7951 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7952 tcg_temp_free_i32(fp32);
b6d96bed 7953 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7954 tcg_temp_free_i64(fp64);
b6d96bed 7955 }
5a5012ec
TS
7956 opn = "floor.l.s";
7957 break;
bf4120ad 7958 case OPC_ROUND_W_S:
b6d96bed 7959 {
a7812ae4 7960 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7961
7962 gen_load_fpr32(fp0, fs);
895c2d04 7963 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7964 gen_store_fpr32(fp0, fd);
a7812ae4 7965 tcg_temp_free_i32(fp0);
b6d96bed 7966 }
5a5012ec
TS
7967 opn = "round.w.s";
7968 break;
bf4120ad 7969 case OPC_TRUNC_W_S:
b6d96bed 7970 {
a7812ae4 7971 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7972
7973 gen_load_fpr32(fp0, fs);
895c2d04 7974 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7975 gen_store_fpr32(fp0, fd);
a7812ae4 7976 tcg_temp_free_i32(fp0);
b6d96bed 7977 }
5a5012ec
TS
7978 opn = "trunc.w.s";
7979 break;
bf4120ad 7980 case OPC_CEIL_W_S:
b6d96bed 7981 {
a7812ae4 7982 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7983
7984 gen_load_fpr32(fp0, fs);
895c2d04 7985 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7986 gen_store_fpr32(fp0, fd);
a7812ae4 7987 tcg_temp_free_i32(fp0);
b6d96bed 7988 }
5a5012ec
TS
7989 opn = "ceil.w.s";
7990 break;
bf4120ad 7991 case OPC_FLOOR_W_S:
b6d96bed 7992 {
a7812ae4 7993 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7994
7995 gen_load_fpr32(fp0, fs);
895c2d04 7996 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7997 gen_store_fpr32(fp0, fd);
a7812ae4 7998 tcg_temp_free_i32(fp0);
b6d96bed 7999 }
5a5012ec
TS
8000 opn = "floor.w.s";
8001 break;
bf4120ad 8002 case OPC_MOVCF_S:
fecd2646 8003 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8004 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
8005 opn = "movcf.s";
8006 break;
bf4120ad 8007 case OPC_MOVZ_S:
fecd2646 8008 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8009 {
8010 int l1 = gen_new_label();
c9297f4d 8011 TCGv_i32 fp0;
a16336e4 8012
c9297f4d
AJ
8013 if (ft != 0) {
8014 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8015 }
8016 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8017 gen_load_fpr32(fp0, fs);
8018 gen_store_fpr32(fp0, fd);
a7812ae4 8019 tcg_temp_free_i32(fp0);
a16336e4
TS
8020 gen_set_label(l1);
8021 }
5a5012ec
TS
8022 opn = "movz.s";
8023 break;
bf4120ad 8024 case OPC_MOVN_S:
fecd2646 8025 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8026 {
8027 int l1 = gen_new_label();
c9297f4d
AJ
8028 TCGv_i32 fp0;
8029
8030 if (ft != 0) {
8031 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8032 fp0 = tcg_temp_new_i32();
8033 gen_load_fpr32(fp0, fs);
8034 gen_store_fpr32(fp0, fd);
8035 tcg_temp_free_i32(fp0);
8036 gen_set_label(l1);
8037 }
a16336e4 8038 }
5a5012ec
TS
8039 opn = "movn.s";
8040 break;
bf4120ad 8041 case OPC_RECIP_S:
b8aa4598 8042 check_cop1x(ctx);
b6d96bed 8043 {
a7812ae4 8044 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8045
8046 gen_load_fpr32(fp0, fs);
895c2d04 8047 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 8048 gen_store_fpr32(fp0, fd);
a7812ae4 8049 tcg_temp_free_i32(fp0);
b6d96bed 8050 }
57fa1fb3
TS
8051 opn = "recip.s";
8052 break;
bf4120ad 8053 case OPC_RSQRT_S:
b8aa4598 8054 check_cop1x(ctx);
b6d96bed 8055 {
a7812ae4 8056 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8057
8058 gen_load_fpr32(fp0, fs);
895c2d04 8059 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 8060 gen_store_fpr32(fp0, fd);
a7812ae4 8061 tcg_temp_free_i32(fp0);
b6d96bed 8062 }
57fa1fb3
TS
8063 opn = "rsqrt.s";
8064 break;
bf4120ad 8065 case OPC_RECIP2_S:
5e755519 8066 check_cp1_64bitmode(ctx);
b6d96bed 8067 {
a7812ae4
PB
8068 TCGv_i32 fp0 = tcg_temp_new_i32();
8069 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8070
8071 gen_load_fpr32(fp0, fs);
d22d7289 8072 gen_load_fpr32(fp1, ft);
895c2d04 8073 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8074 tcg_temp_free_i32(fp1);
b6d96bed 8075 gen_store_fpr32(fp0, fd);
a7812ae4 8076 tcg_temp_free_i32(fp0);
b6d96bed 8077 }
57fa1fb3
TS
8078 opn = "recip2.s";
8079 break;
bf4120ad 8080 case OPC_RECIP1_S:
5e755519 8081 check_cp1_64bitmode(ctx);
b6d96bed 8082 {
a7812ae4 8083 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8084
8085 gen_load_fpr32(fp0, fs);
895c2d04 8086 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 8087 gen_store_fpr32(fp0, fd);
a7812ae4 8088 tcg_temp_free_i32(fp0);
b6d96bed 8089 }
57fa1fb3
TS
8090 opn = "recip1.s";
8091 break;
bf4120ad 8092 case OPC_RSQRT1_S:
5e755519 8093 check_cp1_64bitmode(ctx);
b6d96bed 8094 {
a7812ae4 8095 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8096
8097 gen_load_fpr32(fp0, fs);
895c2d04 8098 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 8099 gen_store_fpr32(fp0, fd);
a7812ae4 8100 tcg_temp_free_i32(fp0);
b6d96bed 8101 }
57fa1fb3
TS
8102 opn = "rsqrt1.s";
8103 break;
bf4120ad 8104 case OPC_RSQRT2_S:
5e755519 8105 check_cp1_64bitmode(ctx);
b6d96bed 8106 {
a7812ae4
PB
8107 TCGv_i32 fp0 = tcg_temp_new_i32();
8108 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8109
8110 gen_load_fpr32(fp0, fs);
8111 gen_load_fpr32(fp1, ft);
895c2d04 8112 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8113 tcg_temp_free_i32(fp1);
b6d96bed 8114 gen_store_fpr32(fp0, fd);
a7812ae4 8115 tcg_temp_free_i32(fp0);
b6d96bed 8116 }
57fa1fb3
TS
8117 opn = "rsqrt2.s";
8118 break;
bf4120ad 8119 case OPC_CVT_D_S:
5e755519 8120 check_cp1_registers(ctx, fd);
b6d96bed 8121 {
a7812ae4
PB
8122 TCGv_i32 fp32 = tcg_temp_new_i32();
8123 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8124
8125 gen_load_fpr32(fp32, fs);
895c2d04 8126 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 8127 tcg_temp_free_i32(fp32);
b6d96bed 8128 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8129 tcg_temp_free_i64(fp64);
b6d96bed 8130 }
5a5012ec
TS
8131 opn = "cvt.d.s";
8132 break;
bf4120ad 8133 case OPC_CVT_W_S:
b6d96bed 8134 {
a7812ae4 8135 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8136
8137 gen_load_fpr32(fp0, fs);
895c2d04 8138 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 8139 gen_store_fpr32(fp0, fd);
a7812ae4 8140 tcg_temp_free_i32(fp0);
b6d96bed 8141 }
5a5012ec
TS
8142 opn = "cvt.w.s";
8143 break;
bf4120ad 8144 case OPC_CVT_L_S:
5e755519 8145 check_cp1_64bitmode(ctx);
b6d96bed 8146 {
a7812ae4
PB
8147 TCGv_i32 fp32 = tcg_temp_new_i32();
8148 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8149
8150 gen_load_fpr32(fp32, fs);
895c2d04 8151 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 8152 tcg_temp_free_i32(fp32);
b6d96bed 8153 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8154 tcg_temp_free_i64(fp64);
b6d96bed 8155 }
5a5012ec
TS
8156 opn = "cvt.l.s";
8157 break;
bf4120ad 8158 case OPC_CVT_PS_S:
fecd2646 8159 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 8160 check_cp1_64bitmode(ctx);
b6d96bed 8161 {
a7812ae4
PB
8162 TCGv_i64 fp64 = tcg_temp_new_i64();
8163 TCGv_i32 fp32_0 = tcg_temp_new_i32();
8164 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
8165
8166 gen_load_fpr32(fp32_0, fs);
8167 gen_load_fpr32(fp32_1, ft);
13d24f49 8168 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
8169 tcg_temp_free_i32(fp32_1);
8170 tcg_temp_free_i32(fp32_0);
36aa55dc 8171 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8172 tcg_temp_free_i64(fp64);
b6d96bed 8173 }
5a5012ec
TS
8174 opn = "cvt.ps.s";
8175 break;
bf4120ad
NF
8176 case OPC_CMP_F_S:
8177 case OPC_CMP_UN_S:
8178 case OPC_CMP_EQ_S:
8179 case OPC_CMP_UEQ_S:
8180 case OPC_CMP_OLT_S:
8181 case OPC_CMP_ULT_S:
8182 case OPC_CMP_OLE_S:
8183 case OPC_CMP_ULE_S:
8184 case OPC_CMP_SF_S:
8185 case OPC_CMP_NGLE_S:
8186 case OPC_CMP_SEQ_S:
8187 case OPC_CMP_NGL_S:
8188 case OPC_CMP_LT_S:
8189 case OPC_CMP_NGE_S:
8190 case OPC_CMP_LE_S:
8191 case OPC_CMP_NGT_S:
fecd2646 8192 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
8193 if (ctx->opcode & (1 << 6)) {
8194 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8195 opn = condnames_abs[func-48];
8196 } else {
8197 gen_cmp_s(ctx, func-48, ft, fs, cc);
8198 opn = condnames[func-48];
5a1e8ffb 8199 }
5a5012ec 8200 break;
bf4120ad 8201 case OPC_ADD_D:
5e755519 8202 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8203 {
a7812ae4
PB
8204 TCGv_i64 fp0 = tcg_temp_new_i64();
8205 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8206
8207 gen_load_fpr64(ctx, fp0, fs);
8208 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8209 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8210 tcg_temp_free_i64(fp1);
b6d96bed 8211 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8212 tcg_temp_free_i64(fp0);
b6d96bed 8213 }
6ea83fed 8214 opn = "add.d";
5a1e8ffb 8215 optype = BINOP;
6ea83fed 8216 break;
bf4120ad 8217 case OPC_SUB_D:
5e755519 8218 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8219 {
a7812ae4
PB
8220 TCGv_i64 fp0 = tcg_temp_new_i64();
8221 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8222
8223 gen_load_fpr64(ctx, fp0, fs);
8224 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8225 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8226 tcg_temp_free_i64(fp1);
b6d96bed 8227 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8228 tcg_temp_free_i64(fp0);
b6d96bed 8229 }
6ea83fed 8230 opn = "sub.d";
5a1e8ffb 8231 optype = BINOP;
6ea83fed 8232 break;
bf4120ad 8233 case OPC_MUL_D:
5e755519 8234 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8235 {
a7812ae4
PB
8236 TCGv_i64 fp0 = tcg_temp_new_i64();
8237 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8238
8239 gen_load_fpr64(ctx, fp0, fs);
8240 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8241 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8242 tcg_temp_free_i64(fp1);
b6d96bed 8243 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8244 tcg_temp_free_i64(fp0);
b6d96bed 8245 }
6ea83fed 8246 opn = "mul.d";
5a1e8ffb 8247 optype = BINOP;
6ea83fed 8248 break;
bf4120ad 8249 case OPC_DIV_D:
5e755519 8250 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8251 {
a7812ae4
PB
8252 TCGv_i64 fp0 = tcg_temp_new_i64();
8253 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8254
8255 gen_load_fpr64(ctx, fp0, fs);
8256 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8257 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8258 tcg_temp_free_i64(fp1);
b6d96bed 8259 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8260 tcg_temp_free_i64(fp0);
b6d96bed 8261 }
6ea83fed 8262 opn = "div.d";
5a1e8ffb 8263 optype = BINOP;
6ea83fed 8264 break;
bf4120ad 8265 case OPC_SQRT_D:
5e755519 8266 check_cp1_registers(ctx, fs | fd);
b6d96bed 8267 {
a7812ae4 8268 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8269
8270 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8271 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 8272 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8273 tcg_temp_free_i64(fp0);
b6d96bed 8274 }
6ea83fed
FB
8275 opn = "sqrt.d";
8276 break;
bf4120ad 8277 case OPC_ABS_D:
5e755519 8278 check_cp1_registers(ctx, fs | fd);
b6d96bed 8279 {
a7812ae4 8280 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8281
8282 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8283 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 8284 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8285 tcg_temp_free_i64(fp0);
b6d96bed 8286 }
6ea83fed
FB
8287 opn = "abs.d";
8288 break;
bf4120ad 8289 case OPC_MOV_D:
5e755519 8290 check_cp1_registers(ctx, fs | fd);
b6d96bed 8291 {
a7812ae4 8292 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8293
8294 gen_load_fpr64(ctx, fp0, fs);
8295 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8296 tcg_temp_free_i64(fp0);
b6d96bed 8297 }
6ea83fed
FB
8298 opn = "mov.d";
8299 break;
bf4120ad 8300 case OPC_NEG_D:
5e755519 8301 check_cp1_registers(ctx, fs | fd);
b6d96bed 8302 {
a7812ae4 8303 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8304
8305 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8306 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 8307 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8308 tcg_temp_free_i64(fp0);
b6d96bed 8309 }
6ea83fed
FB
8310 opn = "neg.d";
8311 break;
bf4120ad 8312 case OPC_ROUND_L_D:
5e755519 8313 check_cp1_64bitmode(ctx);
b6d96bed 8314 {
a7812ae4 8315 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8316
8317 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8318 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 8319 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8320 tcg_temp_free_i64(fp0);
b6d96bed 8321 }
5a5012ec
TS
8322 opn = "round.l.d";
8323 break;
bf4120ad 8324 case OPC_TRUNC_L_D:
5e755519 8325 check_cp1_64bitmode(ctx);
b6d96bed 8326 {
a7812ae4 8327 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8328
8329 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8330 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 8331 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8332 tcg_temp_free_i64(fp0);
b6d96bed 8333 }
5a5012ec
TS
8334 opn = "trunc.l.d";
8335 break;
bf4120ad 8336 case OPC_CEIL_L_D:
5e755519 8337 check_cp1_64bitmode(ctx);
b6d96bed 8338 {
a7812ae4 8339 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8340
8341 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8342 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8343 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8344 tcg_temp_free_i64(fp0);
b6d96bed 8345 }
5a5012ec
TS
8346 opn = "ceil.l.d";
8347 break;
bf4120ad 8348 case OPC_FLOOR_L_D:
5e755519 8349 check_cp1_64bitmode(ctx);
b6d96bed 8350 {
a7812ae4 8351 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8352
8353 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8354 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8355 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8356 tcg_temp_free_i64(fp0);
b6d96bed 8357 }
5a5012ec
TS
8358 opn = "floor.l.d";
8359 break;
bf4120ad 8360 case OPC_ROUND_W_D:
5e755519 8361 check_cp1_registers(ctx, fs);
b6d96bed 8362 {
a7812ae4
PB
8363 TCGv_i32 fp32 = tcg_temp_new_i32();
8364 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8365
8366 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8367 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8368 tcg_temp_free_i64(fp64);
b6d96bed 8369 gen_store_fpr32(fp32, fd);
a7812ae4 8370 tcg_temp_free_i32(fp32);
b6d96bed 8371 }
6ea83fed
FB
8372 opn = "round.w.d";
8373 break;
bf4120ad 8374 case OPC_TRUNC_W_D:
5e755519 8375 check_cp1_registers(ctx, fs);
b6d96bed 8376 {
a7812ae4
PB
8377 TCGv_i32 fp32 = tcg_temp_new_i32();
8378 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8379
8380 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8381 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8382 tcg_temp_free_i64(fp64);
b6d96bed 8383 gen_store_fpr32(fp32, fd);
a7812ae4 8384 tcg_temp_free_i32(fp32);
b6d96bed 8385 }
6ea83fed
FB
8386 opn = "trunc.w.d";
8387 break;
bf4120ad 8388 case OPC_CEIL_W_D:
5e755519 8389 check_cp1_registers(ctx, fs);
b6d96bed 8390 {
a7812ae4
PB
8391 TCGv_i32 fp32 = tcg_temp_new_i32();
8392 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8393
8394 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8395 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8396 tcg_temp_free_i64(fp64);
b6d96bed 8397 gen_store_fpr32(fp32, fd);
a7812ae4 8398 tcg_temp_free_i32(fp32);
b6d96bed 8399 }
6ea83fed
FB
8400 opn = "ceil.w.d";
8401 break;
bf4120ad 8402 case OPC_FLOOR_W_D:
5e755519 8403 check_cp1_registers(ctx, fs);
b6d96bed 8404 {
a7812ae4
PB
8405 TCGv_i32 fp32 = tcg_temp_new_i32();
8406 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8407
8408 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8409 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8410 tcg_temp_free_i64(fp64);
b6d96bed 8411 gen_store_fpr32(fp32, fd);
a7812ae4 8412 tcg_temp_free_i32(fp32);
b6d96bed 8413 }
7a387fff 8414 opn = "floor.w.d";
6ea83fed 8415 break;
bf4120ad 8416 case OPC_MOVCF_D:
fecd2646 8417 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8418 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8419 opn = "movcf.d";
dd016883 8420 break;
bf4120ad 8421 case OPC_MOVZ_D:
fecd2646 8422 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8423 {
8424 int l1 = gen_new_label();
c9297f4d 8425 TCGv_i64 fp0;
a16336e4 8426
c9297f4d
AJ
8427 if (ft != 0) {
8428 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8429 }
8430 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8431 gen_load_fpr64(ctx, fp0, fs);
8432 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8433 tcg_temp_free_i64(fp0);
a16336e4
TS
8434 gen_set_label(l1);
8435 }
5a5012ec
TS
8436 opn = "movz.d";
8437 break;
bf4120ad 8438 case OPC_MOVN_D:
fecd2646 8439 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8440 {
8441 int l1 = gen_new_label();
c9297f4d
AJ
8442 TCGv_i64 fp0;
8443
8444 if (ft != 0) {
8445 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8446 fp0 = tcg_temp_new_i64();
8447 gen_load_fpr64(ctx, fp0, fs);
8448 gen_store_fpr64(ctx, fp0, fd);
8449 tcg_temp_free_i64(fp0);
8450 gen_set_label(l1);
8451 }
a16336e4 8452 }
5a5012ec 8453 opn = "movn.d";
6ea83fed 8454 break;
bf4120ad 8455 case OPC_RECIP_D:
b8aa4598 8456 check_cp1_64bitmode(ctx);
b6d96bed 8457 {
a7812ae4 8458 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8459
8460 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8461 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8462 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8463 tcg_temp_free_i64(fp0);
b6d96bed 8464 }
57fa1fb3
TS
8465 opn = "recip.d";
8466 break;
bf4120ad 8467 case OPC_RSQRT_D:
b8aa4598 8468 check_cp1_64bitmode(ctx);
b6d96bed 8469 {
a7812ae4 8470 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8471
8472 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8473 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8474 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8475 tcg_temp_free_i64(fp0);
b6d96bed 8476 }
57fa1fb3
TS
8477 opn = "rsqrt.d";
8478 break;
bf4120ad 8479 case OPC_RECIP2_D:
5e755519 8480 check_cp1_64bitmode(ctx);
b6d96bed 8481 {
a7812ae4
PB
8482 TCGv_i64 fp0 = tcg_temp_new_i64();
8483 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8484
8485 gen_load_fpr64(ctx, fp0, fs);
8486 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8487 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8488 tcg_temp_free_i64(fp1);
b6d96bed 8489 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8490 tcg_temp_free_i64(fp0);
b6d96bed 8491 }
57fa1fb3
TS
8492 opn = "recip2.d";
8493 break;
bf4120ad 8494 case OPC_RECIP1_D:
5e755519 8495 check_cp1_64bitmode(ctx);
b6d96bed 8496 {
a7812ae4 8497 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8498
8499 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8500 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8501 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8502 tcg_temp_free_i64(fp0);
b6d96bed 8503 }
57fa1fb3
TS
8504 opn = "recip1.d";
8505 break;
bf4120ad 8506 case OPC_RSQRT1_D:
5e755519 8507 check_cp1_64bitmode(ctx);
b6d96bed 8508 {
a7812ae4 8509 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8510
8511 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8512 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8513 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8514 tcg_temp_free_i64(fp0);
b6d96bed 8515 }
57fa1fb3
TS
8516 opn = "rsqrt1.d";
8517 break;
bf4120ad 8518 case OPC_RSQRT2_D:
5e755519 8519 check_cp1_64bitmode(ctx);
b6d96bed 8520 {
a7812ae4
PB
8521 TCGv_i64 fp0 = tcg_temp_new_i64();
8522 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8523
8524 gen_load_fpr64(ctx, fp0, fs);
8525 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8526 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8527 tcg_temp_free_i64(fp1);
b6d96bed 8528 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8529 tcg_temp_free_i64(fp0);
b6d96bed 8530 }
57fa1fb3
TS
8531 opn = "rsqrt2.d";
8532 break;
bf4120ad
NF
8533 case OPC_CMP_F_D:
8534 case OPC_CMP_UN_D:
8535 case OPC_CMP_EQ_D:
8536 case OPC_CMP_UEQ_D:
8537 case OPC_CMP_OLT_D:
8538 case OPC_CMP_ULT_D:
8539 case OPC_CMP_OLE_D:
8540 case OPC_CMP_ULE_D:
8541 case OPC_CMP_SF_D:
8542 case OPC_CMP_NGLE_D:
8543 case OPC_CMP_SEQ_D:
8544 case OPC_CMP_NGL_D:
8545 case OPC_CMP_LT_D:
8546 case OPC_CMP_NGE_D:
8547 case OPC_CMP_LE_D:
8548 case OPC_CMP_NGT_D:
fecd2646 8549 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
8550 if (ctx->opcode & (1 << 6)) {
8551 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8552 opn = condnames_abs[func-48];
8553 } else {
8554 gen_cmp_d(ctx, func-48, ft, fs, cc);
8555 opn = condnames[func-48];
5a1e8ffb 8556 }
6ea83fed 8557 break;
bf4120ad 8558 case OPC_CVT_S_D:
5e755519 8559 check_cp1_registers(ctx, fs);
b6d96bed 8560 {
a7812ae4
PB
8561 TCGv_i32 fp32 = tcg_temp_new_i32();
8562 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8563
8564 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8565 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8566 tcg_temp_free_i64(fp64);
b6d96bed 8567 gen_store_fpr32(fp32, fd);
a7812ae4 8568 tcg_temp_free_i32(fp32);
b6d96bed 8569 }
5a5012ec
TS
8570 opn = "cvt.s.d";
8571 break;
bf4120ad 8572 case OPC_CVT_W_D:
5e755519 8573 check_cp1_registers(ctx, fs);
b6d96bed 8574 {
a7812ae4
PB
8575 TCGv_i32 fp32 = tcg_temp_new_i32();
8576 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8577
8578 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8579 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8580 tcg_temp_free_i64(fp64);
b6d96bed 8581 gen_store_fpr32(fp32, fd);
a7812ae4 8582 tcg_temp_free_i32(fp32);
b6d96bed 8583 }
5a5012ec
TS
8584 opn = "cvt.w.d";
8585 break;
bf4120ad 8586 case OPC_CVT_L_D:
5e755519 8587 check_cp1_64bitmode(ctx);
b6d96bed 8588 {
a7812ae4 8589 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8590
8591 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8592 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8593 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8594 tcg_temp_free_i64(fp0);
b6d96bed 8595 }
5a5012ec
TS
8596 opn = "cvt.l.d";
8597 break;
bf4120ad 8598 case OPC_CVT_S_W:
b6d96bed 8599 {
a7812ae4 8600 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8601
8602 gen_load_fpr32(fp0, fs);
895c2d04 8603 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8604 gen_store_fpr32(fp0, fd);
a7812ae4 8605 tcg_temp_free_i32(fp0);
b6d96bed 8606 }
5a5012ec 8607 opn = "cvt.s.w";
6ea83fed 8608 break;
bf4120ad 8609 case OPC_CVT_D_W:
5e755519 8610 check_cp1_registers(ctx, fd);
b6d96bed 8611 {
a7812ae4
PB
8612 TCGv_i32 fp32 = tcg_temp_new_i32();
8613 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8614
8615 gen_load_fpr32(fp32, fs);
895c2d04 8616 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8617 tcg_temp_free_i32(fp32);
b6d96bed 8618 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8619 tcg_temp_free_i64(fp64);
b6d96bed 8620 }
5a5012ec
TS
8621 opn = "cvt.d.w";
8622 break;
bf4120ad 8623 case OPC_CVT_S_L:
5e755519 8624 check_cp1_64bitmode(ctx);
b6d96bed 8625 {
a7812ae4
PB
8626 TCGv_i32 fp32 = tcg_temp_new_i32();
8627 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8628
8629 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8630 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8631 tcg_temp_free_i64(fp64);
b6d96bed 8632 gen_store_fpr32(fp32, fd);
a7812ae4 8633 tcg_temp_free_i32(fp32);
b6d96bed 8634 }
5a5012ec
TS
8635 opn = "cvt.s.l";
8636 break;
bf4120ad 8637 case OPC_CVT_D_L:
5e755519 8638 check_cp1_64bitmode(ctx);
b6d96bed 8639 {
a7812ae4 8640 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8641
8642 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8643 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8644 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8645 tcg_temp_free_i64(fp0);
b6d96bed 8646 }
5a5012ec
TS
8647 opn = "cvt.d.l";
8648 break;
bf4120ad 8649 case OPC_CVT_PS_PW:
fecd2646 8650 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 8651 check_cp1_64bitmode(ctx);
b6d96bed 8652 {
a7812ae4 8653 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8654
8655 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8656 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8657 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8658 tcg_temp_free_i64(fp0);
b6d96bed 8659 }
5a5012ec
TS
8660 opn = "cvt.ps.pw";
8661 break;
bf4120ad 8662 case OPC_ADD_PS:
5e755519 8663 check_cp1_64bitmode(ctx);
b6d96bed 8664 {
a7812ae4
PB
8665 TCGv_i64 fp0 = tcg_temp_new_i64();
8666 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8667
8668 gen_load_fpr64(ctx, fp0, fs);
8669 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8670 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8671 tcg_temp_free_i64(fp1);
b6d96bed 8672 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8673 tcg_temp_free_i64(fp0);
b6d96bed 8674 }
5a5012ec 8675 opn = "add.ps";
6ea83fed 8676 break;
bf4120ad 8677 case OPC_SUB_PS:
5e755519 8678 check_cp1_64bitmode(ctx);
b6d96bed 8679 {
a7812ae4
PB
8680 TCGv_i64 fp0 = tcg_temp_new_i64();
8681 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8682
8683 gen_load_fpr64(ctx, fp0, fs);
8684 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8685 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8686 tcg_temp_free_i64(fp1);
b6d96bed 8687 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8688 tcg_temp_free_i64(fp0);
b6d96bed 8689 }
5a5012ec 8690 opn = "sub.ps";
6ea83fed 8691 break;
bf4120ad 8692 case OPC_MUL_PS:
5e755519 8693 check_cp1_64bitmode(ctx);
b6d96bed 8694 {
a7812ae4
PB
8695 TCGv_i64 fp0 = tcg_temp_new_i64();
8696 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8697
8698 gen_load_fpr64(ctx, fp0, fs);
8699 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8700 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8701 tcg_temp_free_i64(fp1);
b6d96bed 8702 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8703 tcg_temp_free_i64(fp0);
b6d96bed 8704 }
5a5012ec 8705 opn = "mul.ps";
6ea83fed 8706 break;
bf4120ad 8707 case OPC_ABS_PS:
5e755519 8708 check_cp1_64bitmode(ctx);
b6d96bed 8709 {
a7812ae4 8710 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8711
8712 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8713 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8714 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8715 tcg_temp_free_i64(fp0);
b6d96bed 8716 }
5a5012ec 8717 opn = "abs.ps";
6ea83fed 8718 break;
bf4120ad 8719 case OPC_MOV_PS:
5e755519 8720 check_cp1_64bitmode(ctx);
b6d96bed 8721 {
a7812ae4 8722 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8723
8724 gen_load_fpr64(ctx, fp0, fs);
8725 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8726 tcg_temp_free_i64(fp0);
b6d96bed 8727 }
5a5012ec 8728 opn = "mov.ps";
6ea83fed 8729 break;
bf4120ad 8730 case OPC_NEG_PS:
5e755519 8731 check_cp1_64bitmode(ctx);
b6d96bed 8732 {
a7812ae4 8733 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8734
8735 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8736 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8737 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8738 tcg_temp_free_i64(fp0);
b6d96bed 8739 }
5a5012ec 8740 opn = "neg.ps";
6ea83fed 8741 break;
bf4120ad 8742 case OPC_MOVCF_PS:
5e755519 8743 check_cp1_64bitmode(ctx);
7f6613ce 8744 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8745 opn = "movcf.ps";
6ea83fed 8746 break;
bf4120ad 8747 case OPC_MOVZ_PS:
5e755519 8748 check_cp1_64bitmode(ctx);
a16336e4
TS
8749 {
8750 int l1 = gen_new_label();
30a3848b 8751 TCGv_i64 fp0;
a16336e4 8752
c9297f4d
AJ
8753 if (ft != 0)
8754 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8755 fp0 = tcg_temp_new_i64();
8756 gen_load_fpr64(ctx, fp0, fs);
8757 gen_store_fpr64(ctx, fp0, fd);
8758 tcg_temp_free_i64(fp0);
a16336e4
TS
8759 gen_set_label(l1);
8760 }
5a5012ec 8761 opn = "movz.ps";
6ea83fed 8762 break;
bf4120ad 8763 case OPC_MOVN_PS:
5e755519 8764 check_cp1_64bitmode(ctx);
a16336e4
TS
8765 {
8766 int l1 = gen_new_label();
30a3848b 8767 TCGv_i64 fp0;
c9297f4d
AJ
8768
8769 if (ft != 0) {
8770 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8771 fp0 = tcg_temp_new_i64();
8772 gen_load_fpr64(ctx, fp0, fs);
8773 gen_store_fpr64(ctx, fp0, fd);
8774 tcg_temp_free_i64(fp0);
8775 gen_set_label(l1);
8776 }
a16336e4 8777 }
5a5012ec 8778 opn = "movn.ps";
6ea83fed 8779 break;
bf4120ad 8780 case OPC_ADDR_PS:
5e755519 8781 check_cp1_64bitmode(ctx);
b6d96bed 8782 {
a7812ae4
PB
8783 TCGv_i64 fp0 = tcg_temp_new_i64();
8784 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8785
8786 gen_load_fpr64(ctx, fp0, ft);
8787 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8788 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8789 tcg_temp_free_i64(fp1);
b6d96bed 8790 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8791 tcg_temp_free_i64(fp0);
b6d96bed 8792 }
fbcc6828
TS
8793 opn = "addr.ps";
8794 break;
bf4120ad 8795 case OPC_MULR_PS:
5e755519 8796 check_cp1_64bitmode(ctx);
b6d96bed 8797 {
a7812ae4
PB
8798 TCGv_i64 fp0 = tcg_temp_new_i64();
8799 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8800
8801 gen_load_fpr64(ctx, fp0, ft);
8802 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8803 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8804 tcg_temp_free_i64(fp1);
b6d96bed 8805 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8806 tcg_temp_free_i64(fp0);
b6d96bed 8807 }
57fa1fb3
TS
8808 opn = "mulr.ps";
8809 break;
bf4120ad 8810 case OPC_RECIP2_PS:
5e755519 8811 check_cp1_64bitmode(ctx);
b6d96bed 8812 {
a7812ae4
PB
8813 TCGv_i64 fp0 = tcg_temp_new_i64();
8814 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8815
8816 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8817 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8818 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8819 tcg_temp_free_i64(fp1);
b6d96bed 8820 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8821 tcg_temp_free_i64(fp0);
b6d96bed 8822 }
57fa1fb3
TS
8823 opn = "recip2.ps";
8824 break;
bf4120ad 8825 case OPC_RECIP1_PS:
5e755519 8826 check_cp1_64bitmode(ctx);
b6d96bed 8827 {
a7812ae4 8828 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8829
8830 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8831 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8832 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8833 tcg_temp_free_i64(fp0);
b6d96bed 8834 }
57fa1fb3
TS
8835 opn = "recip1.ps";
8836 break;
bf4120ad 8837 case OPC_RSQRT1_PS:
5e755519 8838 check_cp1_64bitmode(ctx);
b6d96bed 8839 {
a7812ae4 8840 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8841
8842 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8843 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8844 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8845 tcg_temp_free_i64(fp0);
b6d96bed 8846 }
57fa1fb3
TS
8847 opn = "rsqrt1.ps";
8848 break;
bf4120ad 8849 case OPC_RSQRT2_PS:
5e755519 8850 check_cp1_64bitmode(ctx);
b6d96bed 8851 {
a7812ae4
PB
8852 TCGv_i64 fp0 = tcg_temp_new_i64();
8853 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8854
8855 gen_load_fpr64(ctx, fp0, fs);
8856 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8857 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8858 tcg_temp_free_i64(fp1);
b6d96bed 8859 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8860 tcg_temp_free_i64(fp0);
b6d96bed 8861 }
57fa1fb3
TS
8862 opn = "rsqrt2.ps";
8863 break;
bf4120ad 8864 case OPC_CVT_S_PU:
5e755519 8865 check_cp1_64bitmode(ctx);
b6d96bed 8866 {
a7812ae4 8867 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8868
7f6613ce 8869 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 8870 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8871 gen_store_fpr32(fp0, fd);
a7812ae4 8872 tcg_temp_free_i32(fp0);
b6d96bed 8873 }
5a5012ec 8874 opn = "cvt.s.pu";
dd016883 8875 break;
bf4120ad 8876 case OPC_CVT_PW_PS:
5e755519 8877 check_cp1_64bitmode(ctx);
b6d96bed 8878 {
a7812ae4 8879 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8880
8881 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8882 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8883 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8884 tcg_temp_free_i64(fp0);
b6d96bed 8885 }
5a5012ec 8886 opn = "cvt.pw.ps";
6ea83fed 8887 break;
bf4120ad 8888 case OPC_CVT_S_PL:
5e755519 8889 check_cp1_64bitmode(ctx);
b6d96bed 8890 {
a7812ae4 8891 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8892
8893 gen_load_fpr32(fp0, fs);
895c2d04 8894 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8895 gen_store_fpr32(fp0, fd);
a7812ae4 8896 tcg_temp_free_i32(fp0);
b6d96bed 8897 }
5a5012ec 8898 opn = "cvt.s.pl";
6ea83fed 8899 break;
bf4120ad 8900 case OPC_PLL_PS:
5e755519 8901 check_cp1_64bitmode(ctx);
b6d96bed 8902 {
a7812ae4
PB
8903 TCGv_i32 fp0 = tcg_temp_new_i32();
8904 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8905
8906 gen_load_fpr32(fp0, fs);
8907 gen_load_fpr32(fp1, ft);
7f6613ce 8908 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 8909 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8910 tcg_temp_free_i32(fp0);
8911 tcg_temp_free_i32(fp1);
b6d96bed 8912 }
5a5012ec 8913 opn = "pll.ps";
6ea83fed 8914 break;
bf4120ad 8915 case OPC_PLU_PS:
5e755519 8916 check_cp1_64bitmode(ctx);
b6d96bed 8917 {
a7812ae4
PB
8918 TCGv_i32 fp0 = tcg_temp_new_i32();
8919 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8920
8921 gen_load_fpr32(fp0, fs);
7f6613ce 8922 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 8923 gen_store_fpr32(fp1, fd);
7f6613ce 8924 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8925 tcg_temp_free_i32(fp0);
8926 tcg_temp_free_i32(fp1);
b6d96bed 8927 }
5a5012ec
TS
8928 opn = "plu.ps";
8929 break;
bf4120ad 8930 case OPC_PUL_PS:
5e755519 8931 check_cp1_64bitmode(ctx);
b6d96bed 8932 {
a7812ae4
PB
8933 TCGv_i32 fp0 = tcg_temp_new_i32();
8934 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8935
7f6613ce 8936 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
8937 gen_load_fpr32(fp1, ft);
8938 gen_store_fpr32(fp1, fd);
7f6613ce 8939 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8940 tcg_temp_free_i32(fp0);
8941 tcg_temp_free_i32(fp1);
b6d96bed 8942 }
5a5012ec
TS
8943 opn = "pul.ps";
8944 break;
bf4120ad 8945 case OPC_PUU_PS:
5e755519 8946 check_cp1_64bitmode(ctx);
b6d96bed 8947 {
a7812ae4
PB
8948 TCGv_i32 fp0 = tcg_temp_new_i32();
8949 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8950
7f6613ce
PJ
8951 gen_load_fpr32h(ctx, fp0, fs);
8952 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 8953 gen_store_fpr32(fp1, fd);
7f6613ce 8954 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8955 tcg_temp_free_i32(fp0);
8956 tcg_temp_free_i32(fp1);
b6d96bed 8957 }
5a5012ec
TS
8958 opn = "puu.ps";
8959 break;
bf4120ad
NF
8960 case OPC_CMP_F_PS:
8961 case OPC_CMP_UN_PS:
8962 case OPC_CMP_EQ_PS:
8963 case OPC_CMP_UEQ_PS:
8964 case OPC_CMP_OLT_PS:
8965 case OPC_CMP_ULT_PS:
8966 case OPC_CMP_OLE_PS:
8967 case OPC_CMP_ULE_PS:
8968 case OPC_CMP_SF_PS:
8969 case OPC_CMP_NGLE_PS:
8970 case OPC_CMP_SEQ_PS:
8971 case OPC_CMP_NGL_PS:
8972 case OPC_CMP_LT_PS:
8973 case OPC_CMP_NGE_PS:
8974 case OPC_CMP_LE_PS:
8975 case OPC_CMP_NGT_PS:
8153667c
NF
8976 if (ctx->opcode & (1 << 6)) {
8977 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8978 opn = condnames_abs[func-48];
8979 } else {
8980 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8981 opn = condnames[func-48];
5a1e8ffb 8982 }
6ea83fed 8983 break;
5a5012ec 8984 default:
923617a3 8985 MIPS_INVAL(opn);
e397ee33 8986 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8987 return;
8988 }
2abf314d 8989 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8990 switch (optype) {
8991 case BINOP:
6ea83fed 8992 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8993 break;
8994 case CMPOP:
8995 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8996 break;
8997 default:
6ea83fed 8998 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8999 break;
9000 }
6ea83fed 9001}
6af0bf9c 9002
5a5012ec 9003/* Coprocessor 3 (FPU) */
5e755519
TS
9004static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
9005 int fd, int fs, int base, int index)
7a387fff 9006{
923617a3 9007 const char *opn = "extended float load/store";
93b12ccc 9008 int store = 0;
4e2474d6 9009 TCGv t0 = tcg_temp_new();
7a387fff 9010
93b12ccc 9011 if (base == 0) {
6c5c1e20 9012 gen_load_gpr(t0, index);
93b12ccc 9013 } else if (index == 0) {
6c5c1e20 9014 gen_load_gpr(t0, base);
93b12ccc 9015 } else {
05168674 9016 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 9017 }
5a5012ec 9018 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 9019 memory access. */
5a5012ec
TS
9020 switch (opc) {
9021 case OPC_LWXC1:
8c0ab41f 9022 check_cop1x(ctx);
b6d96bed 9023 {
a7812ae4 9024 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9025
5f68f5ae 9026 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 9027 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 9028 gen_store_fpr32(fp0, fd);
a7812ae4 9029 tcg_temp_free_i32(fp0);
b6d96bed 9030 }
5a5012ec
TS
9031 opn = "lwxc1";
9032 break;
9033 case OPC_LDXC1:
8c0ab41f
AJ
9034 check_cop1x(ctx);
9035 check_cp1_registers(ctx, fd);
b6d96bed 9036 {
a7812ae4 9037 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 9038 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 9039 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9040 tcg_temp_free_i64(fp0);
b6d96bed 9041 }
5a5012ec
TS
9042 opn = "ldxc1";
9043 break;
9044 case OPC_LUXC1:
8c0ab41f 9045 check_cp1_64bitmode(ctx);
6c5c1e20 9046 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 9047 {
a7812ae4 9048 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9049
5f68f5ae 9050 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 9051 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9052 tcg_temp_free_i64(fp0);
b6d96bed 9053 }
5a5012ec
TS
9054 opn = "luxc1";
9055 break;
9056 case OPC_SWXC1:
8c0ab41f 9057 check_cop1x(ctx);
b6d96bed 9058 {
a7812ae4 9059 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9060 gen_load_fpr32(fp0, fs);
5f68f5ae 9061 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 9062 tcg_temp_free_i32(fp0);
b6d96bed 9063 }
5a5012ec 9064 opn = "swxc1";
93b12ccc 9065 store = 1;
5a5012ec
TS
9066 break;
9067 case OPC_SDXC1:
8c0ab41f
AJ
9068 check_cop1x(ctx);
9069 check_cp1_registers(ctx, fs);
b6d96bed 9070 {
a7812ae4 9071 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9072 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 9073 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 9074 tcg_temp_free_i64(fp0);
b6d96bed 9075 }
5a5012ec 9076 opn = "sdxc1";
93b12ccc 9077 store = 1;
5a5012ec
TS
9078 break;
9079 case OPC_SUXC1:
8c0ab41f 9080 check_cp1_64bitmode(ctx);
6c5c1e20 9081 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 9082 {
a7812ae4 9083 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9084 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 9085 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 9086 tcg_temp_free_i64(fp0);
b6d96bed 9087 }
5a5012ec 9088 opn = "suxc1";
93b12ccc 9089 store = 1;
5a5012ec 9090 break;
5a5012ec 9091 }
6c5c1e20 9092 tcg_temp_free(t0);
2abf314d 9093 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
9094 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
9095 regnames[index], regnames[base]);
5a5012ec
TS
9096}
9097
5e755519
TS
9098static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
9099 int fd, int fr, int fs, int ft)
5a5012ec 9100{
923617a3 9101 const char *opn = "flt3_arith";
5a5012ec 9102
5a5012ec
TS
9103 switch (opc) {
9104 case OPC_ALNV_PS:
b8aa4598 9105 check_cp1_64bitmode(ctx);
a16336e4 9106 {
a7812ae4 9107 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
9108 TCGv_i32 fp = tcg_temp_new_i32();
9109 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
9110 int l1 = gen_new_label();
9111 int l2 = gen_new_label();
9112
6c5c1e20
TS
9113 gen_load_gpr(t0, fr);
9114 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
9115
9116 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 9117 gen_load_fpr32(fp, fs);
7f6613ce 9118 gen_load_fpr32h(ctx, fph, fs);
c905fdac 9119 gen_store_fpr32(fp, fd);
7f6613ce 9120 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
9121 tcg_gen_br(l2);
9122 gen_set_label(l1);
6c5c1e20
TS
9123 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
9124 tcg_temp_free(t0);
a16336e4 9125#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 9126 gen_load_fpr32(fp, fs);
7f6613ce
PJ
9127 gen_load_fpr32h(ctx, fph, ft);
9128 gen_store_fpr32h(ctx, fp, fd);
c905fdac 9129 gen_store_fpr32(fph, fd);
a16336e4 9130#else
7f6613ce 9131 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
9132 gen_load_fpr32(fp, ft);
9133 gen_store_fpr32(fph, fd);
7f6613ce 9134 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
9135#endif
9136 gen_set_label(l2);
c905fdac
AJ
9137 tcg_temp_free_i32(fp);
9138 tcg_temp_free_i32(fph);
a16336e4 9139 }
5a5012ec
TS
9140 opn = "alnv.ps";
9141 break;
9142 case OPC_MADD_S:
b8aa4598 9143 check_cop1x(ctx);
b6d96bed 9144 {
a7812ae4
PB
9145 TCGv_i32 fp0 = tcg_temp_new_i32();
9146 TCGv_i32 fp1 = tcg_temp_new_i32();
9147 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9148
9149 gen_load_fpr32(fp0, fs);
9150 gen_load_fpr32(fp1, ft);
9151 gen_load_fpr32(fp2, fr);
b3d6cd44 9152 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9153 tcg_temp_free_i32(fp0);
9154 tcg_temp_free_i32(fp1);
b6d96bed 9155 gen_store_fpr32(fp2, fd);
a7812ae4 9156 tcg_temp_free_i32(fp2);
b6d96bed 9157 }
5a5012ec
TS
9158 opn = "madd.s";
9159 break;
9160 case OPC_MADD_D:
b8aa4598
TS
9161 check_cop1x(ctx);
9162 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9163 {
a7812ae4
PB
9164 TCGv_i64 fp0 = tcg_temp_new_i64();
9165 TCGv_i64 fp1 = tcg_temp_new_i64();
9166 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9167
9168 gen_load_fpr64(ctx, fp0, fs);
9169 gen_load_fpr64(ctx, fp1, ft);
9170 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9171 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9172 tcg_temp_free_i64(fp0);
9173 tcg_temp_free_i64(fp1);
b6d96bed 9174 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9175 tcg_temp_free_i64(fp2);
b6d96bed 9176 }
5a5012ec
TS
9177 opn = "madd.d";
9178 break;
9179 case OPC_MADD_PS:
b8aa4598 9180 check_cp1_64bitmode(ctx);
b6d96bed 9181 {
a7812ae4
PB
9182 TCGv_i64 fp0 = tcg_temp_new_i64();
9183 TCGv_i64 fp1 = tcg_temp_new_i64();
9184 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9185
9186 gen_load_fpr64(ctx, fp0, fs);
9187 gen_load_fpr64(ctx, fp1, ft);
9188 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9189 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9190 tcg_temp_free_i64(fp0);
9191 tcg_temp_free_i64(fp1);
b6d96bed 9192 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9193 tcg_temp_free_i64(fp2);
b6d96bed 9194 }
5a5012ec
TS
9195 opn = "madd.ps";
9196 break;
9197 case OPC_MSUB_S:
b8aa4598 9198 check_cop1x(ctx);
b6d96bed 9199 {
a7812ae4
PB
9200 TCGv_i32 fp0 = tcg_temp_new_i32();
9201 TCGv_i32 fp1 = tcg_temp_new_i32();
9202 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9203
9204 gen_load_fpr32(fp0, fs);
9205 gen_load_fpr32(fp1, ft);
9206 gen_load_fpr32(fp2, fr);
b3d6cd44 9207 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9208 tcg_temp_free_i32(fp0);
9209 tcg_temp_free_i32(fp1);
b6d96bed 9210 gen_store_fpr32(fp2, fd);
a7812ae4 9211 tcg_temp_free_i32(fp2);
b6d96bed 9212 }
5a5012ec
TS
9213 opn = "msub.s";
9214 break;
9215 case OPC_MSUB_D:
b8aa4598
TS
9216 check_cop1x(ctx);
9217 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9218 {
a7812ae4
PB
9219 TCGv_i64 fp0 = tcg_temp_new_i64();
9220 TCGv_i64 fp1 = tcg_temp_new_i64();
9221 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9222
9223 gen_load_fpr64(ctx, fp0, fs);
9224 gen_load_fpr64(ctx, fp1, ft);
9225 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9226 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9227 tcg_temp_free_i64(fp0);
9228 tcg_temp_free_i64(fp1);
b6d96bed 9229 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9230 tcg_temp_free_i64(fp2);
b6d96bed 9231 }
5a5012ec
TS
9232 opn = "msub.d";
9233 break;
9234 case OPC_MSUB_PS:
b8aa4598 9235 check_cp1_64bitmode(ctx);
b6d96bed 9236 {
a7812ae4
PB
9237 TCGv_i64 fp0 = tcg_temp_new_i64();
9238 TCGv_i64 fp1 = tcg_temp_new_i64();
9239 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9240
9241 gen_load_fpr64(ctx, fp0, fs);
9242 gen_load_fpr64(ctx, fp1, ft);
9243 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9244 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9245 tcg_temp_free_i64(fp0);
9246 tcg_temp_free_i64(fp1);
b6d96bed 9247 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9248 tcg_temp_free_i64(fp2);
b6d96bed 9249 }
5a5012ec
TS
9250 opn = "msub.ps";
9251 break;
9252 case OPC_NMADD_S:
b8aa4598 9253 check_cop1x(ctx);
b6d96bed 9254 {
a7812ae4
PB
9255 TCGv_i32 fp0 = tcg_temp_new_i32();
9256 TCGv_i32 fp1 = tcg_temp_new_i32();
9257 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9258
9259 gen_load_fpr32(fp0, fs);
9260 gen_load_fpr32(fp1, ft);
9261 gen_load_fpr32(fp2, fr);
b3d6cd44 9262 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9263 tcg_temp_free_i32(fp0);
9264 tcg_temp_free_i32(fp1);
b6d96bed 9265 gen_store_fpr32(fp2, fd);
a7812ae4 9266 tcg_temp_free_i32(fp2);
b6d96bed 9267 }
5a5012ec
TS
9268 opn = "nmadd.s";
9269 break;
9270 case OPC_NMADD_D:
b8aa4598
TS
9271 check_cop1x(ctx);
9272 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9273 {
a7812ae4
PB
9274 TCGv_i64 fp0 = tcg_temp_new_i64();
9275 TCGv_i64 fp1 = tcg_temp_new_i64();
9276 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9277
9278 gen_load_fpr64(ctx, fp0, fs);
9279 gen_load_fpr64(ctx, fp1, ft);
9280 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9281 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9282 tcg_temp_free_i64(fp0);
9283 tcg_temp_free_i64(fp1);
b6d96bed 9284 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9285 tcg_temp_free_i64(fp2);
b6d96bed 9286 }
5a5012ec
TS
9287 opn = "nmadd.d";
9288 break;
9289 case OPC_NMADD_PS:
b8aa4598 9290 check_cp1_64bitmode(ctx);
b6d96bed 9291 {
a7812ae4
PB
9292 TCGv_i64 fp0 = tcg_temp_new_i64();
9293 TCGv_i64 fp1 = tcg_temp_new_i64();
9294 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9295
9296 gen_load_fpr64(ctx, fp0, fs);
9297 gen_load_fpr64(ctx, fp1, ft);
9298 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9299 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9300 tcg_temp_free_i64(fp0);
9301 tcg_temp_free_i64(fp1);
b6d96bed 9302 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9303 tcg_temp_free_i64(fp2);
b6d96bed 9304 }
5a5012ec
TS
9305 opn = "nmadd.ps";
9306 break;
9307 case OPC_NMSUB_S:
b8aa4598 9308 check_cop1x(ctx);
b6d96bed 9309 {
a7812ae4
PB
9310 TCGv_i32 fp0 = tcg_temp_new_i32();
9311 TCGv_i32 fp1 = tcg_temp_new_i32();
9312 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9313
9314 gen_load_fpr32(fp0, fs);
9315 gen_load_fpr32(fp1, ft);
9316 gen_load_fpr32(fp2, fr);
b3d6cd44 9317 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9318 tcg_temp_free_i32(fp0);
9319 tcg_temp_free_i32(fp1);
b6d96bed 9320 gen_store_fpr32(fp2, fd);
a7812ae4 9321 tcg_temp_free_i32(fp2);
b6d96bed 9322 }
5a5012ec
TS
9323 opn = "nmsub.s";
9324 break;
9325 case OPC_NMSUB_D:
b8aa4598
TS
9326 check_cop1x(ctx);
9327 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9328 {
a7812ae4
PB
9329 TCGv_i64 fp0 = tcg_temp_new_i64();
9330 TCGv_i64 fp1 = tcg_temp_new_i64();
9331 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9332
9333 gen_load_fpr64(ctx, fp0, fs);
9334 gen_load_fpr64(ctx, fp1, ft);
9335 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9336 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9337 tcg_temp_free_i64(fp0);
9338 tcg_temp_free_i64(fp1);
b6d96bed 9339 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9340 tcg_temp_free_i64(fp2);
b6d96bed 9341 }
5a5012ec
TS
9342 opn = "nmsub.d";
9343 break;
9344 case OPC_NMSUB_PS:
b8aa4598 9345 check_cp1_64bitmode(ctx);
b6d96bed 9346 {
a7812ae4
PB
9347 TCGv_i64 fp0 = tcg_temp_new_i64();
9348 TCGv_i64 fp1 = tcg_temp_new_i64();
9349 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9350
9351 gen_load_fpr64(ctx, fp0, fs);
9352 gen_load_fpr64(ctx, fp1, ft);
9353 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9354 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9355 tcg_temp_free_i64(fp0);
9356 tcg_temp_free_i64(fp1);
b6d96bed 9357 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9358 tcg_temp_free_i64(fp2);
b6d96bed 9359 }
5a5012ec
TS
9360 opn = "nmsub.ps";
9361 break;
923617a3
TS
9362 default:
9363 MIPS_INVAL(opn);
5a5012ec
TS
9364 generate_exception (ctx, EXCP_RI);
9365 return;
9366 }
2abf314d 9367 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9368 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9369 fregnames[fs], fregnames[ft]);
7a387fff
TS
9370}
9371
d75c135e 9372static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9373{
9374 TCGv t0;
9375
b3167288
RH
9376#if !defined(CONFIG_USER_ONLY)
9377 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9378 Therefore only check the ISA in system mode. */
d75c135e 9379 check_insn(ctx, ISA_MIPS32R2);
b3167288 9380#endif
26ebe468
NF
9381 t0 = tcg_temp_new();
9382
9383 switch (rd) {
9384 case 0:
9385 save_cpu_state(ctx, 1);
895c2d04 9386 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9387 gen_store_gpr(t0, rt);
9388 break;
9389 case 1:
9390 save_cpu_state(ctx, 1);
895c2d04 9391 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9392 gen_store_gpr(t0, rt);
9393 break;
9394 case 2:
9395 save_cpu_state(ctx, 1);
895c2d04 9396 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9397 gen_store_gpr(t0, rt);
9398 break;
9399 case 3:
9400 save_cpu_state(ctx, 1);
895c2d04 9401 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9402 gen_store_gpr(t0, rt);
9403 break;
9404 case 29:
9405#if defined(CONFIG_USER_ONLY)
d279279e
PJ
9406 tcg_gen_ld_tl(t0, cpu_env,
9407 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
9408 gen_store_gpr(t0, rt);
9409 break;
9410#else
d279279e
PJ
9411 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
9412 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
9413 tcg_gen_ld_tl(t0, cpu_env,
9414 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9415 gen_store_gpr(t0, rt);
9416 } else {
9417 generate_exception(ctx, EXCP_RI);
9418 }
9419 break;
26ebe468
NF
9420#endif
9421 default: /* Invalid */
9422 MIPS_INVAL("rdhwr");
9423 generate_exception(ctx, EXCP_RI);
9424 break;
9425 }
9426 tcg_temp_free(t0);
9427}
9428
d75c135e 9429static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9430{
9431 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9432 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9433 /* Branches completion */
9434 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9435 ctx->bstate = BS_BRANCH;
9436 save_cpu_state(ctx, 0);
9437 /* FIXME: Need to clear can_do_io. */
364d4831 9438 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9439 case MIPS_HFLAG_B:
9440 /* unconditional branch */
9441 MIPS_DEBUG("unconditional branch");
364d4831
NF
9442 if (proc_hflags & MIPS_HFLAG_BX) {
9443 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9444 }
c9602061
NF
9445 gen_goto_tb(ctx, 0, ctx->btarget);
9446 break;
9447 case MIPS_HFLAG_BL:
9448 /* blikely taken case */
9449 MIPS_DEBUG("blikely branch taken");
9450 gen_goto_tb(ctx, 0, ctx->btarget);
9451 break;
9452 case MIPS_HFLAG_BC:
9453 /* Conditional branch */
9454 MIPS_DEBUG("conditional branch");
9455 {
9456 int l1 = gen_new_label();
9457
9458 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9459 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9460 gen_set_label(l1);
9461 gen_goto_tb(ctx, 0, ctx->btarget);
9462 }
9463 break;
9464 case MIPS_HFLAG_BR:
9465 /* unconditional branch to register */
9466 MIPS_DEBUG("branch to register");
d75c135e 9467 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9468 TCGv t0 = tcg_temp_new();
9469 TCGv_i32 t1 = tcg_temp_new_i32();
9470
9471 tcg_gen_andi_tl(t0, btarget, 0x1);
9472 tcg_gen_trunc_tl_i32(t1, t0);
9473 tcg_temp_free(t0);
9474 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9475 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9476 tcg_gen_or_i32(hflags, hflags, t1);
9477 tcg_temp_free_i32(t1);
9478
9479 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9480 } else {
9481 tcg_gen_mov_tl(cpu_PC, btarget);
9482 }
c9602061
NF
9483 if (ctx->singlestep_enabled) {
9484 save_cpu_state(ctx, 0);
895c2d04 9485 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9486 }
9487 tcg_gen_exit_tb(0);
9488 break;
9489 default:
9490 MIPS_DEBUG("unknown branch");
9491 break;
9492 }
9493 }
9494}
9495
7a387fff 9496/* ISA extensions (ASEs) */
6af0bf9c 9497/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9498
9499/* MIPS16 major opcodes */
9500enum {
9501 M16_OPC_ADDIUSP = 0x00,
9502 M16_OPC_ADDIUPC = 0x01,
9503 M16_OPC_B = 0x02,
9504 M16_OPC_JAL = 0x03,
9505 M16_OPC_BEQZ = 0x04,
9506 M16_OPC_BNEQZ = 0x05,
9507 M16_OPC_SHIFT = 0x06,
9508 M16_OPC_LD = 0x07,
9509 M16_OPC_RRIA = 0x08,
9510 M16_OPC_ADDIU8 = 0x09,
9511 M16_OPC_SLTI = 0x0a,
9512 M16_OPC_SLTIU = 0x0b,
9513 M16_OPC_I8 = 0x0c,
9514 M16_OPC_LI = 0x0d,
9515 M16_OPC_CMPI = 0x0e,
9516 M16_OPC_SD = 0x0f,
9517 M16_OPC_LB = 0x10,
9518 M16_OPC_LH = 0x11,
9519 M16_OPC_LWSP = 0x12,
9520 M16_OPC_LW = 0x13,
9521 M16_OPC_LBU = 0x14,
9522 M16_OPC_LHU = 0x15,
9523 M16_OPC_LWPC = 0x16,
9524 M16_OPC_LWU = 0x17,
9525 M16_OPC_SB = 0x18,
9526 M16_OPC_SH = 0x19,
9527 M16_OPC_SWSP = 0x1a,
9528 M16_OPC_SW = 0x1b,
9529 M16_OPC_RRR = 0x1c,
9530 M16_OPC_RR = 0x1d,
9531 M16_OPC_EXTEND = 0x1e,
9532 M16_OPC_I64 = 0x1f
9533};
9534
9535/* I8 funct field */
9536enum {
9537 I8_BTEQZ = 0x0,
9538 I8_BTNEZ = 0x1,
9539 I8_SWRASP = 0x2,
9540 I8_ADJSP = 0x3,
9541 I8_SVRS = 0x4,
9542 I8_MOV32R = 0x5,
9543 I8_MOVR32 = 0x7
9544};
9545
9546/* RRR f field */
9547enum {
9548 RRR_DADDU = 0x0,
9549 RRR_ADDU = 0x1,
9550 RRR_DSUBU = 0x2,
9551 RRR_SUBU = 0x3
9552};
9553
9554/* RR funct field */
9555enum {
9556 RR_JR = 0x00,
9557 RR_SDBBP = 0x01,
9558 RR_SLT = 0x02,
9559 RR_SLTU = 0x03,
9560 RR_SLLV = 0x04,
9561 RR_BREAK = 0x05,
9562 RR_SRLV = 0x06,
9563 RR_SRAV = 0x07,
9564 RR_DSRL = 0x08,
9565 RR_CMP = 0x0a,
9566 RR_NEG = 0x0b,
9567 RR_AND = 0x0c,
9568 RR_OR = 0x0d,
9569 RR_XOR = 0x0e,
9570 RR_NOT = 0x0f,
9571 RR_MFHI = 0x10,
9572 RR_CNVT = 0x11,
9573 RR_MFLO = 0x12,
9574 RR_DSRA = 0x13,
9575 RR_DSLLV = 0x14,
9576 RR_DSRLV = 0x16,
9577 RR_DSRAV = 0x17,
9578 RR_MULT = 0x18,
9579 RR_MULTU = 0x19,
9580 RR_DIV = 0x1a,
9581 RR_DIVU = 0x1b,
9582 RR_DMULT = 0x1c,
9583 RR_DMULTU = 0x1d,
9584 RR_DDIV = 0x1e,
9585 RR_DDIVU = 0x1f
9586};
9587
9588/* I64 funct field */
9589enum {
9590 I64_LDSP = 0x0,
9591 I64_SDSP = 0x1,
9592 I64_SDRASP = 0x2,
9593 I64_DADJSP = 0x3,
9594 I64_LDPC = 0x4,
364d4831 9595 I64_DADDIU5 = 0x5,
6ea219d0
NF
9596 I64_DADDIUPC = 0x6,
9597 I64_DADDIUSP = 0x7
9598};
9599
9600/* RR ry field for CNVT */
9601enum {
9602 RR_RY_CNVT_ZEB = 0x0,
9603 RR_RY_CNVT_ZEH = 0x1,
9604 RR_RY_CNVT_ZEW = 0x2,
9605 RR_RY_CNVT_SEB = 0x4,
9606 RR_RY_CNVT_SEH = 0x5,
9607 RR_RY_CNVT_SEW = 0x6,
9608};
9609
364d4831
NF
9610static int xlat (int r)
9611{
9612 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9613
9614 return map[r];
9615}
9616
9617static void gen_mips16_save (DisasContext *ctx,
9618 int xsregs, int aregs,
9619 int do_ra, int do_s0, int do_s1,
9620 int framesize)
9621{
9622 TCGv t0 = tcg_temp_new();
9623 TCGv t1 = tcg_temp_new();
9624 int args, astatic;
9625
9626 switch (aregs) {
9627 case 0:
9628 case 1:
9629 case 2:
9630 case 3:
9631 case 11:
9632 args = 0;
9633 break;
9634 case 4:
9635 case 5:
9636 case 6:
9637 case 7:
9638 args = 1;
9639 break;
9640 case 8:
9641 case 9:
9642 case 10:
9643 args = 2;
9644 break;
9645 case 12:
9646 case 13:
9647 args = 3;
9648 break;
9649 case 14:
9650 args = 4;
9651 break;
9652 default:
9653 generate_exception(ctx, EXCP_RI);
9654 return;
9655 }
9656
9657 switch (args) {
9658 case 4:
9659 gen_base_offset_addr(ctx, t0, 29, 12);
9660 gen_load_gpr(t1, 7);
5f68f5ae 9661 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9662 /* Fall through */
9663 case 3:
9664 gen_base_offset_addr(ctx, t0, 29, 8);
9665 gen_load_gpr(t1, 6);
5f68f5ae 9666 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9667 /* Fall through */
9668 case 2:
9669 gen_base_offset_addr(ctx, t0, 29, 4);
9670 gen_load_gpr(t1, 5);
5f68f5ae 9671 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9672 /* Fall through */
9673 case 1:
9674 gen_base_offset_addr(ctx, t0, 29, 0);
9675 gen_load_gpr(t1, 4);
5f68f5ae 9676 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9677 }
9678
9679 gen_load_gpr(t0, 29);
9680
5f68f5ae
AJ
9681#define DECR_AND_STORE(reg) do { \
9682 tcg_gen_subi_tl(t0, t0, 4); \
9683 gen_load_gpr(t1, reg); \
9684 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
9685 } while (0)
9686
9687 if (do_ra) {
9688 DECR_AND_STORE(31);
9689 }
9690
9691 switch (xsregs) {
9692 case 7:
9693 DECR_AND_STORE(30);
9694 /* Fall through */
9695 case 6:
9696 DECR_AND_STORE(23);
9697 /* Fall through */
9698 case 5:
9699 DECR_AND_STORE(22);
9700 /* Fall through */
9701 case 4:
9702 DECR_AND_STORE(21);
9703 /* Fall through */
9704 case 3:
9705 DECR_AND_STORE(20);
9706 /* Fall through */
9707 case 2:
9708 DECR_AND_STORE(19);
9709 /* Fall through */
9710 case 1:
9711 DECR_AND_STORE(18);
9712 }
9713
9714 if (do_s1) {
9715 DECR_AND_STORE(17);
9716 }
9717 if (do_s0) {
9718 DECR_AND_STORE(16);
9719 }
9720
9721 switch (aregs) {
9722 case 0:
9723 case 4:
9724 case 8:
9725 case 12:
9726 case 14:
9727 astatic = 0;
9728 break;
9729 case 1:
9730 case 5:
9731 case 9:
9732 case 13:
9733 astatic = 1;
9734 break;
9735 case 2:
9736 case 6:
9737 case 10:
9738 astatic = 2;
9739 break;
9740 case 3:
9741 case 7:
9742 astatic = 3;
9743 break;
9744 case 11:
9745 astatic = 4;
9746 break;
9747 default:
9748 generate_exception(ctx, EXCP_RI);
9749 return;
9750 }
9751
9752 if (astatic > 0) {
9753 DECR_AND_STORE(7);
9754 if (astatic > 1) {
9755 DECR_AND_STORE(6);
9756 if (astatic > 2) {
9757 DECR_AND_STORE(5);
9758 if (astatic > 3) {
9759 DECR_AND_STORE(4);
9760 }
9761 }
9762 }
9763 }
9764#undef DECR_AND_STORE
9765
9766 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9767 tcg_temp_free(t0);
9768 tcg_temp_free(t1);
9769}
9770
9771static void gen_mips16_restore (DisasContext *ctx,
9772 int xsregs, int aregs,
9773 int do_ra, int do_s0, int do_s1,
9774 int framesize)
9775{
9776 int astatic;
9777 TCGv t0 = tcg_temp_new();
9778 TCGv t1 = tcg_temp_new();
9779
9780 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9781
5f68f5ae
AJ
9782#define DECR_AND_LOAD(reg) do { \
9783 tcg_gen_subi_tl(t0, t0, 4); \
9784 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9785 gen_store_gpr(t1, reg); \
364d4831
NF
9786 } while (0)
9787
9788 if (do_ra) {
9789 DECR_AND_LOAD(31);
9790 }
9791
9792 switch (xsregs) {
9793 case 7:
9794 DECR_AND_LOAD(30);
9795 /* Fall through */
9796 case 6:
9797 DECR_AND_LOAD(23);
9798 /* Fall through */
9799 case 5:
9800 DECR_AND_LOAD(22);
9801 /* Fall through */
9802 case 4:
9803 DECR_AND_LOAD(21);
9804 /* Fall through */
9805 case 3:
9806 DECR_AND_LOAD(20);
9807 /* Fall through */
9808 case 2:
9809 DECR_AND_LOAD(19);
9810 /* Fall through */
9811 case 1:
9812 DECR_AND_LOAD(18);
9813 }
9814
9815 if (do_s1) {
9816 DECR_AND_LOAD(17);
9817 }
9818 if (do_s0) {
9819 DECR_AND_LOAD(16);
9820 }
9821
9822 switch (aregs) {
9823 case 0:
9824 case 4:
9825 case 8:
9826 case 12:
9827 case 14:
9828 astatic = 0;
9829 break;
9830 case 1:
9831 case 5:
9832 case 9:
9833 case 13:
9834 astatic = 1;
9835 break;
9836 case 2:
9837 case 6:
9838 case 10:
9839 astatic = 2;
9840 break;
9841 case 3:
9842 case 7:
9843 astatic = 3;
9844 break;
9845 case 11:
9846 astatic = 4;
9847 break;
9848 default:
9849 generate_exception(ctx, EXCP_RI);
9850 return;
9851 }
9852
9853 if (astatic > 0) {
9854 DECR_AND_LOAD(7);
9855 if (astatic > 1) {
9856 DECR_AND_LOAD(6);
9857 if (astatic > 2) {
9858 DECR_AND_LOAD(5);
9859 if (astatic > 3) {
9860 DECR_AND_LOAD(4);
9861 }
9862 }
9863 }
9864 }
9865#undef DECR_AND_LOAD
9866
9867 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9868 tcg_temp_free(t0);
9869 tcg_temp_free(t1);
9870}
9871
9872static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9873 int is_64_bit, int extended)
9874{
9875 TCGv t0;
9876
9877 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9878 generate_exception(ctx, EXCP_RI);
9879 return;
9880 }
9881
9882 t0 = tcg_temp_new();
9883
9884 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9885 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9886 if (!is_64_bit) {
9887 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9888 }
9889
9890 tcg_temp_free(t0);
9891}
9892
9893#if defined(TARGET_MIPS64)
d75c135e 9894static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9895 int ry, int funct, int16_t offset,
9896 int extended)
9897{
9898 switch (funct) {
9899 case I64_LDSP:
9900 check_mips_64(ctx);
9901 offset = extended ? offset : offset << 3;
d75c135e 9902 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9903 break;
9904 case I64_SDSP:
9905 check_mips_64(ctx);
9906 offset = extended ? offset : offset << 3;
5c13fdfd 9907 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9908 break;
9909 case I64_SDRASP:
9910 check_mips_64(ctx);
9911 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9912 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9913 break;
9914 case I64_DADJSP:
9915 check_mips_64(ctx);
9916 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9917 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9918 break;
9919 case I64_LDPC:
9920 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9921 generate_exception(ctx, EXCP_RI);
9922 } else {
9923 offset = extended ? offset : offset << 3;
d75c135e 9924 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9925 }
9926 break;
9927 case I64_DADDIU5:
9928 check_mips_64(ctx);
9929 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9930 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9931 break;
9932 case I64_DADDIUPC:
9933 check_mips_64(ctx);
9934 offset = extended ? offset : offset << 2;
9935 gen_addiupc(ctx, ry, offset, 1, extended);
9936 break;
9937 case I64_DADDIUSP:
9938 check_mips_64(ctx);
9939 offset = extended ? offset : offset << 2;
d75c135e 9940 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9941 break;
9942 }
9943}
9944#endif
9945
240ce26a 9946static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 9947{
895c2d04 9948 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9949 int op, rx, ry, funct, sa;
9950 int16_t imm, offset;
9951
9952 ctx->opcode = (ctx->opcode << 16) | extend;
9953 op = (ctx->opcode >> 11) & 0x1f;
9954 sa = (ctx->opcode >> 22) & 0x1f;
9955 funct = (ctx->opcode >> 8) & 0x7;
9956 rx = xlat((ctx->opcode >> 8) & 0x7);
9957 ry = xlat((ctx->opcode >> 5) & 0x7);
9958 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9959 | ((ctx->opcode >> 21) & 0x3f) << 5
9960 | (ctx->opcode & 0x1f));
9961
9962 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9963 counterparts. */
9964 switch (op) {
9965 case M16_OPC_ADDIUSP:
d75c135e 9966 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9967 break;
9968 case M16_OPC_ADDIUPC:
9969 gen_addiupc(ctx, rx, imm, 0, 1);
9970 break;
9971 case M16_OPC_B:
9972 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9973 /* No delay slot, so just process as a normal instruction */
9974 break;
9975 case M16_OPC_BEQZ:
9976 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9977 /* No delay slot, so just process as a normal instruction */
9978 break;
9979 case M16_OPC_BNEQZ:
9980 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9981 /* No delay slot, so just process as a normal instruction */
9982 break;
9983 case M16_OPC_SHIFT:
9984 switch (ctx->opcode & 0x3) {
9985 case 0x0:
d75c135e 9986 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9987 break;
9988 case 0x1:
9989#if defined(TARGET_MIPS64)
9990 check_mips_64(ctx);
d75c135e 9991 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9992#else
9993 generate_exception(ctx, EXCP_RI);
9994#endif
9995 break;
9996 case 0x2:
d75c135e 9997 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9998 break;
9999 case 0x3:
d75c135e 10000 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
10001 break;
10002 }
10003 break;
10004#if defined(TARGET_MIPS64)
10005 case M16_OPC_LD:
10006 check_mips_64(ctx);
d75c135e 10007 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
10008 break;
10009#endif
10010 case M16_OPC_RRIA:
10011 imm = ctx->opcode & 0xf;
10012 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
10013 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
10014 imm = (int16_t) (imm << 1) >> 1;
10015 if ((ctx->opcode >> 4) & 0x1) {
10016#if defined(TARGET_MIPS64)
10017 check_mips_64(ctx);
d75c135e 10018 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
10019#else
10020 generate_exception(ctx, EXCP_RI);
10021#endif
10022 } else {
d75c135e 10023 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
10024 }
10025 break;
10026 case M16_OPC_ADDIU8:
d75c135e 10027 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
10028 break;
10029 case M16_OPC_SLTI:
d75c135e 10030 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
10031 break;
10032 case M16_OPC_SLTIU:
d75c135e 10033 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
10034 break;
10035 case M16_OPC_I8:
10036 switch (funct) {
10037 case I8_BTEQZ:
10038 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
10039 break;
10040 case I8_BTNEZ:
10041 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
10042 break;
10043 case I8_SWRASP:
5c13fdfd 10044 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
10045 break;
10046 case I8_ADJSP:
d75c135e 10047 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
10048 break;
10049 case I8_SVRS:
10050 {
10051 int xsregs = (ctx->opcode >> 24) & 0x7;
10052 int aregs = (ctx->opcode >> 16) & 0xf;
10053 int do_ra = (ctx->opcode >> 6) & 0x1;
10054 int do_s0 = (ctx->opcode >> 5) & 0x1;
10055 int do_s1 = (ctx->opcode >> 4) & 0x1;
10056 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
10057 | (ctx->opcode & 0xf)) << 3;
10058
10059 if (ctx->opcode & (1 << 7)) {
10060 gen_mips16_save(ctx, xsregs, aregs,
10061 do_ra, do_s0, do_s1,
10062 framesize);
10063 } else {
10064 gen_mips16_restore(ctx, xsregs, aregs,
10065 do_ra, do_s0, do_s1,
10066 framesize);
10067 }
10068 }
10069 break;
10070 default:
10071 generate_exception(ctx, EXCP_RI);
10072 break;
10073 }
10074 break;
10075 case M16_OPC_LI:
10076 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
10077 break;
10078 case M16_OPC_CMPI:
10079 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
10080 break;
10081#if defined(TARGET_MIPS64)
10082 case M16_OPC_SD:
5c13fdfd 10083 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
10084 break;
10085#endif
10086 case M16_OPC_LB:
d75c135e 10087 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10088 break;
10089 case M16_OPC_LH:
d75c135e 10090 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
10091 break;
10092 case M16_OPC_LWSP:
d75c135e 10093 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
10094 break;
10095 case M16_OPC_LW:
d75c135e 10096 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
10097 break;
10098 case M16_OPC_LBU:
d75c135e 10099 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10100 break;
10101 case M16_OPC_LHU:
d75c135e 10102 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
10103 break;
10104 case M16_OPC_LWPC:
d75c135e 10105 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
10106 break;
10107#if defined(TARGET_MIPS64)
10108 case M16_OPC_LWU:
d75c135e 10109 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
10110 break;
10111#endif
10112 case M16_OPC_SB:
5c13fdfd 10113 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10114 break;
10115 case M16_OPC_SH:
5c13fdfd 10116 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
10117 break;
10118 case M16_OPC_SWSP:
5c13fdfd 10119 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
10120 break;
10121 case M16_OPC_SW:
5c13fdfd 10122 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
10123 break;
10124#if defined(TARGET_MIPS64)
10125 case M16_OPC_I64:
d75c135e 10126 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
10127 break;
10128#endif
10129 default:
10130 generate_exception(ctx, EXCP_RI);
10131 break;
10132 }
10133
10134 return 4;
10135}
10136
240ce26a 10137static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
10138{
10139 int rx, ry;
10140 int sa;
10141 int op, cnvt_op, op1, offset;
10142 int funct;
10143 int n_bytes;
10144
10145 op = (ctx->opcode >> 11) & 0x1f;
10146 sa = (ctx->opcode >> 2) & 0x7;
10147 sa = sa == 0 ? 8 : sa;
10148 rx = xlat((ctx->opcode >> 8) & 0x7);
10149 cnvt_op = (ctx->opcode >> 5) & 0x7;
10150 ry = xlat((ctx->opcode >> 5) & 0x7);
10151 op1 = offset = ctx->opcode & 0x1f;
10152
10153 n_bytes = 2;
10154
10155 switch (op) {
10156 case M16_OPC_ADDIUSP:
10157 {
10158 int16_t imm = ((uint8_t) ctx->opcode) << 2;
10159
d75c135e 10160 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
10161 }
10162 break;
10163 case M16_OPC_ADDIUPC:
10164 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
10165 break;
10166 case M16_OPC_B:
10167 offset = (ctx->opcode & 0x7ff) << 1;
10168 offset = (int16_t)(offset << 4) >> 4;
10169 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
10170 /* No delay slot, so just process as a normal instruction */
10171 break;
10172 case M16_OPC_JAL:
895c2d04 10173 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
10174 offset = (((ctx->opcode & 0x1f) << 21)
10175 | ((ctx->opcode >> 5) & 0x1f) << 16
10176 | offset) << 2;
620e48f6 10177 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
10178 gen_compute_branch(ctx, op, 4, rx, ry, offset);
10179 n_bytes = 4;
364d4831
NF
10180 break;
10181 case M16_OPC_BEQZ:
10182 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
10183 /* No delay slot, so just process as a normal instruction */
10184 break;
10185 case M16_OPC_BNEQZ:
10186 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
10187 /* No delay slot, so just process as a normal instruction */
10188 break;
10189 case M16_OPC_SHIFT:
10190 switch (ctx->opcode & 0x3) {
10191 case 0x0:
d75c135e 10192 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
10193 break;
10194 case 0x1:
10195#if defined(TARGET_MIPS64)
10196 check_mips_64(ctx);
d75c135e 10197 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
10198#else
10199 generate_exception(ctx, EXCP_RI);
10200#endif
10201 break;
10202 case 0x2:
d75c135e 10203 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
10204 break;
10205 case 0x3:
d75c135e 10206 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
10207 break;
10208 }
10209 break;
10210#if defined(TARGET_MIPS64)
10211 case M16_OPC_LD:
10212 check_mips_64(ctx);
d75c135e 10213 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
10214 break;
10215#endif
10216 case M16_OPC_RRIA:
10217 {
10218 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
10219
10220 if ((ctx->opcode >> 4) & 1) {
10221#if defined(TARGET_MIPS64)
10222 check_mips_64(ctx);
d75c135e 10223 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
10224#else
10225 generate_exception(ctx, EXCP_RI);
10226#endif
10227 } else {
d75c135e 10228 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
10229 }
10230 }
10231 break;
10232 case M16_OPC_ADDIU8:
10233 {
10234 int16_t imm = (int8_t) ctx->opcode;
10235
d75c135e 10236 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
10237 }
10238 break;
10239 case M16_OPC_SLTI:
10240 {
10241 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10242 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
10243 }
10244 break;
10245 case M16_OPC_SLTIU:
10246 {
10247 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10248 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
10249 }
10250 break;
10251 case M16_OPC_I8:
10252 {
10253 int reg32;
10254
10255 funct = (ctx->opcode >> 8) & 0x7;
10256 switch (funct) {
10257 case I8_BTEQZ:
10258 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
10259 ((int8_t)ctx->opcode) << 1);
10260 break;
10261 case I8_BTNEZ:
10262 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
10263 ((int8_t)ctx->opcode) << 1);
10264 break;
10265 case I8_SWRASP:
5c13fdfd 10266 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
10267 break;
10268 case I8_ADJSP:
d75c135e 10269 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
10270 ((int8_t)ctx->opcode) << 3);
10271 break;
10272 case I8_SVRS:
10273 {
10274 int do_ra = ctx->opcode & (1 << 6);
10275 int do_s0 = ctx->opcode & (1 << 5);
10276 int do_s1 = ctx->opcode & (1 << 4);
10277 int framesize = ctx->opcode & 0xf;
10278
10279 if (framesize == 0) {
10280 framesize = 128;
10281 } else {
10282 framesize = framesize << 3;
10283 }
10284
10285 if (ctx->opcode & (1 << 7)) {
10286 gen_mips16_save(ctx, 0, 0,
10287 do_ra, do_s0, do_s1, framesize);
10288 } else {
10289 gen_mips16_restore(ctx, 0, 0,
10290 do_ra, do_s0, do_s1, framesize);
10291 }
10292 }
10293 break;
10294 case I8_MOV32R:
10295 {
10296 int rz = xlat(ctx->opcode & 0x7);
10297
10298 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
10299 ((ctx->opcode >> 5) & 0x7);
d75c135e 10300 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
10301 }
10302 break;
10303 case I8_MOVR32:
10304 reg32 = ctx->opcode & 0x1f;
d75c135e 10305 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
10306 break;
10307 default:
10308 generate_exception(ctx, EXCP_RI);
10309 break;
10310 }
10311 }
10312 break;
10313 case M16_OPC_LI:
10314 {
10315 int16_t imm = (uint8_t) ctx->opcode;
10316
d75c135e 10317 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
10318 }
10319 break;
10320 case M16_OPC_CMPI:
10321 {
10322 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10323 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
10324 }
10325 break;
10326#if defined(TARGET_MIPS64)
10327 case M16_OPC_SD:
10328 check_mips_64(ctx);
5c13fdfd 10329 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
10330 break;
10331#endif
10332 case M16_OPC_LB:
d75c135e 10333 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10334 break;
10335 case M16_OPC_LH:
d75c135e 10336 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
10337 break;
10338 case M16_OPC_LWSP:
d75c135e 10339 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10340 break;
10341 case M16_OPC_LW:
d75c135e 10342 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10343 break;
10344 case M16_OPC_LBU:
d75c135e 10345 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10346 break;
10347 case M16_OPC_LHU:
d75c135e 10348 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10349 break;
10350 case M16_OPC_LWPC:
d75c135e 10351 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10352 break;
10353#if defined (TARGET_MIPS64)
10354 case M16_OPC_LWU:
10355 check_mips_64(ctx);
d75c135e 10356 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10357 break;
10358#endif
10359 case M16_OPC_SB:
5c13fdfd 10360 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10361 break;
10362 case M16_OPC_SH:
5c13fdfd 10363 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10364 break;
10365 case M16_OPC_SWSP:
5c13fdfd 10366 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10367 break;
10368 case M16_OPC_SW:
5c13fdfd 10369 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10370 break;
10371 case M16_OPC_RRR:
10372 {
10373 int rz = xlat((ctx->opcode >> 2) & 0x7);
10374 int mips32_op;
10375
10376 switch (ctx->opcode & 0x3) {
10377 case RRR_ADDU:
10378 mips32_op = OPC_ADDU;
10379 break;
10380 case RRR_SUBU:
10381 mips32_op = OPC_SUBU;
10382 break;
10383#if defined(TARGET_MIPS64)
10384 case RRR_DADDU:
10385 mips32_op = OPC_DADDU;
10386 check_mips_64(ctx);
10387 break;
10388 case RRR_DSUBU:
10389 mips32_op = OPC_DSUBU;
10390 check_mips_64(ctx);
10391 break;
10392#endif
10393 default:
10394 generate_exception(ctx, EXCP_RI);
10395 goto done;
10396 }
10397
d75c135e 10398 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10399 done:
10400 ;
10401 }
10402 break;
10403 case M16_OPC_RR:
10404 switch (op1) {
10405 case RR_JR:
10406 {
10407 int nd = (ctx->opcode >> 7) & 0x1;
10408 int link = (ctx->opcode >> 6) & 0x1;
10409 int ra = (ctx->opcode >> 5) & 0x1;
10410
10411 if (link) {
620e48f6 10412 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10413 } else {
10414 op = OPC_JR;
10415 }
10416
10417 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
364d4831
NF
10418 }
10419 break;
10420 case RR_SDBBP:
10421 /* XXX: not clear which exception should be raised
10422 * when in debug mode...
10423 */
d75c135e 10424 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10425 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10426 generate_exception(ctx, EXCP_DBp);
10427 } else {
10428 generate_exception(ctx, EXCP_DBp);
10429 }
10430 break;
10431 case RR_SLT:
d75c135e 10432 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10433 break;
10434 case RR_SLTU:
d75c135e 10435 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10436 break;
10437 case RR_BREAK:
10438 generate_exception(ctx, EXCP_BREAK);
10439 break;
10440 case RR_SLLV:
d75c135e 10441 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10442 break;
10443 case RR_SRLV:
d75c135e 10444 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10445 break;
10446 case RR_SRAV:
d75c135e 10447 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10448 break;
10449#if defined (TARGET_MIPS64)
10450 case RR_DSRL:
10451 check_mips_64(ctx);
d75c135e 10452 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10453 break;
10454#endif
10455 case RR_CMP:
d75c135e 10456 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10457 break;
10458 case RR_NEG:
d75c135e 10459 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10460 break;
10461 case RR_AND:
d75c135e 10462 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10463 break;
10464 case RR_OR:
d75c135e 10465 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10466 break;
10467 case RR_XOR:
d75c135e 10468 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10469 break;
10470 case RR_NOT:
d75c135e 10471 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10472 break;
10473 case RR_MFHI:
26135ead 10474 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
10475 break;
10476 case RR_CNVT:
10477 switch (cnvt_op) {
10478 case RR_RY_CNVT_ZEB:
10479 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10480 break;
10481 case RR_RY_CNVT_ZEH:
10482 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10483 break;
10484 case RR_RY_CNVT_SEB:
10485 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10486 break;
10487 case RR_RY_CNVT_SEH:
10488 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10489 break;
10490#if defined (TARGET_MIPS64)
10491 case RR_RY_CNVT_ZEW:
10492 check_mips_64(ctx);
10493 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10494 break;
10495 case RR_RY_CNVT_SEW:
10496 check_mips_64(ctx);
10497 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10498 break;
10499#endif
10500 default:
10501 generate_exception(ctx, EXCP_RI);
10502 break;
10503 }
10504 break;
10505 case RR_MFLO:
26135ead 10506 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
10507 break;
10508#if defined (TARGET_MIPS64)
10509 case RR_DSRA:
10510 check_mips_64(ctx);
d75c135e 10511 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10512 break;
10513 case RR_DSLLV:
10514 check_mips_64(ctx);
d75c135e 10515 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10516 break;
10517 case RR_DSRLV:
10518 check_mips_64(ctx);
d75c135e 10519 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10520 break;
10521 case RR_DSRAV:
10522 check_mips_64(ctx);
d75c135e 10523 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10524 break;
10525#endif
10526 case RR_MULT:
26135ead 10527 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
10528 break;
10529 case RR_MULTU:
26135ead 10530 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
10531 break;
10532 case RR_DIV:
26135ead 10533 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
10534 break;
10535 case RR_DIVU:
26135ead 10536 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
10537 break;
10538#if defined (TARGET_MIPS64)
10539 case RR_DMULT:
10540 check_mips_64(ctx);
26135ead 10541 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
10542 break;
10543 case RR_DMULTU:
10544 check_mips_64(ctx);
26135ead 10545 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
10546 break;
10547 case RR_DDIV:
10548 check_mips_64(ctx);
26135ead 10549 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
10550 break;
10551 case RR_DDIVU:
10552 check_mips_64(ctx);
26135ead 10553 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
10554 break;
10555#endif
10556 default:
10557 generate_exception(ctx, EXCP_RI);
10558 break;
10559 }
10560 break;
10561 case M16_OPC_EXTEND:
240ce26a 10562 decode_extended_mips16_opc(env, ctx);
364d4831
NF
10563 n_bytes = 4;
10564 break;
10565#if defined(TARGET_MIPS64)
10566 case M16_OPC_I64:
10567 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10568 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10569 break;
10570#endif
10571 default:
10572 generate_exception(ctx, EXCP_RI);
10573 break;
10574 }
10575
10576 return n_bytes;
10577}
10578
211da992 10579/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10580
211da992
CWR
10581/*
10582 * microMIPS32/microMIPS64 major opcodes
10583 *
10584 * 1. MIPS Architecture for Programmers Volume II-B:
10585 * The microMIPS32 Instruction Set (Revision 3.05)
10586 *
10587 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10588 *
10589 * 2. MIPS Architecture For Programmers Volume II-A:
10590 * The MIPS64 Instruction Set (Revision 3.51)
10591 */
6af0bf9c 10592
3c824109
NF
10593enum {
10594 POOL32A = 0x00,
10595 POOL16A = 0x01,
10596 LBU16 = 0x02,
10597 MOVE16 = 0x03,
10598 ADDI32 = 0x04,
10599 LBU32 = 0x05,
10600 SB32 = 0x06,
10601 LB32 = 0x07,
10602
10603 POOL32B = 0x08,
10604 POOL16B = 0x09,
10605 LHU16 = 0x0a,
10606 ANDI16 = 0x0b,
10607 ADDIU32 = 0x0c,
10608 LHU32 = 0x0d,
10609 SH32 = 0x0e,
10610 LH32 = 0x0f,
10611
10612 POOL32I = 0x10,
10613 POOL16C = 0x11,
10614 LWSP16 = 0x12,
10615 POOL16D = 0x13,
10616 ORI32 = 0x14,
10617 POOL32F = 0x15,
211da992
CWR
10618 POOL32S = 0x16, /* MIPS64 */
10619 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10620
211da992 10621 /* 0x1f is reserved */
3c824109
NF
10622 POOL32C = 0x18,
10623 LWGP16 = 0x19,
10624 LW16 = 0x1a,
10625 POOL16E = 0x1b,
10626 XORI32 = 0x1c,
10627 JALS32 = 0x1d,
10628 ADDIUPC = 0x1e,
3c824109
NF
10629
10630 /* 0x20 is reserved */
10631 RES_20 = 0x20,
10632 POOL16F = 0x21,
10633 SB16 = 0x22,
10634 BEQZ16 = 0x23,
10635 SLTI32 = 0x24,
10636 BEQ32 = 0x25,
10637 SWC132 = 0x26,
10638 LWC132 = 0x27,
10639
10640 /* 0x28 and 0x29 are reserved */
10641 RES_28 = 0x28,
10642 RES_29 = 0x29,
10643 SH16 = 0x2a,
10644 BNEZ16 = 0x2b,
10645 SLTIU32 = 0x2c,
10646 BNE32 = 0x2d,
10647 SDC132 = 0x2e,
10648 LDC132 = 0x2f,
10649
10650 /* 0x30 and 0x31 are reserved */
10651 RES_30 = 0x30,
10652 RES_31 = 0x31,
10653 SWSP16 = 0x32,
10654 B16 = 0x33,
10655 ANDI32 = 0x34,
10656 J32 = 0x35,
211da992
CWR
10657 SD32 = 0x36, /* MIPS64 */
10658 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10659
10660 /* 0x38 and 0x39 are reserved */
10661 RES_38 = 0x38,
10662 RES_39 = 0x39,
10663 SW16 = 0x3a,
10664 LI16 = 0x3b,
10665 JALX32 = 0x3c,
10666 JAL32 = 0x3d,
10667 SW32 = 0x3e,
10668 LW32 = 0x3f
10669};
10670
10671/* POOL32A encoding of minor opcode field */
10672
10673enum {
10674 /* These opcodes are distinguished only by bits 9..6; those bits are
10675 * what are recorded below. */
10676 SLL32 = 0x0,
10677 SRL32 = 0x1,
10678 SRA = 0x2,
10679 ROTR = 0x3,
10680
10681 SLLV = 0x0,
10682 SRLV = 0x1,
10683 SRAV = 0x2,
10684 ROTRV = 0x3,
10685 ADD = 0x4,
10686 ADDU32 = 0x5,
10687 SUB = 0x6,
10688 SUBU32 = 0x7,
10689 MUL = 0x8,
10690 AND = 0x9,
10691 OR32 = 0xa,
10692 NOR = 0xb,
10693 XOR32 = 0xc,
10694 SLT = 0xd,
10695 SLTU = 0xe,
10696
10697 MOVN = 0x0,
10698 MOVZ = 0x1,
10699 LWXS = 0x4,
10700
10701 /* The following can be distinguished by their lower 6 bits. */
10702 INS = 0x0c,
10703 EXT = 0x2c,
10704 POOL32AXF = 0x3c
10705};
10706
10707/* POOL32AXF encoding of minor opcode field extension */
10708
d132c79f
CWR
10709/*
10710 * 1. MIPS Architecture for Programmers Volume II-B:
10711 * The microMIPS32 Instruction Set (Revision 3.05)
10712 *
10713 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10714 *
10715 * 2. MIPS Architecture for Programmers VolumeIV-e:
10716 * The MIPS DSP Application-Specific Extension
10717 * to the microMIPS32 Architecture (Revision 2.34)
10718 *
10719 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10720 */
10721
3c824109
NF
10722enum {
10723 /* bits 11..6 */
10724 TEQ = 0x00,
10725 TGE = 0x08,
10726 TGEU = 0x10,
10727 TLT = 0x20,
10728 TLTU = 0x28,
10729 TNE = 0x30,
10730
10731 MFC0 = 0x03,
10732 MTC0 = 0x0b,
10733
d132c79f
CWR
10734 /* begin of microMIPS32 DSP */
10735
3c824109
NF
10736 /* bits 13..12 for 0x01 */
10737 MFHI_ACC = 0x0,
10738 MFLO_ACC = 0x1,
10739 MTHI_ACC = 0x2,
10740 MTLO_ACC = 0x3,
10741
10742 /* bits 13..12 for 0x2a */
10743 MADD_ACC = 0x0,
10744 MADDU_ACC = 0x1,
10745 MSUB_ACC = 0x2,
10746 MSUBU_ACC = 0x3,
10747
10748 /* bits 13..12 for 0x32 */
10749 MULT_ACC = 0x0,
6801038b 10750 MULTU_ACC = 0x1,
3c824109 10751
d132c79f
CWR
10752 /* end of microMIPS32 DSP */
10753
3c824109
NF
10754 /* bits 15..12 for 0x2c */
10755 SEB = 0x2,
10756 SEH = 0x3,
10757 CLO = 0x4,
10758 CLZ = 0x5,
10759 RDHWR = 0x6,
10760 WSBH = 0x7,
10761 MULT = 0x8,
10762 MULTU = 0x9,
10763 DIV = 0xa,
10764 DIVU = 0xb,
10765 MADD = 0xc,
10766 MADDU = 0xd,
10767 MSUB = 0xe,
10768 MSUBU = 0xf,
10769
10770 /* bits 15..12 for 0x34 */
10771 MFC2 = 0x4,
10772 MTC2 = 0x5,
10773 MFHC2 = 0x8,
10774 MTHC2 = 0x9,
10775 CFC2 = 0xc,
10776 CTC2 = 0xd,
10777
10778 /* bits 15..12 for 0x3c */
10779 JALR = 0x0,
10780 JR = 0x0, /* alias */
10781 JALR_HB = 0x1,
10782 JALRS = 0x4,
10783 JALRS_HB = 0x5,
10784
10785 /* bits 15..12 for 0x05 */
10786 RDPGPR = 0xe,
10787 WRPGPR = 0xf,
10788
10789 /* bits 15..12 for 0x0d */
10790 TLBP = 0x0,
10791 TLBR = 0x1,
10792 TLBWI = 0x2,
10793 TLBWR = 0x3,
10794 WAIT = 0x9,
10795 IRET = 0xd,
10796 DERET = 0xe,
10797 ERET = 0xf,
10798
10799 /* bits 15..12 for 0x15 */
10800 DMT = 0x0,
10801 DVPE = 0x1,
10802 EMT = 0x2,
10803 EVPE = 0x3,
10804
10805 /* bits 15..12 for 0x1d */
10806 DI = 0x4,
10807 EI = 0x5,
10808
10809 /* bits 15..12 for 0x2d */
10810 SYNC = 0x6,
10811 SYSCALL = 0x8,
10812 SDBBP = 0xd,
10813
10814 /* bits 15..12 for 0x35 */
10815 MFHI32 = 0x0,
10816 MFLO32 = 0x1,
10817 MTHI32 = 0x2,
10818 MTLO32 = 0x3,
10819};
10820
10821/* POOL32B encoding of minor opcode field (bits 15..12) */
10822
10823enum {
10824 LWC2 = 0x0,
10825 LWP = 0x1,
10826 LDP = 0x4,
10827 LWM32 = 0x5,
10828 CACHE = 0x6,
10829 LDM = 0x7,
10830 SWC2 = 0x8,
10831 SWP = 0x9,
10832 SDP = 0xc,
10833 SWM32 = 0xd,
10834 SDM = 0xf
10835};
10836
10837/* POOL32C encoding of minor opcode field (bits 15..12) */
10838
10839enum {
10840 LWL = 0x0,
10841 SWL = 0x8,
10842 LWR = 0x1,
10843 SWR = 0x9,
10844 PREF = 0x2,
10845 /* 0xa is reserved */
10846 LL = 0x3,
10847 SC = 0xb,
10848 LDL = 0x4,
10849 SDL = 0xc,
10850 LDR = 0x5,
10851 SDR = 0xd,
10852 /* 0x6 is reserved */
10853 LWU = 0xe,
10854 LLD = 0x7,
10855 SCD = 0xf
10856};
10857
10858/* POOL32F encoding of minor opcode field (bits 5..0) */
10859
10860enum {
10861 /* These are the bit 7..6 values */
10862 ADD_FMT = 0x0,
10863 MOVN_FMT = 0x0,
10864
10865 SUB_FMT = 0x1,
10866 MOVZ_FMT = 0x1,
10867
10868 MUL_FMT = 0x2,
10869
10870 DIV_FMT = 0x3,
10871
10872 /* These are the bit 8..6 values */
10873 RSQRT2_FMT = 0x0,
10874 MOVF_FMT = 0x0,
10875
10876 LWXC1 = 0x1,
10877 MOVT_FMT = 0x1,
10878
10879 PLL_PS = 0x2,
10880 SWXC1 = 0x2,
10881
10882 PLU_PS = 0x3,
10883 LDXC1 = 0x3,
10884
10885 PUL_PS = 0x4,
10886 SDXC1 = 0x4,
10887 RECIP2_FMT = 0x4,
10888
10889 PUU_PS = 0x5,
10890 LUXC1 = 0x5,
10891
10892 CVT_PS_S = 0x6,
10893 SUXC1 = 0x6,
10894 ADDR_PS = 0x6,
10895 PREFX = 0x6,
10896
10897 MULR_PS = 0x7,
10898
10899 MADD_S = 0x01,
10900 MADD_D = 0x09,
10901 MADD_PS = 0x11,
10902 ALNV_PS = 0x19,
10903 MSUB_S = 0x21,
10904 MSUB_D = 0x29,
10905 MSUB_PS = 0x31,
10906
10907 NMADD_S = 0x02,
10908 NMADD_D = 0x0a,
10909 NMADD_PS = 0x12,
10910 NMSUB_S = 0x22,
10911 NMSUB_D = 0x2a,
10912 NMSUB_PS = 0x32,
10913
10914 POOL32FXF = 0x3b,
10915
10916 CABS_COND_FMT = 0x1c, /* MIPS3D */
10917 C_COND_FMT = 0x3c
10918};
10919
10920/* POOL32Fxf encoding of minor opcode extension field */
10921
10922enum {
10923 CVT_L = 0x04,
10924 RSQRT_FMT = 0x08,
10925 FLOOR_L = 0x0c,
10926 CVT_PW_PS = 0x1c,
10927 CVT_W = 0x24,
10928 SQRT_FMT = 0x28,
10929 FLOOR_W = 0x2c,
10930 CVT_PS_PW = 0x3c,
10931 CFC1 = 0x40,
10932 RECIP_FMT = 0x48,
10933 CEIL_L = 0x4c,
10934 CTC1 = 0x60,
10935 CEIL_W = 0x6c,
10936 MFC1 = 0x80,
10937 CVT_S_PL = 0x84,
10938 TRUNC_L = 0x8c,
10939 MTC1 = 0xa0,
10940 CVT_S_PU = 0xa4,
10941 TRUNC_W = 0xac,
10942 MFHC1 = 0xc0,
10943 ROUND_L = 0xcc,
10944 MTHC1 = 0xe0,
10945 ROUND_W = 0xec,
10946
10947 MOV_FMT = 0x01,
10948 MOVF = 0x05,
10949 ABS_FMT = 0x0d,
10950 RSQRT1_FMT = 0x1d,
10951 MOVT = 0x25,
10952 NEG_FMT = 0x2d,
10953 CVT_D = 0x4d,
10954 RECIP1_FMT = 0x5d,
10955 CVT_S = 0x6d
10956};
10957
10958/* POOL32I encoding of minor opcode field (bits 25..21) */
10959
10960enum {
10961 BLTZ = 0x00,
10962 BLTZAL = 0x01,
10963 BGEZ = 0x02,
10964 BGEZAL = 0x03,
10965 BLEZ = 0x04,
10966 BNEZC = 0x05,
10967 BGTZ = 0x06,
10968 BEQZC = 0x07,
10969 TLTI = 0x08,
10970 TGEI = 0x09,
10971 TLTIU = 0x0a,
10972 TGEIU = 0x0b,
10973 TNEI = 0x0c,
10974 LUI = 0x0d,
10975 TEQI = 0x0e,
10976 SYNCI = 0x10,
10977 BLTZALS = 0x11,
10978 BGEZALS = 0x13,
10979 BC2F = 0x14,
10980 BC2T = 0x15,
10981 BPOSGE64 = 0x1a,
10982 BPOSGE32 = 0x1b,
10983 /* These overlap and are distinguished by bit16 of the instruction */
10984 BC1F = 0x1c,
10985 BC1T = 0x1d,
10986 BC1ANY2F = 0x1c,
10987 BC1ANY2T = 0x1d,
10988 BC1ANY4F = 0x1e,
10989 BC1ANY4T = 0x1f
10990};
10991
10992/* POOL16A encoding of minor opcode field */
10993
10994enum {
10995 ADDU16 = 0x0,
10996 SUBU16 = 0x1
10997};
10998
10999/* POOL16B encoding of minor opcode field */
11000
11001enum {
11002 SLL16 = 0x0,
11003 SRL16 = 0x1
11004};
11005
11006/* POOL16C encoding of minor opcode field */
11007
11008enum {
11009 NOT16 = 0x00,
11010 XOR16 = 0x04,
11011 AND16 = 0x08,
11012 OR16 = 0x0c,
11013 LWM16 = 0x10,
11014 SWM16 = 0x14,
11015 JR16 = 0x18,
11016 JRC16 = 0x1a,
11017 JALR16 = 0x1c,
11018 JALR16S = 0x1e,
11019 MFHI16 = 0x20,
11020 MFLO16 = 0x24,
11021 BREAK16 = 0x28,
11022 SDBBP16 = 0x2c,
11023 JRADDIUSP = 0x30
11024};
11025
11026/* POOL16D encoding of minor opcode field */
11027
11028enum {
11029 ADDIUS5 = 0x0,
11030 ADDIUSP = 0x1
11031};
11032
11033/* POOL16E encoding of minor opcode field */
11034
11035enum {
11036 ADDIUR2 = 0x0,
11037 ADDIUR1SP = 0x1
11038};
11039
11040static int mmreg (int r)
11041{
11042 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11043
11044 return map[r];
11045}
11046
11047/* Used for 16-bit store instructions. */
11048static int mmreg2 (int r)
11049{
11050 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
11051
11052 return map[r];
11053}
11054
11055#define uMIPS_RD(op) ((op >> 7) & 0x7)
11056#define uMIPS_RS(op) ((op >> 4) & 0x7)
11057#define uMIPS_RS2(op) uMIPS_RS(op)
11058#define uMIPS_RS1(op) ((op >> 1) & 0x7)
11059#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
11060#define uMIPS_RS5(op) (op & 0x1f)
11061
11062/* Signed immediate */
11063#define SIMM(op, start, width) \
11064 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
11065 << (32-width)) \
11066 >> (32-width))
11067/* Zero-extended immediate */
11068#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
11069
d75c135e 11070static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
11071{
11072 int rd = mmreg(uMIPS_RD(ctx->opcode));
11073
d75c135e 11074 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
11075}
11076
d75c135e 11077static void gen_addiur2(DisasContext *ctx)
3c824109
NF
11078{
11079 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
11080 int rd = mmreg(uMIPS_RD(ctx->opcode));
11081 int rs = mmreg(uMIPS_RS(ctx->opcode));
11082
d75c135e 11083 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
11084}
11085
d75c135e 11086static void gen_addiusp(DisasContext *ctx)
3c824109
NF
11087{
11088 int encoded = ZIMM(ctx->opcode, 1, 9);
11089 int decoded;
11090
11091 if (encoded <= 1) {
11092 decoded = 256 + encoded;
11093 } else if (encoded <= 255) {
11094 decoded = encoded;
11095 } else if (encoded <= 509) {
11096 decoded = encoded - 512;
11097 } else {
11098 decoded = encoded - 768;
11099 }
11100
d75c135e 11101 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
11102}
11103
d75c135e 11104static void gen_addius5(DisasContext *ctx)
3c824109
NF
11105{
11106 int imm = SIMM(ctx->opcode, 1, 4);
11107 int rd = (ctx->opcode >> 5) & 0x1f;
11108
d75c135e 11109 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
11110}
11111
d75c135e 11112static void gen_andi16(DisasContext *ctx)
3c824109
NF
11113{
11114 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
11115 31, 32, 63, 64, 255, 32768, 65535 };
11116 int rd = mmreg(uMIPS_RD(ctx->opcode));
11117 int rs = mmreg(uMIPS_RS(ctx->opcode));
11118 int encoded = ZIMM(ctx->opcode, 0, 4);
11119
d75c135e 11120 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
11121}
11122
11123static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
11124 int base, int16_t offset)
11125{
e1050a76 11126 const char *opn = "ldst_multiple";
3c824109
NF
11127 TCGv t0, t1;
11128 TCGv_i32 t2;
11129
11130 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11131 generate_exception(ctx, EXCP_RI);
11132 return;
11133 }
11134
11135 t0 = tcg_temp_new();
11136
11137 gen_base_offset_addr(ctx, t0, base, offset);
11138
11139 t1 = tcg_const_tl(reglist);
11140 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 11141
3c824109
NF
11142 save_cpu_state(ctx, 1);
11143 switch (opc) {
11144 case LWM32:
895c2d04 11145 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 11146 opn = "lwm";
3c824109
NF
11147 break;
11148 case SWM32:
895c2d04 11149 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 11150 opn = "swm";
3c824109
NF
11151 break;
11152#ifdef TARGET_MIPS64
11153 case LDM:
895c2d04 11154 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 11155 opn = "ldm";
3c824109
NF
11156 break;
11157 case SDM:
895c2d04 11158 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 11159 opn = "sdm";
3c824109 11160 break;
6af0bf9c 11161#endif
3c824109 11162 }
e1050a76 11163 (void)opn;
3c824109
NF
11164 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
11165 tcg_temp_free(t0);
33087598 11166 tcg_temp_free(t1);
3c824109
NF
11167 tcg_temp_free_i32(t2);
11168}
6af0bf9c 11169
3c824109 11170
240ce26a 11171static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 11172{
3c824109
NF
11173 int rd = mmreg((ctx->opcode >> 3) & 0x7);
11174 int rs = mmreg(ctx->opcode & 0x7);
11175 int opc;
6af0bf9c 11176
3c824109
NF
11177 switch (((ctx->opcode) >> 4) & 0x3f) {
11178 case NOT16 + 0:
11179 case NOT16 + 1:
11180 case NOT16 + 2:
11181 case NOT16 + 3:
d75c135e 11182 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
11183 break;
11184 case XOR16 + 0:
11185 case XOR16 + 1:
11186 case XOR16 + 2:
11187 case XOR16 + 3:
d75c135e 11188 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
11189 break;
11190 case AND16 + 0:
11191 case AND16 + 1:
11192 case AND16 + 2:
11193 case AND16 + 3:
d75c135e 11194 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
11195 break;
11196 case OR16 + 0:
11197 case OR16 + 1:
11198 case OR16 + 2:
11199 case OR16 + 3:
d75c135e 11200 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
11201 break;
11202 case LWM16 + 0:
11203 case LWM16 + 1:
11204 case LWM16 + 2:
11205 case LWM16 + 3:
11206 {
11207 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
11208 int offset = ZIMM(ctx->opcode, 0, 4);
11209
11210 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
11211 29, offset << 2);
11212 }
11213 break;
11214 case SWM16 + 0:
11215 case SWM16 + 1:
11216 case SWM16 + 2:
11217 case SWM16 + 3:
11218 {
11219 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
11220 int offset = ZIMM(ctx->opcode, 0, 4);
11221
11222 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
11223 29, offset << 2);
11224 }
11225 break;
11226 case JR16 + 0:
11227 case JR16 + 1:
11228 {
11229 int reg = ctx->opcode & 0x1f;
11230
11231 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
11232 }
3c824109
NF
11233 break;
11234 case JRC16 + 0:
11235 case JRC16 + 1:
11236 {
11237 int reg = ctx->opcode & 0x1f;
11238
11239 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
11240 /* Let normal delay slot handling in our caller take us
11241 to the branch target. */
11242 }
11243 break;
11244 case JALR16 + 0:
11245 case JALR16 + 1:
11246 opc = OPC_JALR;
11247 goto do_jalr;
11248 case JALR16S + 0:
11249 case JALR16S + 1:
11250 opc = OPC_JALRS;
11251 do_jalr:
11252 {
11253 int reg = ctx->opcode & 0x1f;
11254
11255 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
11256 }
3c824109
NF
11257 break;
11258 case MFHI16 + 0:
11259 case MFHI16 + 1:
26135ead 11260 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
11261 break;
11262 case MFLO16 + 0:
11263 case MFLO16 + 1:
26135ead 11264 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
11265 break;
11266 case BREAK16:
11267 generate_exception(ctx, EXCP_BREAK);
11268 break;
11269 case SDBBP16:
11270 /* XXX: not clear which exception should be raised
11271 * when in debug mode...
11272 */
d75c135e 11273 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11274 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11275 generate_exception(ctx, EXCP_DBp);
11276 } else {
11277 generate_exception(ctx, EXCP_DBp);
11278 }
11279 break;
11280 case JRADDIUSP + 0:
11281 case JRADDIUSP + 1:
11282 {
11283 int imm = ZIMM(ctx->opcode, 0, 5);
11284
11285 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 11286 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
11287 /* Let normal delay slot handling in our caller take us
11288 to the branch target. */
11289 }
11290 break;
11291 default:
11292 generate_exception(ctx, EXCP_RI);
11293 break;
11294 }
11295}
11296
11297static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
11298{
11299 TCGv t0 = tcg_temp_new();
11300 TCGv t1 = tcg_temp_new();
11301
11302 gen_load_gpr(t0, base);
11303
11304 if (index != 0) {
11305 gen_load_gpr(t1, index);
11306 tcg_gen_shli_tl(t1, t1, 2);
11307 gen_op_addr_add(ctx, t0, t1, t0);
11308 }
11309
5f68f5ae 11310 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11311 gen_store_gpr(t1, rd);
11312
11313 tcg_temp_free(t0);
11314 tcg_temp_free(t1);
11315}
11316
11317static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
11318 int base, int16_t offset)
11319{
11320 const char *opn = "ldst_pair";
11321 TCGv t0, t1;
11322
36c6711b 11323 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 11324 generate_exception(ctx, EXCP_RI);
d796321b
FB
11325 return;
11326 }
11327
3c824109
NF
11328 t0 = tcg_temp_new();
11329 t1 = tcg_temp_new();
8e9ade68 11330
3c824109
NF
11331 gen_base_offset_addr(ctx, t0, base, offset);
11332
11333 switch (opc) {
11334 case LWP:
36c6711b
EJ
11335 if (rd == base) {
11336 generate_exception(ctx, EXCP_RI);
11337 return;
11338 }
5f68f5ae 11339 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11340 gen_store_gpr(t1, rd);
11341 tcg_gen_movi_tl(t1, 4);
11342 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11343 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11344 gen_store_gpr(t1, rd+1);
11345 opn = "lwp";
11346 break;
11347 case SWP:
3c824109 11348 gen_load_gpr(t1, rd);
5f68f5ae 11349 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
11350 tcg_gen_movi_tl(t1, 4);
11351 gen_op_addr_add(ctx, t0, t0, t1);
11352 gen_load_gpr(t1, rd+1);
5f68f5ae 11353 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
11354 opn = "swp";
11355 break;
11356#ifdef TARGET_MIPS64
11357 case LDP:
36c6711b
EJ
11358 if (rd == base) {
11359 generate_exception(ctx, EXCP_RI);
11360 return;
11361 }
5f68f5ae 11362 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11363 gen_store_gpr(t1, rd);
11364 tcg_gen_movi_tl(t1, 8);
11365 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11366 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11367 gen_store_gpr(t1, rd+1);
11368 opn = "ldp";
11369 break;
11370 case SDP:
3c824109 11371 gen_load_gpr(t1, rd);
5f68f5ae 11372 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11373 tcg_gen_movi_tl(t1, 8);
11374 gen_op_addr_add(ctx, t0, t0, t1);
11375 gen_load_gpr(t1, rd+1);
5f68f5ae 11376 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11377 opn = "sdp";
11378 break;
11379#endif
6af0bf9c 11380 }
2abf314d 11381 (void)opn; /* avoid a compiler warning */
3c824109
NF
11382 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11383 tcg_temp_free(t0);
11384 tcg_temp_free(t1);
11385}
618b0fe9 11386
240ce26a 11387static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
11388{
11389 int extension = (ctx->opcode >> 6) & 0x3f;
11390 int minor = (ctx->opcode >> 12) & 0xf;
11391 uint32_t mips32_op;
11392
11393 switch (extension) {
11394 case TEQ:
11395 mips32_op = OPC_TEQ;
11396 goto do_trap;
11397 case TGE:
11398 mips32_op = OPC_TGE;
11399 goto do_trap;
11400 case TGEU:
11401 mips32_op = OPC_TGEU;
11402 goto do_trap;
11403 case TLT:
11404 mips32_op = OPC_TLT;
11405 goto do_trap;
11406 case TLTU:
11407 mips32_op = OPC_TLTU;
11408 goto do_trap;
11409 case TNE:
11410 mips32_op = OPC_TNE;
11411 do_trap:
11412 gen_trap(ctx, mips32_op, rs, rt, -1);
11413 break;
11414#ifndef CONFIG_USER_ONLY
11415 case MFC0:
11416 case MFC0 + 32:
2e15497c 11417 check_cp0_enabled(ctx);
3c824109
NF
11418 if (rt == 0) {
11419 /* Treat as NOP. */
11420 break;
11421 }
d75c135e 11422 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11423 break;
11424 case MTC0:
11425 case MTC0 + 32:
2e15497c 11426 check_cp0_enabled(ctx);
3c824109
NF
11427 {
11428 TCGv t0 = tcg_temp_new();
618b0fe9 11429
3c824109 11430 gen_load_gpr(t0, rt);
d75c135e 11431 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11432 tcg_temp_free(t0);
11433 }
11434 break;
11435#endif
a1fc6246
LA
11436 case 0x2a:
11437 switch (minor & 3) {
11438 case MADD_ACC:
11439 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11440 break;
11441 case MADDU_ACC:
11442 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11443 break;
11444 case MSUB_ACC:
11445 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11446 break;
11447 case MSUBU_ACC:
11448 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11449 break;
11450 default:
11451 goto pool32axf_invalid;
11452 }
11453 break;
11454 case 0x32:
11455 switch (minor & 3) {
11456 case MULT_ACC:
11457 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11458 break;
11459 case MULTU_ACC:
11460 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11461 break;
11462 default:
11463 goto pool32axf_invalid;
11464 }
11465 break;
3c824109
NF
11466 case 0x2c:
11467 switch (minor) {
11468 case SEB:
11469 gen_bshfl(ctx, OPC_SEB, rs, rt);
11470 break;
11471 case SEH:
11472 gen_bshfl(ctx, OPC_SEH, rs, rt);
11473 break;
11474 case CLO:
11475 mips32_op = OPC_CLO;
11476 goto do_cl;
11477 case CLZ:
11478 mips32_op = OPC_CLZ;
11479 do_cl:
d75c135e 11480 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11481 gen_cl(ctx, mips32_op, rt, rs);
11482 break;
11483 case RDHWR:
d75c135e 11484 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11485 break;
11486 case WSBH:
11487 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11488 break;
11489 case MULT:
11490 mips32_op = OPC_MULT;
26135ead 11491 goto do_mul;
3c824109
NF
11492 case MULTU:
11493 mips32_op = OPC_MULTU;
26135ead 11494 goto do_mul;
3c824109
NF
11495 case DIV:
11496 mips32_op = OPC_DIV;
26135ead 11497 goto do_div;
3c824109
NF
11498 case DIVU:
11499 mips32_op = OPC_DIVU;
26135ead
RS
11500 goto do_div;
11501 do_div:
11502 check_insn(ctx, ISA_MIPS32);
11503 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11504 break;
3c824109
NF
11505 case MADD:
11506 mips32_op = OPC_MADD;
26135ead 11507 goto do_mul;
3c824109
NF
11508 case MADDU:
11509 mips32_op = OPC_MADDU;
26135ead 11510 goto do_mul;
3c824109
NF
11511 case MSUB:
11512 mips32_op = OPC_MSUB;
26135ead 11513 goto do_mul;
3c824109
NF
11514 case MSUBU:
11515 mips32_op = OPC_MSUBU;
26135ead 11516 do_mul:
d75c135e 11517 check_insn(ctx, ISA_MIPS32);
a1fc6246 11518 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
11519 break;
11520 default:
11521 goto pool32axf_invalid;
11522 }
11523 break;
11524 case 0x34:
11525 switch (minor) {
11526 case MFC2:
11527 case MTC2:
11528 case MFHC2:
11529 case MTHC2:
11530 case CFC2:
11531 case CTC2:
11532 generate_exception_err(ctx, EXCP_CpU, 2);
11533 break;
11534 default:
11535 goto pool32axf_invalid;
11536 }
11537 break;
11538 case 0x3c:
11539 switch (minor) {
11540 case JALR:
11541 case JALR_HB:
11542 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
3c824109
NF
11543 break;
11544 case JALRS:
11545 case JALRS_HB:
11546 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
3c824109
NF
11547 break;
11548 default:
11549 goto pool32axf_invalid;
11550 }
11551 break;
11552 case 0x05:
11553 switch (minor) {
11554 case RDPGPR:
2e15497c 11555 check_cp0_enabled(ctx);
d75c135e 11556 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11557 gen_load_srsgpr(rt, rs);
11558 break;
11559 case WRPGPR:
2e15497c 11560 check_cp0_enabled(ctx);
d75c135e 11561 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11562 gen_store_srsgpr(rt, rs);
11563 break;
11564 default:
11565 goto pool32axf_invalid;
11566 }
11567 break;
11568#ifndef CONFIG_USER_ONLY
11569 case 0x0d:
11570 switch (minor) {
11571 case TLBP:
11572 mips32_op = OPC_TLBP;
11573 goto do_cp0;
11574 case TLBR:
11575 mips32_op = OPC_TLBR;
11576 goto do_cp0;
11577 case TLBWI:
11578 mips32_op = OPC_TLBWI;
11579 goto do_cp0;
11580 case TLBWR:
11581 mips32_op = OPC_TLBWR;
11582 goto do_cp0;
11583 case WAIT:
11584 mips32_op = OPC_WAIT;
11585 goto do_cp0;
11586 case DERET:
11587 mips32_op = OPC_DERET;
11588 goto do_cp0;
11589 case ERET:
11590 mips32_op = OPC_ERET;
11591 do_cp0:
11592 gen_cp0(env, ctx, mips32_op, rt, rs);
11593 break;
11594 default:
11595 goto pool32axf_invalid;
11596 }
11597 break;
11598 case 0x1d:
11599 switch (minor) {
11600 case DI:
2e15497c 11601 check_cp0_enabled(ctx);
3c824109
NF
11602 {
11603 TCGv t0 = tcg_temp_new();
11604
11605 save_cpu_state(ctx, 1);
895c2d04 11606 gen_helper_di(t0, cpu_env);
3c824109
NF
11607 gen_store_gpr(t0, rs);
11608 /* Stop translation as we may have switched the execution mode */
11609 ctx->bstate = BS_STOP;
11610 tcg_temp_free(t0);
11611 }
11612 break;
11613 case EI:
2e15497c 11614 check_cp0_enabled(ctx);
3c824109
NF
11615 {
11616 TCGv t0 = tcg_temp_new();
11617
11618 save_cpu_state(ctx, 1);
895c2d04 11619 gen_helper_ei(t0, cpu_env);
3c824109
NF
11620 gen_store_gpr(t0, rs);
11621 /* Stop translation as we may have switched the execution mode */
11622 ctx->bstate = BS_STOP;
11623 tcg_temp_free(t0);
11624 }
11625 break;
11626 default:
11627 goto pool32axf_invalid;
11628 }
11629 break;
11630#endif
11631 case 0x2d:
11632 switch (minor) {
11633 case SYNC:
11634 /* NOP */
11635 break;
11636 case SYSCALL:
11637 generate_exception(ctx, EXCP_SYSCALL);
11638 ctx->bstate = BS_STOP;
11639 break;
11640 case SDBBP:
d75c135e 11641 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11642 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11643 generate_exception(ctx, EXCP_DBp);
11644 } else {
11645 generate_exception(ctx, EXCP_DBp);
11646 }
11647 break;
11648 default:
11649 goto pool32axf_invalid;
11650 }
11651 break;
a1fc6246 11652 case 0x01:
26135ead 11653 switch (minor & 3) {
a1fc6246 11654 case MFHI_ACC:
26135ead 11655 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 11656 break;
a1fc6246 11657 case MFLO_ACC:
26135ead 11658 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 11659 break;
a1fc6246 11660 case MTHI_ACC:
26135ead 11661 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 11662 break;
a1fc6246 11663 case MTLO_ACC:
26135ead 11664 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
11665 break;
11666 default:
11667 goto pool32axf_invalid;
11668 }
11669 break;
a1fc6246
LA
11670 case 0x35:
11671 switch (minor) {
11672 case MFHI32:
11673 gen_HILO(ctx, OPC_MFHI, 0, rs);
11674 break;
11675 case MFLO32:
11676 gen_HILO(ctx, OPC_MFLO, 0, rs);
11677 break;
11678 case MTHI32:
11679 gen_HILO(ctx, OPC_MTHI, 0, rs);
11680 break;
11681 case MTLO32:
11682 gen_HILO(ctx, OPC_MTLO, 0, rs);
11683 break;
11684 default:
11685 goto pool32axf_invalid;
11686 }
11687 break;
3c824109
NF
11688 default:
11689 pool32axf_invalid:
11690 MIPS_INVAL("pool32axf");
11691 generate_exception(ctx, EXCP_RI);
11692 break;
11693 }
11694}
11695
11696/* Values for microMIPS fmt field. Variable-width, depending on which
11697 formats the instruction supports. */
11698
11699enum {
11700 FMT_SD_S = 0,
11701 FMT_SD_D = 1,
11702
11703 FMT_SDPS_S = 0,
11704 FMT_SDPS_D = 1,
11705 FMT_SDPS_PS = 2,
11706
11707 FMT_SWL_S = 0,
11708 FMT_SWL_W = 1,
11709 FMT_SWL_L = 2,
11710
11711 FMT_DWL_D = 0,
11712 FMT_DWL_W = 1,
11713 FMT_DWL_L = 2
11714};
11715
d75c135e 11716static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11717{
11718 int extension = (ctx->opcode >> 6) & 0x3ff;
11719 uint32_t mips32_op;
11720
11721#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11722#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11723#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11724
11725 switch (extension) {
11726 case FLOAT_1BIT_FMT(CFC1, 0):
11727 mips32_op = OPC_CFC1;
11728 goto do_cp1;
11729 case FLOAT_1BIT_FMT(CTC1, 0):
11730 mips32_op = OPC_CTC1;
11731 goto do_cp1;
11732 case FLOAT_1BIT_FMT(MFC1, 0):
11733 mips32_op = OPC_MFC1;
11734 goto do_cp1;
11735 case FLOAT_1BIT_FMT(MTC1, 0):
11736 mips32_op = OPC_MTC1;
11737 goto do_cp1;
11738 case FLOAT_1BIT_FMT(MFHC1, 0):
11739 mips32_op = OPC_MFHC1;
11740 goto do_cp1;
11741 case FLOAT_1BIT_FMT(MTHC1, 0):
11742 mips32_op = OPC_MTHC1;
11743 do_cp1:
11744 gen_cp1(ctx, mips32_op, rt, rs);
11745 break;
11746
11747 /* Reciprocal square root */
11748 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11749 mips32_op = OPC_RSQRT_S;
11750 goto do_unaryfp;
11751 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11752 mips32_op = OPC_RSQRT_D;
11753 goto do_unaryfp;
11754
11755 /* Square root */
11756 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11757 mips32_op = OPC_SQRT_S;
11758 goto do_unaryfp;
11759 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11760 mips32_op = OPC_SQRT_D;
11761 goto do_unaryfp;
11762
11763 /* Reciprocal */
11764 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11765 mips32_op = OPC_RECIP_S;
11766 goto do_unaryfp;
11767 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11768 mips32_op = OPC_RECIP_D;
11769 goto do_unaryfp;
11770
11771 /* Floor */
11772 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11773 mips32_op = OPC_FLOOR_L_S;
11774 goto do_unaryfp;
11775 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11776 mips32_op = OPC_FLOOR_L_D;
11777 goto do_unaryfp;
11778 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11779 mips32_op = OPC_FLOOR_W_S;
11780 goto do_unaryfp;
11781 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11782 mips32_op = OPC_FLOOR_W_D;
11783 goto do_unaryfp;
11784
11785 /* Ceiling */
11786 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11787 mips32_op = OPC_CEIL_L_S;
11788 goto do_unaryfp;
11789 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11790 mips32_op = OPC_CEIL_L_D;
11791 goto do_unaryfp;
11792 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11793 mips32_op = OPC_CEIL_W_S;
11794 goto do_unaryfp;
11795 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11796 mips32_op = OPC_CEIL_W_D;
11797 goto do_unaryfp;
11798
11799 /* Truncation */
11800 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11801 mips32_op = OPC_TRUNC_L_S;
11802 goto do_unaryfp;
11803 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11804 mips32_op = OPC_TRUNC_L_D;
11805 goto do_unaryfp;
11806 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11807 mips32_op = OPC_TRUNC_W_S;
11808 goto do_unaryfp;
11809 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11810 mips32_op = OPC_TRUNC_W_D;
11811 goto do_unaryfp;
11812
11813 /* Round */
11814 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11815 mips32_op = OPC_ROUND_L_S;
11816 goto do_unaryfp;
11817 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11818 mips32_op = OPC_ROUND_L_D;
11819 goto do_unaryfp;
11820 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11821 mips32_op = OPC_ROUND_W_S;
11822 goto do_unaryfp;
11823 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11824 mips32_op = OPC_ROUND_W_D;
11825 goto do_unaryfp;
11826
11827 /* Integer to floating-point conversion */
11828 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11829 mips32_op = OPC_CVT_L_S;
11830 goto do_unaryfp;
11831 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11832 mips32_op = OPC_CVT_L_D;
11833 goto do_unaryfp;
11834 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11835 mips32_op = OPC_CVT_W_S;
11836 goto do_unaryfp;
11837 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11838 mips32_op = OPC_CVT_W_D;
11839 goto do_unaryfp;
11840
11841 /* Paired-foo conversions */
11842 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11843 mips32_op = OPC_CVT_S_PL;
11844 goto do_unaryfp;
11845 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11846 mips32_op = OPC_CVT_S_PU;
11847 goto do_unaryfp;
11848 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11849 mips32_op = OPC_CVT_PW_PS;
11850 goto do_unaryfp;
11851 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11852 mips32_op = OPC_CVT_PS_PW;
11853 goto do_unaryfp;
11854
11855 /* Floating-point moves */
11856 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11857 mips32_op = OPC_MOV_S;
11858 goto do_unaryfp;
11859 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11860 mips32_op = OPC_MOV_D;
11861 goto do_unaryfp;
11862 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11863 mips32_op = OPC_MOV_PS;
11864 goto do_unaryfp;
11865
11866 /* Absolute value */
11867 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11868 mips32_op = OPC_ABS_S;
11869 goto do_unaryfp;
11870 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11871 mips32_op = OPC_ABS_D;
11872 goto do_unaryfp;
11873 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11874 mips32_op = OPC_ABS_PS;
11875 goto do_unaryfp;
11876
11877 /* Negation */
11878 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11879 mips32_op = OPC_NEG_S;
11880 goto do_unaryfp;
11881 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11882 mips32_op = OPC_NEG_D;
11883 goto do_unaryfp;
11884 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11885 mips32_op = OPC_NEG_PS;
11886 goto do_unaryfp;
11887
11888 /* Reciprocal square root step */
11889 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11890 mips32_op = OPC_RSQRT1_S;
11891 goto do_unaryfp;
11892 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11893 mips32_op = OPC_RSQRT1_D;
11894 goto do_unaryfp;
11895 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11896 mips32_op = OPC_RSQRT1_PS;
11897 goto do_unaryfp;
11898
11899 /* Reciprocal step */
11900 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11901 mips32_op = OPC_RECIP1_S;
11902 goto do_unaryfp;
11903 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11904 mips32_op = OPC_RECIP1_S;
11905 goto do_unaryfp;
11906 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11907 mips32_op = OPC_RECIP1_PS;
11908 goto do_unaryfp;
11909
11910 /* Conversions from double */
11911 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11912 mips32_op = OPC_CVT_D_S;
11913 goto do_unaryfp;
11914 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11915 mips32_op = OPC_CVT_D_W;
11916 goto do_unaryfp;
11917 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11918 mips32_op = OPC_CVT_D_L;
11919 goto do_unaryfp;
11920
11921 /* Conversions from single */
11922 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11923 mips32_op = OPC_CVT_S_D;
11924 goto do_unaryfp;
11925 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11926 mips32_op = OPC_CVT_S_W;
11927 goto do_unaryfp;
11928 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11929 mips32_op = OPC_CVT_S_L;
11930 do_unaryfp:
11931 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11932 break;
11933
11934 /* Conditional moves on floating-point codes */
11935 case COND_FLOAT_MOV(MOVT, 0):
11936 case COND_FLOAT_MOV(MOVT, 1):
11937 case COND_FLOAT_MOV(MOVT, 2):
11938 case COND_FLOAT_MOV(MOVT, 3):
11939 case COND_FLOAT_MOV(MOVT, 4):
11940 case COND_FLOAT_MOV(MOVT, 5):
11941 case COND_FLOAT_MOV(MOVT, 6):
11942 case COND_FLOAT_MOV(MOVT, 7):
11943 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11944 break;
11945 case COND_FLOAT_MOV(MOVF, 0):
11946 case COND_FLOAT_MOV(MOVF, 1):
11947 case COND_FLOAT_MOV(MOVF, 2):
11948 case COND_FLOAT_MOV(MOVF, 3):
11949 case COND_FLOAT_MOV(MOVF, 4):
11950 case COND_FLOAT_MOV(MOVF, 5):
11951 case COND_FLOAT_MOV(MOVF, 6):
11952 case COND_FLOAT_MOV(MOVF, 7):
11953 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11954 break;
11955 default:
11956 MIPS_INVAL("pool32fxf");
11957 generate_exception(ctx, EXCP_RI);
11958 break;
11959 }
11960}
11961
7db13fae 11962static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 11963 uint16_t insn_hw1)
3c824109
NF
11964{
11965 int32_t offset;
11966 uint16_t insn;
11967 int rt, rs, rd, rr;
11968 int16_t imm;
11969 uint32_t op, minor, mips32_op;
11970 uint32_t cond, fmt, cc;
11971
895c2d04 11972 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11973 ctx->opcode = (ctx->opcode << 16) | insn;
11974
11975 rt = (ctx->opcode >> 21) & 0x1f;
11976 rs = (ctx->opcode >> 16) & 0x1f;
11977 rd = (ctx->opcode >> 11) & 0x1f;
11978 rr = (ctx->opcode >> 6) & 0x1f;
11979 imm = (int16_t) ctx->opcode;
11980
11981 op = (ctx->opcode >> 26) & 0x3f;
11982 switch (op) {
11983 case POOL32A:
11984 minor = ctx->opcode & 0x3f;
11985 switch (minor) {
11986 case 0x00:
11987 minor = (ctx->opcode >> 6) & 0xf;
11988 switch (minor) {
11989 case SLL32:
11990 mips32_op = OPC_SLL;
11991 goto do_shifti;
11992 case SRA:
11993 mips32_op = OPC_SRA;
11994 goto do_shifti;
11995 case SRL32:
11996 mips32_op = OPC_SRL;
11997 goto do_shifti;
11998 case ROTR:
11999 mips32_op = OPC_ROTR;
12000 do_shifti:
d75c135e 12001 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
12002 break;
12003 default:
12004 goto pool32a_invalid;
12005 }
12006 break;
12007 case 0x10:
12008 minor = (ctx->opcode >> 6) & 0xf;
12009 switch (minor) {
12010 /* Arithmetic */
12011 case ADD:
12012 mips32_op = OPC_ADD;
12013 goto do_arith;
12014 case ADDU32:
12015 mips32_op = OPC_ADDU;
12016 goto do_arith;
12017 case SUB:
12018 mips32_op = OPC_SUB;
12019 goto do_arith;
12020 case SUBU32:
12021 mips32_op = OPC_SUBU;
12022 goto do_arith;
12023 case MUL:
12024 mips32_op = OPC_MUL;
12025 do_arith:
d75c135e 12026 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12027 break;
12028 /* Shifts */
12029 case SLLV:
12030 mips32_op = OPC_SLLV;
12031 goto do_shift;
12032 case SRLV:
12033 mips32_op = OPC_SRLV;
12034 goto do_shift;
12035 case SRAV:
12036 mips32_op = OPC_SRAV;
12037 goto do_shift;
12038 case ROTRV:
12039 mips32_op = OPC_ROTRV;
12040 do_shift:
d75c135e 12041 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12042 break;
12043 /* Logical operations */
12044 case AND:
12045 mips32_op = OPC_AND;
12046 goto do_logic;
12047 case OR32:
12048 mips32_op = OPC_OR;
12049 goto do_logic;
12050 case NOR:
12051 mips32_op = OPC_NOR;
12052 goto do_logic;
12053 case XOR32:
12054 mips32_op = OPC_XOR;
12055 do_logic:
d75c135e 12056 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12057 break;
12058 /* Set less than */
12059 case SLT:
12060 mips32_op = OPC_SLT;
12061 goto do_slt;
12062 case SLTU:
12063 mips32_op = OPC_SLTU;
12064 do_slt:
d75c135e 12065 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12066 break;
12067 default:
12068 goto pool32a_invalid;
12069 }
12070 break;
12071 case 0x18:
12072 minor = (ctx->opcode >> 6) & 0xf;
12073 switch (minor) {
12074 /* Conditional moves */
12075 case MOVN:
12076 mips32_op = OPC_MOVN;
12077 goto do_cmov;
12078 case MOVZ:
12079 mips32_op = OPC_MOVZ;
12080 do_cmov:
d75c135e 12081 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12082 break;
12083 case LWXS:
12084 gen_ldxs(ctx, rs, rt, rd);
12085 break;
12086 default:
12087 goto pool32a_invalid;
12088 }
12089 break;
12090 case INS:
12091 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
12092 return;
12093 case EXT:
12094 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
12095 return;
12096 case POOL32AXF:
240ce26a 12097 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
12098 break;
12099 case 0x07:
12100 generate_exception(ctx, EXCP_BREAK);
12101 break;
12102 default:
12103 pool32a_invalid:
12104 MIPS_INVAL("pool32a");
12105 generate_exception(ctx, EXCP_RI);
12106 break;
12107 }
12108 break;
12109 case POOL32B:
12110 minor = (ctx->opcode >> 12) & 0xf;
12111 switch (minor) {
12112 case CACHE:
2e15497c 12113 check_cp0_enabled(ctx);
3c824109
NF
12114 /* Treat as no-op. */
12115 break;
12116 case LWC2:
12117 case SWC2:
12118 /* COP2: Not implemented. */
12119 generate_exception_err(ctx, EXCP_CpU, 2);
12120 break;
12121 case LWP:
12122 case SWP:
12123#ifdef TARGET_MIPS64
12124 case LDP:
12125 case SDP:
12126#endif
12127 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
12128 break;
12129 case LWM32:
12130 case SWM32:
12131#ifdef TARGET_MIPS64
12132 case LDM:
12133 case SDM:
12134#endif
12135 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
12136 break;
12137 default:
12138 MIPS_INVAL("pool32b");
12139 generate_exception(ctx, EXCP_RI);
12140 break;
12141 }
12142 break;
12143 case POOL32F:
5ab5c041 12144 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
12145 minor = ctx->opcode & 0x3f;
12146 check_cp1_enabled(ctx);
12147 switch (minor) {
12148 case ALNV_PS:
12149 mips32_op = OPC_ALNV_PS;
12150 goto do_madd;
12151 case MADD_S:
12152 mips32_op = OPC_MADD_S;
12153 goto do_madd;
12154 case MADD_D:
12155 mips32_op = OPC_MADD_D;
12156 goto do_madd;
12157 case MADD_PS:
12158 mips32_op = OPC_MADD_PS;
12159 goto do_madd;
12160 case MSUB_S:
12161 mips32_op = OPC_MSUB_S;
12162 goto do_madd;
12163 case MSUB_D:
12164 mips32_op = OPC_MSUB_D;
12165 goto do_madd;
12166 case MSUB_PS:
12167 mips32_op = OPC_MSUB_PS;
12168 goto do_madd;
12169 case NMADD_S:
12170 mips32_op = OPC_NMADD_S;
12171 goto do_madd;
12172 case NMADD_D:
12173 mips32_op = OPC_NMADD_D;
12174 goto do_madd;
12175 case NMADD_PS:
12176 mips32_op = OPC_NMADD_PS;
12177 goto do_madd;
12178 case NMSUB_S:
12179 mips32_op = OPC_NMSUB_S;
12180 goto do_madd;
12181 case NMSUB_D:
12182 mips32_op = OPC_NMSUB_D;
12183 goto do_madd;
12184 case NMSUB_PS:
12185 mips32_op = OPC_NMSUB_PS;
12186 do_madd:
12187 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
12188 break;
12189 case CABS_COND_FMT:
12190 cond = (ctx->opcode >> 6) & 0xf;
12191 cc = (ctx->opcode >> 13) & 0x7;
12192 fmt = (ctx->opcode >> 10) & 0x3;
12193 switch (fmt) {
12194 case 0x0:
12195 gen_cmpabs_s(ctx, cond, rt, rs, cc);
12196 break;
12197 case 0x1:
12198 gen_cmpabs_d(ctx, cond, rt, rs, cc);
12199 break;
12200 case 0x2:
12201 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
12202 break;
12203 default:
12204 goto pool32f_invalid;
12205 }
12206 break;
12207 case C_COND_FMT:
12208 cond = (ctx->opcode >> 6) & 0xf;
12209 cc = (ctx->opcode >> 13) & 0x7;
12210 fmt = (ctx->opcode >> 10) & 0x3;
12211 switch (fmt) {
12212 case 0x0:
12213 gen_cmp_s(ctx, cond, rt, rs, cc);
12214 break;
12215 case 0x1:
12216 gen_cmp_d(ctx, cond, rt, rs, cc);
12217 break;
12218 case 0x2:
12219 gen_cmp_ps(ctx, cond, rt, rs, cc);
12220 break;
12221 default:
12222 goto pool32f_invalid;
12223 }
12224 break;
12225 case POOL32FXF:
d75c135e 12226 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
12227 break;
12228 case 0x00:
12229 /* PLL foo */
12230 switch ((ctx->opcode >> 6) & 0x7) {
12231 case PLL_PS:
12232 mips32_op = OPC_PLL_PS;
12233 goto do_ps;
12234 case PLU_PS:
12235 mips32_op = OPC_PLU_PS;
12236 goto do_ps;
12237 case PUL_PS:
12238 mips32_op = OPC_PUL_PS;
12239 goto do_ps;
12240 case PUU_PS:
12241 mips32_op = OPC_PUU_PS;
12242 goto do_ps;
12243 case CVT_PS_S:
12244 mips32_op = OPC_CVT_PS_S;
12245 do_ps:
12246 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12247 break;
12248 default:
12249 goto pool32f_invalid;
12250 }
12251 break;
12252 case 0x08:
12253 /* [LS][WDU]XC1 */
12254 switch ((ctx->opcode >> 6) & 0x7) {
12255 case LWXC1:
12256 mips32_op = OPC_LWXC1;
12257 goto do_ldst_cp1;
12258 case SWXC1:
12259 mips32_op = OPC_SWXC1;
12260 goto do_ldst_cp1;
12261 case LDXC1:
12262 mips32_op = OPC_LDXC1;
12263 goto do_ldst_cp1;
12264 case SDXC1:
12265 mips32_op = OPC_SDXC1;
12266 goto do_ldst_cp1;
12267 case LUXC1:
12268 mips32_op = OPC_LUXC1;
12269 goto do_ldst_cp1;
12270 case SUXC1:
12271 mips32_op = OPC_SUXC1;
12272 do_ldst_cp1:
12273 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
12274 break;
12275 default:
12276 goto pool32f_invalid;
12277 }
12278 break;
12279 case 0x18:
12280 /* 3D insns */
12281 fmt = (ctx->opcode >> 9) & 0x3;
12282 switch ((ctx->opcode >> 6) & 0x7) {
12283 case RSQRT2_FMT:
12284 switch (fmt) {
12285 case FMT_SDPS_S:
12286 mips32_op = OPC_RSQRT2_S;
12287 goto do_3d;
12288 case FMT_SDPS_D:
12289 mips32_op = OPC_RSQRT2_D;
12290 goto do_3d;
12291 case FMT_SDPS_PS:
12292 mips32_op = OPC_RSQRT2_PS;
12293 goto do_3d;
12294 default:
12295 goto pool32f_invalid;
12296 }
12297 break;
12298 case RECIP2_FMT:
12299 switch (fmt) {
12300 case FMT_SDPS_S:
12301 mips32_op = OPC_RECIP2_S;
12302 goto do_3d;
12303 case FMT_SDPS_D:
12304 mips32_op = OPC_RECIP2_D;
12305 goto do_3d;
12306 case FMT_SDPS_PS:
12307 mips32_op = OPC_RECIP2_PS;
12308 goto do_3d;
12309 default:
12310 goto pool32f_invalid;
12311 }
12312 break;
12313 case ADDR_PS:
12314 mips32_op = OPC_ADDR_PS;
12315 goto do_3d;
12316 case MULR_PS:
12317 mips32_op = OPC_MULR_PS;
12318 do_3d:
12319 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12320 break;
12321 default:
12322 goto pool32f_invalid;
12323 }
12324 break;
12325 case 0x20:
12326 /* MOV[FT].fmt and PREFX */
12327 cc = (ctx->opcode >> 13) & 0x7;
12328 fmt = (ctx->opcode >> 9) & 0x3;
12329 switch ((ctx->opcode >> 6) & 0x7) {
12330 case MOVF_FMT:
12331 switch (fmt) {
12332 case FMT_SDPS_S:
12333 gen_movcf_s(rs, rt, cc, 0);
12334 break;
12335 case FMT_SDPS_D:
12336 gen_movcf_d(ctx, rs, rt, cc, 0);
12337 break;
12338 case FMT_SDPS_PS:
7f6613ce 12339 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
12340 break;
12341 default:
12342 goto pool32f_invalid;
12343 }
12344 break;
12345 case MOVT_FMT:
12346 switch (fmt) {
12347 case FMT_SDPS_S:
12348 gen_movcf_s(rs, rt, cc, 1);
12349 break;
12350 case FMT_SDPS_D:
12351 gen_movcf_d(ctx, rs, rt, cc, 1);
12352 break;
12353 case FMT_SDPS_PS:
7f6613ce 12354 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
12355 break;
12356 default:
12357 goto pool32f_invalid;
12358 }
12359 break;
12360 case PREFX:
12361 break;
12362 default:
12363 goto pool32f_invalid;
12364 }
12365 break;
12366#define FINSN_3ARG_SDPS(prfx) \
12367 switch ((ctx->opcode >> 8) & 0x3) { \
12368 case FMT_SDPS_S: \
12369 mips32_op = OPC_##prfx##_S; \
12370 goto do_fpop; \
12371 case FMT_SDPS_D: \
12372 mips32_op = OPC_##prfx##_D; \
12373 goto do_fpop; \
12374 case FMT_SDPS_PS: \
12375 mips32_op = OPC_##prfx##_PS; \
12376 goto do_fpop; \
12377 default: \
12378 goto pool32f_invalid; \
12379 }
12380 case 0x30:
12381 /* regular FP ops */
12382 switch ((ctx->opcode >> 6) & 0x3) {
12383 case ADD_FMT:
12384 FINSN_3ARG_SDPS(ADD);
12385 break;
12386 case SUB_FMT:
12387 FINSN_3ARG_SDPS(SUB);
12388 break;
12389 case MUL_FMT:
12390 FINSN_3ARG_SDPS(MUL);
12391 break;
12392 case DIV_FMT:
12393 fmt = (ctx->opcode >> 8) & 0x3;
12394 if (fmt == 1) {
12395 mips32_op = OPC_DIV_D;
12396 } else if (fmt == 0) {
12397 mips32_op = OPC_DIV_S;
12398 } else {
12399 goto pool32f_invalid;
12400 }
12401 goto do_fpop;
12402 default:
12403 goto pool32f_invalid;
12404 }
12405 break;
12406 case 0x38:
12407 /* cmovs */
12408 switch ((ctx->opcode >> 6) & 0x3) {
12409 case MOVN_FMT:
12410 FINSN_3ARG_SDPS(MOVN);
12411 break;
12412 case MOVZ_FMT:
12413 FINSN_3ARG_SDPS(MOVZ);
12414 break;
12415 default:
12416 goto pool32f_invalid;
12417 }
12418 break;
12419 do_fpop:
12420 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12421 break;
12422 default:
12423 pool32f_invalid:
12424 MIPS_INVAL("pool32f");
12425 generate_exception(ctx, EXCP_RI);
12426 break;
12427 }
12428 } else {
12429 generate_exception_err(ctx, EXCP_CpU, 1);
12430 }
12431 break;
12432 case POOL32I:
12433 minor = (ctx->opcode >> 21) & 0x1f;
12434 switch (minor) {
12435 case BLTZ:
12436 mips32_op = OPC_BLTZ;
12437 goto do_branch;
12438 case BLTZAL:
12439 mips32_op = OPC_BLTZAL;
12440 goto do_branch;
12441 case BLTZALS:
12442 mips32_op = OPC_BLTZALS;
12443 goto do_branch;
12444 case BGEZ:
12445 mips32_op = OPC_BGEZ;
12446 goto do_branch;
12447 case BGEZAL:
12448 mips32_op = OPC_BGEZAL;
12449 goto do_branch;
12450 case BGEZALS:
12451 mips32_op = OPC_BGEZALS;
12452 goto do_branch;
12453 case BLEZ:
12454 mips32_op = OPC_BLEZ;
12455 goto do_branch;
12456 case BGTZ:
12457 mips32_op = OPC_BGTZ;
12458 do_branch:
12459 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
3c824109
NF
12460 break;
12461
12462 /* Traps */
12463 case TLTI:
12464 mips32_op = OPC_TLTI;
12465 goto do_trapi;
12466 case TGEI:
12467 mips32_op = OPC_TGEI;
12468 goto do_trapi;
12469 case TLTIU:
12470 mips32_op = OPC_TLTIU;
12471 goto do_trapi;
12472 case TGEIU:
12473 mips32_op = OPC_TGEIU;
12474 goto do_trapi;
12475 case TNEI:
12476 mips32_op = OPC_TNEI;
12477 goto do_trapi;
12478 case TEQI:
12479 mips32_op = OPC_TEQI;
12480 do_trapi:
12481 gen_trap(ctx, mips32_op, rs, -1, imm);
12482 break;
12483
12484 case BNEZC:
12485 case BEQZC:
12486 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12487 4, rs, 0, imm << 1);
12488 /* Compact branches don't have a delay slot, so just let
12489 the normal delay slot handling take us to the branch
12490 target. */
12491 break;
12492 case LUI:
d75c135e 12493 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12494 break;
12495 case SYNCI:
12496 break;
12497 case BC2F:
12498 case BC2T:
12499 /* COP2: Not implemented. */
12500 generate_exception_err(ctx, EXCP_CpU, 2);
12501 break;
12502 case BC1F:
12503 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12504 goto do_cp1branch;
12505 case BC1T:
12506 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12507 goto do_cp1branch;
12508 case BC1ANY4F:
12509 mips32_op = OPC_BC1FANY4;
12510 goto do_cp1mips3d;
12511 case BC1ANY4T:
12512 mips32_op = OPC_BC1TANY4;
12513 do_cp1mips3d:
12514 check_cop1x(ctx);
d75c135e 12515 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12516 /* Fall through */
12517 do_cp1branch:
d75c135e 12518 gen_compute_branch1(ctx, mips32_op,
3c824109 12519 (ctx->opcode >> 18) & 0x7, imm << 1);
3c824109
NF
12520 break;
12521 case BPOSGE64:
12522 case BPOSGE32:
12523 /* MIPS DSP: not implemented */
12524 /* Fall through */
12525 default:
12526 MIPS_INVAL("pool32i");
12527 generate_exception(ctx, EXCP_RI);
12528 break;
12529 }
12530 break;
12531 case POOL32C:
12532 minor = (ctx->opcode >> 12) & 0xf;
12533 switch (minor) {
12534 case LWL:
12535 mips32_op = OPC_LWL;
5c13fdfd 12536 goto do_ld_lr;
3c824109
NF
12537 case SWL:
12538 mips32_op = OPC_SWL;
5c13fdfd 12539 goto do_st_lr;
3c824109
NF
12540 case LWR:
12541 mips32_op = OPC_LWR;
5c13fdfd 12542 goto do_ld_lr;
3c824109
NF
12543 case SWR:
12544 mips32_op = OPC_SWR;
5c13fdfd 12545 goto do_st_lr;
3c824109
NF
12546#if defined(TARGET_MIPS64)
12547 case LDL:
12548 mips32_op = OPC_LDL;
5c13fdfd 12549 goto do_ld_lr;
3c824109
NF
12550 case SDL:
12551 mips32_op = OPC_SDL;
5c13fdfd 12552 goto do_st_lr;
3c824109
NF
12553 case LDR:
12554 mips32_op = OPC_LDR;
5c13fdfd 12555 goto do_ld_lr;
3c824109
NF
12556 case SDR:
12557 mips32_op = OPC_SDR;
5c13fdfd 12558 goto do_st_lr;
3c824109
NF
12559 case LWU:
12560 mips32_op = OPC_LWU;
5c13fdfd 12561 goto do_ld_lr;
3c824109
NF
12562 case LLD:
12563 mips32_op = OPC_LLD;
5c13fdfd 12564 goto do_ld_lr;
3c824109
NF
12565#endif
12566 case LL:
12567 mips32_op = OPC_LL;
5c13fdfd
AJ
12568 goto do_ld_lr;
12569 do_ld_lr:
d75c135e 12570 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12571 break;
12572 do_st_lr:
12573 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12574 break;
12575 case SC:
12576 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12577 break;
12578#if defined(TARGET_MIPS64)
12579 case SCD:
12580 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12581 break;
12582#endif
12583 case PREF:
12584 /* Treat as no-op */
12585 break;
12586 default:
12587 MIPS_INVAL("pool32c");
12588 generate_exception(ctx, EXCP_RI);
12589 break;
12590 }
12591 break;
12592 case ADDI32:
12593 mips32_op = OPC_ADDI;
12594 goto do_addi;
12595 case ADDIU32:
12596 mips32_op = OPC_ADDIU;
12597 do_addi:
d75c135e 12598 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12599 break;
12600
12601 /* Logical operations */
12602 case ORI32:
12603 mips32_op = OPC_ORI;
12604 goto do_logici;
12605 case XORI32:
12606 mips32_op = OPC_XORI;
12607 goto do_logici;
12608 case ANDI32:
12609 mips32_op = OPC_ANDI;
12610 do_logici:
d75c135e 12611 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12612 break;
12613
12614 /* Set less than immediate */
12615 case SLTI32:
12616 mips32_op = OPC_SLTI;
12617 goto do_slti;
12618 case SLTIU32:
12619 mips32_op = OPC_SLTIU;
12620 do_slti:
d75c135e 12621 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12622 break;
12623 case JALX32:
12624 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12625 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
3c824109
NF
12626 break;
12627 case JALS32:
12628 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12629 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
3c824109
NF
12630 break;
12631 case BEQ32:
12632 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
3c824109
NF
12633 break;
12634 case BNE32:
12635 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
3c824109
NF
12636 break;
12637 case J32:
12638 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12639 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12640 break;
12641 case JAL32:
12642 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12643 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12644 break;
12645 /* Floating point (COP1) */
12646 case LWC132:
12647 mips32_op = OPC_LWC1;
12648 goto do_cop1;
12649 case LDC132:
12650 mips32_op = OPC_LDC1;
12651 goto do_cop1;
12652 case SWC132:
12653 mips32_op = OPC_SWC1;
12654 goto do_cop1;
12655 case SDC132:
12656 mips32_op = OPC_SDC1;
12657 do_cop1:
5ab5c041 12658 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12659 break;
12660 case ADDIUPC:
12661 {
12662 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12663 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12664
12665 gen_addiupc(ctx, reg, offset, 0, 0);
12666 }
12667 break;
12668 /* Loads and stores */
12669 case LB32:
12670 mips32_op = OPC_LB;
5c13fdfd 12671 goto do_ld;
3c824109
NF
12672 case LBU32:
12673 mips32_op = OPC_LBU;
5c13fdfd 12674 goto do_ld;
3c824109
NF
12675 case LH32:
12676 mips32_op = OPC_LH;
5c13fdfd 12677 goto do_ld;
3c824109
NF
12678 case LHU32:
12679 mips32_op = OPC_LHU;
5c13fdfd 12680 goto do_ld;
3c824109
NF
12681 case LW32:
12682 mips32_op = OPC_LW;
5c13fdfd 12683 goto do_ld;
3c824109
NF
12684#ifdef TARGET_MIPS64
12685 case LD32:
12686 mips32_op = OPC_LD;
5c13fdfd 12687 goto do_ld;
3c824109
NF
12688 case SD32:
12689 mips32_op = OPC_SD;
5c13fdfd 12690 goto do_st;
3c824109
NF
12691#endif
12692 case SB32:
12693 mips32_op = OPC_SB;
5c13fdfd 12694 goto do_st;
3c824109
NF
12695 case SH32:
12696 mips32_op = OPC_SH;
5c13fdfd 12697 goto do_st;
3c824109
NF
12698 case SW32:
12699 mips32_op = OPC_SW;
5c13fdfd
AJ
12700 goto do_st;
12701 do_ld:
d75c135e 12702 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12703 break;
12704 do_st:
12705 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12706 break;
12707 default:
12708 generate_exception(ctx, EXCP_RI);
12709 break;
12710 }
12711}
12712
240ce26a 12713static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
12714{
12715 uint32_t op;
12716
12717 /* make sure instructions are on a halfword boundary */
12718 if (ctx->pc & 0x1) {
12719 env->CP0_BadVAddr = ctx->pc;
12720 generate_exception(ctx, EXCP_AdEL);
12721 ctx->bstate = BS_STOP;
12722 return 2;
12723 }
12724
12725 op = (ctx->opcode >> 10) & 0x3f;
12726 /* Enforce properly-sized instructions in a delay slot */
12727 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12728 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12729
12730 switch (op) {
12731 case POOL32A:
12732 case POOL32B:
12733 case POOL32I:
12734 case POOL32C:
12735 case ADDI32:
12736 case ADDIU32:
12737 case ORI32:
12738 case XORI32:
12739 case SLTI32:
12740 case SLTIU32:
12741 case ANDI32:
12742 case JALX32:
12743 case LBU32:
12744 case LHU32:
12745 case POOL32F:
12746 case JALS32:
12747 case BEQ32:
12748 case BNE32:
12749 case J32:
12750 case JAL32:
12751 case SB32:
12752 case SH32:
12753 case POOL32S:
12754 case ADDIUPC:
12755 case SWC132:
12756 case SDC132:
12757 case SD32:
12758 case SW32:
12759 case LB32:
12760 case LH32:
12761 case DADDIU32:
3c824109
NF
12762 case LWC132:
12763 case LDC132:
12764 case LD32:
12765 case LW32:
12766 if (bits & MIPS_HFLAG_BDS16) {
12767 generate_exception(ctx, EXCP_RI);
12768 /* Just stop translation; the user is confused. */
12769 ctx->bstate = BS_STOP;
12770 return 2;
12771 }
12772 break;
12773 case POOL16A:
12774 case POOL16B:
12775 case POOL16C:
12776 case LWGP16:
12777 case POOL16F:
12778 case LBU16:
12779 case LHU16:
12780 case LWSP16:
12781 case LW16:
12782 case SB16:
12783 case SH16:
12784 case SWSP16:
12785 case SW16:
12786 case MOVE16:
12787 case ANDI16:
12788 case POOL16D:
12789 case POOL16E:
12790 case BEQZ16:
12791 case BNEZ16:
12792 case B16:
12793 case LI16:
12794 if (bits & MIPS_HFLAG_BDS32) {
12795 generate_exception(ctx, EXCP_RI);
12796 /* Just stop translation; the user is confused. */
12797 ctx->bstate = BS_STOP;
12798 return 2;
12799 }
12800 break;
12801 default:
12802 break;
12803 }
12804 }
12805 switch (op) {
12806 case POOL16A:
12807 {
12808 int rd = mmreg(uMIPS_RD(ctx->opcode));
12809 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12810 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12811 uint32_t opc = 0;
12812
12813 switch (ctx->opcode & 0x1) {
12814 case ADDU16:
12815 opc = OPC_ADDU;
12816 break;
12817 case SUBU16:
12818 opc = OPC_SUBU;
12819 break;
12820 }
12821
d75c135e 12822 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12823 }
12824 break;
12825 case POOL16B:
12826 {
12827 int rd = mmreg(uMIPS_RD(ctx->opcode));
12828 int rs = mmreg(uMIPS_RS(ctx->opcode));
12829 int amount = (ctx->opcode >> 1) & 0x7;
12830 uint32_t opc = 0;
12831 amount = amount == 0 ? 8 : amount;
12832
12833 switch (ctx->opcode & 0x1) {
12834 case SLL16:
12835 opc = OPC_SLL;
12836 break;
12837 case SRL16:
12838 opc = OPC_SRL;
12839 break;
12840 }
12841
d75c135e 12842 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12843 }
12844 break;
12845 case POOL16C:
240ce26a 12846 gen_pool16c_insn(ctx);
3c824109
NF
12847 break;
12848 case LWGP16:
12849 {
12850 int rd = mmreg(uMIPS_RD(ctx->opcode));
12851 int rb = 28; /* GP */
12852 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12853
d75c135e 12854 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12855 }
12856 break;
12857 case POOL16F:
12858 if (ctx->opcode & 1) {
12859 generate_exception(ctx, EXCP_RI);
12860 } else {
12861 /* MOVEP */
12862 int enc_dest = uMIPS_RD(ctx->opcode);
12863 int enc_rt = uMIPS_RS2(ctx->opcode);
12864 int enc_rs = uMIPS_RS1(ctx->opcode);
12865 int rd, rs, re, rt;
12866 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12867 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12868 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12869
12870 rd = rd_enc[enc_dest];
12871 re = re_enc[enc_dest];
12872 rs = rs_rt_enc[enc_rs];
12873 rt = rs_rt_enc[enc_rt];
12874
d75c135e
AJ
12875 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12876 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12877 }
12878 break;
12879 case LBU16:
12880 {
12881 int rd = mmreg(uMIPS_RD(ctx->opcode));
12882 int rb = mmreg(uMIPS_RS(ctx->opcode));
12883 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12884 offset = (offset == 0xf ? -1 : offset);
12885
d75c135e 12886 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12887 }
12888 break;
12889 case LHU16:
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) << 1;
12894
d75c135e 12895 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12896 }
12897 break;
12898 case LWSP16:
12899 {
12900 int rd = (ctx->opcode >> 5) & 0x1f;
12901 int rb = 29; /* SP */
12902 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12903
d75c135e 12904 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12905 }
12906 break;
12907 case LW16:
12908 {
12909 int rd = mmreg(uMIPS_RD(ctx->opcode));
12910 int rb = mmreg(uMIPS_RS(ctx->opcode));
12911 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12912
d75c135e 12913 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12914 }
12915 break;
12916 case SB16:
12917 {
12918 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12919 int rb = mmreg(uMIPS_RS(ctx->opcode));
12920 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12921
5c13fdfd 12922 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12923 }
12924 break;
12925 case SH16:
12926 {
12927 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12928 int rb = mmreg(uMIPS_RS(ctx->opcode));
12929 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12930
5c13fdfd 12931 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12932 }
12933 break;
12934 case SWSP16:
12935 {
12936 int rd = (ctx->opcode >> 5) & 0x1f;
12937 int rb = 29; /* SP */
12938 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12939
5c13fdfd 12940 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12941 }
12942 break;
12943 case SW16:
12944 {
12945 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12946 int rb = mmreg(uMIPS_RS(ctx->opcode));
12947 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12948
5c13fdfd 12949 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12950 }
12951 break;
12952 case MOVE16:
12953 {
12954 int rd = uMIPS_RD5(ctx->opcode);
12955 int rs = uMIPS_RS5(ctx->opcode);
12956
d75c135e 12957 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12958 }
12959 break;
12960 case ANDI16:
d75c135e 12961 gen_andi16(ctx);
3c824109
NF
12962 break;
12963 case POOL16D:
12964 switch (ctx->opcode & 0x1) {
12965 case ADDIUS5:
d75c135e 12966 gen_addius5(ctx);
3c824109
NF
12967 break;
12968 case ADDIUSP:
d75c135e 12969 gen_addiusp(ctx);
3c824109
NF
12970 break;
12971 }
12972 break;
12973 case POOL16E:
12974 switch (ctx->opcode & 0x1) {
12975 case ADDIUR2:
d75c135e 12976 gen_addiur2(ctx);
3c824109
NF
12977 break;
12978 case ADDIUR1SP:
d75c135e 12979 gen_addiur1sp(ctx);
3c824109
NF
12980 break;
12981 }
12982 break;
12983 case B16:
12984 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12985 SIMM(ctx->opcode, 0, 10) << 1);
3c824109
NF
12986 break;
12987 case BNEZ16:
12988 case BEQZ16:
12989 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12990 mmreg(uMIPS_RD(ctx->opcode)),
12991 0, SIMM(ctx->opcode, 0, 7) << 1);
3c824109
NF
12992 break;
12993 case LI16:
12994 {
12995 int reg = mmreg(uMIPS_RD(ctx->opcode));
12996 int imm = ZIMM(ctx->opcode, 0, 7);
12997
12998 imm = (imm == 0x7f ? -1 : imm);
12999 tcg_gen_movi_tl(cpu_gpr[reg], imm);
13000 }
13001 break;
13002 case RES_20:
13003 case RES_28:
13004 case RES_29:
13005 case RES_30:
13006 case RES_31:
13007 case RES_38:
13008 case RES_39:
13009 generate_exception(ctx, EXCP_RI);
13010 break;
13011 default:
240ce26a 13012 decode_micromips32_opc (env, ctx, op);
3c824109
NF
13013 return 4;
13014 }
13015
13016 return 2;
13017}
13018
13019/* SmartMIPS extension to MIPS32 */
13020
13021#if defined(TARGET_MIPS64)
13022
13023/* MDMX extension to MIPS64 */
13024
13025#endif
13026
9b1a1d68 13027/* MIPSDSP functions. */
d75c135e 13028static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
13029 int rd, int base, int offset)
13030{
13031 const char *opn = "ldx";
13032 TCGv t0;
13033
9b1a1d68
JL
13034 check_dsp(ctx);
13035 t0 = tcg_temp_new();
13036
13037 if (base == 0) {
13038 gen_load_gpr(t0, offset);
13039 } else if (offset == 0) {
13040 gen_load_gpr(t0, base);
13041 } else {
13042 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
13043 }
13044
9b1a1d68
JL
13045 switch (opc) {
13046 case OPC_LBUX:
5f68f5ae 13047 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
13048 gen_store_gpr(t0, rd);
13049 opn = "lbux";
13050 break;
13051 case OPC_LHX:
5f68f5ae 13052 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
13053 gen_store_gpr(t0, rd);
13054 opn = "lhx";
13055 break;
13056 case OPC_LWX:
5f68f5ae 13057 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
13058 gen_store_gpr(t0, rd);
13059 opn = "lwx";
13060 break;
13061#if defined(TARGET_MIPS64)
13062 case OPC_LDX:
5f68f5ae 13063 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
13064 gen_store_gpr(t0, rd);
13065 opn = "ldx";
13066 break;
13067#endif
13068 }
13069 (void)opn; /* avoid a compiler warning */
13070 MIPS_DEBUG("%s %s, %s(%s)", opn,
13071 regnames[rd], regnames[offset], regnames[base]);
13072 tcg_temp_free(t0);
13073}
13074
461c08df
JL
13075static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
13076 int ret, int v1, int v2)
13077{
13078 const char *opn = "mipsdsp arith";
13079 TCGv v1_t;
13080 TCGv v2_t;
13081
13082 if (ret == 0) {
13083 /* Treat as NOP. */
13084 MIPS_DEBUG("NOP");
13085 return;
13086 }
13087
13088 v1_t = tcg_temp_new();
13089 v2_t = tcg_temp_new();
13090
13091 gen_load_gpr(v1_t, v1);
13092 gen_load_gpr(v2_t, v2);
13093
13094 switch (op1) {
13095 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
13096 case OPC_MULT_G_2E:
13097 check_dspr2(ctx);
13098 switch (op2) {
13099 case OPC_ADDUH_QB:
13100 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
13101 break;
13102 case OPC_ADDUH_R_QB:
13103 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
13104 break;
13105 case OPC_ADDQH_PH:
13106 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
13107 break;
13108 case OPC_ADDQH_R_PH:
13109 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
13110 break;
13111 case OPC_ADDQH_W:
13112 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
13113 break;
13114 case OPC_ADDQH_R_W:
13115 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
13116 break;
13117 case OPC_SUBUH_QB:
13118 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
13119 break;
13120 case OPC_SUBUH_R_QB:
13121 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
13122 break;
13123 case OPC_SUBQH_PH:
13124 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
13125 break;
13126 case OPC_SUBQH_R_PH:
13127 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
13128 break;
13129 case OPC_SUBQH_W:
13130 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
13131 break;
13132 case OPC_SUBQH_R_W:
13133 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
13134 break;
13135 }
13136 break;
13137 case OPC_ABSQ_S_PH_DSP:
13138 switch (op2) {
13139 case OPC_ABSQ_S_QB:
13140 check_dspr2(ctx);
13141 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
13142 break;
13143 case OPC_ABSQ_S_PH:
13144 check_dsp(ctx);
13145 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
13146 break;
13147 case OPC_ABSQ_S_W:
13148 check_dsp(ctx);
13149 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
13150 break;
13151 case OPC_PRECEQ_W_PHL:
13152 check_dsp(ctx);
13153 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
13154 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13155 break;
13156 case OPC_PRECEQ_W_PHR:
13157 check_dsp(ctx);
13158 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
13159 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
13160 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13161 break;
13162 case OPC_PRECEQU_PH_QBL:
13163 check_dsp(ctx);
13164 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
13165 break;
13166 case OPC_PRECEQU_PH_QBR:
13167 check_dsp(ctx);
13168 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
13169 break;
13170 case OPC_PRECEQU_PH_QBLA:
13171 check_dsp(ctx);
13172 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
13173 break;
13174 case OPC_PRECEQU_PH_QBRA:
13175 check_dsp(ctx);
13176 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
13177 break;
13178 case OPC_PRECEU_PH_QBL:
13179 check_dsp(ctx);
13180 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
13181 break;
13182 case OPC_PRECEU_PH_QBR:
13183 check_dsp(ctx);
13184 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
13185 break;
13186 case OPC_PRECEU_PH_QBLA:
13187 check_dsp(ctx);
13188 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
13189 break;
13190 case OPC_PRECEU_PH_QBRA:
13191 check_dsp(ctx);
13192 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
13193 break;
13194 }
13195 break;
13196 case OPC_ADDU_QB_DSP:
13197 switch (op2) {
13198 case OPC_ADDQ_PH:
13199 check_dsp(ctx);
13200 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13201 break;
13202 case OPC_ADDQ_S_PH:
13203 check_dsp(ctx);
13204 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13205 break;
13206 case OPC_ADDQ_S_W:
13207 check_dsp(ctx);
13208 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13209 break;
13210 case OPC_ADDU_QB:
13211 check_dsp(ctx);
13212 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13213 break;
13214 case OPC_ADDU_S_QB:
13215 check_dsp(ctx);
13216 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13217 break;
13218 case OPC_ADDU_PH:
13219 check_dspr2(ctx);
13220 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13221 break;
13222 case OPC_ADDU_S_PH:
13223 check_dspr2(ctx);
13224 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13225 break;
13226 case OPC_SUBQ_PH:
13227 check_dsp(ctx);
13228 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13229 break;
13230 case OPC_SUBQ_S_PH:
13231 check_dsp(ctx);
13232 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13233 break;
13234 case OPC_SUBQ_S_W:
13235 check_dsp(ctx);
13236 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13237 break;
13238 case OPC_SUBU_QB:
13239 check_dsp(ctx);
13240 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13241 break;
13242 case OPC_SUBU_S_QB:
13243 check_dsp(ctx);
13244 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13245 break;
13246 case OPC_SUBU_PH:
13247 check_dspr2(ctx);
13248 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13249 break;
13250 case OPC_SUBU_S_PH:
13251 check_dspr2(ctx);
13252 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13253 break;
13254 case OPC_ADDSC:
13255 check_dsp(ctx);
13256 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13257 break;
13258 case OPC_ADDWC:
13259 check_dsp(ctx);
13260 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13261 break;
13262 case OPC_MODSUB:
13263 check_dsp(ctx);
13264 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
13265 break;
13266 case OPC_RADDU_W_QB:
13267 check_dsp(ctx);
13268 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
13269 break;
13270 }
13271 break;
13272 case OPC_CMPU_EQ_QB_DSP:
13273 switch (op2) {
13274 case OPC_PRECR_QB_PH:
13275 check_dspr2(ctx);
13276 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
13277 break;
13278 case OPC_PRECRQ_QB_PH:
13279 check_dsp(ctx);
13280 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
13281 break;
13282 case OPC_PRECR_SRA_PH_W:
13283 check_dspr2(ctx);
13284 {
13285 TCGv_i32 sa_t = tcg_const_i32(v2);
13286 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
13287 cpu_gpr[ret]);
13288 tcg_temp_free_i32(sa_t);
13289 break;
13290 }
13291 case OPC_PRECR_SRA_R_PH_W:
13292 check_dspr2(ctx);
13293 {
13294 TCGv_i32 sa_t = tcg_const_i32(v2);
13295 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
13296 cpu_gpr[ret]);
13297 tcg_temp_free_i32(sa_t);
13298 break;
13299 }
13300 case OPC_PRECRQ_PH_W:
13301 check_dsp(ctx);
13302 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
13303 break;
13304 case OPC_PRECRQ_RS_PH_W:
13305 check_dsp(ctx);
13306 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13307 break;
13308 case OPC_PRECRQU_S_QB_PH:
13309 check_dsp(ctx);
13310 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13311 break;
13312 }
13313 break;
13314#ifdef TARGET_MIPS64
13315 case OPC_ABSQ_S_QH_DSP:
13316 switch (op2) {
13317 case OPC_PRECEQ_L_PWL:
13318 check_dsp(ctx);
13319 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
13320 break;
13321 case OPC_PRECEQ_L_PWR:
13322 check_dsp(ctx);
13323 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
13324 break;
13325 case OPC_PRECEQ_PW_QHL:
13326 check_dsp(ctx);
13327 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
13328 break;
13329 case OPC_PRECEQ_PW_QHR:
13330 check_dsp(ctx);
13331 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
13332 break;
13333 case OPC_PRECEQ_PW_QHLA:
13334 check_dsp(ctx);
13335 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
13336 break;
13337 case OPC_PRECEQ_PW_QHRA:
13338 check_dsp(ctx);
13339 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
13340 break;
13341 case OPC_PRECEQU_QH_OBL:
13342 check_dsp(ctx);
13343 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
13344 break;
13345 case OPC_PRECEQU_QH_OBR:
13346 check_dsp(ctx);
13347 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
13348 break;
13349 case OPC_PRECEQU_QH_OBLA:
13350 check_dsp(ctx);
13351 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13352 break;
13353 case OPC_PRECEQU_QH_OBRA:
13354 check_dsp(ctx);
13355 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13356 break;
13357 case OPC_PRECEU_QH_OBL:
13358 check_dsp(ctx);
13359 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13360 break;
13361 case OPC_PRECEU_QH_OBR:
13362 check_dsp(ctx);
13363 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13364 break;
13365 case OPC_PRECEU_QH_OBLA:
13366 check_dsp(ctx);
13367 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13368 break;
13369 case OPC_PRECEU_QH_OBRA:
13370 check_dsp(ctx);
13371 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13372 break;
13373 case OPC_ABSQ_S_OB:
13374 check_dspr2(ctx);
13375 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13376 break;
13377 case OPC_ABSQ_S_PW:
13378 check_dsp(ctx);
13379 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13380 break;
13381 case OPC_ABSQ_S_QH:
13382 check_dsp(ctx);
13383 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13384 break;
13385 }
13386 break;
13387 case OPC_ADDU_OB_DSP:
13388 switch (op2) {
13389 case OPC_RADDU_L_OB:
13390 check_dsp(ctx);
13391 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13392 break;
13393 case OPC_SUBQ_PW:
13394 check_dsp(ctx);
13395 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13396 break;
13397 case OPC_SUBQ_S_PW:
13398 check_dsp(ctx);
13399 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13400 break;
13401 case OPC_SUBQ_QH:
13402 check_dsp(ctx);
13403 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13404 break;
13405 case OPC_SUBQ_S_QH:
13406 check_dsp(ctx);
13407 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13408 break;
13409 case OPC_SUBU_OB:
13410 check_dsp(ctx);
13411 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13412 break;
13413 case OPC_SUBU_S_OB:
13414 check_dsp(ctx);
13415 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13416 break;
13417 case OPC_SUBU_QH:
13418 check_dspr2(ctx);
13419 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13420 break;
13421 case OPC_SUBU_S_QH:
13422 check_dspr2(ctx);
13423 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13424 break;
13425 case OPC_SUBUH_OB:
13426 check_dspr2(ctx);
13427 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13428 break;
13429 case OPC_SUBUH_R_OB:
13430 check_dspr2(ctx);
13431 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13432 break;
13433 case OPC_ADDQ_PW:
13434 check_dsp(ctx);
13435 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13436 break;
13437 case OPC_ADDQ_S_PW:
13438 check_dsp(ctx);
13439 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13440 break;
13441 case OPC_ADDQ_QH:
13442 check_dsp(ctx);
13443 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13444 break;
13445 case OPC_ADDQ_S_QH:
13446 check_dsp(ctx);
13447 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13448 break;
13449 case OPC_ADDU_OB:
13450 check_dsp(ctx);
13451 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13452 break;
13453 case OPC_ADDU_S_OB:
13454 check_dsp(ctx);
13455 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13456 break;
13457 case OPC_ADDU_QH:
13458 check_dspr2(ctx);
13459 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13460 break;
13461 case OPC_ADDU_S_QH:
13462 check_dspr2(ctx);
13463 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13464 break;
13465 case OPC_ADDUH_OB:
13466 check_dspr2(ctx);
13467 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13468 break;
13469 case OPC_ADDUH_R_OB:
13470 check_dspr2(ctx);
13471 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13472 break;
13473 }
13474 break;
13475 case OPC_CMPU_EQ_OB_DSP:
13476 switch (op2) {
13477 case OPC_PRECR_OB_QH:
13478 check_dspr2(ctx);
13479 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13480 break;
13481 case OPC_PRECR_SRA_QH_PW:
13482 check_dspr2(ctx);
13483 {
13484 TCGv_i32 ret_t = tcg_const_i32(ret);
13485 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13486 tcg_temp_free_i32(ret_t);
13487 break;
13488 }
13489 case OPC_PRECR_SRA_R_QH_PW:
13490 check_dspr2(ctx);
13491 {
13492 TCGv_i32 sa_v = tcg_const_i32(ret);
13493 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13494 tcg_temp_free_i32(sa_v);
13495 break;
13496 }
13497 case OPC_PRECRQ_OB_QH:
13498 check_dsp(ctx);
13499 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13500 break;
13501 case OPC_PRECRQ_PW_L:
13502 check_dsp(ctx);
13503 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13504 break;
13505 case OPC_PRECRQ_QH_PW:
13506 check_dsp(ctx);
13507 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13508 break;
13509 case OPC_PRECRQ_RS_QH_PW:
13510 check_dsp(ctx);
13511 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13512 break;
13513 case OPC_PRECRQU_S_OB_QH:
13514 check_dsp(ctx);
13515 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13516 break;
13517 }
13518 break;
13519#endif
13520 }
13521
13522 tcg_temp_free(v1_t);
13523 tcg_temp_free(v2_t);
13524
13525 (void)opn; /* avoid a compiler warning */
13526 MIPS_DEBUG("%s", opn);
13527}
9b1a1d68 13528
77c5fa8b
JL
13529static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13530 int ret, int v1, int v2)
13531{
13532 uint32_t op2;
13533 const char *opn = "mipsdsp shift";
13534 TCGv t0;
13535 TCGv v1_t;
13536 TCGv v2_t;
13537
13538 if (ret == 0) {
13539 /* Treat as NOP. */
13540 MIPS_DEBUG("NOP");
13541 return;
13542 }
13543
13544 t0 = tcg_temp_new();
13545 v1_t = tcg_temp_new();
13546 v2_t = tcg_temp_new();
13547
13548 tcg_gen_movi_tl(t0, v1);
13549 gen_load_gpr(v1_t, v1);
13550 gen_load_gpr(v2_t, v2);
13551
13552 switch (opc) {
13553 case OPC_SHLL_QB_DSP:
13554 {
13555 op2 = MASK_SHLL_QB(ctx->opcode);
13556 switch (op2) {
13557 case OPC_SHLL_QB:
13558 check_dsp(ctx);
13559 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13560 break;
13561 case OPC_SHLLV_QB:
13562 check_dsp(ctx);
13563 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13564 break;
13565 case OPC_SHLL_PH:
13566 check_dsp(ctx);
13567 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13568 break;
13569 case OPC_SHLLV_PH:
13570 check_dsp(ctx);
13571 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13572 break;
13573 case OPC_SHLL_S_PH:
13574 check_dsp(ctx);
13575 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13576 break;
13577 case OPC_SHLLV_S_PH:
13578 check_dsp(ctx);
13579 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13580 break;
13581 case OPC_SHLL_S_W:
13582 check_dsp(ctx);
13583 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13584 break;
13585 case OPC_SHLLV_S_W:
13586 check_dsp(ctx);
13587 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13588 break;
13589 case OPC_SHRL_QB:
13590 check_dsp(ctx);
13591 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13592 break;
13593 case OPC_SHRLV_QB:
13594 check_dsp(ctx);
13595 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13596 break;
13597 case OPC_SHRL_PH:
13598 check_dspr2(ctx);
13599 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13600 break;
13601 case OPC_SHRLV_PH:
13602 check_dspr2(ctx);
13603 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13604 break;
13605 case OPC_SHRA_QB:
13606 check_dspr2(ctx);
13607 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13608 break;
13609 case OPC_SHRA_R_QB:
13610 check_dspr2(ctx);
13611 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13612 break;
13613 case OPC_SHRAV_QB:
13614 check_dspr2(ctx);
13615 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13616 break;
13617 case OPC_SHRAV_R_QB:
13618 check_dspr2(ctx);
13619 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13620 break;
13621 case OPC_SHRA_PH:
13622 check_dsp(ctx);
13623 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13624 break;
13625 case OPC_SHRA_R_PH:
13626 check_dsp(ctx);
13627 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13628 break;
13629 case OPC_SHRAV_PH:
13630 check_dsp(ctx);
13631 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13632 break;
13633 case OPC_SHRAV_R_PH:
13634 check_dsp(ctx);
13635 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13636 break;
13637 case OPC_SHRA_R_W:
13638 check_dsp(ctx);
13639 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13640 break;
13641 case OPC_SHRAV_R_W:
13642 check_dsp(ctx);
13643 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13644 break;
13645 default: /* Invalid */
13646 MIPS_INVAL("MASK SHLL.QB");
13647 generate_exception(ctx, EXCP_RI);
13648 break;
13649 }
13650 break;
13651 }
13652#ifdef TARGET_MIPS64
13653 case OPC_SHLL_OB_DSP:
13654 op2 = MASK_SHLL_OB(ctx->opcode);
13655 switch (op2) {
13656 case OPC_SHLL_PW:
13657 check_dsp(ctx);
13658 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13659 break;
13660 case OPC_SHLLV_PW:
13661 check_dsp(ctx);
13662 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13663 break;
13664 case OPC_SHLL_S_PW:
13665 check_dsp(ctx);
13666 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13667 break;
13668 case OPC_SHLLV_S_PW:
13669 check_dsp(ctx);
13670 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13671 break;
13672 case OPC_SHLL_OB:
13673 check_dsp(ctx);
13674 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13675 break;
13676 case OPC_SHLLV_OB:
13677 check_dsp(ctx);
13678 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13679 break;
13680 case OPC_SHLL_QH:
13681 check_dsp(ctx);
13682 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13683 break;
13684 case OPC_SHLLV_QH:
13685 check_dsp(ctx);
13686 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13687 break;
13688 case OPC_SHLL_S_QH:
13689 check_dsp(ctx);
13690 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13691 break;
13692 case OPC_SHLLV_S_QH:
13693 check_dsp(ctx);
13694 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13695 break;
13696 case OPC_SHRA_OB:
13697 check_dspr2(ctx);
13698 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13699 break;
13700 case OPC_SHRAV_OB:
13701 check_dspr2(ctx);
13702 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13703 break;
13704 case OPC_SHRA_R_OB:
13705 check_dspr2(ctx);
13706 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13707 break;
13708 case OPC_SHRAV_R_OB:
13709 check_dspr2(ctx);
13710 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13711 break;
13712 case OPC_SHRA_PW:
13713 check_dsp(ctx);
13714 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13715 break;
13716 case OPC_SHRAV_PW:
13717 check_dsp(ctx);
13718 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13719 break;
13720 case OPC_SHRA_R_PW:
13721 check_dsp(ctx);
13722 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13723 break;
13724 case OPC_SHRAV_R_PW:
13725 check_dsp(ctx);
13726 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13727 break;
13728 case OPC_SHRA_QH:
13729 check_dsp(ctx);
13730 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13731 break;
13732 case OPC_SHRAV_QH:
13733 check_dsp(ctx);
13734 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13735 break;
13736 case OPC_SHRA_R_QH:
13737 check_dsp(ctx);
13738 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13739 break;
13740 case OPC_SHRAV_R_QH:
13741 check_dsp(ctx);
13742 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13743 break;
13744 case OPC_SHRL_OB:
13745 check_dsp(ctx);
13746 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13747 break;
13748 case OPC_SHRLV_OB:
13749 check_dsp(ctx);
13750 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13751 break;
13752 case OPC_SHRL_QH:
13753 check_dspr2(ctx);
13754 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13755 break;
13756 case OPC_SHRLV_QH:
13757 check_dspr2(ctx);
13758 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13759 break;
13760 default: /* Invalid */
13761 MIPS_INVAL("MASK SHLL.OB");
13762 generate_exception(ctx, EXCP_RI);
13763 break;
13764 }
13765 break;
13766#endif
13767 }
13768
13769 tcg_temp_free(t0);
13770 tcg_temp_free(v1_t);
13771 tcg_temp_free(v2_t);
13772 (void)opn; /* avoid a compiler warning */
13773 MIPS_DEBUG("%s", opn);
13774}
13775
a22260ae
JL
13776static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13777 int ret, int v1, int v2, int check_ret)
13778{
13779 const char *opn = "mipsdsp multiply";
13780 TCGv_i32 t0;
13781 TCGv v1_t;
13782 TCGv v2_t;
13783
13784 if ((ret == 0) && (check_ret == 1)) {
13785 /* Treat as NOP. */
13786 MIPS_DEBUG("NOP");
13787 return;
13788 }
13789
13790 t0 = tcg_temp_new_i32();
13791 v1_t = tcg_temp_new();
13792 v2_t = tcg_temp_new();
13793
13794 tcg_gen_movi_i32(t0, ret);
13795 gen_load_gpr(v1_t, v1);
13796 gen_load_gpr(v2_t, v2);
13797
13798 switch (op1) {
13799 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13800 * the same mask and op1. */
13801 case OPC_MULT_G_2E:
639eadb9 13802 check_dspr2(ctx);
a22260ae
JL
13803 switch (op2) {
13804 case OPC_MUL_PH:
13805 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13806 break;
13807 case OPC_MUL_S_PH:
13808 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13809 break;
13810 case OPC_MULQ_S_W:
13811 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13812 break;
13813 case OPC_MULQ_RS_W:
13814 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13815 break;
13816 }
13817 break;
13818 case OPC_DPA_W_PH_DSP:
13819 switch (op2) {
13820 case OPC_DPAU_H_QBL:
13821 check_dsp(ctx);
13822 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13823 break;
13824 case OPC_DPAU_H_QBR:
13825 check_dsp(ctx);
13826 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13827 break;
13828 case OPC_DPSU_H_QBL:
13829 check_dsp(ctx);
13830 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13831 break;
13832 case OPC_DPSU_H_QBR:
13833 check_dsp(ctx);
13834 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13835 break;
13836 case OPC_DPA_W_PH:
13837 check_dspr2(ctx);
13838 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13839 break;
13840 case OPC_DPAX_W_PH:
13841 check_dspr2(ctx);
13842 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13843 break;
13844 case OPC_DPAQ_S_W_PH:
13845 check_dsp(ctx);
13846 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13847 break;
13848 case OPC_DPAQX_S_W_PH:
13849 check_dspr2(ctx);
13850 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13851 break;
13852 case OPC_DPAQX_SA_W_PH:
13853 check_dspr2(ctx);
13854 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13855 break;
13856 case OPC_DPS_W_PH:
13857 check_dspr2(ctx);
13858 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13859 break;
13860 case OPC_DPSX_W_PH:
13861 check_dspr2(ctx);
13862 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13863 break;
13864 case OPC_DPSQ_S_W_PH:
13865 check_dsp(ctx);
13866 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13867 break;
13868 case OPC_DPSQX_S_W_PH:
13869 check_dspr2(ctx);
13870 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13871 break;
13872 case OPC_DPSQX_SA_W_PH:
13873 check_dspr2(ctx);
13874 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13875 break;
13876 case OPC_MULSAQ_S_W_PH:
13877 check_dsp(ctx);
13878 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13879 break;
13880 case OPC_DPAQ_SA_L_W:
13881 check_dsp(ctx);
13882 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13883 break;
13884 case OPC_DPSQ_SA_L_W:
13885 check_dsp(ctx);
13886 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13887 break;
13888 case OPC_MAQ_S_W_PHL:
13889 check_dsp(ctx);
13890 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13891 break;
13892 case OPC_MAQ_S_W_PHR:
13893 check_dsp(ctx);
13894 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13895 break;
13896 case OPC_MAQ_SA_W_PHL:
13897 check_dsp(ctx);
13898 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13899 break;
13900 case OPC_MAQ_SA_W_PHR:
13901 check_dsp(ctx);
13902 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13903 break;
13904 case OPC_MULSA_W_PH:
13905 check_dspr2(ctx);
13906 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13907 break;
13908 }
13909 break;
13910#ifdef TARGET_MIPS64
13911 case OPC_DPAQ_W_QH_DSP:
13912 {
13913 int ac = ret & 0x03;
13914 tcg_gen_movi_i32(t0, ac);
13915
13916 switch (op2) {
13917 case OPC_DMADD:
13918 check_dsp(ctx);
13919 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13920 break;
13921 case OPC_DMADDU:
13922 check_dsp(ctx);
13923 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13924 break;
13925 case OPC_DMSUB:
13926 check_dsp(ctx);
13927 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13928 break;
13929 case OPC_DMSUBU:
13930 check_dsp(ctx);
13931 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13932 break;
13933 case OPC_DPA_W_QH:
13934 check_dspr2(ctx);
13935 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13936 break;
13937 case OPC_DPAQ_S_W_QH:
13938 check_dsp(ctx);
13939 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13940 break;
13941 case OPC_DPAQ_SA_L_PW:
13942 check_dsp(ctx);
13943 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13944 break;
13945 case OPC_DPAU_H_OBL:
13946 check_dsp(ctx);
13947 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13948 break;
13949 case OPC_DPAU_H_OBR:
13950 check_dsp(ctx);
13951 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13952 break;
13953 case OPC_DPS_W_QH:
13954 check_dspr2(ctx);
13955 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13956 break;
13957 case OPC_DPSQ_S_W_QH:
13958 check_dsp(ctx);
13959 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13960 break;
13961 case OPC_DPSQ_SA_L_PW:
13962 check_dsp(ctx);
13963 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13964 break;
13965 case OPC_DPSU_H_OBL:
13966 check_dsp(ctx);
13967 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13968 break;
13969 case OPC_DPSU_H_OBR:
13970 check_dsp(ctx);
13971 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13972 break;
13973 case OPC_MAQ_S_L_PWL:
13974 check_dsp(ctx);
13975 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13976 break;
13977 case OPC_MAQ_S_L_PWR:
13978 check_dsp(ctx);
13979 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13980 break;
13981 case OPC_MAQ_S_W_QHLL:
13982 check_dsp(ctx);
13983 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13984 break;
13985 case OPC_MAQ_SA_W_QHLL:
13986 check_dsp(ctx);
13987 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13988 break;
13989 case OPC_MAQ_S_W_QHLR:
13990 check_dsp(ctx);
13991 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13992 break;
13993 case OPC_MAQ_SA_W_QHLR:
13994 check_dsp(ctx);
13995 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13996 break;
13997 case OPC_MAQ_S_W_QHRL:
13998 check_dsp(ctx);
13999 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
14000 break;
14001 case OPC_MAQ_SA_W_QHRL:
14002 check_dsp(ctx);
14003 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
14004 break;
14005 case OPC_MAQ_S_W_QHRR:
14006 check_dsp(ctx);
14007 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
14008 break;
14009 case OPC_MAQ_SA_W_QHRR:
14010 check_dsp(ctx);
14011 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
14012 break;
14013 case OPC_MULSAQ_S_L_PW:
14014 check_dsp(ctx);
14015 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
14016 break;
14017 case OPC_MULSAQ_S_W_QH:
14018 check_dsp(ctx);
14019 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14020 break;
14021 }
14022 }
14023 break;
14024#endif
14025 case OPC_ADDU_QB_DSP:
14026 switch (op2) {
14027 case OPC_MULEU_S_PH_QBL:
14028 check_dsp(ctx);
14029 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14030 break;
14031 case OPC_MULEU_S_PH_QBR:
14032 check_dsp(ctx);
14033 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14034 break;
14035 case OPC_MULQ_RS_PH:
14036 check_dsp(ctx);
14037 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14038 break;
14039 case OPC_MULEQ_S_W_PHL:
14040 check_dsp(ctx);
14041 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14042 break;
14043 case OPC_MULEQ_S_W_PHR:
14044 check_dsp(ctx);
14045 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14046 break;
14047 case OPC_MULQ_S_PH:
14048 check_dspr2(ctx);
14049 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14050 break;
14051 }
14052 break;
14053#ifdef TARGET_MIPS64
14054 case OPC_ADDU_OB_DSP:
14055 switch (op2) {
14056 case OPC_MULEQ_S_PW_QHL:
14057 check_dsp(ctx);
14058 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14059 break;
14060 case OPC_MULEQ_S_PW_QHR:
14061 check_dsp(ctx);
14062 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14063 break;
14064 case OPC_MULEU_S_QH_OBL:
14065 check_dsp(ctx);
14066 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14067 break;
14068 case OPC_MULEU_S_QH_OBR:
14069 check_dsp(ctx);
14070 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14071 break;
14072 case OPC_MULQ_RS_QH:
14073 check_dsp(ctx);
14074 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14075 break;
14076 }
14077 break;
14078#endif
14079 }
14080
14081 tcg_temp_free_i32(t0);
14082 tcg_temp_free(v1_t);
14083 tcg_temp_free(v2_t);
14084
14085 (void)opn; /* avoid a compiler warning */
14086 MIPS_DEBUG("%s", opn);
14087
14088}
14089
d75c135e 14090static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
14091 int ret, int val)
14092{
14093 const char *opn = "mipsdsp Bit/ Manipulation";
14094 int16_t imm;
14095 TCGv t0;
14096 TCGv val_t;
14097
14098 if (ret == 0) {
14099 /* Treat as NOP. */
14100 MIPS_DEBUG("NOP");
14101 return;
14102 }
14103
14104 t0 = tcg_temp_new();
14105 val_t = tcg_temp_new();
14106 gen_load_gpr(val_t, val);
14107
14108 switch (op1) {
14109 case OPC_ABSQ_S_PH_DSP:
14110 switch (op2) {
14111 case OPC_BITREV:
14112 check_dsp(ctx);
14113 gen_helper_bitrev(cpu_gpr[ret], val_t);
14114 break;
14115 case OPC_REPL_QB:
14116 check_dsp(ctx);
14117 {
14118 target_long result;
14119 imm = (ctx->opcode >> 16) & 0xFF;
14120 result = (uint32_t)imm << 24 |
14121 (uint32_t)imm << 16 |
14122 (uint32_t)imm << 8 |
14123 (uint32_t)imm;
14124 result = (int32_t)result;
14125 tcg_gen_movi_tl(cpu_gpr[ret], result);
14126 }
14127 break;
14128 case OPC_REPLV_QB:
14129 check_dsp(ctx);
14130 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
14131 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
14132 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14133 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14134 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14135 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14136 break;
14137 case OPC_REPL_PH:
14138 check_dsp(ctx);
14139 {
14140 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 14141 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
14142 tcg_gen_movi_tl(cpu_gpr[ret], \
14143 (target_long)((int32_t)imm << 16 | \
c4aaba92 14144 (uint16_t)imm));
1cb6686c
JL
14145 }
14146 break;
14147 case OPC_REPLV_PH:
14148 check_dsp(ctx);
14149 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
14150 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14151 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14152 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14153 break;
14154 }
14155 break;
14156#ifdef TARGET_MIPS64
14157 case OPC_ABSQ_S_QH_DSP:
14158 switch (op2) {
14159 case OPC_REPL_OB:
14160 check_dsp(ctx);
14161 {
14162 target_long temp;
14163
14164 imm = (ctx->opcode >> 16) & 0xFF;
14165 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
14166 temp = (temp << 16) | temp;
14167 temp = (temp << 32) | temp;
14168 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14169 break;
14170 }
14171 case OPC_REPL_PW:
14172 check_dsp(ctx);
14173 {
14174 target_long temp;
14175
14176 imm = (ctx->opcode >> 16) & 0x03FF;
14177 imm = (int16_t)(imm << 6) >> 6;
14178 temp = ((target_long)imm << 32) \
14179 | ((target_long)imm & 0xFFFFFFFF);
14180 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14181 break;
14182 }
14183 case OPC_REPL_QH:
14184 check_dsp(ctx);
14185 {
14186 target_long temp;
14187
14188 imm = (ctx->opcode >> 16) & 0x03FF;
14189 imm = (int16_t)(imm << 6) >> 6;
14190
14191 temp = ((uint64_t)(uint16_t)imm << 48) |
14192 ((uint64_t)(uint16_t)imm << 32) |
14193 ((uint64_t)(uint16_t)imm << 16) |
14194 (uint64_t)(uint16_t)imm;
14195 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14196 break;
14197 }
14198 case OPC_REPLV_OB:
14199 check_dsp(ctx);
14200 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
14201 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
14202 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14203 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14204 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14205 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14206 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14207 break;
14208 case OPC_REPLV_PW:
14209 check_dsp(ctx);
14210 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
14211 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14212 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14213 break;
14214 case OPC_REPLV_QH:
14215 check_dsp(ctx);
14216 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
14217 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14218 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14219 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14220 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14221 break;
14222 }
14223 break;
14224#endif
14225 }
14226 tcg_temp_free(t0);
14227 tcg_temp_free(val_t);
14228
14229 (void)opn; /* avoid a compiler warning */
14230 MIPS_DEBUG("%s", opn);
14231}
14232
26690560
JL
14233static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
14234 uint32_t op1, uint32_t op2,
14235 int ret, int v1, int v2, int check_ret)
14236{
14237 const char *opn = "mipsdsp add compare pick";
26690560
JL
14238 TCGv t1;
14239 TCGv v1_t;
14240 TCGv v2_t;
14241
14242 if ((ret == 0) && (check_ret == 1)) {
14243 /* Treat as NOP. */
14244 MIPS_DEBUG("NOP");
14245 return;
14246 }
14247
26690560
JL
14248 t1 = tcg_temp_new();
14249 v1_t = tcg_temp_new();
14250 v2_t = tcg_temp_new();
14251
14252 gen_load_gpr(v1_t, v1);
14253 gen_load_gpr(v2_t, v2);
14254
14255 switch (op1) {
26690560
JL
14256 case OPC_CMPU_EQ_QB_DSP:
14257 switch (op2) {
14258 case OPC_CMPU_EQ_QB:
14259 check_dsp(ctx);
14260 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
14261 break;
14262 case OPC_CMPU_LT_QB:
14263 check_dsp(ctx);
14264 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
14265 break;
14266 case OPC_CMPU_LE_QB:
14267 check_dsp(ctx);
14268 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
14269 break;
14270 case OPC_CMPGU_EQ_QB:
14271 check_dsp(ctx);
14272 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
14273 break;
14274 case OPC_CMPGU_LT_QB:
14275 check_dsp(ctx);
14276 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
14277 break;
14278 case OPC_CMPGU_LE_QB:
14279 check_dsp(ctx);
14280 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
14281 break;
14282 case OPC_CMPGDU_EQ_QB:
14283 check_dspr2(ctx);
14284 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
14285 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14286 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14287 tcg_gen_shli_tl(t1, t1, 24);
14288 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14289 break;
14290 case OPC_CMPGDU_LT_QB:
14291 check_dspr2(ctx);
14292 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
14293 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14294 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14295 tcg_gen_shli_tl(t1, t1, 24);
14296 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14297 break;
14298 case OPC_CMPGDU_LE_QB:
14299 check_dspr2(ctx);
14300 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
14301 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14302 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14303 tcg_gen_shli_tl(t1, t1, 24);
14304 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14305 break;
14306 case OPC_CMP_EQ_PH:
14307 check_dsp(ctx);
14308 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
14309 break;
14310 case OPC_CMP_LT_PH:
14311 check_dsp(ctx);
14312 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
14313 break;
14314 case OPC_CMP_LE_PH:
14315 check_dsp(ctx);
14316 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
14317 break;
14318 case OPC_PICK_QB:
14319 check_dsp(ctx);
14320 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14321 break;
14322 case OPC_PICK_PH:
14323 check_dsp(ctx);
14324 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14325 break;
14326 case OPC_PACKRL_PH:
14327 check_dsp(ctx);
14328 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
14329 break;
14330 }
14331 break;
14332#ifdef TARGET_MIPS64
14333 case OPC_CMPU_EQ_OB_DSP:
14334 switch (op2) {
14335 case OPC_CMP_EQ_PW:
14336 check_dsp(ctx);
14337 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
14338 break;
14339 case OPC_CMP_LT_PW:
14340 check_dsp(ctx);
14341 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14342 break;
14343 case OPC_CMP_LE_PW:
14344 check_dsp(ctx);
14345 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14346 break;
14347 case OPC_CMP_EQ_QH:
14348 check_dsp(ctx);
14349 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14350 break;
14351 case OPC_CMP_LT_QH:
14352 check_dsp(ctx);
14353 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14354 break;
14355 case OPC_CMP_LE_QH:
14356 check_dsp(ctx);
14357 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14358 break;
14359 case OPC_CMPGDU_EQ_OB:
14360 check_dspr2(ctx);
14361 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14362 break;
14363 case OPC_CMPGDU_LT_OB:
14364 check_dspr2(ctx);
14365 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14366 break;
14367 case OPC_CMPGDU_LE_OB:
14368 check_dspr2(ctx);
14369 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14370 break;
14371 case OPC_CMPGU_EQ_OB:
14372 check_dsp(ctx);
14373 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14374 break;
14375 case OPC_CMPGU_LT_OB:
14376 check_dsp(ctx);
14377 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14378 break;
14379 case OPC_CMPGU_LE_OB:
14380 check_dsp(ctx);
14381 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14382 break;
14383 case OPC_CMPU_EQ_OB:
14384 check_dsp(ctx);
14385 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14386 break;
14387 case OPC_CMPU_LT_OB:
14388 check_dsp(ctx);
14389 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14390 break;
14391 case OPC_CMPU_LE_OB:
14392 check_dsp(ctx);
14393 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14394 break;
14395 case OPC_PACKRL_PW:
14396 check_dsp(ctx);
14397 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14398 break;
14399 case OPC_PICK_OB:
14400 check_dsp(ctx);
14401 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14402 break;
14403 case OPC_PICK_PW:
14404 check_dsp(ctx);
14405 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14406 break;
14407 case OPC_PICK_QH:
14408 check_dsp(ctx);
14409 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14410 break;
14411 }
14412 break;
df6126a7
AJ
14413#endif
14414 }
14415
14416 tcg_temp_free(t1);
14417 tcg_temp_free(v1_t);
14418 tcg_temp_free(v2_t);
14419
14420 (void)opn; /* avoid a compiler warning */
14421 MIPS_DEBUG("%s", opn);
14422}
14423
14424static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14425 uint32_t op1, int rt, int rs, int sa)
14426{
14427 const char *opn = "mipsdsp append/dappend";
14428 TCGv t0;
14429
14430 check_dspr2(ctx);
14431
14432 if (rt == 0) {
14433 /* Treat as NOP. */
14434 MIPS_DEBUG("NOP");
14435 return;
14436 }
14437
14438 t0 = tcg_temp_new();
14439 gen_load_gpr(t0, rs);
14440
14441 switch (op1) {
14442 case OPC_APPEND_DSP:
14443 switch (MASK_APPEND(ctx->opcode)) {
14444 case OPC_APPEND:
14445 if (sa != 0) {
14446 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14447 }
14448 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14449 break;
14450 case OPC_PREPEND:
14451 if (sa != 0) {
14452 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14453 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14454 tcg_gen_shli_tl(t0, t0, 32 - sa);
14455 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14456 }
14457 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14458 break;
14459 case OPC_BALIGN:
14460 sa &= 3;
14461 if (sa != 0 && sa != 2) {
14462 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14463 tcg_gen_ext32u_tl(t0, t0);
14464 tcg_gen_shri_tl(t0, t0, 8 * (4 - 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 default: /* Invalid */
14470 MIPS_INVAL("MASK APPEND");
14471 generate_exception(ctx, EXCP_RI);
14472 break;
14473 }
14474 break;
14475#ifdef TARGET_MIPS64
26690560 14476 case OPC_DAPPEND_DSP:
df6126a7 14477 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 14478 case OPC_DAPPEND:
df6126a7
AJ
14479 if (sa != 0) {
14480 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14481 }
26690560
JL
14482 break;
14483 case OPC_PREPENDD:
df6126a7
AJ
14484 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14485 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14486 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
14487 break;
14488 case OPC_PREPENDW:
df6126a7
AJ
14489 if (sa != 0) {
14490 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14491 tcg_gen_shli_tl(t0, t0, 64 - sa);
14492 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14493 }
26690560
JL
14494 break;
14495 case OPC_DBALIGN:
df6126a7
AJ
14496 sa &= 7;
14497 if (sa != 0 && sa != 2 && sa != 4) {
14498 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14499 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14500 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14501 }
26690560
JL
14502 break;
14503 default: /* Invalid */
14504 MIPS_INVAL("MASK DAPPEND");
14505 generate_exception(ctx, EXCP_RI);
14506 break;
14507 }
14508 break;
14509#endif
14510 }
df6126a7 14511 tcg_temp_free(t0);
26690560
JL
14512 (void)opn; /* avoid a compiler warning */
14513 MIPS_DEBUG("%s", opn);
14514}
14515
b53371ed
JL
14516static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14517 int ret, int v1, int v2, int check_ret)
14518
14519{
14520 const char *opn = "mipsdsp accumulator";
14521 TCGv t0;
14522 TCGv t1;
14523 TCGv v1_t;
14524 TCGv v2_t;
14525 int16_t imm;
14526
14527 if ((ret == 0) && (check_ret == 1)) {
14528 /* Treat as NOP. */
14529 MIPS_DEBUG("NOP");
14530 return;
14531 }
14532
14533 t0 = tcg_temp_new();
14534 t1 = tcg_temp_new();
14535 v1_t = tcg_temp_new();
14536 v2_t = tcg_temp_new();
14537
14538 gen_load_gpr(v1_t, v1);
14539 gen_load_gpr(v2_t, v2);
14540
14541 switch (op1) {
14542 case OPC_EXTR_W_DSP:
14543 check_dsp(ctx);
14544 switch (op2) {
14545 case OPC_EXTR_W:
14546 tcg_gen_movi_tl(t0, v2);
14547 tcg_gen_movi_tl(t1, v1);
14548 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14549 break;
14550 case OPC_EXTR_R_W:
14551 tcg_gen_movi_tl(t0, v2);
14552 tcg_gen_movi_tl(t1, v1);
14553 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14554 break;
14555 case OPC_EXTR_RS_W:
14556 tcg_gen_movi_tl(t0, v2);
14557 tcg_gen_movi_tl(t1, v1);
14558 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14559 break;
14560 case OPC_EXTR_S_H:
14561 tcg_gen_movi_tl(t0, v2);
14562 tcg_gen_movi_tl(t1, v1);
14563 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14564 break;
14565 case OPC_EXTRV_S_H:
14566 tcg_gen_movi_tl(t0, v2);
14567 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14568 break;
14569 case OPC_EXTRV_W:
14570 tcg_gen_movi_tl(t0, v2);
14571 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14572 break;
14573 case OPC_EXTRV_R_W:
14574 tcg_gen_movi_tl(t0, v2);
14575 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14576 break;
14577 case OPC_EXTRV_RS_W:
14578 tcg_gen_movi_tl(t0, v2);
14579 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14580 break;
14581 case OPC_EXTP:
14582 tcg_gen_movi_tl(t0, v2);
14583 tcg_gen_movi_tl(t1, v1);
14584 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14585 break;
14586 case OPC_EXTPV:
14587 tcg_gen_movi_tl(t0, v2);
14588 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14589 break;
14590 case OPC_EXTPDP:
14591 tcg_gen_movi_tl(t0, v2);
14592 tcg_gen_movi_tl(t1, v1);
14593 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14594 break;
14595 case OPC_EXTPDPV:
14596 tcg_gen_movi_tl(t0, v2);
14597 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14598 break;
14599 case OPC_SHILO:
14600 imm = (ctx->opcode >> 20) & 0x3F;
14601 tcg_gen_movi_tl(t0, ret);
14602 tcg_gen_movi_tl(t1, imm);
14603 gen_helper_shilo(t0, t1, cpu_env);
14604 break;
14605 case OPC_SHILOV:
14606 tcg_gen_movi_tl(t0, ret);
14607 gen_helper_shilo(t0, v1_t, cpu_env);
14608 break;
14609 case OPC_MTHLIP:
14610 tcg_gen_movi_tl(t0, ret);
14611 gen_helper_mthlip(t0, v1_t, cpu_env);
14612 break;
14613 case OPC_WRDSP:
14614 imm = (ctx->opcode >> 11) & 0x3FF;
14615 tcg_gen_movi_tl(t0, imm);
14616 gen_helper_wrdsp(v1_t, t0, cpu_env);
14617 break;
14618 case OPC_RDDSP:
14619 imm = (ctx->opcode >> 16) & 0x03FF;
14620 tcg_gen_movi_tl(t0, imm);
14621 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14622 break;
14623 }
14624 break;
14625#ifdef TARGET_MIPS64
14626 case OPC_DEXTR_W_DSP:
14627 check_dsp(ctx);
14628 switch (op2) {
14629 case OPC_DMTHLIP:
14630 tcg_gen_movi_tl(t0, ret);
14631 gen_helper_dmthlip(v1_t, t0, cpu_env);
14632 break;
14633 case OPC_DSHILO:
14634 {
14635 int shift = (ctx->opcode >> 19) & 0x7F;
14636 int ac = (ctx->opcode >> 11) & 0x03;
14637 tcg_gen_movi_tl(t0, shift);
14638 tcg_gen_movi_tl(t1, ac);
14639 gen_helper_dshilo(t0, t1, cpu_env);
14640 break;
14641 }
14642 case OPC_DSHILOV:
14643 {
14644 int ac = (ctx->opcode >> 11) & 0x03;
14645 tcg_gen_movi_tl(t0, ac);
14646 gen_helper_dshilo(v1_t, t0, cpu_env);
14647 break;
14648 }
14649 case OPC_DEXTP:
14650 tcg_gen_movi_tl(t0, v2);
14651 tcg_gen_movi_tl(t1, v1);
14652
14653 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14654 break;
14655 case OPC_DEXTPV:
14656 tcg_gen_movi_tl(t0, v2);
14657 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14658 break;
14659 case OPC_DEXTPDP:
14660 tcg_gen_movi_tl(t0, v2);
14661 tcg_gen_movi_tl(t1, v1);
14662 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14663 break;
14664 case OPC_DEXTPDPV:
14665 tcg_gen_movi_tl(t0, v2);
14666 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14667 break;
14668 case OPC_DEXTR_L:
14669 tcg_gen_movi_tl(t0, v2);
14670 tcg_gen_movi_tl(t1, v1);
14671 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14672 break;
14673 case OPC_DEXTR_R_L:
14674 tcg_gen_movi_tl(t0, v2);
14675 tcg_gen_movi_tl(t1, v1);
14676 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14677 break;
14678 case OPC_DEXTR_RS_L:
14679 tcg_gen_movi_tl(t0, v2);
14680 tcg_gen_movi_tl(t1, v1);
14681 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14682 break;
14683 case OPC_DEXTR_W:
14684 tcg_gen_movi_tl(t0, v2);
14685 tcg_gen_movi_tl(t1, v1);
14686 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14687 break;
14688 case OPC_DEXTR_R_W:
14689 tcg_gen_movi_tl(t0, v2);
14690 tcg_gen_movi_tl(t1, v1);
14691 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14692 break;
14693 case OPC_DEXTR_RS_W:
14694 tcg_gen_movi_tl(t0, v2);
14695 tcg_gen_movi_tl(t1, v1);
14696 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14697 break;
14698 case OPC_DEXTR_S_H:
14699 tcg_gen_movi_tl(t0, v2);
14700 tcg_gen_movi_tl(t1, v1);
14701 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14702 break;
14703 case OPC_DEXTRV_S_H:
14704 tcg_gen_movi_tl(t0, v2);
14705 tcg_gen_movi_tl(t1, v1);
14706 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14707 break;
14708 case OPC_DEXTRV_L:
14709 tcg_gen_movi_tl(t0, v2);
14710 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14711 break;
14712 case OPC_DEXTRV_R_L:
14713 tcg_gen_movi_tl(t0, v2);
14714 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14715 break;
14716 case OPC_DEXTRV_RS_L:
14717 tcg_gen_movi_tl(t0, v2);
14718 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14719 break;
14720 case OPC_DEXTRV_W:
14721 tcg_gen_movi_tl(t0, v2);
14722 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14723 break;
14724 case OPC_DEXTRV_R_W:
14725 tcg_gen_movi_tl(t0, v2);
14726 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14727 break;
14728 case OPC_DEXTRV_RS_W:
14729 tcg_gen_movi_tl(t0, v2);
14730 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14731 break;
14732 }
14733 break;
14734#endif
14735 }
14736
14737 tcg_temp_free(t0);
14738 tcg_temp_free(t1);
14739 tcg_temp_free(v1_t);
14740 tcg_temp_free(v2_t);
14741
14742 (void)opn; /* avoid a compiler warning */
14743 MIPS_DEBUG("%s", opn);
14744}
14745
9b1a1d68
JL
14746/* End MIPSDSP functions. */
14747
10dc65db
LA
14748static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
14749{
14750 int rs, rt, rd;
b42ee5e1 14751 uint32_t op1, op2;
10dc65db
LA
14752
14753 rs = (ctx->opcode >> 21) & 0x1f;
14754 rt = (ctx->opcode >> 16) & 0x1f;
14755 rd = (ctx->opcode >> 11) & 0x1f;
14756
14757 op1 = MASK_SPECIAL(ctx->opcode);
14758 switch (op1) {
b42ee5e1
LA
14759 case OPC_MULT ... OPC_DIVU:
14760 op2 = MASK_R6_MULDIV(ctx->opcode);
14761 switch (op2) {
14762 case R6_OPC_MUL:
14763 case R6_OPC_MUH:
14764 case R6_OPC_MULU:
14765 case R6_OPC_MUHU:
14766 case R6_OPC_DIV:
14767 case R6_OPC_MOD:
14768 case R6_OPC_DIVU:
14769 case R6_OPC_MODU:
14770 gen_r6_muldiv(ctx, op2, rd, rs, rt);
14771 break;
14772 default:
14773 MIPS_INVAL("special_r6 muldiv");
14774 generate_exception(ctx, EXCP_RI);
14775 break;
14776 }
14777 break;
10dc65db
LA
14778 case OPC_SELEQZ:
14779 case OPC_SELNEZ:
14780 gen_cond_move(ctx, op1, rd, rs, rt);
14781 break;
b42ee5e1
LA
14782#if defined(TARGET_MIPS64)
14783 case OPC_DMULT ... OPC_DDIVU:
14784 op2 = MASK_R6_MULDIV(ctx->opcode);
14785 switch (op2) {
14786 case R6_OPC_DMUL:
14787 case R6_OPC_DMUH:
14788 case R6_OPC_DMULU:
14789 case R6_OPC_DMUHU:
14790 case R6_OPC_DDIV:
14791 case R6_OPC_DMOD:
14792 case R6_OPC_DDIVU:
14793 case R6_OPC_DMODU:
14794 check_mips_64(ctx);
14795 gen_r6_muldiv(ctx, op2, rd, rs, rt);
14796 break;
14797 default:
14798 MIPS_INVAL("special_r6 muldiv");
14799 generate_exception(ctx, EXCP_RI);
14800 break;
14801 }
14802 break;
14803#endif
10dc65db
LA
14804 default: /* Invalid */
14805 MIPS_INVAL("special_r6");
14806 generate_exception(ctx, EXCP_RI);
14807 break;
14808 }
14809}
14810
14811static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
14812{
b42ee5e1 14813 int rs, rt, rd, sa;
10dc65db
LA
14814 uint32_t op1;
14815
14816 rs = (ctx->opcode >> 21) & 0x1f;
14817 rt = (ctx->opcode >> 16) & 0x1f;
14818 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 14819 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
14820
14821 op1 = MASK_SPECIAL(ctx->opcode);
14822 switch (op1) {
14823 case OPC_MOVN: /* Conditional move */
14824 case OPC_MOVZ:
14825 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14826 INSN_LOONGSON2E | INSN_LOONGSON2F);
14827 gen_cond_move(ctx, op1, rd, rs, rt);
14828 break;
14829 case OPC_MFHI: /* Move from HI/LO */
14830 case OPC_MFLO:
14831 gen_HILO(ctx, op1, rs & 3, rd);
14832 break;
14833 case OPC_MTHI:
14834 case OPC_MTLO: /* Move to HI/LO */
14835 gen_HILO(ctx, op1, rd & 3, rs);
14836 break;
14837 case OPC_MOVCI:
14838 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14839 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14840 check_cp1_enabled(ctx);
14841 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14842 (ctx->opcode >> 16) & 1);
14843 } else {
14844 generate_exception_err(ctx, EXCP_CpU, 1);
14845 }
14846 break;
b42ee5e1
LA
14847 case OPC_MULT:
14848 case OPC_MULTU:
14849 if (sa) {
14850 check_insn(ctx, INSN_VR54XX);
14851 op1 = MASK_MUL_VR54XX(ctx->opcode);
14852 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14853 } else {
14854 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14855 }
14856 break;
14857 case OPC_DIV:
14858 case OPC_DIVU:
14859 gen_muldiv(ctx, op1, 0, rs, rt);
14860 break;
14861#if defined(TARGET_MIPS64)
14862 case OPC_DMULT ... OPC_DDIVU:
14863 check_insn(ctx, ISA_MIPS3);
14864 check_mips_64(ctx);
14865 gen_muldiv(ctx, op1, 0, rs, rt);
14866 break;
14867#endif
10dc65db
LA
14868 default: /* Invalid */
14869 MIPS_INVAL("special_legacy");
14870 generate_exception(ctx, EXCP_RI);
14871 break;
14872 }
14873}
14874
099e5b4d 14875static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 14876{
3c824109 14877 int rs, rt, rd, sa;
099e5b4d 14878 uint32_t op1;
3c824109 14879
3c824109
NF
14880 rs = (ctx->opcode >> 21) & 0x1f;
14881 rt = (ctx->opcode >> 16) & 0x1f;
14882 rd = (ctx->opcode >> 11) & 0x1f;
14883 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
14884
14885 op1 = MASK_SPECIAL(ctx->opcode);
14886 switch (op1) {
14887 case OPC_SLL: /* Shift with immediate */
14888 case OPC_SRA:
14889 gen_shift_imm(ctx, op1, rd, rt, sa);
14890 break;
14891 case OPC_SRL:
14892 switch ((ctx->opcode >> 21) & 0x1f) {
14893 case 1:
14894 /* rotr is decoded as srl on non-R2 CPUs */
14895 if (ctx->insn_flags & ISA_MIPS32R2) {
14896 op1 = OPC_ROTR;
ea63e2c3 14897 }
099e5b4d
LA
14898 /* Fallthrough */
14899 case 0:
14900 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 14901 break;
099e5b4d
LA
14902 default:
14903 generate_exception(ctx, EXCP_RI);
ea63e2c3 14904 break;
099e5b4d
LA
14905 }
14906 break;
099e5b4d
LA
14907 case OPC_ADD ... OPC_SUBU:
14908 gen_arith(ctx, op1, rd, rs, rt);
14909 break;
14910 case OPC_SLLV: /* Shifts */
14911 case OPC_SRAV:
14912 gen_shift(ctx, op1, rd, rs, rt);
14913 break;
14914 case OPC_SRLV:
14915 switch ((ctx->opcode >> 6) & 0x1f) {
14916 case 1:
14917 /* rotrv is decoded as srlv on non-R2 CPUs */
14918 if (ctx->insn_flags & ISA_MIPS32R2) {
14919 op1 = OPC_ROTRV;
26135ead 14920 }
099e5b4d
LA
14921 /* Fallthrough */
14922 case 0:
14923 gen_shift(ctx, op1, rd, rs, rt);
26135ead 14924 break;
099e5b4d
LA
14925 default:
14926 generate_exception(ctx, EXCP_RI);
6af0bf9c 14927 break;
099e5b4d
LA
14928 }
14929 break;
14930 case OPC_SLT: /* Set on less than */
14931 case OPC_SLTU:
14932 gen_slt(ctx, op1, rd, rs, rt);
14933 break;
14934 case OPC_AND: /* Logic*/
14935 case OPC_OR:
14936 case OPC_NOR:
14937 case OPC_XOR:
14938 gen_logic(ctx, op1, rd, rs, rt);
14939 break;
099e5b4d
LA
14940 case OPC_JR ... OPC_JALR:
14941 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14942 break;
14943 case OPC_TGE ... OPC_TEQ: /* Traps */
14944 case OPC_TNE:
14945 gen_trap(ctx, op1, rs, rt, -1);
14946 break;
099e5b4d 14947 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
b48cfdff 14948#ifdef MIPS_STRICT_STANDARD
099e5b4d
LA
14949 MIPS_INVAL("PMON / selsl");
14950 generate_exception(ctx, EXCP_RI);
b48cfdff 14951#else
099e5b4d 14952 gen_helper_0e0i(pmon, sa);
b48cfdff 14953#endif
099e5b4d
LA
14954 break;
14955 case OPC_SYSCALL:
14956 generate_exception(ctx, EXCP_SYSCALL);
14957 ctx->bstate = BS_STOP;
14958 break;
14959 case OPC_BREAK:
14960 generate_exception(ctx, EXCP_BREAK);
14961 break;
14962 case OPC_SPIM:
b48cfdff 14963#ifdef MIPS_STRICT_STANDARD
099e5b4d
LA
14964 MIPS_INVAL("SPIM");
14965 generate_exception(ctx, EXCP_RI);
b48cfdff 14966#else
099e5b4d
LA
14967 /* Implemented as RI exception for now. */
14968 MIPS_INVAL("spim (unofficial)");
14969 generate_exception(ctx, EXCP_RI);
b48cfdff 14970#endif
099e5b4d
LA
14971 break;
14972 case OPC_SYNC:
14973 /* Treat as NOP. */
14974 break;
4ad40f36 14975
d26bc211 14976#if defined(TARGET_MIPS64)
099e5b4d
LA
14977 /* MIPS64 specific opcodes */
14978 case OPC_DSLL:
14979 case OPC_DSRA:
14980 case OPC_DSLL32:
14981 case OPC_DSRA32:
14982 check_insn(ctx, ISA_MIPS3);
14983 check_mips_64(ctx);
14984 gen_shift_imm(ctx, op1, rd, rt, sa);
14985 break;
14986 case OPC_DSRL:
14987 switch ((ctx->opcode >> 21) & 0x1f) {
14988 case 1:
14989 /* drotr is decoded as dsrl on non-R2 CPUs */
14990 if (ctx->insn_flags & ISA_MIPS32R2) {
14991 op1 = OPC_DROTR;
ea63e2c3 14992 }
099e5b4d
LA
14993 /* Fallthrough */
14994 case 0:
d75c135e 14995 check_insn(ctx, ISA_MIPS3);
e189e748 14996 check_mips_64(ctx);
099e5b4d 14997 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14998 break;
099e5b4d
LA
14999 default:
15000 generate_exception(ctx, EXCP_RI);
460f00c4 15001 break;
099e5b4d
LA
15002 }
15003 break;
15004 case OPC_DSRL32:
15005 switch ((ctx->opcode >> 21) & 0x1f) {
15006 case 1:
15007 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
15008 if (ctx->insn_flags & ISA_MIPS32R2) {
15009 op1 = OPC_DROTR32;
ea63e2c3 15010 }
099e5b4d
LA
15011 /* Fallthrough */
15012 case 0:
d75c135e 15013 check_insn(ctx, ISA_MIPS3);
e189e748 15014 check_mips_64(ctx);
099e5b4d 15015 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 15016 break;
099e5b4d 15017 default:
6af0bf9c
FB
15018 generate_exception(ctx, EXCP_RI);
15019 break;
15020 }
15021 break;
099e5b4d
LA
15022 case OPC_DADD ... OPC_DSUBU:
15023 check_insn(ctx, ISA_MIPS3);
15024 check_mips_64(ctx);
15025 gen_arith(ctx, op1, rd, rs, rt);
15026 break;
15027 case OPC_DSLLV:
15028 case OPC_DSRAV:
15029 check_insn(ctx, ISA_MIPS3);
15030 check_mips_64(ctx);
15031 gen_shift(ctx, op1, rd, rs, rt);
15032 break;
15033 case OPC_DSRLV:
15034 switch ((ctx->opcode >> 6) & 0x1f) {
15035 case 1:
15036 /* drotrv is decoded as dsrlv on non-R2 CPUs */
15037 if (ctx->insn_flags & ISA_MIPS32R2) {
15038 op1 = OPC_DROTRV;
6af0bf9c 15039 }
099e5b4d
LA
15040 /* Fallthrough */
15041 case 0:
15042 check_insn(ctx, ISA_MIPS3);
e189e748 15043 check_mips_64(ctx);
099e5b4d 15044 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 15045 break;
099e5b4d 15046 default:
6af0bf9c
FB
15047 generate_exception(ctx, EXCP_RI);
15048 break;
15049 }
15050 break;
099e5b4d 15051#endif
10dc65db
LA
15052 default:
15053 if (ctx->insn_flags & ISA_MIPS32R6) {
15054 decode_opc_special_r6(env, ctx);
15055 } else {
15056 decode_opc_special_legacy(env, ctx);
15057 }
15058 }
15059}
15060
15061static void decode_opc_special2_r6(CPUMIPSState *env, DisasContext *ctx)
15062{
15063 uint32_t op1;
15064
15065 op1 = MASK_SPECIAL2(ctx->opcode);
15066 switch (op1) {
099e5b4d 15067 default: /* Invalid */
10dc65db 15068 MIPS_INVAL("special2_r6");
099e5b4d
LA
15069 generate_exception(ctx, EXCP_RI);
15070 break;
15071 }
15072}
6c5c1e20 15073
10dc65db 15074static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
15075{
15076 int rs, rt, rd;
15077 uint32_t op1;
6c5c1e20 15078
099e5b4d
LA
15079 rs = (ctx->opcode >> 21) & 0x1f;
15080 rt = (ctx->opcode >> 16) & 0x1f;
15081 rd = (ctx->opcode >> 11) & 0x1f;
15082
15083 op1 = MASK_SPECIAL2(ctx->opcode);
15084 switch (op1) {
15085 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
15086 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
15087 check_insn(ctx, ISA_MIPS32);
15088 gen_muldiv(ctx, op1, rd & 3, rs, rt);
15089 break;
15090 case OPC_MUL:
099e5b4d
LA
15091 gen_arith(ctx, op1, rd, rs, rt);
15092 break;
fac5a073
LA
15093 case OPC_DIV_G_2F:
15094 case OPC_DIVU_G_2F:
15095 case OPC_MULT_G_2F:
15096 case OPC_MULTU_G_2F:
15097 case OPC_MOD_G_2F:
15098 case OPC_MODU_G_2F:
15099 check_insn(ctx, INSN_LOONGSON2F);
15100 gen_loongson_integer(ctx, op1, rd, rs, rt);
15101 break;
15102#if defined(TARGET_MIPS64)
15103 case OPC_DMULT_G_2F:
15104 case OPC_DMULTU_G_2F:
15105 case OPC_DDIV_G_2F:
15106 case OPC_DDIVU_G_2F:
15107 case OPC_DMOD_G_2F:
15108 case OPC_DMODU_G_2F:
15109 check_insn(ctx, INSN_LOONGSON2F);
15110 gen_loongson_integer(ctx, op1, rd, rs, rt);
15111 break;
15112#endif
10dc65db
LA
15113 default: /* Invalid */
15114 MIPS_INVAL("special2_legacy");
15115 generate_exception(ctx, EXCP_RI);
15116 break;
15117 }
15118}
15119
15120static void decode_opc_special2(CPUMIPSState *env, DisasContext *ctx)
15121{
fac5a073 15122 int rs, rd;
10dc65db
LA
15123 uint32_t op1;
15124
15125 rs = (ctx->opcode >> 21) & 0x1f;
10dc65db
LA
15126 rd = (ctx->opcode >> 11) & 0x1f;
15127
15128 op1 = MASK_SPECIAL2(ctx->opcode);
15129 switch (op1) {
099e5b4d
LA
15130 case OPC_CLO:
15131 case OPC_CLZ:
15132 check_insn(ctx, ISA_MIPS32);
15133 gen_cl(ctx, op1, rd, rs);
15134 break;
15135 case OPC_SDBBP:
15136 /* XXX: not clear which exception should be raised
15137 * when in debug mode...
15138 */
15139 check_insn(ctx, ISA_MIPS32);
15140 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
15141 generate_exception(ctx, EXCP_DBp);
15142 } else {
15143 generate_exception(ctx, EXCP_DBp);
15144 }
15145 /* Treat as NOP. */
15146 break;
9b1a1d68 15147#if defined(TARGET_MIPS64)
099e5b4d
LA
15148 case OPC_DCLO:
15149 case OPC_DCLZ:
15150 check_insn(ctx, ISA_MIPS64);
15151 check_mips_64(ctx);
15152 gen_cl(ctx, op1, rd, rs);
15153 break;
10dc65db
LA
15154#endif
15155 default:
15156 if (ctx->insn_flags & ISA_MIPS32R6) {
15157 decode_opc_special2_r6(env, ctx);
15158 } else {
15159 decode_opc_special2_legacy(env, ctx);
15160 }
15161 }
15162}
15163
15164static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
15165{
15166 int rs, rt;
15167 uint32_t op1;
15168 int16_t imm;
15169
15170 rs = (ctx->opcode >> 21) & 0x1f;
15171 rt = (ctx->opcode >> 16) & 0x1f;
15172 imm = (int16_t)ctx->opcode >> 7;
15173
15174 op1 = MASK_SPECIAL3(ctx->opcode);
15175 switch (op1) {
bf7910c6
LA
15176 case R6_OPC_PREF:
15177 if (rt >= 24) {
15178 /* hint codes 24-31 are reserved and signal RI */
15179 generate_exception(ctx, EXCP_RI);
15180 }
15181 /* Treat as NOP. */
15182 break;
15183 case R6_OPC_CACHE:
15184 /* Treat as NOP. */
15185 break;
10dc65db
LA
15186 case R6_OPC_SC:
15187 gen_st_cond(ctx, op1, rt, rs, imm);
15188 break;
15189 case R6_OPC_LL:
15190 gen_ld(ctx, op1, rt, rs, imm);
15191 break;
bf7910c6
LA
15192#if defined(TARGET_MIPS64)
15193 case R6_OPC_SCD:
15194 gen_st_cond(ctx, op1, rt, rs, imm);
15195 break;
15196 case R6_OPC_LLD:
15197 gen_ld(ctx, op1, rt, rs, imm);
15198 break;
15199#endif
10dc65db
LA
15200 default: /* Invalid */
15201 MIPS_INVAL("special3_r6");
15202 generate_exception(ctx, EXCP_RI);
15203 break;
15204 }
15205}
15206
15207static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
15208{
fac5a073 15209 int rs, rt, rd;
099e5b4d 15210 uint32_t op1, op2;
099e5b4d
LA
15211
15212 rs = (ctx->opcode >> 21) & 0x1f;
15213 rt = (ctx->opcode >> 16) & 0x1f;
15214 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
15215
15216 op1 = MASK_SPECIAL3(ctx->opcode);
15217 switch (op1) {
099e5b4d
LA
15218 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
15219 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
15220 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
15221 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15222 * the same mask and op1. */
15223 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
15224 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 15225 switch (op2) {
099e5b4d
LA
15226 case OPC_ADDUH_QB:
15227 case OPC_ADDUH_R_QB:
15228 case OPC_ADDQH_PH:
15229 case OPC_ADDQH_R_PH:
15230 case OPC_ADDQH_W:
15231 case OPC_ADDQH_R_W:
15232 case OPC_SUBUH_QB:
15233 case OPC_SUBUH_R_QB:
15234 case OPC_SUBQH_PH:
15235 case OPC_SUBQH_R_PH:
15236 case OPC_SUBQH_W:
15237 case OPC_SUBQH_R_W:
461c08df
JL
15238 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15239 break;
099e5b4d
LA
15240 case OPC_MUL_PH:
15241 case OPC_MUL_S_PH:
15242 case OPC_MULQ_S_W:
15243 case OPC_MULQ_RS_W:
15244 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 15245 break;
461c08df 15246 default:
099e5b4d 15247 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
15248 generate_exception(ctx, EXCP_RI);
15249 break;
15250 }
099e5b4d
LA
15251 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
15252 gen_loongson_integer(ctx, op1, rd, rs, rt);
15253 } else {
15254 generate_exception(ctx, EXCP_RI);
15255 }
15256 break;
15257 case OPC_LX_DSP:
15258 op2 = MASK_LX(ctx->opcode);
15259 switch (op2) {
15260#if defined(TARGET_MIPS64)
15261 case OPC_LDX:
15262#endif
15263 case OPC_LBUX:
15264 case OPC_LHX:
15265 case OPC_LWX:
15266 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
15267 break;
15268 default: /* Invalid */
15269 MIPS_INVAL("MASK LX");
15270 generate_exception(ctx, EXCP_RI);
15271 break;
15272 }
15273 break;
15274 case OPC_ABSQ_S_PH_DSP:
15275 op2 = MASK_ABSQ_S_PH(ctx->opcode);
15276 switch (op2) {
15277 case OPC_ABSQ_S_QB:
15278 case OPC_ABSQ_S_PH:
15279 case OPC_ABSQ_S_W:
15280 case OPC_PRECEQ_W_PHL:
15281 case OPC_PRECEQ_W_PHR:
15282 case OPC_PRECEQU_PH_QBL:
15283 case OPC_PRECEQU_PH_QBR:
15284 case OPC_PRECEQU_PH_QBLA:
15285 case OPC_PRECEQU_PH_QBRA:
15286 case OPC_PRECEU_PH_QBL:
15287 case OPC_PRECEU_PH_QBR:
15288 case OPC_PRECEU_PH_QBLA:
15289 case OPC_PRECEU_PH_QBRA:
15290 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15291 break;
15292 case OPC_BITREV:
15293 case OPC_REPL_QB:
15294 case OPC_REPLV_QB:
15295 case OPC_REPL_PH:
15296 case OPC_REPLV_PH:
15297 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15298 break;
15299 default:
15300 MIPS_INVAL("MASK ABSQ_S.PH");
15301 generate_exception(ctx, EXCP_RI);
15302 break;
15303 }
15304 break;
15305 case OPC_ADDU_QB_DSP:
15306 op2 = MASK_ADDU_QB(ctx->opcode);
15307 switch (op2) {
15308 case OPC_ADDQ_PH:
15309 case OPC_ADDQ_S_PH:
15310 case OPC_ADDQ_S_W:
15311 case OPC_ADDU_QB:
15312 case OPC_ADDU_S_QB:
15313 case OPC_ADDU_PH:
15314 case OPC_ADDU_S_PH:
15315 case OPC_SUBQ_PH:
15316 case OPC_SUBQ_S_PH:
15317 case OPC_SUBQ_S_W:
15318 case OPC_SUBU_QB:
15319 case OPC_SUBU_S_QB:
15320 case OPC_SUBU_PH:
15321 case OPC_SUBU_S_PH:
15322 case OPC_ADDSC:
15323 case OPC_ADDWC:
15324 case OPC_MODSUB:
15325 case OPC_RADDU_W_QB:
15326 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15327 break;
15328 case OPC_MULEU_S_PH_QBL:
15329 case OPC_MULEU_S_PH_QBR:
15330 case OPC_MULQ_RS_PH:
15331 case OPC_MULEQ_S_W_PHL:
15332 case OPC_MULEQ_S_W_PHR:
15333 case OPC_MULQ_S_PH:
15334 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15335 break;
15336 default: /* Invalid */
15337 MIPS_INVAL("MASK ADDU.QB");
15338 generate_exception(ctx, EXCP_RI);
461c08df 15339 break;
461c08df 15340
099e5b4d
LA
15341 }
15342 break;
15343 case OPC_CMPU_EQ_QB_DSP:
15344 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
15345 switch (op2) {
15346 case OPC_PRECR_SRA_PH_W:
15347 case OPC_PRECR_SRA_R_PH_W:
15348 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 15349 break;
099e5b4d
LA
15350 case OPC_PRECR_QB_PH:
15351 case OPC_PRECRQ_QB_PH:
15352 case OPC_PRECRQ_PH_W:
15353 case OPC_PRECRQ_RS_PH_W:
15354 case OPC_PRECRQU_S_QB_PH:
15355 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 15356 break;
099e5b4d
LA
15357 case OPC_CMPU_EQ_QB:
15358 case OPC_CMPU_LT_QB:
15359 case OPC_CMPU_LE_QB:
15360 case OPC_CMP_EQ_PH:
15361 case OPC_CMP_LT_PH:
15362 case OPC_CMP_LE_PH:
15363 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 15364 break;
099e5b4d
LA
15365 case OPC_CMPGU_EQ_QB:
15366 case OPC_CMPGU_LT_QB:
15367 case OPC_CMPGU_LE_QB:
15368 case OPC_CMPGDU_EQ_QB:
15369 case OPC_CMPGDU_LT_QB:
15370 case OPC_CMPGDU_LE_QB:
15371 case OPC_PICK_QB:
15372 case OPC_PICK_PH:
15373 case OPC_PACKRL_PH:
15374 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15375 break;
15376 default: /* Invalid */
15377 MIPS_INVAL("MASK CMPU.EQ.QB");
15378 generate_exception(ctx, EXCP_RI);
15379 break;
15380 }
15381 break;
15382 case OPC_SHLL_QB_DSP:
15383 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15384 break;
15385 case OPC_DPA_W_PH_DSP:
15386 op2 = MASK_DPA_W_PH(ctx->opcode);
15387 switch (op2) {
15388 case OPC_DPAU_H_QBL:
15389 case OPC_DPAU_H_QBR:
15390 case OPC_DPSU_H_QBL:
15391 case OPC_DPSU_H_QBR:
15392 case OPC_DPA_W_PH:
15393 case OPC_DPAX_W_PH:
15394 case OPC_DPAQ_S_W_PH:
15395 case OPC_DPAQX_S_W_PH:
15396 case OPC_DPAQX_SA_W_PH:
15397 case OPC_DPS_W_PH:
15398 case OPC_DPSX_W_PH:
15399 case OPC_DPSQ_S_W_PH:
15400 case OPC_DPSQX_S_W_PH:
15401 case OPC_DPSQX_SA_W_PH:
15402 case OPC_MULSAQ_S_W_PH:
15403 case OPC_DPAQ_SA_L_W:
15404 case OPC_DPSQ_SA_L_W:
15405 case OPC_MAQ_S_W_PHL:
15406 case OPC_MAQ_S_W_PHR:
15407 case OPC_MAQ_SA_W_PHL:
15408 case OPC_MAQ_SA_W_PHR:
15409 case OPC_MULSA_W_PH:
15410 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15411 break;
15412 default: /* Invalid */
15413 MIPS_INVAL("MASK DPAW.PH");
15414 generate_exception(ctx, EXCP_RI);
15415 break;
15416 }
15417 break;
15418 case OPC_INSV_DSP:
15419 op2 = MASK_INSV(ctx->opcode);
15420 switch (op2) {
15421 case OPC_INSV:
15422 check_dsp(ctx);
15423 {
15424 TCGv t0, t1;
15425
15426 if (rt == 0) {
15427 MIPS_DEBUG("NOP");
15428 break;
15429 }
15430
15431 t0 = tcg_temp_new();
15432 t1 = tcg_temp_new();
15433
15434 gen_load_gpr(t0, rt);
15435 gen_load_gpr(t1, rs);
15436
15437 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
15438
15439 tcg_temp_free(t0);
15440 tcg_temp_free(t1);
a22260ae
JL
15441 break;
15442 }
099e5b4d
LA
15443 default: /* Invalid */
15444 MIPS_INVAL("MASK INSV");
15445 generate_exception(ctx, EXCP_RI);
15446 break;
15447 }
15448 break;
15449 case OPC_APPEND_DSP:
15450 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15451 break;
15452 case OPC_EXTR_W_DSP:
15453 op2 = MASK_EXTR_W(ctx->opcode);
15454 switch (op2) {
15455 case OPC_EXTR_W:
15456 case OPC_EXTR_R_W:
15457 case OPC_EXTR_RS_W:
15458 case OPC_EXTR_S_H:
15459 case OPC_EXTRV_S_H:
15460 case OPC_EXTRV_W:
15461 case OPC_EXTRV_R_W:
15462 case OPC_EXTRV_RS_W:
15463 case OPC_EXTP:
15464 case OPC_EXTPV:
15465 case OPC_EXTPDP:
15466 case OPC_EXTPDPV:
15467 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15468 break;
15469 case OPC_RDDSP:
15470 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
15471 break;
15472 case OPC_SHILO:
15473 case OPC_SHILOV:
15474 case OPC_MTHLIP:
15475 case OPC_WRDSP:
15476 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15477 break;
15478 default: /* Invalid */
15479 MIPS_INVAL("MASK EXTR.W");
15480 generate_exception(ctx, EXCP_RI);
15481 break;
15482 }
15483 break;
099e5b4d 15484#if defined(TARGET_MIPS64)
fac5a073
LA
15485 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15486 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15487 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15488 check_insn(ctx, INSN_LOONGSON2E);
15489 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 15490 break;
099e5b4d
LA
15491 case OPC_ABSQ_S_QH_DSP:
15492 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15493 switch (op2) {
15494 case OPC_PRECEQ_L_PWL:
15495 case OPC_PRECEQ_L_PWR:
15496 case OPC_PRECEQ_PW_QHL:
15497 case OPC_PRECEQ_PW_QHR:
15498 case OPC_PRECEQ_PW_QHLA:
15499 case OPC_PRECEQ_PW_QHRA:
15500 case OPC_PRECEQU_QH_OBL:
15501 case OPC_PRECEQU_QH_OBR:
15502 case OPC_PRECEQU_QH_OBLA:
15503 case OPC_PRECEQU_QH_OBRA:
15504 case OPC_PRECEU_QH_OBL:
15505 case OPC_PRECEU_QH_OBR:
15506 case OPC_PRECEU_QH_OBLA:
15507 case OPC_PRECEU_QH_OBRA:
15508 case OPC_ABSQ_S_OB:
15509 case OPC_ABSQ_S_PW:
15510 case OPC_ABSQ_S_QH:
15511 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15512 break;
15513 case OPC_REPL_OB:
15514 case OPC_REPL_PW:
15515 case OPC_REPL_QH:
15516 case OPC_REPLV_OB:
15517 case OPC_REPLV_PW:
15518 case OPC_REPLV_QH:
15519 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15520 break;
15521 default: /* Invalid */
15522 MIPS_INVAL("MASK ABSQ_S.QH");
15523 generate_exception(ctx, EXCP_RI);
15524 break;
15525 }
15526 break;
15527 case OPC_ADDU_OB_DSP:
15528 op2 = MASK_ADDU_OB(ctx->opcode);
15529 switch (op2) {
15530 case OPC_RADDU_L_OB:
15531 case OPC_SUBQ_PW:
15532 case OPC_SUBQ_S_PW:
15533 case OPC_SUBQ_QH:
15534 case OPC_SUBQ_S_QH:
15535 case OPC_SUBU_OB:
15536 case OPC_SUBU_S_OB:
15537 case OPC_SUBU_QH:
15538 case OPC_SUBU_S_QH:
15539 case OPC_SUBUH_OB:
15540 case OPC_SUBUH_R_OB:
15541 case OPC_ADDQ_PW:
15542 case OPC_ADDQ_S_PW:
15543 case OPC_ADDQ_QH:
15544 case OPC_ADDQ_S_QH:
15545 case OPC_ADDU_OB:
15546 case OPC_ADDU_S_OB:
15547 case OPC_ADDU_QH:
15548 case OPC_ADDU_S_QH:
15549 case OPC_ADDUH_OB:
15550 case OPC_ADDUH_R_OB:
15551 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 15552 break;
099e5b4d
LA
15553 case OPC_MULEQ_S_PW_QHL:
15554 case OPC_MULEQ_S_PW_QHR:
15555 case OPC_MULEU_S_QH_OBL:
15556 case OPC_MULEU_S_QH_OBR:
15557 case OPC_MULQ_RS_QH:
15558 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 15559 break;
099e5b4d
LA
15560 default: /* Invalid */
15561 MIPS_INVAL("MASK ADDU.OB");
15562 generate_exception(ctx, EXCP_RI);
26690560 15563 break;
099e5b4d
LA
15564 }
15565 break;
15566 case OPC_CMPU_EQ_OB_DSP:
15567 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15568 switch (op2) {
15569 case OPC_PRECR_SRA_QH_PW:
15570 case OPC_PRECR_SRA_R_QH_PW:
15571 /* Return value is rt. */
15572 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 15573 break;
099e5b4d
LA
15574 case OPC_PRECR_OB_QH:
15575 case OPC_PRECRQ_OB_QH:
15576 case OPC_PRECRQ_PW_L:
15577 case OPC_PRECRQ_QH_PW:
15578 case OPC_PRECRQ_RS_QH_PW:
15579 case OPC_PRECRQU_S_OB_QH:
15580 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 15581 break;
099e5b4d
LA
15582 case OPC_CMPU_EQ_OB:
15583 case OPC_CMPU_LT_OB:
15584 case OPC_CMPU_LE_OB:
15585 case OPC_CMP_EQ_QH:
15586 case OPC_CMP_LT_QH:
15587 case OPC_CMP_LE_QH:
15588 case OPC_CMP_EQ_PW:
15589 case OPC_CMP_LT_PW:
15590 case OPC_CMP_LE_PW:
15591 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 15592 break;
099e5b4d
LA
15593 case OPC_CMPGDU_EQ_OB:
15594 case OPC_CMPGDU_LT_OB:
15595 case OPC_CMPGDU_LE_OB:
15596 case OPC_CMPGU_EQ_OB:
15597 case OPC_CMPGU_LT_OB:
15598 case OPC_CMPGU_LE_OB:
15599 case OPC_PACKRL_PW:
15600 case OPC_PICK_OB:
15601 case OPC_PICK_PW:
15602 case OPC_PICK_QH:
15603 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 15604 break;
099e5b4d
LA
15605 default: /* Invalid */
15606 MIPS_INVAL("MASK CMPU_EQ.OB");
15607 generate_exception(ctx, EXCP_RI);
161f85e6 15608 break;
099e5b4d
LA
15609 }
15610 break;
15611 case OPC_DAPPEND_DSP:
15612 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15613 break;
15614 case OPC_DEXTR_W_DSP:
15615 op2 = MASK_DEXTR_W(ctx->opcode);
15616 switch (op2) {
15617 case OPC_DEXTP:
15618 case OPC_DEXTPDP:
15619 case OPC_DEXTPDPV:
15620 case OPC_DEXTPV:
15621 case OPC_DEXTR_L:
15622 case OPC_DEXTR_R_L:
15623 case OPC_DEXTR_RS_L:
15624 case OPC_DEXTR_W:
15625 case OPC_DEXTR_R_W:
15626 case OPC_DEXTR_RS_W:
15627 case OPC_DEXTR_S_H:
15628 case OPC_DEXTRV_L:
15629 case OPC_DEXTRV_R_L:
15630 case OPC_DEXTRV_RS_L:
15631 case OPC_DEXTRV_S_H:
15632 case OPC_DEXTRV_W:
15633 case OPC_DEXTRV_R_W:
15634 case OPC_DEXTRV_RS_W:
15635 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 15636 break;
099e5b4d
LA
15637 case OPC_DMTHLIP:
15638 case OPC_DSHILO:
15639 case OPC_DSHILOV:
15640 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 15641 break;
099e5b4d
LA
15642 default: /* Invalid */
15643 MIPS_INVAL("MASK EXTR.W");
15644 generate_exception(ctx, EXCP_RI);
461c08df 15645 break;
099e5b4d
LA
15646 }
15647 break;
15648 case OPC_DPAQ_W_QH_DSP:
15649 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15650 switch (op2) {
15651 case OPC_DPAU_H_OBL:
15652 case OPC_DPAU_H_OBR:
15653 case OPC_DPSU_H_OBL:
15654 case OPC_DPSU_H_OBR:
15655 case OPC_DPA_W_QH:
15656 case OPC_DPAQ_S_W_QH:
15657 case OPC_DPS_W_QH:
15658 case OPC_DPSQ_S_W_QH:
15659 case OPC_MULSAQ_S_W_QH:
15660 case OPC_DPAQ_SA_L_PW:
15661 case OPC_DPSQ_SA_L_PW:
15662 case OPC_MULSAQ_S_L_PW:
15663 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15664 break;
15665 case OPC_MAQ_S_W_QHLL:
15666 case OPC_MAQ_S_W_QHLR:
15667 case OPC_MAQ_S_W_QHRL:
15668 case OPC_MAQ_S_W_QHRR:
15669 case OPC_MAQ_SA_W_QHLL:
15670 case OPC_MAQ_SA_W_QHLR:
15671 case OPC_MAQ_SA_W_QHRL:
15672 case OPC_MAQ_SA_W_QHRR:
15673 case OPC_MAQ_S_L_PWL:
15674 case OPC_MAQ_S_L_PWR:
15675 case OPC_DMADD:
15676 case OPC_DMADDU:
15677 case OPC_DMSUB:
15678 case OPC_DMSUBU:
15679 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 15680 break;
099e5b4d
LA
15681 default: /* Invalid */
15682 MIPS_INVAL("MASK DPAQ.W.QH");
15683 generate_exception(ctx, EXCP_RI);
b53371ed 15684 break;
099e5b4d
LA
15685 }
15686 break;
15687 case OPC_DINSV_DSP:
15688 op2 = MASK_INSV(ctx->opcode);
15689 switch (op2) {
15690 case OPC_DINSV:
15691 {
15692 TCGv t0, t1;
15693
15694 if (rt == 0) {
15695 MIPS_DEBUG("NOP");
a22260ae
JL
15696 break;
15697 }
099e5b4d 15698 check_dsp(ctx);
1cb6686c 15699
099e5b4d
LA
15700 t0 = tcg_temp_new();
15701 t1 = tcg_temp_new();
1cb6686c 15702
099e5b4d
LA
15703 gen_load_gpr(t0, rt);
15704 gen_load_gpr(t1, rs);
1cb6686c 15705
099e5b4d 15706 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 15707
099e5b4d
LA
15708 tcg_temp_free(t0);
15709 tcg_temp_free(t1);
77c5fa8b 15710 break;
099e5b4d 15711 }
7a387fff 15712 default: /* Invalid */
099e5b4d 15713 MIPS_INVAL("MASK DINSV");
7a387fff
TS
15714 generate_exception(ctx, EXCP_RI);
15715 break;
15716 }
15717 break;
099e5b4d
LA
15718 case OPC_SHLL_OB_DSP:
15719 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15720 break;
15721#endif
fac5a073
LA
15722 default: /* Invalid */
15723 MIPS_INVAL("special3_legacy");
15724 generate_exception(ctx, EXCP_RI);
15725 break;
15726 }
15727}
15728
15729static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15730{
15731 int rs, rt, rd, sa;
15732 uint32_t op1, op2;
15733
15734 rs = (ctx->opcode >> 21) & 0x1f;
15735 rt = (ctx->opcode >> 16) & 0x1f;
15736 rd = (ctx->opcode >> 11) & 0x1f;
15737 sa = (ctx->opcode >> 6) & 0x1f;
15738
15739 op1 = MASK_SPECIAL3(ctx->opcode);
15740 switch (op1) {
15741 case OPC_EXT:
15742 case OPC_INS:
15743 check_insn(ctx, ISA_MIPS32R2);
15744 gen_bitops(ctx, op1, rt, rs, sa, rd);
15745 break;
15746 case OPC_BSHFL:
15747 check_insn(ctx, ISA_MIPS32R2);
15748 op2 = MASK_BSHFL(ctx->opcode);
15749 gen_bshfl(ctx, op2, rt, rd);
15750 break;
15751#if defined(TARGET_MIPS64)
15752 case OPC_DEXTM ... OPC_DEXT:
15753 case OPC_DINSM ... OPC_DINS:
15754 check_insn(ctx, ISA_MIPS64R2);
15755 check_mips_64(ctx);
15756 gen_bitops(ctx, op1, rt, rs, sa, rd);
15757 break;
15758 case OPC_DBSHFL:
15759 check_insn(ctx, ISA_MIPS64R2);
15760 check_mips_64(ctx);
15761 op2 = MASK_DBSHFL(ctx->opcode);
15762 gen_bshfl(ctx, op2, rt, rd);
15763 break;
15764#endif
15765 case OPC_RDHWR:
15766 gen_rdhwr(ctx, rt, rd);
15767 break;
15768 case OPC_FORK:
15769 check_insn(ctx, ASE_MT);
15770 {
15771 TCGv t0 = tcg_temp_new();
15772 TCGv t1 = tcg_temp_new();
15773
15774 gen_load_gpr(t0, rt);
15775 gen_load_gpr(t1, rs);
15776 gen_helper_fork(t0, t1);
15777 tcg_temp_free(t0);
15778 tcg_temp_free(t1);
15779 }
15780 break;
15781 case OPC_YIELD:
15782 check_insn(ctx, ASE_MT);
15783 {
15784 TCGv t0 = tcg_temp_new();
15785
15786 save_cpu_state(ctx, 1);
15787 gen_load_gpr(t0, rs);
15788 gen_helper_yield(t0, cpu_env, t0);
15789 gen_store_gpr(t0, rd);
15790 tcg_temp_free(t0);
15791 }
15792 break;
10dc65db
LA
15793 default:
15794 if (ctx->insn_flags & ISA_MIPS32R6) {
15795 decode_opc_special3_r6(env, ctx);
15796 } else {
15797 decode_opc_special3_legacy(env, ctx);
15798 }
099e5b4d
LA
15799 }
15800}
15801
15802static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
15803{
15804 int32_t offset;
15805 int rs, rt, rd, sa;
15806 uint32_t op, op1;
15807 int16_t imm;
15808
15809 /* make sure instructions are on a word boundary */
15810 if (ctx->pc & 0x3) {
15811 env->CP0_BadVAddr = ctx->pc;
15812 generate_exception(ctx, EXCP_AdEL);
15813 return;
15814 }
15815
15816 /* Handle blikely not taken case */
15817 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15818 int l1 = gen_new_label();
15819
15820 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
15821 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15822 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15823 gen_goto_tb(ctx, 1, ctx->pc + 4);
15824 gen_set_label(l1);
15825 }
15826
15827 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
15828 tcg_gen_debug_insn_start(ctx->pc);
15829 }
15830
15831 op = MASK_OP_MAJOR(ctx->opcode);
15832 rs = (ctx->opcode >> 21) & 0x1f;
15833 rt = (ctx->opcode >> 16) & 0x1f;
15834 rd = (ctx->opcode >> 11) & 0x1f;
15835 sa = (ctx->opcode >> 6) & 0x1f;
15836 imm = (int16_t)ctx->opcode;
15837 switch (op) {
15838 case OPC_SPECIAL:
15839 decode_opc_special(env, ctx);
15840 break;
15841 case OPC_SPECIAL2:
15842 decode_opc_special2(env, ctx);
15843 break;
15844 case OPC_SPECIAL3:
15845 decode_opc_special3(env, ctx);
15846 break;
7a387fff
TS
15847 case OPC_REGIMM:
15848 op1 = MASK_REGIMM(ctx->opcode);
15849 switch (op1) {
fecd2646
LA
15850 case OPC_BLTZL: /* REGIMM branches */
15851 case OPC_BGEZL:
15852 case OPC_BLTZALL:
15853 case OPC_BGEZALL:
15854 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15855 case OPC_BLTZ:
15856 case OPC_BGEZ:
15857 case OPC_BLTZAL:
15858 case OPC_BGEZAL:
7dca4ad0 15859 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061 15860 break;
7a387fff
TS
15861 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15862 case OPC_TNEI:
fecd2646 15863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
15864 gen_trap(ctx, op1, rs, -1, imm);
15865 break;
15866 case OPC_SYNCI:
d75c135e 15867 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15868 /* Treat as NOP. */
6af0bf9c 15869 break;
e45a93e2
JL
15870 case OPC_BPOSGE32: /* MIPS DSP branch */
15871#if defined(TARGET_MIPS64)
15872 case OPC_BPOSGE64:
15873#endif
15874 check_dsp(ctx);
15875 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
e45a93e2 15876 break;
6af0bf9c 15877 default: /* Invalid */
923617a3 15878 MIPS_INVAL("regimm");
6af0bf9c
FB
15879 generate_exception(ctx, EXCP_RI);
15880 break;
15881 }
15882 break;
7a387fff 15883 case OPC_CP0:
387a8fe5 15884 check_cp0_enabled(ctx);
7a387fff 15885 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15886 switch (op1) {
7a387fff
TS
15887 case OPC_MFC0:
15888 case OPC_MTC0:
ead9360e
TS
15889 case OPC_MFTR:
15890 case OPC_MTTR:
d26bc211 15891#if defined(TARGET_MIPS64)
7a387fff
TS
15892 case OPC_DMFC0:
15893 case OPC_DMTC0:
15894#endif
f1aa6320 15895#ifndef CONFIG_USER_ONLY
932e71cd 15896 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15897#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15898 break;
15899 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15900#ifndef CONFIG_USER_ONLY
932e71cd 15901 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15902#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15903 break;
15904 case OPC_MFMC0:
8706c382 15905#ifndef CONFIG_USER_ONLY
932e71cd 15906 {
099e5b4d 15907 uint32_t op2;
35fbce2c 15908 TCGv t0 = tcg_temp_new();
6c5c1e20 15909
0eaef5aa 15910 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15911 switch (op2) {
15912 case OPC_DMT:
d75c135e 15913 check_insn(ctx, ASE_MT);
9ed5726c 15914 gen_helper_dmt(t0);
35fbce2c 15915 gen_store_gpr(t0, rt);
6c5c1e20
TS
15916 break;
15917 case OPC_EMT:
d75c135e 15918 check_insn(ctx, ASE_MT);
9ed5726c 15919 gen_helper_emt(t0);
35fbce2c 15920 gen_store_gpr(t0, rt);
da80682b 15921 break;
6c5c1e20 15922 case OPC_DVPE:
d75c135e 15923 check_insn(ctx, ASE_MT);
895c2d04 15924 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15925 gen_store_gpr(t0, rt);
6c5c1e20
TS
15926 break;
15927 case OPC_EVPE:
d75c135e 15928 check_insn(ctx, ASE_MT);
895c2d04 15929 gen_helper_evpe(t0, cpu_env);
35fbce2c 15930 gen_store_gpr(t0, rt);
6c5c1e20
TS
15931 break;
15932 case OPC_DI:
d75c135e 15933 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15934 save_cpu_state(ctx, 1);
895c2d04 15935 gen_helper_di(t0, cpu_env);
35fbce2c 15936 gen_store_gpr(t0, rt);
6c5c1e20
TS
15937 /* Stop translation as we may have switched the execution mode */
15938 ctx->bstate = BS_STOP;
15939 break;
15940 case OPC_EI:
d75c135e 15941 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15942 save_cpu_state(ctx, 1);
895c2d04 15943 gen_helper_ei(t0, cpu_env);
35fbce2c 15944 gen_store_gpr(t0, rt);
6c5c1e20
TS
15945 /* Stop translation as we may have switched the execution mode */
15946 ctx->bstate = BS_STOP;
15947 break;
15948 default: /* Invalid */
15949 MIPS_INVAL("mfmc0");
15950 generate_exception(ctx, EXCP_RI);
15951 break;
15952 }
6c5c1e20 15953 tcg_temp_free(t0);
7a387fff 15954 }
0eaef5aa 15955#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15956 break;
7a387fff 15957 case OPC_RDPGPR:
d75c135e 15958 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15959 gen_load_srsgpr(rt, rd);
ead9360e 15960 break;
7a387fff 15961 case OPC_WRPGPR:
d75c135e 15962 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15963 gen_store_srsgpr(rt, rd);
38121543 15964 break;
6af0bf9c 15965 default:
923617a3 15966 MIPS_INVAL("cp0");
7a387fff 15967 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15968 break;
15969 }
15970 break;
324d9e32
AJ
15971 case OPC_ADDI: /* Arithmetic with immediate opcode */
15972 case OPC_ADDIU:
d75c135e 15973 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15974 break;
324d9e32
AJ
15975 case OPC_SLTI: /* Set on less than with immediate opcode */
15976 case OPC_SLTIU:
d75c135e 15977 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15978 break;
15979 case OPC_ANDI: /* Arithmetic with immediate opcode */
15980 case OPC_LUI:
15981 case OPC_ORI:
15982 case OPC_XORI:
d75c135e 15983 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15984 break;
7a387fff
TS
15985 case OPC_J ... OPC_JAL: /* Jump */
15986 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15987 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061 15988 break;
fecd2646
LA
15989 case OPC_BEQL ... OPC_BGTZL: /* Branch */
15990 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15991 case OPC_BEQ ... OPC_BGTZ:
7dca4ad0 15992 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061 15993 break;
fecd2646
LA
15994 case OPC_LWL: /* Load and stores */
15995 case OPC_LWR:
4368b29a 15996 case OPC_LL:
fecd2646
LA
15997 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15998 case OPC_LB ... OPC_LH:
15999 case OPC_LW ... OPC_LHU:
d75c135e 16000 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 16001 break;
fecd2646 16002 case OPC_SWL:
7a387fff 16003 case OPC_SWR:
fecd2646
LA
16004 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16005 case OPC_SB ... OPC_SH:
16006 case OPC_SW:
5c13fdfd 16007 gen_st(ctx, op, rt, rs, imm);
7a387fff 16008 break;
d66c7132 16009 case OPC_SC:
4368b29a 16010 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
16011 gen_st_cond(ctx, op, rt, rs, imm);
16012 break;
7a387fff 16013 case OPC_CACHE:
bf7910c6 16014 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 16015 check_cp0_enabled(ctx);
d75c135e 16016 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 16017 /* Treat as NOP. */
34ae7b51 16018 break;
7a387fff 16019 case OPC_PREF:
bf7910c6 16020 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 16021 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 16022 /* Treat as NOP. */
6af0bf9c 16023 break;
4ad40f36 16024
923617a3 16025 /* Floating point (COP1). */
7a387fff
TS
16026 case OPC_LWC1:
16027 case OPC_LDC1:
16028 case OPC_SWC1:
16029 case OPC_SDC1:
5ab5c041 16030 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
16031 break;
16032
7a387fff 16033 case OPC_CP1:
5ab5c041 16034 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 16035 check_cp1_enabled(ctx);
36d23958
TS
16036 op1 = MASK_CP1(ctx->opcode);
16037 switch (op1) {
3a95e3a7
TS
16038 case OPC_MFHC1:
16039 case OPC_MTHC1:
d75c135e 16040 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
16041 case OPC_MFC1:
16042 case OPC_CFC1:
16043 case OPC_MTC1:
16044 case OPC_CTC1:
e189e748
TS
16045 gen_cp1(ctx, op1, rt, rd);
16046 break;
d26bc211 16047#if defined(TARGET_MIPS64)
36d23958
TS
16048 case OPC_DMFC1:
16049 case OPC_DMTC1:
d75c135e 16050 check_insn(ctx, ISA_MIPS3);
36d23958
TS
16051 gen_cp1(ctx, op1, rt, rd);
16052 break;
e189e748 16053#endif
fbcc6828
TS
16054 case OPC_BC1ANY2:
16055 case OPC_BC1ANY4:
fecd2646 16056 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b8aa4598 16057 check_cop1x(ctx);
d75c135e 16058 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
16059 /* fall through */
16060 case OPC_BC1:
fecd2646 16061 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 16062 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 16063 (rt >> 2) & 0x7, imm << 2);
c9602061 16064 break;
fecd2646
LA
16065 case OPC_PS_FMT:
16066 check_insn_opc_removed(ctx, ISA_MIPS32R6);
36d23958
TS
16067 case OPC_S_FMT:
16068 case OPC_D_FMT:
16069 case OPC_W_FMT:
16070 case OPC_L_FMT:
bf4120ad 16071 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 16072 (imm >> 8) & 0x7);
36d23958
TS
16073 break;
16074 default:
923617a3 16075 MIPS_INVAL("cp1");
e397ee33 16076 generate_exception (ctx, EXCP_RI);
36d23958
TS
16077 break;
16078 }
16079 } else {
16080 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 16081 }
4ad40f36
FB
16082 break;
16083
16084 /* COP2. */
7a387fff
TS
16085 case OPC_LWC2:
16086 case OPC_LDC2:
16087 case OPC_SWC2:
16088 case OPC_SDC2:
7a387fff 16089 /* COP2: Not implemented. */
4ad40f36
FB
16090 generate_exception_err(ctx, EXCP_CpU, 2);
16091 break;
bd277fa1 16092 case OPC_CP2:
d75c135e 16093 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
16094 /* Note that these instructions use different fields. */
16095 gen_loongson_multimedia(ctx, sa, rd, rt);
16096 break;
4ad40f36 16097
7a387fff 16098 case OPC_CP3:
fecd2646 16099 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 16100 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 16101 check_cp1_enabled(ctx);
36d23958
TS
16102 op1 = MASK_CP3(ctx->opcode);
16103 switch (op1) {
5a5012ec
TS
16104 case OPC_LWXC1:
16105 case OPC_LDXC1:
16106 case OPC_LUXC1:
16107 case OPC_SWXC1:
16108 case OPC_SDXC1:
16109 case OPC_SUXC1:
93b12ccc 16110 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 16111 break;
e0c84da7 16112 case OPC_PREFX:
ead9360e 16113 /* Treat as NOP. */
e0c84da7 16114 break;
5a5012ec
TS
16115 case OPC_ALNV_PS:
16116 case OPC_MADD_S:
16117 case OPC_MADD_D:
16118 case OPC_MADD_PS:
16119 case OPC_MSUB_S:
16120 case OPC_MSUB_D:
16121 case OPC_MSUB_PS:
16122 case OPC_NMADD_S:
16123 case OPC_NMADD_D:
16124 case OPC_NMADD_PS:
16125 case OPC_NMSUB_S:
16126 case OPC_NMSUB_D:
16127 case OPC_NMSUB_PS:
16128 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
16129 break;
36d23958 16130 default:
923617a3 16131 MIPS_INVAL("cp3");
e397ee33 16132 generate_exception (ctx, EXCP_RI);
36d23958
TS
16133 break;
16134 }
16135 } else {
e397ee33 16136 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 16137 }
4ad40f36
FB
16138 break;
16139
d26bc211 16140#if defined(TARGET_MIPS64)
7a387fff 16141 /* MIPS64 opcodes */
7a387fff 16142 case OPC_LDL ... OPC_LDR:
bf7910c6 16143 case OPC_LLD:
fecd2646
LA
16144 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16145 case OPC_LWU:
7a387fff 16146 case OPC_LD:
d75c135e 16147 check_insn(ctx, ISA_MIPS3);
5c13fdfd 16148 check_mips_64(ctx);
d75c135e 16149 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
16150 break;
16151 case OPC_SDL ... OPC_SDR:
fecd2646 16152 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff 16153 case OPC_SD:
d75c135e 16154 check_insn(ctx, ISA_MIPS3);
e189e748 16155 check_mips_64(ctx);
5c13fdfd 16156 gen_st(ctx, op, rt, rs, imm);
7a387fff 16157 break;
d66c7132 16158 case OPC_SCD:
bf7910c6 16159 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 16160 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
16161 check_mips_64(ctx);
16162 gen_st_cond(ctx, op, rt, rs, imm);
16163 break;
324d9e32
AJ
16164 case OPC_DADDI:
16165 case OPC_DADDIU:
d75c135e 16166 check_insn(ctx, ISA_MIPS3);
e189e748 16167 check_mips_64(ctx);
d75c135e 16168 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 16169 break;
6af0bf9c 16170#endif
7a387fff 16171 case OPC_JALX:
d75c135e 16172 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
16173 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16174 gen_compute_branch(ctx, op, 4, rs, rt, offset);
364d4831 16175 break;
7a387fff 16176 case OPC_MDMX:
d75c135e 16177 check_insn(ctx, ASE_MDMX);
7a387fff 16178 /* MDMX: Not implemented. */
6af0bf9c 16179 default: /* Invalid */
923617a3 16180 MIPS_INVAL("major opcode");
6af0bf9c
FB
16181 generate_exception(ctx, EXCP_RI);
16182 break;
16183 }
6af0bf9c
FB
16184}
16185
2cfc5f17 16186static inline void
6429db34
AF
16187gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
16188 bool search_pc)
6af0bf9c 16189{
ed2803da 16190 CPUState *cs = CPU(cpu);
6429db34 16191 CPUMIPSState *env = &cpu->env;
278d0702 16192 DisasContext ctx;
6af0bf9c
FB
16193 target_ulong pc_start;
16194 uint16_t *gen_opc_end;
a1d1bb31 16195 CPUBreakpoint *bp;
6af0bf9c 16196 int j, lj = -1;
2e70f6ef
PB
16197 int num_insns;
16198 int max_insns;
c9602061 16199 int insn_bytes;
240ce26a 16200 int is_delay;
6af0bf9c 16201
93fcfe39
AL
16202 if (search_pc)
16203 qemu_log("search pc %d\n", search_pc);
4ad40f36 16204
6af0bf9c 16205 pc_start = tb->pc;
92414b31 16206 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 16207 ctx.pc = pc_start;
4ad40f36 16208 ctx.saved_pc = -1;
ed2803da 16209 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 16210 ctx.insn_flags = env->insn_flags;
5ab5c041 16211 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
16212 ctx.tb = tb;
16213 ctx.bstate = BS_NONE;
4ad40f36 16214 /* Restore delay slot state from the tb context. */
c068688b 16215 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
d279279e 16216 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
fd4a04eb 16217 restore_cpu_state(env, &ctx);
932e71cd 16218#ifdef CONFIG_USER_ONLY
0eaef5aa 16219 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 16220#else
0eaef5aa 16221 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 16222#endif
2e70f6ef
PB
16223 num_insns = 0;
16224 max_insns = tb->cflags & CF_COUNT_MASK;
16225 if (max_insns == 0)
16226 max_insns = CF_COUNT_MASK;
d12d51d5 16227 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 16228 gen_tb_start();
faf7aaa9 16229 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
16230 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
16231 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 16232 if (bp->pc == ctx.pc) {
278d0702 16233 save_cpu_state(&ctx, 1);
4ad40f36 16234 ctx.bstate = BS_BRANCH;
895c2d04 16235 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
16236 /* Include the breakpoint location or the tb won't
16237 * be flushed when it must be. */
16238 ctx.pc += 4;
4ad40f36
FB
16239 goto done_generating;
16240 }
16241 }
16242 }
16243
6af0bf9c 16244 if (search_pc) {
92414b31 16245 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
16246 if (lj < j) {
16247 lj++;
16248 while (lj < j)
ab1103de 16249 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 16250 }
25983cad 16251 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 16252 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 16253 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 16254 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 16255 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 16256 }
2e70f6ef
PB
16257 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
16258 gen_io_start();
c9602061 16259
240ce26a 16260 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 16261 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 16262 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 16263 insn_bytes = 4;
240ce26a 16264 decode_opc(env, &ctx);
d75c135e 16265 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 16266 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 16267 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 16268 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 16269 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 16270 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
16271 } else {
16272 generate_exception(&ctx, EXCP_RI);
3c824109 16273 ctx.bstate = BS_STOP;
c9602061
NF
16274 break;
16275 }
240ce26a 16276 if (is_delay) {
d75c135e 16277 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
16278 }
16279 ctx.pc += insn_bytes;
16280
2e70f6ef 16281 num_insns++;
4ad40f36 16282
7b270ef2
NF
16283 /* Execute a branch and its delay slot as a single instruction.
16284 This is what GDB expects and is consistent with what the
16285 hardware does (e.g. if a delay slot instruction faults, the
16286 reported PC is the PC of the branch). */
ed2803da 16287 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 16288 break;
ed2803da 16289 }
4ad40f36 16290
6af0bf9c
FB
16291 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
16292 break;
4ad40f36 16293
efd7f486 16294 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 16295 break;
efd7f486 16296 }
faf7aaa9 16297
2e70f6ef
PB
16298 if (num_insns >= max_insns)
16299 break;
1b530a6d
AJ
16300
16301 if (singlestep)
16302 break;
6af0bf9c 16303 }
ed2803da 16304 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 16305 gen_io_end();
ed2803da
AF
16306 }
16307 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 16308 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 16309 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 16310 } else {
6958549d 16311 switch (ctx.bstate) {
16c00cb2 16312 case BS_STOP:
df1561e2
TS
16313 gen_goto_tb(&ctx, 0, ctx.pc);
16314 break;
16c00cb2 16315 case BS_NONE:
278d0702 16316 save_cpu_state(&ctx, 0);
16c00cb2
TS
16317 gen_goto_tb(&ctx, 0, ctx.pc);
16318 break;
5a5012ec 16319 case BS_EXCP:
57fec1fe 16320 tcg_gen_exit_tb(0);
16c00cb2 16321 break;
5a5012ec
TS
16322 case BS_BRANCH:
16323 default:
16324 break;
6958549d 16325 }
6af0bf9c 16326 }
4ad40f36 16327done_generating:
806f352d 16328 gen_tb_end(tb, num_insns);
efd7f486 16329 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 16330 if (search_pc) {
92414b31 16331 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
16332 lj++;
16333 while (lj <= j)
ab1103de 16334 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
16335 } else {
16336 tb->size = ctx.pc - pc_start;
2e70f6ef 16337 tb->icount = num_insns;
6af0bf9c
FB
16338 }
16339#ifdef DEBUG_DISAS
d12d51d5 16340 LOG_DISAS("\n");
8fec2b8c 16341 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 16342 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 16343 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 16344 qemu_log("\n");
6af0bf9c
FB
16345 }
16346#endif
6af0bf9c
FB
16347}
16348
7db13fae 16349void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 16350{
6429db34 16351 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
16352}
16353
7db13fae 16354void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 16355{
6429db34 16356 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
16357}
16358
7db13fae 16359static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 16360 int flags)
6ea83fed
FB
16361{
16362 int i;
5e755519 16363 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 16364
2a5612e6
SW
16365#define printfpr(fp) \
16366 do { \
16367 if (is_fpu64) \
16368 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
16369 " fd:%13g fs:%13g psu: %13g\n", \
16370 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
16371 (double)(fp)->fd, \
16372 (double)(fp)->fs[FP_ENDIAN_IDX], \
16373 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
16374 else { \
16375 fpr_t tmp; \
16376 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
16377 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
16378 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
16379 " fd:%13g fs:%13g psu:%13g\n", \
16380 tmp.w[FP_ENDIAN_IDX], tmp.d, \
16381 (double)tmp.fd, \
16382 (double)tmp.fs[FP_ENDIAN_IDX], \
16383 (double)tmp.fs[!FP_ENDIAN_IDX]); \
16384 } \
6ea83fed
FB
16385 } while(0)
16386
5a5012ec 16387
9a78eead
SW
16388 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
16389 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 16390 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
16391 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
16392 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 16393 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
16394 }
16395
16396#undef printfpr
16397}
16398
d26bc211 16399#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 16400/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 16401 sign-extended values on 64bit machines. */
c570fd16
TS
16402
16403#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
16404
8706c382 16405static void
7db13fae 16406cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 16407 fprintf_function cpu_fprintf,
8706c382 16408 int flags)
c570fd16
TS
16409{
16410 int i;
16411
b5dc7732
TS
16412 if (!SIGN_EXT_P(env->active_tc.PC))
16413 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
16414 if (!SIGN_EXT_P(env->active_tc.HI[0]))
16415 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
16416 if (!SIGN_EXT_P(env->active_tc.LO[0]))
16417 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 16418 if (!SIGN_EXT_P(env->btarget))
3594c774 16419 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
16420
16421 for (i = 0; i < 32; i++) {
b5dc7732
TS
16422 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
16423 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
16424 }
16425
16426 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 16427 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
16428 if (!SIGN_EXT_P(env->lladdr))
16429 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
16430}
16431#endif
16432
878096ee
AF
16433void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
16434 int flags)
6af0bf9c 16435{
878096ee
AF
16436 MIPSCPU *cpu = MIPS_CPU(cs);
16437 CPUMIPSState *env = &cpu->env;
6af0bf9c 16438 int i;
3b46e624 16439
a7200c9f
SW
16440 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
16441 " LO=0x" TARGET_FMT_lx " ds %04x "
16442 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
16443 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
16444 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
16445 for (i = 0; i < 32; i++) {
16446 if ((i & 3) == 0)
16447 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 16448 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
16449 if ((i & 3) == 3)
16450 cpu_fprintf(f, "\n");
16451 }
568b600d 16452
3594c774 16453 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 16454 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 16455 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 16456 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 16457 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 16458 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 16459#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
16460 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
16461#endif
6af0bf9c
FB
16462}
16463
78ce64f4 16464void mips_tcg_init(void)
39454628 16465{
f01be154 16466 int i;
39454628
TS
16467 static int inited;
16468
16469 /* Initialize various static tables. */
16470 if (inited)
6958549d 16471 return;
39454628 16472
a7812ae4 16473 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 16474 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 16475 for (i = 1; i < 32; i++)
a7812ae4 16476 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 16477 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 16478 regnames[i]);
d73ee8a2
RH
16479
16480 for (i = 0; i < 32; i++) {
16481 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
16482 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
16483 }
16484
a7812ae4 16485 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 16486 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 16487 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 16488 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 16489 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 16490 regnames_HI[i]);
a7812ae4 16491 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 16492 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 16493 regnames_LO[i]);
a7812ae4 16494 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 16495 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
16496 regnames_ACX[i]);
16497 }
a7812ae4 16498 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 16499 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 16500 "DSPControl");
1ba74fb8 16501 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 16502 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 16503 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 16504 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 16505 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 16506 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 16507
a7812ae4 16508 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 16509 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
16510 "fcr0");
16511 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 16512 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 16513 "fcr31");
39454628
TS
16514
16515 inited = 1;
16516}
16517
aaed909a
FB
16518#include "translate_init.c"
16519
30bf942d 16520MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 16521{
0f71a709 16522 MIPSCPU *cpu;
6af0bf9c 16523 CPUMIPSState *env;
c227f099 16524 const mips_def_t *def;
6af0bf9c 16525
aaed909a
FB
16526 def = cpu_mips_find_by_name(cpu_model);
16527 if (!def)
16528 return NULL;
0f71a709
AF
16529 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
16530 env = &cpu->env;
aaed909a
FB
16531 env->cpu_model = def;
16532
51cc2e78
BS
16533#ifndef CONFIG_USER_ONLY
16534 mmu_init(env, def);
16535#endif
16536 fpu_init(env, def);
16537 mvp_init(env, def);
c1caf1d9
AF
16538
16539 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
16540
30bf942d 16541 return cpu;
6ae81775
TS
16542}
16543
1bba0dc9 16544void cpu_state_reset(CPUMIPSState *env)
6ae81775 16545{
55e5c285
AF
16546 MIPSCPU *cpu = mips_env_get_cpu(env);
16547 CPUState *cs = CPU(cpu);
6ae81775 16548
51cc2e78
BS
16549 /* Reset registers to their default values */
16550 env->CP0_PRid = env->cpu_model->CP0_PRid;
16551 env->CP0_Config0 = env->cpu_model->CP0_Config0;
16552#ifdef TARGET_WORDS_BIGENDIAN
16553 env->CP0_Config0 |= (1 << CP0C0_BE);
16554#endif
16555 env->CP0_Config1 = env->cpu_model->CP0_Config1;
16556 env->CP0_Config2 = env->cpu_model->CP0_Config2;
16557 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
16558 env->CP0_Config4 = env->cpu_model->CP0_Config4;
16559 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
16560 env->CP0_Config5 = env->cpu_model->CP0_Config5;
16561 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
16562 env->CP0_Config6 = env->cpu_model->CP0_Config6;
16563 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
16564 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
16565 << env->cpu_model->CP0_LLAddr_shift;
16566 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
16567 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
16568 env->CCRes = env->cpu_model->CCRes;
16569 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
16570 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
16571 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
16572 env->current_tc = 0;
16573 env->SEGBITS = env->cpu_model->SEGBITS;
16574 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
16575#if defined(TARGET_MIPS64)
16576 if (env->cpu_model->insn_flags & ISA_MIPS3) {
16577 env->SEGMask |= 3ULL << 62;
16578 }
16579#endif
16580 env->PABITS = env->cpu_model->PABITS;
16581 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
16582 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
16583 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
16584 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
16585 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
16586 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
16587 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
16588 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
16589 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
16590 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
16591 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 16592 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
16593 env->insn_flags = env->cpu_model->insn_flags;
16594
0eaef5aa 16595#if defined(CONFIG_USER_ONLY)
03e6e501 16596 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
16597# ifdef TARGET_MIPS64
16598 /* Enable 64-bit register mode. */
16599 env->CP0_Status |= (1 << CP0St_PX);
16600# endif
16601# ifdef TARGET_ABI_MIPSN64
16602 /* Enable 64-bit address mode. */
16603 env->CP0_Status |= (1 << CP0St_UX);
16604# endif
94159135
MI
16605 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16606 hardware registers. */
16607 env->CP0_HWREna |= 0x0000000F;
91a75935 16608 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 16609 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 16610 }
6f0af304
PJ
16611 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
16612 env->CP0_Status |= (1 << CP0St_MX);
853c3240 16613 }
4d66261f
PJ
16614# if defined(TARGET_MIPS64)
16615 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16616 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
16617 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
16618 env->CP0_Status |= (1 << CP0St_FR);
16619 }
4d66261f 16620# endif
932e71cd
AJ
16621#else
16622 if (env->hflags & MIPS_HFLAG_BMASK) {
16623 /* If the exception was raised from a delay slot,
16624 come back to the jump. */
16625 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 16626 } else {
932e71cd
AJ
16627 env->CP0_ErrorEPC = env->active_tc.PC;
16628 }
16629 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
16630 env->CP0_Random = env->tlb->nb_tlb - 1;
16631 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 16632 env->CP0_Wired = 0;
0a2672b7
JH
16633 env->CP0_EBase = (cs->cpu_index & 0x3FF);
16634 if (kvm_enabled()) {
16635 env->CP0_EBase |= 0x40000000;
16636 } else {
16637 env->CP0_EBase |= 0x80000000;
16638 }
932e71cd
AJ
16639 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16640 /* vectored interrupts not implemented, timer on int 7,
16641 no performance counters. */
16642 env->CP0_IntCtl = 0xe0000000;
16643 {
16644 int i;
16645
16646 for (i = 0; i < 7; i++) {
16647 env->CP0_WatchLo[i] = 0;
16648 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 16649 }
932e71cd
AJ
16650 env->CP0_WatchLo[7] = 0;
16651 env->CP0_WatchHi[7] = 0;
fd88b6ab 16652 }
932e71cd
AJ
16653 /* Count register increments in debug mode, EJTAG version 1 */
16654 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 16655
4b69c7e2
JH
16656 cpu_mips_store_count(env, 1);
16657
9e56e756
EI
16658 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16659 int i;
16660
16661 /* Only TC0 on VPE 0 starts as active. */
16662 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 16663 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
16664 env->tcs[i].CP0_TCHalt = 1;
16665 }
16666 env->active_tc.CP0_TCHalt = 1;
259186a7 16667 cs->halted = 1;
9e56e756 16668
55e5c285 16669 if (cs->cpu_index == 0) {
9e56e756
EI
16670 /* VPE0 starts up enabled. */
16671 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16672 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16673
16674 /* TC0 starts up unhalted. */
259186a7 16675 cs->halted = 0;
9e56e756
EI
16676 env->active_tc.CP0_TCHalt = 0;
16677 env->tcs[0].CP0_TCHalt = 0;
16678 /* With thread 0 active. */
16679 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16680 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16681 }
16682 }
51cc2e78 16683#endif
03e6e501 16684 compute_hflags(env);
27103424 16685 cs->exception_index = EXCP_NONE;
6af0bf9c 16686}
d2856f1a 16687
7db13fae 16688void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16689{
25983cad 16690 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16691 env->hflags &= ~MIPS_HFLAG_BMASK;
16692 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16693 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16694 case MIPS_HFLAG_BR:
16695 break;
16696 case MIPS_HFLAG_BC:
16697 case MIPS_HFLAG_BL:
16698 case MIPS_HFLAG_B:
16699 env->btarget = gen_opc_btarget[pc_pos];
16700 break;
16701 }
d2856f1a 16702}