]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
tcg: Invert the inclusion of helper.h
[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"
6af0bf9c 27
2ef6175a
RH
28#include "exec/helper-proto.h"
29#include "exec/helper-gen.h"
a7812ae4 30
fb7729e2 31#define MIPS_DEBUG_DISAS 0
c570fd16 32//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c 33
7a387fff
TS
34/* MIPS major opcodes */
35#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
36
37enum {
38 /* indirect opcode tables */
7a387fff
TS
39 OPC_SPECIAL = (0x00 << 26),
40 OPC_REGIMM = (0x01 << 26),
41 OPC_CP0 = (0x10 << 26),
42 OPC_CP1 = (0x11 << 26),
43 OPC_CP2 = (0x12 << 26),
44 OPC_CP3 = (0x13 << 26),
45 OPC_SPECIAL2 = (0x1C << 26),
46 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 47 /* arithmetic with immediate */
7a387fff
TS
48 OPC_ADDI = (0x08 << 26),
49 OPC_ADDIU = (0x09 << 26),
50 OPC_SLTI = (0x0A << 26),
51 OPC_SLTIU = (0x0B << 26),
324d9e32 52 /* logic with immediate */
7a387fff
TS
53 OPC_ANDI = (0x0C << 26),
54 OPC_ORI = (0x0D << 26),
55 OPC_XORI = (0x0E << 26),
56 OPC_LUI = (0x0F << 26),
324d9e32 57 /* arithmetic with immediate */
7a387fff
TS
58 OPC_DADDI = (0x18 << 26),
59 OPC_DADDIU = (0x19 << 26),
e37e863f 60 /* Jump and branches */
7a387fff
TS
61 OPC_J = (0x02 << 26),
62 OPC_JAL = (0x03 << 26),
620e48f6 63 OPC_JALS = OPC_JAL | 0x5,
7a387fff
TS
64 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
65 OPC_BEQL = (0x14 << 26),
66 OPC_BNE = (0x05 << 26),
67 OPC_BNEL = (0x15 << 26),
68 OPC_BLEZ = (0x06 << 26),
69 OPC_BLEZL = (0x16 << 26),
70 OPC_BGTZ = (0x07 << 26),
71 OPC_BGTZL = (0x17 << 26),
72 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
620e48f6 73 OPC_JALXS = OPC_JALX | 0x5,
e37e863f 74 /* Load and stores */
7a387fff
TS
75 OPC_LDL = (0x1A << 26),
76 OPC_LDR = (0x1B << 26),
77 OPC_LB = (0x20 << 26),
78 OPC_LH = (0x21 << 26),
79 OPC_LWL = (0x22 << 26),
80 OPC_LW = (0x23 << 26),
364d4831 81 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
82 OPC_LBU = (0x24 << 26),
83 OPC_LHU = (0x25 << 26),
84 OPC_LWR = (0x26 << 26),
85 OPC_LWU = (0x27 << 26),
86 OPC_SB = (0x28 << 26),
87 OPC_SH = (0x29 << 26),
88 OPC_SWL = (0x2A << 26),
89 OPC_SW = (0x2B << 26),
90 OPC_SDL = (0x2C << 26),
91 OPC_SDR = (0x2D << 26),
92 OPC_SWR = (0x2E << 26),
93 OPC_LL = (0x30 << 26),
94 OPC_LLD = (0x34 << 26),
95 OPC_LD = (0x37 << 26),
364d4831 96 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
97 OPC_SC = (0x38 << 26),
98 OPC_SCD = (0x3C << 26),
99 OPC_SD = (0x3F << 26),
e37e863f 100 /* Floating point load/store */
7a387fff
TS
101 OPC_LWC1 = (0x31 << 26),
102 OPC_LWC2 = (0x32 << 26),
103 OPC_LDC1 = (0x35 << 26),
104 OPC_LDC2 = (0x36 << 26),
105 OPC_SWC1 = (0x39 << 26),
106 OPC_SWC2 = (0x3A << 26),
107 OPC_SDC1 = (0x3D << 26),
108 OPC_SDC2 = (0x3E << 26),
109 /* MDMX ASE specific */
110 OPC_MDMX = (0x1E << 26),
e37e863f 111 /* Cache and prefetch */
7a387fff
TS
112 OPC_CACHE = (0x2F << 26),
113 OPC_PREF = (0x33 << 26),
114 /* Reserved major opcode */
115 OPC_MAJOR3B_RESERVED = (0x3B << 26),
e37e863f
FB
116};
117
118/* MIPS special opcodes */
7a387fff
TS
119#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
120
e37e863f
FB
121enum {
122 /* Shifts */
7a387fff 123 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
124 /* NOP is SLL r0, r0, 0 */
125 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
126 /* EHB is SLL r0, r0, 3 */
127 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 128 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
129 OPC_SRA = 0x03 | OPC_SPECIAL,
130 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 131 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 132 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
133 OPC_SRAV = 0x07 | OPC_SPECIAL,
134 OPC_DSLLV = 0x14 | OPC_SPECIAL,
135 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 136 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
137 OPC_DSRAV = 0x17 | OPC_SPECIAL,
138 OPC_DSLL = 0x38 | OPC_SPECIAL,
139 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 140 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
141 OPC_DSRA = 0x3B | OPC_SPECIAL,
142 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
143 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 144 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 145 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 146 /* Multiplication / division */
7a387fff
TS
147 OPC_MULT = 0x18 | OPC_SPECIAL,
148 OPC_MULTU = 0x19 | OPC_SPECIAL,
149 OPC_DIV = 0x1A | OPC_SPECIAL,
150 OPC_DIVU = 0x1B | OPC_SPECIAL,
151 OPC_DMULT = 0x1C | OPC_SPECIAL,
152 OPC_DMULTU = 0x1D | OPC_SPECIAL,
153 OPC_DDIV = 0x1E | OPC_SPECIAL,
154 OPC_DDIVU = 0x1F | OPC_SPECIAL,
e37e863f 155 /* 2 registers arithmetic / logic */
7a387fff
TS
156 OPC_ADD = 0x20 | OPC_SPECIAL,
157 OPC_ADDU = 0x21 | OPC_SPECIAL,
158 OPC_SUB = 0x22 | OPC_SPECIAL,
159 OPC_SUBU = 0x23 | OPC_SPECIAL,
160 OPC_AND = 0x24 | OPC_SPECIAL,
161 OPC_OR = 0x25 | OPC_SPECIAL,
162 OPC_XOR = 0x26 | OPC_SPECIAL,
163 OPC_NOR = 0x27 | OPC_SPECIAL,
164 OPC_SLT = 0x2A | OPC_SPECIAL,
165 OPC_SLTU = 0x2B | OPC_SPECIAL,
166 OPC_DADD = 0x2C | OPC_SPECIAL,
167 OPC_DADDU = 0x2D | OPC_SPECIAL,
168 OPC_DSUB = 0x2E | OPC_SPECIAL,
169 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 170 /* Jumps */
7a387fff
TS
171 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
172 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
364d4831 173 OPC_JALRC = OPC_JALR | (0x5 << 6),
620e48f6 174 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
e37e863f 175 /* Traps */
7a387fff
TS
176 OPC_TGE = 0x30 | OPC_SPECIAL,
177 OPC_TGEU = 0x31 | OPC_SPECIAL,
178 OPC_TLT = 0x32 | OPC_SPECIAL,
179 OPC_TLTU = 0x33 | OPC_SPECIAL,
180 OPC_TEQ = 0x34 | OPC_SPECIAL,
181 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 182 /* HI / LO registers load & stores */
7a387fff
TS
183 OPC_MFHI = 0x10 | OPC_SPECIAL,
184 OPC_MTHI = 0x11 | OPC_SPECIAL,
185 OPC_MFLO = 0x12 | OPC_SPECIAL,
186 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 187 /* Conditional moves */
7a387fff
TS
188 OPC_MOVZ = 0x0A | OPC_SPECIAL,
189 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 190
7a387fff 191 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
192
193 /* Special */
a0d700e4 194 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
195 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
196 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 197 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
198 OPC_SYNC = 0x0F | OPC_SPECIAL,
199
200 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
201 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
202 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
203 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
204 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
205 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
206 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
207};
208
e9c71dd1
TS
209/* Multiplication variants of the vr54xx. */
210#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
211
212enum {
213 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
214 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
215 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
216 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
217 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
218 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
219 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
220 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
221 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
222 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
223 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
224 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
225 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
226 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
227};
228
7a387fff
TS
229/* REGIMM (rt field) opcodes */
230#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
231
232enum {
233 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
234 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
235 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
236 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
237 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
3c824109 238 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
7a387fff
TS
239 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
240 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
3c824109 241 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
7a387fff
TS
242 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
243 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
244 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
245 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
246 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
247 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
248 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
249 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
e37e863f
FB
250};
251
7a387fff
TS
252/* Special2 opcodes */
253#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
254
e37e863f 255enum {
7a387fff
TS
256 /* Multiply & xxx operations */
257 OPC_MADD = 0x00 | OPC_SPECIAL2,
258 OPC_MADDU = 0x01 | OPC_SPECIAL2,
259 OPC_MUL = 0x02 | OPC_SPECIAL2,
260 OPC_MSUB = 0x04 | OPC_SPECIAL2,
261 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
262 /* Loongson 2F */
263 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
264 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
265 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
266 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
267 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
268 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
269 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
270 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
271 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
272 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
273 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
274 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 275 /* Misc */
7a387fff
TS
276 OPC_CLZ = 0x20 | OPC_SPECIAL2,
277 OPC_CLO = 0x21 | OPC_SPECIAL2,
278 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
279 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 280 /* Special */
7a387fff
TS
281 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
282};
283
284/* Special3 opcodes */
285#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
286
287enum {
288 OPC_EXT = 0x00 | OPC_SPECIAL3,
289 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
290 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
291 OPC_DEXT = 0x03 | OPC_SPECIAL3,
292 OPC_INS = 0x04 | OPC_SPECIAL3,
293 OPC_DINSM = 0x05 | OPC_SPECIAL3,
294 OPC_DINSU = 0x06 | OPC_SPECIAL3,
295 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
296 OPC_FORK = 0x08 | OPC_SPECIAL3,
297 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
298 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
299 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
300 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
301
302 /* Loongson 2E */
303 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
304 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
305 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
306 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
307 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
308 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
309 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
310 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
311 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
312 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
313 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
314 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
315
316 /* MIPS DSP Load */
317 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
318 /* MIPS DSP Arithmetic */
319 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 320 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 321 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 322 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
323 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
324 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
325 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 326 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
327 /* MIPS DSP GPR-Based Shift Sub-class */
328 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 329 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
330 /* MIPS DSP Multiply Sub-class insns */
331 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
332 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
333 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 334 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
335 /* DSP Bit/Manipulation Sub-class */
336 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 337 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 338 /* MIPS DSP Append Sub-class */
26690560 339 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 340 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
341 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
342 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 343 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
e37e863f
FB
344};
345
7a387fff
TS
346/* BSHFL opcodes */
347#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
348
e37e863f 349enum {
7a387fff
TS
350 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
351 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
352 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
e37e863f
FB
353};
354
7a387fff
TS
355/* DBSHFL opcodes */
356#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
357
e37e863f 358enum {
7a387fff
TS
359 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
360 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
e37e863f
FB
361};
362
e45a93e2
JL
363/* MIPS DSP REGIMM opcodes */
364enum {
365 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 366 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
367};
368
9b1a1d68
JL
369#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
370/* MIPS DSP Load */
371enum {
372 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
373 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
374 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 375 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
376};
377
461c08df
JL
378#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
379enum {
380 /* MIPS DSP Arithmetic Sub-class */
381 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
382 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
388 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
395 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
397 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
398 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
399 /* MIPS DSP Multiply Sub-class insns */
400 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
401 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
406};
407
408#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
409#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
410enum {
411 /* MIPS DSP Arithmetic Sub-class */
412 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
413 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
424 /* MIPS DSP Multiply Sub-class insns */
425 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
426 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
429};
430
431#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
432enum {
433 /* MIPS DSP Arithmetic Sub-class */
434 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
435 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
447 /* DSP Bit/Manipulation Sub-class */
448 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
449 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
453};
454
455#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
456enum {
457 /* MIPS DSP Arithmetic Sub-class */
458 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
459 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
465 /* DSP Compare-Pick Sub-class */
466 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
467 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 481};
a22260ae 482
77c5fa8b
JL
483#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
484enum {
485 /* MIPS DSP GPR-Based Shift Sub-class */
486 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
487 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
508};
461c08df 509
a22260ae
JL
510#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
511enum {
512 /* MIPS DSP Multiply Sub-class insns */
513 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
514 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
527 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
528 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
530 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
535};
536
1cb6686c
JL
537#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
538enum {
539 /* DSP Bit/Manipulation Sub-class */
540 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
541};
542
26690560
JL
543#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
544enum {
df6126a7 545 /* MIPS DSP Append Sub-class */
26690560
JL
546 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
547 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
548 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
549};
550
b53371ed
JL
551#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
552enum {
553 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
554 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
555 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
566 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
568 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
569 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
570 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
571};
572
461c08df
JL
573#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
574enum {
575 /* MIPS DSP Arithmetic Sub-class */
576 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
577 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
593 /* DSP Bit/Manipulation Sub-class */
594 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
595 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 600};
461c08df 601
461c08df
JL
602#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
603enum {
a22260ae
JL
604 /* MIPS DSP Multiply Sub-class insns */
605 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
606 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
610 /* MIPS DSP Arithmetic Sub-class */
611 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
612 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
622 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
632};
461c08df 633
461c08df
JL
634#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
635enum {
26690560
JL
636 /* DSP Compare-Pick Sub-class */
637 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
638 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
656 /* MIPS DSP Arithmetic Sub-class */
657 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
658 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
665};
461c08df 666
26690560
JL
667#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
668enum {
df6126a7 669 /* DSP Append Sub-class */
26690560
JL
670 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
671 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
673 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
674};
26690560 675
b53371ed
JL
676#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
677enum {
678 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
679 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
680 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
681 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
700};
701
1cb6686c
JL
702#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
703enum {
704 /* DSP Bit/Manipulation Sub-class */
705 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
706};
1cb6686c 707
a22260ae
JL
708#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
709enum {
710 /* MIPS DSP Multiply Sub-class insns */
711 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
712 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
737};
a22260ae 738
77c5fa8b
JL
739#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
740enum {
741 /* MIPS DSP GPR-Based Shift Sub-class */
742 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
743 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
768};
77c5fa8b 769
7a387fff
TS
770/* Coprocessor 0 (rs field) */
771#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
772
6ea83fed 773enum {
7a387fff
TS
774 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
775 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
776 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
777 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 778 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
779 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
780 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 781 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
782 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
783 OPC_C0 = (0x10 << 21) | OPC_CP0,
784 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
785 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 786};
7a387fff
TS
787
788/* MFMC0 opcodes */
b48cfdff 789#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
790
791enum {
ead9360e
TS
792 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
793 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
795 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
796 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
797 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
798};
799
800/* Coprocessor 0 (with rs == C0) */
801#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
802
803enum {
804 OPC_TLBR = 0x01 | OPC_C0,
805 OPC_TLBWI = 0x02 | OPC_C0,
806 OPC_TLBWR = 0x06 | OPC_C0,
807 OPC_TLBP = 0x08 | OPC_C0,
808 OPC_RFE = 0x10 | OPC_C0,
809 OPC_ERET = 0x18 | OPC_C0,
810 OPC_DERET = 0x1F | OPC_C0,
811 OPC_WAIT = 0x20 | OPC_C0,
812};
813
814/* Coprocessor 1 (rs field) */
815#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
816
bf4120ad
NF
817/* Values for the fmt field in FP instructions */
818enum {
819 /* 0 - 15 are reserved */
e459440a
AJ
820 FMT_S = 16, /* single fp */
821 FMT_D = 17, /* double fp */
822 FMT_E = 18, /* extended fp */
823 FMT_Q = 19, /* quad fp */
824 FMT_W = 20, /* 32-bit fixed */
825 FMT_L = 21, /* 64-bit fixed */
826 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
827 /* 23 - 31 are reserved */
828};
829
7a387fff
TS
830enum {
831 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
832 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
833 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 834 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
835 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
836 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
837 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 838 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 839 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
840 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
841 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
e459440a
AJ
842 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
843 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
844 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
845 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
846 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
847 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
848 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
7a387fff
TS
849};
850
5a5012ec
TS
851#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
852#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
853
7a387fff
TS
854enum {
855 OPC_BC1F = (0x00 << 16) | OPC_BC1,
856 OPC_BC1T = (0x01 << 16) | OPC_BC1,
857 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
858 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
859};
860
5a5012ec
TS
861enum {
862 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
863 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
864};
865
866enum {
867 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
868 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
869};
7a387fff
TS
870
871#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
872
873enum {
874 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
875 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
876 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
877 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
878 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
879 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
880 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
881 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
882 OPC_BC2 = (0x08 << 21) | OPC_CP2,
883};
884
bd277fa1
RH
885#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
886
887enum {
888 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
889 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
896
897 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
898 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
905
906 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
907 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
910 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
911 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
912 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
913 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
914
915 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
916 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
919 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
923
924 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
925 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
926 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
927 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
928 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
929 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
930
931 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
932 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
937
938 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
939 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
940 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
944
945 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
946 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
949 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
951
952 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
953 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
954 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
955 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
956 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
958
959 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
960 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
961 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
962 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
963 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
965
966 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
967 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
968 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
969 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
970 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
972
973 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
974 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
975 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
976 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
977 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
978 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
979};
980
981
e0c84da7
TS
982#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
983
984enum {
985 OPC_LWXC1 = 0x00 | OPC_CP3,
986 OPC_LDXC1 = 0x01 | OPC_CP3,
987 OPC_LUXC1 = 0x05 | OPC_CP3,
988 OPC_SWXC1 = 0x08 | OPC_CP3,
989 OPC_SDXC1 = 0x09 | OPC_CP3,
990 OPC_SUXC1 = 0x0D | OPC_CP3,
991 OPC_PREFX = 0x0F | OPC_CP3,
992 OPC_ALNV_PS = 0x1E | OPC_CP3,
993 OPC_MADD_S = 0x20 | OPC_CP3,
994 OPC_MADD_D = 0x21 | OPC_CP3,
995 OPC_MADD_PS = 0x26 | OPC_CP3,
996 OPC_MSUB_S = 0x28 | OPC_CP3,
997 OPC_MSUB_D = 0x29 | OPC_CP3,
998 OPC_MSUB_PS = 0x2E | OPC_CP3,
999 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1000 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1001 OPC_NMADD_PS= 0x36 | OPC_CP3,
1002 OPC_NMSUB_S = 0x38 | OPC_CP3,
1003 OPC_NMSUB_D = 0x39 | OPC_CP3,
1004 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1005};
1006
39454628 1007/* global register indices */
a7812ae4
PB
1008static TCGv_ptr cpu_env;
1009static TCGv cpu_gpr[32], cpu_PC;
4b2eb8d2 1010static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
41db4607
AJ
1011static TCGv cpu_dspctrl, btarget, bcond;
1012static TCGv_i32 hflags;
a7812ae4 1013static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1014static TCGv_i64 fpu_f64[32];
aa0bf00b 1015
1a7ff922 1016static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1017static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1018
022c62cb 1019#include "exec/gen-icount.h"
2e70f6ef 1020
895c2d04 1021#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1022 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1023 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1024 tcg_temp_free_i32(helper_tmp); \
1025 } while(0)
be24bb4f 1026
895c2d04 1027#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1028 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1029 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1030 tcg_temp_free_i32(helper_tmp); \
1031 } while(0)
be24bb4f 1032
895c2d04
BS
1033#define gen_helper_1e0i(name, ret, arg1) do { \
1034 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1035 gen_helper_##name(ret, cpu_env, helper_tmp); \
1036 tcg_temp_free_i32(helper_tmp); \
1037 } while(0)
1038
1039#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1040 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1041 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1042 tcg_temp_free_i32(helper_tmp); \
1043 } while(0)
1044
1045#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1046 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1047 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1048 tcg_temp_free_i32(helper_tmp); \
1049 } while(0)
1050
1051#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1052 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1053 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1054 tcg_temp_free_i32(helper_tmp); \
1055 } while(0)
be24bb4f 1056
895c2d04 1057#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1058 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1059 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1060 tcg_temp_free_i32(helper_tmp); \
1061 } while(0)
c239529e 1062
8e9ade68
TS
1063typedef struct DisasContext {
1064 struct TranslationBlock *tb;
1065 target_ulong pc, saved_pc;
1066 uint32_t opcode;
7b270ef2 1067 int singlestep_enabled;
d75c135e 1068 int insn_flags;
8e9ade68
TS
1069 /* Routine used to access memory */
1070 int mem_idx;
1071 uint32_t hflags, saved_hflags;
1072 int bstate;
1073 target_ulong btarget;
1074} DisasContext;
1075
1076enum {
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1078 * exception condition */
8e9ade68
TS
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1082};
1083
d73ee8a2
RH
1084static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1089};
6af0bf9c 1090
d73ee8a2
RH
1091static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1093};
4b2eb8d2 1094
d73ee8a2
RH
1095static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1097};
4b2eb8d2 1098
d73ee8a2
RH
1099static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1101};
4b2eb8d2 1102
d73ee8a2
RH
1103static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1108};
958fb4a9 1109
fb7729e2
RH
1110#define MIPS_DEBUG(fmt, ...) \
1111 do { \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1116 } \
1117 } while (0)
1118
1119#define LOG_DISAS(...) \
1120 do { \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1123 } \
1124 } while (0)
958fb4a9 1125
8e9ade68 1126#define MIPS_INVAL(op) \
8e9ade68 1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1129
8e9ade68
TS
1130/* General purpose registers moves. */
1131static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1132{
8e9ade68
TS
1133 if (reg == 0)
1134 tcg_gen_movi_tl(t, 0);
1135 else
4b2eb8d2 1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1137}
1138
8e9ade68 1139static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1140{
8e9ade68 1141 if (reg != 0)
4b2eb8d2 1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1143}
1144
b10fa3c9 1145/* Moves to/from ACX register. */
4b2eb8d2 1146static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1147{
4b2eb8d2 1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1149}
1150
4b2eb8d2 1151static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1152{
4b2eb8d2 1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1154}
1155
8e9ade68 1156/* Moves to/from shadow registers. */
be24bb4f 1157static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1158{
d9bea114 1159 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1160
1161 if (from == 0)
d9bea114 1162 tcg_gen_movi_tl(t0, 0);
8e9ade68 1163 else {
d9bea114 1164 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1165 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1166
7db13fae 1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1172 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1173
d9bea114 1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1175 tcg_temp_free_ptr(addr);
d9bea114 1176 tcg_temp_free_i32(t2);
8e9ade68 1177 }
d9bea114
AJ
1178 gen_store_gpr(t0, to);
1179 tcg_temp_free(t0);
aaa9128a
TS
1180}
1181
be24bb4f 1182static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1183{
be24bb4f 1184 if (to != 0) {
d9bea114
AJ
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1187 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1188
d9bea114 1189 gen_load_gpr(t0, from);
7db13fae 1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1195 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1196
d9bea114 1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1198 tcg_temp_free_ptr(addr);
d9bea114
AJ
1199 tcg_temp_free_i32(t2);
1200 tcg_temp_free(t0);
8e9ade68 1201 }
aaa9128a
TS
1202}
1203
aaa9128a 1204/* Floating point register moves. */
d73ee8a2 1205static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1206{
d73ee8a2 1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1208}
1209
d73ee8a2 1210static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1211{
d73ee8a2
RH
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
6d066274
AJ
1216}
1217
7f6613ce 1218static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1219{
7f6613ce
PJ
1220 if (ctx->hflags & MIPS_HFLAG_F64) {
1221 TCGv_i64 t64 = tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1223 tcg_gen_trunc_i64_i32(t, t64);
1224 tcg_temp_free_i64(t64);
1225 } else {
1226 gen_load_fpr32(t, reg | 1);
1227 }
6d066274
AJ
1228}
1229
7f6613ce 1230static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1231{
7f6613ce
PJ
1232 if (ctx->hflags & MIPS_HFLAG_F64) {
1233 TCGv_i64 t64 = tcg_temp_new_i64();
1234 tcg_gen_extu_i32_i64(t64, t);
1235 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1236 tcg_temp_free_i64(t64);
1237 } else {
1238 gen_store_fpr32(t, reg | 1);
1239 }
aa0bf00b 1240}
6ea83fed 1241
d73ee8a2 1242static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1243{
f364515c 1244 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1245 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1246 } else {
d73ee8a2 1247 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1248 }
1249}
6ea83fed 1250
d73ee8a2 1251static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1252{
f364515c 1253 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1254 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1255 } else {
d73ee8a2
RH
1256 TCGv_i64 t0;
1257 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1258 t0 = tcg_temp_new_i64();
6d066274 1259 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1260 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1261 tcg_temp_free_i64(t0);
aa0bf00b
TS
1262 }
1263}
6ea83fed 1264
d94536f4 1265static inline int get_fp_bit (int cc)
a16336e4 1266{
d94536f4
AJ
1267 if (cc)
1268 return 24 + cc;
1269 else
1270 return 23;
a16336e4
TS
1271}
1272
30898801 1273/* Tests */
8e9ade68
TS
1274static inline void gen_save_pc(target_ulong pc)
1275{
1eb75d4a 1276 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1277}
30898801 1278
356265ae 1279static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1280{
d12d51d5 1281 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1282 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1283 gen_save_pc(ctx->pc);
6af0bf9c
FB
1284 ctx->saved_pc = ctx->pc;
1285 }
1286 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1287 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1288 ctx->saved_hflags = ctx->hflags;
364d4831 1289 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1290 case MIPS_HFLAG_BR:
5a5012ec
TS
1291 break;
1292 case MIPS_HFLAG_BC:
5a5012ec 1293 case MIPS_HFLAG_BL:
5a5012ec 1294 case MIPS_HFLAG_B:
d077b6f7 1295 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1296 break;
6af0bf9c
FB
1297 }
1298 }
1299}
1300
7db13fae 1301static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1302{
fd4a04eb 1303 ctx->saved_hflags = ctx->hflags;
364d4831 1304 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1305 case MIPS_HFLAG_BR:
fd4a04eb
TS
1306 break;
1307 case MIPS_HFLAG_BC:
1308 case MIPS_HFLAG_BL:
39454628 1309 case MIPS_HFLAG_B:
fd4a04eb 1310 ctx->btarget = env->btarget;
fd4a04eb 1311 break;
5a5012ec
TS
1312 }
1313}
1314
356265ae 1315static inline void
48d38ca5 1316generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1317{
a7812ae4
PB
1318 TCGv_i32 texcp = tcg_const_i32(excp);
1319 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1320 save_cpu_state(ctx, 1);
895c2d04 1321 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1322 tcg_temp_free_i32(terr);
1323 tcg_temp_free_i32(texcp);
aaa9128a
TS
1324}
1325
356265ae 1326static inline void
48d38ca5 1327generate_exception (DisasContext *ctx, int excp)
aaa9128a 1328{
6af0bf9c 1329 save_cpu_state(ctx, 1);
895c2d04 1330 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1331}
1332
48d38ca5 1333/* Addresses computation */
941694d0 1334static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1335{
941694d0 1336 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1337
1338#if defined(TARGET_MIPS64)
1339 /* For compatibility with 32-bit code, data reference in user mode
1340 with Status_UX = 0 should be casted to 32-bit and sign extended.
1341 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1342 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1343 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1344 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1345 }
1346#endif
4ad40f36
FB
1347}
1348
356265ae 1349static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1350{
fe253235 1351 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1352 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1353}
1354
356265ae 1355static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1356{
fe253235 1357 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1358 generate_exception_err(ctx, EXCP_CpU, 1);
1359}
1360
b8aa4598
TS
1361/* Verify that the processor is running with COP1X instructions enabled.
1362 This is associated with the nabla symbol in the MIPS32 and MIPS64
1363 opcode tables. */
1364
356265ae 1365static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1366{
1367 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1368 generate_exception(ctx, EXCP_RI);
1369}
1370
1371/* Verify that the processor is running with 64-bit floating-point
1372 operations enabled. */
1373
356265ae 1374static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1375{
b8aa4598 1376 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1377 generate_exception(ctx, EXCP_RI);
1378}
1379
1380/*
1381 * Verify if floating point register is valid; an operation is not defined
1382 * if bit 0 of any register specification is set and the FR bit in the
1383 * Status register equals zero, since the register numbers specify an
1384 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1385 * in the Status register equals one, both even and odd register numbers
1386 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1387 *
1388 * Multiple 64 bit wide registers can be checked by calling
1389 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1390 */
356265ae 1391static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1392{
fe253235 1393 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1394 generate_exception(ctx, EXCP_RI);
1395}
1396
853c3240
JL
1397/* Verify that the processor is running with DSP instructions enabled.
1398 This is enabled by CP0 Status register MX(24) bit.
1399 */
1400
1401static inline void check_dsp(DisasContext *ctx)
1402{
1403 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1404 if (ctx->insn_flags & ASE_DSP) {
1405 generate_exception(ctx, EXCP_DSPDIS);
1406 } else {
1407 generate_exception(ctx, EXCP_RI);
1408 }
853c3240
JL
1409 }
1410}
1411
1412static inline void check_dspr2(DisasContext *ctx)
1413{
1414 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1415 if (ctx->insn_flags & ASE_DSP) {
1416 generate_exception(ctx, EXCP_DSPDIS);
1417 } else {
1418 generate_exception(ctx, EXCP_RI);
1419 }
853c3240
JL
1420 }
1421}
1422
3a95e3a7 1423/* This code generates a "reserved instruction" exception if the
e189e748 1424 CPU does not support the instruction set corresponding to flags. */
d75c135e 1425static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1426{
d75c135e 1427 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1428 generate_exception(ctx, EXCP_RI);
d75c135e 1429 }
3a95e3a7
TS
1430}
1431
e189e748
TS
1432/* This code generates a "reserved instruction" exception if 64-bit
1433 instructions are not enabled. */
356265ae 1434static inline void check_mips_64(DisasContext *ctx)
e189e748 1435{
fe253235 1436 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1437 generate_exception(ctx, EXCP_RI);
1438}
1439
8153667c
NF
1440/* Define small wrappers for gen_load_fpr* so that we have a uniform
1441 calling interface for 32 and 64-bit FPRs. No sense in changing
1442 all callers for gen_load_fpr32 when we need the CTX parameter for
1443 this one use. */
1444#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1445#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1446#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1447static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1448 int ft, int fs, int cc) \
1449{ \
1450 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1451 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1452 switch (ifmt) { \
1453 case FMT_PS: \
1454 check_cp1_64bitmode(ctx); \
1455 break; \
1456 case FMT_D: \
1457 if (abs) { \
1458 check_cop1x(ctx); \
1459 } \
1460 check_cp1_registers(ctx, fs | ft); \
1461 break; \
1462 case FMT_S: \
1463 if (abs) { \
1464 check_cop1x(ctx); \
1465 } \
1466 break; \
1467 } \
1468 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1469 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1470 switch (n) { \
895c2d04
BS
1471 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1472 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1473 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1474 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1475 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1476 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1477 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1478 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1479 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1480 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1481 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1482 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1483 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1484 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1485 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1486 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1487 default: abort(); \
1488 } \
1489 tcg_temp_free_i##bits (fp0); \
1490 tcg_temp_free_i##bits (fp1); \
1491}
1492
1493FOP_CONDS(, 0, d, FMT_D, 64)
1494FOP_CONDS(abs, 1, d, FMT_D, 64)
1495FOP_CONDS(, 0, s, FMT_S, 32)
1496FOP_CONDS(abs, 1, s, FMT_S, 32)
1497FOP_CONDS(, 0, ps, FMT_PS, 64)
1498FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1499#undef FOP_CONDS
1500#undef gen_ldcmp_fpr32
1501#undef gen_ldcmp_fpr64
1502
958fb4a9 1503/* load/store instructions. */
e7139c44 1504#ifdef CONFIG_USER_ONLY
d9bea114 1505#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1506static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1507{ \
1508 TCGv t0 = tcg_temp_new(); \
1509 tcg_gen_mov_tl(t0, arg1); \
1510 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1511 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1512 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1513 tcg_temp_free(t0); \
aaa9128a 1514}
e7139c44
AJ
1515#else
1516#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1517static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1518{ \
895c2d04 1519 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1520}
1521#endif
aaa9128a
TS
1522OP_LD_ATOMIC(ll,ld32s);
1523#if defined(TARGET_MIPS64)
1524OP_LD_ATOMIC(lld,ld64);
1525#endif
1526#undef OP_LD_ATOMIC
1527
590bc601
PB
1528#ifdef CONFIG_USER_ONLY
1529#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1530static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1531{ \
1532 TCGv t0 = tcg_temp_new(); \
1533 int l1 = gen_new_label(); \
1534 int l2 = gen_new_label(); \
1535 \
1536 tcg_gen_andi_tl(t0, arg2, almask); \
1537 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1538 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1539 generate_exception(ctx, EXCP_AdES); \
1540 gen_set_label(l1); \
7db13fae 1541 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1542 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1543 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1544 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1545 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1546 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1547 gen_set_label(l2); \
1548 tcg_gen_movi_tl(t0, 0); \
1549 gen_store_gpr(t0, rt); \
1550 tcg_temp_free(t0); \
1551}
1552#else
1553#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1554static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1555{ \
1556 TCGv t0 = tcg_temp_new(); \
895c2d04 1557 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1558 gen_store_gpr(t0, rt); \
590bc601
PB
1559 tcg_temp_free(t0); \
1560}
1561#endif
590bc601 1562OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1563#if defined(TARGET_MIPS64)
590bc601 1564OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1565#endif
1566#undef OP_ST_ATOMIC
1567
662d7485
NF
1568static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1569 int base, int16_t offset)
1570{
1571 if (base == 0) {
1572 tcg_gen_movi_tl(addr, offset);
1573 } else if (offset == 0) {
1574 gen_load_gpr(addr, base);
1575 } else {
1576 tcg_gen_movi_tl(addr, offset);
1577 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1578 }
1579}
1580
364d4831
NF
1581static target_ulong pc_relative_pc (DisasContext *ctx)
1582{
1583 target_ulong pc = ctx->pc;
1584
1585 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1586 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1587
1588 pc -= branch_bytes;
1589 }
1590
1591 pc &= ~(target_ulong)3;
1592 return pc;
1593}
1594
5c13fdfd 1595/* Load */
d75c135e
AJ
1596static void gen_ld(DisasContext *ctx, uint32_t opc,
1597 int rt, int base, int16_t offset)
6af0bf9c 1598{
5c13fdfd 1599 const char *opn = "ld";
fc40787a 1600 TCGv t0, t1, t2;
afa88c3a 1601
d75c135e 1602 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1603 /* Loongson CPU uses a load to zero register for prefetch.
1604 We emulate it as a NOP. On other CPU we must perform the
1605 actual memory access. */
1606 MIPS_DEBUG("NOP");
1607 return;
1608 }
6af0bf9c 1609
afa88c3a 1610 t0 = tcg_temp_new();
662d7485 1611 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1612
6af0bf9c 1613 switch (opc) {
d26bc211 1614#if defined(TARGET_MIPS64)
6e473128 1615 case OPC_LWU:
5f68f5ae 1616 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 1617 gen_store_gpr(t0, rt);
6e473128
TS
1618 opn = "lwu";
1619 break;
6af0bf9c 1620 case OPC_LD:
5f68f5ae 1621 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 1622 gen_store_gpr(t0, rt);
6af0bf9c
FB
1623 opn = "ld";
1624 break;
7a387fff 1625 case OPC_LLD:
b835e919 1626 save_cpu_state(ctx, 1);
5c13fdfd 1627 op_ld_lld(t0, t0, ctx);
78723684 1628 gen_store_gpr(t0, rt);
7a387fff
TS
1629 opn = "lld";
1630 break;
6af0bf9c 1631 case OPC_LDL:
3cee3050 1632 t1 = tcg_temp_new();
fc40787a
AJ
1633 tcg_gen_andi_tl(t1, t0, 7);
1634#ifndef TARGET_WORDS_BIGENDIAN
1635 tcg_gen_xori_tl(t1, t1, 7);
1636#endif
1637 tcg_gen_shli_tl(t1, t1, 3);
1638 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1639 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1640 tcg_gen_shl_tl(t0, t0, t1);
1641 tcg_gen_xori_tl(t1, t1, 63);
1642 t2 = tcg_const_tl(0x7fffffffffffffffull);
1643 tcg_gen_shr_tl(t2, t2, t1);
78723684 1644 gen_load_gpr(t1, rt);
fc40787a
AJ
1645 tcg_gen_and_tl(t1, t1, t2);
1646 tcg_temp_free(t2);
1647 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1648 tcg_temp_free(t1);
fc40787a 1649 gen_store_gpr(t0, rt);
6af0bf9c
FB
1650 opn = "ldl";
1651 break;
6af0bf9c 1652 case OPC_LDR:
3cee3050 1653 t1 = tcg_temp_new();
fc40787a
AJ
1654 tcg_gen_andi_tl(t1, t0, 7);
1655#ifdef TARGET_WORDS_BIGENDIAN
1656 tcg_gen_xori_tl(t1, t1, 7);
1657#endif
1658 tcg_gen_shli_tl(t1, t1, 3);
1659 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1660 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1661 tcg_gen_shr_tl(t0, t0, t1);
1662 tcg_gen_xori_tl(t1, t1, 63);
1663 t2 = tcg_const_tl(0xfffffffffffffffeull);
1664 tcg_gen_shl_tl(t2, t2, t1);
78723684 1665 gen_load_gpr(t1, rt);
fc40787a
AJ
1666 tcg_gen_and_tl(t1, t1, t2);
1667 tcg_temp_free(t2);
1668 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1669 tcg_temp_free(t1);
fc40787a 1670 gen_store_gpr(t0, rt);
6af0bf9c
FB
1671 opn = "ldr";
1672 break;
364d4831 1673 case OPC_LDPC:
3cee3050 1674 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1675 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1676 tcg_temp_free(t1);
5f68f5ae 1677 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 1678 gen_store_gpr(t0, rt);
5c13fdfd 1679 opn = "ldpc";
364d4831 1680 break;
6af0bf9c 1681#endif
364d4831 1682 case OPC_LWPC:
3cee3050 1683 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1684 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1685 tcg_temp_free(t1);
5f68f5ae 1686 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 1687 gen_store_gpr(t0, rt);
5c13fdfd 1688 opn = "lwpc";
364d4831 1689 break;
6af0bf9c 1690 case OPC_LW:
5f68f5ae 1691 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 1692 gen_store_gpr(t0, rt);
6af0bf9c
FB
1693 opn = "lw";
1694 break;
6af0bf9c 1695 case OPC_LH:
5f68f5ae 1696 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 1697 gen_store_gpr(t0, rt);
6af0bf9c
FB
1698 opn = "lh";
1699 break;
6af0bf9c 1700 case OPC_LHU:
5f68f5ae 1701 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 1702 gen_store_gpr(t0, rt);
6af0bf9c
FB
1703 opn = "lhu";
1704 break;
1705 case OPC_LB:
5f68f5ae 1706 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 1707 gen_store_gpr(t0, rt);
6af0bf9c
FB
1708 opn = "lb";
1709 break;
6af0bf9c 1710 case OPC_LBU:
5f68f5ae 1711 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 1712 gen_store_gpr(t0, rt);
6af0bf9c
FB
1713 opn = "lbu";
1714 break;
1715 case OPC_LWL:
3cee3050 1716 t1 = tcg_temp_new();
fc40787a
AJ
1717 tcg_gen_andi_tl(t1, t0, 3);
1718#ifndef TARGET_WORDS_BIGENDIAN
1719 tcg_gen_xori_tl(t1, t1, 3);
1720#endif
1721 tcg_gen_shli_tl(t1, t1, 3);
1722 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1723 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1724 tcg_gen_shl_tl(t0, t0, t1);
1725 tcg_gen_xori_tl(t1, t1, 31);
1726 t2 = tcg_const_tl(0x7fffffffull);
1727 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1728 gen_load_gpr(t1, rt);
fc40787a
AJ
1729 tcg_gen_and_tl(t1, t1, t2);
1730 tcg_temp_free(t2);
1731 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1732 tcg_temp_free(t1);
fc40787a
AJ
1733 tcg_gen_ext32s_tl(t0, t0);
1734 gen_store_gpr(t0, rt);
6af0bf9c
FB
1735 opn = "lwl";
1736 break;
6af0bf9c 1737 case OPC_LWR:
3cee3050 1738 t1 = tcg_temp_new();
fc40787a
AJ
1739 tcg_gen_andi_tl(t1, t0, 3);
1740#ifdef TARGET_WORDS_BIGENDIAN
1741 tcg_gen_xori_tl(t1, t1, 3);
1742#endif
1743 tcg_gen_shli_tl(t1, t1, 3);
1744 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1745 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1746 tcg_gen_shr_tl(t0, t0, t1);
1747 tcg_gen_xori_tl(t1, t1, 31);
1748 t2 = tcg_const_tl(0xfffffffeull);
1749 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1750 gen_load_gpr(t1, rt);
fc40787a
AJ
1751 tcg_gen_and_tl(t1, t1, t2);
1752 tcg_temp_free(t2);
1753 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1754 tcg_temp_free(t1);
c728154b 1755 tcg_gen_ext32s_tl(t0, t0);
fc40787a 1756 gen_store_gpr(t0, rt);
6af0bf9c
FB
1757 opn = "lwr";
1758 break;
6af0bf9c 1759 case OPC_LL:
e7139c44 1760 save_cpu_state(ctx, 1);
5c13fdfd 1761 op_ld_ll(t0, t0, ctx);
78723684 1762 gen_store_gpr(t0, rt);
6af0bf9c
FB
1763 opn = "ll";
1764 break;
d66c7132 1765 }
2abf314d 1766 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1767 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1768 tcg_temp_free(t0);
d66c7132
AJ
1769}
1770
5c13fdfd
AJ
1771/* Store */
1772static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1773 int base, int16_t offset)
1774{
1775 const char *opn = "st";
1776 TCGv t0 = tcg_temp_new();
1777 TCGv t1 = tcg_temp_new();
1778
1779 gen_base_offset_addr(ctx, t0, base, offset);
1780 gen_load_gpr(t1, rt);
1781 switch (opc) {
1782#if defined(TARGET_MIPS64)
1783 case OPC_SD:
5f68f5ae 1784 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
1785 opn = "sd";
1786 break;
1787 case OPC_SDL:
1788 save_cpu_state(ctx, 1);
895c2d04 1789 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1790 opn = "sdl";
1791 break;
1792 case OPC_SDR:
1793 save_cpu_state(ctx, 1);
895c2d04 1794 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1795 opn = "sdr";
1796 break;
1797#endif
1798 case OPC_SW:
5f68f5ae 1799 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
1800 opn = "sw";
1801 break;
1802 case OPC_SH:
5f68f5ae 1803 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
1804 opn = "sh";
1805 break;
1806 case OPC_SB:
5f68f5ae 1807 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
1808 opn = "sb";
1809 break;
1810 case OPC_SWL:
1811 save_cpu_state(ctx, 1);
895c2d04 1812 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1813 opn = "swl";
1814 break;
1815 case OPC_SWR:
1816 save_cpu_state(ctx, 1);
895c2d04 1817 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1818 opn = "swr";
1819 break;
1820 }
2abf314d 1821 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1822 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1823 tcg_temp_free(t0);
1824 tcg_temp_free(t1);
1825}
1826
1827
d66c7132
AJ
1828/* Store conditional */
1829static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1830 int base, int16_t offset)
1831{
1832 const char *opn = "st_cond";
1833 TCGv t0, t1;
1834
2d2826b9 1835#ifdef CONFIG_USER_ONLY
d66c7132 1836 t0 = tcg_temp_local_new();
d66c7132 1837 t1 = tcg_temp_local_new();
2d2826b9
AJ
1838#else
1839 t0 = tcg_temp_new();
1840 t1 = tcg_temp_new();
1841#endif
1842 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1843 gen_load_gpr(t1, rt);
1844 switch (opc) {
1845#if defined(TARGET_MIPS64)
1846 case OPC_SCD:
b835e919 1847 save_cpu_state(ctx, 1);
5c13fdfd 1848 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1849 opn = "scd";
1850 break;
1851#endif
6af0bf9c 1852 case OPC_SC:
e7139c44 1853 save_cpu_state(ctx, 1);
5c13fdfd 1854 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1855 opn = "sc";
1856 break;
6af0bf9c 1857 }
2abf314d 1858 (void)opn; /* avoid a compiler warning */
6af0bf9c 1859 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1860 tcg_temp_free(t1);
d66c7132 1861 tcg_temp_free(t0);
6af0bf9c
FB
1862}
1863
6ea83fed 1864/* Load and store */
7a387fff 1865static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1866 int base, int16_t offset)
6ea83fed 1867{
923617a3 1868 const char *opn = "flt_ldst";
4e2474d6 1869 TCGv t0 = tcg_temp_new();
6ea83fed 1870
662d7485 1871 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1872 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1873 memory access. */
6ea83fed
FB
1874 switch (opc) {
1875 case OPC_LWC1:
b6d96bed 1876 {
a7812ae4 1877 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 1878 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 1879 gen_store_fpr32(fp0, ft);
a7812ae4 1880 tcg_temp_free_i32(fp0);
b6d96bed 1881 }
6ea83fed
FB
1882 opn = "lwc1";
1883 break;
1884 case OPC_SWC1:
b6d96bed 1885 {
a7812ae4 1886 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1887 gen_load_fpr32(fp0, ft);
5f68f5ae 1888 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 1889 tcg_temp_free_i32(fp0);
b6d96bed 1890 }
6ea83fed
FB
1891 opn = "swc1";
1892 break;
1893 case OPC_LDC1:
b6d96bed 1894 {
a7812ae4 1895 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 1896 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 1897 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1898 tcg_temp_free_i64(fp0);
b6d96bed 1899 }
6ea83fed
FB
1900 opn = "ldc1";
1901 break;
1902 case OPC_SDC1:
b6d96bed 1903 {
a7812ae4 1904 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 1905 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 1906 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 1907 tcg_temp_free_i64(fp0);
b6d96bed 1908 }
6ea83fed
FB
1909 opn = "sdc1";
1910 break;
1911 default:
923617a3 1912 MIPS_INVAL(opn);
e397ee33 1913 generate_exception(ctx, EXCP_RI);
78723684 1914 goto out;
6ea83fed 1915 }
2abf314d 1916 (void)opn; /* avoid a compiler warning */
6ea83fed 1917 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1918 out:
1919 tcg_temp_free(t0);
6ea83fed 1920}
6ea83fed 1921
7db13fae 1922static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
26ebe468
NF
1923 uint32_t op, int rt, int rs, int16_t imm)
1924{
1925 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1926 check_cp1_enabled(ctx);
1927 gen_flt_ldst(ctx, op, rt, rs, imm);
1928 } else {
1929 generate_exception_err(ctx, EXCP_CpU, 1);
1930 }
1931}
1932
6af0bf9c 1933/* Arithmetic with immediate operand */
d75c135e
AJ
1934static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1935 int rt, int rs, int16_t imm)
6af0bf9c 1936{
324d9e32 1937 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1938 const char *opn = "imm arith";
6af0bf9c 1939
7a387fff 1940 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1941 /* If no destination, treat it as a NOP.
1942 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1943 MIPS_DEBUG("NOP");
324d9e32 1944 return;
6af0bf9c
FB
1945 }
1946 switch (opc) {
1947 case OPC_ADDI:
48d38ca5 1948 {
324d9e32
AJ
1949 TCGv t0 = tcg_temp_local_new();
1950 TCGv t1 = tcg_temp_new();
1951 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1952 int l1 = gen_new_label();
1953
324d9e32
AJ
1954 gen_load_gpr(t1, rs);
1955 tcg_gen_addi_tl(t0, t1, uimm);
1956 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1957
324d9e32
AJ
1958 tcg_gen_xori_tl(t1, t1, ~uimm);
1959 tcg_gen_xori_tl(t2, t0, uimm);
1960 tcg_gen_and_tl(t1, t1, t2);
1961 tcg_temp_free(t2);
1962 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1963 tcg_temp_free(t1);
48d38ca5
TS
1964 /* operands of same sign, result different sign */
1965 generate_exception(ctx, EXCP_OVERFLOW);
1966 gen_set_label(l1);
78723684 1967 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1968 gen_store_gpr(t0, rt);
1969 tcg_temp_free(t0);
48d38ca5 1970 }
6af0bf9c
FB
1971 opn = "addi";
1972 break;
1973 case OPC_ADDIU:
324d9e32
AJ
1974 if (rs != 0) {
1975 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1976 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1977 } else {
1978 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1979 }
6af0bf9c
FB
1980 opn = "addiu";
1981 break;
d26bc211 1982#if defined(TARGET_MIPS64)
7a387fff 1983 case OPC_DADDI:
48d38ca5 1984 {
324d9e32
AJ
1985 TCGv t0 = tcg_temp_local_new();
1986 TCGv t1 = tcg_temp_new();
1987 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1988 int l1 = gen_new_label();
1989
324d9e32
AJ
1990 gen_load_gpr(t1, rs);
1991 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1992
324d9e32
AJ
1993 tcg_gen_xori_tl(t1, t1, ~uimm);
1994 tcg_gen_xori_tl(t2, t0, uimm);
1995 tcg_gen_and_tl(t1, t1, t2);
1996 tcg_temp_free(t2);
1997 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1998 tcg_temp_free(t1);
48d38ca5
TS
1999 /* operands of same sign, result different sign */
2000 generate_exception(ctx, EXCP_OVERFLOW);
2001 gen_set_label(l1);
324d9e32
AJ
2002 gen_store_gpr(t0, rt);
2003 tcg_temp_free(t0);
48d38ca5 2004 }
7a387fff
TS
2005 opn = "daddi";
2006 break;
2007 case OPC_DADDIU:
324d9e32
AJ
2008 if (rs != 0) {
2009 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2010 } else {
2011 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2012 }
7a387fff
TS
2013 opn = "daddiu";
2014 break;
2015#endif
324d9e32 2016 }
2abf314d 2017 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2018 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2019}
2020
2021/* Logic with immediate operand */
d75c135e 2022static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2023 int rt, int rs, int16_t imm)
324d9e32
AJ
2024{
2025 target_ulong uimm;
324d9e32
AJ
2026
2027 if (rt == 0) {
2028 /* If no destination, treat it as a NOP. */
2029 MIPS_DEBUG("NOP");
2030 return;
2031 }
2032 uimm = (uint16_t)imm;
2033 switch (opc) {
6af0bf9c 2034 case OPC_ANDI:
324d9e32
AJ
2035 if (likely(rs != 0))
2036 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2037 else
2038 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2039 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2040 regnames[rs], uimm);
6af0bf9c
FB
2041 break;
2042 case OPC_ORI:
324d9e32
AJ
2043 if (rs != 0)
2044 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2045 else
2046 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2047 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2048 regnames[rs], uimm);
6af0bf9c
FB
2049 break;
2050 case OPC_XORI:
324d9e32
AJ
2051 if (likely(rs != 0))
2052 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2053 else
2054 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2055 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2056 regnames[rs], uimm);
6af0bf9c
FB
2057 break;
2058 case OPC_LUI:
324d9e32 2059 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2060 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2061 break;
2062
2063 default:
2064 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2065 break;
324d9e32 2066 }
324d9e32
AJ
2067}
2068
2069/* Set on less than with immediate operand */
d75c135e 2070static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2071 int rt, int rs, int16_t imm)
324d9e32
AJ
2072{
2073 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2074 const char *opn = "imm arith";
2075 TCGv t0;
2076
2077 if (rt == 0) {
2078 /* If no destination, treat it as a NOP. */
2079 MIPS_DEBUG("NOP");
2080 return;
2081 }
2082 t0 = tcg_temp_new();
2083 gen_load_gpr(t0, rs);
2084 switch (opc) {
2085 case OPC_SLTI:
e68dd28f 2086 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2087 opn = "slti";
2088 break;
2089 case OPC_SLTIU:
e68dd28f 2090 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2091 opn = "sltiu";
2092 break;
2093 }
2abf314d 2094 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2095 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2096 tcg_temp_free(t0);
2097}
2098
2099/* Shifts with immediate operand */
d75c135e 2100static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2101 int rt, int rs, int16_t imm)
2102{
2103 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2104 const char *opn = "imm shift";
2105 TCGv t0;
2106
2107 if (rt == 0) {
2108 /* If no destination, treat it as a NOP. */
2109 MIPS_DEBUG("NOP");
2110 return;
2111 }
2112
2113 t0 = tcg_temp_new();
2114 gen_load_gpr(t0, rs);
2115 switch (opc) {
6af0bf9c 2116 case OPC_SLL:
78723684 2117 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2118 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2119 opn = "sll";
2120 break;
2121 case OPC_SRA:
324d9e32 2122 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2123 opn = "sra";
2124 break;
2125 case OPC_SRL:
ea63e2c3
NF
2126 if (uimm != 0) {
2127 tcg_gen_ext32u_tl(t0, t0);
2128 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2129 } else {
2130 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2131 }
ea63e2c3
NF
2132 opn = "srl";
2133 break;
2134 case OPC_ROTR:
2135 if (uimm != 0) {
2136 TCGv_i32 t1 = tcg_temp_new_i32();
2137
2138 tcg_gen_trunc_tl_i32(t1, t0);
2139 tcg_gen_rotri_i32(t1, t1, uimm);
2140 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2141 tcg_temp_free_i32(t1);
3399e30f
NF
2142 } else {
2143 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2144 }
2145 opn = "rotr";
7a387fff 2146 break;
d26bc211 2147#if defined(TARGET_MIPS64)
7a387fff 2148 case OPC_DSLL:
324d9e32 2149 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2150 opn = "dsll";
2151 break;
2152 case OPC_DSRA:
324d9e32 2153 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2154 opn = "dsra";
2155 break;
2156 case OPC_DSRL:
ea63e2c3
NF
2157 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2158 opn = "dsrl";
2159 break;
2160 case OPC_DROTR:
2161 if (uimm != 0) {
2162 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2163 } else {
2164 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2165 }
ea63e2c3 2166 opn = "drotr";
7a387fff
TS
2167 break;
2168 case OPC_DSLL32:
324d9e32 2169 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2170 opn = "dsll32";
2171 break;
2172 case OPC_DSRA32:
324d9e32 2173 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2174 opn = "dsra32";
2175 break;
2176 case OPC_DSRL32:
ea63e2c3
NF
2177 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2178 opn = "dsrl32";
2179 break;
2180 case OPC_DROTR32:
2181 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2182 opn = "drotr32";
6af0bf9c 2183 break;
7a387fff 2184#endif
6af0bf9c 2185 }
2abf314d 2186 (void)opn; /* avoid a compiler warning */
93b12ccc 2187 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2188 tcg_temp_free(t0);
6af0bf9c
FB
2189}
2190
2191/* Arithmetic */
d75c135e
AJ
2192static void gen_arith(DisasContext *ctx, uint32_t opc,
2193 int rd, int rs, int rt)
6af0bf9c 2194{
923617a3 2195 const char *opn = "arith";
6af0bf9c 2196
7a387fff
TS
2197 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2198 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2199 /* If no destination, treat it as a NOP.
2200 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2201 MIPS_DEBUG("NOP");
460f00c4 2202 return;
185f0762 2203 }
460f00c4 2204
6af0bf9c
FB
2205 switch (opc) {
2206 case OPC_ADD:
48d38ca5 2207 {
460f00c4
AJ
2208 TCGv t0 = tcg_temp_local_new();
2209 TCGv t1 = tcg_temp_new();
2210 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2211 int l1 = gen_new_label();
2212
460f00c4
AJ
2213 gen_load_gpr(t1, rs);
2214 gen_load_gpr(t2, rt);
2215 tcg_gen_add_tl(t0, t1, t2);
2216 tcg_gen_ext32s_tl(t0, t0);
2217 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2218 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2219 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2220 tcg_temp_free(t2);
2221 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2222 tcg_temp_free(t1);
48d38ca5
TS
2223 /* operands of same sign, result different sign */
2224 generate_exception(ctx, EXCP_OVERFLOW);
2225 gen_set_label(l1);
460f00c4
AJ
2226 gen_store_gpr(t0, rd);
2227 tcg_temp_free(t0);
48d38ca5 2228 }
6af0bf9c
FB
2229 opn = "add";
2230 break;
2231 case OPC_ADDU:
460f00c4
AJ
2232 if (rs != 0 && rt != 0) {
2233 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2234 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2235 } else if (rs == 0 && rt != 0) {
2236 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2237 } else if (rs != 0 && rt == 0) {
2238 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2239 } else {
2240 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2241 }
6af0bf9c
FB
2242 opn = "addu";
2243 break;
2244 case OPC_SUB:
48d38ca5 2245 {
460f00c4
AJ
2246 TCGv t0 = tcg_temp_local_new();
2247 TCGv t1 = tcg_temp_new();
2248 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2249 int l1 = gen_new_label();
2250
460f00c4
AJ
2251 gen_load_gpr(t1, rs);
2252 gen_load_gpr(t2, rt);
2253 tcg_gen_sub_tl(t0, t1, t2);
2254 tcg_gen_ext32s_tl(t0, t0);
2255 tcg_gen_xor_tl(t2, t1, t2);
2256 tcg_gen_xor_tl(t1, t0, t1);
2257 tcg_gen_and_tl(t1, t1, t2);
2258 tcg_temp_free(t2);
2259 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2260 tcg_temp_free(t1);
31e3104f 2261 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2262 generate_exception(ctx, EXCP_OVERFLOW);
2263 gen_set_label(l1);
460f00c4
AJ
2264 gen_store_gpr(t0, rd);
2265 tcg_temp_free(t0);
48d38ca5 2266 }
6af0bf9c
FB
2267 opn = "sub";
2268 break;
2269 case OPC_SUBU:
460f00c4
AJ
2270 if (rs != 0 && rt != 0) {
2271 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2272 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2273 } else if (rs == 0 && rt != 0) {
2274 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2275 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2276 } else if (rs != 0 && rt == 0) {
2277 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2278 } else {
2279 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2280 }
6af0bf9c
FB
2281 opn = "subu";
2282 break;
d26bc211 2283#if defined(TARGET_MIPS64)
7a387fff 2284 case OPC_DADD:
48d38ca5 2285 {
460f00c4
AJ
2286 TCGv t0 = tcg_temp_local_new();
2287 TCGv t1 = tcg_temp_new();
2288 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2289 int l1 = gen_new_label();
2290
460f00c4
AJ
2291 gen_load_gpr(t1, rs);
2292 gen_load_gpr(t2, rt);
2293 tcg_gen_add_tl(t0, t1, t2);
2294 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2295 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2296 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2297 tcg_temp_free(t2);
2298 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2299 tcg_temp_free(t1);
48d38ca5
TS
2300 /* operands of same sign, result different sign */
2301 generate_exception(ctx, EXCP_OVERFLOW);
2302 gen_set_label(l1);
460f00c4
AJ
2303 gen_store_gpr(t0, rd);
2304 tcg_temp_free(t0);
48d38ca5 2305 }
7a387fff
TS
2306 opn = "dadd";
2307 break;
2308 case OPC_DADDU:
460f00c4
AJ
2309 if (rs != 0 && rt != 0) {
2310 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2311 } else if (rs == 0 && rt != 0) {
2312 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2313 } else if (rs != 0 && rt == 0) {
2314 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2315 } else {
2316 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2317 }
7a387fff
TS
2318 opn = "daddu";
2319 break;
2320 case OPC_DSUB:
48d38ca5 2321 {
460f00c4
AJ
2322 TCGv t0 = tcg_temp_local_new();
2323 TCGv t1 = tcg_temp_new();
2324 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2325 int l1 = gen_new_label();
2326
460f00c4
AJ
2327 gen_load_gpr(t1, rs);
2328 gen_load_gpr(t2, rt);
2329 tcg_gen_sub_tl(t0, t1, t2);
2330 tcg_gen_xor_tl(t2, t1, t2);
2331 tcg_gen_xor_tl(t1, t0, t1);
2332 tcg_gen_and_tl(t1, t1, t2);
2333 tcg_temp_free(t2);
2334 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2335 tcg_temp_free(t1);
31e3104f 2336 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2337 generate_exception(ctx, EXCP_OVERFLOW);
2338 gen_set_label(l1);
460f00c4
AJ
2339 gen_store_gpr(t0, rd);
2340 tcg_temp_free(t0);
48d38ca5 2341 }
7a387fff
TS
2342 opn = "dsub";
2343 break;
2344 case OPC_DSUBU:
460f00c4
AJ
2345 if (rs != 0 && rt != 0) {
2346 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2347 } else if (rs == 0 && rt != 0) {
2348 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2349 } else if (rs != 0 && rt == 0) {
2350 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2351 } else {
2352 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2353 }
7a387fff
TS
2354 opn = "dsubu";
2355 break;
2356#endif
460f00c4
AJ
2357 case OPC_MUL:
2358 if (likely(rs != 0 && rt != 0)) {
2359 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2360 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2361 } else {
2362 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2363 }
2364 opn = "mul";
6af0bf9c 2365 break;
460f00c4 2366 }
2abf314d 2367 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2368 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2369}
2370
2371/* Conditional move */
d75c135e 2372static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2373 int rd, int rs, int rt)
460f00c4
AJ
2374{
2375 const char *opn = "cond move";
acf12465 2376 TCGv t0, t1, t2;
460f00c4
AJ
2377
2378 if (rd == 0) {
acf12465 2379 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2380 MIPS_DEBUG("NOP");
2381 return;
2382 }
2383
acf12465
AJ
2384 t0 = tcg_temp_new();
2385 gen_load_gpr(t0, rt);
2386 t1 = tcg_const_tl(0);
2387 t2 = tcg_temp_new();
2388 gen_load_gpr(t2, rs);
460f00c4
AJ
2389 switch (opc) {
2390 case OPC_MOVN:
acf12465 2391 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2392 opn = "movn";
6af0bf9c 2393 break;
460f00c4 2394 case OPC_MOVZ:
acf12465 2395 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2396 opn = "movz";
2397 break;
2398 }
acf12465
AJ
2399 tcg_temp_free(t2);
2400 tcg_temp_free(t1);
2401 tcg_temp_free(t0);
460f00c4 2402
2abf314d 2403 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2404 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2405}
2406
2407/* Logic */
d75c135e 2408static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2409 int rd, int rs, int rt)
460f00c4
AJ
2410{
2411 const char *opn = "logic";
2412
2413 if (rd == 0) {
2414 /* If no destination, treat it as a NOP. */
2415 MIPS_DEBUG("NOP");
2416 return;
2417 }
2418
2419 switch (opc) {
6af0bf9c 2420 case OPC_AND:
460f00c4
AJ
2421 if (likely(rs != 0 && rt != 0)) {
2422 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2423 } else {
2424 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2425 }
6af0bf9c
FB
2426 opn = "and";
2427 break;
2428 case OPC_NOR:
460f00c4
AJ
2429 if (rs != 0 && rt != 0) {
2430 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2431 } else if (rs == 0 && rt != 0) {
2432 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2433 } else if (rs != 0 && rt == 0) {
2434 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2435 } else {
2436 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2437 }
6af0bf9c
FB
2438 opn = "nor";
2439 break;
2440 case OPC_OR:
460f00c4
AJ
2441 if (likely(rs != 0 && rt != 0)) {
2442 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2443 } else if (rs == 0 && rt != 0) {
2444 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2445 } else if (rs != 0 && rt == 0) {
2446 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2447 } else {
2448 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2449 }
6af0bf9c
FB
2450 opn = "or";
2451 break;
2452 case OPC_XOR:
460f00c4
AJ
2453 if (likely(rs != 0 && rt != 0)) {
2454 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2455 } else if (rs == 0 && rt != 0) {
2456 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2457 } else if (rs != 0 && rt == 0) {
2458 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2459 } else {
2460 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2461 }
6af0bf9c
FB
2462 opn = "xor";
2463 break;
460f00c4 2464 }
2abf314d 2465 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2466 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2467}
2468
2469/* Set on lower than */
d75c135e 2470static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2471 int rd, int rs, int rt)
460f00c4
AJ
2472{
2473 const char *opn = "slt";
2474 TCGv t0, t1;
2475
2476 if (rd == 0) {
2477 /* If no destination, treat it as a NOP. */
2478 MIPS_DEBUG("NOP");
2479 return;
2480 }
2481
2482 t0 = tcg_temp_new();
2483 t1 = tcg_temp_new();
2484 gen_load_gpr(t0, rs);
2485 gen_load_gpr(t1, rt);
2486 switch (opc) {
2487 case OPC_SLT:
e68dd28f 2488 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2489 opn = "slt";
6af0bf9c 2490 break;
460f00c4 2491 case OPC_SLTU:
e68dd28f 2492 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2493 opn = "sltu";
2494 break;
2495 }
2abf314d 2496 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2497 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2498 tcg_temp_free(t0);
2499 tcg_temp_free(t1);
2500}
20c4c97c 2501
460f00c4 2502/* Shifts */
d75c135e
AJ
2503static void gen_shift(DisasContext *ctx, uint32_t opc,
2504 int rd, int rs, int rt)
460f00c4
AJ
2505{
2506 const char *opn = "shifts";
2507 TCGv t0, t1;
20c4c97c 2508
460f00c4
AJ
2509 if (rd == 0) {
2510 /* If no destination, treat it as a NOP.
2511 For add & sub, we must generate the overflow exception when needed. */
2512 MIPS_DEBUG("NOP");
2513 return;
2514 }
2515
2516 t0 = tcg_temp_new();
2517 t1 = tcg_temp_new();
2518 gen_load_gpr(t0, rs);
2519 gen_load_gpr(t1, rt);
2520 switch (opc) {
6af0bf9c 2521 case OPC_SLLV:
78723684
TS
2522 tcg_gen_andi_tl(t0, t0, 0x1f);
2523 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2524 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2525 opn = "sllv";
2526 break;
2527 case OPC_SRAV:
78723684 2528 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2529 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2530 opn = "srav";
2531 break;
2532 case OPC_SRLV:
ea63e2c3
NF
2533 tcg_gen_ext32u_tl(t1, t1);
2534 tcg_gen_andi_tl(t0, t0, 0x1f);
2535 tcg_gen_shr_tl(t0, t1, t0);
2536 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2537 opn = "srlv";
2538 break;
2539 case OPC_ROTRV:
2540 {
2541 TCGv_i32 t2 = tcg_temp_new_i32();
2542 TCGv_i32 t3 = tcg_temp_new_i32();
2543
2544 tcg_gen_trunc_tl_i32(t2, t0);
2545 tcg_gen_trunc_tl_i32(t3, t1);
2546 tcg_gen_andi_i32(t2, t2, 0x1f);
2547 tcg_gen_rotr_i32(t2, t3, t2);
2548 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2549 tcg_temp_free_i32(t2);
2550 tcg_temp_free_i32(t3);
2551 opn = "rotrv";
5a63bcb2 2552 }
7a387fff 2553 break;
d26bc211 2554#if defined(TARGET_MIPS64)
7a387fff 2555 case OPC_DSLLV:
78723684 2556 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2557 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2558 opn = "dsllv";
2559 break;
2560 case OPC_DSRAV:
78723684 2561 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2562 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2563 opn = "dsrav";
2564 break;
2565 case OPC_DSRLV:
ea63e2c3
NF
2566 tcg_gen_andi_tl(t0, t0, 0x3f);
2567 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2568 opn = "dsrlv";
2569 break;
2570 case OPC_DROTRV:
2571 tcg_gen_andi_tl(t0, t0, 0x3f);
2572 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2573 opn = "drotrv";
6af0bf9c 2574 break;
7a387fff 2575#endif
6af0bf9c 2576 }
2abf314d 2577 (void)opn; /* avoid a compiler warning */
6af0bf9c 2578 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2579 tcg_temp_free(t0);
2580 tcg_temp_free(t1);
6af0bf9c
FB
2581}
2582
2583/* Arithmetic on HI/LO registers */
26135ead 2584static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 2585{
923617a3 2586 const char *opn = "hilo";
6af0bf9c
FB
2587
2588 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2589 /* Treat as NOP. */
6af0bf9c 2590 MIPS_DEBUG("NOP");
a1f6684d 2591 return;
6af0bf9c 2592 }
4133498f 2593
4133498f
JL
2594 if (acc != 0) {
2595 check_dsp(ctx);
2596 }
2597
6af0bf9c
FB
2598 switch (opc) {
2599 case OPC_MFHI:
4133498f
JL
2600#if defined(TARGET_MIPS64)
2601 if (acc != 0) {
2602 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2603 } else
2604#endif
2605 {
2606 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2607 }
6af0bf9c
FB
2608 opn = "mfhi";
2609 break;
2610 case OPC_MFLO:
4133498f
JL
2611#if defined(TARGET_MIPS64)
2612 if (acc != 0) {
2613 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2614 } else
2615#endif
2616 {
2617 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2618 }
6af0bf9c
FB
2619 opn = "mflo";
2620 break;
2621 case OPC_MTHI:
4133498f
JL
2622 if (reg != 0) {
2623#if defined(TARGET_MIPS64)
2624 if (acc != 0) {
2625 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2626 } else
2627#endif
2628 {
2629 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2630 }
2631 } else {
2632 tcg_gen_movi_tl(cpu_HI[acc], 0);
2633 }
6af0bf9c
FB
2634 opn = "mthi";
2635 break;
2636 case OPC_MTLO:
4133498f
JL
2637 if (reg != 0) {
2638#if defined(TARGET_MIPS64)
2639 if (acc != 0) {
2640 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2641 } else
2642#endif
2643 {
2644 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2645 }
2646 } else {
2647 tcg_gen_movi_tl(cpu_LO[acc], 0);
2648 }
6af0bf9c
FB
2649 opn = "mtlo";
2650 break;
6af0bf9c 2651 }
2abf314d 2652 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2653 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2654}
2655
26135ead
RS
2656static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2657 int acc, int rs, int rt)
6af0bf9c 2658{
923617a3 2659 const char *opn = "mul/div";
d45f89f4
AJ
2660 TCGv t0, t1;
2661
51127181
AJ
2662 t0 = tcg_temp_new();
2663 t1 = tcg_temp_new();
6af0bf9c 2664
78723684
TS
2665 gen_load_gpr(t0, rs);
2666 gen_load_gpr(t1, rt);
51127181 2667
26135ead
RS
2668 if (acc != 0) {
2669 check_dsp(ctx);
2670 }
2671
6af0bf9c
FB
2672 switch (opc) {
2673 case OPC_DIV:
48d38ca5 2674 {
51127181
AJ
2675 TCGv t2 = tcg_temp_new();
2676 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2677 tcg_gen_ext32s_tl(t0, t0);
2678 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2679 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2680 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2681 tcg_gen_and_tl(t2, t2, t3);
2682 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2683 tcg_gen_or_tl(t2, t2, t3);
2684 tcg_gen_movi_tl(t3, 0);
2685 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2686 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2687 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2688 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2689 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2690 tcg_temp_free(t3);
2691 tcg_temp_free(t2);
48d38ca5 2692 }
6af0bf9c
FB
2693 opn = "div";
2694 break;
2695 case OPC_DIVU:
48d38ca5 2696 {
51127181
AJ
2697 TCGv t2 = tcg_const_tl(0);
2698 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
2699 tcg_gen_ext32u_tl(t0, t0);
2700 tcg_gen_ext32u_tl(t1, t1);
51127181 2701 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2702 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2703 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2704 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2705 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2706 tcg_temp_free(t3);
2707 tcg_temp_free(t2);
48d38ca5 2708 }
6af0bf9c
FB
2709 opn = "divu";
2710 break;
2711 case OPC_MULT:
214c465f 2712 {
ce1dd5d1
RH
2713 TCGv_i32 t2 = tcg_temp_new_i32();
2714 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
2715 tcg_gen_trunc_tl_i32(t2, t0);
2716 tcg_gen_trunc_tl_i32(t3, t1);
2717 tcg_gen_muls2_i32(t2, t3, t2, t3);
2718 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2719 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2720 tcg_temp_free_i32(t2);
2721 tcg_temp_free_i32(t3);
214c465f 2722 }
6af0bf9c
FB
2723 opn = "mult";
2724 break;
2725 case OPC_MULTU:
214c465f 2726 {
ce1dd5d1
RH
2727 TCGv_i32 t2 = tcg_temp_new_i32();
2728 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
2729 tcg_gen_trunc_tl_i32(t2, t0);
2730 tcg_gen_trunc_tl_i32(t3, t1);
2731 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2732 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2733 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2734 tcg_temp_free_i32(t2);
2735 tcg_temp_free_i32(t3);
214c465f 2736 }
6af0bf9c
FB
2737 opn = "multu";
2738 break;
d26bc211 2739#if defined(TARGET_MIPS64)
7a387fff 2740 case OPC_DDIV:
48d38ca5 2741 {
51127181
AJ
2742 TCGv t2 = tcg_temp_new();
2743 TCGv t3 = tcg_temp_new();
2744 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2745 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2746 tcg_gen_and_tl(t2, t2, t3);
2747 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2748 tcg_gen_or_tl(t2, t2, t3);
2749 tcg_gen_movi_tl(t3, 0);
2750 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2751 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2752 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
2753 tcg_temp_free(t3);
2754 tcg_temp_free(t2);
48d38ca5 2755 }
7a387fff
TS
2756 opn = "ddiv";
2757 break;
2758 case OPC_DDIVU:
48d38ca5 2759 {
51127181
AJ
2760 TCGv t2 = tcg_const_tl(0);
2761 TCGv t3 = tcg_const_tl(1);
2762 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2763 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2764 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
2765 tcg_temp_free(t3);
2766 tcg_temp_free(t2);
48d38ca5 2767 }
7a387fff
TS
2768 opn = "ddivu";
2769 break;
2770 case OPC_DMULT:
26135ead 2771 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
2772 opn = "dmult";
2773 break;
2774 case OPC_DMULTU:
26135ead 2775 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
2776 opn = "dmultu";
2777 break;
2778#endif
6af0bf9c 2779 case OPC_MADD:
214c465f 2780 {
d45f89f4
AJ
2781 TCGv_i64 t2 = tcg_temp_new_i64();
2782 TCGv_i64 t3 = tcg_temp_new_i64();
2783
2784 tcg_gen_ext_tl_i64(t2, t0);
2785 tcg_gen_ext_tl_i64(t3, t1);
2786 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2787 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2788 tcg_gen_add_i64(t2, t2, t3);
2789 tcg_temp_free_i64(t3);
2790 tcg_gen_trunc_i64_tl(t0, t2);
2791 tcg_gen_shri_i64(t2, t2, 32);
2792 tcg_gen_trunc_i64_tl(t1, t2);
2793 tcg_temp_free_i64(t2);
4133498f
JL
2794 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2795 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2796 }
6af0bf9c
FB
2797 opn = "madd";
2798 break;
2799 case OPC_MADDU:
4133498f 2800 {
d45f89f4
AJ
2801 TCGv_i64 t2 = tcg_temp_new_i64();
2802 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 2803
78723684
TS
2804 tcg_gen_ext32u_tl(t0, t0);
2805 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2806 tcg_gen_extu_tl_i64(t2, t0);
2807 tcg_gen_extu_tl_i64(t3, t1);
2808 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2809 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2810 tcg_gen_add_i64(t2, t2, t3);
2811 tcg_temp_free_i64(t3);
2812 tcg_gen_trunc_i64_tl(t0, t2);
2813 tcg_gen_shri_i64(t2, t2, 32);
2814 tcg_gen_trunc_i64_tl(t1, t2);
2815 tcg_temp_free_i64(t2);
4133498f
JL
2816 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2817 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2818 }
6af0bf9c
FB
2819 opn = "maddu";
2820 break;
2821 case OPC_MSUB:
214c465f 2822 {
d45f89f4
AJ
2823 TCGv_i64 t2 = tcg_temp_new_i64();
2824 TCGv_i64 t3 = tcg_temp_new_i64();
2825
2826 tcg_gen_ext_tl_i64(t2, t0);
2827 tcg_gen_ext_tl_i64(t3, t1);
2828 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2829 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2830 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2831 tcg_temp_free_i64(t3);
2832 tcg_gen_trunc_i64_tl(t0, t2);
2833 tcg_gen_shri_i64(t2, t2, 32);
2834 tcg_gen_trunc_i64_tl(t1, t2);
2835 tcg_temp_free_i64(t2);
4133498f
JL
2836 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2837 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2838 }
6af0bf9c
FB
2839 opn = "msub";
2840 break;
2841 case OPC_MSUBU:
214c465f 2842 {
d45f89f4
AJ
2843 TCGv_i64 t2 = tcg_temp_new_i64();
2844 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 2845
78723684
TS
2846 tcg_gen_ext32u_tl(t0, t0);
2847 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2848 tcg_gen_extu_tl_i64(t2, t0);
2849 tcg_gen_extu_tl_i64(t3, t1);
2850 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2851 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2852 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2853 tcg_temp_free_i64(t3);
2854 tcg_gen_trunc_i64_tl(t0, t2);
2855 tcg_gen_shri_i64(t2, t2, 32);
2856 tcg_gen_trunc_i64_tl(t1, t2);
2857 tcg_temp_free_i64(t2);
4133498f
JL
2858 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2859 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2860 }
6af0bf9c
FB
2861 opn = "msubu";
2862 break;
2863 default:
923617a3 2864 MIPS_INVAL(opn);
6af0bf9c 2865 generate_exception(ctx, EXCP_RI);
78723684 2866 goto out;
6af0bf9c 2867 }
2abf314d 2868 (void)opn; /* avoid a compiler warning */
6af0bf9c 2869 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2870 out:
2871 tcg_temp_free(t0);
2872 tcg_temp_free(t1);
6af0bf9c
FB
2873}
2874
e9c71dd1
TS
2875static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2876 int rd, int rs, int rt)
2877{
2878 const char *opn = "mul vr54xx";
f157bfe1
AJ
2879 TCGv t0 = tcg_temp_new();
2880 TCGv t1 = tcg_temp_new();
e9c71dd1 2881
6c5c1e20
TS
2882 gen_load_gpr(t0, rs);
2883 gen_load_gpr(t1, rt);
e9c71dd1
TS
2884
2885 switch (opc) {
2886 case OPC_VR54XX_MULS:
895c2d04 2887 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2888 opn = "muls";
6958549d 2889 break;
e9c71dd1 2890 case OPC_VR54XX_MULSU:
895c2d04 2891 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2892 opn = "mulsu";
6958549d 2893 break;
e9c71dd1 2894 case OPC_VR54XX_MACC:
895c2d04 2895 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2896 opn = "macc";
6958549d 2897 break;
e9c71dd1 2898 case OPC_VR54XX_MACCU:
895c2d04 2899 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2900 opn = "maccu";
6958549d 2901 break;
e9c71dd1 2902 case OPC_VR54XX_MSAC:
895c2d04 2903 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2904 opn = "msac";
6958549d 2905 break;
e9c71dd1 2906 case OPC_VR54XX_MSACU:
895c2d04 2907 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2908 opn = "msacu";
6958549d 2909 break;
e9c71dd1 2910 case OPC_VR54XX_MULHI:
895c2d04 2911 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2912 opn = "mulhi";
6958549d 2913 break;
e9c71dd1 2914 case OPC_VR54XX_MULHIU:
895c2d04 2915 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2916 opn = "mulhiu";
6958549d 2917 break;
e9c71dd1 2918 case OPC_VR54XX_MULSHI:
895c2d04 2919 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2920 opn = "mulshi";
6958549d 2921 break;
e9c71dd1 2922 case OPC_VR54XX_MULSHIU:
895c2d04 2923 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2924 opn = "mulshiu";
6958549d 2925 break;
e9c71dd1 2926 case OPC_VR54XX_MACCHI:
895c2d04 2927 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2928 opn = "macchi";
6958549d 2929 break;
e9c71dd1 2930 case OPC_VR54XX_MACCHIU:
895c2d04 2931 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2932 opn = "macchiu";
6958549d 2933 break;
e9c71dd1 2934 case OPC_VR54XX_MSACHI:
895c2d04 2935 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2936 opn = "msachi";
6958549d 2937 break;
e9c71dd1 2938 case OPC_VR54XX_MSACHIU:
895c2d04 2939 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2940 opn = "msachiu";
6958549d 2941 break;
e9c71dd1
TS
2942 default:
2943 MIPS_INVAL("mul vr54xx");
2944 generate_exception(ctx, EXCP_RI);
6c5c1e20 2945 goto out;
e9c71dd1 2946 }
6c5c1e20 2947 gen_store_gpr(t0, rd);
2abf314d 2948 (void)opn; /* avoid a compiler warning */
e9c71dd1 2949 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2950
2951 out:
2952 tcg_temp_free(t0);
2953 tcg_temp_free(t1);
e9c71dd1
TS
2954}
2955
7a387fff 2956static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2957 int rd, int rs)
2958{
923617a3 2959 const char *opn = "CLx";
20e1fb52 2960 TCGv t0;
6c5c1e20 2961
6af0bf9c 2962 if (rd == 0) {
ead9360e 2963 /* Treat as NOP. */
6af0bf9c 2964 MIPS_DEBUG("NOP");
20e1fb52 2965 return;
6af0bf9c 2966 }
20e1fb52 2967 t0 = tcg_temp_new();
6c5c1e20 2968 gen_load_gpr(t0, rs);
6af0bf9c
FB
2969 switch (opc) {
2970 case OPC_CLO:
20e1fb52 2971 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
2972 opn = "clo";
2973 break;
2974 case OPC_CLZ:
20e1fb52 2975 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
2976 opn = "clz";
2977 break;
d26bc211 2978#if defined(TARGET_MIPS64)
7a387fff 2979 case OPC_DCLO:
20e1fb52 2980 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
2981 opn = "dclo";
2982 break;
2983 case OPC_DCLZ:
20e1fb52 2984 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
2985 opn = "dclz";
2986 break;
2987#endif
6af0bf9c 2988 }
2abf314d 2989 (void)opn; /* avoid a compiler warning */
6af0bf9c 2990 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 2991 tcg_temp_free(t0);
6af0bf9c
FB
2992}
2993
161f85e6 2994/* Godson integer instructions */
bd277fa1
RH
2995static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2996 int rd, int rs, int rt)
161f85e6
AJ
2997{
2998 const char *opn = "loongson";
2999 TCGv t0, t1;
3000
3001 if (rd == 0) {
3002 /* Treat as NOP. */
3003 MIPS_DEBUG("NOP");
3004 return;
3005 }
3006
3007 switch (opc) {
3008 case OPC_MULT_G_2E:
3009 case OPC_MULT_G_2F:
3010 case OPC_MULTU_G_2E:
3011 case OPC_MULTU_G_2F:
3012#if defined(TARGET_MIPS64)
3013 case OPC_DMULT_G_2E:
3014 case OPC_DMULT_G_2F:
3015 case OPC_DMULTU_G_2E:
3016 case OPC_DMULTU_G_2F:
3017#endif
3018 t0 = tcg_temp_new();
3019 t1 = tcg_temp_new();
3020 break;
3021 default:
3022 t0 = tcg_temp_local_new();
3023 t1 = tcg_temp_local_new();
3024 break;
3025 }
3026
3027 gen_load_gpr(t0, rs);
3028 gen_load_gpr(t1, rt);
3029
3030 switch (opc) {
3031 case OPC_MULT_G_2E:
3032 case OPC_MULT_G_2F:
3033 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3034 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3035 opn = "mult.g";
3036 break;
3037 case OPC_MULTU_G_2E:
3038 case OPC_MULTU_G_2F:
3039 tcg_gen_ext32u_tl(t0, t0);
3040 tcg_gen_ext32u_tl(t1, t1);
3041 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3042 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3043 opn = "multu.g";
3044 break;
3045 case OPC_DIV_G_2E:
3046 case OPC_DIV_G_2F:
3047 {
3048 int l1 = gen_new_label();
3049 int l2 = gen_new_label();
3050 int l3 = gen_new_label();
3051 tcg_gen_ext32s_tl(t0, t0);
3052 tcg_gen_ext32s_tl(t1, t1);
3053 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3054 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3055 tcg_gen_br(l3);
3056 gen_set_label(l1);
3057 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3058 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3059 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3060 tcg_gen_br(l3);
3061 gen_set_label(l2);
3062 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3063 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3064 gen_set_label(l3);
3065 }
3066 opn = "div.g";
3067 break;
3068 case OPC_DIVU_G_2E:
3069 case OPC_DIVU_G_2F:
3070 {
3071 int l1 = gen_new_label();
3072 int l2 = gen_new_label();
3073 tcg_gen_ext32u_tl(t0, t0);
3074 tcg_gen_ext32u_tl(t1, t1);
3075 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3076 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3077 tcg_gen_br(l2);
3078 gen_set_label(l1);
3079 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3080 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3081 gen_set_label(l2);
3082 }
3083 opn = "divu.g";
3084 break;
3085 case OPC_MOD_G_2E:
3086 case OPC_MOD_G_2F:
3087 {
3088 int l1 = gen_new_label();
3089 int l2 = gen_new_label();
3090 int l3 = gen_new_label();
3091 tcg_gen_ext32u_tl(t0, t0);
3092 tcg_gen_ext32u_tl(t1, t1);
3093 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3094 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3095 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3096 gen_set_label(l1);
3097 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3098 tcg_gen_br(l3);
3099 gen_set_label(l2);
3100 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3101 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3102 gen_set_label(l3);
3103 }
3104 opn = "mod.g";
3105 break;
3106 case OPC_MODU_G_2E:
3107 case OPC_MODU_G_2F:
3108 {
3109 int l1 = gen_new_label();
3110 int l2 = gen_new_label();
3111 tcg_gen_ext32u_tl(t0, t0);
3112 tcg_gen_ext32u_tl(t1, t1);
3113 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3114 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3115 tcg_gen_br(l2);
3116 gen_set_label(l1);
3117 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3118 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3119 gen_set_label(l2);
3120 }
3121 opn = "modu.g";
3122 break;
3123#if defined(TARGET_MIPS64)
3124 case OPC_DMULT_G_2E:
3125 case OPC_DMULT_G_2F:
3126 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3127 opn = "dmult.g";
3128 break;
3129 case OPC_DMULTU_G_2E:
3130 case OPC_DMULTU_G_2F:
3131 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3132 opn = "dmultu.g";
3133 break;
3134 case OPC_DDIV_G_2E:
3135 case OPC_DDIV_G_2F:
3136 {
3137 int l1 = gen_new_label();
3138 int l2 = gen_new_label();
3139 int l3 = gen_new_label();
3140 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3141 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3142 tcg_gen_br(l3);
3143 gen_set_label(l1);
3144 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3145 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3146 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3147 tcg_gen_br(l3);
3148 gen_set_label(l2);
3149 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3150 gen_set_label(l3);
3151 }
3152 opn = "ddiv.g";
3153 break;
3154 case OPC_DDIVU_G_2E:
3155 case OPC_DDIVU_G_2F:
3156 {
3157 int l1 = gen_new_label();
3158 int l2 = gen_new_label();
3159 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3160 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3161 tcg_gen_br(l2);
3162 gen_set_label(l1);
3163 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3164 gen_set_label(l2);
3165 }
3166 opn = "ddivu.g";
3167 break;
3168 case OPC_DMOD_G_2E:
3169 case OPC_DMOD_G_2F:
3170 {
3171 int l1 = gen_new_label();
3172 int l2 = gen_new_label();
3173 int l3 = gen_new_label();
3174 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3175 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3176 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3177 gen_set_label(l1);
3178 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3179 tcg_gen_br(l3);
3180 gen_set_label(l2);
3181 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3182 gen_set_label(l3);
3183 }
3184 opn = "dmod.g";
3185 break;
3186 case OPC_DMODU_G_2E:
3187 case OPC_DMODU_G_2F:
3188 {
3189 int l1 = gen_new_label();
3190 int l2 = gen_new_label();
3191 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3192 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3193 tcg_gen_br(l2);
3194 gen_set_label(l1);
3195 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3196 gen_set_label(l2);
3197 }
3198 opn = "dmodu.g";
3199 break;
3200#endif
3201 }
3202
2abf314d 3203 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3204 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3205 tcg_temp_free(t0);
3206 tcg_temp_free(t1);
3207}
3208
bd277fa1
RH
3209/* Loongson multimedia instructions */
3210static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3211{
3212 const char *opn = "loongson_cp2";
3213 uint32_t opc, shift_max;
3214 TCGv_i64 t0, t1;
3215
3216 opc = MASK_LMI(ctx->opcode);
3217 switch (opc) {
3218 case OPC_ADD_CP2:
3219 case OPC_SUB_CP2:
3220 case OPC_DADD_CP2:
3221 case OPC_DSUB_CP2:
3222 t0 = tcg_temp_local_new_i64();
3223 t1 = tcg_temp_local_new_i64();
3224 break;
3225 default:
3226 t0 = tcg_temp_new_i64();
3227 t1 = tcg_temp_new_i64();
3228 break;
3229 }
3230
3231 gen_load_fpr64(ctx, t0, rs);
3232 gen_load_fpr64(ctx, t1, rt);
3233
3234#define LMI_HELPER(UP, LO) \
3235 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3236#define LMI_HELPER_1(UP, LO) \
3237 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3238#define LMI_DIRECT(UP, LO, OP) \
3239 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3240
3241 switch (opc) {
3242 LMI_HELPER(PADDSH, paddsh);
3243 LMI_HELPER(PADDUSH, paddush);
3244 LMI_HELPER(PADDH, paddh);
3245 LMI_HELPER(PADDW, paddw);
3246 LMI_HELPER(PADDSB, paddsb);
3247 LMI_HELPER(PADDUSB, paddusb);
3248 LMI_HELPER(PADDB, paddb);
3249
3250 LMI_HELPER(PSUBSH, psubsh);
3251 LMI_HELPER(PSUBUSH, psubush);
3252 LMI_HELPER(PSUBH, psubh);
3253 LMI_HELPER(PSUBW, psubw);
3254 LMI_HELPER(PSUBSB, psubsb);
3255 LMI_HELPER(PSUBUSB, psubusb);
3256 LMI_HELPER(PSUBB, psubb);
3257
3258 LMI_HELPER(PSHUFH, pshufh);
3259 LMI_HELPER(PACKSSWH, packsswh);
3260 LMI_HELPER(PACKSSHB, packsshb);
3261 LMI_HELPER(PACKUSHB, packushb);
3262
3263 LMI_HELPER(PUNPCKLHW, punpcklhw);
3264 LMI_HELPER(PUNPCKHHW, punpckhhw);
3265 LMI_HELPER(PUNPCKLBH, punpcklbh);
3266 LMI_HELPER(PUNPCKHBH, punpckhbh);
3267 LMI_HELPER(PUNPCKLWD, punpcklwd);
3268 LMI_HELPER(PUNPCKHWD, punpckhwd);
3269
3270 LMI_HELPER(PAVGH, pavgh);
3271 LMI_HELPER(PAVGB, pavgb);
3272 LMI_HELPER(PMAXSH, pmaxsh);
3273 LMI_HELPER(PMINSH, pminsh);
3274 LMI_HELPER(PMAXUB, pmaxub);
3275 LMI_HELPER(PMINUB, pminub);
3276
3277 LMI_HELPER(PCMPEQW, pcmpeqw);
3278 LMI_HELPER(PCMPGTW, pcmpgtw);
3279 LMI_HELPER(PCMPEQH, pcmpeqh);
3280 LMI_HELPER(PCMPGTH, pcmpgth);
3281 LMI_HELPER(PCMPEQB, pcmpeqb);
3282 LMI_HELPER(PCMPGTB, pcmpgtb);
3283
3284 LMI_HELPER(PSLLW, psllw);
3285 LMI_HELPER(PSLLH, psllh);
3286 LMI_HELPER(PSRLW, psrlw);
3287 LMI_HELPER(PSRLH, psrlh);
3288 LMI_HELPER(PSRAW, psraw);
3289 LMI_HELPER(PSRAH, psrah);
3290
3291 LMI_HELPER(PMULLH, pmullh);
3292 LMI_HELPER(PMULHH, pmulhh);
3293 LMI_HELPER(PMULHUH, pmulhuh);
3294 LMI_HELPER(PMADDHW, pmaddhw);
3295
3296 LMI_HELPER(PASUBUB, pasubub);
3297 LMI_HELPER_1(BIADD, biadd);
3298 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3299
3300 LMI_DIRECT(PADDD, paddd, add);
3301 LMI_DIRECT(PSUBD, psubd, sub);
3302 LMI_DIRECT(XOR_CP2, xor, xor);
3303 LMI_DIRECT(NOR_CP2, nor, nor);
3304 LMI_DIRECT(AND_CP2, and, and);
3305 LMI_DIRECT(PANDN, pandn, andc);
3306 LMI_DIRECT(OR, or, or);
3307
3308 case OPC_PINSRH_0:
3309 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3310 opn = "pinsrh_0";
3311 break;
3312 case OPC_PINSRH_1:
3313 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3314 opn = "pinsrh_1";
3315 break;
3316 case OPC_PINSRH_2:
3317 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3318 opn = "pinsrh_2";
3319 break;
3320 case OPC_PINSRH_3:
3321 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3322 opn = "pinsrh_3";
3323 break;
3324
3325 case OPC_PEXTRH:
3326 tcg_gen_andi_i64(t1, t1, 3);
3327 tcg_gen_shli_i64(t1, t1, 4);
3328 tcg_gen_shr_i64(t0, t0, t1);
3329 tcg_gen_ext16u_i64(t0, t0);
3330 opn = "pextrh";
3331 break;
3332
3333 case OPC_ADDU_CP2:
3334 tcg_gen_add_i64(t0, t0, t1);
3335 tcg_gen_ext32s_i64(t0, t0);
3336 opn = "addu";
3337 break;
3338 case OPC_SUBU_CP2:
3339 tcg_gen_sub_i64(t0, t0, t1);
3340 tcg_gen_ext32s_i64(t0, t0);
3341 opn = "addu";
3342 break;
3343
3344 case OPC_SLL_CP2:
3345 opn = "sll";
3346 shift_max = 32;
3347 goto do_shift;
3348 case OPC_SRL_CP2:
3349 opn = "srl";
3350 shift_max = 32;
3351 goto do_shift;
3352 case OPC_SRA_CP2:
3353 opn = "sra";
3354 shift_max = 32;
3355 goto do_shift;
3356 case OPC_DSLL_CP2:
3357 opn = "dsll";
3358 shift_max = 64;
3359 goto do_shift;
3360 case OPC_DSRL_CP2:
3361 opn = "dsrl";
3362 shift_max = 64;
3363 goto do_shift;
3364 case OPC_DSRA_CP2:
3365 opn = "dsra";
3366 shift_max = 64;
3367 goto do_shift;
3368 do_shift:
3369 /* Make sure shift count isn't TCG undefined behaviour. */
3370 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3371
3372 switch (opc) {
3373 case OPC_SLL_CP2:
3374 case OPC_DSLL_CP2:
3375 tcg_gen_shl_i64(t0, t0, t1);
3376 break;
3377 case OPC_SRA_CP2:
3378 case OPC_DSRA_CP2:
3379 /* Since SRA is UndefinedResult without sign-extended inputs,
3380 we can treat SRA and DSRA the same. */
3381 tcg_gen_sar_i64(t0, t0, t1);
3382 break;
3383 case OPC_SRL_CP2:
3384 /* We want to shift in zeros for SRL; zero-extend first. */
3385 tcg_gen_ext32u_i64(t0, t0);
3386 /* FALLTHRU */
3387 case OPC_DSRL_CP2:
3388 tcg_gen_shr_i64(t0, t0, t1);
3389 break;
3390 }
3391
3392 if (shift_max == 32) {
3393 tcg_gen_ext32s_i64(t0, t0);
3394 }
3395
3396 /* Shifts larger than MAX produce zero. */
3397 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3398 tcg_gen_neg_i64(t1, t1);
3399 tcg_gen_and_i64(t0, t0, t1);
3400 break;
3401
3402 case OPC_ADD_CP2:
3403 case OPC_DADD_CP2:
3404 {
3405 TCGv_i64 t2 = tcg_temp_new_i64();
3406 int lab = gen_new_label();
3407
3408 tcg_gen_mov_i64(t2, t0);
3409 tcg_gen_add_i64(t0, t1, t2);
3410 if (opc == OPC_ADD_CP2) {
3411 tcg_gen_ext32s_i64(t0, t0);
3412 }
3413 tcg_gen_xor_i64(t1, t1, t2);
3414 tcg_gen_xor_i64(t2, t2, t0);
3415 tcg_gen_andc_i64(t1, t2, t1);
3416 tcg_temp_free_i64(t2);
3417 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3418 generate_exception(ctx, EXCP_OVERFLOW);
3419 gen_set_label(lab);
3420
3421 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3422 break;
3423 }
3424
3425 case OPC_SUB_CP2:
3426 case OPC_DSUB_CP2:
3427 {
3428 TCGv_i64 t2 = tcg_temp_new_i64();
3429 int lab = gen_new_label();
3430
3431 tcg_gen_mov_i64(t2, t0);
3432 tcg_gen_sub_i64(t0, t1, t2);
3433 if (opc == OPC_SUB_CP2) {
3434 tcg_gen_ext32s_i64(t0, t0);
3435 }
3436 tcg_gen_xor_i64(t1, t1, t2);
3437 tcg_gen_xor_i64(t2, t2, t0);
3438 tcg_gen_and_i64(t1, t1, t2);
3439 tcg_temp_free_i64(t2);
3440 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3441 generate_exception(ctx, EXCP_OVERFLOW);
3442 gen_set_label(lab);
3443
3444 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3445 break;
3446 }
3447
3448 case OPC_PMULUW:
3449 tcg_gen_ext32u_i64(t0, t0);
3450 tcg_gen_ext32u_i64(t1, t1);
3451 tcg_gen_mul_i64(t0, t0, t1);
3452 opn = "pmuluw";
3453 break;
3454
3455 case OPC_SEQU_CP2:
3456 case OPC_SEQ_CP2:
3457 case OPC_SLTU_CP2:
3458 case OPC_SLT_CP2:
3459 case OPC_SLEU_CP2:
3460 case OPC_SLE_CP2:
3461 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3462 FD field is the CC field? */
3463 default:
3464 MIPS_INVAL(opn);
3465 generate_exception(ctx, EXCP_RI);
3466 return;
3467 }
3468
3469#undef LMI_HELPER
3470#undef LMI_DIRECT
3471
3472 gen_store_fpr64(ctx, t0, rd);
3473
3474 (void)opn; /* avoid a compiler warning */
3475 MIPS_DEBUG("%s %s, %s, %s", opn,
3476 fregnames[rd], fregnames[rs], fregnames[rt]);
3477 tcg_temp_free_i64(t0);
3478 tcg_temp_free_i64(t1);
3479}
3480
6af0bf9c 3481/* Traps */
7a387fff 3482static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3483 int rs, int rt, int16_t imm)
3484{
3485 int cond;
cdc0faa6 3486 TCGv t0 = tcg_temp_new();
1ba74fb8 3487 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3488
3489 cond = 0;
3490 /* Load needed operands */
3491 switch (opc) {
3492 case OPC_TEQ:
3493 case OPC_TGE:
3494 case OPC_TGEU:
3495 case OPC_TLT:
3496 case OPC_TLTU:
3497 case OPC_TNE:
3498 /* Compare two registers */
3499 if (rs != rt) {
be24bb4f
TS
3500 gen_load_gpr(t0, rs);
3501 gen_load_gpr(t1, rt);
6af0bf9c
FB
3502 cond = 1;
3503 }
179e32bb 3504 break;
6af0bf9c
FB
3505 case OPC_TEQI:
3506 case OPC_TGEI:
3507 case OPC_TGEIU:
3508 case OPC_TLTI:
3509 case OPC_TLTIU:
3510 case OPC_TNEI:
3511 /* Compare register to immediate */
3512 if (rs != 0 || imm != 0) {
be24bb4f
TS
3513 gen_load_gpr(t0, rs);
3514 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3515 cond = 1;
3516 }
3517 break;
3518 }
3519 if (cond == 0) {
3520 switch (opc) {
3521 case OPC_TEQ: /* rs == rs */
3522 case OPC_TEQI: /* r0 == 0 */
3523 case OPC_TGE: /* rs >= rs */
3524 case OPC_TGEI: /* r0 >= 0 */
3525 case OPC_TGEU: /* rs >= rs unsigned */
3526 case OPC_TGEIU: /* r0 >= 0 unsigned */
3527 /* Always trap */
cdc0faa6 3528 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3529 break;
3530 case OPC_TLT: /* rs < rs */
3531 case OPC_TLTI: /* r0 < 0 */
3532 case OPC_TLTU: /* rs < rs unsigned */
3533 case OPC_TLTIU: /* r0 < 0 unsigned */
3534 case OPC_TNE: /* rs != rs */
3535 case OPC_TNEI: /* r0 != 0 */
ead9360e 3536 /* Never trap: treat as NOP. */
cdc0faa6 3537 break;
6af0bf9c
FB
3538 }
3539 } else {
cdc0faa6
AJ
3540 int l1 = gen_new_label();
3541
6af0bf9c
FB
3542 switch (opc) {
3543 case OPC_TEQ:
3544 case OPC_TEQI:
cdc0faa6 3545 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3546 break;
3547 case OPC_TGE:
3548 case OPC_TGEI:
cdc0faa6 3549 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3550 break;
3551 case OPC_TGEU:
3552 case OPC_TGEIU:
cdc0faa6 3553 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3554 break;
3555 case OPC_TLT:
3556 case OPC_TLTI:
cdc0faa6 3557 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3558 break;
3559 case OPC_TLTU:
3560 case OPC_TLTIU:
cdc0faa6 3561 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3562 break;
3563 case OPC_TNE:
3564 case OPC_TNEI:
cdc0faa6 3565 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3566 break;
6af0bf9c 3567 }
cdc0faa6 3568 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3569 gen_set_label(l1);
3570 }
be24bb4f
TS
3571 tcg_temp_free(t0);
3572 tcg_temp_free(t1);
6af0bf9c
FB
3573}
3574
356265ae 3575static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3576{
6e256c93
FB
3577 TranslationBlock *tb;
3578 tb = ctx->tb;
7b270ef2
NF
3579 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3580 likely(!ctx->singlestep_enabled)) {
57fec1fe 3581 tcg_gen_goto_tb(n);
9b9e4393 3582 gen_save_pc(dest);
8cfd0495 3583 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 3584 } else {
9b9e4393 3585 gen_save_pc(dest);
7b270ef2
NF
3586 if (ctx->singlestep_enabled) {
3587 save_cpu_state(ctx, 0);
895c2d04 3588 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3589 }
57fec1fe 3590 tcg_gen_exit_tb(0);
6e256c93 3591 }
c53be334
FB
3592}
3593
6af0bf9c 3594/* Branches (before delay slot) */
7a387fff 3595static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3596 int insn_bytes,
6af0bf9c
FB
3597 int rs, int rt, int32_t offset)
3598{
d077b6f7 3599 target_ulong btgt = -1;
3ad4bb2d 3600 int blink = 0;
2fdbad25 3601 int bcond_compute = 0;
1ba74fb8
AJ
3602 TCGv t0 = tcg_temp_new();
3603 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3604
3605 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3606#ifdef MIPS_DEBUG_DISAS
d12d51d5 3607 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3608#endif
3ad4bb2d 3609 generate_exception(ctx, EXCP_RI);
6c5c1e20 3610 goto out;
3ad4bb2d 3611 }
6af0bf9c 3612
6af0bf9c
FB
3613 /* Load needed operands */
3614 switch (opc) {
3615 case OPC_BEQ:
3616 case OPC_BEQL:
3617 case OPC_BNE:
3618 case OPC_BNEL:
3619 /* Compare two registers */
3620 if (rs != rt) {
6c5c1e20
TS
3621 gen_load_gpr(t0, rs);
3622 gen_load_gpr(t1, rt);
2fdbad25 3623 bcond_compute = 1;
6af0bf9c 3624 }
7dca4ad0 3625 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3626 break;
3627 case OPC_BGEZ:
3628 case OPC_BGEZAL:
3c824109 3629 case OPC_BGEZALS:
6af0bf9c
FB
3630 case OPC_BGEZALL:
3631 case OPC_BGEZL:
3632 case OPC_BGTZ:
3633 case OPC_BGTZL:
3634 case OPC_BLEZ:
3635 case OPC_BLEZL:
3636 case OPC_BLTZ:
3637 case OPC_BLTZAL:
3c824109 3638 case OPC_BLTZALS:
6af0bf9c
FB
3639 case OPC_BLTZALL:
3640 case OPC_BLTZL:
3641 /* Compare to zero */
3642 if (rs != 0) {
6c5c1e20 3643 gen_load_gpr(t0, rs);
2fdbad25 3644 bcond_compute = 1;
6af0bf9c 3645 }
7dca4ad0 3646 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3647 break;
e45a93e2
JL
3648 case OPC_BPOSGE32:
3649#if defined(TARGET_MIPS64)
3650 case OPC_BPOSGE64:
3651 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3652#else
3653 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3654#endif
3655 bcond_compute = 1;
3656 btgt = ctx->pc + insn_bytes + offset;
3657 break;
6af0bf9c
FB
3658 case OPC_J:
3659 case OPC_JAL:
364d4831 3660 case OPC_JALX:
620e48f6
NF
3661 case OPC_JALS:
3662 case OPC_JALXS:
6af0bf9c 3663 /* Jump to immediate */
7dca4ad0 3664 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3665 break;
3666 case OPC_JR:
3667 case OPC_JALR:
364d4831 3668 case OPC_JALRC:
620e48f6 3669 case OPC_JALRS:
6af0bf9c 3670 /* Jump to register */
7a387fff
TS
3671 if (offset != 0 && offset != 16) {
3672 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3673 others are reserved. */
923617a3 3674 MIPS_INVAL("jump hint");
6af0bf9c 3675 generate_exception(ctx, EXCP_RI);
6c5c1e20 3676 goto out;
6af0bf9c 3677 }
d077b6f7 3678 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3679 break;
3680 default:
3681 MIPS_INVAL("branch/jump");
3682 generate_exception(ctx, EXCP_RI);
6c5c1e20 3683 goto out;
6af0bf9c 3684 }
2fdbad25 3685 if (bcond_compute == 0) {
6af0bf9c
FB
3686 /* No condition to be computed */
3687 switch (opc) {
3688 case OPC_BEQ: /* rx == rx */
3689 case OPC_BEQL: /* rx == rx likely */
3690 case OPC_BGEZ: /* 0 >= 0 */
3691 case OPC_BGEZL: /* 0 >= 0 likely */
3692 case OPC_BLEZ: /* 0 <= 0 */
3693 case OPC_BLEZL: /* 0 <= 0 likely */
3694 /* Always take */
4ad40f36 3695 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3696 MIPS_DEBUG("balways");
3697 break;
3c824109 3698 case OPC_BGEZALS:
6af0bf9c
FB
3699 case OPC_BGEZAL: /* 0 >= 0 */
3700 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3701 ctx->hflags |= (opc == OPC_BGEZALS
3702 ? MIPS_HFLAG_BDS16
3703 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3704 /* Always take and link */
3705 blink = 31;
4ad40f36 3706 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3707 MIPS_DEBUG("balways and link");
3708 break;
3709 case OPC_BNE: /* rx != rx */
3710 case OPC_BGTZ: /* 0 > 0 */
3711 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3712 /* Treat as NOP. */
6af0bf9c 3713 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3714 goto out;
3c824109 3715 case OPC_BLTZALS:
eeef26cd 3716 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3717 ctx->hflags |= (opc == OPC_BLTZALS
3718 ? MIPS_HFLAG_BDS16
3719 : MIPS_HFLAG_BDS32);
3720 /* Handle as an unconditional branch to get correct delay
3721 slot checking. */
3722 blink = 31;
3723 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3724 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3725 MIPS_DEBUG("bnever and link");
3c824109 3726 break;
eeef26cd 3727 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3728 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3729 /* Skip the instruction in the delay slot */
3730 MIPS_DEBUG("bnever, link and skip");
3731 ctx->pc += 4;
6c5c1e20 3732 goto out;
6af0bf9c
FB
3733 case OPC_BNEL: /* rx != rx likely */
3734 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3735 case OPC_BLTZL: /* 0 < 0 likely */
3736 /* Skip the instruction in the delay slot */
3737 MIPS_DEBUG("bnever and skip");
9898128f 3738 ctx->pc += 4;
6c5c1e20 3739 goto out;
6af0bf9c 3740 case OPC_J:
4ad40f36 3741 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3742 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3743 break;
620e48f6 3744 case OPC_JALXS:
364d4831
NF
3745 case OPC_JALX:
3746 ctx->hflags |= MIPS_HFLAG_BX;
3747 /* Fallthrough */
620e48f6 3748 case OPC_JALS:
6af0bf9c
FB
3749 case OPC_JAL:
3750 blink = 31;
4ad40f36 3751 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3752 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3753 ? MIPS_HFLAG_BDS16
3754 : MIPS_HFLAG_BDS32);
d077b6f7 3755 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3756 break;
3757 case OPC_JR:
4ad40f36 3758 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3759 if (insn_bytes == 4)
3760 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3761 MIPS_DEBUG("jr %s", regnames[rs]);
3762 break;
620e48f6 3763 case OPC_JALRS:
6af0bf9c 3764 case OPC_JALR:
364d4831 3765 case OPC_JALRC:
6af0bf9c 3766 blink = rt;
4ad40f36 3767 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3768 ctx->hflags |= (opc == OPC_JALRS
3769 ? MIPS_HFLAG_BDS16
3770 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3771 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3772 break;
3773 default:
3774 MIPS_INVAL("branch/jump");
3775 generate_exception(ctx, EXCP_RI);
6c5c1e20 3776 goto out;
6af0bf9c
FB
3777 }
3778 } else {
3779 switch (opc) {
3780 case OPC_BEQ:
e68dd28f 3781 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3782 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3783 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3784 goto not_likely;
3785 case OPC_BEQL:
e68dd28f 3786 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3787 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3788 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3789 goto likely;
3790 case OPC_BNE:
e68dd28f 3791 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3792 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3793 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3794 goto not_likely;
3795 case OPC_BNEL:
e68dd28f 3796 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3797 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3798 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3799 goto likely;
3800 case OPC_BGEZ:
e68dd28f 3801 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3802 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3803 goto not_likely;
3804 case OPC_BGEZL:
e68dd28f 3805 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3806 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3807 goto likely;
3c824109 3808 case OPC_BGEZALS:
6af0bf9c 3809 case OPC_BGEZAL:
3c824109
NF
3810 ctx->hflags |= (opc == OPC_BGEZALS
3811 ? MIPS_HFLAG_BDS16
3812 : MIPS_HFLAG_BDS32);
e68dd28f 3813 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3814 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3815 blink = 31;
3816 goto not_likely;
3817 case OPC_BGEZALL:
e68dd28f 3818 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3819 blink = 31;
d077b6f7 3820 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3821 goto likely;
3822 case OPC_BGTZ:
e68dd28f 3823 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3824 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3825 goto not_likely;
3826 case OPC_BGTZL:
e68dd28f 3827 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3828 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3829 goto likely;
3830 case OPC_BLEZ:
e68dd28f 3831 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3832 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3833 goto not_likely;
3834 case OPC_BLEZL:
e68dd28f 3835 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3836 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3837 goto likely;
3838 case OPC_BLTZ:
e68dd28f 3839 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3840 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3841 goto not_likely;
3842 case OPC_BLTZL:
e68dd28f 3843 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3844 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3845 goto likely;
e45a93e2
JL
3846 case OPC_BPOSGE32:
3847 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3848 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3849 goto not_likely;
3850#if defined(TARGET_MIPS64)
3851 case OPC_BPOSGE64:
3852 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3853 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3854 goto not_likely;
3855#endif
3c824109 3856 case OPC_BLTZALS:
6af0bf9c 3857 case OPC_BLTZAL:
3c824109
NF
3858 ctx->hflags |= (opc == OPC_BLTZALS
3859 ? MIPS_HFLAG_BDS16
3860 : MIPS_HFLAG_BDS32);
e68dd28f 3861 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3862 blink = 31;
d077b6f7 3863 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3864 not_likely:
4ad40f36 3865 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3866 break;
3867 case OPC_BLTZALL:
e68dd28f 3868 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3869 blink = 31;
d077b6f7 3870 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3871 likely:
4ad40f36 3872 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3873 break;
c53f4a62
TS
3874 default:
3875 MIPS_INVAL("conditional branch/jump");
3876 generate_exception(ctx, EXCP_RI);
6c5c1e20 3877 goto out;
6af0bf9c 3878 }
6af0bf9c 3879 }
923617a3 3880 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3881 blink, ctx->hflags, btgt);
9b9e4393 3882
d077b6f7 3883 ctx->btarget = btgt;
6af0bf9c 3884 if (blink > 0) {
364d4831
NF
3885 int post_delay = insn_bytes;
3886 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3887
3888 if (opc != OPC_JALRC)
3889 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3890
3891 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3892 }
6c5c1e20
TS
3893
3894 out:
364d4831
NF
3895 if (insn_bytes == 2)
3896 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3897 tcg_temp_free(t0);
3898 tcg_temp_free(t1);
6af0bf9c
FB
3899}
3900
7a387fff
TS
3901/* special3 bitfield operations */
3902static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3903 int rs, int lsb, int msb)
7a387fff 3904{
a7812ae4
PB
3905 TCGv t0 = tcg_temp_new();
3906 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
3907
3908 gen_load_gpr(t1, rs);
7a387fff
TS
3909 switch (opc) {
3910 case OPC_EXT:
3911 if (lsb + msb > 31)
3912 goto fail;
505ad7c2
AJ
3913 tcg_gen_shri_tl(t0, t1, lsb);
3914 if (msb != 31) {
3915 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3916 } else {
3917 tcg_gen_ext32s_tl(t0, t0);
3918 }
7a387fff 3919 break;
c6d6dd7c 3920#if defined(TARGET_MIPS64)
7a387fff 3921 case OPC_DEXTM:
505ad7c2
AJ
3922 tcg_gen_shri_tl(t0, t1, lsb);
3923 if (msb != 31) {
3924 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3925 }
7a387fff
TS
3926 break;
3927 case OPC_DEXTU:
505ad7c2
AJ
3928 tcg_gen_shri_tl(t0, t1, lsb + 32);
3929 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3930 break;
3931 case OPC_DEXT:
505ad7c2
AJ
3932 tcg_gen_shri_tl(t0, t1, lsb);
3933 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3934 break;
c6d6dd7c 3935#endif
7a387fff
TS
3936 case OPC_INS:
3937 if (lsb > msb)
3938 goto fail;
6c5c1e20 3939 gen_load_gpr(t0, rt);
e0d002f1 3940 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 3941 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3942 break;
c6d6dd7c 3943#if defined(TARGET_MIPS64)
7a387fff 3944 case OPC_DINSM:
6c5c1e20 3945 gen_load_gpr(t0, rt);
e0d002f1 3946 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
3947 break;
3948 case OPC_DINSU:
6c5c1e20 3949 gen_load_gpr(t0, rt);
e0d002f1 3950 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
3951 break;
3952 case OPC_DINS:
6c5c1e20 3953 gen_load_gpr(t0, rt);
e0d002f1 3954 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 3955 break;
c6d6dd7c 3956#endif
7a387fff
TS
3957 default:
3958fail:
3959 MIPS_INVAL("bitops");
3960 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
3961 tcg_temp_free(t0);
3962 tcg_temp_free(t1);
7a387fff
TS
3963 return;
3964 }
6c5c1e20
TS
3965 gen_store_gpr(t0, rt);
3966 tcg_temp_free(t0);
3967 tcg_temp_free(t1);
7a387fff
TS
3968}
3969
49bcf33c
AJ
3970static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3971{
3a55fa47 3972 TCGv t0;
49bcf33c 3973
3a55fa47
AJ
3974 if (rd == 0) {
3975 /* If no destination, treat it as a NOP. */
3976 MIPS_DEBUG("NOP");
3977 return;
3978 }
3979
3980 t0 = tcg_temp_new();
3981 gen_load_gpr(t0, rt);
49bcf33c
AJ
3982 switch (op2) {
3983 case OPC_WSBH:
3a55fa47
AJ
3984 {
3985 TCGv t1 = tcg_temp_new();
3986
3987 tcg_gen_shri_tl(t1, t0, 8);
3988 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3989 tcg_gen_shli_tl(t0, t0, 8);
3990 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3991 tcg_gen_or_tl(t0, t0, t1);
3992 tcg_temp_free(t1);
3993 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3994 }
49bcf33c
AJ
3995 break;
3996 case OPC_SEB:
3a55fa47 3997 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
3998 break;
3999 case OPC_SEH:
3a55fa47 4000 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4001 break;
4002#if defined(TARGET_MIPS64)
4003 case OPC_DSBH:
3a55fa47
AJ
4004 {
4005 TCGv t1 = tcg_temp_new();
4006
4007 tcg_gen_shri_tl(t1, t0, 8);
4008 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4009 tcg_gen_shli_tl(t0, t0, 8);
4010 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4011 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4012 tcg_temp_free(t1);
4013 }
49bcf33c
AJ
4014 break;
4015 case OPC_DSHD:
3a55fa47
AJ
4016 {
4017 TCGv t1 = tcg_temp_new();
4018
4019 tcg_gen_shri_tl(t1, t0, 16);
4020 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4021 tcg_gen_shli_tl(t0, t0, 16);
4022 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4023 tcg_gen_or_tl(t0, t0, t1);
4024 tcg_gen_shri_tl(t1, t0, 32);
4025 tcg_gen_shli_tl(t0, t0, 32);
4026 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4027 tcg_temp_free(t1);
4028 }
49bcf33c
AJ
4029 break;
4030#endif
4031 default:
4032 MIPS_INVAL("bsfhl");
4033 generate_exception(ctx, EXCP_RI);
4034 tcg_temp_free(t0);
49bcf33c
AJ
4035 return;
4036 }
49bcf33c 4037 tcg_temp_free(t0);
49bcf33c
AJ
4038}
4039
f1aa6320 4040#ifndef CONFIG_USER_ONLY
0eaef5aa 4041/* CP0 (MMU and control) */
d9bea114 4042static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4043{
d9bea114 4044 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4045
d9bea114
AJ
4046 tcg_gen_ld_i32(t0, cpu_env, off);
4047 tcg_gen_ext_i32_tl(arg, t0);
4048 tcg_temp_free_i32(t0);
4f57689a
TS
4049}
4050
d9bea114 4051static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4052{
d9bea114
AJ
4053 tcg_gen_ld_tl(arg, cpu_env, off);
4054 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4055}
4056
d9bea114 4057static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4058{
d9bea114 4059 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4060
d9bea114
AJ
4061 tcg_gen_trunc_tl_i32(t0, arg);
4062 tcg_gen_st_i32(t0, cpu_env, off);
4063 tcg_temp_free_i32(t0);
f1aa6320
TS
4064}
4065
d9bea114 4066static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4067{
d9bea114
AJ
4068 tcg_gen_ext32s_tl(arg, arg);
4069 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4070}
4071
d75c135e 4072static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4073{
7a387fff 4074 const char *rn = "invalid";
873eb012 4075
e189e748 4076 if (sel != 0)
d75c135e 4077 check_insn(ctx, ISA_MIPS32);
e189e748 4078
873eb012
TS
4079 switch (reg) {
4080 case 0:
7a387fff
TS
4081 switch (sel) {
4082 case 0:
7db13fae 4083 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4084 rn = "Index";
4085 break;
4086 case 1:
d75c135e 4087 check_insn(ctx, ASE_MT);
895c2d04 4088 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4089 rn = "MVPControl";
ead9360e 4090 break;
7a387fff 4091 case 2:
d75c135e 4092 check_insn(ctx, ASE_MT);
895c2d04 4093 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4094 rn = "MVPConf0";
ead9360e 4095 break;
7a387fff 4096 case 3:
d75c135e 4097 check_insn(ctx, ASE_MT);
895c2d04 4098 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4099 rn = "MVPConf1";
ead9360e 4100 break;
7a387fff
TS
4101 default:
4102 goto die;
4103 }
873eb012
TS
4104 break;
4105 case 1:
7a387fff
TS
4106 switch (sel) {
4107 case 0:
895c2d04 4108 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4109 rn = "Random";
2423f660 4110 break;
7a387fff 4111 case 1:
d75c135e 4112 check_insn(ctx, ASE_MT);
7db13fae 4113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4114 rn = "VPEControl";
ead9360e 4115 break;
7a387fff 4116 case 2:
d75c135e 4117 check_insn(ctx, ASE_MT);
7db13fae 4118 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4119 rn = "VPEConf0";
ead9360e 4120 break;
7a387fff 4121 case 3:
d75c135e 4122 check_insn(ctx, ASE_MT);
7db13fae 4123 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4124 rn = "VPEConf1";
ead9360e 4125 break;
7a387fff 4126 case 4:
d75c135e 4127 check_insn(ctx, ASE_MT);
7db13fae 4128 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4129 rn = "YQMask";
ead9360e 4130 break;
7a387fff 4131 case 5:
d75c135e 4132 check_insn(ctx, ASE_MT);
7db13fae 4133 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4134 rn = "VPESchedule";
ead9360e 4135 break;
7a387fff 4136 case 6:
d75c135e 4137 check_insn(ctx, ASE_MT);
7db13fae 4138 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4139 rn = "VPEScheFBack";
ead9360e 4140 break;
7a387fff 4141 case 7:
d75c135e 4142 check_insn(ctx, ASE_MT);
7db13fae 4143 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4144 rn = "VPEOpt";
ead9360e 4145 break;
7a387fff
TS
4146 default:
4147 goto die;
4148 }
873eb012
TS
4149 break;
4150 case 2:
7a387fff
TS
4151 switch (sel) {
4152 case 0:
7db13fae 4153 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4154 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4155 rn = "EntryLo0";
4156 break;
7a387fff 4157 case 1:
d75c135e 4158 check_insn(ctx, ASE_MT);
895c2d04 4159 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4160 rn = "TCStatus";
ead9360e 4161 break;
7a387fff 4162 case 2:
d75c135e 4163 check_insn(ctx, ASE_MT);
895c2d04 4164 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4165 rn = "TCBind";
ead9360e 4166 break;
7a387fff 4167 case 3:
d75c135e 4168 check_insn(ctx, ASE_MT);
895c2d04 4169 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4170 rn = "TCRestart";
ead9360e 4171 break;
7a387fff 4172 case 4:
d75c135e 4173 check_insn(ctx, ASE_MT);
895c2d04 4174 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4175 rn = "TCHalt";
ead9360e 4176 break;
7a387fff 4177 case 5:
d75c135e 4178 check_insn(ctx, ASE_MT);
895c2d04 4179 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4180 rn = "TCContext";
ead9360e 4181 break;
7a387fff 4182 case 6:
d75c135e 4183 check_insn(ctx, ASE_MT);
895c2d04 4184 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4185 rn = "TCSchedule";
ead9360e 4186 break;
7a387fff 4187 case 7:
d75c135e 4188 check_insn(ctx, ASE_MT);
895c2d04 4189 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4190 rn = "TCScheFBack";
ead9360e 4191 break;
7a387fff
TS
4192 default:
4193 goto die;
4194 }
873eb012
TS
4195 break;
4196 case 3:
7a387fff
TS
4197 switch (sel) {
4198 case 0:
7db13fae 4199 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4200 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4201 rn = "EntryLo1";
4202 break;
7a387fff
TS
4203 default:
4204 goto die;
1579a72e 4205 }
873eb012
TS
4206 break;
4207 case 4:
7a387fff
TS
4208 switch (sel) {
4209 case 0:
7db13fae 4210 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4211 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4212 rn = "Context";
4213 break;
7a387fff 4214 case 1:
d9bea114 4215// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
4216 rn = "ContextConfig";
4217// break;
7a387fff
TS
4218 default:
4219 goto die;
1579a72e 4220 }
873eb012
TS
4221 break;
4222 case 5:
7a387fff
TS
4223 switch (sel) {
4224 case 0:
7db13fae 4225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4226 rn = "PageMask";
4227 break;
7a387fff 4228 case 1:
d75c135e 4229 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4231 rn = "PageGrain";
4232 break;
7a387fff
TS
4233 default:
4234 goto die;
1579a72e 4235 }
873eb012
TS
4236 break;
4237 case 6:
7a387fff
TS
4238 switch (sel) {
4239 case 0:
7db13fae 4240 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4241 rn = "Wired";
4242 break;
7a387fff 4243 case 1:
d75c135e 4244 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4245 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4246 rn = "SRSConf0";
ead9360e 4247 break;
7a387fff 4248 case 2:
d75c135e 4249 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4250 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4251 rn = "SRSConf1";
ead9360e 4252 break;
7a387fff 4253 case 3:
d75c135e 4254 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4255 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4256 rn = "SRSConf2";
ead9360e 4257 break;
7a387fff 4258 case 4:
d75c135e 4259 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4261 rn = "SRSConf3";
ead9360e 4262 break;
7a387fff 4263 case 5:
d75c135e 4264 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4265 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4266 rn = "SRSConf4";
ead9360e 4267 break;
7a387fff
TS
4268 default:
4269 goto die;
1579a72e 4270 }
873eb012 4271 break;
8c0fdd85 4272 case 7:
7a387fff
TS
4273 switch (sel) {
4274 case 0:
d75c135e 4275 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4277 rn = "HWREna";
4278 break;
7a387fff
TS
4279 default:
4280 goto die;
1579a72e 4281 }
8c0fdd85 4282 break;
873eb012 4283 case 8:
7a387fff
TS
4284 switch (sel) {
4285 case 0:
7db13fae 4286 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4287 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4288 rn = "BadVAddr";
2423f660 4289 break;
7a387fff
TS
4290 default:
4291 goto die;
4292 }
873eb012
TS
4293 break;
4294 case 9:
7a387fff
TS
4295 switch (sel) {
4296 case 0:
2e70f6ef
PB
4297 /* Mark as an IO operation because we read the time. */
4298 if (use_icount)
4299 gen_io_start();
895c2d04 4300 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4301 if (use_icount) {
4302 gen_io_end();
2e70f6ef 4303 }
55807224
EI
4304 /* Break the TB to be able to take timer interrupts immediately
4305 after reading count. */
4306 ctx->bstate = BS_STOP;
2423f660
TS
4307 rn = "Count";
4308 break;
4309 /* 6,7 are implementation dependent */
7a387fff
TS
4310 default:
4311 goto die;
2423f660 4312 }
873eb012
TS
4313 break;
4314 case 10:
7a387fff
TS
4315 switch (sel) {
4316 case 0:
7db13fae 4317 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4318 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4319 rn = "EntryHi";
4320 break;
7a387fff
TS
4321 default:
4322 goto die;
1579a72e 4323 }
873eb012
TS
4324 break;
4325 case 11:
7a387fff
TS
4326 switch (sel) {
4327 case 0:
7db13fae 4328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4329 rn = "Compare";
4330 break;
4331 /* 6,7 are implementation dependent */
7a387fff
TS
4332 default:
4333 goto die;
2423f660 4334 }
873eb012
TS
4335 break;
4336 case 12:
7a387fff
TS
4337 switch (sel) {
4338 case 0:
7db13fae 4339 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4340 rn = "Status";
4341 break;
7a387fff 4342 case 1:
d75c135e 4343 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4345 rn = "IntCtl";
4346 break;
7a387fff 4347 case 2:
d75c135e 4348 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4350 rn = "SRSCtl";
4351 break;
7a387fff 4352 case 3:
d75c135e 4353 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4355 rn = "SRSMap";
fd88b6ab 4356 break;
7a387fff
TS
4357 default:
4358 goto die;
4359 }
873eb012
TS
4360 break;
4361 case 13:
7a387fff
TS
4362 switch (sel) {
4363 case 0:
7db13fae 4364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4365 rn = "Cause";
4366 break;
7a387fff
TS
4367 default:
4368 goto die;
4369 }
873eb012
TS
4370 break;
4371 case 14:
7a387fff
TS
4372 switch (sel) {
4373 case 0:
7db13fae 4374 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4375 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4376 rn = "EPC";
4377 break;
7a387fff
TS
4378 default:
4379 goto die;
1579a72e 4380 }
873eb012
TS
4381 break;
4382 case 15:
7a387fff
TS
4383 switch (sel) {
4384 case 0:
7db13fae 4385 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4386 rn = "PRid";
4387 break;
7a387fff 4388 case 1:
d75c135e 4389 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4390 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4391 rn = "EBase";
4392 break;
7a387fff
TS
4393 default:
4394 goto die;
4395 }
873eb012
TS
4396 break;
4397 case 16:
4398 switch (sel) {
4399 case 0:
7db13fae 4400 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4401 rn = "Config";
4402 break;
4403 case 1:
7db13fae 4404 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4405 rn = "Config1";
4406 break;
7a387fff 4407 case 2:
7db13fae 4408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4409 rn = "Config2";
4410 break;
4411 case 3:
7db13fae 4412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4413 rn = "Config3";
4414 break;
b4160af1
PJ
4415 case 4:
4416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4417 rn = "Config4";
4418 break;
b4dd99a3
PJ
4419 case 5:
4420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4421 rn = "Config5";
4422 break;
e397ee33
TS
4423 /* 6,7 are implementation dependent */
4424 case 6:
7db13fae 4425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4426 rn = "Config6";
4427 break;
4428 case 7:
7db13fae 4429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4430 rn = "Config7";
4431 break;
873eb012 4432 default:
873eb012
TS
4433 goto die;
4434 }
4435 break;
4436 case 17:
7a387fff
TS
4437 switch (sel) {
4438 case 0:
895c2d04 4439 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4440 rn = "LLAddr";
4441 break;
7a387fff
TS
4442 default:
4443 goto die;
4444 }
873eb012
TS
4445 break;
4446 case 18:
7a387fff 4447 switch (sel) {
fd88b6ab 4448 case 0 ... 7:
895c2d04 4449 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4450 rn = "WatchLo";
4451 break;
7a387fff
TS
4452 default:
4453 goto die;
4454 }
873eb012
TS
4455 break;
4456 case 19:
7a387fff 4457 switch (sel) {
fd88b6ab 4458 case 0 ...7:
895c2d04 4459 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4460 rn = "WatchHi";
4461 break;
7a387fff
TS
4462 default:
4463 goto die;
4464 }
873eb012 4465 break;
8c0fdd85 4466 case 20:
7a387fff
TS
4467 switch (sel) {
4468 case 0:
d26bc211 4469#if defined(TARGET_MIPS64)
d75c135e 4470 check_insn(ctx, ISA_MIPS3);
7db13fae 4471 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4472 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4473 rn = "XContext";
4474 break;
703eaf37 4475#endif
7a387fff
TS
4476 default:
4477 goto die;
4478 }
8c0fdd85
TS
4479 break;
4480 case 21:
7a387fff
TS
4481 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4482 switch (sel) {
4483 case 0:
7db13fae 4484 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4485 rn = "Framemask";
4486 break;
7a387fff
TS
4487 default:
4488 goto die;
4489 }
8c0fdd85
TS
4490 break;
4491 case 22:
d9bea114 4492 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4493 rn = "'Diagnostic"; /* implementation dependent */
4494 break;
873eb012 4495 case 23:
7a387fff
TS
4496 switch (sel) {
4497 case 0:
895c2d04 4498 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4499 rn = "Debug";
4500 break;
7a387fff 4501 case 1:
d9bea114 4502// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4503 rn = "TraceControl";
4504// break;
7a387fff 4505 case 2:
d9bea114 4506// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4507 rn = "TraceControl2";
4508// break;
7a387fff 4509 case 3:
d9bea114 4510// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4511 rn = "UserTraceData";
4512// break;
7a387fff 4513 case 4:
d9bea114 4514// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4515 rn = "TraceBPC";
4516// break;
7a387fff
TS
4517 default:
4518 goto die;
4519 }
873eb012
TS
4520 break;
4521 case 24:
7a387fff
TS
4522 switch (sel) {
4523 case 0:
f0b3f3ae 4524 /* EJTAG support */
7db13fae 4525 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4526 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4527 rn = "DEPC";
4528 break;
7a387fff
TS
4529 default:
4530 goto die;
4531 }
873eb012 4532 break;
8c0fdd85 4533 case 25:
7a387fff
TS
4534 switch (sel) {
4535 case 0:
7db13fae 4536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4537 rn = "Performance0";
7a387fff
TS
4538 break;
4539 case 1:
d9bea114 4540// gen_helper_mfc0_performance1(arg);
2423f660
TS
4541 rn = "Performance1";
4542// break;
7a387fff 4543 case 2:
d9bea114 4544// gen_helper_mfc0_performance2(arg);
2423f660
TS
4545 rn = "Performance2";
4546// break;
7a387fff 4547 case 3:
d9bea114 4548// gen_helper_mfc0_performance3(arg);
2423f660
TS
4549 rn = "Performance3";
4550// break;
7a387fff 4551 case 4:
d9bea114 4552// gen_helper_mfc0_performance4(arg);
2423f660
TS
4553 rn = "Performance4";
4554// break;
7a387fff 4555 case 5:
d9bea114 4556// gen_helper_mfc0_performance5(arg);
2423f660
TS
4557 rn = "Performance5";
4558// break;
7a387fff 4559 case 6:
d9bea114 4560// gen_helper_mfc0_performance6(arg);
2423f660
TS
4561 rn = "Performance6";
4562// break;
7a387fff 4563 case 7:
d9bea114 4564// gen_helper_mfc0_performance7(arg);
2423f660
TS
4565 rn = "Performance7";
4566// break;
7a387fff
TS
4567 default:
4568 goto die;
4569 }
8c0fdd85
TS
4570 break;
4571 case 26:
d9bea114 4572 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4573 rn = "ECC";
4574 break;
8c0fdd85 4575 case 27:
7a387fff 4576 switch (sel) {
7a387fff 4577 case 0 ... 3:
d9bea114 4578 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4579 rn = "CacheErr";
4580 break;
7a387fff
TS
4581 default:
4582 goto die;
4583 }
8c0fdd85 4584 break;
873eb012
TS
4585 case 28:
4586 switch (sel) {
4587 case 0:
7a387fff
TS
4588 case 2:
4589 case 4:
4590 case 6:
7db13fae 4591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4592 rn = "TagLo";
4593 break;
4594 case 1:
7a387fff
TS
4595 case 3:
4596 case 5:
4597 case 7:
7db13fae 4598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4599 rn = "DataLo";
4600 break;
4601 default:
873eb012
TS
4602 goto die;
4603 }
4604 break;
8c0fdd85 4605 case 29:
7a387fff
TS
4606 switch (sel) {
4607 case 0:
4608 case 2:
4609 case 4:
4610 case 6:
7db13fae 4611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4612 rn = "TagHi";
4613 break;
4614 case 1:
4615 case 3:
4616 case 5:
4617 case 7:
7db13fae 4618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4619 rn = "DataHi";
4620 break;
4621 default:
4622 goto die;
4623 }
8c0fdd85 4624 break;
873eb012 4625 case 30:
7a387fff
TS
4626 switch (sel) {
4627 case 0:
7db13fae 4628 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4629 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4630 rn = "ErrorEPC";
4631 break;
7a387fff
TS
4632 default:
4633 goto die;
4634 }
873eb012
TS
4635 break;
4636 case 31:
7a387fff
TS
4637 switch (sel) {
4638 case 0:
f0b3f3ae 4639 /* EJTAG support */
7db13fae 4640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4641 rn = "DESAVE";
4642 break;
7a387fff
TS
4643 default:
4644 goto die;
4645 }
873eb012
TS
4646 break;
4647 default:
873eb012
TS
4648 goto die;
4649 }
2abf314d 4650 (void)rn; /* avoid a compiler warning */
d12d51d5 4651 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4652 return;
4653
4654die:
d12d51d5 4655 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4656 generate_exception(ctx, EXCP_RI);
4657}
4658
d75c135e 4659static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4660{
7a387fff
TS
4661 const char *rn = "invalid";
4662
e189e748 4663 if (sel != 0)
d75c135e 4664 check_insn(ctx, ISA_MIPS32);
e189e748 4665
2e70f6ef
PB
4666 if (use_icount)
4667 gen_io_start();
4668
8c0fdd85
TS
4669 switch (reg) {
4670 case 0:
7a387fff
TS
4671 switch (sel) {
4672 case 0:
895c2d04 4673 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4674 rn = "Index";
4675 break;
4676 case 1:
d75c135e 4677 check_insn(ctx, ASE_MT);
895c2d04 4678 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4679 rn = "MVPControl";
ead9360e 4680 break;
7a387fff 4681 case 2:
d75c135e 4682 check_insn(ctx, ASE_MT);
ead9360e 4683 /* ignored */
7a387fff 4684 rn = "MVPConf0";
ead9360e 4685 break;
7a387fff 4686 case 3:
d75c135e 4687 check_insn(ctx, ASE_MT);
ead9360e 4688 /* ignored */
7a387fff 4689 rn = "MVPConf1";
ead9360e 4690 break;
7a387fff
TS
4691 default:
4692 goto die;
4693 }
8c0fdd85
TS
4694 break;
4695 case 1:
7a387fff
TS
4696 switch (sel) {
4697 case 0:
2423f660 4698 /* ignored */
7a387fff 4699 rn = "Random";
2423f660 4700 break;
7a387fff 4701 case 1:
d75c135e 4702 check_insn(ctx, ASE_MT);
895c2d04 4703 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4704 rn = "VPEControl";
ead9360e 4705 break;
7a387fff 4706 case 2:
d75c135e 4707 check_insn(ctx, ASE_MT);
895c2d04 4708 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4709 rn = "VPEConf0";
ead9360e 4710 break;
7a387fff 4711 case 3:
d75c135e 4712 check_insn(ctx, ASE_MT);
895c2d04 4713 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4714 rn = "VPEConf1";
ead9360e 4715 break;
7a387fff 4716 case 4:
d75c135e 4717 check_insn(ctx, ASE_MT);
895c2d04 4718 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4719 rn = "YQMask";
ead9360e 4720 break;
7a387fff 4721 case 5:
d75c135e 4722 check_insn(ctx, ASE_MT);
7db13fae 4723 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4724 rn = "VPESchedule";
ead9360e 4725 break;
7a387fff 4726 case 6:
d75c135e 4727 check_insn(ctx, ASE_MT);
7db13fae 4728 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4729 rn = "VPEScheFBack";
ead9360e 4730 break;
7a387fff 4731 case 7:
d75c135e 4732 check_insn(ctx, ASE_MT);
895c2d04 4733 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4734 rn = "VPEOpt";
ead9360e 4735 break;
7a387fff
TS
4736 default:
4737 goto die;
4738 }
8c0fdd85
TS
4739 break;
4740 case 2:
7a387fff
TS
4741 switch (sel) {
4742 case 0:
895c2d04 4743 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4744 rn = "EntryLo0";
4745 break;
7a387fff 4746 case 1:
d75c135e 4747 check_insn(ctx, ASE_MT);
895c2d04 4748 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4749 rn = "TCStatus";
ead9360e 4750 break;
7a387fff 4751 case 2:
d75c135e 4752 check_insn(ctx, ASE_MT);
895c2d04 4753 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4754 rn = "TCBind";
ead9360e 4755 break;
7a387fff 4756 case 3:
d75c135e 4757 check_insn(ctx, ASE_MT);
895c2d04 4758 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4759 rn = "TCRestart";
ead9360e 4760 break;
7a387fff 4761 case 4:
d75c135e 4762 check_insn(ctx, ASE_MT);
895c2d04 4763 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4764 rn = "TCHalt";
ead9360e 4765 break;
7a387fff 4766 case 5:
d75c135e 4767 check_insn(ctx, ASE_MT);
895c2d04 4768 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4769 rn = "TCContext";
ead9360e 4770 break;
7a387fff 4771 case 6:
d75c135e 4772 check_insn(ctx, ASE_MT);
895c2d04 4773 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4774 rn = "TCSchedule";
ead9360e 4775 break;
7a387fff 4776 case 7:
d75c135e 4777 check_insn(ctx, ASE_MT);
895c2d04 4778 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4779 rn = "TCScheFBack";
ead9360e 4780 break;
7a387fff
TS
4781 default:
4782 goto die;
4783 }
8c0fdd85
TS
4784 break;
4785 case 3:
7a387fff
TS
4786 switch (sel) {
4787 case 0:
895c2d04 4788 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4789 rn = "EntryLo1";
4790 break;
7a387fff
TS
4791 default:
4792 goto die;
876d4b07 4793 }
8c0fdd85
TS
4794 break;
4795 case 4:
7a387fff
TS
4796 switch (sel) {
4797 case 0:
895c2d04 4798 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4799 rn = "Context";
4800 break;
7a387fff 4801 case 1:
895c2d04 4802// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
4803 rn = "ContextConfig";
4804// break;
7a387fff
TS
4805 default:
4806 goto die;
876d4b07 4807 }
8c0fdd85
TS
4808 break;
4809 case 5:
7a387fff
TS
4810 switch (sel) {
4811 case 0:
895c2d04 4812 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4813 rn = "PageMask";
4814 break;
7a387fff 4815 case 1:
d75c135e 4816 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4817 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4818 rn = "PageGrain";
4819 break;
7a387fff
TS
4820 default:
4821 goto die;
876d4b07 4822 }
8c0fdd85
TS
4823 break;
4824 case 6:
7a387fff
TS
4825 switch (sel) {
4826 case 0:
895c2d04 4827 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4828 rn = "Wired";
4829 break;
7a387fff 4830 case 1:
d75c135e 4831 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4832 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4833 rn = "SRSConf0";
ead9360e 4834 break;
7a387fff 4835 case 2:
d75c135e 4836 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4837 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4838 rn = "SRSConf1";
ead9360e 4839 break;
7a387fff 4840 case 3:
d75c135e 4841 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4842 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4843 rn = "SRSConf2";
ead9360e 4844 break;
7a387fff 4845 case 4:
d75c135e 4846 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4847 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4848 rn = "SRSConf3";
ead9360e 4849 break;
7a387fff 4850 case 5:
d75c135e 4851 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4852 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4853 rn = "SRSConf4";
ead9360e 4854 break;
7a387fff
TS
4855 default:
4856 goto die;
876d4b07 4857 }
8c0fdd85
TS
4858 break;
4859 case 7:
7a387fff
TS
4860 switch (sel) {
4861 case 0:
d75c135e 4862 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4863 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
4864 rn = "HWREna";
4865 break;
7a387fff
TS
4866 default:
4867 goto die;
876d4b07 4868 }
8c0fdd85
TS
4869 break;
4870 case 8:
7a387fff 4871 /* ignored */
f0b3f3ae 4872 rn = "BadVAddr";
8c0fdd85
TS
4873 break;
4874 case 9:
7a387fff
TS
4875 switch (sel) {
4876 case 0:
895c2d04 4877 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4878 rn = "Count";
4879 break;
876d4b07 4880 /* 6,7 are implementation dependent */
7a387fff
TS
4881 default:
4882 goto die;
876d4b07 4883 }
8c0fdd85
TS
4884 break;
4885 case 10:
7a387fff
TS
4886 switch (sel) {
4887 case 0:
895c2d04 4888 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4889 rn = "EntryHi";
4890 break;
7a387fff
TS
4891 default:
4892 goto die;
876d4b07 4893 }
8c0fdd85
TS
4894 break;
4895 case 11:
7a387fff
TS
4896 switch (sel) {
4897 case 0:
895c2d04 4898 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4899 rn = "Compare";
4900 break;
4901 /* 6,7 are implementation dependent */
7a387fff
TS
4902 default:
4903 goto die;
876d4b07 4904 }
8c0fdd85
TS
4905 break;
4906 case 12:
7a387fff
TS
4907 switch (sel) {
4908 case 0:
867abc7e 4909 save_cpu_state(ctx, 1);
895c2d04 4910 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4911 /* BS_STOP isn't good enough here, hflags may have changed. */
4912 gen_save_pc(ctx->pc + 4);
4913 ctx->bstate = BS_EXCP;
2423f660
TS
4914 rn = "Status";
4915 break;
7a387fff 4916 case 1:
d75c135e 4917 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4918 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4919 /* Stop translation as we may have switched the execution mode */
4920 ctx->bstate = BS_STOP;
2423f660
TS
4921 rn = "IntCtl";
4922 break;
7a387fff 4923 case 2:
d75c135e 4924 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4925 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4926 /* Stop translation as we may have switched the execution mode */
4927 ctx->bstate = BS_STOP;
2423f660
TS
4928 rn = "SRSCtl";
4929 break;
7a387fff 4930 case 3:
d75c135e 4931 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4932 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4933 /* Stop translation as we may have switched the execution mode */
4934 ctx->bstate = BS_STOP;
2423f660 4935 rn = "SRSMap";
fd88b6ab 4936 break;
7a387fff
TS
4937 default:
4938 goto die;
876d4b07 4939 }
8c0fdd85
TS
4940 break;
4941 case 13:
7a387fff
TS
4942 switch (sel) {
4943 case 0:
867abc7e 4944 save_cpu_state(ctx, 1);
895c2d04 4945 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4946 rn = "Cause";
4947 break;
7a387fff
TS
4948 default:
4949 goto die;
876d4b07 4950 }
8c0fdd85
TS
4951 break;
4952 case 14:
7a387fff
TS
4953 switch (sel) {
4954 case 0:
7db13fae 4955 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4956 rn = "EPC";
4957 break;
7a387fff
TS
4958 default:
4959 goto die;
876d4b07 4960 }
8c0fdd85
TS
4961 break;
4962 case 15:
7a387fff
TS
4963 switch (sel) {
4964 case 0:
2423f660
TS
4965 /* ignored */
4966 rn = "PRid";
4967 break;
7a387fff 4968 case 1:
d75c135e 4969 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4970 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
4971 rn = "EBase";
4972 break;
7a387fff
TS
4973 default:
4974 goto die;
1579a72e 4975 }
8c0fdd85
TS
4976 break;
4977 case 16:
4978 switch (sel) {
4979 case 0:
895c2d04 4980 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 4981 rn = "Config";
2423f660
TS
4982 /* Stop translation as we may have switched the execution mode */
4983 ctx->bstate = BS_STOP;
7a387fff
TS
4984 break;
4985 case 1:
e397ee33 4986 /* ignored, read only */
7a387fff
TS
4987 rn = "Config1";
4988 break;
4989 case 2:
895c2d04 4990 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 4991 rn = "Config2";
2423f660
TS
4992 /* Stop translation as we may have switched the execution mode */
4993 ctx->bstate = BS_STOP;
8c0fdd85 4994 break;
7a387fff 4995 case 3:
e397ee33 4996 /* ignored, read only */
7a387fff
TS
4997 rn = "Config3";
4998 break;
b4160af1
PJ
4999 case 4:
5000 gen_helper_mtc0_config4(cpu_env, arg);
5001 rn = "Config4";
5002 ctx->bstate = BS_STOP;
5003 break;
b4dd99a3
PJ
5004 case 5:
5005 gen_helper_mtc0_config5(cpu_env, arg);
5006 rn = "Config5";
5007 /* Stop translation as we may have switched the execution mode */
5008 ctx->bstate = BS_STOP;
5009 break;
e397ee33
TS
5010 /* 6,7 are implementation dependent */
5011 case 6:
5012 /* ignored */
5013 rn = "Config6";
5014 break;
5015 case 7:
5016 /* ignored */
5017 rn = "Config7";
5018 break;
8c0fdd85
TS
5019 default:
5020 rn = "Invalid config selector";
5021 goto die;
5022 }
5023 break;
5024 case 17:
7a387fff
TS
5025 switch (sel) {
5026 case 0:
895c2d04 5027 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5028 rn = "LLAddr";
5029 break;
7a387fff
TS
5030 default:
5031 goto die;
5032 }
8c0fdd85
TS
5033 break;
5034 case 18:
7a387fff 5035 switch (sel) {
fd88b6ab 5036 case 0 ... 7:
895c2d04 5037 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5038 rn = "WatchLo";
5039 break;
7a387fff
TS
5040 default:
5041 goto die;
5042 }
8c0fdd85
TS
5043 break;
5044 case 19:
7a387fff 5045 switch (sel) {
fd88b6ab 5046 case 0 ... 7:
895c2d04 5047 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5048 rn = "WatchHi";
5049 break;
7a387fff
TS
5050 default:
5051 goto die;
5052 }
8c0fdd85
TS
5053 break;
5054 case 20:
7a387fff
TS
5055 switch (sel) {
5056 case 0:
d26bc211 5057#if defined(TARGET_MIPS64)
d75c135e 5058 check_insn(ctx, ISA_MIPS3);
895c2d04 5059 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5060 rn = "XContext";
5061 break;
703eaf37 5062#endif
7a387fff
TS
5063 default:
5064 goto die;
5065 }
8c0fdd85
TS
5066 break;
5067 case 21:
7a387fff
TS
5068 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5069 switch (sel) {
5070 case 0:
895c2d04 5071 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5072 rn = "Framemask";
5073 break;
7a387fff
TS
5074 default:
5075 goto die;
5076 }
5077 break;
8c0fdd85 5078 case 22:
7a387fff
TS
5079 /* ignored */
5080 rn = "Diagnostic"; /* implementation dependent */
2423f660 5081 break;
8c0fdd85 5082 case 23:
7a387fff
TS
5083 switch (sel) {
5084 case 0:
895c2d04 5085 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5086 /* BS_STOP isn't good enough here, hflags may have changed. */
5087 gen_save_pc(ctx->pc + 4);
5088 ctx->bstate = BS_EXCP;
2423f660
TS
5089 rn = "Debug";
5090 break;
7a387fff 5091 case 1:
895c2d04 5092// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5093 rn = "TraceControl";
8487327a
TS
5094 /* Stop translation as we may have switched the execution mode */
5095 ctx->bstate = BS_STOP;
2423f660 5096// break;
7a387fff 5097 case 2:
895c2d04 5098// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5099 rn = "TraceControl2";
8487327a
TS
5100 /* Stop translation as we may have switched the execution mode */
5101 ctx->bstate = BS_STOP;
2423f660 5102// break;
7a387fff 5103 case 3:
8487327a
TS
5104 /* Stop translation as we may have switched the execution mode */
5105 ctx->bstate = BS_STOP;
895c2d04 5106// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5107 rn = "UserTraceData";
8487327a
TS
5108 /* Stop translation as we may have switched the execution mode */
5109 ctx->bstate = BS_STOP;
2423f660 5110// break;
7a387fff 5111 case 4:
895c2d04 5112// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5113 /* Stop translation as we may have switched the execution mode */
5114 ctx->bstate = BS_STOP;
2423f660
TS
5115 rn = "TraceBPC";
5116// break;
7a387fff
TS
5117 default:
5118 goto die;
5119 }
8c0fdd85
TS
5120 break;
5121 case 24:
7a387fff
TS
5122 switch (sel) {
5123 case 0:
f1aa6320 5124 /* EJTAG support */
7db13fae 5125 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5126 rn = "DEPC";
5127 break;
7a387fff
TS
5128 default:
5129 goto die;
5130 }
8c0fdd85
TS
5131 break;
5132 case 25:
7a387fff
TS
5133 switch (sel) {
5134 case 0:
895c2d04 5135 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5136 rn = "Performance0";
5137 break;
7a387fff 5138 case 1:
d9bea114 5139// gen_helper_mtc0_performance1(arg);
2423f660
TS
5140 rn = "Performance1";
5141// break;
7a387fff 5142 case 2:
d9bea114 5143// gen_helper_mtc0_performance2(arg);
2423f660
TS
5144 rn = "Performance2";
5145// break;
7a387fff 5146 case 3:
d9bea114 5147// gen_helper_mtc0_performance3(arg);
2423f660
TS
5148 rn = "Performance3";
5149// break;
7a387fff 5150 case 4:
d9bea114 5151// gen_helper_mtc0_performance4(arg);
2423f660
TS
5152 rn = "Performance4";
5153// break;
7a387fff 5154 case 5:
d9bea114 5155// gen_helper_mtc0_performance5(arg);
2423f660
TS
5156 rn = "Performance5";
5157// break;
7a387fff 5158 case 6:
d9bea114 5159// gen_helper_mtc0_performance6(arg);
2423f660
TS
5160 rn = "Performance6";
5161// break;
7a387fff 5162 case 7:
d9bea114 5163// gen_helper_mtc0_performance7(arg);
2423f660
TS
5164 rn = "Performance7";
5165// break;
7a387fff
TS
5166 default:
5167 goto die;
5168 }
8c0fdd85
TS
5169 break;
5170 case 26:
2423f660 5171 /* ignored */
8c0fdd85 5172 rn = "ECC";
2423f660 5173 break;
8c0fdd85 5174 case 27:
7a387fff
TS
5175 switch (sel) {
5176 case 0 ... 3:
2423f660
TS
5177 /* ignored */
5178 rn = "CacheErr";
5179 break;
7a387fff
TS
5180 default:
5181 goto die;
5182 }
8c0fdd85
TS
5183 break;
5184 case 28:
5185 switch (sel) {
5186 case 0:
7a387fff
TS
5187 case 2:
5188 case 4:
5189 case 6:
895c2d04 5190 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5191 rn = "TagLo";
5192 break;
7a387fff
TS
5193 case 1:
5194 case 3:
5195 case 5:
5196 case 7:
895c2d04 5197 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5198 rn = "DataLo";
5199 break;
8c0fdd85 5200 default:
8c0fdd85
TS
5201 goto die;
5202 }
5203 break;
5204 case 29:
7a387fff
TS
5205 switch (sel) {
5206 case 0:
5207 case 2:
5208 case 4:
5209 case 6:
895c2d04 5210 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5211 rn = "TagHi";
5212 break;
5213 case 1:
5214 case 3:
5215 case 5:
5216 case 7:
895c2d04 5217 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5218 rn = "DataHi";
5219 break;
5220 default:
5221 rn = "invalid sel";
5222 goto die;
5223 }
8c0fdd85
TS
5224 break;
5225 case 30:
7a387fff
TS
5226 switch (sel) {
5227 case 0:
7db13fae 5228 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5229 rn = "ErrorEPC";
5230 break;
7a387fff
TS
5231 default:
5232 goto die;
5233 }
8c0fdd85
TS
5234 break;
5235 case 31:
7a387fff
TS
5236 switch (sel) {
5237 case 0:
f1aa6320 5238 /* EJTAG support */
7db13fae 5239 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5240 rn = "DESAVE";
5241 break;
7a387fff
TS
5242 default:
5243 goto die;
5244 }
2423f660
TS
5245 /* Stop translation as we may have switched the execution mode */
5246 ctx->bstate = BS_STOP;
8c0fdd85
TS
5247 break;
5248 default:
8c0fdd85
TS
5249 goto die;
5250 }
2abf314d 5251 (void)rn; /* avoid a compiler warning */
d12d51d5 5252 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5253 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5254 if (use_icount) {
5255 gen_io_end();
5256 ctx->bstate = BS_STOP;
5257 }
8c0fdd85
TS
5258 return;
5259
5260die:
d12d51d5 5261 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5262 generate_exception(ctx, EXCP_RI);
5263}
5264
d26bc211 5265#if defined(TARGET_MIPS64)
d75c135e 5266static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5267{
5268 const char *rn = "invalid";
5269
e189e748 5270 if (sel != 0)
d75c135e 5271 check_insn(ctx, ISA_MIPS64);
e189e748 5272
9c2149c8
TS
5273 switch (reg) {
5274 case 0:
5275 switch (sel) {
5276 case 0:
7db13fae 5277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5278 rn = "Index";
5279 break;
5280 case 1:
d75c135e 5281 check_insn(ctx, ASE_MT);
895c2d04 5282 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5283 rn = "MVPControl";
ead9360e 5284 break;
9c2149c8 5285 case 2:
d75c135e 5286 check_insn(ctx, ASE_MT);
895c2d04 5287 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5288 rn = "MVPConf0";
ead9360e 5289 break;
9c2149c8 5290 case 3:
d75c135e 5291 check_insn(ctx, ASE_MT);
895c2d04 5292 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5293 rn = "MVPConf1";
ead9360e 5294 break;
9c2149c8
TS
5295 default:
5296 goto die;
5297 }
5298 break;
5299 case 1:
5300 switch (sel) {
5301 case 0:
895c2d04 5302 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5303 rn = "Random";
2423f660 5304 break;
9c2149c8 5305 case 1:
d75c135e 5306 check_insn(ctx, ASE_MT);
7db13fae 5307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5308 rn = "VPEControl";
ead9360e 5309 break;
9c2149c8 5310 case 2:
d75c135e 5311 check_insn(ctx, ASE_MT);
7db13fae 5312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5313 rn = "VPEConf0";
ead9360e 5314 break;
9c2149c8 5315 case 3:
d75c135e 5316 check_insn(ctx, ASE_MT);
7db13fae 5317 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5318 rn = "VPEConf1";
ead9360e 5319 break;
9c2149c8 5320 case 4:
d75c135e 5321 check_insn(ctx, ASE_MT);
7db13fae 5322 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5323 rn = "YQMask";
ead9360e 5324 break;
9c2149c8 5325 case 5:
d75c135e 5326 check_insn(ctx, ASE_MT);
7db13fae 5327 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5328 rn = "VPESchedule";
ead9360e 5329 break;
9c2149c8 5330 case 6:
d75c135e 5331 check_insn(ctx, ASE_MT);
7db13fae 5332 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5333 rn = "VPEScheFBack";
ead9360e 5334 break;
9c2149c8 5335 case 7:
d75c135e 5336 check_insn(ctx, ASE_MT);
7db13fae 5337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5338 rn = "VPEOpt";
ead9360e 5339 break;
9c2149c8
TS
5340 default:
5341 goto die;
5342 }
5343 break;
5344 case 2:
5345 switch (sel) {
5346 case 0:
7db13fae 5347 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5348 rn = "EntryLo0";
5349 break;
9c2149c8 5350 case 1:
d75c135e 5351 check_insn(ctx, ASE_MT);
895c2d04 5352 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5353 rn = "TCStatus";
ead9360e 5354 break;
9c2149c8 5355 case 2:
d75c135e 5356 check_insn(ctx, ASE_MT);
895c2d04 5357 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5358 rn = "TCBind";
ead9360e 5359 break;
9c2149c8 5360 case 3:
d75c135e 5361 check_insn(ctx, ASE_MT);
895c2d04 5362 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5363 rn = "TCRestart";
ead9360e 5364 break;
9c2149c8 5365 case 4:
d75c135e 5366 check_insn(ctx, ASE_MT);
895c2d04 5367 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5368 rn = "TCHalt";
ead9360e 5369 break;
9c2149c8 5370 case 5:
d75c135e 5371 check_insn(ctx, ASE_MT);
895c2d04 5372 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5373 rn = "TCContext";
ead9360e 5374 break;
9c2149c8 5375 case 6:
d75c135e 5376 check_insn(ctx, ASE_MT);
895c2d04 5377 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5378 rn = "TCSchedule";
ead9360e 5379 break;
9c2149c8 5380 case 7:
d75c135e 5381 check_insn(ctx, ASE_MT);
895c2d04 5382 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5383 rn = "TCScheFBack";
ead9360e 5384 break;
9c2149c8
TS
5385 default:
5386 goto die;
5387 }
5388 break;
5389 case 3:
5390 switch (sel) {
5391 case 0:
7db13fae 5392 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5393 rn = "EntryLo1";
5394 break;
9c2149c8
TS
5395 default:
5396 goto die;
1579a72e 5397 }
9c2149c8
TS
5398 break;
5399 case 4:
5400 switch (sel) {
5401 case 0:
7db13fae 5402 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5403 rn = "Context";
5404 break;
9c2149c8 5405 case 1:
d9bea114 5406// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
5407 rn = "ContextConfig";
5408// break;
9c2149c8
TS
5409 default:
5410 goto die;
876d4b07 5411 }
9c2149c8
TS
5412 break;
5413 case 5:
5414 switch (sel) {
5415 case 0:
7db13fae 5416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5417 rn = "PageMask";
5418 break;
9c2149c8 5419 case 1:
d75c135e 5420 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5421 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5422 rn = "PageGrain";
5423 break;
9c2149c8
TS
5424 default:
5425 goto die;
876d4b07 5426 }
9c2149c8
TS
5427 break;
5428 case 6:
5429 switch (sel) {
5430 case 0:
7db13fae 5431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5432 rn = "Wired";
5433 break;
9c2149c8 5434 case 1:
d75c135e 5435 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5436 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5437 rn = "SRSConf0";
ead9360e 5438 break;
9c2149c8 5439 case 2:
d75c135e 5440 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5441 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5442 rn = "SRSConf1";
ead9360e 5443 break;
9c2149c8 5444 case 3:
d75c135e 5445 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5447 rn = "SRSConf2";
ead9360e 5448 break;
9c2149c8 5449 case 4:
d75c135e 5450 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5452 rn = "SRSConf3";
ead9360e 5453 break;
9c2149c8 5454 case 5:
d75c135e 5455 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5457 rn = "SRSConf4";
ead9360e 5458 break;
9c2149c8
TS
5459 default:
5460 goto die;
876d4b07 5461 }
9c2149c8
TS
5462 break;
5463 case 7:
5464 switch (sel) {
5465 case 0:
d75c135e 5466 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5468 rn = "HWREna";
5469 break;
9c2149c8
TS
5470 default:
5471 goto die;
876d4b07 5472 }
9c2149c8
TS
5473 break;
5474 case 8:
5475 switch (sel) {
5476 case 0:
7db13fae 5477 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5478 rn = "BadVAddr";
2423f660 5479 break;
9c2149c8
TS
5480 default:
5481 goto die;
876d4b07 5482 }
9c2149c8
TS
5483 break;
5484 case 9:
5485 switch (sel) {
5486 case 0:
2e70f6ef
PB
5487 /* Mark as an IO operation because we read the time. */
5488 if (use_icount)
5489 gen_io_start();
895c2d04 5490 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5491 if (use_icount) {
5492 gen_io_end();
2e70f6ef 5493 }
55807224
EI
5494 /* Break the TB to be able to take timer interrupts immediately
5495 after reading count. */
5496 ctx->bstate = BS_STOP;
2423f660
TS
5497 rn = "Count";
5498 break;
5499 /* 6,7 are implementation dependent */
9c2149c8
TS
5500 default:
5501 goto die;
876d4b07 5502 }
9c2149c8
TS
5503 break;
5504 case 10:
5505 switch (sel) {
5506 case 0:
7db13fae 5507 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5508 rn = "EntryHi";
5509 break;
9c2149c8
TS
5510 default:
5511 goto die;
876d4b07 5512 }
9c2149c8
TS
5513 break;
5514 case 11:
5515 switch (sel) {
5516 case 0:
7db13fae 5517 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5518 rn = "Compare";
5519 break;
876d4b07 5520 /* 6,7 are implementation dependent */
9c2149c8
TS
5521 default:
5522 goto die;
876d4b07 5523 }
9c2149c8
TS
5524 break;
5525 case 12:
5526 switch (sel) {
5527 case 0:
7db13fae 5528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5529 rn = "Status";
5530 break;
9c2149c8 5531 case 1:
d75c135e 5532 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5534 rn = "IntCtl";
5535 break;
9c2149c8 5536 case 2:
d75c135e 5537 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5539 rn = "SRSCtl";
5540 break;
9c2149c8 5541 case 3:
d75c135e 5542 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5543 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5544 rn = "SRSMap";
5545 break;
9c2149c8
TS
5546 default:
5547 goto die;
876d4b07 5548 }
9c2149c8
TS
5549 break;
5550 case 13:
5551 switch (sel) {
5552 case 0:
7db13fae 5553 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5554 rn = "Cause";
5555 break;
9c2149c8
TS
5556 default:
5557 goto die;
876d4b07 5558 }
9c2149c8
TS
5559 break;
5560 case 14:
5561 switch (sel) {
5562 case 0:
7db13fae 5563 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5564 rn = "EPC";
5565 break;
9c2149c8
TS
5566 default:
5567 goto die;
876d4b07 5568 }
9c2149c8
TS
5569 break;
5570 case 15:
5571 switch (sel) {
5572 case 0:
7db13fae 5573 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5574 rn = "PRid";
5575 break;
9c2149c8 5576 case 1:
d75c135e 5577 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5578 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5579 rn = "EBase";
5580 break;
9c2149c8
TS
5581 default:
5582 goto die;
876d4b07 5583 }
9c2149c8
TS
5584 break;
5585 case 16:
5586 switch (sel) {
5587 case 0:
7db13fae 5588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5589 rn = "Config";
5590 break;
5591 case 1:
7db13fae 5592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5593 rn = "Config1";
5594 break;
5595 case 2:
7db13fae 5596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5597 rn = "Config2";
5598 break;
5599 case 3:
7db13fae 5600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5601 rn = "Config3";
5602 break;
5603 /* 6,7 are implementation dependent */
f0b3f3ae 5604 case 6:
7db13fae 5605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5606 rn = "Config6";
5607 break;
5608 case 7:
7db13fae 5609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5610 rn = "Config7";
5611 break;
9c2149c8
TS
5612 default:
5613 goto die;
5614 }
5615 break;
5616 case 17:
5617 switch (sel) {
5618 case 0:
895c2d04 5619 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5620 rn = "LLAddr";
5621 break;
9c2149c8
TS
5622 default:
5623 goto die;
5624 }
5625 break;
5626 case 18:
5627 switch (sel) {
fd88b6ab 5628 case 0 ... 7:
895c2d04 5629 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5630 rn = "WatchLo";
5631 break;
9c2149c8
TS
5632 default:
5633 goto die;
5634 }
5635 break;
5636 case 19:
5637 switch (sel) {
fd88b6ab 5638 case 0 ... 7:
895c2d04 5639 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5640 rn = "WatchHi";
5641 break;
9c2149c8
TS
5642 default:
5643 goto die;
5644 }
5645 break;
5646 case 20:
5647 switch (sel) {
5648 case 0:
d75c135e 5649 check_insn(ctx, ISA_MIPS3);
7db13fae 5650 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5651 rn = "XContext";
5652 break;
9c2149c8
TS
5653 default:
5654 goto die;
5655 }
5656 break;
5657 case 21:
5658 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5659 switch (sel) {
5660 case 0:
7db13fae 5661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5662 rn = "Framemask";
5663 break;
9c2149c8
TS
5664 default:
5665 goto die;
5666 }
5667 break;
5668 case 22:
d9bea114 5669 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5670 rn = "'Diagnostic"; /* implementation dependent */
5671 break;
9c2149c8
TS
5672 case 23:
5673 switch (sel) {
5674 case 0:
895c2d04 5675 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5676 rn = "Debug";
5677 break;
9c2149c8 5678 case 1:
895c2d04 5679// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5680 rn = "TraceControl";
5681// break;
9c2149c8 5682 case 2:
895c2d04 5683// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5684 rn = "TraceControl2";
5685// break;
9c2149c8 5686 case 3:
895c2d04 5687// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5688 rn = "UserTraceData";
5689// break;
9c2149c8 5690 case 4:
895c2d04 5691// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5692 rn = "TraceBPC";
5693// break;
9c2149c8
TS
5694 default:
5695 goto die;
5696 }
5697 break;
5698 case 24:
5699 switch (sel) {
5700 case 0:
f0b3f3ae 5701 /* EJTAG support */
7db13fae 5702 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5703 rn = "DEPC";
5704 break;
9c2149c8
TS
5705 default:
5706 goto die;
5707 }
5708 break;
5709 case 25:
5710 switch (sel) {
5711 case 0:
7db13fae 5712 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5713 rn = "Performance0";
9c2149c8
TS
5714 break;
5715 case 1:
d9bea114 5716// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5717 rn = "Performance1";
5718// break;
9c2149c8 5719 case 2:
d9bea114 5720// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5721 rn = "Performance2";
5722// break;
9c2149c8 5723 case 3:
d9bea114 5724// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5725 rn = "Performance3";
5726// break;
9c2149c8 5727 case 4:
d9bea114 5728// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5729 rn = "Performance4";
5730// break;
9c2149c8 5731 case 5:
d9bea114 5732// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5733 rn = "Performance5";
5734// break;
9c2149c8 5735 case 6:
d9bea114 5736// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5737 rn = "Performance6";
5738// break;
9c2149c8 5739 case 7:
d9bea114 5740// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5741 rn = "Performance7";
5742// break;
9c2149c8
TS
5743 default:
5744 goto die;
5745 }
5746 break;
5747 case 26:
d9bea114 5748 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5749 rn = "ECC";
5750 break;
9c2149c8
TS
5751 case 27:
5752 switch (sel) {
5753 /* ignored */
5754 case 0 ... 3:
d9bea114 5755 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5756 rn = "CacheErr";
5757 break;
9c2149c8
TS
5758 default:
5759 goto die;
5760 }
5761 break;
5762 case 28:
5763 switch (sel) {
5764 case 0:
5765 case 2:
5766 case 4:
5767 case 6:
7db13fae 5768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5769 rn = "TagLo";
5770 break;
5771 case 1:
5772 case 3:
5773 case 5:
5774 case 7:
7db13fae 5775 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5776 rn = "DataLo";
5777 break;
5778 default:
5779 goto die;
5780 }
5781 break;
5782 case 29:
5783 switch (sel) {
5784 case 0:
5785 case 2:
5786 case 4:
5787 case 6:
7db13fae 5788 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5789 rn = "TagHi";
5790 break;
5791 case 1:
5792 case 3:
5793 case 5:
5794 case 7:
7db13fae 5795 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5796 rn = "DataHi";
5797 break;
5798 default:
5799 goto die;
5800 }
5801 break;
5802 case 30:
5803 switch (sel) {
5804 case 0:
7db13fae 5805 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5806 rn = "ErrorEPC";
5807 break;
9c2149c8
TS
5808 default:
5809 goto die;
5810 }
5811 break;
5812 case 31:
5813 switch (sel) {
5814 case 0:
f0b3f3ae 5815 /* EJTAG support */
7db13fae 5816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5817 rn = "DESAVE";
5818 break;
9c2149c8
TS
5819 default:
5820 goto die;
5821 }
5822 break;
5823 default:
876d4b07 5824 goto die;
9c2149c8 5825 }
2abf314d 5826 (void)rn; /* avoid a compiler warning */
d12d51d5 5827 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5828 return;
5829
5830die:
d12d51d5 5831 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5832 generate_exception(ctx, EXCP_RI);
5833}
5834
d75c135e 5835static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5836{
5837 const char *rn = "invalid";
5838
e189e748 5839 if (sel != 0)
d75c135e 5840 check_insn(ctx, ISA_MIPS64);
e189e748 5841
2e70f6ef
PB
5842 if (use_icount)
5843 gen_io_start();
5844
9c2149c8
TS
5845 switch (reg) {
5846 case 0:
5847 switch (sel) {
5848 case 0:
895c2d04 5849 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5850 rn = "Index";
5851 break;
5852 case 1:
d75c135e 5853 check_insn(ctx, ASE_MT);
895c2d04 5854 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5855 rn = "MVPControl";
ead9360e 5856 break;
9c2149c8 5857 case 2:
d75c135e 5858 check_insn(ctx, ASE_MT);
ead9360e 5859 /* ignored */
9c2149c8 5860 rn = "MVPConf0";
ead9360e 5861 break;
9c2149c8 5862 case 3:
d75c135e 5863 check_insn(ctx, ASE_MT);
ead9360e 5864 /* ignored */
9c2149c8 5865 rn = "MVPConf1";
ead9360e 5866 break;
9c2149c8
TS
5867 default:
5868 goto die;
5869 }
5870 break;
5871 case 1:
5872 switch (sel) {
5873 case 0:
2423f660 5874 /* ignored */
9c2149c8 5875 rn = "Random";
2423f660 5876 break;
9c2149c8 5877 case 1:
d75c135e 5878 check_insn(ctx, ASE_MT);
895c2d04 5879 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5880 rn = "VPEControl";
ead9360e 5881 break;
9c2149c8 5882 case 2:
d75c135e 5883 check_insn(ctx, ASE_MT);
895c2d04 5884 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5885 rn = "VPEConf0";
ead9360e 5886 break;
9c2149c8 5887 case 3:
d75c135e 5888 check_insn(ctx, ASE_MT);
895c2d04 5889 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5890 rn = "VPEConf1";
ead9360e 5891 break;
9c2149c8 5892 case 4:
d75c135e 5893 check_insn(ctx, ASE_MT);
895c2d04 5894 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5895 rn = "YQMask";
ead9360e 5896 break;
9c2149c8 5897 case 5:
d75c135e 5898 check_insn(ctx, ASE_MT);
7db13fae 5899 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5900 rn = "VPESchedule";
ead9360e 5901 break;
9c2149c8 5902 case 6:
d75c135e 5903 check_insn(ctx, ASE_MT);
7db13fae 5904 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5905 rn = "VPEScheFBack";
ead9360e 5906 break;
9c2149c8 5907 case 7:
d75c135e 5908 check_insn(ctx, ASE_MT);
895c2d04 5909 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5910 rn = "VPEOpt";
ead9360e 5911 break;
9c2149c8
TS
5912 default:
5913 goto die;
5914 }
5915 break;
5916 case 2:
5917 switch (sel) {
5918 case 0:
895c2d04 5919 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5920 rn = "EntryLo0";
5921 break;
9c2149c8 5922 case 1:
d75c135e 5923 check_insn(ctx, ASE_MT);
895c2d04 5924 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5925 rn = "TCStatus";
ead9360e 5926 break;
9c2149c8 5927 case 2:
d75c135e 5928 check_insn(ctx, ASE_MT);
895c2d04 5929 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5930 rn = "TCBind";
ead9360e 5931 break;
9c2149c8 5932 case 3:
d75c135e 5933 check_insn(ctx, ASE_MT);
895c2d04 5934 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5935 rn = "TCRestart";
ead9360e 5936 break;
9c2149c8 5937 case 4:
d75c135e 5938 check_insn(ctx, ASE_MT);
895c2d04 5939 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5940 rn = "TCHalt";
ead9360e 5941 break;
9c2149c8 5942 case 5:
d75c135e 5943 check_insn(ctx, ASE_MT);
895c2d04 5944 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5945 rn = "TCContext";
ead9360e 5946 break;
9c2149c8 5947 case 6:
d75c135e 5948 check_insn(ctx, ASE_MT);
895c2d04 5949 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5950 rn = "TCSchedule";
ead9360e 5951 break;
9c2149c8 5952 case 7:
d75c135e 5953 check_insn(ctx, ASE_MT);
895c2d04 5954 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5955 rn = "TCScheFBack";
ead9360e 5956 break;
9c2149c8
TS
5957 default:
5958 goto die;
5959 }
5960 break;
5961 case 3:
5962 switch (sel) {
5963 case 0:
895c2d04 5964 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5965 rn = "EntryLo1";
5966 break;
9c2149c8
TS
5967 default:
5968 goto die;
876d4b07 5969 }
9c2149c8
TS
5970 break;
5971 case 4:
5972 switch (sel) {
5973 case 0:
895c2d04 5974 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5975 rn = "Context";
5976 break;
9c2149c8 5977 case 1:
895c2d04 5978// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
5979 rn = "ContextConfig";
5980// break;
9c2149c8
TS
5981 default:
5982 goto die;
876d4b07 5983 }
9c2149c8
TS
5984 break;
5985 case 5:
5986 switch (sel) {
5987 case 0:
895c2d04 5988 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5989 rn = "PageMask";
5990 break;
9c2149c8 5991 case 1:
d75c135e 5992 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5993 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5994 rn = "PageGrain";
5995 break;
9c2149c8
TS
5996 default:
5997 goto die;
876d4b07 5998 }
9c2149c8
TS
5999 break;
6000 case 6:
6001 switch (sel) {
6002 case 0:
895c2d04 6003 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6004 rn = "Wired";
6005 break;
9c2149c8 6006 case 1:
d75c135e 6007 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6008 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6009 rn = "SRSConf0";
ead9360e 6010 break;
9c2149c8 6011 case 2:
d75c135e 6012 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6013 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6014 rn = "SRSConf1";
ead9360e 6015 break;
9c2149c8 6016 case 3:
d75c135e 6017 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6018 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6019 rn = "SRSConf2";
ead9360e 6020 break;
9c2149c8 6021 case 4:
d75c135e 6022 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6023 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6024 rn = "SRSConf3";
ead9360e 6025 break;
9c2149c8 6026 case 5:
d75c135e 6027 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6028 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6029 rn = "SRSConf4";
ead9360e 6030 break;
9c2149c8
TS
6031 default:
6032 goto die;
876d4b07 6033 }
9c2149c8
TS
6034 break;
6035 case 7:
6036 switch (sel) {
6037 case 0:
d75c135e 6038 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6039 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
6040 rn = "HWREna";
6041 break;
9c2149c8
TS
6042 default:
6043 goto die;
876d4b07 6044 }
9c2149c8
TS
6045 break;
6046 case 8:
6047 /* ignored */
f0b3f3ae 6048 rn = "BadVAddr";
9c2149c8
TS
6049 break;
6050 case 9:
6051 switch (sel) {
6052 case 0:
895c2d04 6053 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6054 rn = "Count";
6055 break;
876d4b07 6056 /* 6,7 are implementation dependent */
9c2149c8
TS
6057 default:
6058 goto die;
876d4b07
TS
6059 }
6060 /* Stop translation as we may have switched the execution mode */
6061 ctx->bstate = BS_STOP;
9c2149c8
TS
6062 break;
6063 case 10:
6064 switch (sel) {
6065 case 0:
895c2d04 6066 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6067 rn = "EntryHi";
6068 break;
9c2149c8
TS
6069 default:
6070 goto die;
876d4b07 6071 }
9c2149c8
TS
6072 break;
6073 case 11:
6074 switch (sel) {
6075 case 0:
895c2d04 6076 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6077 rn = "Compare";
6078 break;
876d4b07 6079 /* 6,7 are implementation dependent */
9c2149c8
TS
6080 default:
6081 goto die;
876d4b07 6082 }
de9a95f0
AJ
6083 /* Stop translation as we may have switched the execution mode */
6084 ctx->bstate = BS_STOP;
9c2149c8
TS
6085 break;
6086 case 12:
6087 switch (sel) {
6088 case 0:
867abc7e 6089 save_cpu_state(ctx, 1);
895c2d04 6090 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6091 /* BS_STOP isn't good enough here, hflags may have changed. */
6092 gen_save_pc(ctx->pc + 4);
6093 ctx->bstate = BS_EXCP;
2423f660
TS
6094 rn = "Status";
6095 break;
9c2149c8 6096 case 1:
d75c135e 6097 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6098 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6099 /* Stop translation as we may have switched the execution mode */
6100 ctx->bstate = BS_STOP;
2423f660
TS
6101 rn = "IntCtl";
6102 break;
9c2149c8 6103 case 2:
d75c135e 6104 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6105 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6106 /* Stop translation as we may have switched the execution mode */
6107 ctx->bstate = BS_STOP;
2423f660
TS
6108 rn = "SRSCtl";
6109 break;
9c2149c8 6110 case 3:
d75c135e 6111 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6112 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6113 /* Stop translation as we may have switched the execution mode */
6114 ctx->bstate = BS_STOP;
2423f660
TS
6115 rn = "SRSMap";
6116 break;
6117 default:
9c2149c8 6118 goto die;
876d4b07 6119 }
9c2149c8
TS
6120 break;
6121 case 13:
6122 switch (sel) {
6123 case 0:
867abc7e 6124 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6125 /* Mark as an IO operation because we may trigger a software
6126 interrupt. */
6127 if (use_icount) {
6128 gen_io_start();
6129 }
895c2d04 6130 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6131 if (use_icount) {
6132 gen_io_end();
6133 }
6134 /* Stop translation as we may have triggered an intetrupt */
6135 ctx->bstate = BS_STOP;
2423f660
TS
6136 rn = "Cause";
6137 break;
9c2149c8
TS
6138 default:
6139 goto die;
876d4b07 6140 }
9c2149c8
TS
6141 break;
6142 case 14:
6143 switch (sel) {
6144 case 0:
7db13fae 6145 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6146 rn = "EPC";
6147 break;
9c2149c8
TS
6148 default:
6149 goto die;
876d4b07 6150 }
9c2149c8
TS
6151 break;
6152 case 15:
6153 switch (sel) {
6154 case 0:
2423f660
TS
6155 /* ignored */
6156 rn = "PRid";
6157 break;
9c2149c8 6158 case 1:
d75c135e 6159 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6160 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6161 rn = "EBase";
6162 break;
9c2149c8
TS
6163 default:
6164 goto die;
876d4b07 6165 }
9c2149c8
TS
6166 break;
6167 case 16:
6168 switch (sel) {
6169 case 0:
895c2d04 6170 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6171 rn = "Config";
2423f660
TS
6172 /* Stop translation as we may have switched the execution mode */
6173 ctx->bstate = BS_STOP;
9c2149c8
TS
6174 break;
6175 case 1:
1fc7bf6e 6176 /* ignored, read only */
9c2149c8
TS
6177 rn = "Config1";
6178 break;
6179 case 2:
895c2d04 6180 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6181 rn = "Config2";
2423f660
TS
6182 /* Stop translation as we may have switched the execution mode */
6183 ctx->bstate = BS_STOP;
9c2149c8
TS
6184 break;
6185 case 3:
2423f660 6186 /* ignored */
9c2149c8
TS
6187 rn = "Config3";
6188 break;
6189 /* 6,7 are implementation dependent */
6190 default:
6191 rn = "Invalid config selector";
6192 goto die;
6193 }
9c2149c8
TS
6194 break;
6195 case 17:
6196 switch (sel) {
6197 case 0:
895c2d04 6198 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6199 rn = "LLAddr";
6200 break;
9c2149c8
TS
6201 default:
6202 goto die;
6203 }
6204 break;
6205 case 18:
6206 switch (sel) {
fd88b6ab 6207 case 0 ... 7:
895c2d04 6208 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6209 rn = "WatchLo";
6210 break;
9c2149c8
TS
6211 default:
6212 goto die;
6213 }
6214 break;
6215 case 19:
6216 switch (sel) {
fd88b6ab 6217 case 0 ... 7:
895c2d04 6218 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6219 rn = "WatchHi";
6220 break;
9c2149c8
TS
6221 default:
6222 goto die;
6223 }
6224 break;
6225 case 20:
6226 switch (sel) {
6227 case 0:
d75c135e 6228 check_insn(ctx, ISA_MIPS3);
895c2d04 6229 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6230 rn = "XContext";
6231 break;
9c2149c8
TS
6232 default:
6233 goto die;
6234 }
6235 break;
6236 case 21:
6237 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6238 switch (sel) {
6239 case 0:
895c2d04 6240 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6241 rn = "Framemask";
6242 break;
9c2149c8
TS
6243 default:
6244 goto die;
6245 }
6246 break;
6247 case 22:
6248 /* ignored */
6249 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6250 break;
9c2149c8
TS
6251 case 23:
6252 switch (sel) {
6253 case 0:
895c2d04 6254 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6255 /* BS_STOP isn't good enough here, hflags may have changed. */
6256 gen_save_pc(ctx->pc + 4);
6257 ctx->bstate = BS_EXCP;
2423f660
TS
6258 rn = "Debug";
6259 break;
9c2149c8 6260 case 1:
895c2d04 6261// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6262 /* Stop translation as we may have switched the execution mode */
6263 ctx->bstate = BS_STOP;
2423f660
TS
6264 rn = "TraceControl";
6265// break;
9c2149c8 6266 case 2:
895c2d04 6267// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6268 /* Stop translation as we may have switched the execution mode */
6269 ctx->bstate = BS_STOP;
2423f660
TS
6270 rn = "TraceControl2";
6271// break;
9c2149c8 6272 case 3:
895c2d04 6273// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6274 /* Stop translation as we may have switched the execution mode */
6275 ctx->bstate = BS_STOP;
2423f660
TS
6276 rn = "UserTraceData";
6277// break;
9c2149c8 6278 case 4:
895c2d04 6279// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6280 /* Stop translation as we may have switched the execution mode */
6281 ctx->bstate = BS_STOP;
2423f660
TS
6282 rn = "TraceBPC";
6283// break;
9c2149c8
TS
6284 default:
6285 goto die;
6286 }
9c2149c8
TS
6287 break;
6288 case 24:
6289 switch (sel) {
6290 case 0:
f1aa6320 6291 /* EJTAG support */
7db13fae 6292 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6293 rn = "DEPC";
6294 break;
9c2149c8
TS
6295 default:
6296 goto die;
6297 }
6298 break;
6299 case 25:
6300 switch (sel) {
6301 case 0:
895c2d04 6302 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6303 rn = "Performance0";
6304 break;
9c2149c8 6305 case 1:
895c2d04 6306// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6307 rn = "Performance1";
6308// break;
9c2149c8 6309 case 2:
895c2d04 6310// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6311 rn = "Performance2";
6312// break;
9c2149c8 6313 case 3:
895c2d04 6314// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6315 rn = "Performance3";
6316// break;
9c2149c8 6317 case 4:
895c2d04 6318// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6319 rn = "Performance4";
6320// break;
9c2149c8 6321 case 5:
895c2d04 6322// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6323 rn = "Performance5";
6324// break;
9c2149c8 6325 case 6:
895c2d04 6326// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6327 rn = "Performance6";
6328// break;
9c2149c8 6329 case 7:
895c2d04 6330// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6331 rn = "Performance7";
6332// break;
9c2149c8
TS
6333 default:
6334 goto die;
6335 }
876d4b07 6336 break;
9c2149c8 6337 case 26:
876d4b07 6338 /* ignored */
9c2149c8 6339 rn = "ECC";
876d4b07 6340 break;
9c2149c8
TS
6341 case 27:
6342 switch (sel) {
6343 case 0 ... 3:
2423f660
TS
6344 /* ignored */
6345 rn = "CacheErr";
6346 break;
9c2149c8
TS
6347 default:
6348 goto die;
6349 }
876d4b07 6350 break;
9c2149c8
TS
6351 case 28:
6352 switch (sel) {
6353 case 0:
6354 case 2:
6355 case 4:
6356 case 6:
895c2d04 6357 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6358 rn = "TagLo";
6359 break;
6360 case 1:
6361 case 3:
6362 case 5:
6363 case 7:
895c2d04 6364 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6365 rn = "DataLo";
6366 break;
6367 default:
6368 goto die;
6369 }
6370 break;
6371 case 29:
6372 switch (sel) {
6373 case 0:
6374 case 2:
6375 case 4:
6376 case 6:
895c2d04 6377 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6378 rn = "TagHi";
6379 break;
6380 case 1:
6381 case 3:
6382 case 5:
6383 case 7:
895c2d04 6384 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6385 rn = "DataHi";
6386 break;
6387 default:
6388 rn = "invalid sel";
6389 goto die;
6390 }
876d4b07 6391 break;
9c2149c8
TS
6392 case 30:
6393 switch (sel) {
6394 case 0:
7db13fae 6395 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6396 rn = "ErrorEPC";
6397 break;
9c2149c8
TS
6398 default:
6399 goto die;
6400 }
6401 break;
6402 case 31:
6403 switch (sel) {
6404 case 0:
f1aa6320 6405 /* EJTAG support */
7db13fae 6406 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6407 rn = "DESAVE";
6408 break;
9c2149c8
TS
6409 default:
6410 goto die;
6411 }
876d4b07
TS
6412 /* Stop translation as we may have switched the execution mode */
6413 ctx->bstate = BS_STOP;
9c2149c8
TS
6414 break;
6415 default:
876d4b07 6416 goto die;
9c2149c8 6417 }
2abf314d 6418 (void)rn; /* avoid a compiler warning */
d12d51d5 6419 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6420 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6421 if (use_icount) {
6422 gen_io_end();
6423 ctx->bstate = BS_STOP;
6424 }
9c2149c8
TS
6425 return;
6426
6427die:
d12d51d5 6428 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6429 generate_exception(ctx, EXCP_RI);
6430}
d26bc211 6431#endif /* TARGET_MIPS64 */
9c2149c8 6432
7db13fae 6433static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6434 int u, int sel, int h)
6435{
6436 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6437 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6438
6439 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6440 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6441 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6442 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6443 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6444 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6445 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6446 else if (u == 0) {
6447 switch (rt) {
5a25ce94
EI
6448 case 1:
6449 switch (sel) {
6450 case 1:
895c2d04 6451 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6452 break;
6453 case 2:
895c2d04 6454 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6455 break;
6456 default:
6457 goto die;
6458 break;
6459 }
6460 break;
ead9360e
TS
6461 case 2:
6462 switch (sel) {
6463 case 1:
895c2d04 6464 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6465 break;
6466 case 2:
895c2d04 6467 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6468 break;
6469 case 3:
895c2d04 6470 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6471 break;
6472 case 4:
895c2d04 6473 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6474 break;
6475 case 5:
895c2d04 6476 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6477 break;
6478 case 6:
895c2d04 6479 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6480 break;
6481 case 7:
895c2d04 6482 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6483 break;
6484 default:
d75c135e 6485 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6486 break;
6487 }
6488 break;
6489 case 10:
6490 switch (sel) {
6491 case 0:
895c2d04 6492 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6493 break;
6494 default:
d75c135e 6495 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6496 break;
6497 }
6498 case 12:
6499 switch (sel) {
6500 case 0:
895c2d04 6501 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6502 break;
6503 default:
d75c135e 6504 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6505 break;
6506 }
5a25ce94
EI
6507 case 13:
6508 switch (sel) {
6509 case 0:
895c2d04 6510 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6511 break;
6512 default:
6513 goto die;
6514 break;
6515 }
6516 break;
6517 case 14:
6518 switch (sel) {
6519 case 0:
895c2d04 6520 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6521 break;
6522 default:
6523 goto die;
6524 break;
6525 }
6526 break;
6527 case 15:
6528 switch (sel) {
6529 case 1:
895c2d04 6530 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6531 break;
6532 default:
6533 goto die;
6534 break;
6535 }
6536 break;
6537 case 16:
6538 switch (sel) {
6539 case 0 ... 7:
895c2d04 6540 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6541 break;
6542 default:
6543 goto die;
6544 break;
6545 }
6546 break;
ead9360e
TS
6547 case 23:
6548 switch (sel) {
6549 case 0:
895c2d04 6550 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6551 break;
6552 default:
d75c135e 6553 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6554 break;
6555 }
6556 break;
6557 default:
d75c135e 6558 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6559 }
6560 } else switch (sel) {
6561 /* GPR registers. */
6562 case 0:
895c2d04 6563 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6564 break;
6565 /* Auxiliary CPU registers */
6566 case 1:
6567 switch (rt) {
6568 case 0:
895c2d04 6569 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6570 break;
6571 case 1:
895c2d04 6572 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6573 break;
6574 case 2:
895c2d04 6575 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6576 break;
6577 case 4:
895c2d04 6578 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6579 break;
6580 case 5:
895c2d04 6581 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6582 break;
6583 case 6:
895c2d04 6584 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6585 break;
6586 case 8:
895c2d04 6587 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6588 break;
6589 case 9:
895c2d04 6590 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6591 break;
6592 case 10:
895c2d04 6593 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6594 break;
6595 case 12:
895c2d04 6596 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6597 break;
6598 case 13:
895c2d04 6599 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6600 break;
6601 case 14:
895c2d04 6602 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6603 break;
6604 case 16:
895c2d04 6605 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6606 break;
6607 default:
6608 goto die;
6609 }
6610 break;
6611 /* Floating point (COP1). */
6612 case 2:
6613 /* XXX: For now we support only a single FPU context. */
6614 if (h == 0) {
a7812ae4 6615 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6616
6617 gen_load_fpr32(fp0, rt);
6618 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6619 tcg_temp_free_i32(fp0);
ead9360e 6620 } else {
a7812ae4 6621 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 6622
7f6613ce 6623 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 6624 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6625 tcg_temp_free_i32(fp0);
ead9360e
TS
6626 }
6627 break;
6628 case 3:
6629 /* XXX: For now we support only a single FPU context. */
895c2d04 6630 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6631 break;
6632 /* COP2: Not implemented. */
6633 case 4:
6634 case 5:
6635 /* fall through */
6636 default:
6637 goto die;
6638 }
d12d51d5 6639 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6640 gen_store_gpr(t0, rd);
6641 tcg_temp_free(t0);
ead9360e
TS
6642 return;
6643
6644die:
1a3fd9c3 6645 tcg_temp_free(t0);
d12d51d5 6646 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6647 generate_exception(ctx, EXCP_RI);
6648}
6649
7db13fae 6650static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6651 int u, int sel, int h)
6652{
6653 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6654 TCGv t0 = tcg_temp_local_new();
ead9360e 6655
1a3fd9c3 6656 gen_load_gpr(t0, rt);
ead9360e 6657 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6658 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6659 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6660 /* NOP */ ;
6661 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6662 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6663 /* NOP */ ;
6664 else if (u == 0) {
6665 switch (rd) {
5a25ce94
EI
6666 case 1:
6667 switch (sel) {
6668 case 1:
895c2d04 6669 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6670 break;
6671 case 2:
895c2d04 6672 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6673 break;
6674 default:
6675 goto die;
6676 break;
6677 }
6678 break;
ead9360e
TS
6679 case 2:
6680 switch (sel) {
6681 case 1:
895c2d04 6682 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6683 break;
6684 case 2:
895c2d04 6685 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6686 break;
6687 case 3:
895c2d04 6688 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6689 break;
6690 case 4:
895c2d04 6691 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6692 break;
6693 case 5:
895c2d04 6694 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6695 break;
6696 case 6:
895c2d04 6697 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6698 break;
6699 case 7:
895c2d04 6700 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6701 break;
6702 default:
d75c135e 6703 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6704 break;
6705 }
6706 break;
6707 case 10:
6708 switch (sel) {
6709 case 0:
895c2d04 6710 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6711 break;
6712 default:
d75c135e 6713 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6714 break;
6715 }
6716 case 12:
6717 switch (sel) {
6718 case 0:
895c2d04 6719 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6720 break;
6721 default:
d75c135e 6722 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6723 break;
6724 }
5a25ce94
EI
6725 case 13:
6726 switch (sel) {
6727 case 0:
895c2d04 6728 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6729 break;
6730 default:
6731 goto die;
6732 break;
6733 }
6734 break;
6735 case 15:
6736 switch (sel) {
6737 case 1:
895c2d04 6738 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6739 break;
6740 default:
6741 goto die;
6742 break;
6743 }
6744 break;
ead9360e
TS
6745 case 23:
6746 switch (sel) {
6747 case 0:
895c2d04 6748 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6749 break;
6750 default:
d75c135e 6751 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6752 break;
6753 }
6754 break;
6755 default:
d75c135e 6756 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6757 }
6758 } else switch (sel) {
6759 /* GPR registers. */
6760 case 0:
895c2d04 6761 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6762 break;
6763 /* Auxiliary CPU registers */
6764 case 1:
6765 switch (rd) {
6766 case 0:
895c2d04 6767 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6768 break;
6769 case 1:
895c2d04 6770 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6771 break;
6772 case 2:
895c2d04 6773 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6774 break;
6775 case 4:
895c2d04 6776 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6777 break;
6778 case 5:
895c2d04 6779 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6780 break;
6781 case 6:
895c2d04 6782 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6783 break;
6784 case 8:
895c2d04 6785 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6786 break;
6787 case 9:
895c2d04 6788 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6789 break;
6790 case 10:
895c2d04 6791 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6792 break;
6793 case 12:
895c2d04 6794 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6795 break;
6796 case 13:
895c2d04 6797 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6798 break;
6799 case 14:
895c2d04 6800 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6801 break;
6802 case 16:
895c2d04 6803 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6804 break;
6805 default:
6806 goto die;
6807 }
6808 break;
6809 /* Floating point (COP1). */
6810 case 2:
6811 /* XXX: For now we support only a single FPU context. */
6812 if (h == 0) {
a7812ae4 6813 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6814
6815 tcg_gen_trunc_tl_i32(fp0, t0);
6816 gen_store_fpr32(fp0, rd);
a7812ae4 6817 tcg_temp_free_i32(fp0);
ead9360e 6818 } else {
a7812ae4 6819 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6820
6821 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 6822 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 6823 tcg_temp_free_i32(fp0);
ead9360e
TS
6824 }
6825 break;
6826 case 3:
6827 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
6828 {
6829 TCGv_i32 fs_tmp = tcg_const_i32(rd);
6830
6831 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
6832 tcg_temp_free_i32(fs_tmp);
6833 }
ead9360e
TS
6834 break;
6835 /* COP2: Not implemented. */
6836 case 4:
6837 case 5:
6838 /* fall through */
6839 default:
6840 goto die;
6841 }
d12d51d5 6842 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6843 tcg_temp_free(t0);
ead9360e
TS
6844 return;
6845
6846die:
1a3fd9c3 6847 tcg_temp_free(t0);
d12d51d5 6848 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6849 generate_exception(ctx, EXCP_RI);
6850}
6851
7db13fae 6852static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6853{
287c4b84 6854 const char *opn = "ldst";
6af0bf9c 6855
2e15497c 6856 check_cp0_enabled(ctx);
6af0bf9c
FB
6857 switch (opc) {
6858 case OPC_MFC0:
6859 if (rt == 0) {
ead9360e 6860 /* Treat as NOP. */
6af0bf9c
FB
6861 return;
6862 }
d75c135e 6863 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6864 opn = "mfc0";
6865 break;
6866 case OPC_MTC0:
1a3fd9c3 6867 {
1fc7bf6e 6868 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6869
6870 gen_load_gpr(t0, rt);
d75c135e 6871 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6872 tcg_temp_free(t0);
6873 }
6af0bf9c
FB
6874 opn = "mtc0";
6875 break;
d26bc211 6876#if defined(TARGET_MIPS64)
9c2149c8 6877 case OPC_DMFC0:
d75c135e 6878 check_insn(ctx, ISA_MIPS3);
9c2149c8 6879 if (rt == 0) {
ead9360e 6880 /* Treat as NOP. */
9c2149c8
TS
6881 return;
6882 }
d75c135e 6883 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6884 opn = "dmfc0";
6885 break;
6886 case OPC_DMTC0:
d75c135e 6887 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 6888 {
1fc7bf6e 6889 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6890
6891 gen_load_gpr(t0, rt);
d75c135e 6892 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6893 tcg_temp_free(t0);
6894 }
9c2149c8
TS
6895 opn = "dmtc0";
6896 break;
534ce69f 6897#endif
ead9360e 6898 case OPC_MFTR:
d75c135e 6899 check_insn(ctx, ASE_MT);
ead9360e
TS
6900 if (rd == 0) {
6901 /* Treat as NOP. */
6902 return;
6903 }
6c5c1e20 6904 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6905 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6906 opn = "mftr";
6907 break;
6908 case OPC_MTTR:
d75c135e 6909 check_insn(ctx, ASE_MT);
6c5c1e20 6910 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6911 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6912 opn = "mttr";
6913 break;
6af0bf9c 6914 case OPC_TLBWI:
6af0bf9c 6915 opn = "tlbwi";
c01fccd2 6916 if (!env->tlb->helper_tlbwi)
29929e34 6917 goto die;
895c2d04 6918 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6919 break;
6920 case OPC_TLBWR:
6af0bf9c 6921 opn = "tlbwr";
c01fccd2 6922 if (!env->tlb->helper_tlbwr)
29929e34 6923 goto die;
895c2d04 6924 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6925 break;
6926 case OPC_TLBP:
6af0bf9c 6927 opn = "tlbp";
c01fccd2 6928 if (!env->tlb->helper_tlbp)
29929e34 6929 goto die;
895c2d04 6930 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6931 break;
6932 case OPC_TLBR:
6af0bf9c 6933 opn = "tlbr";
c01fccd2 6934 if (!env->tlb->helper_tlbr)
29929e34 6935 goto die;
895c2d04 6936 gen_helper_tlbr(cpu_env);
6af0bf9c 6937 break;
6af0bf9c
FB
6938 case OPC_ERET:
6939 opn = "eret";
d75c135e 6940 check_insn(ctx, ISA_MIPS2);
895c2d04 6941 gen_helper_eret(cpu_env);
6af0bf9c
FB
6942 ctx->bstate = BS_EXCP;
6943 break;
6944 case OPC_DERET:
6945 opn = "deret";
d75c135e 6946 check_insn(ctx, ISA_MIPS32);
6af0bf9c 6947 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6948 MIPS_INVAL(opn);
6af0bf9c
FB
6949 generate_exception(ctx, EXCP_RI);
6950 } else {
895c2d04 6951 gen_helper_deret(cpu_env);
6af0bf9c
FB
6952 ctx->bstate = BS_EXCP;
6953 }
6954 break;
4ad40f36
FB
6955 case OPC_WAIT:
6956 opn = "wait";
d75c135e 6957 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6958 /* If we get an exception, we want to restart at next instruction */
6959 ctx->pc += 4;
6960 save_cpu_state(ctx, 1);
6961 ctx->pc -= 4;
895c2d04 6962 gen_helper_wait(cpu_env);
4ad40f36
FB
6963 ctx->bstate = BS_EXCP;
6964 break;
6af0bf9c 6965 default:
29929e34 6966 die:
923617a3 6967 MIPS_INVAL(opn);
6af0bf9c
FB
6968 generate_exception(ctx, EXCP_RI);
6969 return;
6970 }
2abf314d 6971 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
6972 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6973}
f1aa6320 6974#endif /* !CONFIG_USER_ONLY */
6af0bf9c 6975
6ea83fed 6976/* CP1 Branches (before delay slot) */
d75c135e
AJ
6977static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6978 int32_t cc, int32_t offset)
6ea83fed
FB
6979{
6980 target_ulong btarget;
923617a3 6981 const char *opn = "cp1 cond branch";
a7812ae4 6982 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 6983
e189e748 6984 if (cc != 0)
d75c135e 6985 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 6986
6ea83fed
FB
6987 btarget = ctx->pc + 4 + offset;
6988
7a387fff
TS
6989 switch (op) {
6990 case OPC_BC1F:
d94536f4
AJ
6991 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6992 tcg_gen_not_i32(t0, t0);
6993 tcg_gen_andi_i32(t0, t0, 1);
6994 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 6995 opn = "bc1f";
6ea83fed 6996 goto not_likely;
7a387fff 6997 case OPC_BC1FL:
d94536f4
AJ
6998 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6999 tcg_gen_not_i32(t0, t0);
7000 tcg_gen_andi_i32(t0, t0, 1);
7001 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7002 opn = "bc1fl";
6ea83fed 7003 goto likely;
7a387fff 7004 case OPC_BC1T:
d94536f4
AJ
7005 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7006 tcg_gen_andi_i32(t0, t0, 1);
7007 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7008 opn = "bc1t";
5a5012ec 7009 goto not_likely;
7a387fff 7010 case OPC_BC1TL:
d94536f4
AJ
7011 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7012 tcg_gen_andi_i32(t0, t0, 1);
7013 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7014 opn = "bc1tl";
6ea83fed
FB
7015 likely:
7016 ctx->hflags |= MIPS_HFLAG_BL;
7017 break;
5a5012ec 7018 case OPC_BC1FANY2:
a16336e4 7019 {
d94536f4
AJ
7020 TCGv_i32 t1 = tcg_temp_new_i32();
7021 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7022 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7023 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7024 tcg_temp_free_i32(t1);
d94536f4
AJ
7025 tcg_gen_andi_i32(t0, t0, 1);
7026 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7027 }
fd4a04eb 7028 opn = "bc1any2f";
5a5012ec
TS
7029 goto not_likely;
7030 case OPC_BC1TANY2:
a16336e4 7031 {
d94536f4
AJ
7032 TCGv_i32 t1 = tcg_temp_new_i32();
7033 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7034 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7035 tcg_gen_or_i32(t0, t0, t1);
7036 tcg_temp_free_i32(t1);
7037 tcg_gen_andi_i32(t0, t0, 1);
7038 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7039 }
fd4a04eb 7040 opn = "bc1any2t";
5a5012ec
TS
7041 goto not_likely;
7042 case OPC_BC1FANY4:
a16336e4 7043 {
d94536f4
AJ
7044 TCGv_i32 t1 = tcg_temp_new_i32();
7045 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7046 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7047 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7048 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7049 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7050 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7051 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7052 tcg_temp_free_i32(t1);
d94536f4
AJ
7053 tcg_gen_andi_i32(t0, t0, 1);
7054 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7055 }
fd4a04eb 7056 opn = "bc1any4f";
5a5012ec
TS
7057 goto not_likely;
7058 case OPC_BC1TANY4:
a16336e4 7059 {
d94536f4
AJ
7060 TCGv_i32 t1 = tcg_temp_new_i32();
7061 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7062 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7063 tcg_gen_or_i32(t0, t0, t1);
7064 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7065 tcg_gen_or_i32(t0, t0, t1);
7066 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7067 tcg_gen_or_i32(t0, t0, t1);
7068 tcg_temp_free_i32(t1);
7069 tcg_gen_andi_i32(t0, t0, 1);
7070 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7071 }
fd4a04eb 7072 opn = "bc1any4t";
5a5012ec
TS
7073 not_likely:
7074 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7075 break;
7076 default:
923617a3 7077 MIPS_INVAL(opn);
e397ee33 7078 generate_exception (ctx, EXCP_RI);
6c5c1e20 7079 goto out;
6ea83fed 7080 }
2abf314d 7081 (void)opn; /* avoid a compiler warning */
923617a3 7082 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7083 ctx->hflags, btarget);
7084 ctx->btarget = btarget;
6c5c1e20
TS
7085
7086 out:
a7812ae4 7087 tcg_temp_free_i32(t0);
6ea83fed
FB
7088}
7089
6af0bf9c 7090/* Coprocessor 1 (FPU) */
5a5012ec 7091
5a5012ec
TS
7092#define FOP(func, fmt) (((fmt) << 21) | (func))
7093
bf4120ad
NF
7094enum fopcode {
7095 OPC_ADD_S = FOP(0, FMT_S),
7096 OPC_SUB_S = FOP(1, FMT_S),
7097 OPC_MUL_S = FOP(2, FMT_S),
7098 OPC_DIV_S = FOP(3, FMT_S),
7099 OPC_SQRT_S = FOP(4, FMT_S),
7100 OPC_ABS_S = FOP(5, FMT_S),
7101 OPC_MOV_S = FOP(6, FMT_S),
7102 OPC_NEG_S = FOP(7, FMT_S),
7103 OPC_ROUND_L_S = FOP(8, FMT_S),
7104 OPC_TRUNC_L_S = FOP(9, FMT_S),
7105 OPC_CEIL_L_S = FOP(10, FMT_S),
7106 OPC_FLOOR_L_S = FOP(11, FMT_S),
7107 OPC_ROUND_W_S = FOP(12, FMT_S),
7108 OPC_TRUNC_W_S = FOP(13, FMT_S),
7109 OPC_CEIL_W_S = FOP(14, FMT_S),
7110 OPC_FLOOR_W_S = FOP(15, FMT_S),
7111 OPC_MOVCF_S = FOP(17, FMT_S),
7112 OPC_MOVZ_S = FOP(18, FMT_S),
7113 OPC_MOVN_S = FOP(19, FMT_S),
7114 OPC_RECIP_S = FOP(21, FMT_S),
7115 OPC_RSQRT_S = FOP(22, FMT_S),
7116 OPC_RECIP2_S = FOP(28, FMT_S),
7117 OPC_RECIP1_S = FOP(29, FMT_S),
7118 OPC_RSQRT1_S = FOP(30, FMT_S),
7119 OPC_RSQRT2_S = FOP(31, FMT_S),
7120 OPC_CVT_D_S = FOP(33, FMT_S),
7121 OPC_CVT_W_S = FOP(36, FMT_S),
7122 OPC_CVT_L_S = FOP(37, FMT_S),
7123 OPC_CVT_PS_S = FOP(38, FMT_S),
7124 OPC_CMP_F_S = FOP (48, FMT_S),
7125 OPC_CMP_UN_S = FOP (49, FMT_S),
7126 OPC_CMP_EQ_S = FOP (50, FMT_S),
7127 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7128 OPC_CMP_OLT_S = FOP (52, FMT_S),
7129 OPC_CMP_ULT_S = FOP (53, FMT_S),
7130 OPC_CMP_OLE_S = FOP (54, FMT_S),
7131 OPC_CMP_ULE_S = FOP (55, FMT_S),
7132 OPC_CMP_SF_S = FOP (56, FMT_S),
7133 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7134 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7135 OPC_CMP_NGL_S = FOP (59, FMT_S),
7136 OPC_CMP_LT_S = FOP (60, FMT_S),
7137 OPC_CMP_NGE_S = FOP (61, FMT_S),
7138 OPC_CMP_LE_S = FOP (62, FMT_S),
7139 OPC_CMP_NGT_S = FOP (63, FMT_S),
7140
7141 OPC_ADD_D = FOP(0, FMT_D),
7142 OPC_SUB_D = FOP(1, FMT_D),
7143 OPC_MUL_D = FOP(2, FMT_D),
7144 OPC_DIV_D = FOP(3, FMT_D),
7145 OPC_SQRT_D = FOP(4, FMT_D),
7146 OPC_ABS_D = FOP(5, FMT_D),
7147 OPC_MOV_D = FOP(6, FMT_D),
7148 OPC_NEG_D = FOP(7, FMT_D),
7149 OPC_ROUND_L_D = FOP(8, FMT_D),
7150 OPC_TRUNC_L_D = FOP(9, FMT_D),
7151 OPC_CEIL_L_D = FOP(10, FMT_D),
7152 OPC_FLOOR_L_D = FOP(11, FMT_D),
7153 OPC_ROUND_W_D = FOP(12, FMT_D),
7154 OPC_TRUNC_W_D = FOP(13, FMT_D),
7155 OPC_CEIL_W_D = FOP(14, FMT_D),
7156 OPC_FLOOR_W_D = FOP(15, FMT_D),
7157 OPC_MOVCF_D = FOP(17, FMT_D),
7158 OPC_MOVZ_D = FOP(18, FMT_D),
7159 OPC_MOVN_D = FOP(19, FMT_D),
7160 OPC_RECIP_D = FOP(21, FMT_D),
7161 OPC_RSQRT_D = FOP(22, FMT_D),
7162 OPC_RECIP2_D = FOP(28, FMT_D),
7163 OPC_RECIP1_D = FOP(29, FMT_D),
7164 OPC_RSQRT1_D = FOP(30, FMT_D),
7165 OPC_RSQRT2_D = FOP(31, FMT_D),
7166 OPC_CVT_S_D = FOP(32, FMT_D),
7167 OPC_CVT_W_D = FOP(36, FMT_D),
7168 OPC_CVT_L_D = FOP(37, FMT_D),
7169 OPC_CMP_F_D = FOP (48, FMT_D),
7170 OPC_CMP_UN_D = FOP (49, FMT_D),
7171 OPC_CMP_EQ_D = FOP (50, FMT_D),
7172 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7173 OPC_CMP_OLT_D = FOP (52, FMT_D),
7174 OPC_CMP_ULT_D = FOP (53, FMT_D),
7175 OPC_CMP_OLE_D = FOP (54, FMT_D),
7176 OPC_CMP_ULE_D = FOP (55, FMT_D),
7177 OPC_CMP_SF_D = FOP (56, FMT_D),
7178 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7179 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7180 OPC_CMP_NGL_D = FOP (59, FMT_D),
7181 OPC_CMP_LT_D = FOP (60, FMT_D),
7182 OPC_CMP_NGE_D = FOP (61, FMT_D),
7183 OPC_CMP_LE_D = FOP (62, FMT_D),
7184 OPC_CMP_NGT_D = FOP (63, FMT_D),
7185
7186 OPC_CVT_S_W = FOP(32, FMT_W),
7187 OPC_CVT_D_W = FOP(33, FMT_W),
7188 OPC_CVT_S_L = FOP(32, FMT_L),
7189 OPC_CVT_D_L = FOP(33, FMT_L),
7190 OPC_CVT_PS_PW = FOP(38, FMT_W),
7191
7192 OPC_ADD_PS = FOP(0, FMT_PS),
7193 OPC_SUB_PS = FOP(1, FMT_PS),
7194 OPC_MUL_PS = FOP(2, FMT_PS),
7195 OPC_DIV_PS = FOP(3, FMT_PS),
7196 OPC_ABS_PS = FOP(5, FMT_PS),
7197 OPC_MOV_PS = FOP(6, FMT_PS),
7198 OPC_NEG_PS = FOP(7, FMT_PS),
7199 OPC_MOVCF_PS = FOP(17, FMT_PS),
7200 OPC_MOVZ_PS = FOP(18, FMT_PS),
7201 OPC_MOVN_PS = FOP(19, FMT_PS),
7202 OPC_ADDR_PS = FOP(24, FMT_PS),
7203 OPC_MULR_PS = FOP(26, FMT_PS),
7204 OPC_RECIP2_PS = FOP(28, FMT_PS),
7205 OPC_RECIP1_PS = FOP(29, FMT_PS),
7206 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7207 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7208
7209 OPC_CVT_S_PU = FOP(32, FMT_PS),
7210 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7211 OPC_CVT_S_PL = FOP(40, FMT_PS),
7212 OPC_PLL_PS = FOP(44, FMT_PS),
7213 OPC_PLU_PS = FOP(45, FMT_PS),
7214 OPC_PUL_PS = FOP(46, FMT_PS),
7215 OPC_PUU_PS = FOP(47, FMT_PS),
7216 OPC_CMP_F_PS = FOP (48, FMT_PS),
7217 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7218 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7219 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7220 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7221 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7222 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7223 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7224 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7225 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7226 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7227 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7228 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7229 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7230 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7231 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7232};
7233
7a387fff 7234static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7235{
923617a3 7236 const char *opn = "cp1 move";
72c3a3ee 7237 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7238
7239 switch (opc) {
7240 case OPC_MFC1:
b6d96bed 7241 {
a7812ae4 7242 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7243
7244 gen_load_fpr32(fp0, fs);
7245 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7246 tcg_temp_free_i32(fp0);
6958549d 7247 }
6c5c1e20 7248 gen_store_gpr(t0, rt);
6ea83fed
FB
7249 opn = "mfc1";
7250 break;
7251 case OPC_MTC1:
6c5c1e20 7252 gen_load_gpr(t0, rt);
b6d96bed 7253 {
a7812ae4 7254 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7255
7256 tcg_gen_trunc_tl_i32(fp0, t0);
7257 gen_store_fpr32(fp0, fs);
a7812ae4 7258 tcg_temp_free_i32(fp0);
6958549d 7259 }
6ea83fed
FB
7260 opn = "mtc1";
7261 break;
7262 case OPC_CFC1:
895c2d04 7263 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7264 gen_store_gpr(t0, rt);
6ea83fed
FB
7265 opn = "cfc1";
7266 break;
7267 case OPC_CTC1:
6c5c1e20 7268 gen_load_gpr(t0, rt);
736d120a
PJ
7269 {
7270 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7271
7272 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7273 tcg_temp_free_i32(fs_tmp);
7274 }
6ea83fed
FB
7275 opn = "ctc1";
7276 break;
72c3a3ee 7277#if defined(TARGET_MIPS64)
9c2149c8 7278 case OPC_DMFC1:
72c3a3ee 7279 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7280 gen_store_gpr(t0, rt);
5a5012ec
TS
7281 opn = "dmfc1";
7282 break;
9c2149c8 7283 case OPC_DMTC1:
6c5c1e20 7284 gen_load_gpr(t0, rt);
72c3a3ee 7285 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7286 opn = "dmtc1";
7287 break;
72c3a3ee 7288#endif
5a5012ec 7289 case OPC_MFHC1:
b6d96bed 7290 {
a7812ae4 7291 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7292
7f6613ce 7293 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 7294 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7295 tcg_temp_free_i32(fp0);
6958549d 7296 }
6c5c1e20 7297 gen_store_gpr(t0, rt);
5a5012ec
TS
7298 opn = "mfhc1";
7299 break;
7300 case OPC_MTHC1:
6c5c1e20 7301 gen_load_gpr(t0, rt);
b6d96bed 7302 {
a7812ae4 7303 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7304
7305 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7306 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 7307 tcg_temp_free_i32(fp0);
6958549d 7308 }
5a5012ec
TS
7309 opn = "mthc1";
7310 break;
6ea83fed 7311 default:
923617a3 7312 MIPS_INVAL(opn);
e397ee33 7313 generate_exception (ctx, EXCP_RI);
6c5c1e20 7314 goto out;
6ea83fed 7315 }
2abf314d 7316 (void)opn; /* avoid a compiler warning */
6ea83fed 7317 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7318
7319 out:
7320 tcg_temp_free(t0);
6ea83fed
FB
7321}
7322
5a5012ec
TS
7323static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7324{
af58f9ca 7325 int l1;
e214b9bb 7326 TCGCond cond;
af58f9ca
AJ
7327 TCGv_i32 t0;
7328
7329 if (rd == 0) {
7330 /* Treat as NOP. */
7331 return;
7332 }
6ea83fed 7333
e214b9bb 7334 if (tf)
e214b9bb 7335 cond = TCG_COND_EQ;
27848470
TS
7336 else
7337 cond = TCG_COND_NE;
7338
af58f9ca
AJ
7339 l1 = gen_new_label();
7340 t0 = tcg_temp_new_i32();
fa31af0e 7341 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7342 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7343 tcg_temp_free_i32(t0);
af58f9ca
AJ
7344 if (rs == 0) {
7345 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7346 } else {
7347 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7348 }
e214b9bb 7349 gen_set_label(l1);
5a5012ec
TS
7350}
7351
b6d96bed 7352static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7353{
a16336e4 7354 int cond;
cbc37b28 7355 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7356 int l1 = gen_new_label();
7357
a16336e4
TS
7358 if (tf)
7359 cond = TCG_COND_EQ;
7360 else
7361 cond = TCG_COND_NE;
7362
fa31af0e 7363 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7364 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7365 gen_load_fpr32(t0, fs);
7366 gen_store_fpr32(t0, fd);
a16336e4 7367 gen_set_label(l1);
cbc37b28 7368 tcg_temp_free_i32(t0);
5a5012ec 7369}
a16336e4 7370
b6d96bed 7371static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7372{
a16336e4 7373 int cond;
cbc37b28
AJ
7374 TCGv_i32 t0 = tcg_temp_new_i32();
7375 TCGv_i64 fp0;
a16336e4
TS
7376 int l1 = gen_new_label();
7377
a16336e4
TS
7378 if (tf)
7379 cond = TCG_COND_EQ;
7380 else
7381 cond = TCG_COND_NE;
7382
fa31af0e 7383 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7384 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7385 tcg_temp_free_i32(t0);
11f94258 7386 fp0 = tcg_temp_new_i64();
9bf3eb2c 7387 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7388 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7389 tcg_temp_free_i64(fp0);
cbc37b28 7390 gen_set_label(l1);
a16336e4
TS
7391}
7392
7f6613ce
PJ
7393static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
7394 int cc, int tf)
a16336e4
TS
7395{
7396 int cond;
cbc37b28 7397 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7398 int l1 = gen_new_label();
7399 int l2 = gen_new_label();
7400
7401 if (tf)
7402 cond = TCG_COND_EQ;
7403 else
7404 cond = TCG_COND_NE;
7405
fa31af0e 7406 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7407 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7408 gen_load_fpr32(t0, fs);
7409 gen_store_fpr32(t0, fd);
a16336e4 7410 gen_set_label(l1);
9bf3eb2c 7411
fa31af0e 7412 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 7413 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
7414 gen_load_fpr32h(ctx, t0, fs);
7415 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 7416 tcg_temp_free_i32(t0);
a16336e4 7417 gen_set_label(l2);
a16336e4
TS
7418}
7419
6ea83fed 7420
bf4120ad 7421static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7422 int ft, int fs, int fd, int cc)
6ea83fed 7423{
923617a3 7424 const char *opn = "farith";
6ea83fed
FB
7425 const char *condnames[] = {
7426 "c.f",
7427 "c.un",
7428 "c.eq",
7429 "c.ueq",
7430 "c.olt",
7431 "c.ult",
7432 "c.ole",
7433 "c.ule",
7434 "c.sf",
7435 "c.ngle",
7436 "c.seq",
7437 "c.ngl",
7438 "c.lt",
7439 "c.nge",
7440 "c.le",
7441 "c.ngt",
7442 };
5a1e8ffb
TS
7443 const char *condnames_abs[] = {
7444 "cabs.f",
7445 "cabs.un",
7446 "cabs.eq",
7447 "cabs.ueq",
7448 "cabs.olt",
7449 "cabs.ult",
7450 "cabs.ole",
7451 "cabs.ule",
7452 "cabs.sf",
7453 "cabs.ngle",
7454 "cabs.seq",
7455 "cabs.ngl",
7456 "cabs.lt",
7457 "cabs.nge",
7458 "cabs.le",
7459 "cabs.ngt",
7460 };
7461 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7462 uint32_t func = ctx->opcode & 0x3f;
7463
bf4120ad
NF
7464 switch (op1) {
7465 case OPC_ADD_S:
b6d96bed 7466 {
a7812ae4
PB
7467 TCGv_i32 fp0 = tcg_temp_new_i32();
7468 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7469
7470 gen_load_fpr32(fp0, fs);
7471 gen_load_fpr32(fp1, ft);
895c2d04 7472 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7473 tcg_temp_free_i32(fp1);
b6d96bed 7474 gen_store_fpr32(fp0, fd);
a7812ae4 7475 tcg_temp_free_i32(fp0);
b6d96bed 7476 }
5a5012ec 7477 opn = "add.s";
5a1e8ffb 7478 optype = BINOP;
5a5012ec 7479 break;
bf4120ad 7480 case OPC_SUB_S:
b6d96bed 7481 {
a7812ae4
PB
7482 TCGv_i32 fp0 = tcg_temp_new_i32();
7483 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7484
7485 gen_load_fpr32(fp0, fs);
7486 gen_load_fpr32(fp1, ft);
895c2d04 7487 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7488 tcg_temp_free_i32(fp1);
b6d96bed 7489 gen_store_fpr32(fp0, fd);
a7812ae4 7490 tcg_temp_free_i32(fp0);
b6d96bed 7491 }
5a5012ec 7492 opn = "sub.s";
5a1e8ffb 7493 optype = BINOP;
5a5012ec 7494 break;
bf4120ad 7495 case OPC_MUL_S:
b6d96bed 7496 {
a7812ae4
PB
7497 TCGv_i32 fp0 = tcg_temp_new_i32();
7498 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7499
7500 gen_load_fpr32(fp0, fs);
7501 gen_load_fpr32(fp1, ft);
895c2d04 7502 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7503 tcg_temp_free_i32(fp1);
b6d96bed 7504 gen_store_fpr32(fp0, fd);
a7812ae4 7505 tcg_temp_free_i32(fp0);
b6d96bed 7506 }
5a5012ec 7507 opn = "mul.s";
5a1e8ffb 7508 optype = BINOP;
5a5012ec 7509 break;
bf4120ad 7510 case OPC_DIV_S:
b6d96bed 7511 {
a7812ae4
PB
7512 TCGv_i32 fp0 = tcg_temp_new_i32();
7513 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7514
7515 gen_load_fpr32(fp0, fs);
7516 gen_load_fpr32(fp1, ft);
895c2d04 7517 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7518 tcg_temp_free_i32(fp1);
b6d96bed 7519 gen_store_fpr32(fp0, fd);
a7812ae4 7520 tcg_temp_free_i32(fp0);
b6d96bed 7521 }
5a5012ec 7522 opn = "div.s";
5a1e8ffb 7523 optype = BINOP;
5a5012ec 7524 break;
bf4120ad 7525 case OPC_SQRT_S:
b6d96bed 7526 {
a7812ae4 7527 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7528
7529 gen_load_fpr32(fp0, fs);
895c2d04 7530 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7531 gen_store_fpr32(fp0, fd);
a7812ae4 7532 tcg_temp_free_i32(fp0);
b6d96bed 7533 }
5a5012ec
TS
7534 opn = "sqrt.s";
7535 break;
bf4120ad 7536 case OPC_ABS_S:
b6d96bed 7537 {
a7812ae4 7538 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7539
7540 gen_load_fpr32(fp0, fs);
a7812ae4 7541 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7542 gen_store_fpr32(fp0, fd);
a7812ae4 7543 tcg_temp_free_i32(fp0);
b6d96bed 7544 }
5a5012ec
TS
7545 opn = "abs.s";
7546 break;
bf4120ad 7547 case OPC_MOV_S:
b6d96bed 7548 {
a7812ae4 7549 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7550
7551 gen_load_fpr32(fp0, fs);
7552 gen_store_fpr32(fp0, fd);
a7812ae4 7553 tcg_temp_free_i32(fp0);
b6d96bed 7554 }
5a5012ec
TS
7555 opn = "mov.s";
7556 break;
bf4120ad 7557 case OPC_NEG_S:
b6d96bed 7558 {
a7812ae4 7559 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7560
7561 gen_load_fpr32(fp0, fs);
a7812ae4 7562 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7563 gen_store_fpr32(fp0, fd);
a7812ae4 7564 tcg_temp_free_i32(fp0);
b6d96bed 7565 }
5a5012ec
TS
7566 opn = "neg.s";
7567 break;
bf4120ad 7568 case OPC_ROUND_L_S:
5e755519 7569 check_cp1_64bitmode(ctx);
b6d96bed 7570 {
a7812ae4
PB
7571 TCGv_i32 fp32 = tcg_temp_new_i32();
7572 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7573
7574 gen_load_fpr32(fp32, fs);
895c2d04 7575 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7576 tcg_temp_free_i32(fp32);
b6d96bed 7577 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7578 tcg_temp_free_i64(fp64);
b6d96bed 7579 }
5a5012ec
TS
7580 opn = "round.l.s";
7581 break;
bf4120ad 7582 case OPC_TRUNC_L_S:
5e755519 7583 check_cp1_64bitmode(ctx);
b6d96bed 7584 {
a7812ae4
PB
7585 TCGv_i32 fp32 = tcg_temp_new_i32();
7586 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7587
7588 gen_load_fpr32(fp32, fs);
895c2d04 7589 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7590 tcg_temp_free_i32(fp32);
b6d96bed 7591 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7592 tcg_temp_free_i64(fp64);
b6d96bed 7593 }
5a5012ec
TS
7594 opn = "trunc.l.s";
7595 break;
bf4120ad 7596 case OPC_CEIL_L_S:
5e755519 7597 check_cp1_64bitmode(ctx);
b6d96bed 7598 {
a7812ae4
PB
7599 TCGv_i32 fp32 = tcg_temp_new_i32();
7600 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7601
7602 gen_load_fpr32(fp32, fs);
895c2d04 7603 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7604 tcg_temp_free_i32(fp32);
b6d96bed 7605 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7606 tcg_temp_free_i64(fp64);
b6d96bed 7607 }
5a5012ec
TS
7608 opn = "ceil.l.s";
7609 break;
bf4120ad 7610 case OPC_FLOOR_L_S:
5e755519 7611 check_cp1_64bitmode(ctx);
b6d96bed 7612 {
a7812ae4
PB
7613 TCGv_i32 fp32 = tcg_temp_new_i32();
7614 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7615
7616 gen_load_fpr32(fp32, fs);
895c2d04 7617 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7618 tcg_temp_free_i32(fp32);
b6d96bed 7619 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7620 tcg_temp_free_i64(fp64);
b6d96bed 7621 }
5a5012ec
TS
7622 opn = "floor.l.s";
7623 break;
bf4120ad 7624 case OPC_ROUND_W_S:
b6d96bed 7625 {
a7812ae4 7626 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7627
7628 gen_load_fpr32(fp0, fs);
895c2d04 7629 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7630 gen_store_fpr32(fp0, fd);
a7812ae4 7631 tcg_temp_free_i32(fp0);
b6d96bed 7632 }
5a5012ec
TS
7633 opn = "round.w.s";
7634 break;
bf4120ad 7635 case OPC_TRUNC_W_S:
b6d96bed 7636 {
a7812ae4 7637 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7638
7639 gen_load_fpr32(fp0, fs);
895c2d04 7640 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7641 gen_store_fpr32(fp0, fd);
a7812ae4 7642 tcg_temp_free_i32(fp0);
b6d96bed 7643 }
5a5012ec
TS
7644 opn = "trunc.w.s";
7645 break;
bf4120ad 7646 case OPC_CEIL_W_S:
b6d96bed 7647 {
a7812ae4 7648 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7649
7650 gen_load_fpr32(fp0, fs);
895c2d04 7651 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7652 gen_store_fpr32(fp0, fd);
a7812ae4 7653 tcg_temp_free_i32(fp0);
b6d96bed 7654 }
5a5012ec
TS
7655 opn = "ceil.w.s";
7656 break;
bf4120ad 7657 case OPC_FLOOR_W_S:
b6d96bed 7658 {
a7812ae4 7659 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7660
7661 gen_load_fpr32(fp0, fs);
895c2d04 7662 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7663 gen_store_fpr32(fp0, fd);
a7812ae4 7664 tcg_temp_free_i32(fp0);
b6d96bed 7665 }
5a5012ec
TS
7666 opn = "floor.w.s";
7667 break;
bf4120ad 7668 case OPC_MOVCF_S:
b6d96bed 7669 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7670 opn = "movcf.s";
7671 break;
bf4120ad 7672 case OPC_MOVZ_S:
a16336e4
TS
7673 {
7674 int l1 = gen_new_label();
c9297f4d 7675 TCGv_i32 fp0;
a16336e4 7676
c9297f4d
AJ
7677 if (ft != 0) {
7678 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7679 }
7680 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7681 gen_load_fpr32(fp0, fs);
7682 gen_store_fpr32(fp0, fd);
a7812ae4 7683 tcg_temp_free_i32(fp0);
a16336e4
TS
7684 gen_set_label(l1);
7685 }
5a5012ec
TS
7686 opn = "movz.s";
7687 break;
bf4120ad 7688 case OPC_MOVN_S:
a16336e4
TS
7689 {
7690 int l1 = gen_new_label();
c9297f4d
AJ
7691 TCGv_i32 fp0;
7692
7693 if (ft != 0) {
7694 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7695 fp0 = tcg_temp_new_i32();
7696 gen_load_fpr32(fp0, fs);
7697 gen_store_fpr32(fp0, fd);
7698 tcg_temp_free_i32(fp0);
7699 gen_set_label(l1);
7700 }
a16336e4 7701 }
5a5012ec
TS
7702 opn = "movn.s";
7703 break;
bf4120ad 7704 case OPC_RECIP_S:
b8aa4598 7705 check_cop1x(ctx);
b6d96bed 7706 {
a7812ae4 7707 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7708
7709 gen_load_fpr32(fp0, fs);
895c2d04 7710 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 7711 gen_store_fpr32(fp0, fd);
a7812ae4 7712 tcg_temp_free_i32(fp0);
b6d96bed 7713 }
57fa1fb3
TS
7714 opn = "recip.s";
7715 break;
bf4120ad 7716 case OPC_RSQRT_S:
b8aa4598 7717 check_cop1x(ctx);
b6d96bed 7718 {
a7812ae4 7719 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7720
7721 gen_load_fpr32(fp0, fs);
895c2d04 7722 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7723 gen_store_fpr32(fp0, fd);
a7812ae4 7724 tcg_temp_free_i32(fp0);
b6d96bed 7725 }
57fa1fb3
TS
7726 opn = "rsqrt.s";
7727 break;
bf4120ad 7728 case OPC_RECIP2_S:
5e755519 7729 check_cp1_64bitmode(ctx);
b6d96bed 7730 {
a7812ae4
PB
7731 TCGv_i32 fp0 = tcg_temp_new_i32();
7732 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7733
7734 gen_load_fpr32(fp0, fs);
d22d7289 7735 gen_load_fpr32(fp1, ft);
895c2d04 7736 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7737 tcg_temp_free_i32(fp1);
b6d96bed 7738 gen_store_fpr32(fp0, fd);
a7812ae4 7739 tcg_temp_free_i32(fp0);
b6d96bed 7740 }
57fa1fb3
TS
7741 opn = "recip2.s";
7742 break;
bf4120ad 7743 case OPC_RECIP1_S:
5e755519 7744 check_cp1_64bitmode(ctx);
b6d96bed 7745 {
a7812ae4 7746 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7747
7748 gen_load_fpr32(fp0, fs);
895c2d04 7749 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7750 gen_store_fpr32(fp0, fd);
a7812ae4 7751 tcg_temp_free_i32(fp0);
b6d96bed 7752 }
57fa1fb3
TS
7753 opn = "recip1.s";
7754 break;
bf4120ad 7755 case OPC_RSQRT1_S:
5e755519 7756 check_cp1_64bitmode(ctx);
b6d96bed 7757 {
a7812ae4 7758 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7759
7760 gen_load_fpr32(fp0, fs);
895c2d04 7761 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7762 gen_store_fpr32(fp0, fd);
a7812ae4 7763 tcg_temp_free_i32(fp0);
b6d96bed 7764 }
57fa1fb3
TS
7765 opn = "rsqrt1.s";
7766 break;
bf4120ad 7767 case OPC_RSQRT2_S:
5e755519 7768 check_cp1_64bitmode(ctx);
b6d96bed 7769 {
a7812ae4
PB
7770 TCGv_i32 fp0 = tcg_temp_new_i32();
7771 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7772
7773 gen_load_fpr32(fp0, fs);
7774 gen_load_fpr32(fp1, ft);
895c2d04 7775 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7776 tcg_temp_free_i32(fp1);
b6d96bed 7777 gen_store_fpr32(fp0, fd);
a7812ae4 7778 tcg_temp_free_i32(fp0);
b6d96bed 7779 }
57fa1fb3
TS
7780 opn = "rsqrt2.s";
7781 break;
bf4120ad 7782 case OPC_CVT_D_S:
5e755519 7783 check_cp1_registers(ctx, fd);
b6d96bed 7784 {
a7812ae4
PB
7785 TCGv_i32 fp32 = tcg_temp_new_i32();
7786 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7787
7788 gen_load_fpr32(fp32, fs);
895c2d04 7789 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7790 tcg_temp_free_i32(fp32);
b6d96bed 7791 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7792 tcg_temp_free_i64(fp64);
b6d96bed 7793 }
5a5012ec
TS
7794 opn = "cvt.d.s";
7795 break;
bf4120ad 7796 case OPC_CVT_W_S:
b6d96bed 7797 {
a7812ae4 7798 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7799
7800 gen_load_fpr32(fp0, fs);
895c2d04 7801 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7802 gen_store_fpr32(fp0, fd);
a7812ae4 7803 tcg_temp_free_i32(fp0);
b6d96bed 7804 }
5a5012ec
TS
7805 opn = "cvt.w.s";
7806 break;
bf4120ad 7807 case OPC_CVT_L_S:
5e755519 7808 check_cp1_64bitmode(ctx);
b6d96bed 7809 {
a7812ae4
PB
7810 TCGv_i32 fp32 = tcg_temp_new_i32();
7811 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7812
7813 gen_load_fpr32(fp32, fs);
895c2d04 7814 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7815 tcg_temp_free_i32(fp32);
b6d96bed 7816 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7817 tcg_temp_free_i64(fp64);
b6d96bed 7818 }
5a5012ec
TS
7819 opn = "cvt.l.s";
7820 break;
bf4120ad 7821 case OPC_CVT_PS_S:
5e755519 7822 check_cp1_64bitmode(ctx);
b6d96bed 7823 {
a7812ae4
PB
7824 TCGv_i64 fp64 = tcg_temp_new_i64();
7825 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7826 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7827
7828 gen_load_fpr32(fp32_0, fs);
7829 gen_load_fpr32(fp32_1, ft);
13d24f49 7830 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7831 tcg_temp_free_i32(fp32_1);
7832 tcg_temp_free_i32(fp32_0);
36aa55dc 7833 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7834 tcg_temp_free_i64(fp64);
b6d96bed 7835 }
5a5012ec
TS
7836 opn = "cvt.ps.s";
7837 break;
bf4120ad
NF
7838 case OPC_CMP_F_S:
7839 case OPC_CMP_UN_S:
7840 case OPC_CMP_EQ_S:
7841 case OPC_CMP_UEQ_S:
7842 case OPC_CMP_OLT_S:
7843 case OPC_CMP_ULT_S:
7844 case OPC_CMP_OLE_S:
7845 case OPC_CMP_ULE_S:
7846 case OPC_CMP_SF_S:
7847 case OPC_CMP_NGLE_S:
7848 case OPC_CMP_SEQ_S:
7849 case OPC_CMP_NGL_S:
7850 case OPC_CMP_LT_S:
7851 case OPC_CMP_NGE_S:
7852 case OPC_CMP_LE_S:
7853 case OPC_CMP_NGT_S:
8153667c
NF
7854 if (ctx->opcode & (1 << 6)) {
7855 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7856 opn = condnames_abs[func-48];
7857 } else {
7858 gen_cmp_s(ctx, func-48, ft, fs, cc);
7859 opn = condnames[func-48];
5a1e8ffb 7860 }
5a5012ec 7861 break;
bf4120ad 7862 case OPC_ADD_D:
5e755519 7863 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7864 {
a7812ae4
PB
7865 TCGv_i64 fp0 = tcg_temp_new_i64();
7866 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7867
7868 gen_load_fpr64(ctx, fp0, fs);
7869 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7870 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7871 tcg_temp_free_i64(fp1);
b6d96bed 7872 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7873 tcg_temp_free_i64(fp0);
b6d96bed 7874 }
6ea83fed 7875 opn = "add.d";
5a1e8ffb 7876 optype = BINOP;
6ea83fed 7877 break;
bf4120ad 7878 case OPC_SUB_D:
5e755519 7879 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7880 {
a7812ae4
PB
7881 TCGv_i64 fp0 = tcg_temp_new_i64();
7882 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7883
7884 gen_load_fpr64(ctx, fp0, fs);
7885 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7886 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7887 tcg_temp_free_i64(fp1);
b6d96bed 7888 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7889 tcg_temp_free_i64(fp0);
b6d96bed 7890 }
6ea83fed 7891 opn = "sub.d";
5a1e8ffb 7892 optype = BINOP;
6ea83fed 7893 break;
bf4120ad 7894 case OPC_MUL_D:
5e755519 7895 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7896 {
a7812ae4
PB
7897 TCGv_i64 fp0 = tcg_temp_new_i64();
7898 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7899
7900 gen_load_fpr64(ctx, fp0, fs);
7901 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7902 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7903 tcg_temp_free_i64(fp1);
b6d96bed 7904 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7905 tcg_temp_free_i64(fp0);
b6d96bed 7906 }
6ea83fed 7907 opn = "mul.d";
5a1e8ffb 7908 optype = BINOP;
6ea83fed 7909 break;
bf4120ad 7910 case OPC_DIV_D:
5e755519 7911 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7912 {
a7812ae4
PB
7913 TCGv_i64 fp0 = tcg_temp_new_i64();
7914 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7915
7916 gen_load_fpr64(ctx, fp0, fs);
7917 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7918 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7919 tcg_temp_free_i64(fp1);
b6d96bed 7920 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7921 tcg_temp_free_i64(fp0);
b6d96bed 7922 }
6ea83fed 7923 opn = "div.d";
5a1e8ffb 7924 optype = BINOP;
6ea83fed 7925 break;
bf4120ad 7926 case OPC_SQRT_D:
5e755519 7927 check_cp1_registers(ctx, fs | fd);
b6d96bed 7928 {
a7812ae4 7929 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7930
7931 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7932 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7933 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7934 tcg_temp_free_i64(fp0);
b6d96bed 7935 }
6ea83fed
FB
7936 opn = "sqrt.d";
7937 break;
bf4120ad 7938 case OPC_ABS_D:
5e755519 7939 check_cp1_registers(ctx, fs | fd);
b6d96bed 7940 {
a7812ae4 7941 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7942
7943 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7944 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7945 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7946 tcg_temp_free_i64(fp0);
b6d96bed 7947 }
6ea83fed
FB
7948 opn = "abs.d";
7949 break;
bf4120ad 7950 case OPC_MOV_D:
5e755519 7951 check_cp1_registers(ctx, fs | fd);
b6d96bed 7952 {
a7812ae4 7953 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7954
7955 gen_load_fpr64(ctx, fp0, fs);
7956 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7957 tcg_temp_free_i64(fp0);
b6d96bed 7958 }
6ea83fed
FB
7959 opn = "mov.d";
7960 break;
bf4120ad 7961 case OPC_NEG_D:
5e755519 7962 check_cp1_registers(ctx, fs | fd);
b6d96bed 7963 {
a7812ae4 7964 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7965
7966 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7967 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 7968 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7969 tcg_temp_free_i64(fp0);
b6d96bed 7970 }
6ea83fed
FB
7971 opn = "neg.d";
7972 break;
bf4120ad 7973 case OPC_ROUND_L_D:
5e755519 7974 check_cp1_64bitmode(ctx);
b6d96bed 7975 {
a7812ae4 7976 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7977
7978 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7979 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 7980 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7981 tcg_temp_free_i64(fp0);
b6d96bed 7982 }
5a5012ec
TS
7983 opn = "round.l.d";
7984 break;
bf4120ad 7985 case OPC_TRUNC_L_D:
5e755519 7986 check_cp1_64bitmode(ctx);
b6d96bed 7987 {
a7812ae4 7988 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7989
7990 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7991 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 7992 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7993 tcg_temp_free_i64(fp0);
b6d96bed 7994 }
5a5012ec
TS
7995 opn = "trunc.l.d";
7996 break;
bf4120ad 7997 case OPC_CEIL_L_D:
5e755519 7998 check_cp1_64bitmode(ctx);
b6d96bed 7999 {
a7812ae4 8000 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8001
8002 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8003 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8004 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8005 tcg_temp_free_i64(fp0);
b6d96bed 8006 }
5a5012ec
TS
8007 opn = "ceil.l.d";
8008 break;
bf4120ad 8009 case OPC_FLOOR_L_D:
5e755519 8010 check_cp1_64bitmode(ctx);
b6d96bed 8011 {
a7812ae4 8012 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8013
8014 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8015 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8016 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8017 tcg_temp_free_i64(fp0);
b6d96bed 8018 }
5a5012ec
TS
8019 opn = "floor.l.d";
8020 break;
bf4120ad 8021 case OPC_ROUND_W_D:
5e755519 8022 check_cp1_registers(ctx, fs);
b6d96bed 8023 {
a7812ae4
PB
8024 TCGv_i32 fp32 = tcg_temp_new_i32();
8025 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8026
8027 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8028 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8029 tcg_temp_free_i64(fp64);
b6d96bed 8030 gen_store_fpr32(fp32, fd);
a7812ae4 8031 tcg_temp_free_i32(fp32);
b6d96bed 8032 }
6ea83fed
FB
8033 opn = "round.w.d";
8034 break;
bf4120ad 8035 case OPC_TRUNC_W_D:
5e755519 8036 check_cp1_registers(ctx, fs);
b6d96bed 8037 {
a7812ae4
PB
8038 TCGv_i32 fp32 = tcg_temp_new_i32();
8039 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8040
8041 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8042 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8043 tcg_temp_free_i64(fp64);
b6d96bed 8044 gen_store_fpr32(fp32, fd);
a7812ae4 8045 tcg_temp_free_i32(fp32);
b6d96bed 8046 }
6ea83fed
FB
8047 opn = "trunc.w.d";
8048 break;
bf4120ad 8049 case OPC_CEIL_W_D:
5e755519 8050 check_cp1_registers(ctx, fs);
b6d96bed 8051 {
a7812ae4
PB
8052 TCGv_i32 fp32 = tcg_temp_new_i32();
8053 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8054
8055 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8056 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8057 tcg_temp_free_i64(fp64);
b6d96bed 8058 gen_store_fpr32(fp32, fd);
a7812ae4 8059 tcg_temp_free_i32(fp32);
b6d96bed 8060 }
6ea83fed
FB
8061 opn = "ceil.w.d";
8062 break;
bf4120ad 8063 case OPC_FLOOR_W_D:
5e755519 8064 check_cp1_registers(ctx, fs);
b6d96bed 8065 {
a7812ae4
PB
8066 TCGv_i32 fp32 = tcg_temp_new_i32();
8067 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8068
8069 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8070 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8071 tcg_temp_free_i64(fp64);
b6d96bed 8072 gen_store_fpr32(fp32, fd);
a7812ae4 8073 tcg_temp_free_i32(fp32);
b6d96bed 8074 }
7a387fff 8075 opn = "floor.w.d";
6ea83fed 8076 break;
bf4120ad 8077 case OPC_MOVCF_D:
b6d96bed 8078 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8079 opn = "movcf.d";
dd016883 8080 break;
bf4120ad 8081 case OPC_MOVZ_D:
a16336e4
TS
8082 {
8083 int l1 = gen_new_label();
c9297f4d 8084 TCGv_i64 fp0;
a16336e4 8085
c9297f4d
AJ
8086 if (ft != 0) {
8087 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8088 }
8089 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8090 gen_load_fpr64(ctx, fp0, fs);
8091 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8092 tcg_temp_free_i64(fp0);
a16336e4
TS
8093 gen_set_label(l1);
8094 }
5a5012ec
TS
8095 opn = "movz.d";
8096 break;
bf4120ad 8097 case OPC_MOVN_D:
a16336e4
TS
8098 {
8099 int l1 = gen_new_label();
c9297f4d
AJ
8100 TCGv_i64 fp0;
8101
8102 if (ft != 0) {
8103 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8104 fp0 = tcg_temp_new_i64();
8105 gen_load_fpr64(ctx, fp0, fs);
8106 gen_store_fpr64(ctx, fp0, fd);
8107 tcg_temp_free_i64(fp0);
8108 gen_set_label(l1);
8109 }
a16336e4 8110 }
5a5012ec 8111 opn = "movn.d";
6ea83fed 8112 break;
bf4120ad 8113 case OPC_RECIP_D:
b8aa4598 8114 check_cp1_64bitmode(ctx);
b6d96bed 8115 {
a7812ae4 8116 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8117
8118 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8119 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8120 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8121 tcg_temp_free_i64(fp0);
b6d96bed 8122 }
57fa1fb3
TS
8123 opn = "recip.d";
8124 break;
bf4120ad 8125 case OPC_RSQRT_D:
b8aa4598 8126 check_cp1_64bitmode(ctx);
b6d96bed 8127 {
a7812ae4 8128 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8129
8130 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8131 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8132 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8133 tcg_temp_free_i64(fp0);
b6d96bed 8134 }
57fa1fb3
TS
8135 opn = "rsqrt.d";
8136 break;
bf4120ad 8137 case OPC_RECIP2_D:
5e755519 8138 check_cp1_64bitmode(ctx);
b6d96bed 8139 {
a7812ae4
PB
8140 TCGv_i64 fp0 = tcg_temp_new_i64();
8141 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8142
8143 gen_load_fpr64(ctx, fp0, fs);
8144 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8145 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8146 tcg_temp_free_i64(fp1);
b6d96bed 8147 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8148 tcg_temp_free_i64(fp0);
b6d96bed 8149 }
57fa1fb3
TS
8150 opn = "recip2.d";
8151 break;
bf4120ad 8152 case OPC_RECIP1_D:
5e755519 8153 check_cp1_64bitmode(ctx);
b6d96bed 8154 {
a7812ae4 8155 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8156
8157 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8158 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8159 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8160 tcg_temp_free_i64(fp0);
b6d96bed 8161 }
57fa1fb3
TS
8162 opn = "recip1.d";
8163 break;
bf4120ad 8164 case OPC_RSQRT1_D:
5e755519 8165 check_cp1_64bitmode(ctx);
b6d96bed 8166 {
a7812ae4 8167 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8168
8169 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8170 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8171 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8172 tcg_temp_free_i64(fp0);
b6d96bed 8173 }
57fa1fb3
TS
8174 opn = "rsqrt1.d";
8175 break;
bf4120ad 8176 case OPC_RSQRT2_D:
5e755519 8177 check_cp1_64bitmode(ctx);
b6d96bed 8178 {
a7812ae4
PB
8179 TCGv_i64 fp0 = tcg_temp_new_i64();
8180 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8181
8182 gen_load_fpr64(ctx, fp0, fs);
8183 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8184 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8185 tcg_temp_free_i64(fp1);
b6d96bed 8186 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8187 tcg_temp_free_i64(fp0);
b6d96bed 8188 }
57fa1fb3
TS
8189 opn = "rsqrt2.d";
8190 break;
bf4120ad
NF
8191 case OPC_CMP_F_D:
8192 case OPC_CMP_UN_D:
8193 case OPC_CMP_EQ_D:
8194 case OPC_CMP_UEQ_D:
8195 case OPC_CMP_OLT_D:
8196 case OPC_CMP_ULT_D:
8197 case OPC_CMP_OLE_D:
8198 case OPC_CMP_ULE_D:
8199 case OPC_CMP_SF_D:
8200 case OPC_CMP_NGLE_D:
8201 case OPC_CMP_SEQ_D:
8202 case OPC_CMP_NGL_D:
8203 case OPC_CMP_LT_D:
8204 case OPC_CMP_NGE_D:
8205 case OPC_CMP_LE_D:
8206 case OPC_CMP_NGT_D:
8153667c
NF
8207 if (ctx->opcode & (1 << 6)) {
8208 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8209 opn = condnames_abs[func-48];
8210 } else {
8211 gen_cmp_d(ctx, func-48, ft, fs, cc);
8212 opn = condnames[func-48];
5a1e8ffb 8213 }
6ea83fed 8214 break;
bf4120ad 8215 case OPC_CVT_S_D:
5e755519 8216 check_cp1_registers(ctx, fs);
b6d96bed 8217 {
a7812ae4
PB
8218 TCGv_i32 fp32 = tcg_temp_new_i32();
8219 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8220
8221 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8222 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8223 tcg_temp_free_i64(fp64);
b6d96bed 8224 gen_store_fpr32(fp32, fd);
a7812ae4 8225 tcg_temp_free_i32(fp32);
b6d96bed 8226 }
5a5012ec
TS
8227 opn = "cvt.s.d";
8228 break;
bf4120ad 8229 case OPC_CVT_W_D:
5e755519 8230 check_cp1_registers(ctx, fs);
b6d96bed 8231 {
a7812ae4
PB
8232 TCGv_i32 fp32 = tcg_temp_new_i32();
8233 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8234
8235 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8236 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8237 tcg_temp_free_i64(fp64);
b6d96bed 8238 gen_store_fpr32(fp32, fd);
a7812ae4 8239 tcg_temp_free_i32(fp32);
b6d96bed 8240 }
5a5012ec
TS
8241 opn = "cvt.w.d";
8242 break;
bf4120ad 8243 case OPC_CVT_L_D:
5e755519 8244 check_cp1_64bitmode(ctx);
b6d96bed 8245 {
a7812ae4 8246 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8247
8248 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8249 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8250 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8251 tcg_temp_free_i64(fp0);
b6d96bed 8252 }
5a5012ec
TS
8253 opn = "cvt.l.d";
8254 break;
bf4120ad 8255 case OPC_CVT_S_W:
b6d96bed 8256 {
a7812ae4 8257 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8258
8259 gen_load_fpr32(fp0, fs);
895c2d04 8260 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8261 gen_store_fpr32(fp0, fd);
a7812ae4 8262 tcg_temp_free_i32(fp0);
b6d96bed 8263 }
5a5012ec 8264 opn = "cvt.s.w";
6ea83fed 8265 break;
bf4120ad 8266 case OPC_CVT_D_W:
5e755519 8267 check_cp1_registers(ctx, fd);
b6d96bed 8268 {
a7812ae4
PB
8269 TCGv_i32 fp32 = tcg_temp_new_i32();
8270 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8271
8272 gen_load_fpr32(fp32, fs);
895c2d04 8273 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8274 tcg_temp_free_i32(fp32);
b6d96bed 8275 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8276 tcg_temp_free_i64(fp64);
b6d96bed 8277 }
5a5012ec
TS
8278 opn = "cvt.d.w";
8279 break;
bf4120ad 8280 case OPC_CVT_S_L:
5e755519 8281 check_cp1_64bitmode(ctx);
b6d96bed 8282 {
a7812ae4
PB
8283 TCGv_i32 fp32 = tcg_temp_new_i32();
8284 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8285
8286 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8287 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8288 tcg_temp_free_i64(fp64);
b6d96bed 8289 gen_store_fpr32(fp32, fd);
a7812ae4 8290 tcg_temp_free_i32(fp32);
b6d96bed 8291 }
5a5012ec
TS
8292 opn = "cvt.s.l";
8293 break;
bf4120ad 8294 case OPC_CVT_D_L:
5e755519 8295 check_cp1_64bitmode(ctx);
b6d96bed 8296 {
a7812ae4 8297 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8298
8299 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8300 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8301 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8302 tcg_temp_free_i64(fp0);
b6d96bed 8303 }
5a5012ec
TS
8304 opn = "cvt.d.l";
8305 break;
bf4120ad 8306 case OPC_CVT_PS_PW:
5e755519 8307 check_cp1_64bitmode(ctx);
b6d96bed 8308 {
a7812ae4 8309 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8310
8311 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8312 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8313 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8314 tcg_temp_free_i64(fp0);
b6d96bed 8315 }
5a5012ec
TS
8316 opn = "cvt.ps.pw";
8317 break;
bf4120ad 8318 case OPC_ADD_PS:
5e755519 8319 check_cp1_64bitmode(ctx);
b6d96bed 8320 {
a7812ae4
PB
8321 TCGv_i64 fp0 = tcg_temp_new_i64();
8322 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8323
8324 gen_load_fpr64(ctx, fp0, fs);
8325 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8326 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8327 tcg_temp_free_i64(fp1);
b6d96bed 8328 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8329 tcg_temp_free_i64(fp0);
b6d96bed 8330 }
5a5012ec 8331 opn = "add.ps";
6ea83fed 8332 break;
bf4120ad 8333 case OPC_SUB_PS:
5e755519 8334 check_cp1_64bitmode(ctx);
b6d96bed 8335 {
a7812ae4
PB
8336 TCGv_i64 fp0 = tcg_temp_new_i64();
8337 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8338
8339 gen_load_fpr64(ctx, fp0, fs);
8340 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8341 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8342 tcg_temp_free_i64(fp1);
b6d96bed 8343 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8344 tcg_temp_free_i64(fp0);
b6d96bed 8345 }
5a5012ec 8346 opn = "sub.ps";
6ea83fed 8347 break;
bf4120ad 8348 case OPC_MUL_PS:
5e755519 8349 check_cp1_64bitmode(ctx);
b6d96bed 8350 {
a7812ae4
PB
8351 TCGv_i64 fp0 = tcg_temp_new_i64();
8352 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8353
8354 gen_load_fpr64(ctx, fp0, fs);
8355 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8356 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8357 tcg_temp_free_i64(fp1);
b6d96bed 8358 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8359 tcg_temp_free_i64(fp0);
b6d96bed 8360 }
5a5012ec 8361 opn = "mul.ps";
6ea83fed 8362 break;
bf4120ad 8363 case OPC_ABS_PS:
5e755519 8364 check_cp1_64bitmode(ctx);
b6d96bed 8365 {
a7812ae4 8366 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8367
8368 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8369 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8370 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8371 tcg_temp_free_i64(fp0);
b6d96bed 8372 }
5a5012ec 8373 opn = "abs.ps";
6ea83fed 8374 break;
bf4120ad 8375 case OPC_MOV_PS:
5e755519 8376 check_cp1_64bitmode(ctx);
b6d96bed 8377 {
a7812ae4 8378 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8379
8380 gen_load_fpr64(ctx, fp0, fs);
8381 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8382 tcg_temp_free_i64(fp0);
b6d96bed 8383 }
5a5012ec 8384 opn = "mov.ps";
6ea83fed 8385 break;
bf4120ad 8386 case OPC_NEG_PS:
5e755519 8387 check_cp1_64bitmode(ctx);
b6d96bed 8388 {
a7812ae4 8389 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8390
8391 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8392 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8393 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8394 tcg_temp_free_i64(fp0);
b6d96bed 8395 }
5a5012ec 8396 opn = "neg.ps";
6ea83fed 8397 break;
bf4120ad 8398 case OPC_MOVCF_PS:
5e755519 8399 check_cp1_64bitmode(ctx);
7f6613ce 8400 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8401 opn = "movcf.ps";
6ea83fed 8402 break;
bf4120ad 8403 case OPC_MOVZ_PS:
5e755519 8404 check_cp1_64bitmode(ctx);
a16336e4
TS
8405 {
8406 int l1 = gen_new_label();
30a3848b 8407 TCGv_i64 fp0;
a16336e4 8408
c9297f4d
AJ
8409 if (ft != 0)
8410 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8411 fp0 = tcg_temp_new_i64();
8412 gen_load_fpr64(ctx, fp0, fs);
8413 gen_store_fpr64(ctx, fp0, fd);
8414 tcg_temp_free_i64(fp0);
a16336e4
TS
8415 gen_set_label(l1);
8416 }
5a5012ec 8417 opn = "movz.ps";
6ea83fed 8418 break;
bf4120ad 8419 case OPC_MOVN_PS:
5e755519 8420 check_cp1_64bitmode(ctx);
a16336e4
TS
8421 {
8422 int l1 = gen_new_label();
30a3848b 8423 TCGv_i64 fp0;
c9297f4d
AJ
8424
8425 if (ft != 0) {
8426 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8427 fp0 = tcg_temp_new_i64();
8428 gen_load_fpr64(ctx, fp0, fs);
8429 gen_store_fpr64(ctx, fp0, fd);
8430 tcg_temp_free_i64(fp0);
8431 gen_set_label(l1);
8432 }
a16336e4 8433 }
5a5012ec 8434 opn = "movn.ps";
6ea83fed 8435 break;
bf4120ad 8436 case OPC_ADDR_PS:
5e755519 8437 check_cp1_64bitmode(ctx);
b6d96bed 8438 {
a7812ae4
PB
8439 TCGv_i64 fp0 = tcg_temp_new_i64();
8440 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8441
8442 gen_load_fpr64(ctx, fp0, ft);
8443 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8444 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8445 tcg_temp_free_i64(fp1);
b6d96bed 8446 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8447 tcg_temp_free_i64(fp0);
b6d96bed 8448 }
fbcc6828
TS
8449 opn = "addr.ps";
8450 break;
bf4120ad 8451 case OPC_MULR_PS:
5e755519 8452 check_cp1_64bitmode(ctx);
b6d96bed 8453 {
a7812ae4
PB
8454 TCGv_i64 fp0 = tcg_temp_new_i64();
8455 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8456
8457 gen_load_fpr64(ctx, fp0, ft);
8458 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8459 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8460 tcg_temp_free_i64(fp1);
b6d96bed 8461 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8462 tcg_temp_free_i64(fp0);
b6d96bed 8463 }
57fa1fb3
TS
8464 opn = "mulr.ps";
8465 break;
bf4120ad 8466 case OPC_RECIP2_PS:
5e755519 8467 check_cp1_64bitmode(ctx);
b6d96bed 8468 {
a7812ae4
PB
8469 TCGv_i64 fp0 = tcg_temp_new_i64();
8470 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8471
8472 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8473 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8474 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8475 tcg_temp_free_i64(fp1);
b6d96bed 8476 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8477 tcg_temp_free_i64(fp0);
b6d96bed 8478 }
57fa1fb3
TS
8479 opn = "recip2.ps";
8480 break;
bf4120ad 8481 case OPC_RECIP1_PS:
5e755519 8482 check_cp1_64bitmode(ctx);
b6d96bed 8483 {
a7812ae4 8484 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8485
8486 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8487 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8488 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8489 tcg_temp_free_i64(fp0);
b6d96bed 8490 }
57fa1fb3
TS
8491 opn = "recip1.ps";
8492 break;
bf4120ad 8493 case OPC_RSQRT1_PS:
5e755519 8494 check_cp1_64bitmode(ctx);
b6d96bed 8495 {
a7812ae4 8496 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8497
8498 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8499 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8500 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8501 tcg_temp_free_i64(fp0);
b6d96bed 8502 }
57fa1fb3
TS
8503 opn = "rsqrt1.ps";
8504 break;
bf4120ad 8505 case OPC_RSQRT2_PS:
5e755519 8506 check_cp1_64bitmode(ctx);
b6d96bed 8507 {
a7812ae4
PB
8508 TCGv_i64 fp0 = tcg_temp_new_i64();
8509 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8510
8511 gen_load_fpr64(ctx, fp0, fs);
8512 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8513 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8514 tcg_temp_free_i64(fp1);
b6d96bed 8515 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8516 tcg_temp_free_i64(fp0);
b6d96bed 8517 }
57fa1fb3
TS
8518 opn = "rsqrt2.ps";
8519 break;
bf4120ad 8520 case OPC_CVT_S_PU:
5e755519 8521 check_cp1_64bitmode(ctx);
b6d96bed 8522 {
a7812ae4 8523 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8524
7f6613ce 8525 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 8526 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8527 gen_store_fpr32(fp0, fd);
a7812ae4 8528 tcg_temp_free_i32(fp0);
b6d96bed 8529 }
5a5012ec 8530 opn = "cvt.s.pu";
dd016883 8531 break;
bf4120ad 8532 case OPC_CVT_PW_PS:
5e755519 8533 check_cp1_64bitmode(ctx);
b6d96bed 8534 {
a7812ae4 8535 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8536
8537 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8538 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8539 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8540 tcg_temp_free_i64(fp0);
b6d96bed 8541 }
5a5012ec 8542 opn = "cvt.pw.ps";
6ea83fed 8543 break;
bf4120ad 8544 case OPC_CVT_S_PL:
5e755519 8545 check_cp1_64bitmode(ctx);
b6d96bed 8546 {
a7812ae4 8547 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8548
8549 gen_load_fpr32(fp0, fs);
895c2d04 8550 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8551 gen_store_fpr32(fp0, fd);
a7812ae4 8552 tcg_temp_free_i32(fp0);
b6d96bed 8553 }
5a5012ec 8554 opn = "cvt.s.pl";
6ea83fed 8555 break;
bf4120ad 8556 case OPC_PLL_PS:
5e755519 8557 check_cp1_64bitmode(ctx);
b6d96bed 8558 {
a7812ae4
PB
8559 TCGv_i32 fp0 = tcg_temp_new_i32();
8560 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8561
8562 gen_load_fpr32(fp0, fs);
8563 gen_load_fpr32(fp1, ft);
7f6613ce 8564 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 8565 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8566 tcg_temp_free_i32(fp0);
8567 tcg_temp_free_i32(fp1);
b6d96bed 8568 }
5a5012ec 8569 opn = "pll.ps";
6ea83fed 8570 break;
bf4120ad 8571 case OPC_PLU_PS:
5e755519 8572 check_cp1_64bitmode(ctx);
b6d96bed 8573 {
a7812ae4
PB
8574 TCGv_i32 fp0 = tcg_temp_new_i32();
8575 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8576
8577 gen_load_fpr32(fp0, fs);
7f6613ce 8578 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 8579 gen_store_fpr32(fp1, fd);
7f6613ce 8580 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8581 tcg_temp_free_i32(fp0);
8582 tcg_temp_free_i32(fp1);
b6d96bed 8583 }
5a5012ec
TS
8584 opn = "plu.ps";
8585 break;
bf4120ad 8586 case OPC_PUL_PS:
5e755519 8587 check_cp1_64bitmode(ctx);
b6d96bed 8588 {
a7812ae4
PB
8589 TCGv_i32 fp0 = tcg_temp_new_i32();
8590 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8591
7f6613ce 8592 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
8593 gen_load_fpr32(fp1, ft);
8594 gen_store_fpr32(fp1, fd);
7f6613ce 8595 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8596 tcg_temp_free_i32(fp0);
8597 tcg_temp_free_i32(fp1);
b6d96bed 8598 }
5a5012ec
TS
8599 opn = "pul.ps";
8600 break;
bf4120ad 8601 case OPC_PUU_PS:
5e755519 8602 check_cp1_64bitmode(ctx);
b6d96bed 8603 {
a7812ae4
PB
8604 TCGv_i32 fp0 = tcg_temp_new_i32();
8605 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8606
7f6613ce
PJ
8607 gen_load_fpr32h(ctx, fp0, fs);
8608 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 8609 gen_store_fpr32(fp1, fd);
7f6613ce 8610 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8611 tcg_temp_free_i32(fp0);
8612 tcg_temp_free_i32(fp1);
b6d96bed 8613 }
5a5012ec
TS
8614 opn = "puu.ps";
8615 break;
bf4120ad
NF
8616 case OPC_CMP_F_PS:
8617 case OPC_CMP_UN_PS:
8618 case OPC_CMP_EQ_PS:
8619 case OPC_CMP_UEQ_PS:
8620 case OPC_CMP_OLT_PS:
8621 case OPC_CMP_ULT_PS:
8622 case OPC_CMP_OLE_PS:
8623 case OPC_CMP_ULE_PS:
8624 case OPC_CMP_SF_PS:
8625 case OPC_CMP_NGLE_PS:
8626 case OPC_CMP_SEQ_PS:
8627 case OPC_CMP_NGL_PS:
8628 case OPC_CMP_LT_PS:
8629 case OPC_CMP_NGE_PS:
8630 case OPC_CMP_LE_PS:
8631 case OPC_CMP_NGT_PS:
8153667c
NF
8632 if (ctx->opcode & (1 << 6)) {
8633 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8634 opn = condnames_abs[func-48];
8635 } else {
8636 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8637 opn = condnames[func-48];
5a1e8ffb 8638 }
6ea83fed 8639 break;
5a5012ec 8640 default:
923617a3 8641 MIPS_INVAL(opn);
e397ee33 8642 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8643 return;
8644 }
2abf314d 8645 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8646 switch (optype) {
8647 case BINOP:
6ea83fed 8648 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8649 break;
8650 case CMPOP:
8651 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8652 break;
8653 default:
6ea83fed 8654 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8655 break;
8656 }
6ea83fed 8657}
6af0bf9c 8658
5a5012ec 8659/* Coprocessor 3 (FPU) */
5e755519
TS
8660static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8661 int fd, int fs, int base, int index)
7a387fff 8662{
923617a3 8663 const char *opn = "extended float load/store";
93b12ccc 8664 int store = 0;
4e2474d6 8665 TCGv t0 = tcg_temp_new();
7a387fff 8666
93b12ccc 8667 if (base == 0) {
6c5c1e20 8668 gen_load_gpr(t0, index);
93b12ccc 8669 } else if (index == 0) {
6c5c1e20 8670 gen_load_gpr(t0, base);
93b12ccc 8671 } else {
05168674 8672 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8673 }
5a5012ec 8674 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8675 memory access. */
5a5012ec
TS
8676 switch (opc) {
8677 case OPC_LWXC1:
8c0ab41f 8678 check_cop1x(ctx);
b6d96bed 8679 {
a7812ae4 8680 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8681
5f68f5ae 8682 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 8683 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8684 gen_store_fpr32(fp0, fd);
a7812ae4 8685 tcg_temp_free_i32(fp0);
b6d96bed 8686 }
5a5012ec
TS
8687 opn = "lwxc1";
8688 break;
8689 case OPC_LDXC1:
8c0ab41f
AJ
8690 check_cop1x(ctx);
8691 check_cp1_registers(ctx, fd);
b6d96bed 8692 {
a7812ae4 8693 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 8694 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 8695 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8696 tcg_temp_free_i64(fp0);
b6d96bed 8697 }
5a5012ec
TS
8698 opn = "ldxc1";
8699 break;
8700 case OPC_LUXC1:
8c0ab41f 8701 check_cp1_64bitmode(ctx);
6c5c1e20 8702 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8703 {
a7812ae4 8704 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8705
5f68f5ae 8706 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 8707 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8708 tcg_temp_free_i64(fp0);
b6d96bed 8709 }
5a5012ec
TS
8710 opn = "luxc1";
8711 break;
8712 case OPC_SWXC1:
8c0ab41f 8713 check_cop1x(ctx);
b6d96bed 8714 {
a7812ae4 8715 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8716 gen_load_fpr32(fp0, fs);
5f68f5ae 8717 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 8718 tcg_temp_free_i32(fp0);
b6d96bed 8719 }
5a5012ec 8720 opn = "swxc1";
93b12ccc 8721 store = 1;
5a5012ec
TS
8722 break;
8723 case OPC_SDXC1:
8c0ab41f
AJ
8724 check_cop1x(ctx);
8725 check_cp1_registers(ctx, fs);
b6d96bed 8726 {
a7812ae4 8727 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8728 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 8729 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 8730 tcg_temp_free_i64(fp0);
b6d96bed 8731 }
5a5012ec 8732 opn = "sdxc1";
93b12ccc 8733 store = 1;
5a5012ec
TS
8734 break;
8735 case OPC_SUXC1:
8c0ab41f 8736 check_cp1_64bitmode(ctx);
6c5c1e20 8737 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8738 {
a7812ae4 8739 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8740 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 8741 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 8742 tcg_temp_free_i64(fp0);
b6d96bed 8743 }
5a5012ec 8744 opn = "suxc1";
93b12ccc 8745 store = 1;
5a5012ec 8746 break;
5a5012ec 8747 }
6c5c1e20 8748 tcg_temp_free(t0);
2abf314d 8749 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8750 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8751 regnames[index], regnames[base]);
5a5012ec
TS
8752}
8753
5e755519
TS
8754static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8755 int fd, int fr, int fs, int ft)
5a5012ec 8756{
923617a3 8757 const char *opn = "flt3_arith";
5a5012ec 8758
5a5012ec
TS
8759 switch (opc) {
8760 case OPC_ALNV_PS:
b8aa4598 8761 check_cp1_64bitmode(ctx);
a16336e4 8762 {
a7812ae4 8763 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8764 TCGv_i32 fp = tcg_temp_new_i32();
8765 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8766 int l1 = gen_new_label();
8767 int l2 = gen_new_label();
8768
6c5c1e20
TS
8769 gen_load_gpr(t0, fr);
8770 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8771
8772 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 8773 gen_load_fpr32(fp, fs);
7f6613ce 8774 gen_load_fpr32h(ctx, fph, fs);
c905fdac 8775 gen_store_fpr32(fp, fd);
7f6613ce 8776 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
8777 tcg_gen_br(l2);
8778 gen_set_label(l1);
6c5c1e20
TS
8779 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8780 tcg_temp_free(t0);
a16336e4 8781#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 8782 gen_load_fpr32(fp, fs);
7f6613ce
PJ
8783 gen_load_fpr32h(ctx, fph, ft);
8784 gen_store_fpr32h(ctx, fp, fd);
c905fdac 8785 gen_store_fpr32(fph, fd);
a16336e4 8786#else
7f6613ce 8787 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
8788 gen_load_fpr32(fp, ft);
8789 gen_store_fpr32(fph, fd);
7f6613ce 8790 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
8791#endif
8792 gen_set_label(l2);
c905fdac
AJ
8793 tcg_temp_free_i32(fp);
8794 tcg_temp_free_i32(fph);
a16336e4 8795 }
5a5012ec
TS
8796 opn = "alnv.ps";
8797 break;
8798 case OPC_MADD_S:
b8aa4598 8799 check_cop1x(ctx);
b6d96bed 8800 {
a7812ae4
PB
8801 TCGv_i32 fp0 = tcg_temp_new_i32();
8802 TCGv_i32 fp1 = tcg_temp_new_i32();
8803 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8804
8805 gen_load_fpr32(fp0, fs);
8806 gen_load_fpr32(fp1, ft);
8807 gen_load_fpr32(fp2, fr);
b3d6cd44 8808 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8809 tcg_temp_free_i32(fp0);
8810 tcg_temp_free_i32(fp1);
b6d96bed 8811 gen_store_fpr32(fp2, fd);
a7812ae4 8812 tcg_temp_free_i32(fp2);
b6d96bed 8813 }
5a5012ec
TS
8814 opn = "madd.s";
8815 break;
8816 case OPC_MADD_D:
b8aa4598
TS
8817 check_cop1x(ctx);
8818 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8819 {
a7812ae4
PB
8820 TCGv_i64 fp0 = tcg_temp_new_i64();
8821 TCGv_i64 fp1 = tcg_temp_new_i64();
8822 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8823
8824 gen_load_fpr64(ctx, fp0, fs);
8825 gen_load_fpr64(ctx, fp1, ft);
8826 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8827 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8828 tcg_temp_free_i64(fp0);
8829 tcg_temp_free_i64(fp1);
b6d96bed 8830 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8831 tcg_temp_free_i64(fp2);
b6d96bed 8832 }
5a5012ec
TS
8833 opn = "madd.d";
8834 break;
8835 case OPC_MADD_PS:
b8aa4598 8836 check_cp1_64bitmode(ctx);
b6d96bed 8837 {
a7812ae4
PB
8838 TCGv_i64 fp0 = tcg_temp_new_i64();
8839 TCGv_i64 fp1 = tcg_temp_new_i64();
8840 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8841
8842 gen_load_fpr64(ctx, fp0, fs);
8843 gen_load_fpr64(ctx, fp1, ft);
8844 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8845 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8846 tcg_temp_free_i64(fp0);
8847 tcg_temp_free_i64(fp1);
b6d96bed 8848 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8849 tcg_temp_free_i64(fp2);
b6d96bed 8850 }
5a5012ec
TS
8851 opn = "madd.ps";
8852 break;
8853 case OPC_MSUB_S:
b8aa4598 8854 check_cop1x(ctx);
b6d96bed 8855 {
a7812ae4
PB
8856 TCGv_i32 fp0 = tcg_temp_new_i32();
8857 TCGv_i32 fp1 = tcg_temp_new_i32();
8858 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8859
8860 gen_load_fpr32(fp0, fs);
8861 gen_load_fpr32(fp1, ft);
8862 gen_load_fpr32(fp2, fr);
b3d6cd44 8863 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8864 tcg_temp_free_i32(fp0);
8865 tcg_temp_free_i32(fp1);
b6d96bed 8866 gen_store_fpr32(fp2, fd);
a7812ae4 8867 tcg_temp_free_i32(fp2);
b6d96bed 8868 }
5a5012ec
TS
8869 opn = "msub.s";
8870 break;
8871 case OPC_MSUB_D:
b8aa4598
TS
8872 check_cop1x(ctx);
8873 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8874 {
a7812ae4
PB
8875 TCGv_i64 fp0 = tcg_temp_new_i64();
8876 TCGv_i64 fp1 = tcg_temp_new_i64();
8877 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8878
8879 gen_load_fpr64(ctx, fp0, fs);
8880 gen_load_fpr64(ctx, fp1, ft);
8881 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8882 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8883 tcg_temp_free_i64(fp0);
8884 tcg_temp_free_i64(fp1);
b6d96bed 8885 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8886 tcg_temp_free_i64(fp2);
b6d96bed 8887 }
5a5012ec
TS
8888 opn = "msub.d";
8889 break;
8890 case OPC_MSUB_PS:
b8aa4598 8891 check_cp1_64bitmode(ctx);
b6d96bed 8892 {
a7812ae4
PB
8893 TCGv_i64 fp0 = tcg_temp_new_i64();
8894 TCGv_i64 fp1 = tcg_temp_new_i64();
8895 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8896
8897 gen_load_fpr64(ctx, fp0, fs);
8898 gen_load_fpr64(ctx, fp1, ft);
8899 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8900 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8901 tcg_temp_free_i64(fp0);
8902 tcg_temp_free_i64(fp1);
b6d96bed 8903 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8904 tcg_temp_free_i64(fp2);
b6d96bed 8905 }
5a5012ec
TS
8906 opn = "msub.ps";
8907 break;
8908 case OPC_NMADD_S:
b8aa4598 8909 check_cop1x(ctx);
b6d96bed 8910 {
a7812ae4
PB
8911 TCGv_i32 fp0 = tcg_temp_new_i32();
8912 TCGv_i32 fp1 = tcg_temp_new_i32();
8913 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8914
8915 gen_load_fpr32(fp0, fs);
8916 gen_load_fpr32(fp1, ft);
8917 gen_load_fpr32(fp2, fr);
b3d6cd44 8918 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8919 tcg_temp_free_i32(fp0);
8920 tcg_temp_free_i32(fp1);
b6d96bed 8921 gen_store_fpr32(fp2, fd);
a7812ae4 8922 tcg_temp_free_i32(fp2);
b6d96bed 8923 }
5a5012ec
TS
8924 opn = "nmadd.s";
8925 break;
8926 case OPC_NMADD_D:
b8aa4598
TS
8927 check_cop1x(ctx);
8928 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8929 {
a7812ae4
PB
8930 TCGv_i64 fp0 = tcg_temp_new_i64();
8931 TCGv_i64 fp1 = tcg_temp_new_i64();
8932 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8933
8934 gen_load_fpr64(ctx, fp0, fs);
8935 gen_load_fpr64(ctx, fp1, ft);
8936 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8937 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8938 tcg_temp_free_i64(fp0);
8939 tcg_temp_free_i64(fp1);
b6d96bed 8940 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8941 tcg_temp_free_i64(fp2);
b6d96bed 8942 }
5a5012ec
TS
8943 opn = "nmadd.d";
8944 break;
8945 case OPC_NMADD_PS:
b8aa4598 8946 check_cp1_64bitmode(ctx);
b6d96bed 8947 {
a7812ae4
PB
8948 TCGv_i64 fp0 = tcg_temp_new_i64();
8949 TCGv_i64 fp1 = tcg_temp_new_i64();
8950 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8951
8952 gen_load_fpr64(ctx, fp0, fs);
8953 gen_load_fpr64(ctx, fp1, ft);
8954 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8955 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8956 tcg_temp_free_i64(fp0);
8957 tcg_temp_free_i64(fp1);
b6d96bed 8958 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8959 tcg_temp_free_i64(fp2);
b6d96bed 8960 }
5a5012ec
TS
8961 opn = "nmadd.ps";
8962 break;
8963 case OPC_NMSUB_S:
b8aa4598 8964 check_cop1x(ctx);
b6d96bed 8965 {
a7812ae4
PB
8966 TCGv_i32 fp0 = tcg_temp_new_i32();
8967 TCGv_i32 fp1 = tcg_temp_new_i32();
8968 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8969
8970 gen_load_fpr32(fp0, fs);
8971 gen_load_fpr32(fp1, ft);
8972 gen_load_fpr32(fp2, fr);
b3d6cd44 8973 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8974 tcg_temp_free_i32(fp0);
8975 tcg_temp_free_i32(fp1);
b6d96bed 8976 gen_store_fpr32(fp2, fd);
a7812ae4 8977 tcg_temp_free_i32(fp2);
b6d96bed 8978 }
5a5012ec
TS
8979 opn = "nmsub.s";
8980 break;
8981 case OPC_NMSUB_D:
b8aa4598
TS
8982 check_cop1x(ctx);
8983 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8984 {
a7812ae4
PB
8985 TCGv_i64 fp0 = tcg_temp_new_i64();
8986 TCGv_i64 fp1 = tcg_temp_new_i64();
8987 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8988
8989 gen_load_fpr64(ctx, fp0, fs);
8990 gen_load_fpr64(ctx, fp1, ft);
8991 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8992 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8993 tcg_temp_free_i64(fp0);
8994 tcg_temp_free_i64(fp1);
b6d96bed 8995 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8996 tcg_temp_free_i64(fp2);
b6d96bed 8997 }
5a5012ec
TS
8998 opn = "nmsub.d";
8999 break;
9000 case OPC_NMSUB_PS:
b8aa4598 9001 check_cp1_64bitmode(ctx);
b6d96bed 9002 {
a7812ae4
PB
9003 TCGv_i64 fp0 = tcg_temp_new_i64();
9004 TCGv_i64 fp1 = tcg_temp_new_i64();
9005 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9006
9007 gen_load_fpr64(ctx, fp0, fs);
9008 gen_load_fpr64(ctx, fp1, ft);
9009 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9010 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9011 tcg_temp_free_i64(fp0);
9012 tcg_temp_free_i64(fp1);
b6d96bed 9013 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9014 tcg_temp_free_i64(fp2);
b6d96bed 9015 }
5a5012ec
TS
9016 opn = "nmsub.ps";
9017 break;
923617a3
TS
9018 default:
9019 MIPS_INVAL(opn);
5a5012ec
TS
9020 generate_exception (ctx, EXCP_RI);
9021 return;
9022 }
2abf314d 9023 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9024 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9025 fregnames[fs], fregnames[ft]);
7a387fff
TS
9026}
9027
d75c135e 9028static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9029{
9030 TCGv t0;
9031
b3167288
RH
9032#if !defined(CONFIG_USER_ONLY)
9033 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9034 Therefore only check the ISA in system mode. */
d75c135e 9035 check_insn(ctx, ISA_MIPS32R2);
b3167288 9036#endif
26ebe468
NF
9037 t0 = tcg_temp_new();
9038
9039 switch (rd) {
9040 case 0:
9041 save_cpu_state(ctx, 1);
895c2d04 9042 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9043 gen_store_gpr(t0, rt);
9044 break;
9045 case 1:
9046 save_cpu_state(ctx, 1);
895c2d04 9047 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9048 gen_store_gpr(t0, rt);
9049 break;
9050 case 2:
9051 save_cpu_state(ctx, 1);
895c2d04 9052 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9053 gen_store_gpr(t0, rt);
9054 break;
9055 case 3:
9056 save_cpu_state(ctx, 1);
895c2d04 9057 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9058 gen_store_gpr(t0, rt);
9059 break;
9060 case 29:
9061#if defined(CONFIG_USER_ONLY)
7db13fae 9062 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
26ebe468
NF
9063 gen_store_gpr(t0, rt);
9064 break;
9065#else
9066 /* XXX: Some CPUs implement this in hardware.
9067 Not supported yet. */
9068#endif
9069 default: /* Invalid */
9070 MIPS_INVAL("rdhwr");
9071 generate_exception(ctx, EXCP_RI);
9072 break;
9073 }
9074 tcg_temp_free(t0);
9075}
9076
d75c135e 9077static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9078{
9079 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9080 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9081 /* Branches completion */
9082 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9083 ctx->bstate = BS_BRANCH;
9084 save_cpu_state(ctx, 0);
9085 /* FIXME: Need to clear can_do_io. */
364d4831 9086 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9087 case MIPS_HFLAG_B:
9088 /* unconditional branch */
9089 MIPS_DEBUG("unconditional branch");
364d4831
NF
9090 if (proc_hflags & MIPS_HFLAG_BX) {
9091 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9092 }
c9602061
NF
9093 gen_goto_tb(ctx, 0, ctx->btarget);
9094 break;
9095 case MIPS_HFLAG_BL:
9096 /* blikely taken case */
9097 MIPS_DEBUG("blikely branch taken");
9098 gen_goto_tb(ctx, 0, ctx->btarget);
9099 break;
9100 case MIPS_HFLAG_BC:
9101 /* Conditional branch */
9102 MIPS_DEBUG("conditional branch");
9103 {
9104 int l1 = gen_new_label();
9105
9106 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9107 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9108 gen_set_label(l1);
9109 gen_goto_tb(ctx, 0, ctx->btarget);
9110 }
9111 break;
9112 case MIPS_HFLAG_BR:
9113 /* unconditional branch to register */
9114 MIPS_DEBUG("branch to register");
d75c135e 9115 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9116 TCGv t0 = tcg_temp_new();
9117 TCGv_i32 t1 = tcg_temp_new_i32();
9118
9119 tcg_gen_andi_tl(t0, btarget, 0x1);
9120 tcg_gen_trunc_tl_i32(t1, t0);
9121 tcg_temp_free(t0);
9122 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9123 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9124 tcg_gen_or_i32(hflags, hflags, t1);
9125 tcg_temp_free_i32(t1);
9126
9127 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9128 } else {
9129 tcg_gen_mov_tl(cpu_PC, btarget);
9130 }
c9602061
NF
9131 if (ctx->singlestep_enabled) {
9132 save_cpu_state(ctx, 0);
895c2d04 9133 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9134 }
9135 tcg_gen_exit_tb(0);
9136 break;
9137 default:
9138 MIPS_DEBUG("unknown branch");
9139 break;
9140 }
9141 }
9142}
9143
7a387fff 9144/* ISA extensions (ASEs) */
6af0bf9c 9145/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9146
9147/* MIPS16 major opcodes */
9148enum {
9149 M16_OPC_ADDIUSP = 0x00,
9150 M16_OPC_ADDIUPC = 0x01,
9151 M16_OPC_B = 0x02,
9152 M16_OPC_JAL = 0x03,
9153 M16_OPC_BEQZ = 0x04,
9154 M16_OPC_BNEQZ = 0x05,
9155 M16_OPC_SHIFT = 0x06,
9156 M16_OPC_LD = 0x07,
9157 M16_OPC_RRIA = 0x08,
9158 M16_OPC_ADDIU8 = 0x09,
9159 M16_OPC_SLTI = 0x0a,
9160 M16_OPC_SLTIU = 0x0b,
9161 M16_OPC_I8 = 0x0c,
9162 M16_OPC_LI = 0x0d,
9163 M16_OPC_CMPI = 0x0e,
9164 M16_OPC_SD = 0x0f,
9165 M16_OPC_LB = 0x10,
9166 M16_OPC_LH = 0x11,
9167 M16_OPC_LWSP = 0x12,
9168 M16_OPC_LW = 0x13,
9169 M16_OPC_LBU = 0x14,
9170 M16_OPC_LHU = 0x15,
9171 M16_OPC_LWPC = 0x16,
9172 M16_OPC_LWU = 0x17,
9173 M16_OPC_SB = 0x18,
9174 M16_OPC_SH = 0x19,
9175 M16_OPC_SWSP = 0x1a,
9176 M16_OPC_SW = 0x1b,
9177 M16_OPC_RRR = 0x1c,
9178 M16_OPC_RR = 0x1d,
9179 M16_OPC_EXTEND = 0x1e,
9180 M16_OPC_I64 = 0x1f
9181};
9182
9183/* I8 funct field */
9184enum {
9185 I8_BTEQZ = 0x0,
9186 I8_BTNEZ = 0x1,
9187 I8_SWRASP = 0x2,
9188 I8_ADJSP = 0x3,
9189 I8_SVRS = 0x4,
9190 I8_MOV32R = 0x5,
9191 I8_MOVR32 = 0x7
9192};
9193
9194/* RRR f field */
9195enum {
9196 RRR_DADDU = 0x0,
9197 RRR_ADDU = 0x1,
9198 RRR_DSUBU = 0x2,
9199 RRR_SUBU = 0x3
9200};
9201
9202/* RR funct field */
9203enum {
9204 RR_JR = 0x00,
9205 RR_SDBBP = 0x01,
9206 RR_SLT = 0x02,
9207 RR_SLTU = 0x03,
9208 RR_SLLV = 0x04,
9209 RR_BREAK = 0x05,
9210 RR_SRLV = 0x06,
9211 RR_SRAV = 0x07,
9212 RR_DSRL = 0x08,
9213 RR_CMP = 0x0a,
9214 RR_NEG = 0x0b,
9215 RR_AND = 0x0c,
9216 RR_OR = 0x0d,
9217 RR_XOR = 0x0e,
9218 RR_NOT = 0x0f,
9219 RR_MFHI = 0x10,
9220 RR_CNVT = 0x11,
9221 RR_MFLO = 0x12,
9222 RR_DSRA = 0x13,
9223 RR_DSLLV = 0x14,
9224 RR_DSRLV = 0x16,
9225 RR_DSRAV = 0x17,
9226 RR_MULT = 0x18,
9227 RR_MULTU = 0x19,
9228 RR_DIV = 0x1a,
9229 RR_DIVU = 0x1b,
9230 RR_DMULT = 0x1c,
9231 RR_DMULTU = 0x1d,
9232 RR_DDIV = 0x1e,
9233 RR_DDIVU = 0x1f
9234};
9235
9236/* I64 funct field */
9237enum {
9238 I64_LDSP = 0x0,
9239 I64_SDSP = 0x1,
9240 I64_SDRASP = 0x2,
9241 I64_DADJSP = 0x3,
9242 I64_LDPC = 0x4,
364d4831 9243 I64_DADDIU5 = 0x5,
6ea219d0
NF
9244 I64_DADDIUPC = 0x6,
9245 I64_DADDIUSP = 0x7
9246};
9247
9248/* RR ry field for CNVT */
9249enum {
9250 RR_RY_CNVT_ZEB = 0x0,
9251 RR_RY_CNVT_ZEH = 0x1,
9252 RR_RY_CNVT_ZEW = 0x2,
9253 RR_RY_CNVT_SEB = 0x4,
9254 RR_RY_CNVT_SEH = 0x5,
9255 RR_RY_CNVT_SEW = 0x6,
9256};
9257
364d4831
NF
9258static int xlat (int r)
9259{
9260 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9261
9262 return map[r];
9263}
9264
9265static void gen_mips16_save (DisasContext *ctx,
9266 int xsregs, int aregs,
9267 int do_ra, int do_s0, int do_s1,
9268 int framesize)
9269{
9270 TCGv t0 = tcg_temp_new();
9271 TCGv t1 = tcg_temp_new();
9272 int args, astatic;
9273
9274 switch (aregs) {
9275 case 0:
9276 case 1:
9277 case 2:
9278 case 3:
9279 case 11:
9280 args = 0;
9281 break;
9282 case 4:
9283 case 5:
9284 case 6:
9285 case 7:
9286 args = 1;
9287 break;
9288 case 8:
9289 case 9:
9290 case 10:
9291 args = 2;
9292 break;
9293 case 12:
9294 case 13:
9295 args = 3;
9296 break;
9297 case 14:
9298 args = 4;
9299 break;
9300 default:
9301 generate_exception(ctx, EXCP_RI);
9302 return;
9303 }
9304
9305 switch (args) {
9306 case 4:
9307 gen_base_offset_addr(ctx, t0, 29, 12);
9308 gen_load_gpr(t1, 7);
5f68f5ae 9309 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9310 /* Fall through */
9311 case 3:
9312 gen_base_offset_addr(ctx, t0, 29, 8);
9313 gen_load_gpr(t1, 6);
5f68f5ae 9314 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9315 /* Fall through */
9316 case 2:
9317 gen_base_offset_addr(ctx, t0, 29, 4);
9318 gen_load_gpr(t1, 5);
5f68f5ae 9319 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9320 /* Fall through */
9321 case 1:
9322 gen_base_offset_addr(ctx, t0, 29, 0);
9323 gen_load_gpr(t1, 4);
5f68f5ae 9324 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9325 }
9326
9327 gen_load_gpr(t0, 29);
9328
5f68f5ae
AJ
9329#define DECR_AND_STORE(reg) do { \
9330 tcg_gen_subi_tl(t0, t0, 4); \
9331 gen_load_gpr(t1, reg); \
9332 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
9333 } while (0)
9334
9335 if (do_ra) {
9336 DECR_AND_STORE(31);
9337 }
9338
9339 switch (xsregs) {
9340 case 7:
9341 DECR_AND_STORE(30);
9342 /* Fall through */
9343 case 6:
9344 DECR_AND_STORE(23);
9345 /* Fall through */
9346 case 5:
9347 DECR_AND_STORE(22);
9348 /* Fall through */
9349 case 4:
9350 DECR_AND_STORE(21);
9351 /* Fall through */
9352 case 3:
9353 DECR_AND_STORE(20);
9354 /* Fall through */
9355 case 2:
9356 DECR_AND_STORE(19);
9357 /* Fall through */
9358 case 1:
9359 DECR_AND_STORE(18);
9360 }
9361
9362 if (do_s1) {
9363 DECR_AND_STORE(17);
9364 }
9365 if (do_s0) {
9366 DECR_AND_STORE(16);
9367 }
9368
9369 switch (aregs) {
9370 case 0:
9371 case 4:
9372 case 8:
9373 case 12:
9374 case 14:
9375 astatic = 0;
9376 break;
9377 case 1:
9378 case 5:
9379 case 9:
9380 case 13:
9381 astatic = 1;
9382 break;
9383 case 2:
9384 case 6:
9385 case 10:
9386 astatic = 2;
9387 break;
9388 case 3:
9389 case 7:
9390 astatic = 3;
9391 break;
9392 case 11:
9393 astatic = 4;
9394 break;
9395 default:
9396 generate_exception(ctx, EXCP_RI);
9397 return;
9398 }
9399
9400 if (astatic > 0) {
9401 DECR_AND_STORE(7);
9402 if (astatic > 1) {
9403 DECR_AND_STORE(6);
9404 if (astatic > 2) {
9405 DECR_AND_STORE(5);
9406 if (astatic > 3) {
9407 DECR_AND_STORE(4);
9408 }
9409 }
9410 }
9411 }
9412#undef DECR_AND_STORE
9413
9414 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9415 tcg_temp_free(t0);
9416 tcg_temp_free(t1);
9417}
9418
9419static void gen_mips16_restore (DisasContext *ctx,
9420 int xsregs, int aregs,
9421 int do_ra, int do_s0, int do_s1,
9422 int framesize)
9423{
9424 int astatic;
9425 TCGv t0 = tcg_temp_new();
9426 TCGv t1 = tcg_temp_new();
9427
9428 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9429
5f68f5ae
AJ
9430#define DECR_AND_LOAD(reg) do { \
9431 tcg_gen_subi_tl(t0, t0, 4); \
9432 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9433 gen_store_gpr(t1, reg); \
364d4831
NF
9434 } while (0)
9435
9436 if (do_ra) {
9437 DECR_AND_LOAD(31);
9438 }
9439
9440 switch (xsregs) {
9441 case 7:
9442 DECR_AND_LOAD(30);
9443 /* Fall through */
9444 case 6:
9445 DECR_AND_LOAD(23);
9446 /* Fall through */
9447 case 5:
9448 DECR_AND_LOAD(22);
9449 /* Fall through */
9450 case 4:
9451 DECR_AND_LOAD(21);
9452 /* Fall through */
9453 case 3:
9454 DECR_AND_LOAD(20);
9455 /* Fall through */
9456 case 2:
9457 DECR_AND_LOAD(19);
9458 /* Fall through */
9459 case 1:
9460 DECR_AND_LOAD(18);
9461 }
9462
9463 if (do_s1) {
9464 DECR_AND_LOAD(17);
9465 }
9466 if (do_s0) {
9467 DECR_AND_LOAD(16);
9468 }
9469
9470 switch (aregs) {
9471 case 0:
9472 case 4:
9473 case 8:
9474 case 12:
9475 case 14:
9476 astatic = 0;
9477 break;
9478 case 1:
9479 case 5:
9480 case 9:
9481 case 13:
9482 astatic = 1;
9483 break;
9484 case 2:
9485 case 6:
9486 case 10:
9487 astatic = 2;
9488 break;
9489 case 3:
9490 case 7:
9491 astatic = 3;
9492 break;
9493 case 11:
9494 astatic = 4;
9495 break;
9496 default:
9497 generate_exception(ctx, EXCP_RI);
9498 return;
9499 }
9500
9501 if (astatic > 0) {
9502 DECR_AND_LOAD(7);
9503 if (astatic > 1) {
9504 DECR_AND_LOAD(6);
9505 if (astatic > 2) {
9506 DECR_AND_LOAD(5);
9507 if (astatic > 3) {
9508 DECR_AND_LOAD(4);
9509 }
9510 }
9511 }
9512 }
9513#undef DECR_AND_LOAD
9514
9515 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9516 tcg_temp_free(t0);
9517 tcg_temp_free(t1);
9518}
9519
9520static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9521 int is_64_bit, int extended)
9522{
9523 TCGv t0;
9524
9525 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9526 generate_exception(ctx, EXCP_RI);
9527 return;
9528 }
9529
9530 t0 = tcg_temp_new();
9531
9532 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9533 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9534 if (!is_64_bit) {
9535 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9536 }
9537
9538 tcg_temp_free(t0);
9539}
9540
9541#if defined(TARGET_MIPS64)
d75c135e 9542static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9543 int ry, int funct, int16_t offset,
9544 int extended)
9545{
9546 switch (funct) {
9547 case I64_LDSP:
9548 check_mips_64(ctx);
9549 offset = extended ? offset : offset << 3;
d75c135e 9550 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9551 break;
9552 case I64_SDSP:
9553 check_mips_64(ctx);
9554 offset = extended ? offset : offset << 3;
5c13fdfd 9555 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9556 break;
9557 case I64_SDRASP:
9558 check_mips_64(ctx);
9559 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9560 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9561 break;
9562 case I64_DADJSP:
9563 check_mips_64(ctx);
9564 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9565 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9566 break;
9567 case I64_LDPC:
9568 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9569 generate_exception(ctx, EXCP_RI);
9570 } else {
9571 offset = extended ? offset : offset << 3;
d75c135e 9572 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9573 }
9574 break;
9575 case I64_DADDIU5:
9576 check_mips_64(ctx);
9577 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9578 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9579 break;
9580 case I64_DADDIUPC:
9581 check_mips_64(ctx);
9582 offset = extended ? offset : offset << 2;
9583 gen_addiupc(ctx, ry, offset, 1, extended);
9584 break;
9585 case I64_DADDIUSP:
9586 check_mips_64(ctx);
9587 offset = extended ? offset : offset << 2;
d75c135e 9588 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9589 break;
9590 }
9591}
9592#endif
9593
240ce26a 9594static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 9595{
895c2d04 9596 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9597 int op, rx, ry, funct, sa;
9598 int16_t imm, offset;
9599
9600 ctx->opcode = (ctx->opcode << 16) | extend;
9601 op = (ctx->opcode >> 11) & 0x1f;
9602 sa = (ctx->opcode >> 22) & 0x1f;
9603 funct = (ctx->opcode >> 8) & 0x7;
9604 rx = xlat((ctx->opcode >> 8) & 0x7);
9605 ry = xlat((ctx->opcode >> 5) & 0x7);
9606 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9607 | ((ctx->opcode >> 21) & 0x3f) << 5
9608 | (ctx->opcode & 0x1f));
9609
9610 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9611 counterparts. */
9612 switch (op) {
9613 case M16_OPC_ADDIUSP:
d75c135e 9614 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9615 break;
9616 case M16_OPC_ADDIUPC:
9617 gen_addiupc(ctx, rx, imm, 0, 1);
9618 break;
9619 case M16_OPC_B:
9620 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9621 /* No delay slot, so just process as a normal instruction */
9622 break;
9623 case M16_OPC_BEQZ:
9624 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9625 /* No delay slot, so just process as a normal instruction */
9626 break;
9627 case M16_OPC_BNEQZ:
9628 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9629 /* No delay slot, so just process as a normal instruction */
9630 break;
9631 case M16_OPC_SHIFT:
9632 switch (ctx->opcode & 0x3) {
9633 case 0x0:
d75c135e 9634 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9635 break;
9636 case 0x1:
9637#if defined(TARGET_MIPS64)
9638 check_mips_64(ctx);
d75c135e 9639 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9640#else
9641 generate_exception(ctx, EXCP_RI);
9642#endif
9643 break;
9644 case 0x2:
d75c135e 9645 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9646 break;
9647 case 0x3:
d75c135e 9648 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9649 break;
9650 }
9651 break;
9652#if defined(TARGET_MIPS64)
9653 case M16_OPC_LD:
9654 check_mips_64(ctx);
d75c135e 9655 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9656 break;
9657#endif
9658 case M16_OPC_RRIA:
9659 imm = ctx->opcode & 0xf;
9660 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9661 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9662 imm = (int16_t) (imm << 1) >> 1;
9663 if ((ctx->opcode >> 4) & 0x1) {
9664#if defined(TARGET_MIPS64)
9665 check_mips_64(ctx);
d75c135e 9666 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9667#else
9668 generate_exception(ctx, EXCP_RI);
9669#endif
9670 } else {
d75c135e 9671 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9672 }
9673 break;
9674 case M16_OPC_ADDIU8:
d75c135e 9675 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9676 break;
9677 case M16_OPC_SLTI:
d75c135e 9678 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9679 break;
9680 case M16_OPC_SLTIU:
d75c135e 9681 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9682 break;
9683 case M16_OPC_I8:
9684 switch (funct) {
9685 case I8_BTEQZ:
9686 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9687 break;
9688 case I8_BTNEZ:
9689 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9690 break;
9691 case I8_SWRASP:
5c13fdfd 9692 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9693 break;
9694 case I8_ADJSP:
d75c135e 9695 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
9696 break;
9697 case I8_SVRS:
9698 {
9699 int xsregs = (ctx->opcode >> 24) & 0x7;
9700 int aregs = (ctx->opcode >> 16) & 0xf;
9701 int do_ra = (ctx->opcode >> 6) & 0x1;
9702 int do_s0 = (ctx->opcode >> 5) & 0x1;
9703 int do_s1 = (ctx->opcode >> 4) & 0x1;
9704 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9705 | (ctx->opcode & 0xf)) << 3;
9706
9707 if (ctx->opcode & (1 << 7)) {
9708 gen_mips16_save(ctx, xsregs, aregs,
9709 do_ra, do_s0, do_s1,
9710 framesize);
9711 } else {
9712 gen_mips16_restore(ctx, xsregs, aregs,
9713 do_ra, do_s0, do_s1,
9714 framesize);
9715 }
9716 }
9717 break;
9718 default:
9719 generate_exception(ctx, EXCP_RI);
9720 break;
9721 }
9722 break;
9723 case M16_OPC_LI:
9724 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9725 break;
9726 case M16_OPC_CMPI:
9727 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9728 break;
9729#if defined(TARGET_MIPS64)
9730 case M16_OPC_SD:
5c13fdfd 9731 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9732 break;
9733#endif
9734 case M16_OPC_LB:
d75c135e 9735 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9736 break;
9737 case M16_OPC_LH:
d75c135e 9738 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9739 break;
9740 case M16_OPC_LWSP:
d75c135e 9741 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9742 break;
9743 case M16_OPC_LW:
d75c135e 9744 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9745 break;
9746 case M16_OPC_LBU:
d75c135e 9747 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9748 break;
9749 case M16_OPC_LHU:
d75c135e 9750 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9751 break;
9752 case M16_OPC_LWPC:
d75c135e 9753 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9754 break;
9755#if defined(TARGET_MIPS64)
9756 case M16_OPC_LWU:
d75c135e 9757 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9758 break;
9759#endif
9760 case M16_OPC_SB:
5c13fdfd 9761 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9762 break;
9763 case M16_OPC_SH:
5c13fdfd 9764 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9765 break;
9766 case M16_OPC_SWSP:
5c13fdfd 9767 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9768 break;
9769 case M16_OPC_SW:
5c13fdfd 9770 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9771 break;
9772#if defined(TARGET_MIPS64)
9773 case M16_OPC_I64:
d75c135e 9774 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
9775 break;
9776#endif
9777 default:
9778 generate_exception(ctx, EXCP_RI);
9779 break;
9780 }
9781
9782 return 4;
9783}
9784
240ce26a 9785static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
9786{
9787 int rx, ry;
9788 int sa;
9789 int op, cnvt_op, op1, offset;
9790 int funct;
9791 int n_bytes;
9792
9793 op = (ctx->opcode >> 11) & 0x1f;
9794 sa = (ctx->opcode >> 2) & 0x7;
9795 sa = sa == 0 ? 8 : sa;
9796 rx = xlat((ctx->opcode >> 8) & 0x7);
9797 cnvt_op = (ctx->opcode >> 5) & 0x7;
9798 ry = xlat((ctx->opcode >> 5) & 0x7);
9799 op1 = offset = ctx->opcode & 0x1f;
9800
9801 n_bytes = 2;
9802
9803 switch (op) {
9804 case M16_OPC_ADDIUSP:
9805 {
9806 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9807
d75c135e 9808 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9809 }
9810 break;
9811 case M16_OPC_ADDIUPC:
9812 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9813 break;
9814 case M16_OPC_B:
9815 offset = (ctx->opcode & 0x7ff) << 1;
9816 offset = (int16_t)(offset << 4) >> 4;
9817 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9818 /* No delay slot, so just process as a normal instruction */
9819 break;
9820 case M16_OPC_JAL:
895c2d04 9821 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9822 offset = (((ctx->opcode & 0x1f) << 21)
9823 | ((ctx->opcode >> 5) & 0x1f) << 16
9824 | offset) << 2;
620e48f6 9825 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9826 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9827 n_bytes = 4;
364d4831
NF
9828 break;
9829 case M16_OPC_BEQZ:
9830 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9831 /* No delay slot, so just process as a normal instruction */
9832 break;
9833 case M16_OPC_BNEQZ:
9834 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9835 /* No delay slot, so just process as a normal instruction */
9836 break;
9837 case M16_OPC_SHIFT:
9838 switch (ctx->opcode & 0x3) {
9839 case 0x0:
d75c135e 9840 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9841 break;
9842 case 0x1:
9843#if defined(TARGET_MIPS64)
9844 check_mips_64(ctx);
d75c135e 9845 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9846#else
9847 generate_exception(ctx, EXCP_RI);
9848#endif
9849 break;
9850 case 0x2:
d75c135e 9851 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9852 break;
9853 case 0x3:
d75c135e 9854 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9855 break;
9856 }
9857 break;
9858#if defined(TARGET_MIPS64)
9859 case M16_OPC_LD:
9860 check_mips_64(ctx);
d75c135e 9861 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9862 break;
9863#endif
9864 case M16_OPC_RRIA:
9865 {
9866 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9867
9868 if ((ctx->opcode >> 4) & 1) {
9869#if defined(TARGET_MIPS64)
9870 check_mips_64(ctx);
d75c135e 9871 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9872#else
9873 generate_exception(ctx, EXCP_RI);
9874#endif
9875 } else {
d75c135e 9876 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9877 }
9878 }
9879 break;
9880 case M16_OPC_ADDIU8:
9881 {
9882 int16_t imm = (int8_t) ctx->opcode;
9883
d75c135e 9884 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9885 }
9886 break;
9887 case M16_OPC_SLTI:
9888 {
9889 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9890 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9891 }
9892 break;
9893 case M16_OPC_SLTIU:
9894 {
9895 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9896 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9897 }
9898 break;
9899 case M16_OPC_I8:
9900 {
9901 int reg32;
9902
9903 funct = (ctx->opcode >> 8) & 0x7;
9904 switch (funct) {
9905 case I8_BTEQZ:
9906 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9907 ((int8_t)ctx->opcode) << 1);
9908 break;
9909 case I8_BTNEZ:
9910 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9911 ((int8_t)ctx->opcode) << 1);
9912 break;
9913 case I8_SWRASP:
5c13fdfd 9914 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9915 break;
9916 case I8_ADJSP:
d75c135e 9917 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
9918 ((int8_t)ctx->opcode) << 3);
9919 break;
9920 case I8_SVRS:
9921 {
9922 int do_ra = ctx->opcode & (1 << 6);
9923 int do_s0 = ctx->opcode & (1 << 5);
9924 int do_s1 = ctx->opcode & (1 << 4);
9925 int framesize = ctx->opcode & 0xf;
9926
9927 if (framesize == 0) {
9928 framesize = 128;
9929 } else {
9930 framesize = framesize << 3;
9931 }
9932
9933 if (ctx->opcode & (1 << 7)) {
9934 gen_mips16_save(ctx, 0, 0,
9935 do_ra, do_s0, do_s1, framesize);
9936 } else {
9937 gen_mips16_restore(ctx, 0, 0,
9938 do_ra, do_s0, do_s1, framesize);
9939 }
9940 }
9941 break;
9942 case I8_MOV32R:
9943 {
9944 int rz = xlat(ctx->opcode & 0x7);
9945
9946 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9947 ((ctx->opcode >> 5) & 0x7);
d75c135e 9948 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
9949 }
9950 break;
9951 case I8_MOVR32:
9952 reg32 = ctx->opcode & 0x1f;
d75c135e 9953 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
9954 break;
9955 default:
9956 generate_exception(ctx, EXCP_RI);
9957 break;
9958 }
9959 }
9960 break;
9961 case M16_OPC_LI:
9962 {
9963 int16_t imm = (uint8_t) ctx->opcode;
9964
d75c135e 9965 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
9966 }
9967 break;
9968 case M16_OPC_CMPI:
9969 {
9970 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9971 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
9972 }
9973 break;
9974#if defined(TARGET_MIPS64)
9975 case M16_OPC_SD:
9976 check_mips_64(ctx);
5c13fdfd 9977 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
9978 break;
9979#endif
9980 case M16_OPC_LB:
d75c135e 9981 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9982 break;
9983 case M16_OPC_LH:
d75c135e 9984 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
9985 break;
9986 case M16_OPC_LWSP:
d75c135e 9987 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
9988 break;
9989 case M16_OPC_LW:
d75c135e 9990 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
9991 break;
9992 case M16_OPC_LBU:
d75c135e 9993 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9994 break;
9995 case M16_OPC_LHU:
d75c135e 9996 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
9997 break;
9998 case M16_OPC_LWPC:
d75c135e 9999 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10000 break;
10001#if defined (TARGET_MIPS64)
10002 case M16_OPC_LWU:
10003 check_mips_64(ctx);
d75c135e 10004 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10005 break;
10006#endif
10007 case M16_OPC_SB:
5c13fdfd 10008 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10009 break;
10010 case M16_OPC_SH:
5c13fdfd 10011 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10012 break;
10013 case M16_OPC_SWSP:
5c13fdfd 10014 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10015 break;
10016 case M16_OPC_SW:
5c13fdfd 10017 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10018 break;
10019 case M16_OPC_RRR:
10020 {
10021 int rz = xlat((ctx->opcode >> 2) & 0x7);
10022 int mips32_op;
10023
10024 switch (ctx->opcode & 0x3) {
10025 case RRR_ADDU:
10026 mips32_op = OPC_ADDU;
10027 break;
10028 case RRR_SUBU:
10029 mips32_op = OPC_SUBU;
10030 break;
10031#if defined(TARGET_MIPS64)
10032 case RRR_DADDU:
10033 mips32_op = OPC_DADDU;
10034 check_mips_64(ctx);
10035 break;
10036 case RRR_DSUBU:
10037 mips32_op = OPC_DSUBU;
10038 check_mips_64(ctx);
10039 break;
10040#endif
10041 default:
10042 generate_exception(ctx, EXCP_RI);
10043 goto done;
10044 }
10045
d75c135e 10046 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10047 done:
10048 ;
10049 }
10050 break;
10051 case M16_OPC_RR:
10052 switch (op1) {
10053 case RR_JR:
10054 {
10055 int nd = (ctx->opcode >> 7) & 0x1;
10056 int link = (ctx->opcode >> 6) & 0x1;
10057 int ra = (ctx->opcode >> 5) & 0x1;
10058
10059 if (link) {
620e48f6 10060 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10061 } else {
10062 op = OPC_JR;
10063 }
10064
10065 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
364d4831
NF
10066 }
10067 break;
10068 case RR_SDBBP:
10069 /* XXX: not clear which exception should be raised
10070 * when in debug mode...
10071 */
d75c135e 10072 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10073 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10074 generate_exception(ctx, EXCP_DBp);
10075 } else {
10076 generate_exception(ctx, EXCP_DBp);
10077 }
10078 break;
10079 case RR_SLT:
d75c135e 10080 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10081 break;
10082 case RR_SLTU:
d75c135e 10083 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10084 break;
10085 case RR_BREAK:
10086 generate_exception(ctx, EXCP_BREAK);
10087 break;
10088 case RR_SLLV:
d75c135e 10089 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10090 break;
10091 case RR_SRLV:
d75c135e 10092 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10093 break;
10094 case RR_SRAV:
d75c135e 10095 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10096 break;
10097#if defined (TARGET_MIPS64)
10098 case RR_DSRL:
10099 check_mips_64(ctx);
d75c135e 10100 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10101 break;
10102#endif
10103 case RR_CMP:
d75c135e 10104 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10105 break;
10106 case RR_NEG:
d75c135e 10107 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10108 break;
10109 case RR_AND:
d75c135e 10110 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10111 break;
10112 case RR_OR:
d75c135e 10113 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10114 break;
10115 case RR_XOR:
d75c135e 10116 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10117 break;
10118 case RR_NOT:
d75c135e 10119 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10120 break;
10121 case RR_MFHI:
26135ead 10122 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
10123 break;
10124 case RR_CNVT:
10125 switch (cnvt_op) {
10126 case RR_RY_CNVT_ZEB:
10127 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10128 break;
10129 case RR_RY_CNVT_ZEH:
10130 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10131 break;
10132 case RR_RY_CNVT_SEB:
10133 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10134 break;
10135 case RR_RY_CNVT_SEH:
10136 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10137 break;
10138#if defined (TARGET_MIPS64)
10139 case RR_RY_CNVT_ZEW:
10140 check_mips_64(ctx);
10141 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10142 break;
10143 case RR_RY_CNVT_SEW:
10144 check_mips_64(ctx);
10145 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10146 break;
10147#endif
10148 default:
10149 generate_exception(ctx, EXCP_RI);
10150 break;
10151 }
10152 break;
10153 case RR_MFLO:
26135ead 10154 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
10155 break;
10156#if defined (TARGET_MIPS64)
10157 case RR_DSRA:
10158 check_mips_64(ctx);
d75c135e 10159 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10160 break;
10161 case RR_DSLLV:
10162 check_mips_64(ctx);
d75c135e 10163 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10164 break;
10165 case RR_DSRLV:
10166 check_mips_64(ctx);
d75c135e 10167 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10168 break;
10169 case RR_DSRAV:
10170 check_mips_64(ctx);
d75c135e 10171 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10172 break;
10173#endif
10174 case RR_MULT:
26135ead 10175 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
10176 break;
10177 case RR_MULTU:
26135ead 10178 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
10179 break;
10180 case RR_DIV:
26135ead 10181 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
10182 break;
10183 case RR_DIVU:
26135ead 10184 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
10185 break;
10186#if defined (TARGET_MIPS64)
10187 case RR_DMULT:
10188 check_mips_64(ctx);
26135ead 10189 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
10190 break;
10191 case RR_DMULTU:
10192 check_mips_64(ctx);
26135ead 10193 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
10194 break;
10195 case RR_DDIV:
10196 check_mips_64(ctx);
26135ead 10197 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
10198 break;
10199 case RR_DDIVU:
10200 check_mips_64(ctx);
26135ead 10201 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
10202 break;
10203#endif
10204 default:
10205 generate_exception(ctx, EXCP_RI);
10206 break;
10207 }
10208 break;
10209 case M16_OPC_EXTEND:
240ce26a 10210 decode_extended_mips16_opc(env, ctx);
364d4831
NF
10211 n_bytes = 4;
10212 break;
10213#if defined(TARGET_MIPS64)
10214 case M16_OPC_I64:
10215 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10216 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10217 break;
10218#endif
10219 default:
10220 generate_exception(ctx, EXCP_RI);
10221 break;
10222 }
10223
10224 return n_bytes;
10225}
10226
211da992 10227/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10228
211da992
CWR
10229/*
10230 * microMIPS32/microMIPS64 major opcodes
10231 *
10232 * 1. MIPS Architecture for Programmers Volume II-B:
10233 * The microMIPS32 Instruction Set (Revision 3.05)
10234 *
10235 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10236 *
10237 * 2. MIPS Architecture For Programmers Volume II-A:
10238 * The MIPS64 Instruction Set (Revision 3.51)
10239 */
6af0bf9c 10240
3c824109
NF
10241enum {
10242 POOL32A = 0x00,
10243 POOL16A = 0x01,
10244 LBU16 = 0x02,
10245 MOVE16 = 0x03,
10246 ADDI32 = 0x04,
10247 LBU32 = 0x05,
10248 SB32 = 0x06,
10249 LB32 = 0x07,
10250
10251 POOL32B = 0x08,
10252 POOL16B = 0x09,
10253 LHU16 = 0x0a,
10254 ANDI16 = 0x0b,
10255 ADDIU32 = 0x0c,
10256 LHU32 = 0x0d,
10257 SH32 = 0x0e,
10258 LH32 = 0x0f,
10259
10260 POOL32I = 0x10,
10261 POOL16C = 0x11,
10262 LWSP16 = 0x12,
10263 POOL16D = 0x13,
10264 ORI32 = 0x14,
10265 POOL32F = 0x15,
211da992
CWR
10266 POOL32S = 0x16, /* MIPS64 */
10267 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10268
211da992 10269 /* 0x1f is reserved */
3c824109
NF
10270 POOL32C = 0x18,
10271 LWGP16 = 0x19,
10272 LW16 = 0x1a,
10273 POOL16E = 0x1b,
10274 XORI32 = 0x1c,
10275 JALS32 = 0x1d,
10276 ADDIUPC = 0x1e,
3c824109
NF
10277
10278 /* 0x20 is reserved */
10279 RES_20 = 0x20,
10280 POOL16F = 0x21,
10281 SB16 = 0x22,
10282 BEQZ16 = 0x23,
10283 SLTI32 = 0x24,
10284 BEQ32 = 0x25,
10285 SWC132 = 0x26,
10286 LWC132 = 0x27,
10287
10288 /* 0x28 and 0x29 are reserved */
10289 RES_28 = 0x28,
10290 RES_29 = 0x29,
10291 SH16 = 0x2a,
10292 BNEZ16 = 0x2b,
10293 SLTIU32 = 0x2c,
10294 BNE32 = 0x2d,
10295 SDC132 = 0x2e,
10296 LDC132 = 0x2f,
10297
10298 /* 0x30 and 0x31 are reserved */
10299 RES_30 = 0x30,
10300 RES_31 = 0x31,
10301 SWSP16 = 0x32,
10302 B16 = 0x33,
10303 ANDI32 = 0x34,
10304 J32 = 0x35,
211da992
CWR
10305 SD32 = 0x36, /* MIPS64 */
10306 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10307
10308 /* 0x38 and 0x39 are reserved */
10309 RES_38 = 0x38,
10310 RES_39 = 0x39,
10311 SW16 = 0x3a,
10312 LI16 = 0x3b,
10313 JALX32 = 0x3c,
10314 JAL32 = 0x3d,
10315 SW32 = 0x3e,
10316 LW32 = 0x3f
10317};
10318
10319/* POOL32A encoding of minor opcode field */
10320
10321enum {
10322 /* These opcodes are distinguished only by bits 9..6; those bits are
10323 * what are recorded below. */
10324 SLL32 = 0x0,
10325 SRL32 = 0x1,
10326 SRA = 0x2,
10327 ROTR = 0x3,
10328
10329 SLLV = 0x0,
10330 SRLV = 0x1,
10331 SRAV = 0x2,
10332 ROTRV = 0x3,
10333 ADD = 0x4,
10334 ADDU32 = 0x5,
10335 SUB = 0x6,
10336 SUBU32 = 0x7,
10337 MUL = 0x8,
10338 AND = 0x9,
10339 OR32 = 0xa,
10340 NOR = 0xb,
10341 XOR32 = 0xc,
10342 SLT = 0xd,
10343 SLTU = 0xe,
10344
10345 MOVN = 0x0,
10346 MOVZ = 0x1,
10347 LWXS = 0x4,
10348
10349 /* The following can be distinguished by their lower 6 bits. */
10350 INS = 0x0c,
10351 EXT = 0x2c,
10352 POOL32AXF = 0x3c
10353};
10354
10355/* POOL32AXF encoding of minor opcode field extension */
10356
d132c79f
CWR
10357/*
10358 * 1. MIPS Architecture for Programmers Volume II-B:
10359 * The microMIPS32 Instruction Set (Revision 3.05)
10360 *
10361 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10362 *
10363 * 2. MIPS Architecture for Programmers VolumeIV-e:
10364 * The MIPS DSP Application-Specific Extension
10365 * to the microMIPS32 Architecture (Revision 2.34)
10366 *
10367 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10368 */
10369
3c824109
NF
10370enum {
10371 /* bits 11..6 */
10372 TEQ = 0x00,
10373 TGE = 0x08,
10374 TGEU = 0x10,
10375 TLT = 0x20,
10376 TLTU = 0x28,
10377 TNE = 0x30,
10378
10379 MFC0 = 0x03,
10380 MTC0 = 0x0b,
10381
d132c79f
CWR
10382 /* begin of microMIPS32 DSP */
10383
3c824109
NF
10384 /* bits 13..12 for 0x01 */
10385 MFHI_ACC = 0x0,
10386 MFLO_ACC = 0x1,
10387 MTHI_ACC = 0x2,
10388 MTLO_ACC = 0x3,
10389
10390 /* bits 13..12 for 0x2a */
10391 MADD_ACC = 0x0,
10392 MADDU_ACC = 0x1,
10393 MSUB_ACC = 0x2,
10394 MSUBU_ACC = 0x3,
10395
10396 /* bits 13..12 for 0x32 */
10397 MULT_ACC = 0x0,
6801038b 10398 MULTU_ACC = 0x1,
3c824109 10399
d132c79f
CWR
10400 /* end of microMIPS32 DSP */
10401
3c824109
NF
10402 /* bits 15..12 for 0x2c */
10403 SEB = 0x2,
10404 SEH = 0x3,
10405 CLO = 0x4,
10406 CLZ = 0x5,
10407 RDHWR = 0x6,
10408 WSBH = 0x7,
10409 MULT = 0x8,
10410 MULTU = 0x9,
10411 DIV = 0xa,
10412 DIVU = 0xb,
10413 MADD = 0xc,
10414 MADDU = 0xd,
10415 MSUB = 0xe,
10416 MSUBU = 0xf,
10417
10418 /* bits 15..12 for 0x34 */
10419 MFC2 = 0x4,
10420 MTC2 = 0x5,
10421 MFHC2 = 0x8,
10422 MTHC2 = 0x9,
10423 CFC2 = 0xc,
10424 CTC2 = 0xd,
10425
10426 /* bits 15..12 for 0x3c */
10427 JALR = 0x0,
10428 JR = 0x0, /* alias */
10429 JALR_HB = 0x1,
10430 JALRS = 0x4,
10431 JALRS_HB = 0x5,
10432
10433 /* bits 15..12 for 0x05 */
10434 RDPGPR = 0xe,
10435 WRPGPR = 0xf,
10436
10437 /* bits 15..12 for 0x0d */
10438 TLBP = 0x0,
10439 TLBR = 0x1,
10440 TLBWI = 0x2,
10441 TLBWR = 0x3,
10442 WAIT = 0x9,
10443 IRET = 0xd,
10444 DERET = 0xe,
10445 ERET = 0xf,
10446
10447 /* bits 15..12 for 0x15 */
10448 DMT = 0x0,
10449 DVPE = 0x1,
10450 EMT = 0x2,
10451 EVPE = 0x3,
10452
10453 /* bits 15..12 for 0x1d */
10454 DI = 0x4,
10455 EI = 0x5,
10456
10457 /* bits 15..12 for 0x2d */
10458 SYNC = 0x6,
10459 SYSCALL = 0x8,
10460 SDBBP = 0xd,
10461
10462 /* bits 15..12 for 0x35 */
10463 MFHI32 = 0x0,
10464 MFLO32 = 0x1,
10465 MTHI32 = 0x2,
10466 MTLO32 = 0x3,
10467};
10468
10469/* POOL32B encoding of minor opcode field (bits 15..12) */
10470
10471enum {
10472 LWC2 = 0x0,
10473 LWP = 0x1,
10474 LDP = 0x4,
10475 LWM32 = 0x5,
10476 CACHE = 0x6,
10477 LDM = 0x7,
10478 SWC2 = 0x8,
10479 SWP = 0x9,
10480 SDP = 0xc,
10481 SWM32 = 0xd,
10482 SDM = 0xf
10483};
10484
10485/* POOL32C encoding of minor opcode field (bits 15..12) */
10486
10487enum {
10488 LWL = 0x0,
10489 SWL = 0x8,
10490 LWR = 0x1,
10491 SWR = 0x9,
10492 PREF = 0x2,
10493 /* 0xa is reserved */
10494 LL = 0x3,
10495 SC = 0xb,
10496 LDL = 0x4,
10497 SDL = 0xc,
10498 LDR = 0x5,
10499 SDR = 0xd,
10500 /* 0x6 is reserved */
10501 LWU = 0xe,
10502 LLD = 0x7,
10503 SCD = 0xf
10504};
10505
10506/* POOL32F encoding of minor opcode field (bits 5..0) */
10507
10508enum {
10509 /* These are the bit 7..6 values */
10510 ADD_FMT = 0x0,
10511 MOVN_FMT = 0x0,
10512
10513 SUB_FMT = 0x1,
10514 MOVZ_FMT = 0x1,
10515
10516 MUL_FMT = 0x2,
10517
10518 DIV_FMT = 0x3,
10519
10520 /* These are the bit 8..6 values */
10521 RSQRT2_FMT = 0x0,
10522 MOVF_FMT = 0x0,
10523
10524 LWXC1 = 0x1,
10525 MOVT_FMT = 0x1,
10526
10527 PLL_PS = 0x2,
10528 SWXC1 = 0x2,
10529
10530 PLU_PS = 0x3,
10531 LDXC1 = 0x3,
10532
10533 PUL_PS = 0x4,
10534 SDXC1 = 0x4,
10535 RECIP2_FMT = 0x4,
10536
10537 PUU_PS = 0x5,
10538 LUXC1 = 0x5,
10539
10540 CVT_PS_S = 0x6,
10541 SUXC1 = 0x6,
10542 ADDR_PS = 0x6,
10543 PREFX = 0x6,
10544
10545 MULR_PS = 0x7,
10546
10547 MADD_S = 0x01,
10548 MADD_D = 0x09,
10549 MADD_PS = 0x11,
10550 ALNV_PS = 0x19,
10551 MSUB_S = 0x21,
10552 MSUB_D = 0x29,
10553 MSUB_PS = 0x31,
10554
10555 NMADD_S = 0x02,
10556 NMADD_D = 0x0a,
10557 NMADD_PS = 0x12,
10558 NMSUB_S = 0x22,
10559 NMSUB_D = 0x2a,
10560 NMSUB_PS = 0x32,
10561
10562 POOL32FXF = 0x3b,
10563
10564 CABS_COND_FMT = 0x1c, /* MIPS3D */
10565 C_COND_FMT = 0x3c
10566};
10567
10568/* POOL32Fxf encoding of minor opcode extension field */
10569
10570enum {
10571 CVT_L = 0x04,
10572 RSQRT_FMT = 0x08,
10573 FLOOR_L = 0x0c,
10574 CVT_PW_PS = 0x1c,
10575 CVT_W = 0x24,
10576 SQRT_FMT = 0x28,
10577 FLOOR_W = 0x2c,
10578 CVT_PS_PW = 0x3c,
10579 CFC1 = 0x40,
10580 RECIP_FMT = 0x48,
10581 CEIL_L = 0x4c,
10582 CTC1 = 0x60,
10583 CEIL_W = 0x6c,
10584 MFC1 = 0x80,
10585 CVT_S_PL = 0x84,
10586 TRUNC_L = 0x8c,
10587 MTC1 = 0xa0,
10588 CVT_S_PU = 0xa4,
10589 TRUNC_W = 0xac,
10590 MFHC1 = 0xc0,
10591 ROUND_L = 0xcc,
10592 MTHC1 = 0xe0,
10593 ROUND_W = 0xec,
10594
10595 MOV_FMT = 0x01,
10596 MOVF = 0x05,
10597 ABS_FMT = 0x0d,
10598 RSQRT1_FMT = 0x1d,
10599 MOVT = 0x25,
10600 NEG_FMT = 0x2d,
10601 CVT_D = 0x4d,
10602 RECIP1_FMT = 0x5d,
10603 CVT_S = 0x6d
10604};
10605
10606/* POOL32I encoding of minor opcode field (bits 25..21) */
10607
10608enum {
10609 BLTZ = 0x00,
10610 BLTZAL = 0x01,
10611 BGEZ = 0x02,
10612 BGEZAL = 0x03,
10613 BLEZ = 0x04,
10614 BNEZC = 0x05,
10615 BGTZ = 0x06,
10616 BEQZC = 0x07,
10617 TLTI = 0x08,
10618 TGEI = 0x09,
10619 TLTIU = 0x0a,
10620 TGEIU = 0x0b,
10621 TNEI = 0x0c,
10622 LUI = 0x0d,
10623 TEQI = 0x0e,
10624 SYNCI = 0x10,
10625 BLTZALS = 0x11,
10626 BGEZALS = 0x13,
10627 BC2F = 0x14,
10628 BC2T = 0x15,
10629 BPOSGE64 = 0x1a,
10630 BPOSGE32 = 0x1b,
10631 /* These overlap and are distinguished by bit16 of the instruction */
10632 BC1F = 0x1c,
10633 BC1T = 0x1d,
10634 BC1ANY2F = 0x1c,
10635 BC1ANY2T = 0x1d,
10636 BC1ANY4F = 0x1e,
10637 BC1ANY4T = 0x1f
10638};
10639
10640/* POOL16A encoding of minor opcode field */
10641
10642enum {
10643 ADDU16 = 0x0,
10644 SUBU16 = 0x1
10645};
10646
10647/* POOL16B encoding of minor opcode field */
10648
10649enum {
10650 SLL16 = 0x0,
10651 SRL16 = 0x1
10652};
10653
10654/* POOL16C encoding of minor opcode field */
10655
10656enum {
10657 NOT16 = 0x00,
10658 XOR16 = 0x04,
10659 AND16 = 0x08,
10660 OR16 = 0x0c,
10661 LWM16 = 0x10,
10662 SWM16 = 0x14,
10663 JR16 = 0x18,
10664 JRC16 = 0x1a,
10665 JALR16 = 0x1c,
10666 JALR16S = 0x1e,
10667 MFHI16 = 0x20,
10668 MFLO16 = 0x24,
10669 BREAK16 = 0x28,
10670 SDBBP16 = 0x2c,
10671 JRADDIUSP = 0x30
10672};
10673
10674/* POOL16D encoding of minor opcode field */
10675
10676enum {
10677 ADDIUS5 = 0x0,
10678 ADDIUSP = 0x1
10679};
10680
10681/* POOL16E encoding of minor opcode field */
10682
10683enum {
10684 ADDIUR2 = 0x0,
10685 ADDIUR1SP = 0x1
10686};
10687
10688static int mmreg (int r)
10689{
10690 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10691
10692 return map[r];
10693}
10694
10695/* Used for 16-bit store instructions. */
10696static int mmreg2 (int r)
10697{
10698 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10699
10700 return map[r];
10701}
10702
10703#define uMIPS_RD(op) ((op >> 7) & 0x7)
10704#define uMIPS_RS(op) ((op >> 4) & 0x7)
10705#define uMIPS_RS2(op) uMIPS_RS(op)
10706#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10707#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10708#define uMIPS_RS5(op) (op & 0x1f)
10709
10710/* Signed immediate */
10711#define SIMM(op, start, width) \
10712 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10713 << (32-width)) \
10714 >> (32-width))
10715/* Zero-extended immediate */
10716#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10717
d75c135e 10718static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
10719{
10720 int rd = mmreg(uMIPS_RD(ctx->opcode));
10721
d75c135e 10722 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
10723}
10724
d75c135e 10725static void gen_addiur2(DisasContext *ctx)
3c824109
NF
10726{
10727 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10728 int rd = mmreg(uMIPS_RD(ctx->opcode));
10729 int rs = mmreg(uMIPS_RS(ctx->opcode));
10730
d75c135e 10731 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
10732}
10733
d75c135e 10734static void gen_addiusp(DisasContext *ctx)
3c824109
NF
10735{
10736 int encoded = ZIMM(ctx->opcode, 1, 9);
10737 int decoded;
10738
10739 if (encoded <= 1) {
10740 decoded = 256 + encoded;
10741 } else if (encoded <= 255) {
10742 decoded = encoded;
10743 } else if (encoded <= 509) {
10744 decoded = encoded - 512;
10745 } else {
10746 decoded = encoded - 768;
10747 }
10748
d75c135e 10749 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
10750}
10751
d75c135e 10752static void gen_addius5(DisasContext *ctx)
3c824109
NF
10753{
10754 int imm = SIMM(ctx->opcode, 1, 4);
10755 int rd = (ctx->opcode >> 5) & 0x1f;
10756
d75c135e 10757 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
10758}
10759
d75c135e 10760static void gen_andi16(DisasContext *ctx)
3c824109
NF
10761{
10762 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10763 31, 32, 63, 64, 255, 32768, 65535 };
10764 int rd = mmreg(uMIPS_RD(ctx->opcode));
10765 int rs = mmreg(uMIPS_RS(ctx->opcode));
10766 int encoded = ZIMM(ctx->opcode, 0, 4);
10767
d75c135e 10768 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10769}
10770
10771static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10772 int base, int16_t offset)
10773{
e1050a76 10774 const char *opn = "ldst_multiple";
3c824109
NF
10775 TCGv t0, t1;
10776 TCGv_i32 t2;
10777
10778 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10779 generate_exception(ctx, EXCP_RI);
10780 return;
10781 }
10782
10783 t0 = tcg_temp_new();
10784
10785 gen_base_offset_addr(ctx, t0, base, offset);
10786
10787 t1 = tcg_const_tl(reglist);
10788 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10789
3c824109
NF
10790 save_cpu_state(ctx, 1);
10791 switch (opc) {
10792 case LWM32:
895c2d04 10793 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10794 opn = "lwm";
3c824109
NF
10795 break;
10796 case SWM32:
895c2d04 10797 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10798 opn = "swm";
3c824109
NF
10799 break;
10800#ifdef TARGET_MIPS64
10801 case LDM:
895c2d04 10802 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10803 opn = "ldm";
3c824109
NF
10804 break;
10805 case SDM:
895c2d04 10806 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10807 opn = "sdm";
3c824109 10808 break;
6af0bf9c 10809#endif
3c824109 10810 }
e1050a76 10811 (void)opn;
3c824109
NF
10812 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10813 tcg_temp_free(t0);
33087598 10814 tcg_temp_free(t1);
3c824109
NF
10815 tcg_temp_free_i32(t2);
10816}
6af0bf9c 10817
3c824109 10818
240ce26a 10819static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 10820{
3c824109
NF
10821 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10822 int rs = mmreg(ctx->opcode & 0x7);
10823 int opc;
6af0bf9c 10824
3c824109
NF
10825 switch (((ctx->opcode) >> 4) & 0x3f) {
10826 case NOT16 + 0:
10827 case NOT16 + 1:
10828 case NOT16 + 2:
10829 case NOT16 + 3:
d75c135e 10830 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10831 break;
10832 case XOR16 + 0:
10833 case XOR16 + 1:
10834 case XOR16 + 2:
10835 case XOR16 + 3:
d75c135e 10836 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10837 break;
10838 case AND16 + 0:
10839 case AND16 + 1:
10840 case AND16 + 2:
10841 case AND16 + 3:
d75c135e 10842 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10843 break;
10844 case OR16 + 0:
10845 case OR16 + 1:
10846 case OR16 + 2:
10847 case OR16 + 3:
d75c135e 10848 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10849 break;
10850 case LWM16 + 0:
10851 case LWM16 + 1:
10852 case LWM16 + 2:
10853 case LWM16 + 3:
10854 {
10855 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10856 int offset = ZIMM(ctx->opcode, 0, 4);
10857
10858 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10859 29, offset << 2);
10860 }
10861 break;
10862 case SWM16 + 0:
10863 case SWM16 + 1:
10864 case SWM16 + 2:
10865 case SWM16 + 3:
10866 {
10867 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10868 int offset = ZIMM(ctx->opcode, 0, 4);
10869
10870 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10871 29, offset << 2);
10872 }
10873 break;
10874 case JR16 + 0:
10875 case JR16 + 1:
10876 {
10877 int reg = ctx->opcode & 0x1f;
10878
10879 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10880 }
3c824109
NF
10881 break;
10882 case JRC16 + 0:
10883 case JRC16 + 1:
10884 {
10885 int reg = ctx->opcode & 0x1f;
10886
10887 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10888 /* Let normal delay slot handling in our caller take us
10889 to the branch target. */
10890 }
10891 break;
10892 case JALR16 + 0:
10893 case JALR16 + 1:
10894 opc = OPC_JALR;
10895 goto do_jalr;
10896 case JALR16S + 0:
10897 case JALR16S + 1:
10898 opc = OPC_JALRS;
10899 do_jalr:
10900 {
10901 int reg = ctx->opcode & 0x1f;
10902
10903 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10904 }
3c824109
NF
10905 break;
10906 case MFHI16 + 0:
10907 case MFHI16 + 1:
26135ead 10908 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
10909 break;
10910 case MFLO16 + 0:
10911 case MFLO16 + 1:
26135ead 10912 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
10913 break;
10914 case BREAK16:
10915 generate_exception(ctx, EXCP_BREAK);
10916 break;
10917 case SDBBP16:
10918 /* XXX: not clear which exception should be raised
10919 * when in debug mode...
10920 */
d75c135e 10921 check_insn(ctx, ISA_MIPS32);
3c824109
NF
10922 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10923 generate_exception(ctx, EXCP_DBp);
10924 } else {
10925 generate_exception(ctx, EXCP_DBp);
10926 }
10927 break;
10928 case JRADDIUSP + 0:
10929 case JRADDIUSP + 1:
10930 {
10931 int imm = ZIMM(ctx->opcode, 0, 5);
10932
10933 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 10934 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
10935 /* Let normal delay slot handling in our caller take us
10936 to the branch target. */
10937 }
10938 break;
10939 default:
10940 generate_exception(ctx, EXCP_RI);
10941 break;
10942 }
10943}
10944
10945static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10946{
10947 TCGv t0 = tcg_temp_new();
10948 TCGv t1 = tcg_temp_new();
10949
10950 gen_load_gpr(t0, base);
10951
10952 if (index != 0) {
10953 gen_load_gpr(t1, index);
10954 tcg_gen_shli_tl(t1, t1, 2);
10955 gen_op_addr_add(ctx, t0, t1, t0);
10956 }
10957
5f68f5ae 10958 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
10959 gen_store_gpr(t1, rd);
10960
10961 tcg_temp_free(t0);
10962 tcg_temp_free(t1);
10963}
10964
10965static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10966 int base, int16_t offset)
10967{
10968 const char *opn = "ldst_pair";
10969 TCGv t0, t1;
10970
36c6711b 10971 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 10972 generate_exception(ctx, EXCP_RI);
d796321b
FB
10973 return;
10974 }
10975
3c824109
NF
10976 t0 = tcg_temp_new();
10977 t1 = tcg_temp_new();
8e9ade68 10978
3c824109
NF
10979 gen_base_offset_addr(ctx, t0, base, offset);
10980
10981 switch (opc) {
10982 case LWP:
36c6711b
EJ
10983 if (rd == base) {
10984 generate_exception(ctx, EXCP_RI);
10985 return;
10986 }
5f68f5ae 10987 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
10988 gen_store_gpr(t1, rd);
10989 tcg_gen_movi_tl(t1, 4);
10990 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 10991 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
10992 gen_store_gpr(t1, rd+1);
10993 opn = "lwp";
10994 break;
10995 case SWP:
3c824109 10996 gen_load_gpr(t1, rd);
5f68f5ae 10997 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
10998 tcg_gen_movi_tl(t1, 4);
10999 gen_op_addr_add(ctx, t0, t0, t1);
11000 gen_load_gpr(t1, rd+1);
5f68f5ae 11001 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
11002 opn = "swp";
11003 break;
11004#ifdef TARGET_MIPS64
11005 case LDP:
36c6711b
EJ
11006 if (rd == base) {
11007 generate_exception(ctx, EXCP_RI);
11008 return;
11009 }
5f68f5ae 11010 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11011 gen_store_gpr(t1, rd);
11012 tcg_gen_movi_tl(t1, 8);
11013 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11014 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11015 gen_store_gpr(t1, rd+1);
11016 opn = "ldp";
11017 break;
11018 case SDP:
3c824109 11019 gen_load_gpr(t1, rd);
5f68f5ae 11020 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11021 tcg_gen_movi_tl(t1, 8);
11022 gen_op_addr_add(ctx, t0, t0, t1);
11023 gen_load_gpr(t1, rd+1);
5f68f5ae 11024 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11025 opn = "sdp";
11026 break;
11027#endif
6af0bf9c 11028 }
2abf314d 11029 (void)opn; /* avoid a compiler warning */
3c824109
NF
11030 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11031 tcg_temp_free(t0);
11032 tcg_temp_free(t1);
11033}
618b0fe9 11034
240ce26a 11035static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
11036{
11037 int extension = (ctx->opcode >> 6) & 0x3f;
11038 int minor = (ctx->opcode >> 12) & 0xf;
11039 uint32_t mips32_op;
11040
11041 switch (extension) {
11042 case TEQ:
11043 mips32_op = OPC_TEQ;
11044 goto do_trap;
11045 case TGE:
11046 mips32_op = OPC_TGE;
11047 goto do_trap;
11048 case TGEU:
11049 mips32_op = OPC_TGEU;
11050 goto do_trap;
11051 case TLT:
11052 mips32_op = OPC_TLT;
11053 goto do_trap;
11054 case TLTU:
11055 mips32_op = OPC_TLTU;
11056 goto do_trap;
11057 case TNE:
11058 mips32_op = OPC_TNE;
11059 do_trap:
11060 gen_trap(ctx, mips32_op, rs, rt, -1);
11061 break;
11062#ifndef CONFIG_USER_ONLY
11063 case MFC0:
11064 case MFC0 + 32:
2e15497c 11065 check_cp0_enabled(ctx);
3c824109
NF
11066 if (rt == 0) {
11067 /* Treat as NOP. */
11068 break;
11069 }
d75c135e 11070 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11071 break;
11072 case MTC0:
11073 case MTC0 + 32:
2e15497c 11074 check_cp0_enabled(ctx);
3c824109
NF
11075 {
11076 TCGv t0 = tcg_temp_new();
618b0fe9 11077
3c824109 11078 gen_load_gpr(t0, rt);
d75c135e 11079 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11080 tcg_temp_free(t0);
11081 }
11082 break;
11083#endif
a1fc6246
LA
11084 case 0x2a:
11085 switch (minor & 3) {
11086 case MADD_ACC:
11087 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11088 break;
11089 case MADDU_ACC:
11090 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11091 break;
11092 case MSUB_ACC:
11093 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11094 break;
11095 case MSUBU_ACC:
11096 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11097 break;
11098 default:
11099 goto pool32axf_invalid;
11100 }
11101 break;
11102 case 0x32:
11103 switch (minor & 3) {
11104 case MULT_ACC:
11105 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11106 break;
11107 case MULTU_ACC:
11108 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11109 break;
11110 default:
11111 goto pool32axf_invalid;
11112 }
11113 break;
3c824109
NF
11114 case 0x2c:
11115 switch (minor) {
11116 case SEB:
11117 gen_bshfl(ctx, OPC_SEB, rs, rt);
11118 break;
11119 case SEH:
11120 gen_bshfl(ctx, OPC_SEH, rs, rt);
11121 break;
11122 case CLO:
11123 mips32_op = OPC_CLO;
11124 goto do_cl;
11125 case CLZ:
11126 mips32_op = OPC_CLZ;
11127 do_cl:
d75c135e 11128 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11129 gen_cl(ctx, mips32_op, rt, rs);
11130 break;
11131 case RDHWR:
d75c135e 11132 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11133 break;
11134 case WSBH:
11135 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11136 break;
11137 case MULT:
11138 mips32_op = OPC_MULT;
26135ead 11139 goto do_mul;
3c824109
NF
11140 case MULTU:
11141 mips32_op = OPC_MULTU;
26135ead 11142 goto do_mul;
3c824109
NF
11143 case DIV:
11144 mips32_op = OPC_DIV;
26135ead 11145 goto do_div;
3c824109
NF
11146 case DIVU:
11147 mips32_op = OPC_DIVU;
26135ead
RS
11148 goto do_div;
11149 do_div:
11150 check_insn(ctx, ISA_MIPS32);
11151 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11152 break;
3c824109
NF
11153 case MADD:
11154 mips32_op = OPC_MADD;
26135ead 11155 goto do_mul;
3c824109
NF
11156 case MADDU:
11157 mips32_op = OPC_MADDU;
26135ead 11158 goto do_mul;
3c824109
NF
11159 case MSUB:
11160 mips32_op = OPC_MSUB;
26135ead 11161 goto do_mul;
3c824109
NF
11162 case MSUBU:
11163 mips32_op = OPC_MSUBU;
26135ead 11164 do_mul:
d75c135e 11165 check_insn(ctx, ISA_MIPS32);
a1fc6246 11166 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
11167 break;
11168 default:
11169 goto pool32axf_invalid;
11170 }
11171 break;
11172 case 0x34:
11173 switch (minor) {
11174 case MFC2:
11175 case MTC2:
11176 case MFHC2:
11177 case MTHC2:
11178 case CFC2:
11179 case CTC2:
11180 generate_exception_err(ctx, EXCP_CpU, 2);
11181 break;
11182 default:
11183 goto pool32axf_invalid;
11184 }
11185 break;
11186 case 0x3c:
11187 switch (minor) {
11188 case JALR:
11189 case JALR_HB:
11190 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
3c824109
NF
11191 break;
11192 case JALRS:
11193 case JALRS_HB:
11194 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
3c824109
NF
11195 break;
11196 default:
11197 goto pool32axf_invalid;
11198 }
11199 break;
11200 case 0x05:
11201 switch (minor) {
11202 case RDPGPR:
2e15497c 11203 check_cp0_enabled(ctx);
d75c135e 11204 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11205 gen_load_srsgpr(rt, rs);
11206 break;
11207 case WRPGPR:
2e15497c 11208 check_cp0_enabled(ctx);
d75c135e 11209 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11210 gen_store_srsgpr(rt, rs);
11211 break;
11212 default:
11213 goto pool32axf_invalid;
11214 }
11215 break;
11216#ifndef CONFIG_USER_ONLY
11217 case 0x0d:
11218 switch (minor) {
11219 case TLBP:
11220 mips32_op = OPC_TLBP;
11221 goto do_cp0;
11222 case TLBR:
11223 mips32_op = OPC_TLBR;
11224 goto do_cp0;
11225 case TLBWI:
11226 mips32_op = OPC_TLBWI;
11227 goto do_cp0;
11228 case TLBWR:
11229 mips32_op = OPC_TLBWR;
11230 goto do_cp0;
11231 case WAIT:
11232 mips32_op = OPC_WAIT;
11233 goto do_cp0;
11234 case DERET:
11235 mips32_op = OPC_DERET;
11236 goto do_cp0;
11237 case ERET:
11238 mips32_op = OPC_ERET;
11239 do_cp0:
11240 gen_cp0(env, ctx, mips32_op, rt, rs);
11241 break;
11242 default:
11243 goto pool32axf_invalid;
11244 }
11245 break;
11246 case 0x1d:
11247 switch (minor) {
11248 case DI:
2e15497c 11249 check_cp0_enabled(ctx);
3c824109
NF
11250 {
11251 TCGv t0 = tcg_temp_new();
11252
11253 save_cpu_state(ctx, 1);
895c2d04 11254 gen_helper_di(t0, cpu_env);
3c824109
NF
11255 gen_store_gpr(t0, rs);
11256 /* Stop translation as we may have switched the execution mode */
11257 ctx->bstate = BS_STOP;
11258 tcg_temp_free(t0);
11259 }
11260 break;
11261 case EI:
2e15497c 11262 check_cp0_enabled(ctx);
3c824109
NF
11263 {
11264 TCGv t0 = tcg_temp_new();
11265
11266 save_cpu_state(ctx, 1);
895c2d04 11267 gen_helper_ei(t0, cpu_env);
3c824109
NF
11268 gen_store_gpr(t0, rs);
11269 /* Stop translation as we may have switched the execution mode */
11270 ctx->bstate = BS_STOP;
11271 tcg_temp_free(t0);
11272 }
11273 break;
11274 default:
11275 goto pool32axf_invalid;
11276 }
11277 break;
11278#endif
11279 case 0x2d:
11280 switch (minor) {
11281 case SYNC:
11282 /* NOP */
11283 break;
11284 case SYSCALL:
11285 generate_exception(ctx, EXCP_SYSCALL);
11286 ctx->bstate = BS_STOP;
11287 break;
11288 case SDBBP:
d75c135e 11289 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11290 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11291 generate_exception(ctx, EXCP_DBp);
11292 } else {
11293 generate_exception(ctx, EXCP_DBp);
11294 }
11295 break;
11296 default:
11297 goto pool32axf_invalid;
11298 }
11299 break;
a1fc6246 11300 case 0x01:
26135ead 11301 switch (minor & 3) {
a1fc6246 11302 case MFHI_ACC:
26135ead 11303 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 11304 break;
a1fc6246 11305 case MFLO_ACC:
26135ead 11306 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 11307 break;
a1fc6246 11308 case MTHI_ACC:
26135ead 11309 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 11310 break;
a1fc6246 11311 case MTLO_ACC:
26135ead 11312 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
11313 break;
11314 default:
11315 goto pool32axf_invalid;
11316 }
11317 break;
a1fc6246
LA
11318 case 0x35:
11319 switch (minor) {
11320 case MFHI32:
11321 gen_HILO(ctx, OPC_MFHI, 0, rs);
11322 break;
11323 case MFLO32:
11324 gen_HILO(ctx, OPC_MFLO, 0, rs);
11325 break;
11326 case MTHI32:
11327 gen_HILO(ctx, OPC_MTHI, 0, rs);
11328 break;
11329 case MTLO32:
11330 gen_HILO(ctx, OPC_MTLO, 0, rs);
11331 break;
11332 default:
11333 goto pool32axf_invalid;
11334 }
11335 break;
3c824109
NF
11336 default:
11337 pool32axf_invalid:
11338 MIPS_INVAL("pool32axf");
11339 generate_exception(ctx, EXCP_RI);
11340 break;
11341 }
11342}
11343
11344/* Values for microMIPS fmt field. Variable-width, depending on which
11345 formats the instruction supports. */
11346
11347enum {
11348 FMT_SD_S = 0,
11349 FMT_SD_D = 1,
11350
11351 FMT_SDPS_S = 0,
11352 FMT_SDPS_D = 1,
11353 FMT_SDPS_PS = 2,
11354
11355 FMT_SWL_S = 0,
11356 FMT_SWL_W = 1,
11357 FMT_SWL_L = 2,
11358
11359 FMT_DWL_D = 0,
11360 FMT_DWL_W = 1,
11361 FMT_DWL_L = 2
11362};
11363
d75c135e 11364static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11365{
11366 int extension = (ctx->opcode >> 6) & 0x3ff;
11367 uint32_t mips32_op;
11368
11369#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11370#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11371#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11372
11373 switch (extension) {
11374 case FLOAT_1BIT_FMT(CFC1, 0):
11375 mips32_op = OPC_CFC1;
11376 goto do_cp1;
11377 case FLOAT_1BIT_FMT(CTC1, 0):
11378 mips32_op = OPC_CTC1;
11379 goto do_cp1;
11380 case FLOAT_1BIT_FMT(MFC1, 0):
11381 mips32_op = OPC_MFC1;
11382 goto do_cp1;
11383 case FLOAT_1BIT_FMT(MTC1, 0):
11384 mips32_op = OPC_MTC1;
11385 goto do_cp1;
11386 case FLOAT_1BIT_FMT(MFHC1, 0):
11387 mips32_op = OPC_MFHC1;
11388 goto do_cp1;
11389 case FLOAT_1BIT_FMT(MTHC1, 0):
11390 mips32_op = OPC_MTHC1;
11391 do_cp1:
11392 gen_cp1(ctx, mips32_op, rt, rs);
11393 break;
11394
11395 /* Reciprocal square root */
11396 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11397 mips32_op = OPC_RSQRT_S;
11398 goto do_unaryfp;
11399 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11400 mips32_op = OPC_RSQRT_D;
11401 goto do_unaryfp;
11402
11403 /* Square root */
11404 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11405 mips32_op = OPC_SQRT_S;
11406 goto do_unaryfp;
11407 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11408 mips32_op = OPC_SQRT_D;
11409 goto do_unaryfp;
11410
11411 /* Reciprocal */
11412 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11413 mips32_op = OPC_RECIP_S;
11414 goto do_unaryfp;
11415 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11416 mips32_op = OPC_RECIP_D;
11417 goto do_unaryfp;
11418
11419 /* Floor */
11420 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11421 mips32_op = OPC_FLOOR_L_S;
11422 goto do_unaryfp;
11423 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11424 mips32_op = OPC_FLOOR_L_D;
11425 goto do_unaryfp;
11426 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11427 mips32_op = OPC_FLOOR_W_S;
11428 goto do_unaryfp;
11429 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11430 mips32_op = OPC_FLOOR_W_D;
11431 goto do_unaryfp;
11432
11433 /* Ceiling */
11434 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11435 mips32_op = OPC_CEIL_L_S;
11436 goto do_unaryfp;
11437 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11438 mips32_op = OPC_CEIL_L_D;
11439 goto do_unaryfp;
11440 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11441 mips32_op = OPC_CEIL_W_S;
11442 goto do_unaryfp;
11443 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11444 mips32_op = OPC_CEIL_W_D;
11445 goto do_unaryfp;
11446
11447 /* Truncation */
11448 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11449 mips32_op = OPC_TRUNC_L_S;
11450 goto do_unaryfp;
11451 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11452 mips32_op = OPC_TRUNC_L_D;
11453 goto do_unaryfp;
11454 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11455 mips32_op = OPC_TRUNC_W_S;
11456 goto do_unaryfp;
11457 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11458 mips32_op = OPC_TRUNC_W_D;
11459 goto do_unaryfp;
11460
11461 /* Round */
11462 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11463 mips32_op = OPC_ROUND_L_S;
11464 goto do_unaryfp;
11465 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11466 mips32_op = OPC_ROUND_L_D;
11467 goto do_unaryfp;
11468 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11469 mips32_op = OPC_ROUND_W_S;
11470 goto do_unaryfp;
11471 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11472 mips32_op = OPC_ROUND_W_D;
11473 goto do_unaryfp;
11474
11475 /* Integer to floating-point conversion */
11476 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11477 mips32_op = OPC_CVT_L_S;
11478 goto do_unaryfp;
11479 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11480 mips32_op = OPC_CVT_L_D;
11481 goto do_unaryfp;
11482 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11483 mips32_op = OPC_CVT_W_S;
11484 goto do_unaryfp;
11485 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11486 mips32_op = OPC_CVT_W_D;
11487 goto do_unaryfp;
11488
11489 /* Paired-foo conversions */
11490 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11491 mips32_op = OPC_CVT_S_PL;
11492 goto do_unaryfp;
11493 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11494 mips32_op = OPC_CVT_S_PU;
11495 goto do_unaryfp;
11496 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11497 mips32_op = OPC_CVT_PW_PS;
11498 goto do_unaryfp;
11499 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11500 mips32_op = OPC_CVT_PS_PW;
11501 goto do_unaryfp;
11502
11503 /* Floating-point moves */
11504 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11505 mips32_op = OPC_MOV_S;
11506 goto do_unaryfp;
11507 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11508 mips32_op = OPC_MOV_D;
11509 goto do_unaryfp;
11510 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11511 mips32_op = OPC_MOV_PS;
11512 goto do_unaryfp;
11513
11514 /* Absolute value */
11515 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11516 mips32_op = OPC_ABS_S;
11517 goto do_unaryfp;
11518 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11519 mips32_op = OPC_ABS_D;
11520 goto do_unaryfp;
11521 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11522 mips32_op = OPC_ABS_PS;
11523 goto do_unaryfp;
11524
11525 /* Negation */
11526 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11527 mips32_op = OPC_NEG_S;
11528 goto do_unaryfp;
11529 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11530 mips32_op = OPC_NEG_D;
11531 goto do_unaryfp;
11532 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11533 mips32_op = OPC_NEG_PS;
11534 goto do_unaryfp;
11535
11536 /* Reciprocal square root step */
11537 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11538 mips32_op = OPC_RSQRT1_S;
11539 goto do_unaryfp;
11540 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11541 mips32_op = OPC_RSQRT1_D;
11542 goto do_unaryfp;
11543 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11544 mips32_op = OPC_RSQRT1_PS;
11545 goto do_unaryfp;
11546
11547 /* Reciprocal step */
11548 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11549 mips32_op = OPC_RECIP1_S;
11550 goto do_unaryfp;
11551 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11552 mips32_op = OPC_RECIP1_S;
11553 goto do_unaryfp;
11554 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11555 mips32_op = OPC_RECIP1_PS;
11556 goto do_unaryfp;
11557
11558 /* Conversions from double */
11559 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11560 mips32_op = OPC_CVT_D_S;
11561 goto do_unaryfp;
11562 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11563 mips32_op = OPC_CVT_D_W;
11564 goto do_unaryfp;
11565 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11566 mips32_op = OPC_CVT_D_L;
11567 goto do_unaryfp;
11568
11569 /* Conversions from single */
11570 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11571 mips32_op = OPC_CVT_S_D;
11572 goto do_unaryfp;
11573 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11574 mips32_op = OPC_CVT_S_W;
11575 goto do_unaryfp;
11576 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11577 mips32_op = OPC_CVT_S_L;
11578 do_unaryfp:
11579 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11580 break;
11581
11582 /* Conditional moves on floating-point codes */
11583 case COND_FLOAT_MOV(MOVT, 0):
11584 case COND_FLOAT_MOV(MOVT, 1):
11585 case COND_FLOAT_MOV(MOVT, 2):
11586 case COND_FLOAT_MOV(MOVT, 3):
11587 case COND_FLOAT_MOV(MOVT, 4):
11588 case COND_FLOAT_MOV(MOVT, 5):
11589 case COND_FLOAT_MOV(MOVT, 6):
11590 case COND_FLOAT_MOV(MOVT, 7):
11591 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11592 break;
11593 case COND_FLOAT_MOV(MOVF, 0):
11594 case COND_FLOAT_MOV(MOVF, 1):
11595 case COND_FLOAT_MOV(MOVF, 2):
11596 case COND_FLOAT_MOV(MOVF, 3):
11597 case COND_FLOAT_MOV(MOVF, 4):
11598 case COND_FLOAT_MOV(MOVF, 5):
11599 case COND_FLOAT_MOV(MOVF, 6):
11600 case COND_FLOAT_MOV(MOVF, 7):
11601 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11602 break;
11603 default:
11604 MIPS_INVAL("pool32fxf");
11605 generate_exception(ctx, EXCP_RI);
11606 break;
11607 }
11608}
11609
7db13fae 11610static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 11611 uint16_t insn_hw1)
3c824109
NF
11612{
11613 int32_t offset;
11614 uint16_t insn;
11615 int rt, rs, rd, rr;
11616 int16_t imm;
11617 uint32_t op, minor, mips32_op;
11618 uint32_t cond, fmt, cc;
11619
895c2d04 11620 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11621 ctx->opcode = (ctx->opcode << 16) | insn;
11622
11623 rt = (ctx->opcode >> 21) & 0x1f;
11624 rs = (ctx->opcode >> 16) & 0x1f;
11625 rd = (ctx->opcode >> 11) & 0x1f;
11626 rr = (ctx->opcode >> 6) & 0x1f;
11627 imm = (int16_t) ctx->opcode;
11628
11629 op = (ctx->opcode >> 26) & 0x3f;
11630 switch (op) {
11631 case POOL32A:
11632 minor = ctx->opcode & 0x3f;
11633 switch (minor) {
11634 case 0x00:
11635 minor = (ctx->opcode >> 6) & 0xf;
11636 switch (minor) {
11637 case SLL32:
11638 mips32_op = OPC_SLL;
11639 goto do_shifti;
11640 case SRA:
11641 mips32_op = OPC_SRA;
11642 goto do_shifti;
11643 case SRL32:
11644 mips32_op = OPC_SRL;
11645 goto do_shifti;
11646 case ROTR:
11647 mips32_op = OPC_ROTR;
11648 do_shifti:
d75c135e 11649 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
11650 break;
11651 default:
11652 goto pool32a_invalid;
11653 }
11654 break;
11655 case 0x10:
11656 minor = (ctx->opcode >> 6) & 0xf;
11657 switch (minor) {
11658 /* Arithmetic */
11659 case ADD:
11660 mips32_op = OPC_ADD;
11661 goto do_arith;
11662 case ADDU32:
11663 mips32_op = OPC_ADDU;
11664 goto do_arith;
11665 case SUB:
11666 mips32_op = OPC_SUB;
11667 goto do_arith;
11668 case SUBU32:
11669 mips32_op = OPC_SUBU;
11670 goto do_arith;
11671 case MUL:
11672 mips32_op = OPC_MUL;
11673 do_arith:
d75c135e 11674 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11675 break;
11676 /* Shifts */
11677 case SLLV:
11678 mips32_op = OPC_SLLV;
11679 goto do_shift;
11680 case SRLV:
11681 mips32_op = OPC_SRLV;
11682 goto do_shift;
11683 case SRAV:
11684 mips32_op = OPC_SRAV;
11685 goto do_shift;
11686 case ROTRV:
11687 mips32_op = OPC_ROTRV;
11688 do_shift:
d75c135e 11689 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11690 break;
11691 /* Logical operations */
11692 case AND:
11693 mips32_op = OPC_AND;
11694 goto do_logic;
11695 case OR32:
11696 mips32_op = OPC_OR;
11697 goto do_logic;
11698 case NOR:
11699 mips32_op = OPC_NOR;
11700 goto do_logic;
11701 case XOR32:
11702 mips32_op = OPC_XOR;
11703 do_logic:
d75c135e 11704 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11705 break;
11706 /* Set less than */
11707 case SLT:
11708 mips32_op = OPC_SLT;
11709 goto do_slt;
11710 case SLTU:
11711 mips32_op = OPC_SLTU;
11712 do_slt:
d75c135e 11713 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11714 break;
11715 default:
11716 goto pool32a_invalid;
11717 }
11718 break;
11719 case 0x18:
11720 minor = (ctx->opcode >> 6) & 0xf;
11721 switch (minor) {
11722 /* Conditional moves */
11723 case MOVN:
11724 mips32_op = OPC_MOVN;
11725 goto do_cmov;
11726 case MOVZ:
11727 mips32_op = OPC_MOVZ;
11728 do_cmov:
d75c135e 11729 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11730 break;
11731 case LWXS:
11732 gen_ldxs(ctx, rs, rt, rd);
11733 break;
11734 default:
11735 goto pool32a_invalid;
11736 }
11737 break;
11738 case INS:
11739 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11740 return;
11741 case EXT:
11742 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11743 return;
11744 case POOL32AXF:
240ce26a 11745 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
11746 break;
11747 case 0x07:
11748 generate_exception(ctx, EXCP_BREAK);
11749 break;
11750 default:
11751 pool32a_invalid:
11752 MIPS_INVAL("pool32a");
11753 generate_exception(ctx, EXCP_RI);
11754 break;
11755 }
11756 break;
11757 case POOL32B:
11758 minor = (ctx->opcode >> 12) & 0xf;
11759 switch (minor) {
11760 case CACHE:
2e15497c 11761 check_cp0_enabled(ctx);
3c824109
NF
11762 /* Treat as no-op. */
11763 break;
11764 case LWC2:
11765 case SWC2:
11766 /* COP2: Not implemented. */
11767 generate_exception_err(ctx, EXCP_CpU, 2);
11768 break;
11769 case LWP:
11770 case SWP:
11771#ifdef TARGET_MIPS64
11772 case LDP:
11773 case SDP:
11774#endif
11775 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11776 break;
11777 case LWM32:
11778 case SWM32:
11779#ifdef TARGET_MIPS64
11780 case LDM:
11781 case SDM:
11782#endif
11783 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11784 break;
11785 default:
11786 MIPS_INVAL("pool32b");
11787 generate_exception(ctx, EXCP_RI);
11788 break;
11789 }
11790 break;
11791 case POOL32F:
11792 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11793 minor = ctx->opcode & 0x3f;
11794 check_cp1_enabled(ctx);
11795 switch (minor) {
11796 case ALNV_PS:
11797 mips32_op = OPC_ALNV_PS;
11798 goto do_madd;
11799 case MADD_S:
11800 mips32_op = OPC_MADD_S;
11801 goto do_madd;
11802 case MADD_D:
11803 mips32_op = OPC_MADD_D;
11804 goto do_madd;
11805 case MADD_PS:
11806 mips32_op = OPC_MADD_PS;
11807 goto do_madd;
11808 case MSUB_S:
11809 mips32_op = OPC_MSUB_S;
11810 goto do_madd;
11811 case MSUB_D:
11812 mips32_op = OPC_MSUB_D;
11813 goto do_madd;
11814 case MSUB_PS:
11815 mips32_op = OPC_MSUB_PS;
11816 goto do_madd;
11817 case NMADD_S:
11818 mips32_op = OPC_NMADD_S;
11819 goto do_madd;
11820 case NMADD_D:
11821 mips32_op = OPC_NMADD_D;
11822 goto do_madd;
11823 case NMADD_PS:
11824 mips32_op = OPC_NMADD_PS;
11825 goto do_madd;
11826 case NMSUB_S:
11827 mips32_op = OPC_NMSUB_S;
11828 goto do_madd;
11829 case NMSUB_D:
11830 mips32_op = OPC_NMSUB_D;
11831 goto do_madd;
11832 case NMSUB_PS:
11833 mips32_op = OPC_NMSUB_PS;
11834 do_madd:
11835 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11836 break;
11837 case CABS_COND_FMT:
11838 cond = (ctx->opcode >> 6) & 0xf;
11839 cc = (ctx->opcode >> 13) & 0x7;
11840 fmt = (ctx->opcode >> 10) & 0x3;
11841 switch (fmt) {
11842 case 0x0:
11843 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11844 break;
11845 case 0x1:
11846 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11847 break;
11848 case 0x2:
11849 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11850 break;
11851 default:
11852 goto pool32f_invalid;
11853 }
11854 break;
11855 case C_COND_FMT:
11856 cond = (ctx->opcode >> 6) & 0xf;
11857 cc = (ctx->opcode >> 13) & 0x7;
11858 fmt = (ctx->opcode >> 10) & 0x3;
11859 switch (fmt) {
11860 case 0x0:
11861 gen_cmp_s(ctx, cond, rt, rs, cc);
11862 break;
11863 case 0x1:
11864 gen_cmp_d(ctx, cond, rt, rs, cc);
11865 break;
11866 case 0x2:
11867 gen_cmp_ps(ctx, cond, rt, rs, cc);
11868 break;
11869 default:
11870 goto pool32f_invalid;
11871 }
11872 break;
11873 case POOL32FXF:
d75c135e 11874 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
11875 break;
11876 case 0x00:
11877 /* PLL foo */
11878 switch ((ctx->opcode >> 6) & 0x7) {
11879 case PLL_PS:
11880 mips32_op = OPC_PLL_PS;
11881 goto do_ps;
11882 case PLU_PS:
11883 mips32_op = OPC_PLU_PS;
11884 goto do_ps;
11885 case PUL_PS:
11886 mips32_op = OPC_PUL_PS;
11887 goto do_ps;
11888 case PUU_PS:
11889 mips32_op = OPC_PUU_PS;
11890 goto do_ps;
11891 case CVT_PS_S:
11892 mips32_op = OPC_CVT_PS_S;
11893 do_ps:
11894 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11895 break;
11896 default:
11897 goto pool32f_invalid;
11898 }
11899 break;
11900 case 0x08:
11901 /* [LS][WDU]XC1 */
11902 switch ((ctx->opcode >> 6) & 0x7) {
11903 case LWXC1:
11904 mips32_op = OPC_LWXC1;
11905 goto do_ldst_cp1;
11906 case SWXC1:
11907 mips32_op = OPC_SWXC1;
11908 goto do_ldst_cp1;
11909 case LDXC1:
11910 mips32_op = OPC_LDXC1;
11911 goto do_ldst_cp1;
11912 case SDXC1:
11913 mips32_op = OPC_SDXC1;
11914 goto do_ldst_cp1;
11915 case LUXC1:
11916 mips32_op = OPC_LUXC1;
11917 goto do_ldst_cp1;
11918 case SUXC1:
11919 mips32_op = OPC_SUXC1;
11920 do_ldst_cp1:
11921 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11922 break;
11923 default:
11924 goto pool32f_invalid;
11925 }
11926 break;
11927 case 0x18:
11928 /* 3D insns */
11929 fmt = (ctx->opcode >> 9) & 0x3;
11930 switch ((ctx->opcode >> 6) & 0x7) {
11931 case RSQRT2_FMT:
11932 switch (fmt) {
11933 case FMT_SDPS_S:
11934 mips32_op = OPC_RSQRT2_S;
11935 goto do_3d;
11936 case FMT_SDPS_D:
11937 mips32_op = OPC_RSQRT2_D;
11938 goto do_3d;
11939 case FMT_SDPS_PS:
11940 mips32_op = OPC_RSQRT2_PS;
11941 goto do_3d;
11942 default:
11943 goto pool32f_invalid;
11944 }
11945 break;
11946 case RECIP2_FMT:
11947 switch (fmt) {
11948 case FMT_SDPS_S:
11949 mips32_op = OPC_RECIP2_S;
11950 goto do_3d;
11951 case FMT_SDPS_D:
11952 mips32_op = OPC_RECIP2_D;
11953 goto do_3d;
11954 case FMT_SDPS_PS:
11955 mips32_op = OPC_RECIP2_PS;
11956 goto do_3d;
11957 default:
11958 goto pool32f_invalid;
11959 }
11960 break;
11961 case ADDR_PS:
11962 mips32_op = OPC_ADDR_PS;
11963 goto do_3d;
11964 case MULR_PS:
11965 mips32_op = OPC_MULR_PS;
11966 do_3d:
11967 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11968 break;
11969 default:
11970 goto pool32f_invalid;
11971 }
11972 break;
11973 case 0x20:
11974 /* MOV[FT].fmt and PREFX */
11975 cc = (ctx->opcode >> 13) & 0x7;
11976 fmt = (ctx->opcode >> 9) & 0x3;
11977 switch ((ctx->opcode >> 6) & 0x7) {
11978 case MOVF_FMT:
11979 switch (fmt) {
11980 case FMT_SDPS_S:
11981 gen_movcf_s(rs, rt, cc, 0);
11982 break;
11983 case FMT_SDPS_D:
11984 gen_movcf_d(ctx, rs, rt, cc, 0);
11985 break;
11986 case FMT_SDPS_PS:
7f6613ce 11987 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
11988 break;
11989 default:
11990 goto pool32f_invalid;
11991 }
11992 break;
11993 case MOVT_FMT:
11994 switch (fmt) {
11995 case FMT_SDPS_S:
11996 gen_movcf_s(rs, rt, cc, 1);
11997 break;
11998 case FMT_SDPS_D:
11999 gen_movcf_d(ctx, rs, rt, cc, 1);
12000 break;
12001 case FMT_SDPS_PS:
7f6613ce 12002 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
12003 break;
12004 default:
12005 goto pool32f_invalid;
12006 }
12007 break;
12008 case PREFX:
12009 break;
12010 default:
12011 goto pool32f_invalid;
12012 }
12013 break;
12014#define FINSN_3ARG_SDPS(prfx) \
12015 switch ((ctx->opcode >> 8) & 0x3) { \
12016 case FMT_SDPS_S: \
12017 mips32_op = OPC_##prfx##_S; \
12018 goto do_fpop; \
12019 case FMT_SDPS_D: \
12020 mips32_op = OPC_##prfx##_D; \
12021 goto do_fpop; \
12022 case FMT_SDPS_PS: \
12023 mips32_op = OPC_##prfx##_PS; \
12024 goto do_fpop; \
12025 default: \
12026 goto pool32f_invalid; \
12027 }
12028 case 0x30:
12029 /* regular FP ops */
12030 switch ((ctx->opcode >> 6) & 0x3) {
12031 case ADD_FMT:
12032 FINSN_3ARG_SDPS(ADD);
12033 break;
12034 case SUB_FMT:
12035 FINSN_3ARG_SDPS(SUB);
12036 break;
12037 case MUL_FMT:
12038 FINSN_3ARG_SDPS(MUL);
12039 break;
12040 case DIV_FMT:
12041 fmt = (ctx->opcode >> 8) & 0x3;
12042 if (fmt == 1) {
12043 mips32_op = OPC_DIV_D;
12044 } else if (fmt == 0) {
12045 mips32_op = OPC_DIV_S;
12046 } else {
12047 goto pool32f_invalid;
12048 }
12049 goto do_fpop;
12050 default:
12051 goto pool32f_invalid;
12052 }
12053 break;
12054 case 0x38:
12055 /* cmovs */
12056 switch ((ctx->opcode >> 6) & 0x3) {
12057 case MOVN_FMT:
12058 FINSN_3ARG_SDPS(MOVN);
12059 break;
12060 case MOVZ_FMT:
12061 FINSN_3ARG_SDPS(MOVZ);
12062 break;
12063 default:
12064 goto pool32f_invalid;
12065 }
12066 break;
12067 do_fpop:
12068 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12069 break;
12070 default:
12071 pool32f_invalid:
12072 MIPS_INVAL("pool32f");
12073 generate_exception(ctx, EXCP_RI);
12074 break;
12075 }
12076 } else {
12077 generate_exception_err(ctx, EXCP_CpU, 1);
12078 }
12079 break;
12080 case POOL32I:
12081 minor = (ctx->opcode >> 21) & 0x1f;
12082 switch (minor) {
12083 case BLTZ:
12084 mips32_op = OPC_BLTZ;
12085 goto do_branch;
12086 case BLTZAL:
12087 mips32_op = OPC_BLTZAL;
12088 goto do_branch;
12089 case BLTZALS:
12090 mips32_op = OPC_BLTZALS;
12091 goto do_branch;
12092 case BGEZ:
12093 mips32_op = OPC_BGEZ;
12094 goto do_branch;
12095 case BGEZAL:
12096 mips32_op = OPC_BGEZAL;
12097 goto do_branch;
12098 case BGEZALS:
12099 mips32_op = OPC_BGEZALS;
12100 goto do_branch;
12101 case BLEZ:
12102 mips32_op = OPC_BLEZ;
12103 goto do_branch;
12104 case BGTZ:
12105 mips32_op = OPC_BGTZ;
12106 do_branch:
12107 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
3c824109
NF
12108 break;
12109
12110 /* Traps */
12111 case TLTI:
12112 mips32_op = OPC_TLTI;
12113 goto do_trapi;
12114 case TGEI:
12115 mips32_op = OPC_TGEI;
12116 goto do_trapi;
12117 case TLTIU:
12118 mips32_op = OPC_TLTIU;
12119 goto do_trapi;
12120 case TGEIU:
12121 mips32_op = OPC_TGEIU;
12122 goto do_trapi;
12123 case TNEI:
12124 mips32_op = OPC_TNEI;
12125 goto do_trapi;
12126 case TEQI:
12127 mips32_op = OPC_TEQI;
12128 do_trapi:
12129 gen_trap(ctx, mips32_op, rs, -1, imm);
12130 break;
12131
12132 case BNEZC:
12133 case BEQZC:
12134 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12135 4, rs, 0, imm << 1);
12136 /* Compact branches don't have a delay slot, so just let
12137 the normal delay slot handling take us to the branch
12138 target. */
12139 break;
12140 case LUI:
d75c135e 12141 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12142 break;
12143 case SYNCI:
12144 break;
12145 case BC2F:
12146 case BC2T:
12147 /* COP2: Not implemented. */
12148 generate_exception_err(ctx, EXCP_CpU, 2);
12149 break;
12150 case BC1F:
12151 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12152 goto do_cp1branch;
12153 case BC1T:
12154 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12155 goto do_cp1branch;
12156 case BC1ANY4F:
12157 mips32_op = OPC_BC1FANY4;
12158 goto do_cp1mips3d;
12159 case BC1ANY4T:
12160 mips32_op = OPC_BC1TANY4;
12161 do_cp1mips3d:
12162 check_cop1x(ctx);
d75c135e 12163 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12164 /* Fall through */
12165 do_cp1branch:
d75c135e 12166 gen_compute_branch1(ctx, mips32_op,
3c824109 12167 (ctx->opcode >> 18) & 0x7, imm << 1);
3c824109
NF
12168 break;
12169 case BPOSGE64:
12170 case BPOSGE32:
12171 /* MIPS DSP: not implemented */
12172 /* Fall through */
12173 default:
12174 MIPS_INVAL("pool32i");
12175 generate_exception(ctx, EXCP_RI);
12176 break;
12177 }
12178 break;
12179 case POOL32C:
12180 minor = (ctx->opcode >> 12) & 0xf;
12181 switch (minor) {
12182 case LWL:
12183 mips32_op = OPC_LWL;
5c13fdfd 12184 goto do_ld_lr;
3c824109
NF
12185 case SWL:
12186 mips32_op = OPC_SWL;
5c13fdfd 12187 goto do_st_lr;
3c824109
NF
12188 case LWR:
12189 mips32_op = OPC_LWR;
5c13fdfd 12190 goto do_ld_lr;
3c824109
NF
12191 case SWR:
12192 mips32_op = OPC_SWR;
5c13fdfd 12193 goto do_st_lr;
3c824109
NF
12194#if defined(TARGET_MIPS64)
12195 case LDL:
12196 mips32_op = OPC_LDL;
5c13fdfd 12197 goto do_ld_lr;
3c824109
NF
12198 case SDL:
12199 mips32_op = OPC_SDL;
5c13fdfd 12200 goto do_st_lr;
3c824109
NF
12201 case LDR:
12202 mips32_op = OPC_LDR;
5c13fdfd 12203 goto do_ld_lr;
3c824109
NF
12204 case SDR:
12205 mips32_op = OPC_SDR;
5c13fdfd 12206 goto do_st_lr;
3c824109
NF
12207 case LWU:
12208 mips32_op = OPC_LWU;
5c13fdfd 12209 goto do_ld_lr;
3c824109
NF
12210 case LLD:
12211 mips32_op = OPC_LLD;
5c13fdfd 12212 goto do_ld_lr;
3c824109
NF
12213#endif
12214 case LL:
12215 mips32_op = OPC_LL;
5c13fdfd
AJ
12216 goto do_ld_lr;
12217 do_ld_lr:
d75c135e 12218 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12219 break;
12220 do_st_lr:
12221 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12222 break;
12223 case SC:
12224 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12225 break;
12226#if defined(TARGET_MIPS64)
12227 case SCD:
12228 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12229 break;
12230#endif
12231 case PREF:
12232 /* Treat as no-op */
12233 break;
12234 default:
12235 MIPS_INVAL("pool32c");
12236 generate_exception(ctx, EXCP_RI);
12237 break;
12238 }
12239 break;
12240 case ADDI32:
12241 mips32_op = OPC_ADDI;
12242 goto do_addi;
12243 case ADDIU32:
12244 mips32_op = OPC_ADDIU;
12245 do_addi:
d75c135e 12246 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12247 break;
12248
12249 /* Logical operations */
12250 case ORI32:
12251 mips32_op = OPC_ORI;
12252 goto do_logici;
12253 case XORI32:
12254 mips32_op = OPC_XORI;
12255 goto do_logici;
12256 case ANDI32:
12257 mips32_op = OPC_ANDI;
12258 do_logici:
d75c135e 12259 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12260 break;
12261
12262 /* Set less than immediate */
12263 case SLTI32:
12264 mips32_op = OPC_SLTI;
12265 goto do_slti;
12266 case SLTIU32:
12267 mips32_op = OPC_SLTIU;
12268 do_slti:
d75c135e 12269 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12270 break;
12271 case JALX32:
12272 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12273 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
3c824109
NF
12274 break;
12275 case JALS32:
12276 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12277 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
3c824109
NF
12278 break;
12279 case BEQ32:
12280 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
3c824109
NF
12281 break;
12282 case BNE32:
12283 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
3c824109
NF
12284 break;
12285 case J32:
12286 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12287 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12288 break;
12289 case JAL32:
12290 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12291 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12292 break;
12293 /* Floating point (COP1) */
12294 case LWC132:
12295 mips32_op = OPC_LWC1;
12296 goto do_cop1;
12297 case LDC132:
12298 mips32_op = OPC_LDC1;
12299 goto do_cop1;
12300 case SWC132:
12301 mips32_op = OPC_SWC1;
12302 goto do_cop1;
12303 case SDC132:
12304 mips32_op = OPC_SDC1;
12305 do_cop1:
12306 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12307 break;
12308 case ADDIUPC:
12309 {
12310 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12311 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12312
12313 gen_addiupc(ctx, reg, offset, 0, 0);
12314 }
12315 break;
12316 /* Loads and stores */
12317 case LB32:
12318 mips32_op = OPC_LB;
5c13fdfd 12319 goto do_ld;
3c824109
NF
12320 case LBU32:
12321 mips32_op = OPC_LBU;
5c13fdfd 12322 goto do_ld;
3c824109
NF
12323 case LH32:
12324 mips32_op = OPC_LH;
5c13fdfd 12325 goto do_ld;
3c824109
NF
12326 case LHU32:
12327 mips32_op = OPC_LHU;
5c13fdfd 12328 goto do_ld;
3c824109
NF
12329 case LW32:
12330 mips32_op = OPC_LW;
5c13fdfd 12331 goto do_ld;
3c824109
NF
12332#ifdef TARGET_MIPS64
12333 case LD32:
12334 mips32_op = OPC_LD;
5c13fdfd 12335 goto do_ld;
3c824109
NF
12336 case SD32:
12337 mips32_op = OPC_SD;
5c13fdfd 12338 goto do_st;
3c824109
NF
12339#endif
12340 case SB32:
12341 mips32_op = OPC_SB;
5c13fdfd 12342 goto do_st;
3c824109
NF
12343 case SH32:
12344 mips32_op = OPC_SH;
5c13fdfd 12345 goto do_st;
3c824109
NF
12346 case SW32:
12347 mips32_op = OPC_SW;
5c13fdfd
AJ
12348 goto do_st;
12349 do_ld:
d75c135e 12350 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12351 break;
12352 do_st:
12353 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12354 break;
12355 default:
12356 generate_exception(ctx, EXCP_RI);
12357 break;
12358 }
12359}
12360
240ce26a 12361static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
12362{
12363 uint32_t op;
12364
12365 /* make sure instructions are on a halfword boundary */
12366 if (ctx->pc & 0x1) {
12367 env->CP0_BadVAddr = ctx->pc;
12368 generate_exception(ctx, EXCP_AdEL);
12369 ctx->bstate = BS_STOP;
12370 return 2;
12371 }
12372
12373 op = (ctx->opcode >> 10) & 0x3f;
12374 /* Enforce properly-sized instructions in a delay slot */
12375 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12376 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12377
12378 switch (op) {
12379 case POOL32A:
12380 case POOL32B:
12381 case POOL32I:
12382 case POOL32C:
12383 case ADDI32:
12384 case ADDIU32:
12385 case ORI32:
12386 case XORI32:
12387 case SLTI32:
12388 case SLTIU32:
12389 case ANDI32:
12390 case JALX32:
12391 case LBU32:
12392 case LHU32:
12393 case POOL32F:
12394 case JALS32:
12395 case BEQ32:
12396 case BNE32:
12397 case J32:
12398 case JAL32:
12399 case SB32:
12400 case SH32:
12401 case POOL32S:
12402 case ADDIUPC:
12403 case SWC132:
12404 case SDC132:
12405 case SD32:
12406 case SW32:
12407 case LB32:
12408 case LH32:
12409 case DADDIU32:
3c824109
NF
12410 case LWC132:
12411 case LDC132:
12412 case LD32:
12413 case LW32:
12414 if (bits & MIPS_HFLAG_BDS16) {
12415 generate_exception(ctx, EXCP_RI);
12416 /* Just stop translation; the user is confused. */
12417 ctx->bstate = BS_STOP;
12418 return 2;
12419 }
12420 break;
12421 case POOL16A:
12422 case POOL16B:
12423 case POOL16C:
12424 case LWGP16:
12425 case POOL16F:
12426 case LBU16:
12427 case LHU16:
12428 case LWSP16:
12429 case LW16:
12430 case SB16:
12431 case SH16:
12432 case SWSP16:
12433 case SW16:
12434 case MOVE16:
12435 case ANDI16:
12436 case POOL16D:
12437 case POOL16E:
12438 case BEQZ16:
12439 case BNEZ16:
12440 case B16:
12441 case LI16:
12442 if (bits & MIPS_HFLAG_BDS32) {
12443 generate_exception(ctx, EXCP_RI);
12444 /* Just stop translation; the user is confused. */
12445 ctx->bstate = BS_STOP;
12446 return 2;
12447 }
12448 break;
12449 default:
12450 break;
12451 }
12452 }
12453 switch (op) {
12454 case POOL16A:
12455 {
12456 int rd = mmreg(uMIPS_RD(ctx->opcode));
12457 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12458 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12459 uint32_t opc = 0;
12460
12461 switch (ctx->opcode & 0x1) {
12462 case ADDU16:
12463 opc = OPC_ADDU;
12464 break;
12465 case SUBU16:
12466 opc = OPC_SUBU;
12467 break;
12468 }
12469
d75c135e 12470 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12471 }
12472 break;
12473 case POOL16B:
12474 {
12475 int rd = mmreg(uMIPS_RD(ctx->opcode));
12476 int rs = mmreg(uMIPS_RS(ctx->opcode));
12477 int amount = (ctx->opcode >> 1) & 0x7;
12478 uint32_t opc = 0;
12479 amount = amount == 0 ? 8 : amount;
12480
12481 switch (ctx->opcode & 0x1) {
12482 case SLL16:
12483 opc = OPC_SLL;
12484 break;
12485 case SRL16:
12486 opc = OPC_SRL;
12487 break;
12488 }
12489
d75c135e 12490 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12491 }
12492 break;
12493 case POOL16C:
240ce26a 12494 gen_pool16c_insn(ctx);
3c824109
NF
12495 break;
12496 case LWGP16:
12497 {
12498 int rd = mmreg(uMIPS_RD(ctx->opcode));
12499 int rb = 28; /* GP */
12500 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12501
d75c135e 12502 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12503 }
12504 break;
12505 case POOL16F:
12506 if (ctx->opcode & 1) {
12507 generate_exception(ctx, EXCP_RI);
12508 } else {
12509 /* MOVEP */
12510 int enc_dest = uMIPS_RD(ctx->opcode);
12511 int enc_rt = uMIPS_RS2(ctx->opcode);
12512 int enc_rs = uMIPS_RS1(ctx->opcode);
12513 int rd, rs, re, rt;
12514 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12515 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12516 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12517
12518 rd = rd_enc[enc_dest];
12519 re = re_enc[enc_dest];
12520 rs = rs_rt_enc[enc_rs];
12521 rt = rs_rt_enc[enc_rt];
12522
d75c135e
AJ
12523 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12524 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12525 }
12526 break;
12527 case LBU16:
12528 {
12529 int rd = mmreg(uMIPS_RD(ctx->opcode));
12530 int rb = mmreg(uMIPS_RS(ctx->opcode));
12531 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12532 offset = (offset == 0xf ? -1 : offset);
12533
d75c135e 12534 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12535 }
12536 break;
12537 case LHU16:
12538 {
12539 int rd = mmreg(uMIPS_RD(ctx->opcode));
12540 int rb = mmreg(uMIPS_RS(ctx->opcode));
12541 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12542
d75c135e 12543 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12544 }
12545 break;
12546 case LWSP16:
12547 {
12548 int rd = (ctx->opcode >> 5) & 0x1f;
12549 int rb = 29; /* SP */
12550 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12551
d75c135e 12552 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12553 }
12554 break;
12555 case LW16:
12556 {
12557 int rd = mmreg(uMIPS_RD(ctx->opcode));
12558 int rb = mmreg(uMIPS_RS(ctx->opcode));
12559 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12560
d75c135e 12561 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12562 }
12563 break;
12564 case SB16:
12565 {
12566 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12567 int rb = mmreg(uMIPS_RS(ctx->opcode));
12568 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12569
5c13fdfd 12570 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12571 }
12572 break;
12573 case SH16:
12574 {
12575 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12576 int rb = mmreg(uMIPS_RS(ctx->opcode));
12577 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12578
5c13fdfd 12579 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12580 }
12581 break;
12582 case SWSP16:
12583 {
12584 int rd = (ctx->opcode >> 5) & 0x1f;
12585 int rb = 29; /* SP */
12586 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12587
5c13fdfd 12588 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12589 }
12590 break;
12591 case SW16:
12592 {
12593 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12594 int rb = mmreg(uMIPS_RS(ctx->opcode));
12595 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12596
5c13fdfd 12597 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12598 }
12599 break;
12600 case MOVE16:
12601 {
12602 int rd = uMIPS_RD5(ctx->opcode);
12603 int rs = uMIPS_RS5(ctx->opcode);
12604
d75c135e 12605 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12606 }
12607 break;
12608 case ANDI16:
d75c135e 12609 gen_andi16(ctx);
3c824109
NF
12610 break;
12611 case POOL16D:
12612 switch (ctx->opcode & 0x1) {
12613 case ADDIUS5:
d75c135e 12614 gen_addius5(ctx);
3c824109
NF
12615 break;
12616 case ADDIUSP:
d75c135e 12617 gen_addiusp(ctx);
3c824109
NF
12618 break;
12619 }
12620 break;
12621 case POOL16E:
12622 switch (ctx->opcode & 0x1) {
12623 case ADDIUR2:
d75c135e 12624 gen_addiur2(ctx);
3c824109
NF
12625 break;
12626 case ADDIUR1SP:
d75c135e 12627 gen_addiur1sp(ctx);
3c824109
NF
12628 break;
12629 }
12630 break;
12631 case B16:
12632 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12633 SIMM(ctx->opcode, 0, 10) << 1);
3c824109
NF
12634 break;
12635 case BNEZ16:
12636 case BEQZ16:
12637 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12638 mmreg(uMIPS_RD(ctx->opcode)),
12639 0, SIMM(ctx->opcode, 0, 7) << 1);
3c824109
NF
12640 break;
12641 case LI16:
12642 {
12643 int reg = mmreg(uMIPS_RD(ctx->opcode));
12644 int imm = ZIMM(ctx->opcode, 0, 7);
12645
12646 imm = (imm == 0x7f ? -1 : imm);
12647 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12648 }
12649 break;
12650 case RES_20:
12651 case RES_28:
12652 case RES_29:
12653 case RES_30:
12654 case RES_31:
12655 case RES_38:
12656 case RES_39:
12657 generate_exception(ctx, EXCP_RI);
12658 break;
12659 default:
240ce26a 12660 decode_micromips32_opc (env, ctx, op);
3c824109
NF
12661 return 4;
12662 }
12663
12664 return 2;
12665}
12666
12667/* SmartMIPS extension to MIPS32 */
12668
12669#if defined(TARGET_MIPS64)
12670
12671/* MDMX extension to MIPS64 */
12672
12673#endif
12674
9b1a1d68 12675/* MIPSDSP functions. */
d75c135e 12676static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12677 int rd, int base, int offset)
12678{
12679 const char *opn = "ldx";
12680 TCGv t0;
12681
9b1a1d68
JL
12682 check_dsp(ctx);
12683 t0 = tcg_temp_new();
12684
12685 if (base == 0) {
12686 gen_load_gpr(t0, offset);
12687 } else if (offset == 0) {
12688 gen_load_gpr(t0, base);
12689 } else {
12690 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12691 }
12692
9b1a1d68
JL
12693 switch (opc) {
12694 case OPC_LBUX:
5f68f5ae 12695 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
12696 gen_store_gpr(t0, rd);
12697 opn = "lbux";
12698 break;
12699 case OPC_LHX:
5f68f5ae 12700 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
12701 gen_store_gpr(t0, rd);
12702 opn = "lhx";
12703 break;
12704 case OPC_LWX:
5f68f5ae 12705 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
12706 gen_store_gpr(t0, rd);
12707 opn = "lwx";
12708 break;
12709#if defined(TARGET_MIPS64)
12710 case OPC_LDX:
5f68f5ae 12711 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
12712 gen_store_gpr(t0, rd);
12713 opn = "ldx";
12714 break;
12715#endif
12716 }
12717 (void)opn; /* avoid a compiler warning */
12718 MIPS_DEBUG("%s %s, %s(%s)", opn,
12719 regnames[rd], regnames[offset], regnames[base]);
12720 tcg_temp_free(t0);
12721}
12722
461c08df
JL
12723static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12724 int ret, int v1, int v2)
12725{
12726 const char *opn = "mipsdsp arith";
12727 TCGv v1_t;
12728 TCGv v2_t;
12729
12730 if (ret == 0) {
12731 /* Treat as NOP. */
12732 MIPS_DEBUG("NOP");
12733 return;
12734 }
12735
12736 v1_t = tcg_temp_new();
12737 v2_t = tcg_temp_new();
12738
12739 gen_load_gpr(v1_t, v1);
12740 gen_load_gpr(v2_t, v2);
12741
12742 switch (op1) {
12743 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12744 case OPC_MULT_G_2E:
12745 check_dspr2(ctx);
12746 switch (op2) {
12747 case OPC_ADDUH_QB:
12748 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12749 break;
12750 case OPC_ADDUH_R_QB:
12751 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12752 break;
12753 case OPC_ADDQH_PH:
12754 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12755 break;
12756 case OPC_ADDQH_R_PH:
12757 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12758 break;
12759 case OPC_ADDQH_W:
12760 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12761 break;
12762 case OPC_ADDQH_R_W:
12763 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12764 break;
12765 case OPC_SUBUH_QB:
12766 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12767 break;
12768 case OPC_SUBUH_R_QB:
12769 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12770 break;
12771 case OPC_SUBQH_PH:
12772 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12773 break;
12774 case OPC_SUBQH_R_PH:
12775 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12776 break;
12777 case OPC_SUBQH_W:
12778 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12779 break;
12780 case OPC_SUBQH_R_W:
12781 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12782 break;
12783 }
12784 break;
12785 case OPC_ABSQ_S_PH_DSP:
12786 switch (op2) {
12787 case OPC_ABSQ_S_QB:
12788 check_dspr2(ctx);
12789 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12790 break;
12791 case OPC_ABSQ_S_PH:
12792 check_dsp(ctx);
12793 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12794 break;
12795 case OPC_ABSQ_S_W:
12796 check_dsp(ctx);
12797 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12798 break;
12799 case OPC_PRECEQ_W_PHL:
12800 check_dsp(ctx);
12801 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12802 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12803 break;
12804 case OPC_PRECEQ_W_PHR:
12805 check_dsp(ctx);
12806 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12807 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12808 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12809 break;
12810 case OPC_PRECEQU_PH_QBL:
12811 check_dsp(ctx);
12812 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12813 break;
12814 case OPC_PRECEQU_PH_QBR:
12815 check_dsp(ctx);
12816 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12817 break;
12818 case OPC_PRECEQU_PH_QBLA:
12819 check_dsp(ctx);
12820 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12821 break;
12822 case OPC_PRECEQU_PH_QBRA:
12823 check_dsp(ctx);
12824 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12825 break;
12826 case OPC_PRECEU_PH_QBL:
12827 check_dsp(ctx);
12828 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12829 break;
12830 case OPC_PRECEU_PH_QBR:
12831 check_dsp(ctx);
12832 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12833 break;
12834 case OPC_PRECEU_PH_QBLA:
12835 check_dsp(ctx);
12836 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12837 break;
12838 case OPC_PRECEU_PH_QBRA:
12839 check_dsp(ctx);
12840 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12841 break;
12842 }
12843 break;
12844 case OPC_ADDU_QB_DSP:
12845 switch (op2) {
12846 case OPC_ADDQ_PH:
12847 check_dsp(ctx);
12848 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849 break;
12850 case OPC_ADDQ_S_PH:
12851 check_dsp(ctx);
12852 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853 break;
12854 case OPC_ADDQ_S_W:
12855 check_dsp(ctx);
12856 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12857 break;
12858 case OPC_ADDU_QB:
12859 check_dsp(ctx);
12860 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861 break;
12862 case OPC_ADDU_S_QB:
12863 check_dsp(ctx);
12864 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865 break;
12866 case OPC_ADDU_PH:
12867 check_dspr2(ctx);
12868 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12869 break;
12870 case OPC_ADDU_S_PH:
12871 check_dspr2(ctx);
12872 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12873 break;
12874 case OPC_SUBQ_PH:
12875 check_dsp(ctx);
12876 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12877 break;
12878 case OPC_SUBQ_S_PH:
12879 check_dsp(ctx);
12880 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12881 break;
12882 case OPC_SUBQ_S_W:
12883 check_dsp(ctx);
12884 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885 break;
12886 case OPC_SUBU_QB:
12887 check_dsp(ctx);
12888 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 break;
12890 case OPC_SUBU_S_QB:
12891 check_dsp(ctx);
12892 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12893 break;
12894 case OPC_SUBU_PH:
12895 check_dspr2(ctx);
12896 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12897 break;
12898 case OPC_SUBU_S_PH:
12899 check_dspr2(ctx);
12900 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12901 break;
12902 case OPC_ADDSC:
12903 check_dsp(ctx);
12904 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12905 break;
12906 case OPC_ADDWC:
12907 check_dsp(ctx);
12908 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12909 break;
12910 case OPC_MODSUB:
12911 check_dsp(ctx);
12912 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12913 break;
12914 case OPC_RADDU_W_QB:
12915 check_dsp(ctx);
12916 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12917 break;
12918 }
12919 break;
12920 case OPC_CMPU_EQ_QB_DSP:
12921 switch (op2) {
12922 case OPC_PRECR_QB_PH:
12923 check_dspr2(ctx);
12924 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12925 break;
12926 case OPC_PRECRQ_QB_PH:
12927 check_dsp(ctx);
12928 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12929 break;
12930 case OPC_PRECR_SRA_PH_W:
12931 check_dspr2(ctx);
12932 {
12933 TCGv_i32 sa_t = tcg_const_i32(v2);
12934 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12935 cpu_gpr[ret]);
12936 tcg_temp_free_i32(sa_t);
12937 break;
12938 }
12939 case OPC_PRECR_SRA_R_PH_W:
12940 check_dspr2(ctx);
12941 {
12942 TCGv_i32 sa_t = tcg_const_i32(v2);
12943 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12944 cpu_gpr[ret]);
12945 tcg_temp_free_i32(sa_t);
12946 break;
12947 }
12948 case OPC_PRECRQ_PH_W:
12949 check_dsp(ctx);
12950 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12951 break;
12952 case OPC_PRECRQ_RS_PH_W:
12953 check_dsp(ctx);
12954 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12955 break;
12956 case OPC_PRECRQU_S_QB_PH:
12957 check_dsp(ctx);
12958 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12959 break;
12960 }
12961 break;
12962#ifdef TARGET_MIPS64
12963 case OPC_ABSQ_S_QH_DSP:
12964 switch (op2) {
12965 case OPC_PRECEQ_L_PWL:
12966 check_dsp(ctx);
12967 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12968 break;
12969 case OPC_PRECEQ_L_PWR:
12970 check_dsp(ctx);
12971 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12972 break;
12973 case OPC_PRECEQ_PW_QHL:
12974 check_dsp(ctx);
12975 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12976 break;
12977 case OPC_PRECEQ_PW_QHR:
12978 check_dsp(ctx);
12979 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12980 break;
12981 case OPC_PRECEQ_PW_QHLA:
12982 check_dsp(ctx);
12983 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12984 break;
12985 case OPC_PRECEQ_PW_QHRA:
12986 check_dsp(ctx);
12987 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12988 break;
12989 case OPC_PRECEQU_QH_OBL:
12990 check_dsp(ctx);
12991 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12992 break;
12993 case OPC_PRECEQU_QH_OBR:
12994 check_dsp(ctx);
12995 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12996 break;
12997 case OPC_PRECEQU_QH_OBLA:
12998 check_dsp(ctx);
12999 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13000 break;
13001 case OPC_PRECEQU_QH_OBRA:
13002 check_dsp(ctx);
13003 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13004 break;
13005 case OPC_PRECEU_QH_OBL:
13006 check_dsp(ctx);
13007 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13008 break;
13009 case OPC_PRECEU_QH_OBR:
13010 check_dsp(ctx);
13011 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13012 break;
13013 case OPC_PRECEU_QH_OBLA:
13014 check_dsp(ctx);
13015 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13016 break;
13017 case OPC_PRECEU_QH_OBRA:
13018 check_dsp(ctx);
13019 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13020 break;
13021 case OPC_ABSQ_S_OB:
13022 check_dspr2(ctx);
13023 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13024 break;
13025 case OPC_ABSQ_S_PW:
13026 check_dsp(ctx);
13027 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13028 break;
13029 case OPC_ABSQ_S_QH:
13030 check_dsp(ctx);
13031 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13032 break;
13033 }
13034 break;
13035 case OPC_ADDU_OB_DSP:
13036 switch (op2) {
13037 case OPC_RADDU_L_OB:
13038 check_dsp(ctx);
13039 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13040 break;
13041 case OPC_SUBQ_PW:
13042 check_dsp(ctx);
13043 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044 break;
13045 case OPC_SUBQ_S_PW:
13046 check_dsp(ctx);
13047 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048 break;
13049 case OPC_SUBQ_QH:
13050 check_dsp(ctx);
13051 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052 break;
13053 case OPC_SUBQ_S_QH:
13054 check_dsp(ctx);
13055 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13056 break;
13057 case OPC_SUBU_OB:
13058 check_dsp(ctx);
13059 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13060 break;
13061 case OPC_SUBU_S_OB:
13062 check_dsp(ctx);
13063 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13064 break;
13065 case OPC_SUBU_QH:
13066 check_dspr2(ctx);
13067 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13068 break;
13069 case OPC_SUBU_S_QH:
13070 check_dspr2(ctx);
13071 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13072 break;
13073 case OPC_SUBUH_OB:
13074 check_dspr2(ctx);
13075 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13076 break;
13077 case OPC_SUBUH_R_OB:
13078 check_dspr2(ctx);
13079 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13080 break;
13081 case OPC_ADDQ_PW:
13082 check_dsp(ctx);
13083 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084 break;
13085 case OPC_ADDQ_S_PW:
13086 check_dsp(ctx);
13087 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13088 break;
13089 case OPC_ADDQ_QH:
13090 check_dsp(ctx);
13091 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092 break;
13093 case OPC_ADDQ_S_QH:
13094 check_dsp(ctx);
13095 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13096 break;
13097 case OPC_ADDU_OB:
13098 check_dsp(ctx);
13099 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13100 break;
13101 case OPC_ADDU_S_OB:
13102 check_dsp(ctx);
13103 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13104 break;
13105 case OPC_ADDU_QH:
13106 check_dspr2(ctx);
13107 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13108 break;
13109 case OPC_ADDU_S_QH:
13110 check_dspr2(ctx);
13111 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13112 break;
13113 case OPC_ADDUH_OB:
13114 check_dspr2(ctx);
13115 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13116 break;
13117 case OPC_ADDUH_R_OB:
13118 check_dspr2(ctx);
13119 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13120 break;
13121 }
13122 break;
13123 case OPC_CMPU_EQ_OB_DSP:
13124 switch (op2) {
13125 case OPC_PRECR_OB_QH:
13126 check_dspr2(ctx);
13127 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13128 break;
13129 case OPC_PRECR_SRA_QH_PW:
13130 check_dspr2(ctx);
13131 {
13132 TCGv_i32 ret_t = tcg_const_i32(ret);
13133 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13134 tcg_temp_free_i32(ret_t);
13135 break;
13136 }
13137 case OPC_PRECR_SRA_R_QH_PW:
13138 check_dspr2(ctx);
13139 {
13140 TCGv_i32 sa_v = tcg_const_i32(ret);
13141 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13142 tcg_temp_free_i32(sa_v);
13143 break;
13144 }
13145 case OPC_PRECRQ_OB_QH:
13146 check_dsp(ctx);
13147 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13148 break;
13149 case OPC_PRECRQ_PW_L:
13150 check_dsp(ctx);
13151 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13152 break;
13153 case OPC_PRECRQ_QH_PW:
13154 check_dsp(ctx);
13155 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13156 break;
13157 case OPC_PRECRQ_RS_QH_PW:
13158 check_dsp(ctx);
13159 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13160 break;
13161 case OPC_PRECRQU_S_OB_QH:
13162 check_dsp(ctx);
13163 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13164 break;
13165 }
13166 break;
13167#endif
13168 }
13169
13170 tcg_temp_free(v1_t);
13171 tcg_temp_free(v2_t);
13172
13173 (void)opn; /* avoid a compiler warning */
13174 MIPS_DEBUG("%s", opn);
13175}
9b1a1d68 13176
77c5fa8b
JL
13177static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13178 int ret, int v1, int v2)
13179{
13180 uint32_t op2;
13181 const char *opn = "mipsdsp shift";
13182 TCGv t0;
13183 TCGv v1_t;
13184 TCGv v2_t;
13185
13186 if (ret == 0) {
13187 /* Treat as NOP. */
13188 MIPS_DEBUG("NOP");
13189 return;
13190 }
13191
13192 t0 = tcg_temp_new();
13193 v1_t = tcg_temp_new();
13194 v2_t = tcg_temp_new();
13195
13196 tcg_gen_movi_tl(t0, v1);
13197 gen_load_gpr(v1_t, v1);
13198 gen_load_gpr(v2_t, v2);
13199
13200 switch (opc) {
13201 case OPC_SHLL_QB_DSP:
13202 {
13203 op2 = MASK_SHLL_QB(ctx->opcode);
13204 switch (op2) {
13205 case OPC_SHLL_QB:
13206 check_dsp(ctx);
13207 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13208 break;
13209 case OPC_SHLLV_QB:
13210 check_dsp(ctx);
13211 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13212 break;
13213 case OPC_SHLL_PH:
13214 check_dsp(ctx);
13215 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13216 break;
13217 case OPC_SHLLV_PH:
13218 check_dsp(ctx);
13219 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13220 break;
13221 case OPC_SHLL_S_PH:
13222 check_dsp(ctx);
13223 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13224 break;
13225 case OPC_SHLLV_S_PH:
13226 check_dsp(ctx);
13227 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13228 break;
13229 case OPC_SHLL_S_W:
13230 check_dsp(ctx);
13231 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13232 break;
13233 case OPC_SHLLV_S_W:
13234 check_dsp(ctx);
13235 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13236 break;
13237 case OPC_SHRL_QB:
13238 check_dsp(ctx);
13239 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13240 break;
13241 case OPC_SHRLV_QB:
13242 check_dsp(ctx);
13243 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13244 break;
13245 case OPC_SHRL_PH:
13246 check_dspr2(ctx);
13247 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13248 break;
13249 case OPC_SHRLV_PH:
13250 check_dspr2(ctx);
13251 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13252 break;
13253 case OPC_SHRA_QB:
13254 check_dspr2(ctx);
13255 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13256 break;
13257 case OPC_SHRA_R_QB:
13258 check_dspr2(ctx);
13259 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13260 break;
13261 case OPC_SHRAV_QB:
13262 check_dspr2(ctx);
13263 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13264 break;
13265 case OPC_SHRAV_R_QB:
13266 check_dspr2(ctx);
13267 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13268 break;
13269 case OPC_SHRA_PH:
13270 check_dsp(ctx);
13271 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13272 break;
13273 case OPC_SHRA_R_PH:
13274 check_dsp(ctx);
13275 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13276 break;
13277 case OPC_SHRAV_PH:
13278 check_dsp(ctx);
13279 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13280 break;
13281 case OPC_SHRAV_R_PH:
13282 check_dsp(ctx);
13283 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13284 break;
13285 case OPC_SHRA_R_W:
13286 check_dsp(ctx);
13287 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13288 break;
13289 case OPC_SHRAV_R_W:
13290 check_dsp(ctx);
13291 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13292 break;
13293 default: /* Invalid */
13294 MIPS_INVAL("MASK SHLL.QB");
13295 generate_exception(ctx, EXCP_RI);
13296 break;
13297 }
13298 break;
13299 }
13300#ifdef TARGET_MIPS64
13301 case OPC_SHLL_OB_DSP:
13302 op2 = MASK_SHLL_OB(ctx->opcode);
13303 switch (op2) {
13304 case OPC_SHLL_PW:
13305 check_dsp(ctx);
13306 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13307 break;
13308 case OPC_SHLLV_PW:
13309 check_dsp(ctx);
13310 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13311 break;
13312 case OPC_SHLL_S_PW:
13313 check_dsp(ctx);
13314 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13315 break;
13316 case OPC_SHLLV_S_PW:
13317 check_dsp(ctx);
13318 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13319 break;
13320 case OPC_SHLL_OB:
13321 check_dsp(ctx);
13322 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13323 break;
13324 case OPC_SHLLV_OB:
13325 check_dsp(ctx);
13326 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13327 break;
13328 case OPC_SHLL_QH:
13329 check_dsp(ctx);
13330 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13331 break;
13332 case OPC_SHLLV_QH:
13333 check_dsp(ctx);
13334 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13335 break;
13336 case OPC_SHLL_S_QH:
13337 check_dsp(ctx);
13338 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13339 break;
13340 case OPC_SHLLV_S_QH:
13341 check_dsp(ctx);
13342 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13343 break;
13344 case OPC_SHRA_OB:
13345 check_dspr2(ctx);
13346 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13347 break;
13348 case OPC_SHRAV_OB:
13349 check_dspr2(ctx);
13350 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13351 break;
13352 case OPC_SHRA_R_OB:
13353 check_dspr2(ctx);
13354 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13355 break;
13356 case OPC_SHRAV_R_OB:
13357 check_dspr2(ctx);
13358 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13359 break;
13360 case OPC_SHRA_PW:
13361 check_dsp(ctx);
13362 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13363 break;
13364 case OPC_SHRAV_PW:
13365 check_dsp(ctx);
13366 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13367 break;
13368 case OPC_SHRA_R_PW:
13369 check_dsp(ctx);
13370 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13371 break;
13372 case OPC_SHRAV_R_PW:
13373 check_dsp(ctx);
13374 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13375 break;
13376 case OPC_SHRA_QH:
13377 check_dsp(ctx);
13378 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13379 break;
13380 case OPC_SHRAV_QH:
13381 check_dsp(ctx);
13382 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13383 break;
13384 case OPC_SHRA_R_QH:
13385 check_dsp(ctx);
13386 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13387 break;
13388 case OPC_SHRAV_R_QH:
13389 check_dsp(ctx);
13390 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13391 break;
13392 case OPC_SHRL_OB:
13393 check_dsp(ctx);
13394 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13395 break;
13396 case OPC_SHRLV_OB:
13397 check_dsp(ctx);
13398 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13399 break;
13400 case OPC_SHRL_QH:
13401 check_dspr2(ctx);
13402 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13403 break;
13404 case OPC_SHRLV_QH:
13405 check_dspr2(ctx);
13406 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13407 break;
13408 default: /* Invalid */
13409 MIPS_INVAL("MASK SHLL.OB");
13410 generate_exception(ctx, EXCP_RI);
13411 break;
13412 }
13413 break;
13414#endif
13415 }
13416
13417 tcg_temp_free(t0);
13418 tcg_temp_free(v1_t);
13419 tcg_temp_free(v2_t);
13420 (void)opn; /* avoid a compiler warning */
13421 MIPS_DEBUG("%s", opn);
13422}
13423
a22260ae
JL
13424static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13425 int ret, int v1, int v2, int check_ret)
13426{
13427 const char *opn = "mipsdsp multiply";
13428 TCGv_i32 t0;
13429 TCGv v1_t;
13430 TCGv v2_t;
13431
13432 if ((ret == 0) && (check_ret == 1)) {
13433 /* Treat as NOP. */
13434 MIPS_DEBUG("NOP");
13435 return;
13436 }
13437
13438 t0 = tcg_temp_new_i32();
13439 v1_t = tcg_temp_new();
13440 v2_t = tcg_temp_new();
13441
13442 tcg_gen_movi_i32(t0, ret);
13443 gen_load_gpr(v1_t, v1);
13444 gen_load_gpr(v2_t, v2);
13445
13446 switch (op1) {
13447 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13448 * the same mask and op1. */
13449 case OPC_MULT_G_2E:
639eadb9 13450 check_dspr2(ctx);
a22260ae
JL
13451 switch (op2) {
13452 case OPC_MUL_PH:
13453 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13454 break;
13455 case OPC_MUL_S_PH:
13456 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13457 break;
13458 case OPC_MULQ_S_W:
13459 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13460 break;
13461 case OPC_MULQ_RS_W:
13462 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13463 break;
13464 }
13465 break;
13466 case OPC_DPA_W_PH_DSP:
13467 switch (op2) {
13468 case OPC_DPAU_H_QBL:
13469 check_dsp(ctx);
13470 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13471 break;
13472 case OPC_DPAU_H_QBR:
13473 check_dsp(ctx);
13474 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13475 break;
13476 case OPC_DPSU_H_QBL:
13477 check_dsp(ctx);
13478 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13479 break;
13480 case OPC_DPSU_H_QBR:
13481 check_dsp(ctx);
13482 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13483 break;
13484 case OPC_DPA_W_PH:
13485 check_dspr2(ctx);
13486 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13487 break;
13488 case OPC_DPAX_W_PH:
13489 check_dspr2(ctx);
13490 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13491 break;
13492 case OPC_DPAQ_S_W_PH:
13493 check_dsp(ctx);
13494 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13495 break;
13496 case OPC_DPAQX_S_W_PH:
13497 check_dspr2(ctx);
13498 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13499 break;
13500 case OPC_DPAQX_SA_W_PH:
13501 check_dspr2(ctx);
13502 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13503 break;
13504 case OPC_DPS_W_PH:
13505 check_dspr2(ctx);
13506 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13507 break;
13508 case OPC_DPSX_W_PH:
13509 check_dspr2(ctx);
13510 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13511 break;
13512 case OPC_DPSQ_S_W_PH:
13513 check_dsp(ctx);
13514 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13515 break;
13516 case OPC_DPSQX_S_W_PH:
13517 check_dspr2(ctx);
13518 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13519 break;
13520 case OPC_DPSQX_SA_W_PH:
13521 check_dspr2(ctx);
13522 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13523 break;
13524 case OPC_MULSAQ_S_W_PH:
13525 check_dsp(ctx);
13526 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13527 break;
13528 case OPC_DPAQ_SA_L_W:
13529 check_dsp(ctx);
13530 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13531 break;
13532 case OPC_DPSQ_SA_L_W:
13533 check_dsp(ctx);
13534 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13535 break;
13536 case OPC_MAQ_S_W_PHL:
13537 check_dsp(ctx);
13538 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13539 break;
13540 case OPC_MAQ_S_W_PHR:
13541 check_dsp(ctx);
13542 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13543 break;
13544 case OPC_MAQ_SA_W_PHL:
13545 check_dsp(ctx);
13546 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13547 break;
13548 case OPC_MAQ_SA_W_PHR:
13549 check_dsp(ctx);
13550 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13551 break;
13552 case OPC_MULSA_W_PH:
13553 check_dspr2(ctx);
13554 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13555 break;
13556 }
13557 break;
13558#ifdef TARGET_MIPS64
13559 case OPC_DPAQ_W_QH_DSP:
13560 {
13561 int ac = ret & 0x03;
13562 tcg_gen_movi_i32(t0, ac);
13563
13564 switch (op2) {
13565 case OPC_DMADD:
13566 check_dsp(ctx);
13567 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13568 break;
13569 case OPC_DMADDU:
13570 check_dsp(ctx);
13571 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13572 break;
13573 case OPC_DMSUB:
13574 check_dsp(ctx);
13575 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13576 break;
13577 case OPC_DMSUBU:
13578 check_dsp(ctx);
13579 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13580 break;
13581 case OPC_DPA_W_QH:
13582 check_dspr2(ctx);
13583 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13584 break;
13585 case OPC_DPAQ_S_W_QH:
13586 check_dsp(ctx);
13587 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13588 break;
13589 case OPC_DPAQ_SA_L_PW:
13590 check_dsp(ctx);
13591 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13592 break;
13593 case OPC_DPAU_H_OBL:
13594 check_dsp(ctx);
13595 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13596 break;
13597 case OPC_DPAU_H_OBR:
13598 check_dsp(ctx);
13599 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13600 break;
13601 case OPC_DPS_W_QH:
13602 check_dspr2(ctx);
13603 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13604 break;
13605 case OPC_DPSQ_S_W_QH:
13606 check_dsp(ctx);
13607 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13608 break;
13609 case OPC_DPSQ_SA_L_PW:
13610 check_dsp(ctx);
13611 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13612 break;
13613 case OPC_DPSU_H_OBL:
13614 check_dsp(ctx);
13615 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13616 break;
13617 case OPC_DPSU_H_OBR:
13618 check_dsp(ctx);
13619 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13620 break;
13621 case OPC_MAQ_S_L_PWL:
13622 check_dsp(ctx);
13623 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13624 break;
13625 case OPC_MAQ_S_L_PWR:
13626 check_dsp(ctx);
13627 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13628 break;
13629 case OPC_MAQ_S_W_QHLL:
13630 check_dsp(ctx);
13631 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13632 break;
13633 case OPC_MAQ_SA_W_QHLL:
13634 check_dsp(ctx);
13635 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13636 break;
13637 case OPC_MAQ_S_W_QHLR:
13638 check_dsp(ctx);
13639 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13640 break;
13641 case OPC_MAQ_SA_W_QHLR:
13642 check_dsp(ctx);
13643 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13644 break;
13645 case OPC_MAQ_S_W_QHRL:
13646 check_dsp(ctx);
13647 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13648 break;
13649 case OPC_MAQ_SA_W_QHRL:
13650 check_dsp(ctx);
13651 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13652 break;
13653 case OPC_MAQ_S_W_QHRR:
13654 check_dsp(ctx);
13655 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13656 break;
13657 case OPC_MAQ_SA_W_QHRR:
13658 check_dsp(ctx);
13659 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13660 break;
13661 case OPC_MULSAQ_S_L_PW:
13662 check_dsp(ctx);
13663 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13664 break;
13665 case OPC_MULSAQ_S_W_QH:
13666 check_dsp(ctx);
13667 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13668 break;
13669 }
13670 }
13671 break;
13672#endif
13673 case OPC_ADDU_QB_DSP:
13674 switch (op2) {
13675 case OPC_MULEU_S_PH_QBL:
13676 check_dsp(ctx);
13677 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13678 break;
13679 case OPC_MULEU_S_PH_QBR:
13680 check_dsp(ctx);
13681 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13682 break;
13683 case OPC_MULQ_RS_PH:
13684 check_dsp(ctx);
13685 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13686 break;
13687 case OPC_MULEQ_S_W_PHL:
13688 check_dsp(ctx);
13689 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13690 break;
13691 case OPC_MULEQ_S_W_PHR:
13692 check_dsp(ctx);
13693 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13694 break;
13695 case OPC_MULQ_S_PH:
13696 check_dspr2(ctx);
13697 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13698 break;
13699 }
13700 break;
13701#ifdef TARGET_MIPS64
13702 case OPC_ADDU_OB_DSP:
13703 switch (op2) {
13704 case OPC_MULEQ_S_PW_QHL:
13705 check_dsp(ctx);
13706 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13707 break;
13708 case OPC_MULEQ_S_PW_QHR:
13709 check_dsp(ctx);
13710 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13711 break;
13712 case OPC_MULEU_S_QH_OBL:
13713 check_dsp(ctx);
13714 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13715 break;
13716 case OPC_MULEU_S_QH_OBR:
13717 check_dsp(ctx);
13718 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13719 break;
13720 case OPC_MULQ_RS_QH:
13721 check_dsp(ctx);
13722 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13723 break;
13724 }
13725 break;
13726#endif
13727 }
13728
13729 tcg_temp_free_i32(t0);
13730 tcg_temp_free(v1_t);
13731 tcg_temp_free(v2_t);
13732
13733 (void)opn; /* avoid a compiler warning */
13734 MIPS_DEBUG("%s", opn);
13735
13736}
13737
d75c135e 13738static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13739 int ret, int val)
13740{
13741 const char *opn = "mipsdsp Bit/ Manipulation";
13742 int16_t imm;
13743 TCGv t0;
13744 TCGv val_t;
13745
13746 if (ret == 0) {
13747 /* Treat as NOP. */
13748 MIPS_DEBUG("NOP");
13749 return;
13750 }
13751
13752 t0 = tcg_temp_new();
13753 val_t = tcg_temp_new();
13754 gen_load_gpr(val_t, val);
13755
13756 switch (op1) {
13757 case OPC_ABSQ_S_PH_DSP:
13758 switch (op2) {
13759 case OPC_BITREV:
13760 check_dsp(ctx);
13761 gen_helper_bitrev(cpu_gpr[ret], val_t);
13762 break;
13763 case OPC_REPL_QB:
13764 check_dsp(ctx);
13765 {
13766 target_long result;
13767 imm = (ctx->opcode >> 16) & 0xFF;
13768 result = (uint32_t)imm << 24 |
13769 (uint32_t)imm << 16 |
13770 (uint32_t)imm << 8 |
13771 (uint32_t)imm;
13772 result = (int32_t)result;
13773 tcg_gen_movi_tl(cpu_gpr[ret], result);
13774 }
13775 break;
13776 case OPC_REPLV_QB:
13777 check_dsp(ctx);
13778 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13779 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13780 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13781 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13782 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13783 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13784 break;
13785 case OPC_REPL_PH:
13786 check_dsp(ctx);
13787 {
13788 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13789 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13790 tcg_gen_movi_tl(cpu_gpr[ret], \
13791 (target_long)((int32_t)imm << 16 | \
c4aaba92 13792 (uint16_t)imm));
1cb6686c
JL
13793 }
13794 break;
13795 case OPC_REPLV_PH:
13796 check_dsp(ctx);
13797 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13798 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13799 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13800 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13801 break;
13802 }
13803 break;
13804#ifdef TARGET_MIPS64
13805 case OPC_ABSQ_S_QH_DSP:
13806 switch (op2) {
13807 case OPC_REPL_OB:
13808 check_dsp(ctx);
13809 {
13810 target_long temp;
13811
13812 imm = (ctx->opcode >> 16) & 0xFF;
13813 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13814 temp = (temp << 16) | temp;
13815 temp = (temp << 32) | temp;
13816 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13817 break;
13818 }
13819 case OPC_REPL_PW:
13820 check_dsp(ctx);
13821 {
13822 target_long temp;
13823
13824 imm = (ctx->opcode >> 16) & 0x03FF;
13825 imm = (int16_t)(imm << 6) >> 6;
13826 temp = ((target_long)imm << 32) \
13827 | ((target_long)imm & 0xFFFFFFFF);
13828 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13829 break;
13830 }
13831 case OPC_REPL_QH:
13832 check_dsp(ctx);
13833 {
13834 target_long temp;
13835
13836 imm = (ctx->opcode >> 16) & 0x03FF;
13837 imm = (int16_t)(imm << 6) >> 6;
13838
13839 temp = ((uint64_t)(uint16_t)imm << 48) |
13840 ((uint64_t)(uint16_t)imm << 32) |
13841 ((uint64_t)(uint16_t)imm << 16) |
13842 (uint64_t)(uint16_t)imm;
13843 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13844 break;
13845 }
13846 case OPC_REPLV_OB:
13847 check_dsp(ctx);
13848 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13849 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13850 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13851 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13852 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13853 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13854 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13855 break;
13856 case OPC_REPLV_PW:
13857 check_dsp(ctx);
13858 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13859 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13860 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13861 break;
13862 case OPC_REPLV_QH:
13863 check_dsp(ctx);
13864 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13865 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13866 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13867 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13868 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13869 break;
13870 }
13871 break;
13872#endif
13873 }
13874 tcg_temp_free(t0);
13875 tcg_temp_free(val_t);
13876
13877 (void)opn; /* avoid a compiler warning */
13878 MIPS_DEBUG("%s", opn);
13879}
13880
26690560
JL
13881static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13882 uint32_t op1, uint32_t op2,
13883 int ret, int v1, int v2, int check_ret)
13884{
13885 const char *opn = "mipsdsp add compare pick";
26690560
JL
13886 TCGv t1;
13887 TCGv v1_t;
13888 TCGv v2_t;
13889
13890 if ((ret == 0) && (check_ret == 1)) {
13891 /* Treat as NOP. */
13892 MIPS_DEBUG("NOP");
13893 return;
13894 }
13895
26690560
JL
13896 t1 = tcg_temp_new();
13897 v1_t = tcg_temp_new();
13898 v2_t = tcg_temp_new();
13899
13900 gen_load_gpr(v1_t, v1);
13901 gen_load_gpr(v2_t, v2);
13902
13903 switch (op1) {
26690560
JL
13904 case OPC_CMPU_EQ_QB_DSP:
13905 switch (op2) {
13906 case OPC_CMPU_EQ_QB:
13907 check_dsp(ctx);
13908 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13909 break;
13910 case OPC_CMPU_LT_QB:
13911 check_dsp(ctx);
13912 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13913 break;
13914 case OPC_CMPU_LE_QB:
13915 check_dsp(ctx);
13916 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13917 break;
13918 case OPC_CMPGU_EQ_QB:
13919 check_dsp(ctx);
13920 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13921 break;
13922 case OPC_CMPGU_LT_QB:
13923 check_dsp(ctx);
13924 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13925 break;
13926 case OPC_CMPGU_LE_QB:
13927 check_dsp(ctx);
13928 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13929 break;
13930 case OPC_CMPGDU_EQ_QB:
13931 check_dspr2(ctx);
13932 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13933 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13934 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13935 tcg_gen_shli_tl(t1, t1, 24);
13936 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13937 break;
13938 case OPC_CMPGDU_LT_QB:
13939 check_dspr2(ctx);
13940 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13941 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13942 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13943 tcg_gen_shli_tl(t1, t1, 24);
13944 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13945 break;
13946 case OPC_CMPGDU_LE_QB:
13947 check_dspr2(ctx);
13948 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13949 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13950 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13951 tcg_gen_shli_tl(t1, t1, 24);
13952 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13953 break;
13954 case OPC_CMP_EQ_PH:
13955 check_dsp(ctx);
13956 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13957 break;
13958 case OPC_CMP_LT_PH:
13959 check_dsp(ctx);
13960 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13961 break;
13962 case OPC_CMP_LE_PH:
13963 check_dsp(ctx);
13964 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13965 break;
13966 case OPC_PICK_QB:
13967 check_dsp(ctx);
13968 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13969 break;
13970 case OPC_PICK_PH:
13971 check_dsp(ctx);
13972 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13973 break;
13974 case OPC_PACKRL_PH:
13975 check_dsp(ctx);
13976 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13977 break;
13978 }
13979 break;
13980#ifdef TARGET_MIPS64
13981 case OPC_CMPU_EQ_OB_DSP:
13982 switch (op2) {
13983 case OPC_CMP_EQ_PW:
13984 check_dsp(ctx);
13985 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13986 break;
13987 case OPC_CMP_LT_PW:
13988 check_dsp(ctx);
13989 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13990 break;
13991 case OPC_CMP_LE_PW:
13992 check_dsp(ctx);
13993 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13994 break;
13995 case OPC_CMP_EQ_QH:
13996 check_dsp(ctx);
13997 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13998 break;
13999 case OPC_CMP_LT_QH:
14000 check_dsp(ctx);
14001 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14002 break;
14003 case OPC_CMP_LE_QH:
14004 check_dsp(ctx);
14005 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14006 break;
14007 case OPC_CMPGDU_EQ_OB:
14008 check_dspr2(ctx);
14009 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14010 break;
14011 case OPC_CMPGDU_LT_OB:
14012 check_dspr2(ctx);
14013 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14014 break;
14015 case OPC_CMPGDU_LE_OB:
14016 check_dspr2(ctx);
14017 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14018 break;
14019 case OPC_CMPGU_EQ_OB:
14020 check_dsp(ctx);
14021 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14022 break;
14023 case OPC_CMPGU_LT_OB:
14024 check_dsp(ctx);
14025 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14026 break;
14027 case OPC_CMPGU_LE_OB:
14028 check_dsp(ctx);
14029 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14030 break;
14031 case OPC_CMPU_EQ_OB:
14032 check_dsp(ctx);
14033 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14034 break;
14035 case OPC_CMPU_LT_OB:
14036 check_dsp(ctx);
14037 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14038 break;
14039 case OPC_CMPU_LE_OB:
14040 check_dsp(ctx);
14041 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14042 break;
14043 case OPC_PACKRL_PW:
14044 check_dsp(ctx);
14045 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14046 break;
14047 case OPC_PICK_OB:
14048 check_dsp(ctx);
14049 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14050 break;
14051 case OPC_PICK_PW:
14052 check_dsp(ctx);
14053 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14054 break;
14055 case OPC_PICK_QH:
14056 check_dsp(ctx);
14057 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14058 break;
14059 }
14060 break;
df6126a7
AJ
14061#endif
14062 }
14063
14064 tcg_temp_free(t1);
14065 tcg_temp_free(v1_t);
14066 tcg_temp_free(v2_t);
14067
14068 (void)opn; /* avoid a compiler warning */
14069 MIPS_DEBUG("%s", opn);
14070}
14071
14072static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14073 uint32_t op1, int rt, int rs, int sa)
14074{
14075 const char *opn = "mipsdsp append/dappend";
14076 TCGv t0;
14077
14078 check_dspr2(ctx);
14079
14080 if (rt == 0) {
14081 /* Treat as NOP. */
14082 MIPS_DEBUG("NOP");
14083 return;
14084 }
14085
14086 t0 = tcg_temp_new();
14087 gen_load_gpr(t0, rs);
14088
14089 switch (op1) {
14090 case OPC_APPEND_DSP:
14091 switch (MASK_APPEND(ctx->opcode)) {
14092 case OPC_APPEND:
14093 if (sa != 0) {
14094 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14095 }
14096 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14097 break;
14098 case OPC_PREPEND:
14099 if (sa != 0) {
14100 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14101 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14102 tcg_gen_shli_tl(t0, t0, 32 - sa);
14103 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14104 }
14105 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14106 break;
14107 case OPC_BALIGN:
14108 sa &= 3;
14109 if (sa != 0 && sa != 2) {
14110 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14111 tcg_gen_ext32u_tl(t0, t0);
14112 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14113 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14114 }
14115 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14116 break;
14117 default: /* Invalid */
14118 MIPS_INVAL("MASK APPEND");
14119 generate_exception(ctx, EXCP_RI);
14120 break;
14121 }
14122 break;
14123#ifdef TARGET_MIPS64
26690560 14124 case OPC_DAPPEND_DSP:
df6126a7 14125 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 14126 case OPC_DAPPEND:
df6126a7
AJ
14127 if (sa != 0) {
14128 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14129 }
26690560
JL
14130 break;
14131 case OPC_PREPENDD:
df6126a7
AJ
14132 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14133 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14134 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
14135 break;
14136 case OPC_PREPENDW:
df6126a7
AJ
14137 if (sa != 0) {
14138 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14139 tcg_gen_shli_tl(t0, t0, 64 - sa);
14140 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14141 }
26690560
JL
14142 break;
14143 case OPC_DBALIGN:
df6126a7
AJ
14144 sa &= 7;
14145 if (sa != 0 && sa != 2 && sa != 4) {
14146 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14147 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14148 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14149 }
26690560
JL
14150 break;
14151 default: /* Invalid */
14152 MIPS_INVAL("MASK DAPPEND");
14153 generate_exception(ctx, EXCP_RI);
14154 break;
14155 }
14156 break;
14157#endif
14158 }
df6126a7 14159 tcg_temp_free(t0);
26690560
JL
14160 (void)opn; /* avoid a compiler warning */
14161 MIPS_DEBUG("%s", opn);
14162}
14163
b53371ed
JL
14164static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14165 int ret, int v1, int v2, int check_ret)
14166
14167{
14168 const char *opn = "mipsdsp accumulator";
14169 TCGv t0;
14170 TCGv t1;
14171 TCGv v1_t;
14172 TCGv v2_t;
14173 int16_t imm;
14174
14175 if ((ret == 0) && (check_ret == 1)) {
14176 /* Treat as NOP. */
14177 MIPS_DEBUG("NOP");
14178 return;
14179 }
14180
14181 t0 = tcg_temp_new();
14182 t1 = tcg_temp_new();
14183 v1_t = tcg_temp_new();
14184 v2_t = tcg_temp_new();
14185
14186 gen_load_gpr(v1_t, v1);
14187 gen_load_gpr(v2_t, v2);
14188
14189 switch (op1) {
14190 case OPC_EXTR_W_DSP:
14191 check_dsp(ctx);
14192 switch (op2) {
14193 case OPC_EXTR_W:
14194 tcg_gen_movi_tl(t0, v2);
14195 tcg_gen_movi_tl(t1, v1);
14196 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14197 break;
14198 case OPC_EXTR_R_W:
14199 tcg_gen_movi_tl(t0, v2);
14200 tcg_gen_movi_tl(t1, v1);
14201 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14202 break;
14203 case OPC_EXTR_RS_W:
14204 tcg_gen_movi_tl(t0, v2);
14205 tcg_gen_movi_tl(t1, v1);
14206 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14207 break;
14208 case OPC_EXTR_S_H:
14209 tcg_gen_movi_tl(t0, v2);
14210 tcg_gen_movi_tl(t1, v1);
14211 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14212 break;
14213 case OPC_EXTRV_S_H:
14214 tcg_gen_movi_tl(t0, v2);
14215 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14216 break;
14217 case OPC_EXTRV_W:
14218 tcg_gen_movi_tl(t0, v2);
14219 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14220 break;
14221 case OPC_EXTRV_R_W:
14222 tcg_gen_movi_tl(t0, v2);
14223 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14224 break;
14225 case OPC_EXTRV_RS_W:
14226 tcg_gen_movi_tl(t0, v2);
14227 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14228 break;
14229 case OPC_EXTP:
14230 tcg_gen_movi_tl(t0, v2);
14231 tcg_gen_movi_tl(t1, v1);
14232 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14233 break;
14234 case OPC_EXTPV:
14235 tcg_gen_movi_tl(t0, v2);
14236 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14237 break;
14238 case OPC_EXTPDP:
14239 tcg_gen_movi_tl(t0, v2);
14240 tcg_gen_movi_tl(t1, v1);
14241 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14242 break;
14243 case OPC_EXTPDPV:
14244 tcg_gen_movi_tl(t0, v2);
14245 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14246 break;
14247 case OPC_SHILO:
14248 imm = (ctx->opcode >> 20) & 0x3F;
14249 tcg_gen_movi_tl(t0, ret);
14250 tcg_gen_movi_tl(t1, imm);
14251 gen_helper_shilo(t0, t1, cpu_env);
14252 break;
14253 case OPC_SHILOV:
14254 tcg_gen_movi_tl(t0, ret);
14255 gen_helper_shilo(t0, v1_t, cpu_env);
14256 break;
14257 case OPC_MTHLIP:
14258 tcg_gen_movi_tl(t0, ret);
14259 gen_helper_mthlip(t0, v1_t, cpu_env);
14260 break;
14261 case OPC_WRDSP:
14262 imm = (ctx->opcode >> 11) & 0x3FF;
14263 tcg_gen_movi_tl(t0, imm);
14264 gen_helper_wrdsp(v1_t, t0, cpu_env);
14265 break;
14266 case OPC_RDDSP:
14267 imm = (ctx->opcode >> 16) & 0x03FF;
14268 tcg_gen_movi_tl(t0, imm);
14269 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14270 break;
14271 }
14272 break;
14273#ifdef TARGET_MIPS64
14274 case OPC_DEXTR_W_DSP:
14275 check_dsp(ctx);
14276 switch (op2) {
14277 case OPC_DMTHLIP:
14278 tcg_gen_movi_tl(t0, ret);
14279 gen_helper_dmthlip(v1_t, t0, cpu_env);
14280 break;
14281 case OPC_DSHILO:
14282 {
14283 int shift = (ctx->opcode >> 19) & 0x7F;
14284 int ac = (ctx->opcode >> 11) & 0x03;
14285 tcg_gen_movi_tl(t0, shift);
14286 tcg_gen_movi_tl(t1, ac);
14287 gen_helper_dshilo(t0, t1, cpu_env);
14288 break;
14289 }
14290 case OPC_DSHILOV:
14291 {
14292 int ac = (ctx->opcode >> 11) & 0x03;
14293 tcg_gen_movi_tl(t0, ac);
14294 gen_helper_dshilo(v1_t, t0, cpu_env);
14295 break;
14296 }
14297 case OPC_DEXTP:
14298 tcg_gen_movi_tl(t0, v2);
14299 tcg_gen_movi_tl(t1, v1);
14300
14301 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14302 break;
14303 case OPC_DEXTPV:
14304 tcg_gen_movi_tl(t0, v2);
14305 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14306 break;
14307 case OPC_DEXTPDP:
14308 tcg_gen_movi_tl(t0, v2);
14309 tcg_gen_movi_tl(t1, v1);
14310 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14311 break;
14312 case OPC_DEXTPDPV:
14313 tcg_gen_movi_tl(t0, v2);
14314 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14315 break;
14316 case OPC_DEXTR_L:
14317 tcg_gen_movi_tl(t0, v2);
14318 tcg_gen_movi_tl(t1, v1);
14319 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14320 break;
14321 case OPC_DEXTR_R_L:
14322 tcg_gen_movi_tl(t0, v2);
14323 tcg_gen_movi_tl(t1, v1);
14324 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14325 break;
14326 case OPC_DEXTR_RS_L:
14327 tcg_gen_movi_tl(t0, v2);
14328 tcg_gen_movi_tl(t1, v1);
14329 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14330 break;
14331 case OPC_DEXTR_W:
14332 tcg_gen_movi_tl(t0, v2);
14333 tcg_gen_movi_tl(t1, v1);
14334 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14335 break;
14336 case OPC_DEXTR_R_W:
14337 tcg_gen_movi_tl(t0, v2);
14338 tcg_gen_movi_tl(t1, v1);
14339 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14340 break;
14341 case OPC_DEXTR_RS_W:
14342 tcg_gen_movi_tl(t0, v2);
14343 tcg_gen_movi_tl(t1, v1);
14344 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14345 break;
14346 case OPC_DEXTR_S_H:
14347 tcg_gen_movi_tl(t0, v2);
14348 tcg_gen_movi_tl(t1, v1);
14349 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14350 break;
14351 case OPC_DEXTRV_S_H:
14352 tcg_gen_movi_tl(t0, v2);
14353 tcg_gen_movi_tl(t1, v1);
14354 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14355 break;
14356 case OPC_DEXTRV_L:
14357 tcg_gen_movi_tl(t0, v2);
14358 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14359 break;
14360 case OPC_DEXTRV_R_L:
14361 tcg_gen_movi_tl(t0, v2);
14362 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14363 break;
14364 case OPC_DEXTRV_RS_L:
14365 tcg_gen_movi_tl(t0, v2);
14366 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14367 break;
14368 case OPC_DEXTRV_W:
14369 tcg_gen_movi_tl(t0, v2);
14370 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14371 break;
14372 case OPC_DEXTRV_R_W:
14373 tcg_gen_movi_tl(t0, v2);
14374 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14375 break;
14376 case OPC_DEXTRV_RS_W:
14377 tcg_gen_movi_tl(t0, v2);
14378 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14379 break;
14380 }
14381 break;
14382#endif
14383 }
14384
14385 tcg_temp_free(t0);
14386 tcg_temp_free(t1);
14387 tcg_temp_free(v1_t);
14388 tcg_temp_free(v2_t);
14389
14390 (void)opn; /* avoid a compiler warning */
14391 MIPS_DEBUG("%s", opn);
14392}
14393
9b1a1d68
JL
14394/* End MIPSDSP functions. */
14395
240ce26a 14396static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14397{
14398 int32_t offset;
14399 int rs, rt, rd, sa;
14400 uint32_t op, op1, op2;
14401 int16_t imm;
14402
14403 /* make sure instructions are on a word boundary */
14404 if (ctx->pc & 0x3) {
14405 env->CP0_BadVAddr = ctx->pc;
14406 generate_exception(ctx, EXCP_AdEL);
14407 return;
14408 }
14409
14410 /* Handle blikely not taken case */
14411 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14412 int l1 = gen_new_label();
14413
14414 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14415 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14416 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14417 gen_goto_tb(ctx, 1, ctx->pc + 4);
14418 gen_set_label(l1);
14419 }
14420
fdefe51c 14421 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14422 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14423 }
3c824109
NF
14424
14425 op = MASK_OP_MAJOR(ctx->opcode);
14426 rs = (ctx->opcode >> 21) & 0x1f;
14427 rt = (ctx->opcode >> 16) & 0x1f;
14428 rd = (ctx->opcode >> 11) & 0x1f;
14429 sa = (ctx->opcode >> 6) & 0x1f;
14430 imm = (int16_t)ctx->opcode;
14431 switch (op) {
7a387fff
TS
14432 case OPC_SPECIAL:
14433 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14434 switch (op1) {
324d9e32
AJ
14435 case OPC_SLL: /* Shift with immediate */
14436 case OPC_SRA:
d75c135e 14437 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14438 break;
ea63e2c3
NF
14439 case OPC_SRL:
14440 switch ((ctx->opcode >> 21) & 0x1f) {
14441 case 1:
14442 /* rotr is decoded as srl on non-R2 CPUs */
d75c135e 14443 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14444 op1 = OPC_ROTR;
14445 }
14446 /* Fallthrough */
14447 case 0:
d75c135e 14448 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14449 break;
14450 default:
14451 generate_exception(ctx, EXCP_RI);
14452 break;
14453 }
14454 break;
460f00c4
AJ
14455 case OPC_MOVN: /* Conditional move */
14456 case OPC_MOVZ:
d75c135e 14457 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
aa8f4009 14458 INSN_LOONGSON2E | INSN_LOONGSON2F);
d75c135e 14459 gen_cond_move(ctx, op1, rd, rs, rt);
460f00c4
AJ
14460 break;
14461 case OPC_ADD ... OPC_SUBU:
d75c135e 14462 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14463 break;
460f00c4 14464 case OPC_SLLV: /* Shifts */
460f00c4 14465 case OPC_SRAV:
d75c135e 14466 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14467 break;
ea63e2c3
NF
14468 case OPC_SRLV:
14469 switch ((ctx->opcode >> 6) & 0x1f) {
14470 case 1:
14471 /* rotrv is decoded as srlv on non-R2 CPUs */
d75c135e 14472 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14473 op1 = OPC_ROTRV;
14474 }
14475 /* Fallthrough */
14476 case 0:
d75c135e 14477 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14478 break;
14479 default:
14480 generate_exception(ctx, EXCP_RI);
14481 break;
14482 }
14483 break;
460f00c4
AJ
14484 case OPC_SLT: /* Set on less than */
14485 case OPC_SLTU:
d75c135e 14486 gen_slt(ctx, op1, rd, rs, rt);
460f00c4
AJ
14487 break;
14488 case OPC_AND: /* Logic*/
14489 case OPC_OR:
14490 case OPC_NOR:
14491 case OPC_XOR:
d75c135e 14492 gen_logic(ctx, op1, rd, rs, rt);
460f00c4 14493 break;
26135ead
RS
14494 case OPC_MULT:
14495 case OPC_MULTU:
e9c71dd1 14496 if (sa) {
d75c135e 14497 check_insn(ctx, INSN_VR54XX);
e9c71dd1
TS
14498 op1 = MASK_MUL_VR54XX(ctx->opcode);
14499 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
26135ead
RS
14500 } else {
14501 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14502 }
14503 break;
14504 case OPC_DIV:
14505 case OPC_DIVU:
14506 gen_muldiv(ctx, op1, 0, rs, rt);
7a387fff
TS
14507 break;
14508 case OPC_JR ... OPC_JALR:
7dca4ad0 14509 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061 14510 break;
7a387fff
TS
14511 case OPC_TGE ... OPC_TEQ: /* Traps */
14512 case OPC_TNE:
14513 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14514 break;
7a387fff
TS
14515 case OPC_MFHI: /* Move from HI/LO */
14516 case OPC_MFLO:
26135ead 14517 gen_HILO(ctx, op1, rs & 3, rd);
6af0bf9c 14518 break;
7a387fff
TS
14519 case OPC_MTHI:
14520 case OPC_MTLO: /* Move to HI/LO */
26135ead 14521 gen_HILO(ctx, op1, rd & 3, rs);
6af0bf9c 14522 break;
b48cfdff
TS
14523 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14524#ifdef MIPS_STRICT_STANDARD
14525 MIPS_INVAL("PMON / selsl");
14526 generate_exception(ctx, EXCP_RI);
14527#else
895c2d04 14528 gen_helper_0e0i(pmon, sa);
b48cfdff 14529#endif
7a387fff
TS
14530 break;
14531 case OPC_SYSCALL:
6af0bf9c 14532 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14533 ctx->bstate = BS_STOP;
6af0bf9c 14534 break;
7a387fff 14535 case OPC_BREAK:
6af0bf9c
FB
14536 generate_exception(ctx, EXCP_BREAK);
14537 break;
b48cfdff
TS
14538 case OPC_SPIM:
14539#ifdef MIPS_STRICT_STANDARD
14540 MIPS_INVAL("SPIM");
14541 generate_exception(ctx, EXCP_RI);
14542#else
7a387fff
TS
14543 /* Implemented as RI exception for now. */
14544 MIPS_INVAL("spim (unofficial)");
14545 generate_exception(ctx, EXCP_RI);
b48cfdff 14546#endif
6af0bf9c 14547 break;
7a387fff 14548 case OPC_SYNC:
ead9360e 14549 /* Treat as NOP. */
6af0bf9c 14550 break;
4ad40f36 14551
7a387fff 14552 case OPC_MOVCI:
d75c135e 14553 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14554 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14555 check_cp1_enabled(ctx);
36d23958
TS
14556 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14557 (ctx->opcode >> 16) & 1);
14558 } else {
e397ee33 14559 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14560 }
4ad40f36
FB
14561 break;
14562
d26bc211 14563#if defined(TARGET_MIPS64)
7a387fff
TS
14564 /* MIPS64 specific opcodes */
14565 case OPC_DSLL:
324d9e32 14566 case OPC_DSRA:
7a387fff 14567 case OPC_DSLL32:
324d9e32 14568 case OPC_DSRA32:
d75c135e 14569 check_insn(ctx, ISA_MIPS3);
e189e748 14570 check_mips_64(ctx);
d75c135e 14571 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14572 break;
ea63e2c3
NF
14573 case OPC_DSRL:
14574 switch ((ctx->opcode >> 21) & 0x1f) {
14575 case 1:
14576 /* drotr is decoded as dsrl on non-R2 CPUs */
d75c135e 14577 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14578 op1 = OPC_DROTR;
14579 }
14580 /* Fallthrough */
14581 case 0:
d75c135e 14582 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14583 check_mips_64(ctx);
d75c135e 14584 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14585 break;
14586 default:
14587 generate_exception(ctx, EXCP_RI);
14588 break;
14589 }
14590 break;
14591 case OPC_DSRL32:
14592 switch ((ctx->opcode >> 21) & 0x1f) {
14593 case 1:
14594 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
d75c135e 14595 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14596 op1 = OPC_DROTR32;
14597 }
14598 /* Fallthrough */
14599 case 0:
d75c135e 14600 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14601 check_mips_64(ctx);
d75c135e 14602 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14603 break;
14604 default:
14605 generate_exception(ctx, EXCP_RI);
14606 break;
14607 }
14608 break;
7a387fff 14609 case OPC_DADD ... OPC_DSUBU:
d75c135e 14610 check_insn(ctx, ISA_MIPS3);
e189e748 14611 check_mips_64(ctx);
d75c135e 14612 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14613 break;
460f00c4
AJ
14614 case OPC_DSLLV:
14615 case OPC_DSRAV:
d75c135e 14616 check_insn(ctx, ISA_MIPS3);
460f00c4 14617 check_mips_64(ctx);
d75c135e 14618 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14619 break;
ea63e2c3
NF
14620 case OPC_DSRLV:
14621 switch ((ctx->opcode >> 6) & 0x1f) {
14622 case 1:
14623 /* drotrv is decoded as dsrlv on non-R2 CPUs */
d75c135e 14624 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14625 op1 = OPC_DROTRV;
14626 }
14627 /* Fallthrough */
14628 case 0:
d75c135e 14629 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14630 check_mips_64(ctx);
d75c135e 14631 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14632 break;
14633 default:
14634 generate_exception(ctx, EXCP_RI);
14635 break;
14636 }
14637 break;
7a387fff 14638 case OPC_DMULT ... OPC_DDIVU:
d75c135e 14639 check_insn(ctx, ISA_MIPS3);
e189e748 14640 check_mips_64(ctx);
26135ead 14641 gen_muldiv(ctx, op1, 0, rs, rt);
7a387fff 14642 break;
6af0bf9c
FB
14643#endif
14644 default: /* Invalid */
14645 MIPS_INVAL("special");
14646 generate_exception(ctx, EXCP_RI);
14647 break;
14648 }
14649 break;
7a387fff
TS
14650 case OPC_SPECIAL2:
14651 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14652 switch (op1) {
7a387fff
TS
14653 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14654 case OPC_MSUB ... OPC_MSUBU:
d75c135e 14655 check_insn(ctx, ISA_MIPS32);
26135ead 14656 gen_muldiv(ctx, op1, rd & 3, rs, rt);
6af0bf9c 14657 break;
7a387fff 14658 case OPC_MUL:
d75c135e 14659 gen_arith(ctx, op1, rd, rs, rt);
6af0bf9c 14660 break;
20e1fb52
AJ
14661 case OPC_CLO:
14662 case OPC_CLZ:
d75c135e 14663 check_insn(ctx, ISA_MIPS32);
7a387fff 14664 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14665 break;
7a387fff 14666 case OPC_SDBBP:
6af0bf9c
FB
14667 /* XXX: not clear which exception should be raised
14668 * when in debug mode...
14669 */
d75c135e 14670 check_insn(ctx, ISA_MIPS32);
6af0bf9c
FB
14671 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14672 generate_exception(ctx, EXCP_DBp);
14673 } else {
14674 generate_exception(ctx, EXCP_DBp);
14675 }
ead9360e 14676 /* Treat as NOP. */
6af0bf9c 14677 break;
161f85e6
AJ
14678 case OPC_DIV_G_2F:
14679 case OPC_DIVU_G_2F:
14680 case OPC_MULT_G_2F:
14681 case OPC_MULTU_G_2F:
14682 case OPC_MOD_G_2F:
14683 case OPC_MODU_G_2F:
d75c135e 14684 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14685 gen_loongson_integer(ctx, op1, rd, rs, rt);
14686 break;
d26bc211 14687#if defined(TARGET_MIPS64)
20e1fb52
AJ
14688 case OPC_DCLO:
14689 case OPC_DCLZ:
d75c135e 14690 check_insn(ctx, ISA_MIPS64);
e189e748 14691 check_mips_64(ctx);
7a387fff
TS
14692 gen_cl(ctx, op1, rd, rs);
14693 break;
161f85e6
AJ
14694 case OPC_DMULT_G_2F:
14695 case OPC_DMULTU_G_2F:
14696 case OPC_DDIV_G_2F:
14697 case OPC_DDIVU_G_2F:
14698 case OPC_DMOD_G_2F:
14699 case OPC_DMODU_G_2F:
d75c135e 14700 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14701 gen_loongson_integer(ctx, op1, rd, rs, rt);
14702 break;
7a387fff 14703#endif
6af0bf9c
FB
14704 default: /* Invalid */
14705 MIPS_INVAL("special2");
14706 generate_exception(ctx, EXCP_RI);
14707 break;
14708 }
14709 break;
7a387fff 14710 case OPC_SPECIAL3:
2b0233ab
TS
14711 op1 = MASK_SPECIAL3(ctx->opcode);
14712 switch (op1) {
14713 case OPC_EXT:
14714 case OPC_INS:
d75c135e 14715 check_insn(ctx, ISA_MIPS32R2);
2b0233ab
TS
14716 gen_bitops(ctx, op1, rt, rs, sa, rd);
14717 break;
14718 case OPC_BSHFL:
d75c135e 14719 check_insn(ctx, ISA_MIPS32R2);
2b0233ab 14720 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14721 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14722 break;
1579a72e 14723 case OPC_RDHWR:
d75c135e 14724 gen_rdhwr(ctx, rt, rd);
1579a72e 14725 break;
ead9360e 14726 case OPC_FORK:
d75c135e 14727 check_insn(ctx, ASE_MT);
6c5c1e20 14728 {
35fbce2c
AJ
14729 TCGv t0 = tcg_temp_new();
14730 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14731
14732 gen_load_gpr(t0, rt);
14733 gen_load_gpr(t1, rs);
a7812ae4 14734 gen_helper_fork(t0, t1);
6c5c1e20
TS
14735 tcg_temp_free(t0);
14736 tcg_temp_free(t1);
14737 }
ead9360e
TS
14738 break;
14739 case OPC_YIELD:
d75c135e 14740 check_insn(ctx, ASE_MT);
6c5c1e20 14741 {
35fbce2c 14742 TCGv t0 = tcg_temp_new();
6c5c1e20 14743
35fbce2c 14744 save_cpu_state(ctx, 1);
6c5c1e20 14745 gen_load_gpr(t0, rs);
895c2d04 14746 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14747 gen_store_gpr(t0, rd);
14748 tcg_temp_free(t0);
14749 }
ead9360e 14750 break;
161f85e6 14751 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14752 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14753 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14754 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14755 * the same mask and op1. */
d75c135e 14756 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
461c08df
JL
14757 op2 = MASK_ADDUH_QB(ctx->opcode);
14758 switch (op2) {
14759 case OPC_ADDUH_QB:
14760 case OPC_ADDUH_R_QB:
14761 case OPC_ADDQH_PH:
14762 case OPC_ADDQH_R_PH:
14763 case OPC_ADDQH_W:
14764 case OPC_ADDQH_R_W:
14765 case OPC_SUBUH_QB:
14766 case OPC_SUBUH_R_QB:
14767 case OPC_SUBQH_PH:
14768 case OPC_SUBQH_R_PH:
14769 case OPC_SUBQH_W:
14770 case OPC_SUBQH_R_W:
14771 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14772 break;
a22260ae
JL
14773 case OPC_MUL_PH:
14774 case OPC_MUL_S_PH:
14775 case OPC_MULQ_S_W:
14776 case OPC_MULQ_RS_W:
14777 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14778 break;
461c08df
JL
14779 default:
14780 MIPS_INVAL("MASK ADDUH.QB");
14781 generate_exception(ctx, EXCP_RI);
14782 break;
14783 }
d75c135e 14784 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
461c08df
JL
14785 gen_loongson_integer(ctx, op1, rd, rs, rt);
14786 } else {
14787 generate_exception(ctx, EXCP_RI);
14788 }
161f85e6 14789 break;
9b1a1d68
JL
14790 case OPC_LX_DSP:
14791 op2 = MASK_LX(ctx->opcode);
14792 switch (op2) {
14793#if defined(TARGET_MIPS64)
14794 case OPC_LDX:
14795#endif
14796 case OPC_LBUX:
14797 case OPC_LHX:
14798 case OPC_LWX:
d75c135e 14799 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
9b1a1d68
JL
14800 break;
14801 default: /* Invalid */
14802 MIPS_INVAL("MASK LX");
14803 generate_exception(ctx, EXCP_RI);
14804 break;
14805 }
14806 break;
461c08df
JL
14807 case OPC_ABSQ_S_PH_DSP:
14808 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14809 switch (op2) {
14810 case OPC_ABSQ_S_QB:
14811 case OPC_ABSQ_S_PH:
14812 case OPC_ABSQ_S_W:
14813 case OPC_PRECEQ_W_PHL:
14814 case OPC_PRECEQ_W_PHR:
14815 case OPC_PRECEQU_PH_QBL:
14816 case OPC_PRECEQU_PH_QBR:
14817 case OPC_PRECEQU_PH_QBLA:
14818 case OPC_PRECEQU_PH_QBRA:
14819 case OPC_PRECEU_PH_QBL:
14820 case OPC_PRECEU_PH_QBR:
14821 case OPC_PRECEU_PH_QBLA:
14822 case OPC_PRECEU_PH_QBRA:
14823 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14824 break;
1cb6686c
JL
14825 case OPC_BITREV:
14826 case OPC_REPL_QB:
14827 case OPC_REPLV_QB:
14828 case OPC_REPL_PH:
14829 case OPC_REPLV_PH:
d75c135e 14830 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 14831 break;
461c08df
JL
14832 default:
14833 MIPS_INVAL("MASK ABSQ_S.PH");
14834 generate_exception(ctx, EXCP_RI);
14835 break;
14836 }
14837 break;
14838 case OPC_ADDU_QB_DSP:
14839 op2 = MASK_ADDU_QB(ctx->opcode);
14840 switch (op2) {
14841 case OPC_ADDQ_PH:
14842 case OPC_ADDQ_S_PH:
14843 case OPC_ADDQ_S_W:
14844 case OPC_ADDU_QB:
14845 case OPC_ADDU_S_QB:
14846 case OPC_ADDU_PH:
14847 case OPC_ADDU_S_PH:
14848 case OPC_SUBQ_PH:
14849 case OPC_SUBQ_S_PH:
14850 case OPC_SUBQ_S_W:
14851 case OPC_SUBU_QB:
14852 case OPC_SUBU_S_QB:
14853 case OPC_SUBU_PH:
14854 case OPC_SUBU_S_PH:
14855 case OPC_ADDSC:
14856 case OPC_ADDWC:
14857 case OPC_MODSUB:
14858 case OPC_RADDU_W_QB:
14859 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14860 break;
a22260ae
JL
14861 case OPC_MULEU_S_PH_QBL:
14862 case OPC_MULEU_S_PH_QBR:
14863 case OPC_MULQ_RS_PH:
14864 case OPC_MULEQ_S_W_PHL:
14865 case OPC_MULEQ_S_W_PHR:
14866 case OPC_MULQ_S_PH:
14867 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14868 break;
461c08df
JL
14869 default: /* Invalid */
14870 MIPS_INVAL("MASK ADDU.QB");
14871 generate_exception(ctx, EXCP_RI);
14872 break;
14873
14874 }
14875 break;
14876 case OPC_CMPU_EQ_QB_DSP:
14877 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14878 switch (op2) {
14879 case OPC_PRECR_SRA_PH_W:
14880 case OPC_PRECR_SRA_R_PH_W:
14881 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14882 break;
14883 case OPC_PRECR_QB_PH:
14884 case OPC_PRECRQ_QB_PH:
14885 case OPC_PRECRQ_PH_W:
14886 case OPC_PRECRQ_RS_PH_W:
14887 case OPC_PRECRQU_S_QB_PH:
14888 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14889 break;
26690560
JL
14890 case OPC_CMPU_EQ_QB:
14891 case OPC_CMPU_LT_QB:
14892 case OPC_CMPU_LE_QB:
14893 case OPC_CMP_EQ_PH:
14894 case OPC_CMP_LT_PH:
14895 case OPC_CMP_LE_PH:
14896 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14897 break;
14898 case OPC_CMPGU_EQ_QB:
14899 case OPC_CMPGU_LT_QB:
14900 case OPC_CMPGU_LE_QB:
14901 case OPC_CMPGDU_EQ_QB:
14902 case OPC_CMPGDU_LT_QB:
14903 case OPC_CMPGDU_LE_QB:
14904 case OPC_PICK_QB:
14905 case OPC_PICK_PH:
14906 case OPC_PACKRL_PH:
14907 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14908 break;
461c08df
JL
14909 default: /* Invalid */
14910 MIPS_INVAL("MASK CMPU.EQ.QB");
14911 generate_exception(ctx, EXCP_RI);
14912 break;
14913 }
14914 break;
77c5fa8b
JL
14915 case OPC_SHLL_QB_DSP:
14916 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14917 break;
a22260ae
JL
14918 case OPC_DPA_W_PH_DSP:
14919 op2 = MASK_DPA_W_PH(ctx->opcode);
14920 switch (op2) {
14921 case OPC_DPAU_H_QBL:
14922 case OPC_DPAU_H_QBR:
14923 case OPC_DPSU_H_QBL:
14924 case OPC_DPSU_H_QBR:
14925 case OPC_DPA_W_PH:
14926 case OPC_DPAX_W_PH:
14927 case OPC_DPAQ_S_W_PH:
14928 case OPC_DPAQX_S_W_PH:
14929 case OPC_DPAQX_SA_W_PH:
14930 case OPC_DPS_W_PH:
14931 case OPC_DPSX_W_PH:
14932 case OPC_DPSQ_S_W_PH:
14933 case OPC_DPSQX_S_W_PH:
14934 case OPC_DPSQX_SA_W_PH:
14935 case OPC_MULSAQ_S_W_PH:
14936 case OPC_DPAQ_SA_L_W:
14937 case OPC_DPSQ_SA_L_W:
14938 case OPC_MAQ_S_W_PHL:
14939 case OPC_MAQ_S_W_PHR:
14940 case OPC_MAQ_SA_W_PHL:
14941 case OPC_MAQ_SA_W_PHR:
14942 case OPC_MULSA_W_PH:
14943 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14944 break;
14945 default: /* Invalid */
14946 MIPS_INVAL("MASK DPAW.PH");
14947 generate_exception(ctx, EXCP_RI);
14948 break;
14949 }
14950 break;
1cb6686c
JL
14951 case OPC_INSV_DSP:
14952 op2 = MASK_INSV(ctx->opcode);
14953 switch (op2) {
14954 case OPC_INSV:
14955 check_dsp(ctx);
14956 {
14957 TCGv t0, t1;
14958
14959 if (rt == 0) {
14960 MIPS_DEBUG("NOP");
14961 break;
14962 }
14963
14964 t0 = tcg_temp_new();
14965 t1 = tcg_temp_new();
14966
14967 gen_load_gpr(t0, rt);
14968 gen_load_gpr(t1, rs);
14969
14970 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14971
14972 tcg_temp_free(t0);
14973 tcg_temp_free(t1);
14974 break;
14975 }
14976 default: /* Invalid */
14977 MIPS_INVAL("MASK INSV");
14978 generate_exception(ctx, EXCP_RI);
14979 break;
14980 }
14981 break;
26690560 14982 case OPC_APPEND_DSP:
df6126a7 14983 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 14984 break;
b53371ed
JL
14985 case OPC_EXTR_W_DSP:
14986 op2 = MASK_EXTR_W(ctx->opcode);
14987 switch (op2) {
14988 case OPC_EXTR_W:
14989 case OPC_EXTR_R_W:
14990 case OPC_EXTR_RS_W:
14991 case OPC_EXTR_S_H:
14992 case OPC_EXTRV_S_H:
14993 case OPC_EXTRV_W:
14994 case OPC_EXTRV_R_W:
14995 case OPC_EXTRV_RS_W:
14996 case OPC_EXTP:
14997 case OPC_EXTPV:
14998 case OPC_EXTPDP:
14999 case OPC_EXTPDPV:
15000 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15001 break;
15002 case OPC_RDDSP:
15003 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
15004 break;
15005 case OPC_SHILO:
15006 case OPC_SHILOV:
15007 case OPC_MTHLIP:
15008 case OPC_WRDSP:
15009 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15010 break;
15011 default: /* Invalid */
15012 MIPS_INVAL("MASK EXTR.W");
15013 generate_exception(ctx, EXCP_RI);
15014 break;
15015 }
15016 break;
d26bc211 15017#if defined(TARGET_MIPS64)
1579a72e
TS
15018 case OPC_DEXTM ... OPC_DEXT:
15019 case OPC_DINSM ... OPC_DINS:
d75c135e 15020 check_insn(ctx, ISA_MIPS64R2);
e189e748 15021 check_mips_64(ctx);
1579a72e 15022 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 15023 break;
1579a72e 15024 case OPC_DBSHFL:
d75c135e 15025 check_insn(ctx, ISA_MIPS64R2);
e189e748 15026 check_mips_64(ctx);
1579a72e 15027 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 15028 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 15029 break;
161f85e6
AJ
15030 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15031 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15032 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
d75c135e 15033 check_insn(ctx, INSN_LOONGSON2E);
161f85e6
AJ
15034 gen_loongson_integer(ctx, op1, rd, rs, rt);
15035 break;
461c08df
JL
15036 case OPC_ABSQ_S_QH_DSP:
15037 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15038 switch (op2) {
15039 case OPC_PRECEQ_L_PWL:
15040 case OPC_PRECEQ_L_PWR:
15041 case OPC_PRECEQ_PW_QHL:
15042 case OPC_PRECEQ_PW_QHR:
15043 case OPC_PRECEQ_PW_QHLA:
15044 case OPC_PRECEQ_PW_QHRA:
15045 case OPC_PRECEQU_QH_OBL:
15046 case OPC_PRECEQU_QH_OBR:
15047 case OPC_PRECEQU_QH_OBLA:
15048 case OPC_PRECEQU_QH_OBRA:
15049 case OPC_PRECEU_QH_OBL:
15050 case OPC_PRECEU_QH_OBR:
15051 case OPC_PRECEU_QH_OBLA:
15052 case OPC_PRECEU_QH_OBRA:
15053 case OPC_ABSQ_S_OB:
15054 case OPC_ABSQ_S_PW:
15055 case OPC_ABSQ_S_QH:
15056 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15057 break;
1cb6686c
JL
15058 case OPC_REPL_OB:
15059 case OPC_REPL_PW:
15060 case OPC_REPL_QH:
15061 case OPC_REPLV_OB:
15062 case OPC_REPLV_PW:
15063 case OPC_REPLV_QH:
d75c135e 15064 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 15065 break;
461c08df
JL
15066 default: /* Invalid */
15067 MIPS_INVAL("MASK ABSQ_S.QH");
15068 generate_exception(ctx, EXCP_RI);
15069 break;
15070 }
15071 break;
15072 case OPC_ADDU_OB_DSP:
15073 op2 = MASK_ADDU_OB(ctx->opcode);
15074 switch (op2) {
15075 case OPC_RADDU_L_OB:
15076 case OPC_SUBQ_PW:
15077 case OPC_SUBQ_S_PW:
15078 case OPC_SUBQ_QH:
15079 case OPC_SUBQ_S_QH:
15080 case OPC_SUBU_OB:
15081 case OPC_SUBU_S_OB:
15082 case OPC_SUBU_QH:
15083 case OPC_SUBU_S_QH:
15084 case OPC_SUBUH_OB:
15085 case OPC_SUBUH_R_OB:
15086 case OPC_ADDQ_PW:
15087 case OPC_ADDQ_S_PW:
15088 case OPC_ADDQ_QH:
15089 case OPC_ADDQ_S_QH:
15090 case OPC_ADDU_OB:
15091 case OPC_ADDU_S_OB:
15092 case OPC_ADDU_QH:
15093 case OPC_ADDU_S_QH:
15094 case OPC_ADDUH_OB:
15095 case OPC_ADDUH_R_OB:
15096 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15097 break;
a22260ae
JL
15098 case OPC_MULEQ_S_PW_QHL:
15099 case OPC_MULEQ_S_PW_QHR:
15100 case OPC_MULEU_S_QH_OBL:
15101 case OPC_MULEU_S_QH_OBR:
15102 case OPC_MULQ_RS_QH:
15103 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15104 break;
461c08df
JL
15105 default: /* Invalid */
15106 MIPS_INVAL("MASK ADDU.OB");
15107 generate_exception(ctx, EXCP_RI);
15108 break;
15109 }
15110 break;
15111 case OPC_CMPU_EQ_OB_DSP:
15112 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15113 switch (op2) {
15114 case OPC_PRECR_SRA_QH_PW:
15115 case OPC_PRECR_SRA_R_QH_PW:
15116 /* Return value is rt. */
15117 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15118 break;
15119 case OPC_PRECR_OB_QH:
15120 case OPC_PRECRQ_OB_QH:
15121 case OPC_PRECRQ_PW_L:
15122 case OPC_PRECRQ_QH_PW:
15123 case OPC_PRECRQ_RS_QH_PW:
15124 case OPC_PRECRQU_S_OB_QH:
15125 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15126 break;
26690560
JL
15127 case OPC_CMPU_EQ_OB:
15128 case OPC_CMPU_LT_OB:
15129 case OPC_CMPU_LE_OB:
15130 case OPC_CMP_EQ_QH:
15131 case OPC_CMP_LT_QH:
15132 case OPC_CMP_LE_QH:
15133 case OPC_CMP_EQ_PW:
15134 case OPC_CMP_LT_PW:
15135 case OPC_CMP_LE_PW:
15136 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15137 break;
15138 case OPC_CMPGDU_EQ_OB:
15139 case OPC_CMPGDU_LT_OB:
15140 case OPC_CMPGDU_LE_OB:
15141 case OPC_CMPGU_EQ_OB:
15142 case OPC_CMPGU_LT_OB:
15143 case OPC_CMPGU_LE_OB:
15144 case OPC_PACKRL_PW:
15145 case OPC_PICK_OB:
15146 case OPC_PICK_PW:
15147 case OPC_PICK_QH:
15148 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15149 break;
461c08df
JL
15150 default: /* Invalid */
15151 MIPS_INVAL("MASK CMPU_EQ.OB");
15152 generate_exception(ctx, EXCP_RI);
15153 break;
15154 }
15155 break;
26690560 15156 case OPC_DAPPEND_DSP:
df6126a7 15157 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 15158 break;
b53371ed
JL
15159 case OPC_DEXTR_W_DSP:
15160 op2 = MASK_DEXTR_W(ctx->opcode);
15161 switch (op2) {
15162 case OPC_DEXTP:
15163 case OPC_DEXTPDP:
15164 case OPC_DEXTPDPV:
15165 case OPC_DEXTPV:
15166 case OPC_DEXTR_L:
15167 case OPC_DEXTR_R_L:
15168 case OPC_DEXTR_RS_L:
15169 case OPC_DEXTR_W:
15170 case OPC_DEXTR_R_W:
15171 case OPC_DEXTR_RS_W:
15172 case OPC_DEXTR_S_H:
15173 case OPC_DEXTRV_L:
15174 case OPC_DEXTRV_R_L:
15175 case OPC_DEXTRV_RS_L:
15176 case OPC_DEXTRV_S_H:
15177 case OPC_DEXTRV_W:
15178 case OPC_DEXTRV_R_W:
15179 case OPC_DEXTRV_RS_W:
15180 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15181 break;
15182 case OPC_DMTHLIP:
15183 case OPC_DSHILO:
15184 case OPC_DSHILOV:
15185 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15186 break;
15187 default: /* Invalid */
15188 MIPS_INVAL("MASK EXTR.W");
15189 generate_exception(ctx, EXCP_RI);
15190 break;
15191 }
15192 break;
a22260ae
JL
15193 case OPC_DPAQ_W_QH_DSP:
15194 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15195 switch (op2) {
15196 case OPC_DPAU_H_OBL:
15197 case OPC_DPAU_H_OBR:
15198 case OPC_DPSU_H_OBL:
15199 case OPC_DPSU_H_OBR:
15200 case OPC_DPA_W_QH:
15201 case OPC_DPAQ_S_W_QH:
15202 case OPC_DPS_W_QH:
15203 case OPC_DPSQ_S_W_QH:
15204 case OPC_MULSAQ_S_W_QH:
15205 case OPC_DPAQ_SA_L_PW:
15206 case OPC_DPSQ_SA_L_PW:
15207 case OPC_MULSAQ_S_L_PW:
15208 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15209 break;
15210 case OPC_MAQ_S_W_QHLL:
15211 case OPC_MAQ_S_W_QHLR:
15212 case OPC_MAQ_S_W_QHRL:
15213 case OPC_MAQ_S_W_QHRR:
15214 case OPC_MAQ_SA_W_QHLL:
15215 case OPC_MAQ_SA_W_QHLR:
15216 case OPC_MAQ_SA_W_QHRL:
15217 case OPC_MAQ_SA_W_QHRR:
15218 case OPC_MAQ_S_L_PWL:
15219 case OPC_MAQ_S_L_PWR:
15220 case OPC_DMADD:
15221 case OPC_DMADDU:
15222 case OPC_DMSUB:
15223 case OPC_DMSUBU:
15224 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15225 break;
15226 default: /* Invalid */
15227 MIPS_INVAL("MASK DPAQ.W.QH");
15228 generate_exception(ctx, EXCP_RI);
15229 break;
15230 }
15231 break;
1cb6686c
JL
15232 case OPC_DINSV_DSP:
15233 op2 = MASK_INSV(ctx->opcode);
15234 switch (op2) {
15235 case OPC_DINSV:
15236 {
15237 TCGv t0, t1;
15238
15239 if (rt == 0) {
15240 MIPS_DEBUG("NOP");
15241 break;
15242 }
15243 check_dsp(ctx);
15244
15245 t0 = tcg_temp_new();
15246 t1 = tcg_temp_new();
15247
15248 gen_load_gpr(t0, rt);
15249 gen_load_gpr(t1, rs);
15250
15251 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15252 break;
15253 }
15254 default: /* Invalid */
15255 MIPS_INVAL("MASK DINSV");
15256 generate_exception(ctx, EXCP_RI);
15257 break;
15258 }
15259 break;
77c5fa8b
JL
15260 case OPC_SHLL_OB_DSP:
15261 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15262 break;
7a387fff
TS
15263#endif
15264 default: /* Invalid */
15265 MIPS_INVAL("special3");
15266 generate_exception(ctx, EXCP_RI);
15267 break;
15268 }
15269 break;
15270 case OPC_REGIMM:
15271 op1 = MASK_REGIMM(ctx->opcode);
15272 switch (op1) {
15273 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15274 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15275 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061 15276 break;
7a387fff
TS
15277 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15278 case OPC_TNEI:
15279 gen_trap(ctx, op1, rs, -1, imm);
15280 break;
15281 case OPC_SYNCI:
d75c135e 15282 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15283 /* Treat as NOP. */
6af0bf9c 15284 break;
e45a93e2
JL
15285 case OPC_BPOSGE32: /* MIPS DSP branch */
15286#if defined(TARGET_MIPS64)
15287 case OPC_BPOSGE64:
15288#endif
15289 check_dsp(ctx);
15290 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
e45a93e2 15291 break;
6af0bf9c 15292 default: /* Invalid */
923617a3 15293 MIPS_INVAL("regimm");
6af0bf9c
FB
15294 generate_exception(ctx, EXCP_RI);
15295 break;
15296 }
15297 break;
7a387fff 15298 case OPC_CP0:
387a8fe5 15299 check_cp0_enabled(ctx);
7a387fff 15300 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15301 switch (op1) {
7a387fff
TS
15302 case OPC_MFC0:
15303 case OPC_MTC0:
ead9360e
TS
15304 case OPC_MFTR:
15305 case OPC_MTTR:
d26bc211 15306#if defined(TARGET_MIPS64)
7a387fff
TS
15307 case OPC_DMFC0:
15308 case OPC_DMTC0:
15309#endif
f1aa6320 15310#ifndef CONFIG_USER_ONLY
932e71cd 15311 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15312#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15313 break;
15314 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15315#ifndef CONFIG_USER_ONLY
932e71cd 15316 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15317#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15318 break;
15319 case OPC_MFMC0:
8706c382 15320#ifndef CONFIG_USER_ONLY
932e71cd 15321 {
35fbce2c 15322 TCGv t0 = tcg_temp_new();
6c5c1e20 15323
0eaef5aa 15324 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15325 switch (op2) {
15326 case OPC_DMT:
d75c135e 15327 check_insn(ctx, ASE_MT);
9ed5726c 15328 gen_helper_dmt(t0);
35fbce2c 15329 gen_store_gpr(t0, rt);
6c5c1e20
TS
15330 break;
15331 case OPC_EMT:
d75c135e 15332 check_insn(ctx, ASE_MT);
9ed5726c 15333 gen_helper_emt(t0);
35fbce2c 15334 gen_store_gpr(t0, rt);
da80682b 15335 break;
6c5c1e20 15336 case OPC_DVPE:
d75c135e 15337 check_insn(ctx, ASE_MT);
895c2d04 15338 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15339 gen_store_gpr(t0, rt);
6c5c1e20
TS
15340 break;
15341 case OPC_EVPE:
d75c135e 15342 check_insn(ctx, ASE_MT);
895c2d04 15343 gen_helper_evpe(t0, cpu_env);
35fbce2c 15344 gen_store_gpr(t0, rt);
6c5c1e20
TS
15345 break;
15346 case OPC_DI:
d75c135e 15347 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15348 save_cpu_state(ctx, 1);
895c2d04 15349 gen_helper_di(t0, cpu_env);
35fbce2c 15350 gen_store_gpr(t0, rt);
6c5c1e20
TS
15351 /* Stop translation as we may have switched the execution mode */
15352 ctx->bstate = BS_STOP;
15353 break;
15354 case OPC_EI:
d75c135e 15355 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15356 save_cpu_state(ctx, 1);
895c2d04 15357 gen_helper_ei(t0, cpu_env);
35fbce2c 15358 gen_store_gpr(t0, rt);
6c5c1e20
TS
15359 /* Stop translation as we may have switched the execution mode */
15360 ctx->bstate = BS_STOP;
15361 break;
15362 default: /* Invalid */
15363 MIPS_INVAL("mfmc0");
15364 generate_exception(ctx, EXCP_RI);
15365 break;
15366 }
6c5c1e20 15367 tcg_temp_free(t0);
7a387fff 15368 }
0eaef5aa 15369#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15370 break;
7a387fff 15371 case OPC_RDPGPR:
d75c135e 15372 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15373 gen_load_srsgpr(rt, rd);
ead9360e 15374 break;
7a387fff 15375 case OPC_WRPGPR:
d75c135e 15376 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15377 gen_store_srsgpr(rt, rd);
38121543 15378 break;
6af0bf9c 15379 default:
923617a3 15380 MIPS_INVAL("cp0");
7a387fff 15381 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15382 break;
15383 }
15384 break;
324d9e32
AJ
15385 case OPC_ADDI: /* Arithmetic with immediate opcode */
15386 case OPC_ADDIU:
d75c135e 15387 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15388 break;
324d9e32
AJ
15389 case OPC_SLTI: /* Set on less than with immediate opcode */
15390 case OPC_SLTIU:
d75c135e 15391 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15392 break;
15393 case OPC_ANDI: /* Arithmetic with immediate opcode */
15394 case OPC_LUI:
15395 case OPC_ORI:
15396 case OPC_XORI:
d75c135e 15397 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15398 break;
7a387fff
TS
15399 case OPC_J ... OPC_JAL: /* Jump */
15400 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15401 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061 15402 break;
7a387fff
TS
15403 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15404 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15405 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061 15406 break;
7a387fff 15407 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15408 case OPC_LL:
d75c135e 15409 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15410 break;
7a387fff
TS
15411 case OPC_SB ... OPC_SW:
15412 case OPC_SWR:
5c13fdfd 15413 gen_st(ctx, op, rt, rs, imm);
7a387fff 15414 break;
d66c7132
AJ
15415 case OPC_SC:
15416 gen_st_cond(ctx, op, rt, rs, imm);
15417 break;
7a387fff 15418 case OPC_CACHE:
2e15497c 15419 check_cp0_enabled(ctx);
d75c135e 15420 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15421 /* Treat as NOP. */
34ae7b51 15422 break;
7a387fff 15423 case OPC_PREF:
d75c135e 15424 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15425 /* Treat as NOP. */
6af0bf9c 15426 break;
4ad40f36 15427
923617a3 15428 /* Floating point (COP1). */
7a387fff
TS
15429 case OPC_LWC1:
15430 case OPC_LDC1:
15431 case OPC_SWC1:
15432 case OPC_SDC1:
26ebe468 15433 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15434 break;
15435
7a387fff 15436 case OPC_CP1:
36d23958 15437 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15438 check_cp1_enabled(ctx);
36d23958
TS
15439 op1 = MASK_CP1(ctx->opcode);
15440 switch (op1) {
3a95e3a7
TS
15441 case OPC_MFHC1:
15442 case OPC_MTHC1:
d75c135e 15443 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
15444 case OPC_MFC1:
15445 case OPC_CFC1:
15446 case OPC_MTC1:
15447 case OPC_CTC1:
e189e748
TS
15448 gen_cp1(ctx, op1, rt, rd);
15449 break;
d26bc211 15450#if defined(TARGET_MIPS64)
36d23958
TS
15451 case OPC_DMFC1:
15452 case OPC_DMTC1:
d75c135e 15453 check_insn(ctx, ISA_MIPS3);
36d23958
TS
15454 gen_cp1(ctx, op1, rt, rd);
15455 break;
e189e748 15456#endif
fbcc6828
TS
15457 case OPC_BC1ANY2:
15458 case OPC_BC1ANY4:
b8aa4598 15459 check_cop1x(ctx);
d75c135e 15460 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
15461 /* fall through */
15462 case OPC_BC1:
d75c135e 15463 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15464 (rt >> 2) & 0x7, imm << 2);
c9602061 15465 break;
36d23958
TS
15466 case OPC_S_FMT:
15467 case OPC_D_FMT:
15468 case OPC_W_FMT:
15469 case OPC_L_FMT:
5a5012ec 15470 case OPC_PS_FMT:
bf4120ad 15471 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15472 (imm >> 8) & 0x7);
36d23958
TS
15473 break;
15474 default:
923617a3 15475 MIPS_INVAL("cp1");
e397ee33 15476 generate_exception (ctx, EXCP_RI);
36d23958
TS
15477 break;
15478 }
15479 } else {
15480 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15481 }
4ad40f36
FB
15482 break;
15483
15484 /* COP2. */
7a387fff
TS
15485 case OPC_LWC2:
15486 case OPC_LDC2:
15487 case OPC_SWC2:
15488 case OPC_SDC2:
7a387fff 15489 /* COP2: Not implemented. */
4ad40f36
FB
15490 generate_exception_err(ctx, EXCP_CpU, 2);
15491 break;
bd277fa1 15492 case OPC_CP2:
d75c135e 15493 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
15494 /* Note that these instructions use different fields. */
15495 gen_loongson_multimedia(ctx, sa, rd, rt);
15496 break;
4ad40f36 15497
7a387fff 15498 case OPC_CP3:
36d23958 15499 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15500 check_cp1_enabled(ctx);
36d23958
TS
15501 op1 = MASK_CP3(ctx->opcode);
15502 switch (op1) {
5a5012ec
TS
15503 case OPC_LWXC1:
15504 case OPC_LDXC1:
15505 case OPC_LUXC1:
15506 case OPC_SWXC1:
15507 case OPC_SDXC1:
15508 case OPC_SUXC1:
93b12ccc 15509 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15510 break;
e0c84da7 15511 case OPC_PREFX:
ead9360e 15512 /* Treat as NOP. */
e0c84da7 15513 break;
5a5012ec
TS
15514 case OPC_ALNV_PS:
15515 case OPC_MADD_S:
15516 case OPC_MADD_D:
15517 case OPC_MADD_PS:
15518 case OPC_MSUB_S:
15519 case OPC_MSUB_D:
15520 case OPC_MSUB_PS:
15521 case OPC_NMADD_S:
15522 case OPC_NMADD_D:
15523 case OPC_NMADD_PS:
15524 case OPC_NMSUB_S:
15525 case OPC_NMSUB_D:
15526 case OPC_NMSUB_PS:
15527 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15528 break;
36d23958 15529 default:
923617a3 15530 MIPS_INVAL("cp3");
e397ee33 15531 generate_exception (ctx, EXCP_RI);
36d23958
TS
15532 break;
15533 }
15534 } else {
e397ee33 15535 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15536 }
4ad40f36
FB
15537 break;
15538
d26bc211 15539#if defined(TARGET_MIPS64)
7a387fff
TS
15540 /* MIPS64 opcodes */
15541 case OPC_LWU:
15542 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15543 case OPC_LLD:
15544 case OPC_LD:
d75c135e 15545 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15546 check_mips_64(ctx);
d75c135e 15547 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
15548 break;
15549 case OPC_SDL ... OPC_SDR:
7a387fff 15550 case OPC_SD:
d75c135e 15551 check_insn(ctx, ISA_MIPS3);
e189e748 15552 check_mips_64(ctx);
5c13fdfd 15553 gen_st(ctx, op, rt, rs, imm);
7a387fff 15554 break;
d66c7132 15555 case OPC_SCD:
d75c135e 15556 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
15557 check_mips_64(ctx);
15558 gen_st_cond(ctx, op, rt, rs, imm);
15559 break;
324d9e32
AJ
15560 case OPC_DADDI:
15561 case OPC_DADDIU:
d75c135e 15562 check_insn(ctx, ISA_MIPS3);
e189e748 15563 check_mips_64(ctx);
d75c135e 15564 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15565 break;
6af0bf9c 15566#endif
7a387fff 15567 case OPC_JALX:
d75c135e 15568 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15569 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15570 gen_compute_branch(ctx, op, 4, rs, rt, offset);
364d4831 15571 break;
7a387fff 15572 case OPC_MDMX:
d75c135e 15573 check_insn(ctx, ASE_MDMX);
7a387fff 15574 /* MDMX: Not implemented. */
6af0bf9c 15575 default: /* Invalid */
923617a3 15576 MIPS_INVAL("major opcode");
6af0bf9c
FB
15577 generate_exception(ctx, EXCP_RI);
15578 break;
15579 }
6af0bf9c
FB
15580}
15581
2cfc5f17 15582static inline void
6429db34
AF
15583gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15584 bool search_pc)
6af0bf9c 15585{
ed2803da 15586 CPUState *cs = CPU(cpu);
6429db34 15587 CPUMIPSState *env = &cpu->env;
278d0702 15588 DisasContext ctx;
6af0bf9c
FB
15589 target_ulong pc_start;
15590 uint16_t *gen_opc_end;
a1d1bb31 15591 CPUBreakpoint *bp;
6af0bf9c 15592 int j, lj = -1;
2e70f6ef
PB
15593 int num_insns;
15594 int max_insns;
c9602061 15595 int insn_bytes;
240ce26a 15596 int is_delay;
6af0bf9c 15597
93fcfe39
AL
15598 if (search_pc)
15599 qemu_log("search pc %d\n", search_pc);
4ad40f36 15600
6af0bf9c 15601 pc_start = tb->pc;
92414b31 15602 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15603 ctx.pc = pc_start;
4ad40f36 15604 ctx.saved_pc = -1;
ed2803da 15605 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 15606 ctx.insn_flags = env->insn_flags;
6af0bf9c
FB
15607 ctx.tb = tb;
15608 ctx.bstate = BS_NONE;
4ad40f36 15609 /* Restore delay slot state from the tb context. */
c068688b 15610 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
fd4a04eb 15611 restore_cpu_state(env, &ctx);
932e71cd 15612#ifdef CONFIG_USER_ONLY
0eaef5aa 15613 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15614#else
0eaef5aa 15615 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15616#endif
2e70f6ef
PB
15617 num_insns = 0;
15618 max_insns = tb->cflags & CF_COUNT_MASK;
15619 if (max_insns == 0)
15620 max_insns = CF_COUNT_MASK;
d12d51d5 15621 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 15622 gen_tb_start();
faf7aaa9 15623 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
15624 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
15625 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 15626 if (bp->pc == ctx.pc) {
278d0702 15627 save_cpu_state(&ctx, 1);
4ad40f36 15628 ctx.bstate = BS_BRANCH;
895c2d04 15629 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15630 /* Include the breakpoint location or the tb won't
15631 * be flushed when it must be. */
15632 ctx.pc += 4;
4ad40f36
FB
15633 goto done_generating;
15634 }
15635 }
15636 }
15637
6af0bf9c 15638 if (search_pc) {
92414b31 15639 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15640 if (lj < j) {
15641 lj++;
15642 while (lj < j)
ab1103de 15643 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 15644 }
25983cad 15645 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 15646 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15647 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 15648 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 15649 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 15650 }
2e70f6ef
PB
15651 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15652 gen_io_start();
c9602061 15653
240ce26a 15654 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 15655 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15656 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 15657 insn_bytes = 4;
240ce26a 15658 decode_opc(env, &ctx);
d75c135e 15659 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 15660 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 15661 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 15662 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 15663 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 15664 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
15665 } else {
15666 generate_exception(&ctx, EXCP_RI);
3c824109 15667 ctx.bstate = BS_STOP;
c9602061
NF
15668 break;
15669 }
240ce26a 15670 if (is_delay) {
d75c135e 15671 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
15672 }
15673 ctx.pc += insn_bytes;
15674
2e70f6ef 15675 num_insns++;
4ad40f36 15676
7b270ef2
NF
15677 /* Execute a branch and its delay slot as a single instruction.
15678 This is what GDB expects and is consistent with what the
15679 hardware does (e.g. if a delay slot instruction faults, the
15680 reported PC is the PC of the branch). */
ed2803da 15681 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 15682 break;
ed2803da 15683 }
4ad40f36 15684
6af0bf9c
FB
15685 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15686 break;
4ad40f36 15687
efd7f486 15688 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 15689 break;
efd7f486 15690 }
faf7aaa9 15691
2e70f6ef
PB
15692 if (num_insns >= max_insns)
15693 break;
1b530a6d
AJ
15694
15695 if (singlestep)
15696 break;
6af0bf9c 15697 }
ed2803da 15698 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 15699 gen_io_end();
ed2803da
AF
15700 }
15701 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15702 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15703 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15704 } else {
6958549d 15705 switch (ctx.bstate) {
16c00cb2 15706 case BS_STOP:
df1561e2
TS
15707 gen_goto_tb(&ctx, 0, ctx.pc);
15708 break;
16c00cb2 15709 case BS_NONE:
278d0702 15710 save_cpu_state(&ctx, 0);
16c00cb2
TS
15711 gen_goto_tb(&ctx, 0, ctx.pc);
15712 break;
5a5012ec 15713 case BS_EXCP:
57fec1fe 15714 tcg_gen_exit_tb(0);
16c00cb2 15715 break;
5a5012ec
TS
15716 case BS_BRANCH:
15717 default:
15718 break;
6958549d 15719 }
6af0bf9c 15720 }
4ad40f36 15721done_generating:
806f352d 15722 gen_tb_end(tb, num_insns);
efd7f486 15723 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 15724 if (search_pc) {
92414b31 15725 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15726 lj++;
15727 while (lj <= j)
ab1103de 15728 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15729 } else {
15730 tb->size = ctx.pc - pc_start;
2e70f6ef 15731 tb->icount = num_insns;
6af0bf9c
FB
15732 }
15733#ifdef DEBUG_DISAS
d12d51d5 15734 LOG_DISAS("\n");
8fec2b8c 15735 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 15736 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 15737 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 15738 qemu_log("\n");
6af0bf9c
FB
15739 }
15740#endif
6af0bf9c
FB
15741}
15742
7db13fae 15743void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15744{
6429db34 15745 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
15746}
15747
7db13fae 15748void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15749{
6429db34 15750 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
15751}
15752
7db13fae 15753static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15754 int flags)
6ea83fed
FB
15755{
15756 int i;
5e755519 15757 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15758
2a5612e6
SW
15759#define printfpr(fp) \
15760 do { \
15761 if (is_fpu64) \
15762 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15763 " fd:%13g fs:%13g psu: %13g\n", \
15764 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15765 (double)(fp)->fd, \
15766 (double)(fp)->fs[FP_ENDIAN_IDX], \
15767 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15768 else { \
15769 fpr_t tmp; \
15770 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15771 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15772 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15773 " fd:%13g fs:%13g psu:%13g\n", \
15774 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15775 (double)tmp.fd, \
15776 (double)tmp.fs[FP_ENDIAN_IDX], \
15777 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15778 } \
6ea83fed
FB
15779 } while(0)
15780
5a5012ec 15781
9a78eead
SW
15782 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15783 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15784 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15785 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15786 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15787 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15788 }
15789
15790#undef printfpr
15791}
15792
d26bc211 15793#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15794/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15795 sign-extended values on 64bit machines. */
c570fd16
TS
15796
15797#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15798
8706c382 15799static void
7db13fae 15800cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15801 fprintf_function cpu_fprintf,
8706c382 15802 int flags)
c570fd16
TS
15803{
15804 int i;
15805
b5dc7732
TS
15806 if (!SIGN_EXT_P(env->active_tc.PC))
15807 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15808 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15809 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15810 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15811 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15812 if (!SIGN_EXT_P(env->btarget))
3594c774 15813 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15814
15815 for (i = 0; i < 32; i++) {
b5dc7732
TS
15816 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15817 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15818 }
15819
15820 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15821 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15822 if (!SIGN_EXT_P(env->lladdr))
15823 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15824}
15825#endif
15826
878096ee
AF
15827void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15828 int flags)
6af0bf9c 15829{
878096ee
AF
15830 MIPSCPU *cpu = MIPS_CPU(cs);
15831 CPUMIPSState *env = &cpu->env;
6af0bf9c 15832 int i;
3b46e624 15833
a7200c9f
SW
15834 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15835 " LO=0x" TARGET_FMT_lx " ds %04x "
15836 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15837 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15838 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15839 for (i = 0; i < 32; i++) {
15840 if ((i & 3) == 0)
15841 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15842 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15843 if ((i & 3) == 3)
15844 cpu_fprintf(f, "\n");
15845 }
568b600d 15846
3594c774 15847 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15848 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15849 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15850 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15851 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15852 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15853#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15854 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15855#endif
6af0bf9c
FB
15856}
15857
78ce64f4 15858void mips_tcg_init(void)
39454628 15859{
f01be154 15860 int i;
39454628
TS
15861 static int inited;
15862
15863 /* Initialize various static tables. */
15864 if (inited)
6958549d 15865 return;
39454628 15866
a7812ae4 15867 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15868 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15869 for (i = 1; i < 32; i++)
a7812ae4 15870 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15871 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15872 regnames[i]);
d73ee8a2
RH
15873
15874 for (i = 0; i < 32; i++) {
15875 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15876 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15877 }
15878
a7812ae4 15879 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15880 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15881 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15882 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15883 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15884 regnames_HI[i]);
a7812ae4 15885 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15886 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15887 regnames_LO[i]);
a7812ae4 15888 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15889 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15890 regnames_ACX[i]);
15891 }
a7812ae4 15892 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15893 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15894 "DSPControl");
1ba74fb8 15895 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15896 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15897 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15898 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15899 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15900 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15901
a7812ae4 15902 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15903 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15904 "fcr0");
15905 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15906 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15907 "fcr31");
39454628
TS
15908
15909 inited = 1;
15910}
15911
aaed909a
FB
15912#include "translate_init.c"
15913
30bf942d 15914MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15915{
0f71a709 15916 MIPSCPU *cpu;
6af0bf9c 15917 CPUMIPSState *env;
c227f099 15918 const mips_def_t *def;
6af0bf9c 15919
aaed909a
FB
15920 def = cpu_mips_find_by_name(cpu_model);
15921 if (!def)
15922 return NULL;
0f71a709
AF
15923 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15924 env = &cpu->env;
aaed909a
FB
15925 env->cpu_model = def;
15926
51cc2e78
BS
15927#ifndef CONFIG_USER_ONLY
15928 mmu_init(env, def);
15929#endif
15930 fpu_init(env, def);
15931 mvp_init(env, def);
c1caf1d9
AF
15932
15933 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15934
30bf942d 15935 return cpu;
6ae81775
TS
15936}
15937
1bba0dc9 15938void cpu_state_reset(CPUMIPSState *env)
6ae81775 15939{
55e5c285
AF
15940 MIPSCPU *cpu = mips_env_get_cpu(env);
15941 CPUState *cs = CPU(cpu);
6ae81775 15942
51cc2e78
BS
15943 /* Reset registers to their default values */
15944 env->CP0_PRid = env->cpu_model->CP0_PRid;
15945 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15946#ifdef TARGET_WORDS_BIGENDIAN
15947 env->CP0_Config0 |= (1 << CP0C0_BE);
15948#endif
15949 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15950 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15951 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
15952 env->CP0_Config4 = env->cpu_model->CP0_Config4;
15953 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
15954 env->CP0_Config5 = env->cpu_model->CP0_Config5;
15955 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
15956 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15957 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
15958 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15959 << env->cpu_model->CP0_LLAddr_shift;
15960 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
15961 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15962 env->CCRes = env->cpu_model->CCRes;
15963 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15964 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15965 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15966 env->current_tc = 0;
15967 env->SEGBITS = env->cpu_model->SEGBITS;
15968 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15969#if defined(TARGET_MIPS64)
15970 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15971 env->SEGMask |= 3ULL << 62;
15972 }
15973#endif
15974 env->PABITS = env->cpu_model->PABITS;
15975 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15976 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15977 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15978 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15979 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15980 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15981 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15982 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15983 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15984 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15985 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 15986 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
15987 env->insn_flags = env->cpu_model->insn_flags;
15988
0eaef5aa 15989#if defined(CONFIG_USER_ONLY)
03e6e501 15990 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
15991# ifdef TARGET_MIPS64
15992 /* Enable 64-bit register mode. */
15993 env->CP0_Status |= (1 << CP0St_PX);
15994# endif
15995# ifdef TARGET_ABI_MIPSN64
15996 /* Enable 64-bit address mode. */
15997 env->CP0_Status |= (1 << CP0St_UX);
15998# endif
94159135
MI
15999 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16000 hardware registers. */
16001 env->CP0_HWREna |= 0x0000000F;
91a75935 16002 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 16003 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 16004 }
6f0af304
PJ
16005 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
16006 env->CP0_Status |= (1 << CP0St_MX);
853c3240 16007 }
4d66261f
PJ
16008# if defined(TARGET_MIPS64)
16009 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16010 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
16011 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
16012 env->CP0_Status |= (1 << CP0St_FR);
16013 }
4d66261f 16014# endif
932e71cd
AJ
16015#else
16016 if (env->hflags & MIPS_HFLAG_BMASK) {
16017 /* If the exception was raised from a delay slot,
16018 come back to the jump. */
16019 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 16020 } else {
932e71cd
AJ
16021 env->CP0_ErrorEPC = env->active_tc.PC;
16022 }
16023 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
16024 env->CP0_Random = env->tlb->nb_tlb - 1;
16025 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 16026 env->CP0_Wired = 0;
55e5c285 16027 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
932e71cd
AJ
16028 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16029 /* vectored interrupts not implemented, timer on int 7,
16030 no performance counters. */
16031 env->CP0_IntCtl = 0xe0000000;
16032 {
16033 int i;
16034
16035 for (i = 0; i < 7; i++) {
16036 env->CP0_WatchLo[i] = 0;
16037 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 16038 }
932e71cd
AJ
16039 env->CP0_WatchLo[7] = 0;
16040 env->CP0_WatchHi[7] = 0;
fd88b6ab 16041 }
932e71cd
AJ
16042 /* Count register increments in debug mode, EJTAG version 1 */
16043 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756
EI
16044
16045 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16046 int i;
16047
16048 /* Only TC0 on VPE 0 starts as active. */
16049 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 16050 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
16051 env->tcs[i].CP0_TCHalt = 1;
16052 }
16053 env->active_tc.CP0_TCHalt = 1;
259186a7 16054 cs->halted = 1;
9e56e756 16055
55e5c285 16056 if (cs->cpu_index == 0) {
9e56e756
EI
16057 /* VPE0 starts up enabled. */
16058 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16059 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16060
16061 /* TC0 starts up unhalted. */
259186a7 16062 cs->halted = 0;
9e56e756
EI
16063 env->active_tc.CP0_TCHalt = 0;
16064 env->tcs[0].CP0_TCHalt = 0;
16065 /* With thread 0 active. */
16066 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16067 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16068 }
16069 }
51cc2e78 16070#endif
03e6e501 16071 compute_hflags(env);
27103424 16072 cs->exception_index = EXCP_NONE;
6af0bf9c 16073}
d2856f1a 16074
7db13fae 16075void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16076{
25983cad 16077 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16078 env->hflags &= ~MIPS_HFLAG_BMASK;
16079 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16080 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16081 case MIPS_HFLAG_BR:
16082 break;
16083 case MIPS_HFLAG_BC:
16084 case MIPS_HFLAG_BL:
16085 case MIPS_HFLAG_B:
16086 env->btarget = gen_opc_btarget[pc_pos];
16087 break;
16088 }
d2856f1a 16089}