]> git.proxmox.com Git - qemu.git/blame - target-mips/translate.c
translate-all.c: Remove cpu_unlink_tb()
[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
a7812ae4
PB
28#include "helper.h"
29#define GEN_HELPER 1
30#include "helper.h"
31
fb7729e2 32#define MIPS_DEBUG_DISAS 0
c570fd16 33//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c 34
7a387fff
TS
35/* MIPS major opcodes */
36#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
37
38enum {
39 /* indirect opcode tables */
7a387fff
TS
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 48 /* arithmetic with immediate */
7a387fff
TS
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
324d9e32 53 /* logic with immediate */
7a387fff
TS
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
324d9e32 58 /* arithmetic with immediate */
7a387fff
TS
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
e37e863f 61 /* Jump and branches */
7a387fff
TS
62 OPC_J = (0x02 << 26),
63 OPC_JAL = (0x03 << 26),
620e48f6 64 OPC_JALS = OPC_JAL | 0x5,
7a387fff
TS
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
620e48f6 74 OPC_JALXS = OPC_JALX | 0x5,
e37e863f 75 /* Load and stores */
7a387fff
TS
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
364d4831 82 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
364d4831 97 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
e37e863f 101 /* Floating point load/store */
7a387fff
TS
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
e37e863f 112 /* Cache and prefetch */
7a387fff
TS
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
e37e863f
FB
117};
118
119/* MIPS special opcodes */
7a387fff
TS
120#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
121
e37e863f
FB
122enum {
123 /* Shifts */
7a387fff 124 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 129 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 133 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 141 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 147 /* Multiplication / division */
7a387fff
TS
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
e37e863f 156 /* 2 registers arithmetic / logic */
7a387fff
TS
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 171 /* Jumps */
7a387fff
TS
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
364d4831 174 OPC_JALRC = OPC_JALR | (0x5 << 6),
620e48f6 175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
e37e863f 176 /* Traps */
7a387fff
TS
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 183 /* HI / LO registers load & stores */
7a387fff
TS
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 188 /* Conditional moves */
7a387fff
TS
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 191
7a387fff 192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
193
194 /* Special */
a0d700e4 195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
200
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
208};
209
e9c71dd1
TS
210/* Multiplication variants of the vr54xx. */
211#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
212
213enum {
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
228};
229
7a387fff
TS
230/* REGIMM (rt field) opcodes */
231#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
232
233enum {
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
3c824109 239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
7a387fff
TS
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
3c824109 242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
7a387fff
TS
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
e37e863f
FB
251};
252
7a387fff
TS
253/* Special2 opcodes */
254#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
255
e37e863f 256enum {
7a387fff
TS
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
263 /* Loongson 2F */
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 276 /* Misc */
7a387fff
TS
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 281 /* Special */
7a387fff
TS
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
283};
284
285/* Special3 opcodes */
286#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
287
288enum {
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
302
303 /* Loongson 2E */
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
316
317 /* MIPS DSP Load */
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 339 /* MIPS DSP Append Sub-class */
26690560 340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
e37e863f
FB
345};
346
7a387fff
TS
347/* BSHFL opcodes */
348#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
349
e37e863f 350enum {
7a387fff
TS
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
e37e863f
FB
354};
355
7a387fff
TS
356/* DBSHFL opcodes */
357#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
358
e37e863f 359enum {
7a387fff
TS
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
e37e863f
FB
362};
363
e45a93e2
JL
364/* MIPS DSP REGIMM opcodes */
365enum {
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
368};
369
9b1a1d68
JL
370#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
371/* MIPS DSP Load */
372enum {
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
377};
378
461c08df
JL
379#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
380enum {
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
407};
408
409#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
411enum {
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
430};
431
432#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
433enum {
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
454};
455
456#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457enum {
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 482};
a22260ae 483
77c5fa8b
JL
484#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485enum {
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
509};
461c08df 510
a22260ae
JL
511#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
512enum {
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
536};
537
1cb6686c
JL
538#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539enum {
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
542};
543
26690560
JL
544#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545enum {
df6126a7 546 /* MIPS DSP Append Sub-class */
26690560
JL
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
550};
551
b53371ed
JL
552#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553enum {
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
572};
573
461c08df
JL
574#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 601};
461c08df 602
461c08df
JL
603#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604enum {
a22260ae
JL
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
633};
461c08df 634
461c08df
JL
635#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636enum {
26690560
JL
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
666};
461c08df 667
26690560
JL
668#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669enum {
df6126a7 670 /* DSP Append Sub-class */
26690560
JL
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
675};
26690560 676
b53371ed
JL
677#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678enum {
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
701};
702
1cb6686c
JL
703#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704enum {
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
707};
1cb6686c 708
a22260ae
JL
709#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710enum {
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
738};
a22260ae 739
77c5fa8b
JL
740#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741enum {
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
769};
77c5fa8b 770
7a387fff
TS
771/* Coprocessor 0 (rs field) */
772#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
773
6ea83fed 774enum {
7a387fff
TS
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 787};
7a387fff
TS
788
789/* MFMC0 opcodes */
b48cfdff 790#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
791
792enum {
ead9360e
TS
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
799};
800
801/* Coprocessor 0 (with rs == C0) */
802#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
803
804enum {
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
813};
814
815/* Coprocessor 1 (rs field) */
816#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
817
bf4120ad
NF
818/* Values for the fmt field in FP instructions */
819enum {
820 /* 0 - 15 are reserved */
e459440a
AJ
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
828 /* 23 - 31 are reserved */
829};
830
7a387fff
TS
831enum {
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
e459440a
AJ
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
7a387fff
TS
850};
851
5a5012ec
TS
852#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
854
7a387fff
TS
855enum {
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
860};
861
5a5012ec
TS
862enum {
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
865};
866
867enum {
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
870};
7a387fff
TS
871
872#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
873
874enum {
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
884};
885
bd277fa1
RH
886#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
887
888enum {
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
897
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
906
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
915
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
924
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
931
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
938
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
945
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
952
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
959
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
966
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
973
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
980};
981
982
e0c84da7
TS
983#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
984
985enum {
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1001 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1006};
1007
39454628 1008/* global register indices */
a7812ae4
PB
1009static TCGv_ptr cpu_env;
1010static TCGv cpu_gpr[32], cpu_PC;
4b2eb8d2 1011static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
41db4607
AJ
1012static TCGv cpu_dspctrl, btarget, bcond;
1013static TCGv_i32 hflags;
a7812ae4 1014static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1015static TCGv_i64 fpu_f64[32];
aa0bf00b 1016
1a7ff922 1017static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1018static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1019
022c62cb 1020#include "exec/gen-icount.h"
2e70f6ef 1021
895c2d04 1022#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1024 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1025 tcg_temp_free_i32(helper_tmp); \
1026 } while(0)
be24bb4f 1027
895c2d04 1028#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1031 tcg_temp_free_i32(helper_tmp); \
1032 } while(0)
be24bb4f 1033
895c2d04
BS
1034#define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1038 } while(0)
1039
1040#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1044 } while(0)
1045
1046#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1050 } while(0)
1051
1052#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1055 tcg_temp_free_i32(helper_tmp); \
1056 } while(0)
be24bb4f 1057
895c2d04 1058#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1061 tcg_temp_free_i32(helper_tmp); \
1062 } while(0)
c239529e 1063
8e9ade68
TS
1064typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1067 uint32_t opcode;
7b270ef2 1068 int singlestep_enabled;
d75c135e 1069 int insn_flags;
8e9ade68
TS
1070 /* Routine used to access memory */
1071 int mem_idx;
1072 uint32_t hflags, saved_hflags;
1073 int bstate;
1074 target_ulong btarget;
1075} DisasContext;
1076
1077enum {
1078 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1079 * exception condition */
8e9ade68
TS
1080 BS_STOP = 1, /* We want to stop translation for any reason */
1081 BS_BRANCH = 2, /* We reached a branch condition */
1082 BS_EXCP = 3, /* We reached an exception condition */
1083};
1084
d73ee8a2
RH
1085static const char * const regnames[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1090};
6af0bf9c 1091
d73ee8a2
RH
1092static const char * const regnames_HI[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1094};
4b2eb8d2 1095
d73ee8a2
RH
1096static const char * const regnames_LO[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1098};
4b2eb8d2 1099
d73ee8a2
RH
1100static const char * const regnames_ACX[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1102};
4b2eb8d2 1103
d73ee8a2
RH
1104static const char * const fregnames[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1109};
958fb4a9 1110
fb7729e2
RH
1111#define MIPS_DEBUG(fmt, ...) \
1112 do { \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1117 } \
1118 } while (0)
1119
1120#define LOG_DISAS(...) \
1121 do { \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1124 } \
1125 } while (0)
958fb4a9 1126
8e9ade68 1127#define MIPS_INVAL(op) \
8e9ade68 1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1130
8e9ade68
TS
1131/* General purpose registers moves. */
1132static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1133{
8e9ade68
TS
1134 if (reg == 0)
1135 tcg_gen_movi_tl(t, 0);
1136 else
4b2eb8d2 1137 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1138}
1139
8e9ade68 1140static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1141{
8e9ade68 1142 if (reg != 0)
4b2eb8d2 1143 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1144}
1145
b10fa3c9 1146/* Moves to/from ACX register. */
4b2eb8d2 1147static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1148{
4b2eb8d2 1149 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1150}
1151
4b2eb8d2 1152static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1153{
4b2eb8d2 1154 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1155}
1156
8e9ade68 1157/* Moves to/from shadow registers. */
be24bb4f 1158static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1159{
d9bea114 1160 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1161
1162 if (from == 0)
d9bea114 1163 tcg_gen_movi_tl(t0, 0);
8e9ade68 1164 else {
d9bea114 1165 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1166 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1167
7db13fae 1168 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1169 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1170 tcg_gen_andi_i32(t2, t2, 0xf);
1171 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1172 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1173 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1174
d9bea114 1175 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1176 tcg_temp_free_ptr(addr);
d9bea114 1177 tcg_temp_free_i32(t2);
8e9ade68 1178 }
d9bea114
AJ
1179 gen_store_gpr(t0, to);
1180 tcg_temp_free(t0);
aaa9128a
TS
1181}
1182
be24bb4f 1183static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1184{
be24bb4f 1185 if (to != 0) {
d9bea114
AJ
1186 TCGv t0 = tcg_temp_new();
1187 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1188 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1189
d9bea114 1190 gen_load_gpr(t0, from);
7db13fae 1191 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1192 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1193 tcg_gen_andi_i32(t2, t2, 0xf);
1194 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1195 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1196 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1197
d9bea114 1198 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1199 tcg_temp_free_ptr(addr);
d9bea114
AJ
1200 tcg_temp_free_i32(t2);
1201 tcg_temp_free(t0);
8e9ade68 1202 }
aaa9128a
TS
1203}
1204
aaa9128a 1205/* Floating point register moves. */
d73ee8a2 1206static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1207{
d73ee8a2 1208 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1209}
1210
d73ee8a2 1211static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1212{
d73ee8a2
RH
1213 TCGv_i64 t64 = tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64, t);
1215 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1216 tcg_temp_free_i64(t64);
6d066274
AJ
1217}
1218
d73ee8a2 1219static void gen_load_fpr32h(TCGv_i32 t, int reg)
6d066274 1220{
d73ee8a2
RH
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);
6d066274
AJ
1225}
1226
d73ee8a2 1227static void gen_store_fpr32h(TCGv_i32 t, int reg)
6d066274 1228{
d73ee8a2
RH
1229 TCGv_i64 t64 = tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64, t);
1231 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1232 tcg_temp_free_i64(t64);
aa0bf00b 1233}
6ea83fed 1234
d73ee8a2 1235static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1236{
f364515c 1237 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1238 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1239 } else {
d73ee8a2 1240 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1241 }
1242}
6ea83fed 1243
d73ee8a2 1244static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1245{
f364515c 1246 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1247 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1248 } else {
d73ee8a2
RH
1249 TCGv_i64 t0;
1250 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1251 t0 = tcg_temp_new_i64();
6d066274 1252 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1253 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1254 tcg_temp_free_i64(t0);
aa0bf00b
TS
1255 }
1256}
6ea83fed 1257
d94536f4 1258static inline int get_fp_bit (int cc)
a16336e4 1259{
d94536f4
AJ
1260 if (cc)
1261 return 24 + cc;
1262 else
1263 return 23;
a16336e4
TS
1264}
1265
30898801 1266/* Tests */
8e9ade68
TS
1267static inline void gen_save_pc(target_ulong pc)
1268{
1eb75d4a 1269 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1270}
30898801 1271
356265ae 1272static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1273{
d12d51d5 1274 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1275 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1276 gen_save_pc(ctx->pc);
6af0bf9c
FB
1277 ctx->saved_pc = ctx->pc;
1278 }
1279 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1280 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1281 ctx->saved_hflags = ctx->hflags;
364d4831 1282 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1283 case MIPS_HFLAG_BR:
5a5012ec
TS
1284 break;
1285 case MIPS_HFLAG_BC:
5a5012ec 1286 case MIPS_HFLAG_BL:
5a5012ec 1287 case MIPS_HFLAG_B:
d077b6f7 1288 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1289 break;
6af0bf9c
FB
1290 }
1291 }
1292}
1293
7db13fae 1294static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1295{
fd4a04eb 1296 ctx->saved_hflags = ctx->hflags;
364d4831 1297 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1298 case MIPS_HFLAG_BR:
fd4a04eb
TS
1299 break;
1300 case MIPS_HFLAG_BC:
1301 case MIPS_HFLAG_BL:
39454628 1302 case MIPS_HFLAG_B:
fd4a04eb 1303 ctx->btarget = env->btarget;
fd4a04eb 1304 break;
5a5012ec
TS
1305 }
1306}
1307
356265ae 1308static inline void
48d38ca5 1309generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1310{
a7812ae4
PB
1311 TCGv_i32 texcp = tcg_const_i32(excp);
1312 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1313 save_cpu_state(ctx, 1);
895c2d04 1314 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1315 tcg_temp_free_i32(terr);
1316 tcg_temp_free_i32(texcp);
aaa9128a
TS
1317}
1318
356265ae 1319static inline void
48d38ca5 1320generate_exception (DisasContext *ctx, int excp)
aaa9128a 1321{
6af0bf9c 1322 save_cpu_state(ctx, 1);
895c2d04 1323 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1324}
1325
48d38ca5 1326/* Addresses computation */
941694d0 1327static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1328{
941694d0 1329 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1330
1331#if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1335 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1336 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1337 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1338 }
1339#endif
4ad40f36
FB
1340}
1341
356265ae 1342static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1343{
fe253235 1344 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1345 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1346}
1347
356265ae 1348static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1349{
fe253235 1350 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1351 generate_exception_err(ctx, EXCP_CpU, 1);
1352}
1353
b8aa4598
TS
1354/* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1356 opcode tables. */
1357
356265ae 1358static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1359{
1360 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1361 generate_exception(ctx, EXCP_RI);
1362}
1363
1364/* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1366
356265ae 1367static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1368{
b8aa4598 1369 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1370 generate_exception(ctx, EXCP_RI);
1371}
1372
1373/*
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 *
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 */
356265ae 1384static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1385{
fe253235 1386 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1387 generate_exception(ctx, EXCP_RI);
1388}
1389
853c3240
JL
1390/* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1392 */
1393
1394static inline void check_dsp(DisasContext *ctx)
1395{
1396 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1397 if (ctx->insn_flags & ASE_DSP) {
1398 generate_exception(ctx, EXCP_DSPDIS);
1399 } else {
1400 generate_exception(ctx, EXCP_RI);
1401 }
853c3240
JL
1402 }
1403}
1404
1405static inline void check_dspr2(DisasContext *ctx)
1406{
1407 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1408 if (ctx->insn_flags & ASE_DSP) {
1409 generate_exception(ctx, EXCP_DSPDIS);
1410 } else {
1411 generate_exception(ctx, EXCP_RI);
1412 }
853c3240
JL
1413 }
1414}
1415
3a95e3a7 1416/* This code generates a "reserved instruction" exception if the
e189e748 1417 CPU does not support the instruction set corresponding to flags. */
d75c135e 1418static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1419{
d75c135e 1420 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1421 generate_exception(ctx, EXCP_RI);
d75c135e 1422 }
3a95e3a7
TS
1423}
1424
e189e748
TS
1425/* This code generates a "reserved instruction" exception if 64-bit
1426 instructions are not enabled. */
356265ae 1427static inline void check_mips_64(DisasContext *ctx)
e189e748 1428{
fe253235 1429 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1430 generate_exception(ctx, EXCP_RI);
1431}
1432
8153667c
NF
1433/* Define small wrappers for gen_load_fpr* so that we have a uniform
1434 calling interface for 32 and 64-bit FPRs. No sense in changing
1435 all callers for gen_load_fpr32 when we need the CTX parameter for
1436 this one use. */
1437#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1440static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1441 int ft, int fs, int cc) \
1442{ \
1443 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1444 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1445 switch (ifmt) { \
1446 case FMT_PS: \
1447 check_cp1_64bitmode(ctx); \
1448 break; \
1449 case FMT_D: \
1450 if (abs) { \
1451 check_cop1x(ctx); \
1452 } \
1453 check_cp1_registers(ctx, fs | ft); \
1454 break; \
1455 case FMT_S: \
1456 if (abs) { \
1457 check_cop1x(ctx); \
1458 } \
1459 break; \
1460 } \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1463 switch (n) { \
895c2d04
BS
1464 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1465 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1466 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1467 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1468 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1469 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1470 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1471 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1472 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1473 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1475 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1476 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1477 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1478 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1479 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1480 default: abort(); \
1481 } \
1482 tcg_temp_free_i##bits (fp0); \
1483 tcg_temp_free_i##bits (fp1); \
1484}
1485
1486FOP_CONDS(, 0, d, FMT_D, 64)
1487FOP_CONDS(abs, 1, d, FMT_D, 64)
1488FOP_CONDS(, 0, s, FMT_S, 32)
1489FOP_CONDS(abs, 1, s, FMT_S, 32)
1490FOP_CONDS(, 0, ps, FMT_PS, 64)
1491FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1492#undef FOP_CONDS
1493#undef gen_ldcmp_fpr32
1494#undef gen_ldcmp_fpr64
1495
958fb4a9 1496/* load/store instructions. */
e7139c44 1497#ifdef CONFIG_USER_ONLY
d9bea114 1498#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1499static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1500{ \
1501 TCGv t0 = tcg_temp_new(); \
1502 tcg_gen_mov_tl(t0, arg1); \
1503 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1504 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1505 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1506 tcg_temp_free(t0); \
aaa9128a 1507}
e7139c44
AJ
1508#else
1509#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1510static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1511{ \
895c2d04 1512 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1513}
1514#endif
aaa9128a
TS
1515OP_LD_ATOMIC(ll,ld32s);
1516#if defined(TARGET_MIPS64)
1517OP_LD_ATOMIC(lld,ld64);
1518#endif
1519#undef OP_LD_ATOMIC
1520
590bc601
PB
1521#ifdef CONFIG_USER_ONLY
1522#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1523static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1524{ \
1525 TCGv t0 = tcg_temp_new(); \
1526 int l1 = gen_new_label(); \
1527 int l2 = gen_new_label(); \
1528 \
1529 tcg_gen_andi_tl(t0, arg2, almask); \
1530 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1531 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1532 generate_exception(ctx, EXCP_AdES); \
1533 gen_set_label(l1); \
7db13fae 1534 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1535 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1536 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1537 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1538 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1539 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1540 gen_set_label(l2); \
1541 tcg_gen_movi_tl(t0, 0); \
1542 gen_store_gpr(t0, rt); \
1543 tcg_temp_free(t0); \
1544}
1545#else
1546#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1547static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1548{ \
1549 TCGv t0 = tcg_temp_new(); \
895c2d04 1550 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1551 gen_store_gpr(t0, rt); \
590bc601
PB
1552 tcg_temp_free(t0); \
1553}
1554#endif
590bc601 1555OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1556#if defined(TARGET_MIPS64)
590bc601 1557OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1558#endif
1559#undef OP_ST_ATOMIC
1560
662d7485
NF
1561static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1562 int base, int16_t offset)
1563{
1564 if (base == 0) {
1565 tcg_gen_movi_tl(addr, offset);
1566 } else if (offset == 0) {
1567 gen_load_gpr(addr, base);
1568 } else {
1569 tcg_gen_movi_tl(addr, offset);
1570 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1571 }
1572}
1573
364d4831
NF
1574static target_ulong pc_relative_pc (DisasContext *ctx)
1575{
1576 target_ulong pc = ctx->pc;
1577
1578 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1579 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1580
1581 pc -= branch_bytes;
1582 }
1583
1584 pc &= ~(target_ulong)3;
1585 return pc;
1586}
1587
5c13fdfd 1588/* Load */
d75c135e
AJ
1589static void gen_ld(DisasContext *ctx, uint32_t opc,
1590 int rt, int base, int16_t offset)
6af0bf9c 1591{
5c13fdfd 1592 const char *opn = "ld";
fc40787a 1593 TCGv t0, t1, t2;
afa88c3a 1594
d75c135e 1595 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1596 /* Loongson CPU uses a load to zero register for prefetch.
1597 We emulate it as a NOP. On other CPU we must perform the
1598 actual memory access. */
1599 MIPS_DEBUG("NOP");
1600 return;
1601 }
6af0bf9c 1602
afa88c3a 1603 t0 = tcg_temp_new();
662d7485 1604 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1605
6af0bf9c 1606 switch (opc) {
d26bc211 1607#if defined(TARGET_MIPS64)
6e473128 1608 case OPC_LWU:
2910c6cb 1609 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
78723684 1610 gen_store_gpr(t0, rt);
6e473128
TS
1611 opn = "lwu";
1612 break;
6af0bf9c 1613 case OPC_LD:
2910c6cb 1614 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
78723684 1615 gen_store_gpr(t0, rt);
6af0bf9c
FB
1616 opn = "ld";
1617 break;
7a387fff 1618 case OPC_LLD:
b835e919 1619 save_cpu_state(ctx, 1);
5c13fdfd 1620 op_ld_lld(t0, t0, ctx);
78723684 1621 gen_store_gpr(t0, rt);
7a387fff
TS
1622 opn = "lld";
1623 break;
6af0bf9c 1624 case OPC_LDL:
3cee3050 1625 t1 = tcg_temp_new();
fc40787a
AJ
1626 tcg_gen_andi_tl(t1, t0, 7);
1627#ifndef TARGET_WORDS_BIGENDIAN
1628 tcg_gen_xori_tl(t1, t1, 7);
1629#endif
1630 tcg_gen_shli_tl(t1, t1, 3);
1631 tcg_gen_andi_tl(t0, t0, ~7);
1632 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1633 tcg_gen_shl_tl(t0, t0, t1);
1634 tcg_gen_xori_tl(t1, t1, 63);
1635 t2 = tcg_const_tl(0x7fffffffffffffffull);
1636 tcg_gen_shr_tl(t2, t2, t1);
78723684 1637 gen_load_gpr(t1, rt);
fc40787a
AJ
1638 tcg_gen_and_tl(t1, t1, t2);
1639 tcg_temp_free(t2);
1640 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1641 tcg_temp_free(t1);
fc40787a 1642 gen_store_gpr(t0, rt);
6af0bf9c
FB
1643 opn = "ldl";
1644 break;
6af0bf9c 1645 case OPC_LDR:
3cee3050 1646 t1 = tcg_temp_new();
fc40787a
AJ
1647 tcg_gen_andi_tl(t1, t0, 7);
1648#ifdef TARGET_WORDS_BIGENDIAN
1649 tcg_gen_xori_tl(t1, t1, 7);
1650#endif
1651 tcg_gen_shli_tl(t1, t1, 3);
1652 tcg_gen_andi_tl(t0, t0, ~7);
1653 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1654 tcg_gen_shr_tl(t0, t0, t1);
1655 tcg_gen_xori_tl(t1, t1, 63);
1656 t2 = tcg_const_tl(0xfffffffffffffffeull);
1657 tcg_gen_shl_tl(t2, t2, t1);
78723684 1658 gen_load_gpr(t1, rt);
fc40787a
AJ
1659 tcg_gen_and_tl(t1, t1, t2);
1660 tcg_temp_free(t2);
1661 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1662 tcg_temp_free(t1);
fc40787a 1663 gen_store_gpr(t0, rt);
6af0bf9c
FB
1664 opn = "ldr";
1665 break;
364d4831 1666 case OPC_LDPC:
3cee3050 1667 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1668 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1669 tcg_temp_free(t1);
2910c6cb 1670 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
364d4831 1671 gen_store_gpr(t0, rt);
5c13fdfd 1672 opn = "ldpc";
364d4831 1673 break;
6af0bf9c 1674#endif
364d4831 1675 case OPC_LWPC:
3cee3050 1676 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1677 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1678 tcg_temp_free(t1);
2910c6cb 1679 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
364d4831 1680 gen_store_gpr(t0, rt);
5c13fdfd 1681 opn = "lwpc";
364d4831 1682 break;
6af0bf9c 1683 case OPC_LW:
2910c6cb 1684 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
78723684 1685 gen_store_gpr(t0, rt);
6af0bf9c
FB
1686 opn = "lw";
1687 break;
6af0bf9c 1688 case OPC_LH:
2910c6cb 1689 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
78723684 1690 gen_store_gpr(t0, rt);
6af0bf9c
FB
1691 opn = "lh";
1692 break;
6af0bf9c 1693 case OPC_LHU:
2910c6cb 1694 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
78723684 1695 gen_store_gpr(t0, rt);
6af0bf9c
FB
1696 opn = "lhu";
1697 break;
1698 case OPC_LB:
2910c6cb 1699 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
78723684 1700 gen_store_gpr(t0, rt);
6af0bf9c
FB
1701 opn = "lb";
1702 break;
6af0bf9c 1703 case OPC_LBU:
2910c6cb 1704 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
78723684 1705 gen_store_gpr(t0, rt);
6af0bf9c
FB
1706 opn = "lbu";
1707 break;
1708 case OPC_LWL:
3cee3050 1709 t1 = tcg_temp_new();
fc40787a
AJ
1710 tcg_gen_andi_tl(t1, t0, 3);
1711#ifndef TARGET_WORDS_BIGENDIAN
1712 tcg_gen_xori_tl(t1, t1, 3);
1713#endif
1714 tcg_gen_shli_tl(t1, t1, 3);
1715 tcg_gen_andi_tl(t0, t0, ~3);
1716 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1717 tcg_gen_shl_tl(t0, t0, t1);
1718 tcg_gen_xori_tl(t1, t1, 31);
1719 t2 = tcg_const_tl(0x7fffffffull);
1720 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1721 gen_load_gpr(t1, rt);
fc40787a
AJ
1722 tcg_gen_and_tl(t1, t1, t2);
1723 tcg_temp_free(t2);
1724 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1725 tcg_temp_free(t1);
fc40787a
AJ
1726 tcg_gen_ext32s_tl(t0, t0);
1727 gen_store_gpr(t0, rt);
6af0bf9c
FB
1728 opn = "lwl";
1729 break;
6af0bf9c 1730 case OPC_LWR:
3cee3050 1731 t1 = tcg_temp_new();
fc40787a
AJ
1732 tcg_gen_andi_tl(t1, t0, 3);
1733#ifdef TARGET_WORDS_BIGENDIAN
1734 tcg_gen_xori_tl(t1, t1, 3);
1735#endif
1736 tcg_gen_shli_tl(t1, t1, 3);
1737 tcg_gen_andi_tl(t0, t0, ~3);
1738 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1739 tcg_gen_shr_tl(t0, t0, t1);
1740 tcg_gen_xori_tl(t1, t1, 31);
1741 t2 = tcg_const_tl(0xfffffffeull);
1742 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1743 gen_load_gpr(t1, rt);
fc40787a
AJ
1744 tcg_gen_and_tl(t1, t1, t2);
1745 tcg_temp_free(t2);
1746 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1747 tcg_temp_free(t1);
c728154b 1748 tcg_gen_ext32s_tl(t0, t0);
fc40787a 1749 gen_store_gpr(t0, rt);
6af0bf9c
FB
1750 opn = "lwr";
1751 break;
6af0bf9c 1752 case OPC_LL:
e7139c44 1753 save_cpu_state(ctx, 1);
5c13fdfd 1754 op_ld_ll(t0, t0, ctx);
78723684 1755 gen_store_gpr(t0, rt);
6af0bf9c
FB
1756 opn = "ll";
1757 break;
d66c7132 1758 }
2abf314d 1759 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1760 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1761 tcg_temp_free(t0);
d66c7132
AJ
1762}
1763
5c13fdfd
AJ
1764/* Store */
1765static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1766 int base, int16_t offset)
1767{
1768 const char *opn = "st";
1769 TCGv t0 = tcg_temp_new();
1770 TCGv t1 = tcg_temp_new();
1771
1772 gen_base_offset_addr(ctx, t0, base, offset);
1773 gen_load_gpr(t1, rt);
1774 switch (opc) {
1775#if defined(TARGET_MIPS64)
1776 case OPC_SD:
2910c6cb 1777 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1778 opn = "sd";
1779 break;
1780 case OPC_SDL:
1781 save_cpu_state(ctx, 1);
895c2d04 1782 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1783 opn = "sdl";
1784 break;
1785 case OPC_SDR:
1786 save_cpu_state(ctx, 1);
895c2d04 1787 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1788 opn = "sdr";
1789 break;
1790#endif
1791 case OPC_SW:
2910c6cb 1792 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1793 opn = "sw";
1794 break;
1795 case OPC_SH:
2910c6cb 1796 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1797 opn = "sh";
1798 break;
1799 case OPC_SB:
2910c6cb 1800 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1801 opn = "sb";
1802 break;
1803 case OPC_SWL:
1804 save_cpu_state(ctx, 1);
895c2d04 1805 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1806 opn = "swl";
1807 break;
1808 case OPC_SWR:
1809 save_cpu_state(ctx, 1);
895c2d04 1810 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1811 opn = "swr";
1812 break;
1813 }
2abf314d 1814 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1815 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1816 tcg_temp_free(t0);
1817 tcg_temp_free(t1);
1818}
1819
1820
d66c7132
AJ
1821/* Store conditional */
1822static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1823 int base, int16_t offset)
1824{
1825 const char *opn = "st_cond";
1826 TCGv t0, t1;
1827
2d2826b9 1828#ifdef CONFIG_USER_ONLY
d66c7132 1829 t0 = tcg_temp_local_new();
d66c7132 1830 t1 = tcg_temp_local_new();
2d2826b9
AJ
1831#else
1832 t0 = tcg_temp_new();
1833 t1 = tcg_temp_new();
1834#endif
1835 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1836 gen_load_gpr(t1, rt);
1837 switch (opc) {
1838#if defined(TARGET_MIPS64)
1839 case OPC_SCD:
b835e919 1840 save_cpu_state(ctx, 1);
5c13fdfd 1841 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1842 opn = "scd";
1843 break;
1844#endif
6af0bf9c 1845 case OPC_SC:
e7139c44 1846 save_cpu_state(ctx, 1);
5c13fdfd 1847 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1848 opn = "sc";
1849 break;
6af0bf9c 1850 }
2abf314d 1851 (void)opn; /* avoid a compiler warning */
6af0bf9c 1852 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1853 tcg_temp_free(t1);
d66c7132 1854 tcg_temp_free(t0);
6af0bf9c
FB
1855}
1856
6ea83fed 1857/* Load and store */
7a387fff 1858static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1859 int base, int16_t offset)
6ea83fed 1860{
923617a3 1861 const char *opn = "flt_ldst";
4e2474d6 1862 TCGv t0 = tcg_temp_new();
6ea83fed 1863
662d7485 1864 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1865 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1866 memory access. */
6ea83fed
FB
1867 switch (opc) {
1868 case OPC_LWC1:
b6d96bed 1869 {
a7812ae4 1870 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1871
c407df81
AJ
1872 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1873 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 1874 gen_store_fpr32(fp0, ft);
a7812ae4 1875 tcg_temp_free_i32(fp0);
b6d96bed 1876 }
6ea83fed
FB
1877 opn = "lwc1";
1878 break;
1879 case OPC_SWC1:
b6d96bed 1880 {
a7812ae4
PB
1881 TCGv_i32 fp0 = tcg_temp_new_i32();
1882 TCGv t1 = tcg_temp_new();
b6d96bed
TS
1883
1884 gen_load_fpr32(fp0, ft);
a7812ae4
PB
1885 tcg_gen_extu_i32_tl(t1, fp0);
1886 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1887 tcg_temp_free(t1);
1888 tcg_temp_free_i32(fp0);
b6d96bed 1889 }
6ea83fed
FB
1890 opn = "swc1";
1891 break;
1892 case OPC_LDC1:
b6d96bed 1893 {
a7812ae4 1894 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1895
1896 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
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
TS
1905
1906 gen_load_fpr64(ctx, fp0, ft);
1907 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 1908 tcg_temp_free_i64(fp0);
b6d96bed 1909 }
6ea83fed
FB
1910 opn = "sdc1";
1911 break;
1912 default:
923617a3 1913 MIPS_INVAL(opn);
e397ee33 1914 generate_exception(ctx, EXCP_RI);
78723684 1915 goto out;
6ea83fed 1916 }
2abf314d 1917 (void)opn; /* avoid a compiler warning */
6ea83fed 1918 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1919 out:
1920 tcg_temp_free(t0);
6ea83fed 1921}
6ea83fed 1922
7db13fae 1923static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
26ebe468
NF
1924 uint32_t op, int rt, int rs, int16_t imm)
1925{
1926 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1927 check_cp1_enabled(ctx);
1928 gen_flt_ldst(ctx, op, rt, rs, imm);
1929 } else {
1930 generate_exception_err(ctx, EXCP_CpU, 1);
1931 }
1932}
1933
6af0bf9c 1934/* Arithmetic with immediate operand */
d75c135e
AJ
1935static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1936 int rt, int rs, int16_t imm)
6af0bf9c 1937{
324d9e32 1938 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1939 const char *opn = "imm arith";
6af0bf9c 1940
7a387fff 1941 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1942 /* If no destination, treat it as a NOP.
1943 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1944 MIPS_DEBUG("NOP");
324d9e32 1945 return;
6af0bf9c
FB
1946 }
1947 switch (opc) {
1948 case OPC_ADDI:
48d38ca5 1949 {
324d9e32
AJ
1950 TCGv t0 = tcg_temp_local_new();
1951 TCGv t1 = tcg_temp_new();
1952 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1953 int l1 = gen_new_label();
1954
324d9e32
AJ
1955 gen_load_gpr(t1, rs);
1956 tcg_gen_addi_tl(t0, t1, uimm);
1957 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1958
324d9e32
AJ
1959 tcg_gen_xori_tl(t1, t1, ~uimm);
1960 tcg_gen_xori_tl(t2, t0, uimm);
1961 tcg_gen_and_tl(t1, t1, t2);
1962 tcg_temp_free(t2);
1963 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1964 tcg_temp_free(t1);
48d38ca5
TS
1965 /* operands of same sign, result different sign */
1966 generate_exception(ctx, EXCP_OVERFLOW);
1967 gen_set_label(l1);
78723684 1968 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1969 gen_store_gpr(t0, rt);
1970 tcg_temp_free(t0);
48d38ca5 1971 }
6af0bf9c
FB
1972 opn = "addi";
1973 break;
1974 case OPC_ADDIU:
324d9e32
AJ
1975 if (rs != 0) {
1976 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1977 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1978 } else {
1979 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1980 }
6af0bf9c
FB
1981 opn = "addiu";
1982 break;
d26bc211 1983#if defined(TARGET_MIPS64)
7a387fff 1984 case OPC_DADDI:
48d38ca5 1985 {
324d9e32
AJ
1986 TCGv t0 = tcg_temp_local_new();
1987 TCGv t1 = tcg_temp_new();
1988 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1989 int l1 = gen_new_label();
1990
324d9e32
AJ
1991 gen_load_gpr(t1, rs);
1992 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1993
324d9e32
AJ
1994 tcg_gen_xori_tl(t1, t1, ~uimm);
1995 tcg_gen_xori_tl(t2, t0, uimm);
1996 tcg_gen_and_tl(t1, t1, t2);
1997 tcg_temp_free(t2);
1998 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1999 tcg_temp_free(t1);
48d38ca5
TS
2000 /* operands of same sign, result different sign */
2001 generate_exception(ctx, EXCP_OVERFLOW);
2002 gen_set_label(l1);
324d9e32
AJ
2003 gen_store_gpr(t0, rt);
2004 tcg_temp_free(t0);
48d38ca5 2005 }
7a387fff
TS
2006 opn = "daddi";
2007 break;
2008 case OPC_DADDIU:
324d9e32
AJ
2009 if (rs != 0) {
2010 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2011 } else {
2012 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2013 }
7a387fff
TS
2014 opn = "daddiu";
2015 break;
2016#endif
324d9e32 2017 }
2abf314d 2018 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2019 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2020}
2021
2022/* Logic with immediate operand */
d75c135e 2023static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2024 int rt, int rs, int16_t imm)
324d9e32
AJ
2025{
2026 target_ulong uimm;
324d9e32
AJ
2027
2028 if (rt == 0) {
2029 /* If no destination, treat it as a NOP. */
2030 MIPS_DEBUG("NOP");
2031 return;
2032 }
2033 uimm = (uint16_t)imm;
2034 switch (opc) {
6af0bf9c 2035 case OPC_ANDI:
324d9e32
AJ
2036 if (likely(rs != 0))
2037 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2038 else
2039 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2040 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2041 regnames[rs], uimm);
6af0bf9c
FB
2042 break;
2043 case OPC_ORI:
324d9e32
AJ
2044 if (rs != 0)
2045 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2046 else
2047 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2048 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2049 regnames[rs], uimm);
6af0bf9c
FB
2050 break;
2051 case OPC_XORI:
324d9e32
AJ
2052 if (likely(rs != 0))
2053 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2054 else
2055 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2056 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2057 regnames[rs], uimm);
6af0bf9c
FB
2058 break;
2059 case OPC_LUI:
324d9e32 2060 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2061 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2062 break;
2063
2064 default:
2065 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2066 break;
324d9e32 2067 }
324d9e32
AJ
2068}
2069
2070/* Set on less than with immediate operand */
d75c135e 2071static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2072 int rt, int rs, int16_t imm)
324d9e32
AJ
2073{
2074 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2075 const char *opn = "imm arith";
2076 TCGv t0;
2077
2078 if (rt == 0) {
2079 /* If no destination, treat it as a NOP. */
2080 MIPS_DEBUG("NOP");
2081 return;
2082 }
2083 t0 = tcg_temp_new();
2084 gen_load_gpr(t0, rs);
2085 switch (opc) {
2086 case OPC_SLTI:
e68dd28f 2087 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2088 opn = "slti";
2089 break;
2090 case OPC_SLTIU:
e68dd28f 2091 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2092 opn = "sltiu";
2093 break;
2094 }
2abf314d 2095 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2096 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2097 tcg_temp_free(t0);
2098}
2099
2100/* Shifts with immediate operand */
d75c135e 2101static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2102 int rt, int rs, int16_t imm)
2103{
2104 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2105 const char *opn = "imm shift";
2106 TCGv t0;
2107
2108 if (rt == 0) {
2109 /* If no destination, treat it as a NOP. */
2110 MIPS_DEBUG("NOP");
2111 return;
2112 }
2113
2114 t0 = tcg_temp_new();
2115 gen_load_gpr(t0, rs);
2116 switch (opc) {
6af0bf9c 2117 case OPC_SLL:
78723684 2118 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2119 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2120 opn = "sll";
2121 break;
2122 case OPC_SRA:
324d9e32 2123 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2124 opn = "sra";
2125 break;
2126 case OPC_SRL:
ea63e2c3
NF
2127 if (uimm != 0) {
2128 tcg_gen_ext32u_tl(t0, t0);
2129 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2130 } else {
2131 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2132 }
ea63e2c3
NF
2133 opn = "srl";
2134 break;
2135 case OPC_ROTR:
2136 if (uimm != 0) {
2137 TCGv_i32 t1 = tcg_temp_new_i32();
2138
2139 tcg_gen_trunc_tl_i32(t1, t0);
2140 tcg_gen_rotri_i32(t1, t1, uimm);
2141 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2142 tcg_temp_free_i32(t1);
3399e30f
NF
2143 } else {
2144 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2145 }
2146 opn = "rotr";
7a387fff 2147 break;
d26bc211 2148#if defined(TARGET_MIPS64)
7a387fff 2149 case OPC_DSLL:
324d9e32 2150 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2151 opn = "dsll";
2152 break;
2153 case OPC_DSRA:
324d9e32 2154 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2155 opn = "dsra";
2156 break;
2157 case OPC_DSRL:
ea63e2c3
NF
2158 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2159 opn = "dsrl";
2160 break;
2161 case OPC_DROTR:
2162 if (uimm != 0) {
2163 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2164 } else {
2165 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2166 }
ea63e2c3 2167 opn = "drotr";
7a387fff
TS
2168 break;
2169 case OPC_DSLL32:
324d9e32 2170 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2171 opn = "dsll32";
2172 break;
2173 case OPC_DSRA32:
324d9e32 2174 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2175 opn = "dsra32";
2176 break;
2177 case OPC_DSRL32:
ea63e2c3
NF
2178 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2179 opn = "dsrl32";
2180 break;
2181 case OPC_DROTR32:
2182 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2183 opn = "drotr32";
6af0bf9c 2184 break;
7a387fff 2185#endif
6af0bf9c 2186 }
2abf314d 2187 (void)opn; /* avoid a compiler warning */
93b12ccc 2188 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2189 tcg_temp_free(t0);
6af0bf9c
FB
2190}
2191
2192/* Arithmetic */
d75c135e
AJ
2193static void gen_arith(DisasContext *ctx, uint32_t opc,
2194 int rd, int rs, int rt)
6af0bf9c 2195{
923617a3 2196 const char *opn = "arith";
6af0bf9c 2197
7a387fff
TS
2198 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2199 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2200 /* If no destination, treat it as a NOP.
2201 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2202 MIPS_DEBUG("NOP");
460f00c4 2203 return;
185f0762 2204 }
460f00c4 2205
6af0bf9c
FB
2206 switch (opc) {
2207 case OPC_ADD:
48d38ca5 2208 {
460f00c4
AJ
2209 TCGv t0 = tcg_temp_local_new();
2210 TCGv t1 = tcg_temp_new();
2211 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2212 int l1 = gen_new_label();
2213
460f00c4
AJ
2214 gen_load_gpr(t1, rs);
2215 gen_load_gpr(t2, rt);
2216 tcg_gen_add_tl(t0, t1, t2);
2217 tcg_gen_ext32s_tl(t0, t0);
2218 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2219 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2220 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2221 tcg_temp_free(t2);
2222 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2223 tcg_temp_free(t1);
48d38ca5
TS
2224 /* operands of same sign, result different sign */
2225 generate_exception(ctx, EXCP_OVERFLOW);
2226 gen_set_label(l1);
460f00c4
AJ
2227 gen_store_gpr(t0, rd);
2228 tcg_temp_free(t0);
48d38ca5 2229 }
6af0bf9c
FB
2230 opn = "add";
2231 break;
2232 case OPC_ADDU:
460f00c4
AJ
2233 if (rs != 0 && rt != 0) {
2234 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2235 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2236 } else if (rs == 0 && rt != 0) {
2237 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2238 } else if (rs != 0 && rt == 0) {
2239 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2240 } else {
2241 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2242 }
6af0bf9c
FB
2243 opn = "addu";
2244 break;
2245 case OPC_SUB:
48d38ca5 2246 {
460f00c4
AJ
2247 TCGv t0 = tcg_temp_local_new();
2248 TCGv t1 = tcg_temp_new();
2249 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2250 int l1 = gen_new_label();
2251
460f00c4
AJ
2252 gen_load_gpr(t1, rs);
2253 gen_load_gpr(t2, rt);
2254 tcg_gen_sub_tl(t0, t1, t2);
2255 tcg_gen_ext32s_tl(t0, t0);
2256 tcg_gen_xor_tl(t2, t1, t2);
2257 tcg_gen_xor_tl(t1, t0, t1);
2258 tcg_gen_and_tl(t1, t1, t2);
2259 tcg_temp_free(t2);
2260 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2261 tcg_temp_free(t1);
31e3104f 2262 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2263 generate_exception(ctx, EXCP_OVERFLOW);
2264 gen_set_label(l1);
460f00c4
AJ
2265 gen_store_gpr(t0, rd);
2266 tcg_temp_free(t0);
48d38ca5 2267 }
6af0bf9c
FB
2268 opn = "sub";
2269 break;
2270 case OPC_SUBU:
460f00c4
AJ
2271 if (rs != 0 && rt != 0) {
2272 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2273 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2274 } else if (rs == 0 && rt != 0) {
2275 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2276 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2277 } else if (rs != 0 && rt == 0) {
2278 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2279 } else {
2280 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2281 }
6af0bf9c
FB
2282 opn = "subu";
2283 break;
d26bc211 2284#if defined(TARGET_MIPS64)
7a387fff 2285 case OPC_DADD:
48d38ca5 2286 {
460f00c4
AJ
2287 TCGv t0 = tcg_temp_local_new();
2288 TCGv t1 = tcg_temp_new();
2289 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2290 int l1 = gen_new_label();
2291
460f00c4
AJ
2292 gen_load_gpr(t1, rs);
2293 gen_load_gpr(t2, rt);
2294 tcg_gen_add_tl(t0, t1, t2);
2295 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2296 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2297 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2298 tcg_temp_free(t2);
2299 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2300 tcg_temp_free(t1);
48d38ca5
TS
2301 /* operands of same sign, result different sign */
2302 generate_exception(ctx, EXCP_OVERFLOW);
2303 gen_set_label(l1);
460f00c4
AJ
2304 gen_store_gpr(t0, rd);
2305 tcg_temp_free(t0);
48d38ca5 2306 }
7a387fff
TS
2307 opn = "dadd";
2308 break;
2309 case OPC_DADDU:
460f00c4
AJ
2310 if (rs != 0 && rt != 0) {
2311 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2312 } else if (rs == 0 && rt != 0) {
2313 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2314 } else if (rs != 0 && rt == 0) {
2315 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2316 } else {
2317 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2318 }
7a387fff
TS
2319 opn = "daddu";
2320 break;
2321 case OPC_DSUB:
48d38ca5 2322 {
460f00c4
AJ
2323 TCGv t0 = tcg_temp_local_new();
2324 TCGv t1 = tcg_temp_new();
2325 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2326 int l1 = gen_new_label();
2327
460f00c4
AJ
2328 gen_load_gpr(t1, rs);
2329 gen_load_gpr(t2, rt);
2330 tcg_gen_sub_tl(t0, t1, t2);
2331 tcg_gen_xor_tl(t2, t1, t2);
2332 tcg_gen_xor_tl(t1, t0, t1);
2333 tcg_gen_and_tl(t1, t1, t2);
2334 tcg_temp_free(t2);
2335 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2336 tcg_temp_free(t1);
31e3104f 2337 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2338 generate_exception(ctx, EXCP_OVERFLOW);
2339 gen_set_label(l1);
460f00c4
AJ
2340 gen_store_gpr(t0, rd);
2341 tcg_temp_free(t0);
48d38ca5 2342 }
7a387fff
TS
2343 opn = "dsub";
2344 break;
2345 case OPC_DSUBU:
460f00c4
AJ
2346 if (rs != 0 && rt != 0) {
2347 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2348 } else if (rs == 0 && rt != 0) {
2349 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2350 } else if (rs != 0 && rt == 0) {
2351 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2352 } else {
2353 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2354 }
7a387fff
TS
2355 opn = "dsubu";
2356 break;
2357#endif
460f00c4
AJ
2358 case OPC_MUL:
2359 if (likely(rs != 0 && rt != 0)) {
2360 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2361 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2362 } else {
2363 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2364 }
2365 opn = "mul";
6af0bf9c 2366 break;
460f00c4 2367 }
2abf314d 2368 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2369 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2370}
2371
2372/* Conditional move */
d75c135e 2373static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2374 int rd, int rs, int rt)
460f00c4
AJ
2375{
2376 const char *opn = "cond move";
acf12465 2377 TCGv t0, t1, t2;
460f00c4
AJ
2378
2379 if (rd == 0) {
acf12465 2380 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2381 MIPS_DEBUG("NOP");
2382 return;
2383 }
2384
acf12465
AJ
2385 t0 = tcg_temp_new();
2386 gen_load_gpr(t0, rt);
2387 t1 = tcg_const_tl(0);
2388 t2 = tcg_temp_new();
2389 gen_load_gpr(t2, rs);
460f00c4
AJ
2390 switch (opc) {
2391 case OPC_MOVN:
acf12465 2392 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2393 opn = "movn";
6af0bf9c 2394 break;
460f00c4 2395 case OPC_MOVZ:
acf12465 2396 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2397 opn = "movz";
2398 break;
2399 }
acf12465
AJ
2400 tcg_temp_free(t2);
2401 tcg_temp_free(t1);
2402 tcg_temp_free(t0);
460f00c4 2403
2abf314d 2404 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2405 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2406}
2407
2408/* Logic */
d75c135e 2409static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2410 int rd, int rs, int rt)
460f00c4
AJ
2411{
2412 const char *opn = "logic";
2413
2414 if (rd == 0) {
2415 /* If no destination, treat it as a NOP. */
2416 MIPS_DEBUG("NOP");
2417 return;
2418 }
2419
2420 switch (opc) {
6af0bf9c 2421 case OPC_AND:
460f00c4
AJ
2422 if (likely(rs != 0 && rt != 0)) {
2423 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2424 } else {
2425 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2426 }
6af0bf9c
FB
2427 opn = "and";
2428 break;
2429 case OPC_NOR:
460f00c4
AJ
2430 if (rs != 0 && rt != 0) {
2431 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2432 } else if (rs == 0 && rt != 0) {
2433 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2434 } else if (rs != 0 && rt == 0) {
2435 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2436 } else {
2437 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2438 }
6af0bf9c
FB
2439 opn = "nor";
2440 break;
2441 case OPC_OR:
460f00c4
AJ
2442 if (likely(rs != 0 && rt != 0)) {
2443 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2444 } else if (rs == 0 && rt != 0) {
2445 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2446 } else if (rs != 0 && rt == 0) {
2447 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2448 } else {
2449 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2450 }
6af0bf9c
FB
2451 opn = "or";
2452 break;
2453 case OPC_XOR:
460f00c4
AJ
2454 if (likely(rs != 0 && rt != 0)) {
2455 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2456 } else if (rs == 0 && rt != 0) {
2457 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2458 } else if (rs != 0 && rt == 0) {
2459 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2460 } else {
2461 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2462 }
6af0bf9c
FB
2463 opn = "xor";
2464 break;
460f00c4 2465 }
2abf314d 2466 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2467 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2468}
2469
2470/* Set on lower than */
d75c135e 2471static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2472 int rd, int rs, int rt)
460f00c4
AJ
2473{
2474 const char *opn = "slt";
2475 TCGv t0, t1;
2476
2477 if (rd == 0) {
2478 /* If no destination, treat it as a NOP. */
2479 MIPS_DEBUG("NOP");
2480 return;
2481 }
2482
2483 t0 = tcg_temp_new();
2484 t1 = tcg_temp_new();
2485 gen_load_gpr(t0, rs);
2486 gen_load_gpr(t1, rt);
2487 switch (opc) {
2488 case OPC_SLT:
e68dd28f 2489 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2490 opn = "slt";
6af0bf9c 2491 break;
460f00c4 2492 case OPC_SLTU:
e68dd28f 2493 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2494 opn = "sltu";
2495 break;
2496 }
2abf314d 2497 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2498 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2499 tcg_temp_free(t0);
2500 tcg_temp_free(t1);
2501}
20c4c97c 2502
460f00c4 2503/* Shifts */
d75c135e
AJ
2504static void gen_shift(DisasContext *ctx, uint32_t opc,
2505 int rd, int rs, int rt)
460f00c4
AJ
2506{
2507 const char *opn = "shifts";
2508 TCGv t0, t1;
20c4c97c 2509
460f00c4
AJ
2510 if (rd == 0) {
2511 /* If no destination, treat it as a NOP.
2512 For add & sub, we must generate the overflow exception when needed. */
2513 MIPS_DEBUG("NOP");
2514 return;
2515 }
2516
2517 t0 = tcg_temp_new();
2518 t1 = tcg_temp_new();
2519 gen_load_gpr(t0, rs);
2520 gen_load_gpr(t1, rt);
2521 switch (opc) {
6af0bf9c 2522 case OPC_SLLV:
78723684
TS
2523 tcg_gen_andi_tl(t0, t0, 0x1f);
2524 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2525 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2526 opn = "sllv";
2527 break;
2528 case OPC_SRAV:
78723684 2529 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2530 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2531 opn = "srav";
2532 break;
2533 case OPC_SRLV:
ea63e2c3
NF
2534 tcg_gen_ext32u_tl(t1, t1);
2535 tcg_gen_andi_tl(t0, t0, 0x1f);
2536 tcg_gen_shr_tl(t0, t1, t0);
2537 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2538 opn = "srlv";
2539 break;
2540 case OPC_ROTRV:
2541 {
2542 TCGv_i32 t2 = tcg_temp_new_i32();
2543 TCGv_i32 t3 = tcg_temp_new_i32();
2544
2545 tcg_gen_trunc_tl_i32(t2, t0);
2546 tcg_gen_trunc_tl_i32(t3, t1);
2547 tcg_gen_andi_i32(t2, t2, 0x1f);
2548 tcg_gen_rotr_i32(t2, t3, t2);
2549 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2550 tcg_temp_free_i32(t2);
2551 tcg_temp_free_i32(t3);
2552 opn = "rotrv";
5a63bcb2 2553 }
7a387fff 2554 break;
d26bc211 2555#if defined(TARGET_MIPS64)
7a387fff 2556 case OPC_DSLLV:
78723684 2557 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2558 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2559 opn = "dsllv";
2560 break;
2561 case OPC_DSRAV:
78723684 2562 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2563 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2564 opn = "dsrav";
2565 break;
2566 case OPC_DSRLV:
ea63e2c3
NF
2567 tcg_gen_andi_tl(t0, t0, 0x3f);
2568 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2569 opn = "dsrlv";
2570 break;
2571 case OPC_DROTRV:
2572 tcg_gen_andi_tl(t0, t0, 0x3f);
2573 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2574 opn = "drotrv";
6af0bf9c 2575 break;
7a387fff 2576#endif
6af0bf9c 2577 }
2abf314d 2578 (void)opn; /* avoid a compiler warning */
6af0bf9c 2579 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2580 tcg_temp_free(t0);
2581 tcg_temp_free(t1);
6af0bf9c
FB
2582}
2583
2584/* Arithmetic on HI/LO registers */
7a387fff 2585static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
6af0bf9c 2586{
923617a3 2587 const char *opn = "hilo";
4133498f 2588 unsigned int acc;
6af0bf9c
FB
2589
2590 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2591 /* Treat as NOP. */
6af0bf9c 2592 MIPS_DEBUG("NOP");
a1f6684d 2593 return;
6af0bf9c 2594 }
4133498f
JL
2595
2596 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2597 acc = ((ctx->opcode) >> 21) & 0x03;
2598 } else {
2599 acc = ((ctx->opcode) >> 11) & 0x03;
2600 }
2601
2602 if (acc != 0) {
2603 check_dsp(ctx);
2604 }
2605
6af0bf9c
FB
2606 switch (opc) {
2607 case OPC_MFHI:
4133498f
JL
2608#if defined(TARGET_MIPS64)
2609 if (acc != 0) {
2610 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2611 } else
2612#endif
2613 {
2614 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2615 }
6af0bf9c
FB
2616 opn = "mfhi";
2617 break;
2618 case OPC_MFLO:
4133498f
JL
2619#if defined(TARGET_MIPS64)
2620 if (acc != 0) {
2621 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2622 } else
2623#endif
2624 {
2625 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2626 }
6af0bf9c
FB
2627 opn = "mflo";
2628 break;
2629 case OPC_MTHI:
4133498f
JL
2630 if (reg != 0) {
2631#if defined(TARGET_MIPS64)
2632 if (acc != 0) {
2633 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2634 } else
2635#endif
2636 {
2637 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2638 }
2639 } else {
2640 tcg_gen_movi_tl(cpu_HI[acc], 0);
2641 }
6af0bf9c
FB
2642 opn = "mthi";
2643 break;
2644 case OPC_MTLO:
4133498f
JL
2645 if (reg != 0) {
2646#if defined(TARGET_MIPS64)
2647 if (acc != 0) {
2648 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2649 } else
2650#endif
2651 {
2652 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2653 }
2654 } else {
2655 tcg_gen_movi_tl(cpu_LO[acc], 0);
2656 }
6af0bf9c
FB
2657 opn = "mtlo";
2658 break;
6af0bf9c 2659 }
2abf314d 2660 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2661 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2662}
2663
7a387fff 2664static void gen_muldiv (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2665 int rs, int rt)
2666{
923617a3 2667 const char *opn = "mul/div";
d45f89f4 2668 TCGv t0, t1;
4133498f 2669 unsigned int acc;
d45f89f4 2670
51127181
AJ
2671 t0 = tcg_temp_new();
2672 t1 = tcg_temp_new();
6af0bf9c 2673
78723684
TS
2674 gen_load_gpr(t0, rs);
2675 gen_load_gpr(t1, rt);
51127181 2676
6af0bf9c
FB
2677 switch (opc) {
2678 case OPC_DIV:
48d38ca5 2679 {
51127181
AJ
2680 TCGv t2 = tcg_temp_new();
2681 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2682 tcg_gen_ext32s_tl(t0, t0);
2683 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2684 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2685 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2686 tcg_gen_and_tl(t2, t2, t3);
2687 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2688 tcg_gen_or_tl(t2, t2, t3);
2689 tcg_gen_movi_tl(t3, 0);
2690 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
d45f89f4
AJ
2691 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2692 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2693 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2694 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
51127181
AJ
2695 tcg_temp_free(t3);
2696 tcg_temp_free(t2);
48d38ca5 2697 }
6af0bf9c
FB
2698 opn = "div";
2699 break;
2700 case OPC_DIVU:
48d38ca5 2701 {
51127181
AJ
2702 TCGv t2 = tcg_const_tl(0);
2703 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
2704 tcg_gen_ext32u_tl(t0, t0);
2705 tcg_gen_ext32u_tl(t1, t1);
51127181 2706 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
d45f89f4
AJ
2707 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2708 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2709 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2710 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
51127181
AJ
2711 tcg_temp_free(t3);
2712 tcg_temp_free(t2);
48d38ca5 2713 }
6af0bf9c
FB
2714 opn = "divu";
2715 break;
2716 case OPC_MULT:
214c465f 2717 {
ce1dd5d1
RH
2718 TCGv_i32 t2 = tcg_temp_new_i32();
2719 TCGv_i32 t3 = tcg_temp_new_i32();
4133498f
JL
2720 acc = ((ctx->opcode) >> 11) & 0x03;
2721 if (acc != 0) {
2722 check_dsp(ctx);
2723 }
d45f89f4 2724
ce1dd5d1
RH
2725 tcg_gen_trunc_tl_i32(t2, t0);
2726 tcg_gen_trunc_tl_i32(t3, t1);
2727 tcg_gen_muls2_i32(t2, t3, t2, t3);
2728 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2729 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2730 tcg_temp_free_i32(t2);
2731 tcg_temp_free_i32(t3);
214c465f 2732 }
6af0bf9c
FB
2733 opn = "mult";
2734 break;
2735 case OPC_MULTU:
214c465f 2736 {
ce1dd5d1
RH
2737 TCGv_i32 t2 = tcg_temp_new_i32();
2738 TCGv_i32 t3 = tcg_temp_new_i32();
4133498f
JL
2739 acc = ((ctx->opcode) >> 11) & 0x03;
2740 if (acc != 0) {
2741 check_dsp(ctx);
2742 }
214c465f 2743
ce1dd5d1
RH
2744 tcg_gen_trunc_tl_i32(t2, t0);
2745 tcg_gen_trunc_tl_i32(t3, t1);
2746 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2747 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2748 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2749 tcg_temp_free_i32(t2);
2750 tcg_temp_free_i32(t3);
214c465f 2751 }
6af0bf9c
FB
2752 opn = "multu";
2753 break;
d26bc211 2754#if defined(TARGET_MIPS64)
7a387fff 2755 case OPC_DDIV:
48d38ca5 2756 {
51127181
AJ
2757 TCGv t2 = tcg_temp_new();
2758 TCGv t3 = tcg_temp_new();
2759 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2760 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2761 tcg_gen_and_tl(t2, t2, t3);
2762 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2763 tcg_gen_or_tl(t2, t2, t3);
2764 tcg_gen_movi_tl(t3, 0);
2765 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2766 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2767 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2768 tcg_temp_free(t3);
2769 tcg_temp_free(t2);
48d38ca5 2770 }
7a387fff
TS
2771 opn = "ddiv";
2772 break;
2773 case OPC_DDIVU:
48d38ca5 2774 {
51127181
AJ
2775 TCGv t2 = tcg_const_tl(0);
2776 TCGv t3 = tcg_const_tl(1);
2777 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
b10fa3c9
AJ
2778 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2779 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
51127181
AJ
2780 tcg_temp_free(t3);
2781 tcg_temp_free(t2);
48d38ca5 2782 }
7a387fff
TS
2783 opn = "ddivu";
2784 break;
2785 case OPC_DMULT:
ce1dd5d1 2786 tcg_gen_muls2_i64(cpu_LO[0], cpu_HI[0], t0, t1);
7a387fff
TS
2787 opn = "dmult";
2788 break;
2789 case OPC_DMULTU:
ce1dd5d1 2790 tcg_gen_mulu2_i64(cpu_LO[0], cpu_HI[0], t0, t1);
7a387fff
TS
2791 opn = "dmultu";
2792 break;
2793#endif
6af0bf9c 2794 case OPC_MADD:
214c465f 2795 {
d45f89f4
AJ
2796 TCGv_i64 t2 = tcg_temp_new_i64();
2797 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2798 acc = ((ctx->opcode) >> 11) & 0x03;
2799 if (acc != 0) {
2800 check_dsp(ctx);
2801 }
d45f89f4
AJ
2802
2803 tcg_gen_ext_tl_i64(t2, t0);
2804 tcg_gen_ext_tl_i64(t3, t1);
2805 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2806 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2807 tcg_gen_add_i64(t2, t2, t3);
2808 tcg_temp_free_i64(t3);
2809 tcg_gen_trunc_i64_tl(t0, t2);
2810 tcg_gen_shri_i64(t2, t2, 32);
2811 tcg_gen_trunc_i64_tl(t1, t2);
2812 tcg_temp_free_i64(t2);
4133498f
JL
2813 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2814 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2815 }
6af0bf9c
FB
2816 opn = "madd";
2817 break;
2818 case OPC_MADDU:
4133498f 2819 {
d45f89f4
AJ
2820 TCGv_i64 t2 = tcg_temp_new_i64();
2821 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2822 acc = ((ctx->opcode) >> 11) & 0x03;
2823 if (acc != 0) {
2824 check_dsp(ctx);
2825 }
214c465f 2826
78723684
TS
2827 tcg_gen_ext32u_tl(t0, t0);
2828 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2829 tcg_gen_extu_tl_i64(t2, t0);
2830 tcg_gen_extu_tl_i64(t3, t1);
2831 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2832 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2833 tcg_gen_add_i64(t2, t2, t3);
2834 tcg_temp_free_i64(t3);
2835 tcg_gen_trunc_i64_tl(t0, t2);
2836 tcg_gen_shri_i64(t2, t2, 32);
2837 tcg_gen_trunc_i64_tl(t1, t2);
2838 tcg_temp_free_i64(t2);
4133498f
JL
2839 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2840 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2841 }
6af0bf9c
FB
2842 opn = "maddu";
2843 break;
2844 case OPC_MSUB:
214c465f 2845 {
d45f89f4
AJ
2846 TCGv_i64 t2 = tcg_temp_new_i64();
2847 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2848 acc = ((ctx->opcode) >> 11) & 0x03;
2849 if (acc != 0) {
2850 check_dsp(ctx);
2851 }
d45f89f4
AJ
2852
2853 tcg_gen_ext_tl_i64(t2, t0);
2854 tcg_gen_ext_tl_i64(t3, t1);
2855 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2856 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2857 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2858 tcg_temp_free_i64(t3);
2859 tcg_gen_trunc_i64_tl(t0, t2);
2860 tcg_gen_shri_i64(t2, t2, 32);
2861 tcg_gen_trunc_i64_tl(t1, t2);
2862 tcg_temp_free_i64(t2);
4133498f
JL
2863 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2864 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2865 }
6af0bf9c
FB
2866 opn = "msub";
2867 break;
2868 case OPC_MSUBU:
214c465f 2869 {
d45f89f4
AJ
2870 TCGv_i64 t2 = tcg_temp_new_i64();
2871 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2872 acc = ((ctx->opcode) >> 11) & 0x03;
2873 if (acc != 0) {
2874 check_dsp(ctx);
2875 }
214c465f 2876
78723684
TS
2877 tcg_gen_ext32u_tl(t0, t0);
2878 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2879 tcg_gen_extu_tl_i64(t2, t0);
2880 tcg_gen_extu_tl_i64(t3, t1);
2881 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2882 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2883 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2884 tcg_temp_free_i64(t3);
2885 tcg_gen_trunc_i64_tl(t0, t2);
2886 tcg_gen_shri_i64(t2, t2, 32);
2887 tcg_gen_trunc_i64_tl(t1, t2);
2888 tcg_temp_free_i64(t2);
4133498f
JL
2889 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2890 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2891 }
6af0bf9c
FB
2892 opn = "msubu";
2893 break;
2894 default:
923617a3 2895 MIPS_INVAL(opn);
6af0bf9c 2896 generate_exception(ctx, EXCP_RI);
78723684 2897 goto out;
6af0bf9c 2898 }
2abf314d 2899 (void)opn; /* avoid a compiler warning */
6af0bf9c 2900 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2901 out:
2902 tcg_temp_free(t0);
2903 tcg_temp_free(t1);
6af0bf9c
FB
2904}
2905
e9c71dd1
TS
2906static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2907 int rd, int rs, int rt)
2908{
2909 const char *opn = "mul vr54xx";
f157bfe1
AJ
2910 TCGv t0 = tcg_temp_new();
2911 TCGv t1 = tcg_temp_new();
e9c71dd1 2912
6c5c1e20
TS
2913 gen_load_gpr(t0, rs);
2914 gen_load_gpr(t1, rt);
e9c71dd1
TS
2915
2916 switch (opc) {
2917 case OPC_VR54XX_MULS:
895c2d04 2918 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2919 opn = "muls";
6958549d 2920 break;
e9c71dd1 2921 case OPC_VR54XX_MULSU:
895c2d04 2922 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2923 opn = "mulsu";
6958549d 2924 break;
e9c71dd1 2925 case OPC_VR54XX_MACC:
895c2d04 2926 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2927 opn = "macc";
6958549d 2928 break;
e9c71dd1 2929 case OPC_VR54XX_MACCU:
895c2d04 2930 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2931 opn = "maccu";
6958549d 2932 break;
e9c71dd1 2933 case OPC_VR54XX_MSAC:
895c2d04 2934 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2935 opn = "msac";
6958549d 2936 break;
e9c71dd1 2937 case OPC_VR54XX_MSACU:
895c2d04 2938 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2939 opn = "msacu";
6958549d 2940 break;
e9c71dd1 2941 case OPC_VR54XX_MULHI:
895c2d04 2942 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2943 opn = "mulhi";
6958549d 2944 break;
e9c71dd1 2945 case OPC_VR54XX_MULHIU:
895c2d04 2946 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2947 opn = "mulhiu";
6958549d 2948 break;
e9c71dd1 2949 case OPC_VR54XX_MULSHI:
895c2d04 2950 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2951 opn = "mulshi";
6958549d 2952 break;
e9c71dd1 2953 case OPC_VR54XX_MULSHIU:
895c2d04 2954 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2955 opn = "mulshiu";
6958549d 2956 break;
e9c71dd1 2957 case OPC_VR54XX_MACCHI:
895c2d04 2958 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2959 opn = "macchi";
6958549d 2960 break;
e9c71dd1 2961 case OPC_VR54XX_MACCHIU:
895c2d04 2962 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2963 opn = "macchiu";
6958549d 2964 break;
e9c71dd1 2965 case OPC_VR54XX_MSACHI:
895c2d04 2966 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2967 opn = "msachi";
6958549d 2968 break;
e9c71dd1 2969 case OPC_VR54XX_MSACHIU:
895c2d04 2970 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2971 opn = "msachiu";
6958549d 2972 break;
e9c71dd1
TS
2973 default:
2974 MIPS_INVAL("mul vr54xx");
2975 generate_exception(ctx, EXCP_RI);
6c5c1e20 2976 goto out;
e9c71dd1 2977 }
6c5c1e20 2978 gen_store_gpr(t0, rd);
2abf314d 2979 (void)opn; /* avoid a compiler warning */
e9c71dd1 2980 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2981
2982 out:
2983 tcg_temp_free(t0);
2984 tcg_temp_free(t1);
e9c71dd1
TS
2985}
2986
7a387fff 2987static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2988 int rd, int rs)
2989{
923617a3 2990 const char *opn = "CLx";
20e1fb52 2991 TCGv t0;
6c5c1e20 2992
6af0bf9c 2993 if (rd == 0) {
ead9360e 2994 /* Treat as NOP. */
6af0bf9c 2995 MIPS_DEBUG("NOP");
20e1fb52 2996 return;
6af0bf9c 2997 }
20e1fb52 2998 t0 = tcg_temp_new();
6c5c1e20 2999 gen_load_gpr(t0, rs);
6af0bf9c
FB
3000 switch (opc) {
3001 case OPC_CLO:
20e1fb52 3002 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3003 opn = "clo";
3004 break;
3005 case OPC_CLZ:
20e1fb52 3006 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3007 opn = "clz";
3008 break;
d26bc211 3009#if defined(TARGET_MIPS64)
7a387fff 3010 case OPC_DCLO:
20e1fb52 3011 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3012 opn = "dclo";
3013 break;
3014 case OPC_DCLZ:
20e1fb52 3015 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3016 opn = "dclz";
3017 break;
3018#endif
6af0bf9c 3019 }
2abf314d 3020 (void)opn; /* avoid a compiler warning */
6af0bf9c 3021 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3022 tcg_temp_free(t0);
6af0bf9c
FB
3023}
3024
161f85e6 3025/* Godson integer instructions */
bd277fa1
RH
3026static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3027 int rd, int rs, int rt)
161f85e6
AJ
3028{
3029 const char *opn = "loongson";
3030 TCGv t0, t1;
3031
3032 if (rd == 0) {
3033 /* Treat as NOP. */
3034 MIPS_DEBUG("NOP");
3035 return;
3036 }
3037
3038 switch (opc) {
3039 case OPC_MULT_G_2E:
3040 case OPC_MULT_G_2F:
3041 case OPC_MULTU_G_2E:
3042 case OPC_MULTU_G_2F:
3043#if defined(TARGET_MIPS64)
3044 case OPC_DMULT_G_2E:
3045 case OPC_DMULT_G_2F:
3046 case OPC_DMULTU_G_2E:
3047 case OPC_DMULTU_G_2F:
3048#endif
3049 t0 = tcg_temp_new();
3050 t1 = tcg_temp_new();
3051 break;
3052 default:
3053 t0 = tcg_temp_local_new();
3054 t1 = tcg_temp_local_new();
3055 break;
3056 }
3057
3058 gen_load_gpr(t0, rs);
3059 gen_load_gpr(t1, rt);
3060
3061 switch (opc) {
3062 case OPC_MULT_G_2E:
3063 case OPC_MULT_G_2F:
3064 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3065 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3066 opn = "mult.g";
3067 break;
3068 case OPC_MULTU_G_2E:
3069 case OPC_MULTU_G_2F:
3070 tcg_gen_ext32u_tl(t0, t0);
3071 tcg_gen_ext32u_tl(t1, t1);
3072 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3073 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3074 opn = "multu.g";
3075 break;
3076 case OPC_DIV_G_2E:
3077 case OPC_DIV_G_2F:
3078 {
3079 int l1 = gen_new_label();
3080 int l2 = gen_new_label();
3081 int l3 = gen_new_label();
3082 tcg_gen_ext32s_tl(t0, t0);
3083 tcg_gen_ext32s_tl(t1, t1);
3084 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3085 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3086 tcg_gen_br(l3);
3087 gen_set_label(l1);
3088 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3089 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3090 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3091 tcg_gen_br(l3);
3092 gen_set_label(l2);
3093 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3094 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3095 gen_set_label(l3);
3096 }
3097 opn = "div.g";
3098 break;
3099 case OPC_DIVU_G_2E:
3100 case OPC_DIVU_G_2F:
3101 {
3102 int l1 = gen_new_label();
3103 int l2 = gen_new_label();
3104 tcg_gen_ext32u_tl(t0, t0);
3105 tcg_gen_ext32u_tl(t1, t1);
3106 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3107 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3108 tcg_gen_br(l2);
3109 gen_set_label(l1);
3110 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3111 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3112 gen_set_label(l2);
3113 }
3114 opn = "divu.g";
3115 break;
3116 case OPC_MOD_G_2E:
3117 case OPC_MOD_G_2F:
3118 {
3119 int l1 = gen_new_label();
3120 int l2 = gen_new_label();
3121 int l3 = gen_new_label();
3122 tcg_gen_ext32u_tl(t0, t0);
3123 tcg_gen_ext32u_tl(t1, t1);
3124 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3125 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3126 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3127 gen_set_label(l1);
3128 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3129 tcg_gen_br(l3);
3130 gen_set_label(l2);
3131 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3132 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3133 gen_set_label(l3);
3134 }
3135 opn = "mod.g";
3136 break;
3137 case OPC_MODU_G_2E:
3138 case OPC_MODU_G_2F:
3139 {
3140 int l1 = gen_new_label();
3141 int l2 = gen_new_label();
3142 tcg_gen_ext32u_tl(t0, t0);
3143 tcg_gen_ext32u_tl(t1, t1);
3144 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3145 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3146 tcg_gen_br(l2);
3147 gen_set_label(l1);
3148 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3149 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3150 gen_set_label(l2);
3151 }
3152 opn = "modu.g";
3153 break;
3154#if defined(TARGET_MIPS64)
3155 case OPC_DMULT_G_2E:
3156 case OPC_DMULT_G_2F:
3157 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3158 opn = "dmult.g";
3159 break;
3160 case OPC_DMULTU_G_2E:
3161 case OPC_DMULTU_G_2F:
3162 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3163 opn = "dmultu.g";
3164 break;
3165 case OPC_DDIV_G_2E:
3166 case OPC_DDIV_G_2F:
3167 {
3168 int l1 = gen_new_label();
3169 int l2 = gen_new_label();
3170 int l3 = gen_new_label();
3171 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3172 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3173 tcg_gen_br(l3);
3174 gen_set_label(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 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3178 tcg_gen_br(l3);
3179 gen_set_label(l2);
3180 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3181 gen_set_label(l3);
3182 }
3183 opn = "ddiv.g";
3184 break;
3185 case OPC_DDIVU_G_2E:
3186 case OPC_DDIVU_G_2F:
3187 {
3188 int l1 = gen_new_label();
3189 int l2 = gen_new_label();
3190 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3191 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3192 tcg_gen_br(l2);
3193 gen_set_label(l1);
3194 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3195 gen_set_label(l2);
3196 }
3197 opn = "ddivu.g";
3198 break;
3199 case OPC_DMOD_G_2E:
3200 case OPC_DMOD_G_2F:
3201 {
3202 int l1 = gen_new_label();
3203 int l2 = gen_new_label();
3204 int l3 = gen_new_label();
3205 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3206 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3207 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3208 gen_set_label(l1);
3209 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3210 tcg_gen_br(l3);
3211 gen_set_label(l2);
3212 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3213 gen_set_label(l3);
3214 }
3215 opn = "dmod.g";
3216 break;
3217 case OPC_DMODU_G_2E:
3218 case OPC_DMODU_G_2F:
3219 {
3220 int l1 = gen_new_label();
3221 int l2 = gen_new_label();
3222 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3223 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3224 tcg_gen_br(l2);
3225 gen_set_label(l1);
3226 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3227 gen_set_label(l2);
3228 }
3229 opn = "dmodu.g";
3230 break;
3231#endif
3232 }
3233
2abf314d 3234 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3235 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3236 tcg_temp_free(t0);
3237 tcg_temp_free(t1);
3238}
3239
bd277fa1
RH
3240/* Loongson multimedia instructions */
3241static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3242{
3243 const char *opn = "loongson_cp2";
3244 uint32_t opc, shift_max;
3245 TCGv_i64 t0, t1;
3246
3247 opc = MASK_LMI(ctx->opcode);
3248 switch (opc) {
3249 case OPC_ADD_CP2:
3250 case OPC_SUB_CP2:
3251 case OPC_DADD_CP2:
3252 case OPC_DSUB_CP2:
3253 t0 = tcg_temp_local_new_i64();
3254 t1 = tcg_temp_local_new_i64();
3255 break;
3256 default:
3257 t0 = tcg_temp_new_i64();
3258 t1 = tcg_temp_new_i64();
3259 break;
3260 }
3261
3262 gen_load_fpr64(ctx, t0, rs);
3263 gen_load_fpr64(ctx, t1, rt);
3264
3265#define LMI_HELPER(UP, LO) \
3266 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3267#define LMI_HELPER_1(UP, LO) \
3268 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3269#define LMI_DIRECT(UP, LO, OP) \
3270 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3271
3272 switch (opc) {
3273 LMI_HELPER(PADDSH, paddsh);
3274 LMI_HELPER(PADDUSH, paddush);
3275 LMI_HELPER(PADDH, paddh);
3276 LMI_HELPER(PADDW, paddw);
3277 LMI_HELPER(PADDSB, paddsb);
3278 LMI_HELPER(PADDUSB, paddusb);
3279 LMI_HELPER(PADDB, paddb);
3280
3281 LMI_HELPER(PSUBSH, psubsh);
3282 LMI_HELPER(PSUBUSH, psubush);
3283 LMI_HELPER(PSUBH, psubh);
3284 LMI_HELPER(PSUBW, psubw);
3285 LMI_HELPER(PSUBSB, psubsb);
3286 LMI_HELPER(PSUBUSB, psubusb);
3287 LMI_HELPER(PSUBB, psubb);
3288
3289 LMI_HELPER(PSHUFH, pshufh);
3290 LMI_HELPER(PACKSSWH, packsswh);
3291 LMI_HELPER(PACKSSHB, packsshb);
3292 LMI_HELPER(PACKUSHB, packushb);
3293
3294 LMI_HELPER(PUNPCKLHW, punpcklhw);
3295 LMI_HELPER(PUNPCKHHW, punpckhhw);
3296 LMI_HELPER(PUNPCKLBH, punpcklbh);
3297 LMI_HELPER(PUNPCKHBH, punpckhbh);
3298 LMI_HELPER(PUNPCKLWD, punpcklwd);
3299 LMI_HELPER(PUNPCKHWD, punpckhwd);
3300
3301 LMI_HELPER(PAVGH, pavgh);
3302 LMI_HELPER(PAVGB, pavgb);
3303 LMI_HELPER(PMAXSH, pmaxsh);
3304 LMI_HELPER(PMINSH, pminsh);
3305 LMI_HELPER(PMAXUB, pmaxub);
3306 LMI_HELPER(PMINUB, pminub);
3307
3308 LMI_HELPER(PCMPEQW, pcmpeqw);
3309 LMI_HELPER(PCMPGTW, pcmpgtw);
3310 LMI_HELPER(PCMPEQH, pcmpeqh);
3311 LMI_HELPER(PCMPGTH, pcmpgth);
3312 LMI_HELPER(PCMPEQB, pcmpeqb);
3313 LMI_HELPER(PCMPGTB, pcmpgtb);
3314
3315 LMI_HELPER(PSLLW, psllw);
3316 LMI_HELPER(PSLLH, psllh);
3317 LMI_HELPER(PSRLW, psrlw);
3318 LMI_HELPER(PSRLH, psrlh);
3319 LMI_HELPER(PSRAW, psraw);
3320 LMI_HELPER(PSRAH, psrah);
3321
3322 LMI_HELPER(PMULLH, pmullh);
3323 LMI_HELPER(PMULHH, pmulhh);
3324 LMI_HELPER(PMULHUH, pmulhuh);
3325 LMI_HELPER(PMADDHW, pmaddhw);
3326
3327 LMI_HELPER(PASUBUB, pasubub);
3328 LMI_HELPER_1(BIADD, biadd);
3329 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3330
3331 LMI_DIRECT(PADDD, paddd, add);
3332 LMI_DIRECT(PSUBD, psubd, sub);
3333 LMI_DIRECT(XOR_CP2, xor, xor);
3334 LMI_DIRECT(NOR_CP2, nor, nor);
3335 LMI_DIRECT(AND_CP2, and, and);
3336 LMI_DIRECT(PANDN, pandn, andc);
3337 LMI_DIRECT(OR, or, or);
3338
3339 case OPC_PINSRH_0:
3340 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3341 opn = "pinsrh_0";
3342 break;
3343 case OPC_PINSRH_1:
3344 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3345 opn = "pinsrh_1";
3346 break;
3347 case OPC_PINSRH_2:
3348 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3349 opn = "pinsrh_2";
3350 break;
3351 case OPC_PINSRH_3:
3352 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3353 opn = "pinsrh_3";
3354 break;
3355
3356 case OPC_PEXTRH:
3357 tcg_gen_andi_i64(t1, t1, 3);
3358 tcg_gen_shli_i64(t1, t1, 4);
3359 tcg_gen_shr_i64(t0, t0, t1);
3360 tcg_gen_ext16u_i64(t0, t0);
3361 opn = "pextrh";
3362 break;
3363
3364 case OPC_ADDU_CP2:
3365 tcg_gen_add_i64(t0, t0, t1);
3366 tcg_gen_ext32s_i64(t0, t0);
3367 opn = "addu";
3368 break;
3369 case OPC_SUBU_CP2:
3370 tcg_gen_sub_i64(t0, t0, t1);
3371 tcg_gen_ext32s_i64(t0, t0);
3372 opn = "addu";
3373 break;
3374
3375 case OPC_SLL_CP2:
3376 opn = "sll";
3377 shift_max = 32;
3378 goto do_shift;
3379 case OPC_SRL_CP2:
3380 opn = "srl";
3381 shift_max = 32;
3382 goto do_shift;
3383 case OPC_SRA_CP2:
3384 opn = "sra";
3385 shift_max = 32;
3386 goto do_shift;
3387 case OPC_DSLL_CP2:
3388 opn = "dsll";
3389 shift_max = 64;
3390 goto do_shift;
3391 case OPC_DSRL_CP2:
3392 opn = "dsrl";
3393 shift_max = 64;
3394 goto do_shift;
3395 case OPC_DSRA_CP2:
3396 opn = "dsra";
3397 shift_max = 64;
3398 goto do_shift;
3399 do_shift:
3400 /* Make sure shift count isn't TCG undefined behaviour. */
3401 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3402
3403 switch (opc) {
3404 case OPC_SLL_CP2:
3405 case OPC_DSLL_CP2:
3406 tcg_gen_shl_i64(t0, t0, t1);
3407 break;
3408 case OPC_SRA_CP2:
3409 case OPC_DSRA_CP2:
3410 /* Since SRA is UndefinedResult without sign-extended inputs,
3411 we can treat SRA and DSRA the same. */
3412 tcg_gen_sar_i64(t0, t0, t1);
3413 break;
3414 case OPC_SRL_CP2:
3415 /* We want to shift in zeros for SRL; zero-extend first. */
3416 tcg_gen_ext32u_i64(t0, t0);
3417 /* FALLTHRU */
3418 case OPC_DSRL_CP2:
3419 tcg_gen_shr_i64(t0, t0, t1);
3420 break;
3421 }
3422
3423 if (shift_max == 32) {
3424 tcg_gen_ext32s_i64(t0, t0);
3425 }
3426
3427 /* Shifts larger than MAX produce zero. */
3428 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3429 tcg_gen_neg_i64(t1, t1);
3430 tcg_gen_and_i64(t0, t0, t1);
3431 break;
3432
3433 case OPC_ADD_CP2:
3434 case OPC_DADD_CP2:
3435 {
3436 TCGv_i64 t2 = tcg_temp_new_i64();
3437 int lab = gen_new_label();
3438
3439 tcg_gen_mov_i64(t2, t0);
3440 tcg_gen_add_i64(t0, t1, t2);
3441 if (opc == OPC_ADD_CP2) {
3442 tcg_gen_ext32s_i64(t0, t0);
3443 }
3444 tcg_gen_xor_i64(t1, t1, t2);
3445 tcg_gen_xor_i64(t2, t2, t0);
3446 tcg_gen_andc_i64(t1, t2, t1);
3447 tcg_temp_free_i64(t2);
3448 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3449 generate_exception(ctx, EXCP_OVERFLOW);
3450 gen_set_label(lab);
3451
3452 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3453 break;
3454 }
3455
3456 case OPC_SUB_CP2:
3457 case OPC_DSUB_CP2:
3458 {
3459 TCGv_i64 t2 = tcg_temp_new_i64();
3460 int lab = gen_new_label();
3461
3462 tcg_gen_mov_i64(t2, t0);
3463 tcg_gen_sub_i64(t0, t1, t2);
3464 if (opc == OPC_SUB_CP2) {
3465 tcg_gen_ext32s_i64(t0, t0);
3466 }
3467 tcg_gen_xor_i64(t1, t1, t2);
3468 tcg_gen_xor_i64(t2, t2, t0);
3469 tcg_gen_and_i64(t1, t1, t2);
3470 tcg_temp_free_i64(t2);
3471 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3472 generate_exception(ctx, EXCP_OVERFLOW);
3473 gen_set_label(lab);
3474
3475 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3476 break;
3477 }
3478
3479 case OPC_PMULUW:
3480 tcg_gen_ext32u_i64(t0, t0);
3481 tcg_gen_ext32u_i64(t1, t1);
3482 tcg_gen_mul_i64(t0, t0, t1);
3483 opn = "pmuluw";
3484 break;
3485
3486 case OPC_SEQU_CP2:
3487 case OPC_SEQ_CP2:
3488 case OPC_SLTU_CP2:
3489 case OPC_SLT_CP2:
3490 case OPC_SLEU_CP2:
3491 case OPC_SLE_CP2:
3492 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3493 FD field is the CC field? */
3494 default:
3495 MIPS_INVAL(opn);
3496 generate_exception(ctx, EXCP_RI);
3497 return;
3498 }
3499
3500#undef LMI_HELPER
3501#undef LMI_DIRECT
3502
3503 gen_store_fpr64(ctx, t0, rd);
3504
3505 (void)opn; /* avoid a compiler warning */
3506 MIPS_DEBUG("%s %s, %s, %s", opn,
3507 fregnames[rd], fregnames[rs], fregnames[rt]);
3508 tcg_temp_free_i64(t0);
3509 tcg_temp_free_i64(t1);
3510}
3511
6af0bf9c 3512/* Traps */
7a387fff 3513static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3514 int rs, int rt, int16_t imm)
3515{
3516 int cond;
cdc0faa6 3517 TCGv t0 = tcg_temp_new();
1ba74fb8 3518 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3519
3520 cond = 0;
3521 /* Load needed operands */
3522 switch (opc) {
3523 case OPC_TEQ:
3524 case OPC_TGE:
3525 case OPC_TGEU:
3526 case OPC_TLT:
3527 case OPC_TLTU:
3528 case OPC_TNE:
3529 /* Compare two registers */
3530 if (rs != rt) {
be24bb4f
TS
3531 gen_load_gpr(t0, rs);
3532 gen_load_gpr(t1, rt);
6af0bf9c
FB
3533 cond = 1;
3534 }
179e32bb 3535 break;
6af0bf9c
FB
3536 case OPC_TEQI:
3537 case OPC_TGEI:
3538 case OPC_TGEIU:
3539 case OPC_TLTI:
3540 case OPC_TLTIU:
3541 case OPC_TNEI:
3542 /* Compare register to immediate */
3543 if (rs != 0 || imm != 0) {
be24bb4f
TS
3544 gen_load_gpr(t0, rs);
3545 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3546 cond = 1;
3547 }
3548 break;
3549 }
3550 if (cond == 0) {
3551 switch (opc) {
3552 case OPC_TEQ: /* rs == rs */
3553 case OPC_TEQI: /* r0 == 0 */
3554 case OPC_TGE: /* rs >= rs */
3555 case OPC_TGEI: /* r0 >= 0 */
3556 case OPC_TGEU: /* rs >= rs unsigned */
3557 case OPC_TGEIU: /* r0 >= 0 unsigned */
3558 /* Always trap */
cdc0faa6 3559 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3560 break;
3561 case OPC_TLT: /* rs < rs */
3562 case OPC_TLTI: /* r0 < 0 */
3563 case OPC_TLTU: /* rs < rs unsigned */
3564 case OPC_TLTIU: /* r0 < 0 unsigned */
3565 case OPC_TNE: /* rs != rs */
3566 case OPC_TNEI: /* r0 != 0 */
ead9360e 3567 /* Never trap: treat as NOP. */
cdc0faa6 3568 break;
6af0bf9c
FB
3569 }
3570 } else {
cdc0faa6
AJ
3571 int l1 = gen_new_label();
3572
6af0bf9c
FB
3573 switch (opc) {
3574 case OPC_TEQ:
3575 case OPC_TEQI:
cdc0faa6 3576 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3577 break;
3578 case OPC_TGE:
3579 case OPC_TGEI:
cdc0faa6 3580 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3581 break;
3582 case OPC_TGEU:
3583 case OPC_TGEIU:
cdc0faa6 3584 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3585 break;
3586 case OPC_TLT:
3587 case OPC_TLTI:
cdc0faa6 3588 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3589 break;
3590 case OPC_TLTU:
3591 case OPC_TLTIU:
cdc0faa6 3592 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3593 break;
3594 case OPC_TNE:
3595 case OPC_TNEI:
cdc0faa6 3596 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3597 break;
6af0bf9c 3598 }
cdc0faa6 3599 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3600 gen_set_label(l1);
3601 }
be24bb4f
TS
3602 tcg_temp_free(t0);
3603 tcg_temp_free(t1);
6af0bf9c
FB
3604}
3605
356265ae 3606static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3607{
6e256c93
FB
3608 TranslationBlock *tb;
3609 tb = ctx->tb;
7b270ef2
NF
3610 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3611 likely(!ctx->singlestep_enabled)) {
57fec1fe 3612 tcg_gen_goto_tb(n);
9b9e4393 3613 gen_save_pc(dest);
4b4a72e5 3614 tcg_gen_exit_tb((tcg_target_long)tb + n);
6e256c93 3615 } else {
9b9e4393 3616 gen_save_pc(dest);
7b270ef2
NF
3617 if (ctx->singlestep_enabled) {
3618 save_cpu_state(ctx, 0);
895c2d04 3619 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3620 }
57fec1fe 3621 tcg_gen_exit_tb(0);
6e256c93 3622 }
c53be334
FB
3623}
3624
6af0bf9c 3625/* Branches (before delay slot) */
7a387fff 3626static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3627 int insn_bytes,
6af0bf9c
FB
3628 int rs, int rt, int32_t offset)
3629{
d077b6f7 3630 target_ulong btgt = -1;
3ad4bb2d 3631 int blink = 0;
2fdbad25 3632 int bcond_compute = 0;
1ba74fb8
AJ
3633 TCGv t0 = tcg_temp_new();
3634 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3635
3636 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3637#ifdef MIPS_DEBUG_DISAS
d12d51d5 3638 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3639#endif
3ad4bb2d 3640 generate_exception(ctx, EXCP_RI);
6c5c1e20 3641 goto out;
3ad4bb2d 3642 }
6af0bf9c 3643
6af0bf9c
FB
3644 /* Load needed operands */
3645 switch (opc) {
3646 case OPC_BEQ:
3647 case OPC_BEQL:
3648 case OPC_BNE:
3649 case OPC_BNEL:
3650 /* Compare two registers */
3651 if (rs != rt) {
6c5c1e20
TS
3652 gen_load_gpr(t0, rs);
3653 gen_load_gpr(t1, rt);
2fdbad25 3654 bcond_compute = 1;
6af0bf9c 3655 }
7dca4ad0 3656 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3657 break;
3658 case OPC_BGEZ:
3659 case OPC_BGEZAL:
3c824109 3660 case OPC_BGEZALS:
6af0bf9c
FB
3661 case OPC_BGEZALL:
3662 case OPC_BGEZL:
3663 case OPC_BGTZ:
3664 case OPC_BGTZL:
3665 case OPC_BLEZ:
3666 case OPC_BLEZL:
3667 case OPC_BLTZ:
3668 case OPC_BLTZAL:
3c824109 3669 case OPC_BLTZALS:
6af0bf9c
FB
3670 case OPC_BLTZALL:
3671 case OPC_BLTZL:
3672 /* Compare to zero */
3673 if (rs != 0) {
6c5c1e20 3674 gen_load_gpr(t0, rs);
2fdbad25 3675 bcond_compute = 1;
6af0bf9c 3676 }
7dca4ad0 3677 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3678 break;
e45a93e2
JL
3679 case OPC_BPOSGE32:
3680#if defined(TARGET_MIPS64)
3681 case OPC_BPOSGE64:
3682 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3683#else
3684 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3685#endif
3686 bcond_compute = 1;
3687 btgt = ctx->pc + insn_bytes + offset;
3688 break;
6af0bf9c
FB
3689 case OPC_J:
3690 case OPC_JAL:
364d4831 3691 case OPC_JALX:
620e48f6
NF
3692 case OPC_JALS:
3693 case OPC_JALXS:
6af0bf9c 3694 /* Jump to immediate */
7dca4ad0 3695 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3696 break;
3697 case OPC_JR:
3698 case OPC_JALR:
364d4831 3699 case OPC_JALRC:
620e48f6 3700 case OPC_JALRS:
6af0bf9c 3701 /* Jump to register */
7a387fff
TS
3702 if (offset != 0 && offset != 16) {
3703 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3704 others are reserved. */
923617a3 3705 MIPS_INVAL("jump hint");
6af0bf9c 3706 generate_exception(ctx, EXCP_RI);
6c5c1e20 3707 goto out;
6af0bf9c 3708 }
d077b6f7 3709 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3710 break;
3711 default:
3712 MIPS_INVAL("branch/jump");
3713 generate_exception(ctx, EXCP_RI);
6c5c1e20 3714 goto out;
6af0bf9c 3715 }
2fdbad25 3716 if (bcond_compute == 0) {
6af0bf9c
FB
3717 /* No condition to be computed */
3718 switch (opc) {
3719 case OPC_BEQ: /* rx == rx */
3720 case OPC_BEQL: /* rx == rx likely */
3721 case OPC_BGEZ: /* 0 >= 0 */
3722 case OPC_BGEZL: /* 0 >= 0 likely */
3723 case OPC_BLEZ: /* 0 <= 0 */
3724 case OPC_BLEZL: /* 0 <= 0 likely */
3725 /* Always take */
4ad40f36 3726 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3727 MIPS_DEBUG("balways");
3728 break;
3c824109 3729 case OPC_BGEZALS:
6af0bf9c
FB
3730 case OPC_BGEZAL: /* 0 >= 0 */
3731 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3732 ctx->hflags |= (opc == OPC_BGEZALS
3733 ? MIPS_HFLAG_BDS16
3734 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3735 /* Always take and link */
3736 blink = 31;
4ad40f36 3737 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3738 MIPS_DEBUG("balways and link");
3739 break;
3740 case OPC_BNE: /* rx != rx */
3741 case OPC_BGTZ: /* 0 > 0 */
3742 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3743 /* Treat as NOP. */
6af0bf9c 3744 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3745 goto out;
3c824109 3746 case OPC_BLTZALS:
eeef26cd 3747 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3748 ctx->hflags |= (opc == OPC_BLTZALS
3749 ? MIPS_HFLAG_BDS16
3750 : MIPS_HFLAG_BDS32);
3751 /* Handle as an unconditional branch to get correct delay
3752 slot checking. */
3753 blink = 31;
3754 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3755 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3756 MIPS_DEBUG("bnever and link");
3c824109 3757 break;
eeef26cd 3758 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3759 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3760 /* Skip the instruction in the delay slot */
3761 MIPS_DEBUG("bnever, link and skip");
3762 ctx->pc += 4;
6c5c1e20 3763 goto out;
6af0bf9c
FB
3764 case OPC_BNEL: /* rx != rx likely */
3765 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3766 case OPC_BLTZL: /* 0 < 0 likely */
3767 /* Skip the instruction in the delay slot */
3768 MIPS_DEBUG("bnever and skip");
9898128f 3769 ctx->pc += 4;
6c5c1e20 3770 goto out;
6af0bf9c 3771 case OPC_J:
4ad40f36 3772 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3773 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3774 break;
620e48f6 3775 case OPC_JALXS:
364d4831
NF
3776 case OPC_JALX:
3777 ctx->hflags |= MIPS_HFLAG_BX;
3778 /* Fallthrough */
620e48f6 3779 case OPC_JALS:
6af0bf9c
FB
3780 case OPC_JAL:
3781 blink = 31;
4ad40f36 3782 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3783 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3784 ? MIPS_HFLAG_BDS16
3785 : MIPS_HFLAG_BDS32);
d077b6f7 3786 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3787 break;
3788 case OPC_JR:
4ad40f36 3789 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3790 if (insn_bytes == 4)
3791 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3792 MIPS_DEBUG("jr %s", regnames[rs]);
3793 break;
620e48f6 3794 case OPC_JALRS:
6af0bf9c 3795 case OPC_JALR:
364d4831 3796 case OPC_JALRC:
6af0bf9c 3797 blink = rt;
4ad40f36 3798 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3799 ctx->hflags |= (opc == OPC_JALRS
3800 ? MIPS_HFLAG_BDS16
3801 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3802 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3803 break;
3804 default:
3805 MIPS_INVAL("branch/jump");
3806 generate_exception(ctx, EXCP_RI);
6c5c1e20 3807 goto out;
6af0bf9c
FB
3808 }
3809 } else {
3810 switch (opc) {
3811 case OPC_BEQ:
e68dd28f 3812 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3813 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3814 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3815 goto not_likely;
3816 case OPC_BEQL:
e68dd28f 3817 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3818 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3819 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3820 goto likely;
3821 case OPC_BNE:
e68dd28f 3822 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3823 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3824 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3825 goto not_likely;
3826 case OPC_BNEL:
e68dd28f 3827 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3828 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3829 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3830 goto likely;
3831 case OPC_BGEZ:
e68dd28f 3832 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3833 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3834 goto not_likely;
3835 case OPC_BGEZL:
e68dd28f 3836 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3837 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3838 goto likely;
3c824109 3839 case OPC_BGEZALS:
6af0bf9c 3840 case OPC_BGEZAL:
3c824109
NF
3841 ctx->hflags |= (opc == OPC_BGEZALS
3842 ? MIPS_HFLAG_BDS16
3843 : MIPS_HFLAG_BDS32);
e68dd28f 3844 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3845 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3846 blink = 31;
3847 goto not_likely;
3848 case OPC_BGEZALL:
e68dd28f 3849 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3850 blink = 31;
d077b6f7 3851 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3852 goto likely;
3853 case OPC_BGTZ:
e68dd28f 3854 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3855 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3856 goto not_likely;
3857 case OPC_BGTZL:
e68dd28f 3858 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3859 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3860 goto likely;
3861 case OPC_BLEZ:
e68dd28f 3862 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3863 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3864 goto not_likely;
3865 case OPC_BLEZL:
e68dd28f 3866 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3867 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3868 goto likely;
3869 case OPC_BLTZ:
e68dd28f 3870 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3871 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3872 goto not_likely;
3873 case OPC_BLTZL:
e68dd28f 3874 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3875 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3876 goto likely;
e45a93e2
JL
3877 case OPC_BPOSGE32:
3878 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3879 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3880 goto not_likely;
3881#if defined(TARGET_MIPS64)
3882 case OPC_BPOSGE64:
3883 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3884 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3885 goto not_likely;
3886#endif
3c824109 3887 case OPC_BLTZALS:
6af0bf9c 3888 case OPC_BLTZAL:
3c824109
NF
3889 ctx->hflags |= (opc == OPC_BLTZALS
3890 ? MIPS_HFLAG_BDS16
3891 : MIPS_HFLAG_BDS32);
e68dd28f 3892 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3893 blink = 31;
d077b6f7 3894 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3895 not_likely:
4ad40f36 3896 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3897 break;
3898 case OPC_BLTZALL:
e68dd28f 3899 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3900 blink = 31;
d077b6f7 3901 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3902 likely:
4ad40f36 3903 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3904 break;
c53f4a62
TS
3905 default:
3906 MIPS_INVAL("conditional branch/jump");
3907 generate_exception(ctx, EXCP_RI);
6c5c1e20 3908 goto out;
6af0bf9c 3909 }
6af0bf9c 3910 }
923617a3 3911 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3912 blink, ctx->hflags, btgt);
9b9e4393 3913
d077b6f7 3914 ctx->btarget = btgt;
6af0bf9c 3915 if (blink > 0) {
364d4831
NF
3916 int post_delay = insn_bytes;
3917 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3918
3919 if (opc != OPC_JALRC)
3920 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3921
3922 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3923 }
6c5c1e20
TS
3924
3925 out:
364d4831
NF
3926 if (insn_bytes == 2)
3927 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3928 tcg_temp_free(t0);
3929 tcg_temp_free(t1);
6af0bf9c
FB
3930}
3931
7a387fff
TS
3932/* special3 bitfield operations */
3933static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3934 int rs, int lsb, int msb)
7a387fff 3935{
a7812ae4
PB
3936 TCGv t0 = tcg_temp_new();
3937 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
3938
3939 gen_load_gpr(t1, rs);
7a387fff
TS
3940 switch (opc) {
3941 case OPC_EXT:
3942 if (lsb + msb > 31)
3943 goto fail;
505ad7c2
AJ
3944 tcg_gen_shri_tl(t0, t1, lsb);
3945 if (msb != 31) {
3946 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3947 } else {
3948 tcg_gen_ext32s_tl(t0, t0);
3949 }
7a387fff 3950 break;
c6d6dd7c 3951#if defined(TARGET_MIPS64)
7a387fff 3952 case OPC_DEXTM:
505ad7c2
AJ
3953 tcg_gen_shri_tl(t0, t1, lsb);
3954 if (msb != 31) {
3955 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3956 }
7a387fff
TS
3957 break;
3958 case OPC_DEXTU:
505ad7c2
AJ
3959 tcg_gen_shri_tl(t0, t1, lsb + 32);
3960 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3961 break;
3962 case OPC_DEXT:
505ad7c2
AJ
3963 tcg_gen_shri_tl(t0, t1, lsb);
3964 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3965 break;
c6d6dd7c 3966#endif
7a387fff
TS
3967 case OPC_INS:
3968 if (lsb > msb)
3969 goto fail;
6c5c1e20 3970 gen_load_gpr(t0, rt);
e0d002f1 3971 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 3972 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3973 break;
c6d6dd7c 3974#if defined(TARGET_MIPS64)
7a387fff 3975 case OPC_DINSM:
6c5c1e20 3976 gen_load_gpr(t0, rt);
e0d002f1 3977 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
3978 break;
3979 case OPC_DINSU:
6c5c1e20 3980 gen_load_gpr(t0, rt);
e0d002f1 3981 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
3982 break;
3983 case OPC_DINS:
6c5c1e20 3984 gen_load_gpr(t0, rt);
e0d002f1 3985 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 3986 break;
c6d6dd7c 3987#endif
7a387fff
TS
3988 default:
3989fail:
3990 MIPS_INVAL("bitops");
3991 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
3992 tcg_temp_free(t0);
3993 tcg_temp_free(t1);
7a387fff
TS
3994 return;
3995 }
6c5c1e20
TS
3996 gen_store_gpr(t0, rt);
3997 tcg_temp_free(t0);
3998 tcg_temp_free(t1);
7a387fff
TS
3999}
4000
49bcf33c
AJ
4001static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4002{
3a55fa47 4003 TCGv t0;
49bcf33c 4004
3a55fa47
AJ
4005 if (rd == 0) {
4006 /* If no destination, treat it as a NOP. */
4007 MIPS_DEBUG("NOP");
4008 return;
4009 }
4010
4011 t0 = tcg_temp_new();
4012 gen_load_gpr(t0, rt);
49bcf33c
AJ
4013 switch (op2) {
4014 case OPC_WSBH:
3a55fa47
AJ
4015 {
4016 TCGv t1 = tcg_temp_new();
4017
4018 tcg_gen_shri_tl(t1, t0, 8);
4019 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4020 tcg_gen_shli_tl(t0, t0, 8);
4021 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4022 tcg_gen_or_tl(t0, t0, t1);
4023 tcg_temp_free(t1);
4024 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4025 }
49bcf33c
AJ
4026 break;
4027 case OPC_SEB:
3a55fa47 4028 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4029 break;
4030 case OPC_SEH:
3a55fa47 4031 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4032 break;
4033#if defined(TARGET_MIPS64)
4034 case OPC_DSBH:
3a55fa47
AJ
4035 {
4036 TCGv t1 = tcg_temp_new();
4037
4038 tcg_gen_shri_tl(t1, t0, 8);
4039 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4040 tcg_gen_shli_tl(t0, t0, 8);
4041 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4042 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4043 tcg_temp_free(t1);
4044 }
49bcf33c
AJ
4045 break;
4046 case OPC_DSHD:
3a55fa47
AJ
4047 {
4048 TCGv t1 = tcg_temp_new();
4049
4050 tcg_gen_shri_tl(t1, t0, 16);
4051 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4052 tcg_gen_shli_tl(t0, t0, 16);
4053 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4054 tcg_gen_or_tl(t0, t0, t1);
4055 tcg_gen_shri_tl(t1, t0, 32);
4056 tcg_gen_shli_tl(t0, t0, 32);
4057 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4058 tcg_temp_free(t1);
4059 }
49bcf33c
AJ
4060 break;
4061#endif
4062 default:
4063 MIPS_INVAL("bsfhl");
4064 generate_exception(ctx, EXCP_RI);
4065 tcg_temp_free(t0);
49bcf33c
AJ
4066 return;
4067 }
49bcf33c 4068 tcg_temp_free(t0);
49bcf33c
AJ
4069}
4070
f1aa6320 4071#ifndef CONFIG_USER_ONLY
0eaef5aa 4072/* CP0 (MMU and control) */
d9bea114 4073static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4074{
d9bea114 4075 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4076
d9bea114
AJ
4077 tcg_gen_ld_i32(t0, cpu_env, off);
4078 tcg_gen_ext_i32_tl(arg, t0);
4079 tcg_temp_free_i32(t0);
4f57689a
TS
4080}
4081
d9bea114 4082static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4083{
d9bea114
AJ
4084 tcg_gen_ld_tl(arg, cpu_env, off);
4085 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4086}
4087
d9bea114 4088static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4089{
d9bea114 4090 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4091
d9bea114
AJ
4092 tcg_gen_trunc_tl_i32(t0, arg);
4093 tcg_gen_st_i32(t0, cpu_env, off);
4094 tcg_temp_free_i32(t0);
f1aa6320
TS
4095}
4096
d9bea114 4097static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4098{
d9bea114
AJ
4099 tcg_gen_ext32s_tl(arg, arg);
4100 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4101}
4102
d75c135e 4103static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4104{
7a387fff 4105 const char *rn = "invalid";
873eb012 4106
e189e748 4107 if (sel != 0)
d75c135e 4108 check_insn(ctx, ISA_MIPS32);
e189e748 4109
873eb012
TS
4110 switch (reg) {
4111 case 0:
7a387fff
TS
4112 switch (sel) {
4113 case 0:
7db13fae 4114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4115 rn = "Index";
4116 break;
4117 case 1:
d75c135e 4118 check_insn(ctx, ASE_MT);
895c2d04 4119 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4120 rn = "MVPControl";
ead9360e 4121 break;
7a387fff 4122 case 2:
d75c135e 4123 check_insn(ctx, ASE_MT);
895c2d04 4124 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4125 rn = "MVPConf0";
ead9360e 4126 break;
7a387fff 4127 case 3:
d75c135e 4128 check_insn(ctx, ASE_MT);
895c2d04 4129 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4130 rn = "MVPConf1";
ead9360e 4131 break;
7a387fff
TS
4132 default:
4133 goto die;
4134 }
873eb012
TS
4135 break;
4136 case 1:
7a387fff
TS
4137 switch (sel) {
4138 case 0:
895c2d04 4139 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4140 rn = "Random";
2423f660 4141 break;
7a387fff 4142 case 1:
d75c135e 4143 check_insn(ctx, ASE_MT);
7db13fae 4144 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4145 rn = "VPEControl";
ead9360e 4146 break;
7a387fff 4147 case 2:
d75c135e 4148 check_insn(ctx, ASE_MT);
7db13fae 4149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4150 rn = "VPEConf0";
ead9360e 4151 break;
7a387fff 4152 case 3:
d75c135e 4153 check_insn(ctx, ASE_MT);
7db13fae 4154 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4155 rn = "VPEConf1";
ead9360e 4156 break;
7a387fff 4157 case 4:
d75c135e 4158 check_insn(ctx, ASE_MT);
7db13fae 4159 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4160 rn = "YQMask";
ead9360e 4161 break;
7a387fff 4162 case 5:
d75c135e 4163 check_insn(ctx, ASE_MT);
7db13fae 4164 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4165 rn = "VPESchedule";
ead9360e 4166 break;
7a387fff 4167 case 6:
d75c135e 4168 check_insn(ctx, ASE_MT);
7db13fae 4169 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4170 rn = "VPEScheFBack";
ead9360e 4171 break;
7a387fff 4172 case 7:
d75c135e 4173 check_insn(ctx, ASE_MT);
7db13fae 4174 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4175 rn = "VPEOpt";
ead9360e 4176 break;
7a387fff
TS
4177 default:
4178 goto die;
4179 }
873eb012
TS
4180 break;
4181 case 2:
7a387fff
TS
4182 switch (sel) {
4183 case 0:
7db13fae 4184 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4185 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4186 rn = "EntryLo0";
4187 break;
7a387fff 4188 case 1:
d75c135e 4189 check_insn(ctx, ASE_MT);
895c2d04 4190 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4191 rn = "TCStatus";
ead9360e 4192 break;
7a387fff 4193 case 2:
d75c135e 4194 check_insn(ctx, ASE_MT);
895c2d04 4195 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4196 rn = "TCBind";
ead9360e 4197 break;
7a387fff 4198 case 3:
d75c135e 4199 check_insn(ctx, ASE_MT);
895c2d04 4200 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4201 rn = "TCRestart";
ead9360e 4202 break;
7a387fff 4203 case 4:
d75c135e 4204 check_insn(ctx, ASE_MT);
895c2d04 4205 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4206 rn = "TCHalt";
ead9360e 4207 break;
7a387fff 4208 case 5:
d75c135e 4209 check_insn(ctx, ASE_MT);
895c2d04 4210 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4211 rn = "TCContext";
ead9360e 4212 break;
7a387fff 4213 case 6:
d75c135e 4214 check_insn(ctx, ASE_MT);
895c2d04 4215 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4216 rn = "TCSchedule";
ead9360e 4217 break;
7a387fff 4218 case 7:
d75c135e 4219 check_insn(ctx, ASE_MT);
895c2d04 4220 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4221 rn = "TCScheFBack";
ead9360e 4222 break;
7a387fff
TS
4223 default:
4224 goto die;
4225 }
873eb012
TS
4226 break;
4227 case 3:
7a387fff
TS
4228 switch (sel) {
4229 case 0:
7db13fae 4230 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4231 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4232 rn = "EntryLo1";
4233 break;
7a387fff
TS
4234 default:
4235 goto die;
1579a72e 4236 }
873eb012
TS
4237 break;
4238 case 4:
7a387fff
TS
4239 switch (sel) {
4240 case 0:
7db13fae 4241 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4242 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4243 rn = "Context";
4244 break;
7a387fff 4245 case 1:
d9bea114 4246// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
4247 rn = "ContextConfig";
4248// break;
7a387fff
TS
4249 default:
4250 goto die;
1579a72e 4251 }
873eb012
TS
4252 break;
4253 case 5:
7a387fff
TS
4254 switch (sel) {
4255 case 0:
7db13fae 4256 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4257 rn = "PageMask";
4258 break;
7a387fff 4259 case 1:
d75c135e 4260 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4262 rn = "PageGrain";
4263 break;
7a387fff
TS
4264 default:
4265 goto die;
1579a72e 4266 }
873eb012
TS
4267 break;
4268 case 6:
7a387fff
TS
4269 switch (sel) {
4270 case 0:
7db13fae 4271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4272 rn = "Wired";
4273 break;
7a387fff 4274 case 1:
d75c135e 4275 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4277 rn = "SRSConf0";
ead9360e 4278 break;
7a387fff 4279 case 2:
d75c135e 4280 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4281 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4282 rn = "SRSConf1";
ead9360e 4283 break;
7a387fff 4284 case 3:
d75c135e 4285 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4287 rn = "SRSConf2";
ead9360e 4288 break;
7a387fff 4289 case 4:
d75c135e 4290 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4292 rn = "SRSConf3";
ead9360e 4293 break;
7a387fff 4294 case 5:
d75c135e 4295 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4297 rn = "SRSConf4";
ead9360e 4298 break;
7a387fff
TS
4299 default:
4300 goto die;
1579a72e 4301 }
873eb012 4302 break;
8c0fdd85 4303 case 7:
7a387fff
TS
4304 switch (sel) {
4305 case 0:
d75c135e 4306 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4308 rn = "HWREna";
4309 break;
7a387fff
TS
4310 default:
4311 goto die;
1579a72e 4312 }
8c0fdd85 4313 break;
873eb012 4314 case 8:
7a387fff
TS
4315 switch (sel) {
4316 case 0:
7db13fae 4317 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4318 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4319 rn = "BadVAddr";
2423f660 4320 break;
7a387fff
TS
4321 default:
4322 goto die;
4323 }
873eb012
TS
4324 break;
4325 case 9:
7a387fff
TS
4326 switch (sel) {
4327 case 0:
2e70f6ef
PB
4328 /* Mark as an IO operation because we read the time. */
4329 if (use_icount)
4330 gen_io_start();
895c2d04 4331 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4332 if (use_icount) {
4333 gen_io_end();
2e70f6ef 4334 }
55807224
EI
4335 /* Break the TB to be able to take timer interrupts immediately
4336 after reading count. */
4337 ctx->bstate = BS_STOP;
2423f660
TS
4338 rn = "Count";
4339 break;
4340 /* 6,7 are implementation dependent */
7a387fff
TS
4341 default:
4342 goto die;
2423f660 4343 }
873eb012
TS
4344 break;
4345 case 10:
7a387fff
TS
4346 switch (sel) {
4347 case 0:
7db13fae 4348 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4349 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4350 rn = "EntryHi";
4351 break;
7a387fff
TS
4352 default:
4353 goto die;
1579a72e 4354 }
873eb012
TS
4355 break;
4356 case 11:
7a387fff
TS
4357 switch (sel) {
4358 case 0:
7db13fae 4359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4360 rn = "Compare";
4361 break;
4362 /* 6,7 are implementation dependent */
7a387fff
TS
4363 default:
4364 goto die;
2423f660 4365 }
873eb012
TS
4366 break;
4367 case 12:
7a387fff
TS
4368 switch (sel) {
4369 case 0:
7db13fae 4370 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4371 rn = "Status";
4372 break;
7a387fff 4373 case 1:
d75c135e 4374 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4375 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4376 rn = "IntCtl";
4377 break;
7a387fff 4378 case 2:
d75c135e 4379 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4380 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4381 rn = "SRSCtl";
4382 break;
7a387fff 4383 case 3:
d75c135e 4384 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4385 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4386 rn = "SRSMap";
fd88b6ab 4387 break;
7a387fff
TS
4388 default:
4389 goto die;
4390 }
873eb012
TS
4391 break;
4392 case 13:
7a387fff
TS
4393 switch (sel) {
4394 case 0:
7db13fae 4395 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4396 rn = "Cause";
4397 break;
7a387fff
TS
4398 default:
4399 goto die;
4400 }
873eb012
TS
4401 break;
4402 case 14:
7a387fff
TS
4403 switch (sel) {
4404 case 0:
7db13fae 4405 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4406 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4407 rn = "EPC";
4408 break;
7a387fff
TS
4409 default:
4410 goto die;
1579a72e 4411 }
873eb012
TS
4412 break;
4413 case 15:
7a387fff
TS
4414 switch (sel) {
4415 case 0:
7db13fae 4416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4417 rn = "PRid";
4418 break;
7a387fff 4419 case 1:
d75c135e 4420 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4421 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4422 rn = "EBase";
4423 break;
7a387fff
TS
4424 default:
4425 goto die;
4426 }
873eb012
TS
4427 break;
4428 case 16:
4429 switch (sel) {
4430 case 0:
7db13fae 4431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4432 rn = "Config";
4433 break;
4434 case 1:
7db13fae 4435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4436 rn = "Config1";
4437 break;
7a387fff 4438 case 2:
7db13fae 4439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4440 rn = "Config2";
4441 break;
4442 case 3:
7db13fae 4443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4444 rn = "Config3";
4445 break;
e397ee33
TS
4446 /* 4,5 are reserved */
4447 /* 6,7 are implementation dependent */
4448 case 6:
7db13fae 4449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4450 rn = "Config6";
4451 break;
4452 case 7:
7db13fae 4453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4454 rn = "Config7";
4455 break;
873eb012 4456 default:
873eb012
TS
4457 goto die;
4458 }
4459 break;
4460 case 17:
7a387fff
TS
4461 switch (sel) {
4462 case 0:
895c2d04 4463 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4464 rn = "LLAddr";
4465 break;
7a387fff
TS
4466 default:
4467 goto die;
4468 }
873eb012
TS
4469 break;
4470 case 18:
7a387fff 4471 switch (sel) {
fd88b6ab 4472 case 0 ... 7:
895c2d04 4473 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4474 rn = "WatchLo";
4475 break;
7a387fff
TS
4476 default:
4477 goto die;
4478 }
873eb012
TS
4479 break;
4480 case 19:
7a387fff 4481 switch (sel) {
fd88b6ab 4482 case 0 ...7:
895c2d04 4483 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4484 rn = "WatchHi";
4485 break;
7a387fff
TS
4486 default:
4487 goto die;
4488 }
873eb012 4489 break;
8c0fdd85 4490 case 20:
7a387fff
TS
4491 switch (sel) {
4492 case 0:
d26bc211 4493#if defined(TARGET_MIPS64)
d75c135e 4494 check_insn(ctx, ISA_MIPS3);
7db13fae 4495 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4496 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4497 rn = "XContext";
4498 break;
703eaf37 4499#endif
7a387fff
TS
4500 default:
4501 goto die;
4502 }
8c0fdd85
TS
4503 break;
4504 case 21:
7a387fff
TS
4505 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4506 switch (sel) {
4507 case 0:
7db13fae 4508 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4509 rn = "Framemask";
4510 break;
7a387fff
TS
4511 default:
4512 goto die;
4513 }
8c0fdd85
TS
4514 break;
4515 case 22:
d9bea114 4516 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4517 rn = "'Diagnostic"; /* implementation dependent */
4518 break;
873eb012 4519 case 23:
7a387fff
TS
4520 switch (sel) {
4521 case 0:
895c2d04 4522 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4523 rn = "Debug";
4524 break;
7a387fff 4525 case 1:
d9bea114 4526// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4527 rn = "TraceControl";
4528// break;
7a387fff 4529 case 2:
d9bea114 4530// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4531 rn = "TraceControl2";
4532// break;
7a387fff 4533 case 3:
d9bea114 4534// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4535 rn = "UserTraceData";
4536// break;
7a387fff 4537 case 4:
d9bea114 4538// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4539 rn = "TraceBPC";
4540// break;
7a387fff
TS
4541 default:
4542 goto die;
4543 }
873eb012
TS
4544 break;
4545 case 24:
7a387fff
TS
4546 switch (sel) {
4547 case 0:
f0b3f3ae 4548 /* EJTAG support */
7db13fae 4549 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4550 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4551 rn = "DEPC";
4552 break;
7a387fff
TS
4553 default:
4554 goto die;
4555 }
873eb012 4556 break;
8c0fdd85 4557 case 25:
7a387fff
TS
4558 switch (sel) {
4559 case 0:
7db13fae 4560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4561 rn = "Performance0";
7a387fff
TS
4562 break;
4563 case 1:
d9bea114 4564// gen_helper_mfc0_performance1(arg);
2423f660
TS
4565 rn = "Performance1";
4566// break;
7a387fff 4567 case 2:
d9bea114 4568// gen_helper_mfc0_performance2(arg);
2423f660
TS
4569 rn = "Performance2";
4570// break;
7a387fff 4571 case 3:
d9bea114 4572// gen_helper_mfc0_performance3(arg);
2423f660
TS
4573 rn = "Performance3";
4574// break;
7a387fff 4575 case 4:
d9bea114 4576// gen_helper_mfc0_performance4(arg);
2423f660
TS
4577 rn = "Performance4";
4578// break;
7a387fff 4579 case 5:
d9bea114 4580// gen_helper_mfc0_performance5(arg);
2423f660
TS
4581 rn = "Performance5";
4582// break;
7a387fff 4583 case 6:
d9bea114 4584// gen_helper_mfc0_performance6(arg);
2423f660
TS
4585 rn = "Performance6";
4586// break;
7a387fff 4587 case 7:
d9bea114 4588// gen_helper_mfc0_performance7(arg);
2423f660
TS
4589 rn = "Performance7";
4590// break;
7a387fff
TS
4591 default:
4592 goto die;
4593 }
8c0fdd85
TS
4594 break;
4595 case 26:
d9bea114 4596 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4597 rn = "ECC";
4598 break;
8c0fdd85 4599 case 27:
7a387fff 4600 switch (sel) {
7a387fff 4601 case 0 ... 3:
d9bea114 4602 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4603 rn = "CacheErr";
4604 break;
7a387fff
TS
4605 default:
4606 goto die;
4607 }
8c0fdd85 4608 break;
873eb012
TS
4609 case 28:
4610 switch (sel) {
4611 case 0:
7a387fff
TS
4612 case 2:
4613 case 4:
4614 case 6:
7db13fae 4615 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4616 rn = "TagLo";
4617 break;
4618 case 1:
7a387fff
TS
4619 case 3:
4620 case 5:
4621 case 7:
7db13fae 4622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4623 rn = "DataLo";
4624 break;
4625 default:
873eb012
TS
4626 goto die;
4627 }
4628 break;
8c0fdd85 4629 case 29:
7a387fff
TS
4630 switch (sel) {
4631 case 0:
4632 case 2:
4633 case 4:
4634 case 6:
7db13fae 4635 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4636 rn = "TagHi";
4637 break;
4638 case 1:
4639 case 3:
4640 case 5:
4641 case 7:
7db13fae 4642 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4643 rn = "DataHi";
4644 break;
4645 default:
4646 goto die;
4647 }
8c0fdd85 4648 break;
873eb012 4649 case 30:
7a387fff
TS
4650 switch (sel) {
4651 case 0:
7db13fae 4652 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4653 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4654 rn = "ErrorEPC";
4655 break;
7a387fff
TS
4656 default:
4657 goto die;
4658 }
873eb012
TS
4659 break;
4660 case 31:
7a387fff
TS
4661 switch (sel) {
4662 case 0:
f0b3f3ae 4663 /* EJTAG support */
7db13fae 4664 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4665 rn = "DESAVE";
4666 break;
7a387fff
TS
4667 default:
4668 goto die;
4669 }
873eb012
TS
4670 break;
4671 default:
873eb012
TS
4672 goto die;
4673 }
2abf314d 4674 (void)rn; /* avoid a compiler warning */
d12d51d5 4675 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4676 return;
4677
4678die:
d12d51d5 4679 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4680 generate_exception(ctx, EXCP_RI);
4681}
4682
d75c135e 4683static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4684{
7a387fff
TS
4685 const char *rn = "invalid";
4686
e189e748 4687 if (sel != 0)
d75c135e 4688 check_insn(ctx, ISA_MIPS32);
e189e748 4689
2e70f6ef
PB
4690 if (use_icount)
4691 gen_io_start();
4692
8c0fdd85
TS
4693 switch (reg) {
4694 case 0:
7a387fff
TS
4695 switch (sel) {
4696 case 0:
895c2d04 4697 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4698 rn = "Index";
4699 break;
4700 case 1:
d75c135e 4701 check_insn(ctx, ASE_MT);
895c2d04 4702 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4703 rn = "MVPControl";
ead9360e 4704 break;
7a387fff 4705 case 2:
d75c135e 4706 check_insn(ctx, ASE_MT);
ead9360e 4707 /* ignored */
7a387fff 4708 rn = "MVPConf0";
ead9360e 4709 break;
7a387fff 4710 case 3:
d75c135e 4711 check_insn(ctx, ASE_MT);
ead9360e 4712 /* ignored */
7a387fff 4713 rn = "MVPConf1";
ead9360e 4714 break;
7a387fff
TS
4715 default:
4716 goto die;
4717 }
8c0fdd85
TS
4718 break;
4719 case 1:
7a387fff
TS
4720 switch (sel) {
4721 case 0:
2423f660 4722 /* ignored */
7a387fff 4723 rn = "Random";
2423f660 4724 break;
7a387fff 4725 case 1:
d75c135e 4726 check_insn(ctx, ASE_MT);
895c2d04 4727 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4728 rn = "VPEControl";
ead9360e 4729 break;
7a387fff 4730 case 2:
d75c135e 4731 check_insn(ctx, ASE_MT);
895c2d04 4732 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4733 rn = "VPEConf0";
ead9360e 4734 break;
7a387fff 4735 case 3:
d75c135e 4736 check_insn(ctx, ASE_MT);
895c2d04 4737 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4738 rn = "VPEConf1";
ead9360e 4739 break;
7a387fff 4740 case 4:
d75c135e 4741 check_insn(ctx, ASE_MT);
895c2d04 4742 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4743 rn = "YQMask";
ead9360e 4744 break;
7a387fff 4745 case 5:
d75c135e 4746 check_insn(ctx, ASE_MT);
7db13fae 4747 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4748 rn = "VPESchedule";
ead9360e 4749 break;
7a387fff 4750 case 6:
d75c135e 4751 check_insn(ctx, ASE_MT);
7db13fae 4752 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4753 rn = "VPEScheFBack";
ead9360e 4754 break;
7a387fff 4755 case 7:
d75c135e 4756 check_insn(ctx, ASE_MT);
895c2d04 4757 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4758 rn = "VPEOpt";
ead9360e 4759 break;
7a387fff
TS
4760 default:
4761 goto die;
4762 }
8c0fdd85
TS
4763 break;
4764 case 2:
7a387fff
TS
4765 switch (sel) {
4766 case 0:
895c2d04 4767 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4768 rn = "EntryLo0";
4769 break;
7a387fff 4770 case 1:
d75c135e 4771 check_insn(ctx, ASE_MT);
895c2d04 4772 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4773 rn = "TCStatus";
ead9360e 4774 break;
7a387fff 4775 case 2:
d75c135e 4776 check_insn(ctx, ASE_MT);
895c2d04 4777 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4778 rn = "TCBind";
ead9360e 4779 break;
7a387fff 4780 case 3:
d75c135e 4781 check_insn(ctx, ASE_MT);
895c2d04 4782 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4783 rn = "TCRestart";
ead9360e 4784 break;
7a387fff 4785 case 4:
d75c135e 4786 check_insn(ctx, ASE_MT);
895c2d04 4787 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4788 rn = "TCHalt";
ead9360e 4789 break;
7a387fff 4790 case 5:
d75c135e 4791 check_insn(ctx, ASE_MT);
895c2d04 4792 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4793 rn = "TCContext";
ead9360e 4794 break;
7a387fff 4795 case 6:
d75c135e 4796 check_insn(ctx, ASE_MT);
895c2d04 4797 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4798 rn = "TCSchedule";
ead9360e 4799 break;
7a387fff 4800 case 7:
d75c135e 4801 check_insn(ctx, ASE_MT);
895c2d04 4802 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4803 rn = "TCScheFBack";
ead9360e 4804 break;
7a387fff
TS
4805 default:
4806 goto die;
4807 }
8c0fdd85
TS
4808 break;
4809 case 3:
7a387fff
TS
4810 switch (sel) {
4811 case 0:
895c2d04 4812 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4813 rn = "EntryLo1";
4814 break;
7a387fff
TS
4815 default:
4816 goto die;
876d4b07 4817 }
8c0fdd85
TS
4818 break;
4819 case 4:
7a387fff
TS
4820 switch (sel) {
4821 case 0:
895c2d04 4822 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4823 rn = "Context";
4824 break;
7a387fff 4825 case 1:
895c2d04 4826// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
4827 rn = "ContextConfig";
4828// break;
7a387fff
TS
4829 default:
4830 goto die;
876d4b07 4831 }
8c0fdd85
TS
4832 break;
4833 case 5:
7a387fff
TS
4834 switch (sel) {
4835 case 0:
895c2d04 4836 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4837 rn = "PageMask";
4838 break;
7a387fff 4839 case 1:
d75c135e 4840 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4841 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4842 rn = "PageGrain";
4843 break;
7a387fff
TS
4844 default:
4845 goto die;
876d4b07 4846 }
8c0fdd85
TS
4847 break;
4848 case 6:
7a387fff
TS
4849 switch (sel) {
4850 case 0:
895c2d04 4851 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4852 rn = "Wired";
4853 break;
7a387fff 4854 case 1:
d75c135e 4855 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4856 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4857 rn = "SRSConf0";
ead9360e 4858 break;
7a387fff 4859 case 2:
d75c135e 4860 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4861 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4862 rn = "SRSConf1";
ead9360e 4863 break;
7a387fff 4864 case 3:
d75c135e 4865 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4866 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4867 rn = "SRSConf2";
ead9360e 4868 break;
7a387fff 4869 case 4:
d75c135e 4870 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4871 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4872 rn = "SRSConf3";
ead9360e 4873 break;
7a387fff 4874 case 5:
d75c135e 4875 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4876 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4877 rn = "SRSConf4";
ead9360e 4878 break;
7a387fff
TS
4879 default:
4880 goto die;
876d4b07 4881 }
8c0fdd85
TS
4882 break;
4883 case 7:
7a387fff
TS
4884 switch (sel) {
4885 case 0:
d75c135e 4886 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4887 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
4888 rn = "HWREna";
4889 break;
7a387fff
TS
4890 default:
4891 goto die;
876d4b07 4892 }
8c0fdd85
TS
4893 break;
4894 case 8:
7a387fff 4895 /* ignored */
f0b3f3ae 4896 rn = "BadVAddr";
8c0fdd85
TS
4897 break;
4898 case 9:
7a387fff
TS
4899 switch (sel) {
4900 case 0:
895c2d04 4901 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4902 rn = "Count";
4903 break;
876d4b07 4904 /* 6,7 are implementation dependent */
7a387fff
TS
4905 default:
4906 goto die;
876d4b07 4907 }
8c0fdd85
TS
4908 break;
4909 case 10:
7a387fff
TS
4910 switch (sel) {
4911 case 0:
895c2d04 4912 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4913 rn = "EntryHi";
4914 break;
7a387fff
TS
4915 default:
4916 goto die;
876d4b07 4917 }
8c0fdd85
TS
4918 break;
4919 case 11:
7a387fff
TS
4920 switch (sel) {
4921 case 0:
895c2d04 4922 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4923 rn = "Compare";
4924 break;
4925 /* 6,7 are implementation dependent */
7a387fff
TS
4926 default:
4927 goto die;
876d4b07 4928 }
8c0fdd85
TS
4929 break;
4930 case 12:
7a387fff
TS
4931 switch (sel) {
4932 case 0:
867abc7e 4933 save_cpu_state(ctx, 1);
895c2d04 4934 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4935 /* BS_STOP isn't good enough here, hflags may have changed. */
4936 gen_save_pc(ctx->pc + 4);
4937 ctx->bstate = BS_EXCP;
2423f660
TS
4938 rn = "Status";
4939 break;
7a387fff 4940 case 1:
d75c135e 4941 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4942 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4943 /* Stop translation as we may have switched the execution mode */
4944 ctx->bstate = BS_STOP;
2423f660
TS
4945 rn = "IntCtl";
4946 break;
7a387fff 4947 case 2:
d75c135e 4948 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4949 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4950 /* Stop translation as we may have switched the execution mode */
4951 ctx->bstate = BS_STOP;
2423f660
TS
4952 rn = "SRSCtl";
4953 break;
7a387fff 4954 case 3:
d75c135e 4955 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4956 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4957 /* Stop translation as we may have switched the execution mode */
4958 ctx->bstate = BS_STOP;
2423f660 4959 rn = "SRSMap";
fd88b6ab 4960 break;
7a387fff
TS
4961 default:
4962 goto die;
876d4b07 4963 }
8c0fdd85
TS
4964 break;
4965 case 13:
7a387fff
TS
4966 switch (sel) {
4967 case 0:
867abc7e 4968 save_cpu_state(ctx, 1);
895c2d04 4969 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4970 rn = "Cause";
4971 break;
7a387fff
TS
4972 default:
4973 goto die;
876d4b07 4974 }
8c0fdd85
TS
4975 break;
4976 case 14:
7a387fff
TS
4977 switch (sel) {
4978 case 0:
7db13fae 4979 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4980 rn = "EPC";
4981 break;
7a387fff
TS
4982 default:
4983 goto die;
876d4b07 4984 }
8c0fdd85
TS
4985 break;
4986 case 15:
7a387fff
TS
4987 switch (sel) {
4988 case 0:
2423f660
TS
4989 /* ignored */
4990 rn = "PRid";
4991 break;
7a387fff 4992 case 1:
d75c135e 4993 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4994 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
4995 rn = "EBase";
4996 break;
7a387fff
TS
4997 default:
4998 goto die;
1579a72e 4999 }
8c0fdd85
TS
5000 break;
5001 case 16:
5002 switch (sel) {
5003 case 0:
895c2d04 5004 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5005 rn = "Config";
2423f660
TS
5006 /* Stop translation as we may have switched the execution mode */
5007 ctx->bstate = BS_STOP;
7a387fff
TS
5008 break;
5009 case 1:
e397ee33 5010 /* ignored, read only */
7a387fff
TS
5011 rn = "Config1";
5012 break;
5013 case 2:
895c2d04 5014 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5015 rn = "Config2";
2423f660
TS
5016 /* Stop translation as we may have switched the execution mode */
5017 ctx->bstate = BS_STOP;
8c0fdd85 5018 break;
7a387fff 5019 case 3:
e397ee33 5020 /* ignored, read only */
7a387fff
TS
5021 rn = "Config3";
5022 break;
e397ee33
TS
5023 /* 4,5 are reserved */
5024 /* 6,7 are implementation dependent */
5025 case 6:
5026 /* ignored */
5027 rn = "Config6";
5028 break;
5029 case 7:
5030 /* ignored */
5031 rn = "Config7";
5032 break;
8c0fdd85
TS
5033 default:
5034 rn = "Invalid config selector";
5035 goto die;
5036 }
5037 break;
5038 case 17:
7a387fff
TS
5039 switch (sel) {
5040 case 0:
895c2d04 5041 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5042 rn = "LLAddr";
5043 break;
7a387fff
TS
5044 default:
5045 goto die;
5046 }
8c0fdd85
TS
5047 break;
5048 case 18:
7a387fff 5049 switch (sel) {
fd88b6ab 5050 case 0 ... 7:
895c2d04 5051 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5052 rn = "WatchLo";
5053 break;
7a387fff
TS
5054 default:
5055 goto die;
5056 }
8c0fdd85
TS
5057 break;
5058 case 19:
7a387fff 5059 switch (sel) {
fd88b6ab 5060 case 0 ... 7:
895c2d04 5061 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5062 rn = "WatchHi";
5063 break;
7a387fff
TS
5064 default:
5065 goto die;
5066 }
8c0fdd85
TS
5067 break;
5068 case 20:
7a387fff
TS
5069 switch (sel) {
5070 case 0:
d26bc211 5071#if defined(TARGET_MIPS64)
d75c135e 5072 check_insn(ctx, ISA_MIPS3);
895c2d04 5073 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5074 rn = "XContext";
5075 break;
703eaf37 5076#endif
7a387fff
TS
5077 default:
5078 goto die;
5079 }
8c0fdd85
TS
5080 break;
5081 case 21:
7a387fff
TS
5082 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5083 switch (sel) {
5084 case 0:
895c2d04 5085 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5086 rn = "Framemask";
5087 break;
7a387fff
TS
5088 default:
5089 goto die;
5090 }
5091 break;
8c0fdd85 5092 case 22:
7a387fff
TS
5093 /* ignored */
5094 rn = "Diagnostic"; /* implementation dependent */
2423f660 5095 break;
8c0fdd85 5096 case 23:
7a387fff
TS
5097 switch (sel) {
5098 case 0:
895c2d04 5099 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5100 /* BS_STOP isn't good enough here, hflags may have changed. */
5101 gen_save_pc(ctx->pc + 4);
5102 ctx->bstate = BS_EXCP;
2423f660
TS
5103 rn = "Debug";
5104 break;
7a387fff 5105 case 1:
895c2d04 5106// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5107 rn = "TraceControl";
8487327a
TS
5108 /* Stop translation as we may have switched the execution mode */
5109 ctx->bstate = BS_STOP;
2423f660 5110// break;
7a387fff 5111 case 2:
895c2d04 5112// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5113 rn = "TraceControl2";
8487327a
TS
5114 /* Stop translation as we may have switched the execution mode */
5115 ctx->bstate = BS_STOP;
2423f660 5116// break;
7a387fff 5117 case 3:
8487327a
TS
5118 /* Stop translation as we may have switched the execution mode */
5119 ctx->bstate = BS_STOP;
895c2d04 5120// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5121 rn = "UserTraceData";
8487327a
TS
5122 /* Stop translation as we may have switched the execution mode */
5123 ctx->bstate = BS_STOP;
2423f660 5124// break;
7a387fff 5125 case 4:
895c2d04 5126// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5127 /* Stop translation as we may have switched the execution mode */
5128 ctx->bstate = BS_STOP;
2423f660
TS
5129 rn = "TraceBPC";
5130// break;
7a387fff
TS
5131 default:
5132 goto die;
5133 }
8c0fdd85
TS
5134 break;
5135 case 24:
7a387fff
TS
5136 switch (sel) {
5137 case 0:
f1aa6320 5138 /* EJTAG support */
7db13fae 5139 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5140 rn = "DEPC";
5141 break;
7a387fff
TS
5142 default:
5143 goto die;
5144 }
8c0fdd85
TS
5145 break;
5146 case 25:
7a387fff
TS
5147 switch (sel) {
5148 case 0:
895c2d04 5149 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5150 rn = "Performance0";
5151 break;
7a387fff 5152 case 1:
d9bea114 5153// gen_helper_mtc0_performance1(arg);
2423f660
TS
5154 rn = "Performance1";
5155// break;
7a387fff 5156 case 2:
d9bea114 5157// gen_helper_mtc0_performance2(arg);
2423f660
TS
5158 rn = "Performance2";
5159// break;
7a387fff 5160 case 3:
d9bea114 5161// gen_helper_mtc0_performance3(arg);
2423f660
TS
5162 rn = "Performance3";
5163// break;
7a387fff 5164 case 4:
d9bea114 5165// gen_helper_mtc0_performance4(arg);
2423f660
TS
5166 rn = "Performance4";
5167// break;
7a387fff 5168 case 5:
d9bea114 5169// gen_helper_mtc0_performance5(arg);
2423f660
TS
5170 rn = "Performance5";
5171// break;
7a387fff 5172 case 6:
d9bea114 5173// gen_helper_mtc0_performance6(arg);
2423f660
TS
5174 rn = "Performance6";
5175// break;
7a387fff 5176 case 7:
d9bea114 5177// gen_helper_mtc0_performance7(arg);
2423f660
TS
5178 rn = "Performance7";
5179// break;
7a387fff
TS
5180 default:
5181 goto die;
5182 }
8c0fdd85
TS
5183 break;
5184 case 26:
2423f660 5185 /* ignored */
8c0fdd85 5186 rn = "ECC";
2423f660 5187 break;
8c0fdd85 5188 case 27:
7a387fff
TS
5189 switch (sel) {
5190 case 0 ... 3:
2423f660
TS
5191 /* ignored */
5192 rn = "CacheErr";
5193 break;
7a387fff
TS
5194 default:
5195 goto die;
5196 }
8c0fdd85
TS
5197 break;
5198 case 28:
5199 switch (sel) {
5200 case 0:
7a387fff
TS
5201 case 2:
5202 case 4:
5203 case 6:
895c2d04 5204 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5205 rn = "TagLo";
5206 break;
7a387fff
TS
5207 case 1:
5208 case 3:
5209 case 5:
5210 case 7:
895c2d04 5211 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5212 rn = "DataLo";
5213 break;
8c0fdd85 5214 default:
8c0fdd85
TS
5215 goto die;
5216 }
5217 break;
5218 case 29:
7a387fff
TS
5219 switch (sel) {
5220 case 0:
5221 case 2:
5222 case 4:
5223 case 6:
895c2d04 5224 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5225 rn = "TagHi";
5226 break;
5227 case 1:
5228 case 3:
5229 case 5:
5230 case 7:
895c2d04 5231 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5232 rn = "DataHi";
5233 break;
5234 default:
5235 rn = "invalid sel";
5236 goto die;
5237 }
8c0fdd85
TS
5238 break;
5239 case 30:
7a387fff
TS
5240 switch (sel) {
5241 case 0:
7db13fae 5242 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5243 rn = "ErrorEPC";
5244 break;
7a387fff
TS
5245 default:
5246 goto die;
5247 }
8c0fdd85
TS
5248 break;
5249 case 31:
7a387fff
TS
5250 switch (sel) {
5251 case 0:
f1aa6320 5252 /* EJTAG support */
7db13fae 5253 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5254 rn = "DESAVE";
5255 break;
7a387fff
TS
5256 default:
5257 goto die;
5258 }
2423f660
TS
5259 /* Stop translation as we may have switched the execution mode */
5260 ctx->bstate = BS_STOP;
8c0fdd85
TS
5261 break;
5262 default:
8c0fdd85
TS
5263 goto die;
5264 }
2abf314d 5265 (void)rn; /* avoid a compiler warning */
d12d51d5 5266 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5267 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5268 if (use_icount) {
5269 gen_io_end();
5270 ctx->bstate = BS_STOP;
5271 }
8c0fdd85
TS
5272 return;
5273
5274die:
d12d51d5 5275 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5276 generate_exception(ctx, EXCP_RI);
5277}
5278
d26bc211 5279#if defined(TARGET_MIPS64)
d75c135e 5280static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5281{
5282 const char *rn = "invalid";
5283
e189e748 5284 if (sel != 0)
d75c135e 5285 check_insn(ctx, ISA_MIPS64);
e189e748 5286
9c2149c8
TS
5287 switch (reg) {
5288 case 0:
5289 switch (sel) {
5290 case 0:
7db13fae 5291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5292 rn = "Index";
5293 break;
5294 case 1:
d75c135e 5295 check_insn(ctx, ASE_MT);
895c2d04 5296 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5297 rn = "MVPControl";
ead9360e 5298 break;
9c2149c8 5299 case 2:
d75c135e 5300 check_insn(ctx, ASE_MT);
895c2d04 5301 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5302 rn = "MVPConf0";
ead9360e 5303 break;
9c2149c8 5304 case 3:
d75c135e 5305 check_insn(ctx, ASE_MT);
895c2d04 5306 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5307 rn = "MVPConf1";
ead9360e 5308 break;
9c2149c8
TS
5309 default:
5310 goto die;
5311 }
5312 break;
5313 case 1:
5314 switch (sel) {
5315 case 0:
895c2d04 5316 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5317 rn = "Random";
2423f660 5318 break;
9c2149c8 5319 case 1:
d75c135e 5320 check_insn(ctx, ASE_MT);
7db13fae 5321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5322 rn = "VPEControl";
ead9360e 5323 break;
9c2149c8 5324 case 2:
d75c135e 5325 check_insn(ctx, ASE_MT);
7db13fae 5326 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5327 rn = "VPEConf0";
ead9360e 5328 break;
9c2149c8 5329 case 3:
d75c135e 5330 check_insn(ctx, ASE_MT);
7db13fae 5331 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5332 rn = "VPEConf1";
ead9360e 5333 break;
9c2149c8 5334 case 4:
d75c135e 5335 check_insn(ctx, ASE_MT);
7db13fae 5336 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5337 rn = "YQMask";
ead9360e 5338 break;
9c2149c8 5339 case 5:
d75c135e 5340 check_insn(ctx, ASE_MT);
7db13fae 5341 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5342 rn = "VPESchedule";
ead9360e 5343 break;
9c2149c8 5344 case 6:
d75c135e 5345 check_insn(ctx, ASE_MT);
7db13fae 5346 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5347 rn = "VPEScheFBack";
ead9360e 5348 break;
9c2149c8 5349 case 7:
d75c135e 5350 check_insn(ctx, ASE_MT);
7db13fae 5351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5352 rn = "VPEOpt";
ead9360e 5353 break;
9c2149c8
TS
5354 default:
5355 goto die;
5356 }
5357 break;
5358 case 2:
5359 switch (sel) {
5360 case 0:
7db13fae 5361 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5362 rn = "EntryLo0";
5363 break;
9c2149c8 5364 case 1:
d75c135e 5365 check_insn(ctx, ASE_MT);
895c2d04 5366 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5367 rn = "TCStatus";
ead9360e 5368 break;
9c2149c8 5369 case 2:
d75c135e 5370 check_insn(ctx, ASE_MT);
895c2d04 5371 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5372 rn = "TCBind";
ead9360e 5373 break;
9c2149c8 5374 case 3:
d75c135e 5375 check_insn(ctx, ASE_MT);
895c2d04 5376 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5377 rn = "TCRestart";
ead9360e 5378 break;
9c2149c8 5379 case 4:
d75c135e 5380 check_insn(ctx, ASE_MT);
895c2d04 5381 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5382 rn = "TCHalt";
ead9360e 5383 break;
9c2149c8 5384 case 5:
d75c135e 5385 check_insn(ctx, ASE_MT);
895c2d04 5386 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5387 rn = "TCContext";
ead9360e 5388 break;
9c2149c8 5389 case 6:
d75c135e 5390 check_insn(ctx, ASE_MT);
895c2d04 5391 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5392 rn = "TCSchedule";
ead9360e 5393 break;
9c2149c8 5394 case 7:
d75c135e 5395 check_insn(ctx, ASE_MT);
895c2d04 5396 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5397 rn = "TCScheFBack";
ead9360e 5398 break;
9c2149c8
TS
5399 default:
5400 goto die;
5401 }
5402 break;
5403 case 3:
5404 switch (sel) {
5405 case 0:
7db13fae 5406 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5407 rn = "EntryLo1";
5408 break;
9c2149c8
TS
5409 default:
5410 goto die;
1579a72e 5411 }
9c2149c8
TS
5412 break;
5413 case 4:
5414 switch (sel) {
5415 case 0:
7db13fae 5416 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5417 rn = "Context";
5418 break;
9c2149c8 5419 case 1:
d9bea114 5420// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
5421 rn = "ContextConfig";
5422// break;
9c2149c8
TS
5423 default:
5424 goto die;
876d4b07 5425 }
9c2149c8
TS
5426 break;
5427 case 5:
5428 switch (sel) {
5429 case 0:
7db13fae 5430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5431 rn = "PageMask";
5432 break;
9c2149c8 5433 case 1:
d75c135e 5434 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5436 rn = "PageGrain";
5437 break;
9c2149c8
TS
5438 default:
5439 goto die;
876d4b07 5440 }
9c2149c8
TS
5441 break;
5442 case 6:
5443 switch (sel) {
5444 case 0:
7db13fae 5445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5446 rn = "Wired";
5447 break;
9c2149c8 5448 case 1:
d75c135e 5449 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5451 rn = "SRSConf0";
ead9360e 5452 break;
9c2149c8 5453 case 2:
d75c135e 5454 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5455 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5456 rn = "SRSConf1";
ead9360e 5457 break;
9c2149c8 5458 case 3:
d75c135e 5459 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5461 rn = "SRSConf2";
ead9360e 5462 break;
9c2149c8 5463 case 4:
d75c135e 5464 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5466 rn = "SRSConf3";
ead9360e 5467 break;
9c2149c8 5468 case 5:
d75c135e 5469 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5471 rn = "SRSConf4";
ead9360e 5472 break;
9c2149c8
TS
5473 default:
5474 goto die;
876d4b07 5475 }
9c2149c8
TS
5476 break;
5477 case 7:
5478 switch (sel) {
5479 case 0:
d75c135e 5480 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5482 rn = "HWREna";
5483 break;
9c2149c8
TS
5484 default:
5485 goto die;
876d4b07 5486 }
9c2149c8
TS
5487 break;
5488 case 8:
5489 switch (sel) {
5490 case 0:
7db13fae 5491 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5492 rn = "BadVAddr";
2423f660 5493 break;
9c2149c8
TS
5494 default:
5495 goto die;
876d4b07 5496 }
9c2149c8
TS
5497 break;
5498 case 9:
5499 switch (sel) {
5500 case 0:
2e70f6ef
PB
5501 /* Mark as an IO operation because we read the time. */
5502 if (use_icount)
5503 gen_io_start();
895c2d04 5504 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5505 if (use_icount) {
5506 gen_io_end();
2e70f6ef 5507 }
55807224
EI
5508 /* Break the TB to be able to take timer interrupts immediately
5509 after reading count. */
5510 ctx->bstate = BS_STOP;
2423f660
TS
5511 rn = "Count";
5512 break;
5513 /* 6,7 are implementation dependent */
9c2149c8
TS
5514 default:
5515 goto die;
876d4b07 5516 }
9c2149c8
TS
5517 break;
5518 case 10:
5519 switch (sel) {
5520 case 0:
7db13fae 5521 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5522 rn = "EntryHi";
5523 break;
9c2149c8
TS
5524 default:
5525 goto die;
876d4b07 5526 }
9c2149c8
TS
5527 break;
5528 case 11:
5529 switch (sel) {
5530 case 0:
7db13fae 5531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5532 rn = "Compare";
5533 break;
876d4b07 5534 /* 6,7 are implementation dependent */
9c2149c8
TS
5535 default:
5536 goto die;
876d4b07 5537 }
9c2149c8
TS
5538 break;
5539 case 12:
5540 switch (sel) {
5541 case 0:
7db13fae 5542 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5543 rn = "Status";
5544 break;
9c2149c8 5545 case 1:
d75c135e 5546 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5548 rn = "IntCtl";
5549 break;
9c2149c8 5550 case 2:
d75c135e 5551 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5552 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5553 rn = "SRSCtl";
5554 break;
9c2149c8 5555 case 3:
d75c135e 5556 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5558 rn = "SRSMap";
5559 break;
9c2149c8
TS
5560 default:
5561 goto die;
876d4b07 5562 }
9c2149c8
TS
5563 break;
5564 case 13:
5565 switch (sel) {
5566 case 0:
7db13fae 5567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5568 rn = "Cause";
5569 break;
9c2149c8
TS
5570 default:
5571 goto die;
876d4b07 5572 }
9c2149c8
TS
5573 break;
5574 case 14:
5575 switch (sel) {
5576 case 0:
7db13fae 5577 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5578 rn = "EPC";
5579 break;
9c2149c8
TS
5580 default:
5581 goto die;
876d4b07 5582 }
9c2149c8
TS
5583 break;
5584 case 15:
5585 switch (sel) {
5586 case 0:
7db13fae 5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5588 rn = "PRid";
5589 break;
9c2149c8 5590 case 1:
d75c135e 5591 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5593 rn = "EBase";
5594 break;
9c2149c8
TS
5595 default:
5596 goto die;
876d4b07 5597 }
9c2149c8
TS
5598 break;
5599 case 16:
5600 switch (sel) {
5601 case 0:
7db13fae 5602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5603 rn = "Config";
5604 break;
5605 case 1:
7db13fae 5606 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5607 rn = "Config1";
5608 break;
5609 case 2:
7db13fae 5610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5611 rn = "Config2";
5612 break;
5613 case 3:
7db13fae 5614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5615 rn = "Config3";
5616 break;
5617 /* 6,7 are implementation dependent */
f0b3f3ae 5618 case 6:
7db13fae 5619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5620 rn = "Config6";
5621 break;
5622 case 7:
7db13fae 5623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5624 rn = "Config7";
5625 break;
9c2149c8
TS
5626 default:
5627 goto die;
5628 }
5629 break;
5630 case 17:
5631 switch (sel) {
5632 case 0:
895c2d04 5633 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5634 rn = "LLAddr";
5635 break;
9c2149c8
TS
5636 default:
5637 goto die;
5638 }
5639 break;
5640 case 18:
5641 switch (sel) {
fd88b6ab 5642 case 0 ... 7:
895c2d04 5643 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5644 rn = "WatchLo";
5645 break;
9c2149c8
TS
5646 default:
5647 goto die;
5648 }
5649 break;
5650 case 19:
5651 switch (sel) {
fd88b6ab 5652 case 0 ... 7:
895c2d04 5653 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5654 rn = "WatchHi";
5655 break;
9c2149c8
TS
5656 default:
5657 goto die;
5658 }
5659 break;
5660 case 20:
5661 switch (sel) {
5662 case 0:
d75c135e 5663 check_insn(ctx, ISA_MIPS3);
7db13fae 5664 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5665 rn = "XContext";
5666 break;
9c2149c8
TS
5667 default:
5668 goto die;
5669 }
5670 break;
5671 case 21:
5672 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5673 switch (sel) {
5674 case 0:
7db13fae 5675 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5676 rn = "Framemask";
5677 break;
9c2149c8
TS
5678 default:
5679 goto die;
5680 }
5681 break;
5682 case 22:
d9bea114 5683 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5684 rn = "'Diagnostic"; /* implementation dependent */
5685 break;
9c2149c8
TS
5686 case 23:
5687 switch (sel) {
5688 case 0:
895c2d04 5689 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5690 rn = "Debug";
5691 break;
9c2149c8 5692 case 1:
895c2d04 5693// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5694 rn = "TraceControl";
5695// break;
9c2149c8 5696 case 2:
895c2d04 5697// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5698 rn = "TraceControl2";
5699// break;
9c2149c8 5700 case 3:
895c2d04 5701// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5702 rn = "UserTraceData";
5703// break;
9c2149c8 5704 case 4:
895c2d04 5705// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5706 rn = "TraceBPC";
5707// break;
9c2149c8
TS
5708 default:
5709 goto die;
5710 }
5711 break;
5712 case 24:
5713 switch (sel) {
5714 case 0:
f0b3f3ae 5715 /* EJTAG support */
7db13fae 5716 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5717 rn = "DEPC";
5718 break;
9c2149c8
TS
5719 default:
5720 goto die;
5721 }
5722 break;
5723 case 25:
5724 switch (sel) {
5725 case 0:
7db13fae 5726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5727 rn = "Performance0";
9c2149c8
TS
5728 break;
5729 case 1:
d9bea114 5730// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5731 rn = "Performance1";
5732// break;
9c2149c8 5733 case 2:
d9bea114 5734// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5735 rn = "Performance2";
5736// break;
9c2149c8 5737 case 3:
d9bea114 5738// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5739 rn = "Performance3";
5740// break;
9c2149c8 5741 case 4:
d9bea114 5742// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5743 rn = "Performance4";
5744// break;
9c2149c8 5745 case 5:
d9bea114 5746// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5747 rn = "Performance5";
5748// break;
9c2149c8 5749 case 6:
d9bea114 5750// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5751 rn = "Performance6";
5752// break;
9c2149c8 5753 case 7:
d9bea114 5754// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5755 rn = "Performance7";
5756// break;
9c2149c8
TS
5757 default:
5758 goto die;
5759 }
5760 break;
5761 case 26:
d9bea114 5762 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5763 rn = "ECC";
5764 break;
9c2149c8
TS
5765 case 27:
5766 switch (sel) {
5767 /* ignored */
5768 case 0 ... 3:
d9bea114 5769 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5770 rn = "CacheErr";
5771 break;
9c2149c8
TS
5772 default:
5773 goto die;
5774 }
5775 break;
5776 case 28:
5777 switch (sel) {
5778 case 0:
5779 case 2:
5780 case 4:
5781 case 6:
7db13fae 5782 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5783 rn = "TagLo";
5784 break;
5785 case 1:
5786 case 3:
5787 case 5:
5788 case 7:
7db13fae 5789 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5790 rn = "DataLo";
5791 break;
5792 default:
5793 goto die;
5794 }
5795 break;
5796 case 29:
5797 switch (sel) {
5798 case 0:
5799 case 2:
5800 case 4:
5801 case 6:
7db13fae 5802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5803 rn = "TagHi";
5804 break;
5805 case 1:
5806 case 3:
5807 case 5:
5808 case 7:
7db13fae 5809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5810 rn = "DataHi";
5811 break;
5812 default:
5813 goto die;
5814 }
5815 break;
5816 case 30:
5817 switch (sel) {
5818 case 0:
7db13fae 5819 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5820 rn = "ErrorEPC";
5821 break;
9c2149c8
TS
5822 default:
5823 goto die;
5824 }
5825 break;
5826 case 31:
5827 switch (sel) {
5828 case 0:
f0b3f3ae 5829 /* EJTAG support */
7db13fae 5830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5831 rn = "DESAVE";
5832 break;
9c2149c8
TS
5833 default:
5834 goto die;
5835 }
5836 break;
5837 default:
876d4b07 5838 goto die;
9c2149c8 5839 }
2abf314d 5840 (void)rn; /* avoid a compiler warning */
d12d51d5 5841 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5842 return;
5843
5844die:
d12d51d5 5845 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5846 generate_exception(ctx, EXCP_RI);
5847}
5848
d75c135e 5849static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5850{
5851 const char *rn = "invalid";
5852
e189e748 5853 if (sel != 0)
d75c135e 5854 check_insn(ctx, ISA_MIPS64);
e189e748 5855
2e70f6ef
PB
5856 if (use_icount)
5857 gen_io_start();
5858
9c2149c8
TS
5859 switch (reg) {
5860 case 0:
5861 switch (sel) {
5862 case 0:
895c2d04 5863 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5864 rn = "Index";
5865 break;
5866 case 1:
d75c135e 5867 check_insn(ctx, ASE_MT);
895c2d04 5868 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5869 rn = "MVPControl";
ead9360e 5870 break;
9c2149c8 5871 case 2:
d75c135e 5872 check_insn(ctx, ASE_MT);
ead9360e 5873 /* ignored */
9c2149c8 5874 rn = "MVPConf0";
ead9360e 5875 break;
9c2149c8 5876 case 3:
d75c135e 5877 check_insn(ctx, ASE_MT);
ead9360e 5878 /* ignored */
9c2149c8 5879 rn = "MVPConf1";
ead9360e 5880 break;
9c2149c8
TS
5881 default:
5882 goto die;
5883 }
5884 break;
5885 case 1:
5886 switch (sel) {
5887 case 0:
2423f660 5888 /* ignored */
9c2149c8 5889 rn = "Random";
2423f660 5890 break;
9c2149c8 5891 case 1:
d75c135e 5892 check_insn(ctx, ASE_MT);
895c2d04 5893 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5894 rn = "VPEControl";
ead9360e 5895 break;
9c2149c8 5896 case 2:
d75c135e 5897 check_insn(ctx, ASE_MT);
895c2d04 5898 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5899 rn = "VPEConf0";
ead9360e 5900 break;
9c2149c8 5901 case 3:
d75c135e 5902 check_insn(ctx, ASE_MT);
895c2d04 5903 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5904 rn = "VPEConf1";
ead9360e 5905 break;
9c2149c8 5906 case 4:
d75c135e 5907 check_insn(ctx, ASE_MT);
895c2d04 5908 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5909 rn = "YQMask";
ead9360e 5910 break;
9c2149c8 5911 case 5:
d75c135e 5912 check_insn(ctx, ASE_MT);
7db13fae 5913 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5914 rn = "VPESchedule";
ead9360e 5915 break;
9c2149c8 5916 case 6:
d75c135e 5917 check_insn(ctx, ASE_MT);
7db13fae 5918 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5919 rn = "VPEScheFBack";
ead9360e 5920 break;
9c2149c8 5921 case 7:
d75c135e 5922 check_insn(ctx, ASE_MT);
895c2d04 5923 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5924 rn = "VPEOpt";
ead9360e 5925 break;
9c2149c8
TS
5926 default:
5927 goto die;
5928 }
5929 break;
5930 case 2:
5931 switch (sel) {
5932 case 0:
895c2d04 5933 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5934 rn = "EntryLo0";
5935 break;
9c2149c8 5936 case 1:
d75c135e 5937 check_insn(ctx, ASE_MT);
895c2d04 5938 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5939 rn = "TCStatus";
ead9360e 5940 break;
9c2149c8 5941 case 2:
d75c135e 5942 check_insn(ctx, ASE_MT);
895c2d04 5943 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5944 rn = "TCBind";
ead9360e 5945 break;
9c2149c8 5946 case 3:
d75c135e 5947 check_insn(ctx, ASE_MT);
895c2d04 5948 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5949 rn = "TCRestart";
ead9360e 5950 break;
9c2149c8 5951 case 4:
d75c135e 5952 check_insn(ctx, ASE_MT);
895c2d04 5953 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5954 rn = "TCHalt";
ead9360e 5955 break;
9c2149c8 5956 case 5:
d75c135e 5957 check_insn(ctx, ASE_MT);
895c2d04 5958 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5959 rn = "TCContext";
ead9360e 5960 break;
9c2149c8 5961 case 6:
d75c135e 5962 check_insn(ctx, ASE_MT);
895c2d04 5963 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5964 rn = "TCSchedule";
ead9360e 5965 break;
9c2149c8 5966 case 7:
d75c135e 5967 check_insn(ctx, ASE_MT);
895c2d04 5968 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5969 rn = "TCScheFBack";
ead9360e 5970 break;
9c2149c8
TS
5971 default:
5972 goto die;
5973 }
5974 break;
5975 case 3:
5976 switch (sel) {
5977 case 0:
895c2d04 5978 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5979 rn = "EntryLo1";
5980 break;
9c2149c8
TS
5981 default:
5982 goto die;
876d4b07 5983 }
9c2149c8
TS
5984 break;
5985 case 4:
5986 switch (sel) {
5987 case 0:
895c2d04 5988 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5989 rn = "Context";
5990 break;
9c2149c8 5991 case 1:
895c2d04 5992// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
5993 rn = "ContextConfig";
5994// break;
9c2149c8
TS
5995 default:
5996 goto die;
876d4b07 5997 }
9c2149c8
TS
5998 break;
5999 case 5:
6000 switch (sel) {
6001 case 0:
895c2d04 6002 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6003 rn = "PageMask";
6004 break;
9c2149c8 6005 case 1:
d75c135e 6006 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6007 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6008 rn = "PageGrain";
6009 break;
9c2149c8
TS
6010 default:
6011 goto die;
876d4b07 6012 }
9c2149c8
TS
6013 break;
6014 case 6:
6015 switch (sel) {
6016 case 0:
895c2d04 6017 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6018 rn = "Wired";
6019 break;
9c2149c8 6020 case 1:
d75c135e 6021 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6022 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6023 rn = "SRSConf0";
ead9360e 6024 break;
9c2149c8 6025 case 2:
d75c135e 6026 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6027 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6028 rn = "SRSConf1";
ead9360e 6029 break;
9c2149c8 6030 case 3:
d75c135e 6031 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6032 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6033 rn = "SRSConf2";
ead9360e 6034 break;
9c2149c8 6035 case 4:
d75c135e 6036 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6037 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6038 rn = "SRSConf3";
ead9360e 6039 break;
9c2149c8 6040 case 5:
d75c135e 6041 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6042 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6043 rn = "SRSConf4";
ead9360e 6044 break;
9c2149c8
TS
6045 default:
6046 goto die;
876d4b07 6047 }
9c2149c8
TS
6048 break;
6049 case 7:
6050 switch (sel) {
6051 case 0:
d75c135e 6052 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6053 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
6054 rn = "HWREna";
6055 break;
9c2149c8
TS
6056 default:
6057 goto die;
876d4b07 6058 }
9c2149c8
TS
6059 break;
6060 case 8:
6061 /* ignored */
f0b3f3ae 6062 rn = "BadVAddr";
9c2149c8
TS
6063 break;
6064 case 9:
6065 switch (sel) {
6066 case 0:
895c2d04 6067 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6068 rn = "Count";
6069 break;
876d4b07 6070 /* 6,7 are implementation dependent */
9c2149c8
TS
6071 default:
6072 goto die;
876d4b07
TS
6073 }
6074 /* Stop translation as we may have switched the execution mode */
6075 ctx->bstate = BS_STOP;
9c2149c8
TS
6076 break;
6077 case 10:
6078 switch (sel) {
6079 case 0:
895c2d04 6080 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6081 rn = "EntryHi";
6082 break;
9c2149c8
TS
6083 default:
6084 goto die;
876d4b07 6085 }
9c2149c8
TS
6086 break;
6087 case 11:
6088 switch (sel) {
6089 case 0:
895c2d04 6090 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6091 rn = "Compare";
6092 break;
876d4b07 6093 /* 6,7 are implementation dependent */
9c2149c8
TS
6094 default:
6095 goto die;
876d4b07 6096 }
de9a95f0
AJ
6097 /* Stop translation as we may have switched the execution mode */
6098 ctx->bstate = BS_STOP;
9c2149c8
TS
6099 break;
6100 case 12:
6101 switch (sel) {
6102 case 0:
867abc7e 6103 save_cpu_state(ctx, 1);
895c2d04 6104 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6105 /* BS_STOP isn't good enough here, hflags may have changed. */
6106 gen_save_pc(ctx->pc + 4);
6107 ctx->bstate = BS_EXCP;
2423f660
TS
6108 rn = "Status";
6109 break;
9c2149c8 6110 case 1:
d75c135e 6111 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6112 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6113 /* Stop translation as we may have switched the execution mode */
6114 ctx->bstate = BS_STOP;
2423f660
TS
6115 rn = "IntCtl";
6116 break;
9c2149c8 6117 case 2:
d75c135e 6118 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6119 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6120 /* Stop translation as we may have switched the execution mode */
6121 ctx->bstate = BS_STOP;
2423f660
TS
6122 rn = "SRSCtl";
6123 break;
9c2149c8 6124 case 3:
d75c135e 6125 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6126 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx->bstate = BS_STOP;
2423f660
TS
6129 rn = "SRSMap";
6130 break;
6131 default:
9c2149c8 6132 goto die;
876d4b07 6133 }
9c2149c8
TS
6134 break;
6135 case 13:
6136 switch (sel) {
6137 case 0:
867abc7e 6138 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6139 /* Mark as an IO operation because we may trigger a software
6140 interrupt. */
6141 if (use_icount) {
6142 gen_io_start();
6143 }
895c2d04 6144 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6145 if (use_icount) {
6146 gen_io_end();
6147 }
6148 /* Stop translation as we may have triggered an intetrupt */
6149 ctx->bstate = BS_STOP;
2423f660
TS
6150 rn = "Cause";
6151 break;
9c2149c8
TS
6152 default:
6153 goto die;
876d4b07 6154 }
9c2149c8
TS
6155 break;
6156 case 14:
6157 switch (sel) {
6158 case 0:
7db13fae 6159 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6160 rn = "EPC";
6161 break;
9c2149c8
TS
6162 default:
6163 goto die;
876d4b07 6164 }
9c2149c8
TS
6165 break;
6166 case 15:
6167 switch (sel) {
6168 case 0:
2423f660
TS
6169 /* ignored */
6170 rn = "PRid";
6171 break;
9c2149c8 6172 case 1:
d75c135e 6173 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6174 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6175 rn = "EBase";
6176 break;
9c2149c8
TS
6177 default:
6178 goto die;
876d4b07 6179 }
9c2149c8
TS
6180 break;
6181 case 16:
6182 switch (sel) {
6183 case 0:
895c2d04 6184 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6185 rn = "Config";
2423f660
TS
6186 /* Stop translation as we may have switched the execution mode */
6187 ctx->bstate = BS_STOP;
9c2149c8
TS
6188 break;
6189 case 1:
1fc7bf6e 6190 /* ignored, read only */
9c2149c8
TS
6191 rn = "Config1";
6192 break;
6193 case 2:
895c2d04 6194 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6195 rn = "Config2";
2423f660
TS
6196 /* Stop translation as we may have switched the execution mode */
6197 ctx->bstate = BS_STOP;
9c2149c8
TS
6198 break;
6199 case 3:
2423f660 6200 /* ignored */
9c2149c8
TS
6201 rn = "Config3";
6202 break;
6203 /* 6,7 are implementation dependent */
6204 default:
6205 rn = "Invalid config selector";
6206 goto die;
6207 }
9c2149c8
TS
6208 break;
6209 case 17:
6210 switch (sel) {
6211 case 0:
895c2d04 6212 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6213 rn = "LLAddr";
6214 break;
9c2149c8
TS
6215 default:
6216 goto die;
6217 }
6218 break;
6219 case 18:
6220 switch (sel) {
fd88b6ab 6221 case 0 ... 7:
895c2d04 6222 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6223 rn = "WatchLo";
6224 break;
9c2149c8
TS
6225 default:
6226 goto die;
6227 }
6228 break;
6229 case 19:
6230 switch (sel) {
fd88b6ab 6231 case 0 ... 7:
895c2d04 6232 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6233 rn = "WatchHi";
6234 break;
9c2149c8
TS
6235 default:
6236 goto die;
6237 }
6238 break;
6239 case 20:
6240 switch (sel) {
6241 case 0:
d75c135e 6242 check_insn(ctx, ISA_MIPS3);
895c2d04 6243 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6244 rn = "XContext";
6245 break;
9c2149c8
TS
6246 default:
6247 goto die;
6248 }
6249 break;
6250 case 21:
6251 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6252 switch (sel) {
6253 case 0:
895c2d04 6254 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6255 rn = "Framemask";
6256 break;
9c2149c8
TS
6257 default:
6258 goto die;
6259 }
6260 break;
6261 case 22:
6262 /* ignored */
6263 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6264 break;
9c2149c8
TS
6265 case 23:
6266 switch (sel) {
6267 case 0:
895c2d04 6268 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6269 /* BS_STOP isn't good enough here, hflags may have changed. */
6270 gen_save_pc(ctx->pc + 4);
6271 ctx->bstate = BS_EXCP;
2423f660
TS
6272 rn = "Debug";
6273 break;
9c2149c8 6274 case 1:
895c2d04 6275// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6276 /* Stop translation as we may have switched the execution mode */
6277 ctx->bstate = BS_STOP;
2423f660
TS
6278 rn = "TraceControl";
6279// break;
9c2149c8 6280 case 2:
895c2d04 6281// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6282 /* Stop translation as we may have switched the execution mode */
6283 ctx->bstate = BS_STOP;
2423f660
TS
6284 rn = "TraceControl2";
6285// break;
9c2149c8 6286 case 3:
895c2d04 6287// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6288 /* Stop translation as we may have switched the execution mode */
6289 ctx->bstate = BS_STOP;
2423f660
TS
6290 rn = "UserTraceData";
6291// break;
9c2149c8 6292 case 4:
895c2d04 6293// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6294 /* Stop translation as we may have switched the execution mode */
6295 ctx->bstate = BS_STOP;
2423f660
TS
6296 rn = "TraceBPC";
6297// break;
9c2149c8
TS
6298 default:
6299 goto die;
6300 }
9c2149c8
TS
6301 break;
6302 case 24:
6303 switch (sel) {
6304 case 0:
f1aa6320 6305 /* EJTAG support */
7db13fae 6306 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6307 rn = "DEPC";
6308 break;
9c2149c8
TS
6309 default:
6310 goto die;
6311 }
6312 break;
6313 case 25:
6314 switch (sel) {
6315 case 0:
895c2d04 6316 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6317 rn = "Performance0";
6318 break;
9c2149c8 6319 case 1:
895c2d04 6320// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6321 rn = "Performance1";
6322// break;
9c2149c8 6323 case 2:
895c2d04 6324// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6325 rn = "Performance2";
6326// break;
9c2149c8 6327 case 3:
895c2d04 6328// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6329 rn = "Performance3";
6330// break;
9c2149c8 6331 case 4:
895c2d04 6332// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6333 rn = "Performance4";
6334// break;
9c2149c8 6335 case 5:
895c2d04 6336// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6337 rn = "Performance5";
6338// break;
9c2149c8 6339 case 6:
895c2d04 6340// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6341 rn = "Performance6";
6342// break;
9c2149c8 6343 case 7:
895c2d04 6344// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6345 rn = "Performance7";
6346// break;
9c2149c8
TS
6347 default:
6348 goto die;
6349 }
876d4b07 6350 break;
9c2149c8 6351 case 26:
876d4b07 6352 /* ignored */
9c2149c8 6353 rn = "ECC";
876d4b07 6354 break;
9c2149c8
TS
6355 case 27:
6356 switch (sel) {
6357 case 0 ... 3:
2423f660
TS
6358 /* ignored */
6359 rn = "CacheErr";
6360 break;
9c2149c8
TS
6361 default:
6362 goto die;
6363 }
876d4b07 6364 break;
9c2149c8
TS
6365 case 28:
6366 switch (sel) {
6367 case 0:
6368 case 2:
6369 case 4:
6370 case 6:
895c2d04 6371 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6372 rn = "TagLo";
6373 break;
6374 case 1:
6375 case 3:
6376 case 5:
6377 case 7:
895c2d04 6378 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6379 rn = "DataLo";
6380 break;
6381 default:
6382 goto die;
6383 }
6384 break;
6385 case 29:
6386 switch (sel) {
6387 case 0:
6388 case 2:
6389 case 4:
6390 case 6:
895c2d04 6391 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6392 rn = "TagHi";
6393 break;
6394 case 1:
6395 case 3:
6396 case 5:
6397 case 7:
895c2d04 6398 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6399 rn = "DataHi";
6400 break;
6401 default:
6402 rn = "invalid sel";
6403 goto die;
6404 }
876d4b07 6405 break;
9c2149c8
TS
6406 case 30:
6407 switch (sel) {
6408 case 0:
7db13fae 6409 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6410 rn = "ErrorEPC";
6411 break;
9c2149c8
TS
6412 default:
6413 goto die;
6414 }
6415 break;
6416 case 31:
6417 switch (sel) {
6418 case 0:
f1aa6320 6419 /* EJTAG support */
7db13fae 6420 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6421 rn = "DESAVE";
6422 break;
9c2149c8
TS
6423 default:
6424 goto die;
6425 }
876d4b07
TS
6426 /* Stop translation as we may have switched the execution mode */
6427 ctx->bstate = BS_STOP;
9c2149c8
TS
6428 break;
6429 default:
876d4b07 6430 goto die;
9c2149c8 6431 }
2abf314d 6432 (void)rn; /* avoid a compiler warning */
d12d51d5 6433 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6434 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6435 if (use_icount) {
6436 gen_io_end();
6437 ctx->bstate = BS_STOP;
6438 }
9c2149c8
TS
6439 return;
6440
6441die:
d12d51d5 6442 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6443 generate_exception(ctx, EXCP_RI);
6444}
d26bc211 6445#endif /* TARGET_MIPS64 */
9c2149c8 6446
7db13fae 6447static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6448 int u, int sel, int h)
6449{
6450 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6451 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6452
6453 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6454 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6455 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6456 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6457 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6458 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6459 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6460 else if (u == 0) {
6461 switch (rt) {
5a25ce94
EI
6462 case 1:
6463 switch (sel) {
6464 case 1:
895c2d04 6465 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6466 break;
6467 case 2:
895c2d04 6468 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6469 break;
6470 default:
6471 goto die;
6472 break;
6473 }
6474 break;
ead9360e
TS
6475 case 2:
6476 switch (sel) {
6477 case 1:
895c2d04 6478 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6479 break;
6480 case 2:
895c2d04 6481 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6482 break;
6483 case 3:
895c2d04 6484 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6485 break;
6486 case 4:
895c2d04 6487 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6488 break;
6489 case 5:
895c2d04 6490 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6491 break;
6492 case 6:
895c2d04 6493 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6494 break;
6495 case 7:
895c2d04 6496 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6497 break;
6498 default:
d75c135e 6499 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6500 break;
6501 }
6502 break;
6503 case 10:
6504 switch (sel) {
6505 case 0:
895c2d04 6506 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6507 break;
6508 default:
d75c135e 6509 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6510 break;
6511 }
6512 case 12:
6513 switch (sel) {
6514 case 0:
895c2d04 6515 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6516 break;
6517 default:
d75c135e 6518 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6519 break;
6520 }
5a25ce94
EI
6521 case 13:
6522 switch (sel) {
6523 case 0:
895c2d04 6524 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6525 break;
6526 default:
6527 goto die;
6528 break;
6529 }
6530 break;
6531 case 14:
6532 switch (sel) {
6533 case 0:
895c2d04 6534 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6535 break;
6536 default:
6537 goto die;
6538 break;
6539 }
6540 break;
6541 case 15:
6542 switch (sel) {
6543 case 1:
895c2d04 6544 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6545 break;
6546 default:
6547 goto die;
6548 break;
6549 }
6550 break;
6551 case 16:
6552 switch (sel) {
6553 case 0 ... 7:
895c2d04 6554 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6555 break;
6556 default:
6557 goto die;
6558 break;
6559 }
6560 break;
ead9360e
TS
6561 case 23:
6562 switch (sel) {
6563 case 0:
895c2d04 6564 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6565 break;
6566 default:
d75c135e 6567 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6568 break;
6569 }
6570 break;
6571 default:
d75c135e 6572 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6573 }
6574 } else switch (sel) {
6575 /* GPR registers. */
6576 case 0:
895c2d04 6577 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6578 break;
6579 /* Auxiliary CPU registers */
6580 case 1:
6581 switch (rt) {
6582 case 0:
895c2d04 6583 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6584 break;
6585 case 1:
895c2d04 6586 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6587 break;
6588 case 2:
895c2d04 6589 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6590 break;
6591 case 4:
895c2d04 6592 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6593 break;
6594 case 5:
895c2d04 6595 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6596 break;
6597 case 6:
895c2d04 6598 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6599 break;
6600 case 8:
895c2d04 6601 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6602 break;
6603 case 9:
895c2d04 6604 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6605 break;
6606 case 10:
895c2d04 6607 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6608 break;
6609 case 12:
895c2d04 6610 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6611 break;
6612 case 13:
895c2d04 6613 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6614 break;
6615 case 14:
895c2d04 6616 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6617 break;
6618 case 16:
895c2d04 6619 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6620 break;
6621 default:
6622 goto die;
6623 }
6624 break;
6625 /* Floating point (COP1). */
6626 case 2:
6627 /* XXX: For now we support only a single FPU context. */
6628 if (h == 0) {
a7812ae4 6629 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6630
6631 gen_load_fpr32(fp0, rt);
6632 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6633 tcg_temp_free_i32(fp0);
ead9360e 6634 } else {
a7812ae4 6635 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6636
6637 gen_load_fpr32h(fp0, rt);
6638 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6639 tcg_temp_free_i32(fp0);
ead9360e
TS
6640 }
6641 break;
6642 case 3:
6643 /* XXX: For now we support only a single FPU context. */
895c2d04 6644 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6645 break;
6646 /* COP2: Not implemented. */
6647 case 4:
6648 case 5:
6649 /* fall through */
6650 default:
6651 goto die;
6652 }
d12d51d5 6653 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6654 gen_store_gpr(t0, rd);
6655 tcg_temp_free(t0);
ead9360e
TS
6656 return;
6657
6658die:
1a3fd9c3 6659 tcg_temp_free(t0);
d12d51d5 6660 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6661 generate_exception(ctx, EXCP_RI);
6662}
6663
7db13fae 6664static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6665 int u, int sel, int h)
6666{
6667 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6668 TCGv t0 = tcg_temp_local_new();
ead9360e 6669
1a3fd9c3 6670 gen_load_gpr(t0, rt);
ead9360e 6671 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6672 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6673 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6674 /* NOP */ ;
6675 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6676 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6677 /* NOP */ ;
6678 else if (u == 0) {
6679 switch (rd) {
5a25ce94
EI
6680 case 1:
6681 switch (sel) {
6682 case 1:
895c2d04 6683 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6684 break;
6685 case 2:
895c2d04 6686 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6687 break;
6688 default:
6689 goto die;
6690 break;
6691 }
6692 break;
ead9360e
TS
6693 case 2:
6694 switch (sel) {
6695 case 1:
895c2d04 6696 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6697 break;
6698 case 2:
895c2d04 6699 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6700 break;
6701 case 3:
895c2d04 6702 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6703 break;
6704 case 4:
895c2d04 6705 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6706 break;
6707 case 5:
895c2d04 6708 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6709 break;
6710 case 6:
895c2d04 6711 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6712 break;
6713 case 7:
895c2d04 6714 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6715 break;
6716 default:
d75c135e 6717 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6718 break;
6719 }
6720 break;
6721 case 10:
6722 switch (sel) {
6723 case 0:
895c2d04 6724 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6725 break;
6726 default:
d75c135e 6727 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6728 break;
6729 }
6730 case 12:
6731 switch (sel) {
6732 case 0:
895c2d04 6733 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6734 break;
6735 default:
d75c135e 6736 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6737 break;
6738 }
5a25ce94
EI
6739 case 13:
6740 switch (sel) {
6741 case 0:
895c2d04 6742 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6743 break;
6744 default:
6745 goto die;
6746 break;
6747 }
6748 break;
6749 case 15:
6750 switch (sel) {
6751 case 1:
895c2d04 6752 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6753 break;
6754 default:
6755 goto die;
6756 break;
6757 }
6758 break;
ead9360e
TS
6759 case 23:
6760 switch (sel) {
6761 case 0:
895c2d04 6762 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6763 break;
6764 default:
d75c135e 6765 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6766 break;
6767 }
6768 break;
6769 default:
d75c135e 6770 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6771 }
6772 } else switch (sel) {
6773 /* GPR registers. */
6774 case 0:
895c2d04 6775 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6776 break;
6777 /* Auxiliary CPU registers */
6778 case 1:
6779 switch (rd) {
6780 case 0:
895c2d04 6781 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6782 break;
6783 case 1:
895c2d04 6784 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6785 break;
6786 case 2:
895c2d04 6787 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6788 break;
6789 case 4:
895c2d04 6790 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6791 break;
6792 case 5:
895c2d04 6793 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6794 break;
6795 case 6:
895c2d04 6796 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6797 break;
6798 case 8:
895c2d04 6799 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6800 break;
6801 case 9:
895c2d04 6802 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6803 break;
6804 case 10:
895c2d04 6805 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6806 break;
6807 case 12:
895c2d04 6808 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6809 break;
6810 case 13:
895c2d04 6811 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6812 break;
6813 case 14:
895c2d04 6814 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6815 break;
6816 case 16:
895c2d04 6817 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6818 break;
6819 default:
6820 goto die;
6821 }
6822 break;
6823 /* Floating point (COP1). */
6824 case 2:
6825 /* XXX: For now we support only a single FPU context. */
6826 if (h == 0) {
a7812ae4 6827 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6828
6829 tcg_gen_trunc_tl_i32(fp0, t0);
6830 gen_store_fpr32(fp0, rd);
a7812ae4 6831 tcg_temp_free_i32(fp0);
ead9360e 6832 } else {
a7812ae4 6833 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6834
6835 tcg_gen_trunc_tl_i32(fp0, t0);
6836 gen_store_fpr32h(fp0, rd);
a7812ae4 6837 tcg_temp_free_i32(fp0);
ead9360e
TS
6838 }
6839 break;
6840 case 3:
6841 /* XXX: For now we support only a single FPU context. */
895c2d04 6842 gen_helper_0e1i(ctc1, t0, rd);
ead9360e
TS
6843 break;
6844 /* COP2: Not implemented. */
6845 case 4:
6846 case 5:
6847 /* fall through */
6848 default:
6849 goto die;
6850 }
d12d51d5 6851 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6852 tcg_temp_free(t0);
ead9360e
TS
6853 return;
6854
6855die:
1a3fd9c3 6856 tcg_temp_free(t0);
d12d51d5 6857 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6858 generate_exception(ctx, EXCP_RI);
6859}
6860
7db13fae 6861static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6862{
287c4b84 6863 const char *opn = "ldst";
6af0bf9c 6864
2e15497c 6865 check_cp0_enabled(ctx);
6af0bf9c
FB
6866 switch (opc) {
6867 case OPC_MFC0:
6868 if (rt == 0) {
ead9360e 6869 /* Treat as NOP. */
6af0bf9c
FB
6870 return;
6871 }
d75c135e 6872 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6873 opn = "mfc0";
6874 break;
6875 case OPC_MTC0:
1a3fd9c3 6876 {
1fc7bf6e 6877 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6878
6879 gen_load_gpr(t0, rt);
d75c135e 6880 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6881 tcg_temp_free(t0);
6882 }
6af0bf9c
FB
6883 opn = "mtc0";
6884 break;
d26bc211 6885#if defined(TARGET_MIPS64)
9c2149c8 6886 case OPC_DMFC0:
d75c135e 6887 check_insn(ctx, ISA_MIPS3);
9c2149c8 6888 if (rt == 0) {
ead9360e 6889 /* Treat as NOP. */
9c2149c8
TS
6890 return;
6891 }
d75c135e 6892 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6893 opn = "dmfc0";
6894 break;
6895 case OPC_DMTC0:
d75c135e 6896 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 6897 {
1fc7bf6e 6898 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6899
6900 gen_load_gpr(t0, rt);
d75c135e 6901 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6902 tcg_temp_free(t0);
6903 }
9c2149c8
TS
6904 opn = "dmtc0";
6905 break;
534ce69f 6906#endif
ead9360e 6907 case OPC_MFTR:
d75c135e 6908 check_insn(ctx, ASE_MT);
ead9360e
TS
6909 if (rd == 0) {
6910 /* Treat as NOP. */
6911 return;
6912 }
6c5c1e20 6913 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6914 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6915 opn = "mftr";
6916 break;
6917 case OPC_MTTR:
d75c135e 6918 check_insn(ctx, ASE_MT);
6c5c1e20 6919 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6920 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6921 opn = "mttr";
6922 break;
6af0bf9c 6923 case OPC_TLBWI:
6af0bf9c 6924 opn = "tlbwi";
c01fccd2 6925 if (!env->tlb->helper_tlbwi)
29929e34 6926 goto die;
895c2d04 6927 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6928 break;
6929 case OPC_TLBWR:
6af0bf9c 6930 opn = "tlbwr";
c01fccd2 6931 if (!env->tlb->helper_tlbwr)
29929e34 6932 goto die;
895c2d04 6933 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6934 break;
6935 case OPC_TLBP:
6af0bf9c 6936 opn = "tlbp";
c01fccd2 6937 if (!env->tlb->helper_tlbp)
29929e34 6938 goto die;
895c2d04 6939 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6940 break;
6941 case OPC_TLBR:
6af0bf9c 6942 opn = "tlbr";
c01fccd2 6943 if (!env->tlb->helper_tlbr)
29929e34 6944 goto die;
895c2d04 6945 gen_helper_tlbr(cpu_env);
6af0bf9c 6946 break;
6af0bf9c
FB
6947 case OPC_ERET:
6948 opn = "eret";
d75c135e 6949 check_insn(ctx, ISA_MIPS2);
895c2d04 6950 gen_helper_eret(cpu_env);
6af0bf9c
FB
6951 ctx->bstate = BS_EXCP;
6952 break;
6953 case OPC_DERET:
6954 opn = "deret";
d75c135e 6955 check_insn(ctx, ISA_MIPS32);
6af0bf9c 6956 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6957 MIPS_INVAL(opn);
6af0bf9c
FB
6958 generate_exception(ctx, EXCP_RI);
6959 } else {
895c2d04 6960 gen_helper_deret(cpu_env);
6af0bf9c
FB
6961 ctx->bstate = BS_EXCP;
6962 }
6963 break;
4ad40f36
FB
6964 case OPC_WAIT:
6965 opn = "wait";
d75c135e 6966 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6967 /* If we get an exception, we want to restart at next instruction */
6968 ctx->pc += 4;
6969 save_cpu_state(ctx, 1);
6970 ctx->pc -= 4;
895c2d04 6971 gen_helper_wait(cpu_env);
4ad40f36
FB
6972 ctx->bstate = BS_EXCP;
6973 break;
6af0bf9c 6974 default:
29929e34 6975 die:
923617a3 6976 MIPS_INVAL(opn);
6af0bf9c
FB
6977 generate_exception(ctx, EXCP_RI);
6978 return;
6979 }
2abf314d 6980 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
6981 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6982}
f1aa6320 6983#endif /* !CONFIG_USER_ONLY */
6af0bf9c 6984
6ea83fed 6985/* CP1 Branches (before delay slot) */
d75c135e
AJ
6986static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6987 int32_t cc, int32_t offset)
6ea83fed
FB
6988{
6989 target_ulong btarget;
923617a3 6990 const char *opn = "cp1 cond branch";
a7812ae4 6991 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 6992
e189e748 6993 if (cc != 0)
d75c135e 6994 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 6995
6ea83fed
FB
6996 btarget = ctx->pc + 4 + offset;
6997
7a387fff
TS
6998 switch (op) {
6999 case OPC_BC1F:
d94536f4
AJ
7000 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7001 tcg_gen_not_i32(t0, t0);
7002 tcg_gen_andi_i32(t0, t0, 1);
7003 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7004 opn = "bc1f";
6ea83fed 7005 goto not_likely;
7a387fff 7006 case OPC_BC1FL:
d94536f4
AJ
7007 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7008 tcg_gen_not_i32(t0, t0);
7009 tcg_gen_andi_i32(t0, t0, 1);
7010 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7011 opn = "bc1fl";
6ea83fed 7012 goto likely;
7a387fff 7013 case OPC_BC1T:
d94536f4
AJ
7014 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7015 tcg_gen_andi_i32(t0, t0, 1);
7016 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7017 opn = "bc1t";
5a5012ec 7018 goto not_likely;
7a387fff 7019 case OPC_BC1TL:
d94536f4
AJ
7020 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7021 tcg_gen_andi_i32(t0, t0, 1);
7022 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7023 opn = "bc1tl";
6ea83fed
FB
7024 likely:
7025 ctx->hflags |= MIPS_HFLAG_BL;
7026 break;
5a5012ec 7027 case OPC_BC1FANY2:
a16336e4 7028 {
d94536f4
AJ
7029 TCGv_i32 t1 = tcg_temp_new_i32();
7030 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7031 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7032 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7033 tcg_temp_free_i32(t1);
d94536f4
AJ
7034 tcg_gen_andi_i32(t0, t0, 1);
7035 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7036 }
fd4a04eb 7037 opn = "bc1any2f";
5a5012ec
TS
7038 goto not_likely;
7039 case OPC_BC1TANY2:
a16336e4 7040 {
d94536f4
AJ
7041 TCGv_i32 t1 = tcg_temp_new_i32();
7042 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7043 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7044 tcg_gen_or_i32(t0, t0, t1);
7045 tcg_temp_free_i32(t1);
7046 tcg_gen_andi_i32(t0, t0, 1);
7047 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7048 }
fd4a04eb 7049 opn = "bc1any2t";
5a5012ec
TS
7050 goto not_likely;
7051 case OPC_BC1FANY4:
a16336e4 7052 {
d94536f4
AJ
7053 TCGv_i32 t1 = tcg_temp_new_i32();
7054 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7055 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7056 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7057 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7058 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7060 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7061 tcg_temp_free_i32(t1);
d94536f4
AJ
7062 tcg_gen_andi_i32(t0, t0, 1);
7063 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7064 }
fd4a04eb 7065 opn = "bc1any4f";
5a5012ec
TS
7066 goto not_likely;
7067 case OPC_BC1TANY4:
a16336e4 7068 {
d94536f4
AJ
7069 TCGv_i32 t1 = tcg_temp_new_i32();
7070 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7071 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7072 tcg_gen_or_i32(t0, t0, t1);
7073 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7074 tcg_gen_or_i32(t0, t0, t1);
7075 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7076 tcg_gen_or_i32(t0, t0, t1);
7077 tcg_temp_free_i32(t1);
7078 tcg_gen_andi_i32(t0, t0, 1);
7079 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7080 }
fd4a04eb 7081 opn = "bc1any4t";
5a5012ec
TS
7082 not_likely:
7083 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7084 break;
7085 default:
923617a3 7086 MIPS_INVAL(opn);
e397ee33 7087 generate_exception (ctx, EXCP_RI);
6c5c1e20 7088 goto out;
6ea83fed 7089 }
2abf314d 7090 (void)opn; /* avoid a compiler warning */
923617a3 7091 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7092 ctx->hflags, btarget);
7093 ctx->btarget = btarget;
6c5c1e20
TS
7094
7095 out:
a7812ae4 7096 tcg_temp_free_i32(t0);
6ea83fed
FB
7097}
7098
6af0bf9c 7099/* Coprocessor 1 (FPU) */
5a5012ec 7100
5a5012ec
TS
7101#define FOP(func, fmt) (((fmt) << 21) | (func))
7102
bf4120ad
NF
7103enum fopcode {
7104 OPC_ADD_S = FOP(0, FMT_S),
7105 OPC_SUB_S = FOP(1, FMT_S),
7106 OPC_MUL_S = FOP(2, FMT_S),
7107 OPC_DIV_S = FOP(3, FMT_S),
7108 OPC_SQRT_S = FOP(4, FMT_S),
7109 OPC_ABS_S = FOP(5, FMT_S),
7110 OPC_MOV_S = FOP(6, FMT_S),
7111 OPC_NEG_S = FOP(7, FMT_S),
7112 OPC_ROUND_L_S = FOP(8, FMT_S),
7113 OPC_TRUNC_L_S = FOP(9, FMT_S),
7114 OPC_CEIL_L_S = FOP(10, FMT_S),
7115 OPC_FLOOR_L_S = FOP(11, FMT_S),
7116 OPC_ROUND_W_S = FOP(12, FMT_S),
7117 OPC_TRUNC_W_S = FOP(13, FMT_S),
7118 OPC_CEIL_W_S = FOP(14, FMT_S),
7119 OPC_FLOOR_W_S = FOP(15, FMT_S),
7120 OPC_MOVCF_S = FOP(17, FMT_S),
7121 OPC_MOVZ_S = FOP(18, FMT_S),
7122 OPC_MOVN_S = FOP(19, FMT_S),
7123 OPC_RECIP_S = FOP(21, FMT_S),
7124 OPC_RSQRT_S = FOP(22, FMT_S),
7125 OPC_RECIP2_S = FOP(28, FMT_S),
7126 OPC_RECIP1_S = FOP(29, FMT_S),
7127 OPC_RSQRT1_S = FOP(30, FMT_S),
7128 OPC_RSQRT2_S = FOP(31, FMT_S),
7129 OPC_CVT_D_S = FOP(33, FMT_S),
7130 OPC_CVT_W_S = FOP(36, FMT_S),
7131 OPC_CVT_L_S = FOP(37, FMT_S),
7132 OPC_CVT_PS_S = FOP(38, FMT_S),
7133 OPC_CMP_F_S = FOP (48, FMT_S),
7134 OPC_CMP_UN_S = FOP (49, FMT_S),
7135 OPC_CMP_EQ_S = FOP (50, FMT_S),
7136 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7137 OPC_CMP_OLT_S = FOP (52, FMT_S),
7138 OPC_CMP_ULT_S = FOP (53, FMT_S),
7139 OPC_CMP_OLE_S = FOP (54, FMT_S),
7140 OPC_CMP_ULE_S = FOP (55, FMT_S),
7141 OPC_CMP_SF_S = FOP (56, FMT_S),
7142 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7143 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7144 OPC_CMP_NGL_S = FOP (59, FMT_S),
7145 OPC_CMP_LT_S = FOP (60, FMT_S),
7146 OPC_CMP_NGE_S = FOP (61, FMT_S),
7147 OPC_CMP_LE_S = FOP (62, FMT_S),
7148 OPC_CMP_NGT_S = FOP (63, FMT_S),
7149
7150 OPC_ADD_D = FOP(0, FMT_D),
7151 OPC_SUB_D = FOP(1, FMT_D),
7152 OPC_MUL_D = FOP(2, FMT_D),
7153 OPC_DIV_D = FOP(3, FMT_D),
7154 OPC_SQRT_D = FOP(4, FMT_D),
7155 OPC_ABS_D = FOP(5, FMT_D),
7156 OPC_MOV_D = FOP(6, FMT_D),
7157 OPC_NEG_D = FOP(7, FMT_D),
7158 OPC_ROUND_L_D = FOP(8, FMT_D),
7159 OPC_TRUNC_L_D = FOP(9, FMT_D),
7160 OPC_CEIL_L_D = FOP(10, FMT_D),
7161 OPC_FLOOR_L_D = FOP(11, FMT_D),
7162 OPC_ROUND_W_D = FOP(12, FMT_D),
7163 OPC_TRUNC_W_D = FOP(13, FMT_D),
7164 OPC_CEIL_W_D = FOP(14, FMT_D),
7165 OPC_FLOOR_W_D = FOP(15, FMT_D),
7166 OPC_MOVCF_D = FOP(17, FMT_D),
7167 OPC_MOVZ_D = FOP(18, FMT_D),
7168 OPC_MOVN_D = FOP(19, FMT_D),
7169 OPC_RECIP_D = FOP(21, FMT_D),
7170 OPC_RSQRT_D = FOP(22, FMT_D),
7171 OPC_RECIP2_D = FOP(28, FMT_D),
7172 OPC_RECIP1_D = FOP(29, FMT_D),
7173 OPC_RSQRT1_D = FOP(30, FMT_D),
7174 OPC_RSQRT2_D = FOP(31, FMT_D),
7175 OPC_CVT_S_D = FOP(32, FMT_D),
7176 OPC_CVT_W_D = FOP(36, FMT_D),
7177 OPC_CVT_L_D = FOP(37, FMT_D),
7178 OPC_CMP_F_D = FOP (48, FMT_D),
7179 OPC_CMP_UN_D = FOP (49, FMT_D),
7180 OPC_CMP_EQ_D = FOP (50, FMT_D),
7181 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7182 OPC_CMP_OLT_D = FOP (52, FMT_D),
7183 OPC_CMP_ULT_D = FOP (53, FMT_D),
7184 OPC_CMP_OLE_D = FOP (54, FMT_D),
7185 OPC_CMP_ULE_D = FOP (55, FMT_D),
7186 OPC_CMP_SF_D = FOP (56, FMT_D),
7187 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7188 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7189 OPC_CMP_NGL_D = FOP (59, FMT_D),
7190 OPC_CMP_LT_D = FOP (60, FMT_D),
7191 OPC_CMP_NGE_D = FOP (61, FMT_D),
7192 OPC_CMP_LE_D = FOP (62, FMT_D),
7193 OPC_CMP_NGT_D = FOP (63, FMT_D),
7194
7195 OPC_CVT_S_W = FOP(32, FMT_W),
7196 OPC_CVT_D_W = FOP(33, FMT_W),
7197 OPC_CVT_S_L = FOP(32, FMT_L),
7198 OPC_CVT_D_L = FOP(33, FMT_L),
7199 OPC_CVT_PS_PW = FOP(38, FMT_W),
7200
7201 OPC_ADD_PS = FOP(0, FMT_PS),
7202 OPC_SUB_PS = FOP(1, FMT_PS),
7203 OPC_MUL_PS = FOP(2, FMT_PS),
7204 OPC_DIV_PS = FOP(3, FMT_PS),
7205 OPC_ABS_PS = FOP(5, FMT_PS),
7206 OPC_MOV_PS = FOP(6, FMT_PS),
7207 OPC_NEG_PS = FOP(7, FMT_PS),
7208 OPC_MOVCF_PS = FOP(17, FMT_PS),
7209 OPC_MOVZ_PS = FOP(18, FMT_PS),
7210 OPC_MOVN_PS = FOP(19, FMT_PS),
7211 OPC_ADDR_PS = FOP(24, FMT_PS),
7212 OPC_MULR_PS = FOP(26, FMT_PS),
7213 OPC_RECIP2_PS = FOP(28, FMT_PS),
7214 OPC_RECIP1_PS = FOP(29, FMT_PS),
7215 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7216 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7217
7218 OPC_CVT_S_PU = FOP(32, FMT_PS),
7219 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7220 OPC_CVT_S_PL = FOP(40, FMT_PS),
7221 OPC_PLL_PS = FOP(44, FMT_PS),
7222 OPC_PLU_PS = FOP(45, FMT_PS),
7223 OPC_PUL_PS = FOP(46, FMT_PS),
7224 OPC_PUU_PS = FOP(47, FMT_PS),
7225 OPC_CMP_F_PS = FOP (48, FMT_PS),
7226 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7227 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7228 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7229 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7230 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7231 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7232 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7233 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7234 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7235 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7236 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7237 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7238 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7239 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7240 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7241};
7242
7a387fff 7243static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7244{
923617a3 7245 const char *opn = "cp1 move";
72c3a3ee 7246 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7247
7248 switch (opc) {
7249 case OPC_MFC1:
b6d96bed 7250 {
a7812ae4 7251 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7252
7253 gen_load_fpr32(fp0, fs);
7254 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7255 tcg_temp_free_i32(fp0);
6958549d 7256 }
6c5c1e20 7257 gen_store_gpr(t0, rt);
6ea83fed
FB
7258 opn = "mfc1";
7259 break;
7260 case OPC_MTC1:
6c5c1e20 7261 gen_load_gpr(t0, rt);
b6d96bed 7262 {
a7812ae4 7263 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7264
7265 tcg_gen_trunc_tl_i32(fp0, t0);
7266 gen_store_fpr32(fp0, fs);
a7812ae4 7267 tcg_temp_free_i32(fp0);
6958549d 7268 }
6ea83fed
FB
7269 opn = "mtc1";
7270 break;
7271 case OPC_CFC1:
895c2d04 7272 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7273 gen_store_gpr(t0, rt);
6ea83fed
FB
7274 opn = "cfc1";
7275 break;
7276 case OPC_CTC1:
6c5c1e20 7277 gen_load_gpr(t0, rt);
895c2d04 7278 gen_helper_0e1i(ctc1, t0, fs);
6ea83fed
FB
7279 opn = "ctc1";
7280 break;
72c3a3ee 7281#if defined(TARGET_MIPS64)
9c2149c8 7282 case OPC_DMFC1:
72c3a3ee 7283 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7284 gen_store_gpr(t0, rt);
5a5012ec
TS
7285 opn = "dmfc1";
7286 break;
9c2149c8 7287 case OPC_DMTC1:
6c5c1e20 7288 gen_load_gpr(t0, rt);
72c3a3ee 7289 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7290 opn = "dmtc1";
7291 break;
72c3a3ee 7292#endif
5a5012ec 7293 case OPC_MFHC1:
b6d96bed 7294 {
a7812ae4 7295 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7296
7297 gen_load_fpr32h(fp0, fs);
7298 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7299 tcg_temp_free_i32(fp0);
6958549d 7300 }
6c5c1e20 7301 gen_store_gpr(t0, rt);
5a5012ec
TS
7302 opn = "mfhc1";
7303 break;
7304 case OPC_MTHC1:
6c5c1e20 7305 gen_load_gpr(t0, rt);
b6d96bed 7306 {
a7812ae4 7307 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7308
7309 tcg_gen_trunc_tl_i32(fp0, t0);
7310 gen_store_fpr32h(fp0, fs);
a7812ae4 7311 tcg_temp_free_i32(fp0);
6958549d 7312 }
5a5012ec
TS
7313 opn = "mthc1";
7314 break;
6ea83fed 7315 default:
923617a3 7316 MIPS_INVAL(opn);
e397ee33 7317 generate_exception (ctx, EXCP_RI);
6c5c1e20 7318 goto out;
6ea83fed 7319 }
2abf314d 7320 (void)opn; /* avoid a compiler warning */
6ea83fed 7321 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7322
7323 out:
7324 tcg_temp_free(t0);
6ea83fed
FB
7325}
7326
5a5012ec
TS
7327static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7328{
af58f9ca 7329 int l1;
e214b9bb 7330 TCGCond cond;
af58f9ca
AJ
7331 TCGv_i32 t0;
7332
7333 if (rd == 0) {
7334 /* Treat as NOP. */
7335 return;
7336 }
6ea83fed 7337
e214b9bb 7338 if (tf)
e214b9bb 7339 cond = TCG_COND_EQ;
27848470
TS
7340 else
7341 cond = TCG_COND_NE;
7342
af58f9ca
AJ
7343 l1 = gen_new_label();
7344 t0 = tcg_temp_new_i32();
fa31af0e 7345 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7346 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7347 tcg_temp_free_i32(t0);
af58f9ca
AJ
7348 if (rs == 0) {
7349 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7350 } else {
7351 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7352 }
e214b9bb 7353 gen_set_label(l1);
5a5012ec
TS
7354}
7355
b6d96bed 7356static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7357{
a16336e4 7358 int cond;
cbc37b28 7359 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7360 int l1 = gen_new_label();
7361
a16336e4
TS
7362 if (tf)
7363 cond = TCG_COND_EQ;
7364 else
7365 cond = TCG_COND_NE;
7366
fa31af0e 7367 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7368 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7369 gen_load_fpr32(t0, fs);
7370 gen_store_fpr32(t0, fd);
a16336e4 7371 gen_set_label(l1);
cbc37b28 7372 tcg_temp_free_i32(t0);
5a5012ec 7373}
a16336e4 7374
b6d96bed 7375static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7376{
a16336e4 7377 int cond;
cbc37b28
AJ
7378 TCGv_i32 t0 = tcg_temp_new_i32();
7379 TCGv_i64 fp0;
a16336e4
TS
7380 int l1 = gen_new_label();
7381
a16336e4
TS
7382 if (tf)
7383 cond = TCG_COND_EQ;
7384 else
7385 cond = TCG_COND_NE;
7386
fa31af0e 7387 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7388 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7389 tcg_temp_free_i32(t0);
11f94258 7390 fp0 = tcg_temp_new_i64();
9bf3eb2c 7391 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7392 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7393 tcg_temp_free_i64(fp0);
cbc37b28 7394 gen_set_label(l1);
a16336e4
TS
7395}
7396
b6d96bed 7397static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
a16336e4
TS
7398{
7399 int cond;
cbc37b28 7400 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7401 int l1 = gen_new_label();
7402 int l2 = gen_new_label();
7403
7404 if (tf)
7405 cond = TCG_COND_EQ;
7406 else
7407 cond = TCG_COND_NE;
7408
fa31af0e 7409 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7410 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7411 gen_load_fpr32(t0, fs);
7412 gen_store_fpr32(t0, fd);
a16336e4 7413 gen_set_label(l1);
9bf3eb2c 7414
fa31af0e 7415 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28
AJ
7416 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7417 gen_load_fpr32h(t0, fs);
7418 gen_store_fpr32h(t0, fd);
52a0e9eb 7419 tcg_temp_free_i32(t0);
a16336e4 7420 gen_set_label(l2);
a16336e4
TS
7421}
7422
6ea83fed 7423
bf4120ad 7424static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7425 int ft, int fs, int fd, int cc)
6ea83fed 7426{
923617a3 7427 const char *opn = "farith";
6ea83fed
FB
7428 const char *condnames[] = {
7429 "c.f",
7430 "c.un",
7431 "c.eq",
7432 "c.ueq",
7433 "c.olt",
7434 "c.ult",
7435 "c.ole",
7436 "c.ule",
7437 "c.sf",
7438 "c.ngle",
7439 "c.seq",
7440 "c.ngl",
7441 "c.lt",
7442 "c.nge",
7443 "c.le",
7444 "c.ngt",
7445 };
5a1e8ffb
TS
7446 const char *condnames_abs[] = {
7447 "cabs.f",
7448 "cabs.un",
7449 "cabs.eq",
7450 "cabs.ueq",
7451 "cabs.olt",
7452 "cabs.ult",
7453 "cabs.ole",
7454 "cabs.ule",
7455 "cabs.sf",
7456 "cabs.ngle",
7457 "cabs.seq",
7458 "cabs.ngl",
7459 "cabs.lt",
7460 "cabs.nge",
7461 "cabs.le",
7462 "cabs.ngt",
7463 };
7464 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7465 uint32_t func = ctx->opcode & 0x3f;
7466
bf4120ad
NF
7467 switch (op1) {
7468 case OPC_ADD_S:
b6d96bed 7469 {
a7812ae4
PB
7470 TCGv_i32 fp0 = tcg_temp_new_i32();
7471 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7472
7473 gen_load_fpr32(fp0, fs);
7474 gen_load_fpr32(fp1, ft);
895c2d04 7475 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7476 tcg_temp_free_i32(fp1);
b6d96bed 7477 gen_store_fpr32(fp0, fd);
a7812ae4 7478 tcg_temp_free_i32(fp0);
b6d96bed 7479 }
5a5012ec 7480 opn = "add.s";
5a1e8ffb 7481 optype = BINOP;
5a5012ec 7482 break;
bf4120ad 7483 case OPC_SUB_S:
b6d96bed 7484 {
a7812ae4
PB
7485 TCGv_i32 fp0 = tcg_temp_new_i32();
7486 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7487
7488 gen_load_fpr32(fp0, fs);
7489 gen_load_fpr32(fp1, ft);
895c2d04 7490 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7491 tcg_temp_free_i32(fp1);
b6d96bed 7492 gen_store_fpr32(fp0, fd);
a7812ae4 7493 tcg_temp_free_i32(fp0);
b6d96bed 7494 }
5a5012ec 7495 opn = "sub.s";
5a1e8ffb 7496 optype = BINOP;
5a5012ec 7497 break;
bf4120ad 7498 case OPC_MUL_S:
b6d96bed 7499 {
a7812ae4
PB
7500 TCGv_i32 fp0 = tcg_temp_new_i32();
7501 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7502
7503 gen_load_fpr32(fp0, fs);
7504 gen_load_fpr32(fp1, ft);
895c2d04 7505 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7506 tcg_temp_free_i32(fp1);
b6d96bed 7507 gen_store_fpr32(fp0, fd);
a7812ae4 7508 tcg_temp_free_i32(fp0);
b6d96bed 7509 }
5a5012ec 7510 opn = "mul.s";
5a1e8ffb 7511 optype = BINOP;
5a5012ec 7512 break;
bf4120ad 7513 case OPC_DIV_S:
b6d96bed 7514 {
a7812ae4
PB
7515 TCGv_i32 fp0 = tcg_temp_new_i32();
7516 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7517
7518 gen_load_fpr32(fp0, fs);
7519 gen_load_fpr32(fp1, ft);
895c2d04 7520 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7521 tcg_temp_free_i32(fp1);
b6d96bed 7522 gen_store_fpr32(fp0, fd);
a7812ae4 7523 tcg_temp_free_i32(fp0);
b6d96bed 7524 }
5a5012ec 7525 opn = "div.s";
5a1e8ffb 7526 optype = BINOP;
5a5012ec 7527 break;
bf4120ad 7528 case OPC_SQRT_S:
b6d96bed 7529 {
a7812ae4 7530 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7531
7532 gen_load_fpr32(fp0, fs);
895c2d04 7533 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7534 gen_store_fpr32(fp0, fd);
a7812ae4 7535 tcg_temp_free_i32(fp0);
b6d96bed 7536 }
5a5012ec
TS
7537 opn = "sqrt.s";
7538 break;
bf4120ad 7539 case OPC_ABS_S:
b6d96bed 7540 {
a7812ae4 7541 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7542
7543 gen_load_fpr32(fp0, fs);
a7812ae4 7544 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7545 gen_store_fpr32(fp0, fd);
a7812ae4 7546 tcg_temp_free_i32(fp0);
b6d96bed 7547 }
5a5012ec
TS
7548 opn = "abs.s";
7549 break;
bf4120ad 7550 case OPC_MOV_S:
b6d96bed 7551 {
a7812ae4 7552 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7553
7554 gen_load_fpr32(fp0, fs);
7555 gen_store_fpr32(fp0, fd);
a7812ae4 7556 tcg_temp_free_i32(fp0);
b6d96bed 7557 }
5a5012ec
TS
7558 opn = "mov.s";
7559 break;
bf4120ad 7560 case OPC_NEG_S:
b6d96bed 7561 {
a7812ae4 7562 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7563
7564 gen_load_fpr32(fp0, fs);
a7812ae4 7565 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7566 gen_store_fpr32(fp0, fd);
a7812ae4 7567 tcg_temp_free_i32(fp0);
b6d96bed 7568 }
5a5012ec
TS
7569 opn = "neg.s";
7570 break;
bf4120ad 7571 case OPC_ROUND_L_S:
5e755519 7572 check_cp1_64bitmode(ctx);
b6d96bed 7573 {
a7812ae4
PB
7574 TCGv_i32 fp32 = tcg_temp_new_i32();
7575 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7576
7577 gen_load_fpr32(fp32, fs);
895c2d04 7578 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7579 tcg_temp_free_i32(fp32);
b6d96bed 7580 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7581 tcg_temp_free_i64(fp64);
b6d96bed 7582 }
5a5012ec
TS
7583 opn = "round.l.s";
7584 break;
bf4120ad 7585 case OPC_TRUNC_L_S:
5e755519 7586 check_cp1_64bitmode(ctx);
b6d96bed 7587 {
a7812ae4
PB
7588 TCGv_i32 fp32 = tcg_temp_new_i32();
7589 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7590
7591 gen_load_fpr32(fp32, fs);
895c2d04 7592 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7593 tcg_temp_free_i32(fp32);
b6d96bed 7594 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7595 tcg_temp_free_i64(fp64);
b6d96bed 7596 }
5a5012ec
TS
7597 opn = "trunc.l.s";
7598 break;
bf4120ad 7599 case OPC_CEIL_L_S:
5e755519 7600 check_cp1_64bitmode(ctx);
b6d96bed 7601 {
a7812ae4
PB
7602 TCGv_i32 fp32 = tcg_temp_new_i32();
7603 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7604
7605 gen_load_fpr32(fp32, fs);
895c2d04 7606 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7607 tcg_temp_free_i32(fp32);
b6d96bed 7608 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7609 tcg_temp_free_i64(fp64);
b6d96bed 7610 }
5a5012ec
TS
7611 opn = "ceil.l.s";
7612 break;
bf4120ad 7613 case OPC_FLOOR_L_S:
5e755519 7614 check_cp1_64bitmode(ctx);
b6d96bed 7615 {
a7812ae4
PB
7616 TCGv_i32 fp32 = tcg_temp_new_i32();
7617 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7618
7619 gen_load_fpr32(fp32, fs);
895c2d04 7620 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7621 tcg_temp_free_i32(fp32);
b6d96bed 7622 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7623 tcg_temp_free_i64(fp64);
b6d96bed 7624 }
5a5012ec
TS
7625 opn = "floor.l.s";
7626 break;
bf4120ad 7627 case OPC_ROUND_W_S:
b6d96bed 7628 {
a7812ae4 7629 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7630
7631 gen_load_fpr32(fp0, fs);
895c2d04 7632 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7633 gen_store_fpr32(fp0, fd);
a7812ae4 7634 tcg_temp_free_i32(fp0);
b6d96bed 7635 }
5a5012ec
TS
7636 opn = "round.w.s";
7637 break;
bf4120ad 7638 case OPC_TRUNC_W_S:
b6d96bed 7639 {
a7812ae4 7640 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7641
7642 gen_load_fpr32(fp0, fs);
895c2d04 7643 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7644 gen_store_fpr32(fp0, fd);
a7812ae4 7645 tcg_temp_free_i32(fp0);
b6d96bed 7646 }
5a5012ec
TS
7647 opn = "trunc.w.s";
7648 break;
bf4120ad 7649 case OPC_CEIL_W_S:
b6d96bed 7650 {
a7812ae4 7651 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7652
7653 gen_load_fpr32(fp0, fs);
895c2d04 7654 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7655 gen_store_fpr32(fp0, fd);
a7812ae4 7656 tcg_temp_free_i32(fp0);
b6d96bed 7657 }
5a5012ec
TS
7658 opn = "ceil.w.s";
7659 break;
bf4120ad 7660 case OPC_FLOOR_W_S:
b6d96bed 7661 {
a7812ae4 7662 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7663
7664 gen_load_fpr32(fp0, fs);
895c2d04 7665 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7666 gen_store_fpr32(fp0, fd);
a7812ae4 7667 tcg_temp_free_i32(fp0);
b6d96bed 7668 }
5a5012ec
TS
7669 opn = "floor.w.s";
7670 break;
bf4120ad 7671 case OPC_MOVCF_S:
b6d96bed 7672 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7673 opn = "movcf.s";
7674 break;
bf4120ad 7675 case OPC_MOVZ_S:
a16336e4
TS
7676 {
7677 int l1 = gen_new_label();
c9297f4d 7678 TCGv_i32 fp0;
a16336e4 7679
c9297f4d
AJ
7680 if (ft != 0) {
7681 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7682 }
7683 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7684 gen_load_fpr32(fp0, fs);
7685 gen_store_fpr32(fp0, fd);
a7812ae4 7686 tcg_temp_free_i32(fp0);
a16336e4
TS
7687 gen_set_label(l1);
7688 }
5a5012ec
TS
7689 opn = "movz.s";
7690 break;
bf4120ad 7691 case OPC_MOVN_S:
a16336e4
TS
7692 {
7693 int l1 = gen_new_label();
c9297f4d
AJ
7694 TCGv_i32 fp0;
7695
7696 if (ft != 0) {
7697 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7698 fp0 = tcg_temp_new_i32();
7699 gen_load_fpr32(fp0, fs);
7700 gen_store_fpr32(fp0, fd);
7701 tcg_temp_free_i32(fp0);
7702 gen_set_label(l1);
7703 }
a16336e4 7704 }
5a5012ec
TS
7705 opn = "movn.s";
7706 break;
bf4120ad 7707 case OPC_RECIP_S:
b8aa4598 7708 check_cop1x(ctx);
b6d96bed 7709 {
a7812ae4 7710 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7711
7712 gen_load_fpr32(fp0, fs);
895c2d04 7713 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 7714 gen_store_fpr32(fp0, fd);
a7812ae4 7715 tcg_temp_free_i32(fp0);
b6d96bed 7716 }
57fa1fb3
TS
7717 opn = "recip.s";
7718 break;
bf4120ad 7719 case OPC_RSQRT_S:
b8aa4598 7720 check_cop1x(ctx);
b6d96bed 7721 {
a7812ae4 7722 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7723
7724 gen_load_fpr32(fp0, fs);
895c2d04 7725 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7726 gen_store_fpr32(fp0, fd);
a7812ae4 7727 tcg_temp_free_i32(fp0);
b6d96bed 7728 }
57fa1fb3
TS
7729 opn = "rsqrt.s";
7730 break;
bf4120ad 7731 case OPC_RECIP2_S:
5e755519 7732 check_cp1_64bitmode(ctx);
b6d96bed 7733 {
a7812ae4
PB
7734 TCGv_i32 fp0 = tcg_temp_new_i32();
7735 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7736
7737 gen_load_fpr32(fp0, fs);
d22d7289 7738 gen_load_fpr32(fp1, ft);
895c2d04 7739 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7740 tcg_temp_free_i32(fp1);
b6d96bed 7741 gen_store_fpr32(fp0, fd);
a7812ae4 7742 tcg_temp_free_i32(fp0);
b6d96bed 7743 }
57fa1fb3
TS
7744 opn = "recip2.s";
7745 break;
bf4120ad 7746 case OPC_RECIP1_S:
5e755519 7747 check_cp1_64bitmode(ctx);
b6d96bed 7748 {
a7812ae4 7749 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7750
7751 gen_load_fpr32(fp0, fs);
895c2d04 7752 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7753 gen_store_fpr32(fp0, fd);
a7812ae4 7754 tcg_temp_free_i32(fp0);
b6d96bed 7755 }
57fa1fb3
TS
7756 opn = "recip1.s";
7757 break;
bf4120ad 7758 case OPC_RSQRT1_S:
5e755519 7759 check_cp1_64bitmode(ctx);
b6d96bed 7760 {
a7812ae4 7761 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7762
7763 gen_load_fpr32(fp0, fs);
895c2d04 7764 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7765 gen_store_fpr32(fp0, fd);
a7812ae4 7766 tcg_temp_free_i32(fp0);
b6d96bed 7767 }
57fa1fb3
TS
7768 opn = "rsqrt1.s";
7769 break;
bf4120ad 7770 case OPC_RSQRT2_S:
5e755519 7771 check_cp1_64bitmode(ctx);
b6d96bed 7772 {
a7812ae4
PB
7773 TCGv_i32 fp0 = tcg_temp_new_i32();
7774 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7775
7776 gen_load_fpr32(fp0, fs);
7777 gen_load_fpr32(fp1, ft);
895c2d04 7778 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7779 tcg_temp_free_i32(fp1);
b6d96bed 7780 gen_store_fpr32(fp0, fd);
a7812ae4 7781 tcg_temp_free_i32(fp0);
b6d96bed 7782 }
57fa1fb3
TS
7783 opn = "rsqrt2.s";
7784 break;
bf4120ad 7785 case OPC_CVT_D_S:
5e755519 7786 check_cp1_registers(ctx, fd);
b6d96bed 7787 {
a7812ae4
PB
7788 TCGv_i32 fp32 = tcg_temp_new_i32();
7789 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7790
7791 gen_load_fpr32(fp32, fs);
895c2d04 7792 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7793 tcg_temp_free_i32(fp32);
b6d96bed 7794 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7795 tcg_temp_free_i64(fp64);
b6d96bed 7796 }
5a5012ec
TS
7797 opn = "cvt.d.s";
7798 break;
bf4120ad 7799 case OPC_CVT_W_S:
b6d96bed 7800 {
a7812ae4 7801 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7802
7803 gen_load_fpr32(fp0, fs);
895c2d04 7804 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7805 gen_store_fpr32(fp0, fd);
a7812ae4 7806 tcg_temp_free_i32(fp0);
b6d96bed 7807 }
5a5012ec
TS
7808 opn = "cvt.w.s";
7809 break;
bf4120ad 7810 case OPC_CVT_L_S:
5e755519 7811 check_cp1_64bitmode(ctx);
b6d96bed 7812 {
a7812ae4
PB
7813 TCGv_i32 fp32 = tcg_temp_new_i32();
7814 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7815
7816 gen_load_fpr32(fp32, fs);
895c2d04 7817 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7818 tcg_temp_free_i32(fp32);
b6d96bed 7819 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7820 tcg_temp_free_i64(fp64);
b6d96bed 7821 }
5a5012ec
TS
7822 opn = "cvt.l.s";
7823 break;
bf4120ad 7824 case OPC_CVT_PS_S:
5e755519 7825 check_cp1_64bitmode(ctx);
b6d96bed 7826 {
a7812ae4
PB
7827 TCGv_i64 fp64 = tcg_temp_new_i64();
7828 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7829 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7830
7831 gen_load_fpr32(fp32_0, fs);
7832 gen_load_fpr32(fp32_1, ft);
13d24f49 7833 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7834 tcg_temp_free_i32(fp32_1);
7835 tcg_temp_free_i32(fp32_0);
36aa55dc 7836 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7837 tcg_temp_free_i64(fp64);
b6d96bed 7838 }
5a5012ec
TS
7839 opn = "cvt.ps.s";
7840 break;
bf4120ad
NF
7841 case OPC_CMP_F_S:
7842 case OPC_CMP_UN_S:
7843 case OPC_CMP_EQ_S:
7844 case OPC_CMP_UEQ_S:
7845 case OPC_CMP_OLT_S:
7846 case OPC_CMP_ULT_S:
7847 case OPC_CMP_OLE_S:
7848 case OPC_CMP_ULE_S:
7849 case OPC_CMP_SF_S:
7850 case OPC_CMP_NGLE_S:
7851 case OPC_CMP_SEQ_S:
7852 case OPC_CMP_NGL_S:
7853 case OPC_CMP_LT_S:
7854 case OPC_CMP_NGE_S:
7855 case OPC_CMP_LE_S:
7856 case OPC_CMP_NGT_S:
8153667c
NF
7857 if (ctx->opcode & (1 << 6)) {
7858 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7859 opn = condnames_abs[func-48];
7860 } else {
7861 gen_cmp_s(ctx, func-48, ft, fs, cc);
7862 opn = condnames[func-48];
5a1e8ffb 7863 }
5a5012ec 7864 break;
bf4120ad 7865 case OPC_ADD_D:
5e755519 7866 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7867 {
a7812ae4
PB
7868 TCGv_i64 fp0 = tcg_temp_new_i64();
7869 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7870
7871 gen_load_fpr64(ctx, fp0, fs);
7872 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7873 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7874 tcg_temp_free_i64(fp1);
b6d96bed 7875 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7876 tcg_temp_free_i64(fp0);
b6d96bed 7877 }
6ea83fed 7878 opn = "add.d";
5a1e8ffb 7879 optype = BINOP;
6ea83fed 7880 break;
bf4120ad 7881 case OPC_SUB_D:
5e755519 7882 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7883 {
a7812ae4
PB
7884 TCGv_i64 fp0 = tcg_temp_new_i64();
7885 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7886
7887 gen_load_fpr64(ctx, fp0, fs);
7888 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7889 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7890 tcg_temp_free_i64(fp1);
b6d96bed 7891 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7892 tcg_temp_free_i64(fp0);
b6d96bed 7893 }
6ea83fed 7894 opn = "sub.d";
5a1e8ffb 7895 optype = BINOP;
6ea83fed 7896 break;
bf4120ad 7897 case OPC_MUL_D:
5e755519 7898 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7899 {
a7812ae4
PB
7900 TCGv_i64 fp0 = tcg_temp_new_i64();
7901 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7902
7903 gen_load_fpr64(ctx, fp0, fs);
7904 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7905 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7906 tcg_temp_free_i64(fp1);
b6d96bed 7907 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7908 tcg_temp_free_i64(fp0);
b6d96bed 7909 }
6ea83fed 7910 opn = "mul.d";
5a1e8ffb 7911 optype = BINOP;
6ea83fed 7912 break;
bf4120ad 7913 case OPC_DIV_D:
5e755519 7914 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7915 {
a7812ae4
PB
7916 TCGv_i64 fp0 = tcg_temp_new_i64();
7917 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7918
7919 gen_load_fpr64(ctx, fp0, fs);
7920 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7921 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7922 tcg_temp_free_i64(fp1);
b6d96bed 7923 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7924 tcg_temp_free_i64(fp0);
b6d96bed 7925 }
6ea83fed 7926 opn = "div.d";
5a1e8ffb 7927 optype = BINOP;
6ea83fed 7928 break;
bf4120ad 7929 case OPC_SQRT_D:
5e755519 7930 check_cp1_registers(ctx, fs | fd);
b6d96bed 7931 {
a7812ae4 7932 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7933
7934 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7935 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7936 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7937 tcg_temp_free_i64(fp0);
b6d96bed 7938 }
6ea83fed
FB
7939 opn = "sqrt.d";
7940 break;
bf4120ad 7941 case OPC_ABS_D:
5e755519 7942 check_cp1_registers(ctx, fs | fd);
b6d96bed 7943 {
a7812ae4 7944 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7945
7946 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7947 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7948 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7949 tcg_temp_free_i64(fp0);
b6d96bed 7950 }
6ea83fed
FB
7951 opn = "abs.d";
7952 break;
bf4120ad 7953 case OPC_MOV_D:
5e755519 7954 check_cp1_registers(ctx, fs | fd);
b6d96bed 7955 {
a7812ae4 7956 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7957
7958 gen_load_fpr64(ctx, fp0, fs);
7959 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7960 tcg_temp_free_i64(fp0);
b6d96bed 7961 }
6ea83fed
FB
7962 opn = "mov.d";
7963 break;
bf4120ad 7964 case OPC_NEG_D:
5e755519 7965 check_cp1_registers(ctx, fs | fd);
b6d96bed 7966 {
a7812ae4 7967 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7968
7969 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7970 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 7971 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7972 tcg_temp_free_i64(fp0);
b6d96bed 7973 }
6ea83fed
FB
7974 opn = "neg.d";
7975 break;
bf4120ad 7976 case OPC_ROUND_L_D:
5e755519 7977 check_cp1_64bitmode(ctx);
b6d96bed 7978 {
a7812ae4 7979 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7980
7981 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7982 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 7983 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7984 tcg_temp_free_i64(fp0);
b6d96bed 7985 }
5a5012ec
TS
7986 opn = "round.l.d";
7987 break;
bf4120ad 7988 case OPC_TRUNC_L_D:
5e755519 7989 check_cp1_64bitmode(ctx);
b6d96bed 7990 {
a7812ae4 7991 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7992
7993 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7994 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 7995 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7996 tcg_temp_free_i64(fp0);
b6d96bed 7997 }
5a5012ec
TS
7998 opn = "trunc.l.d";
7999 break;
bf4120ad 8000 case OPC_CEIL_L_D:
5e755519 8001 check_cp1_64bitmode(ctx);
b6d96bed 8002 {
a7812ae4 8003 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8004
8005 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8006 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8007 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8008 tcg_temp_free_i64(fp0);
b6d96bed 8009 }
5a5012ec
TS
8010 opn = "ceil.l.d";
8011 break;
bf4120ad 8012 case OPC_FLOOR_L_D:
5e755519 8013 check_cp1_64bitmode(ctx);
b6d96bed 8014 {
a7812ae4 8015 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8016
8017 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8018 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8019 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8020 tcg_temp_free_i64(fp0);
b6d96bed 8021 }
5a5012ec
TS
8022 opn = "floor.l.d";
8023 break;
bf4120ad 8024 case OPC_ROUND_W_D:
5e755519 8025 check_cp1_registers(ctx, fs);
b6d96bed 8026 {
a7812ae4
PB
8027 TCGv_i32 fp32 = tcg_temp_new_i32();
8028 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8029
8030 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8031 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8032 tcg_temp_free_i64(fp64);
b6d96bed 8033 gen_store_fpr32(fp32, fd);
a7812ae4 8034 tcg_temp_free_i32(fp32);
b6d96bed 8035 }
6ea83fed
FB
8036 opn = "round.w.d";
8037 break;
bf4120ad 8038 case OPC_TRUNC_W_D:
5e755519 8039 check_cp1_registers(ctx, fs);
b6d96bed 8040 {
a7812ae4
PB
8041 TCGv_i32 fp32 = tcg_temp_new_i32();
8042 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8043
8044 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8045 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8046 tcg_temp_free_i64(fp64);
b6d96bed 8047 gen_store_fpr32(fp32, fd);
a7812ae4 8048 tcg_temp_free_i32(fp32);
b6d96bed 8049 }
6ea83fed
FB
8050 opn = "trunc.w.d";
8051 break;
bf4120ad 8052 case OPC_CEIL_W_D:
5e755519 8053 check_cp1_registers(ctx, fs);
b6d96bed 8054 {
a7812ae4
PB
8055 TCGv_i32 fp32 = tcg_temp_new_i32();
8056 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8057
8058 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8059 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8060 tcg_temp_free_i64(fp64);
b6d96bed 8061 gen_store_fpr32(fp32, fd);
a7812ae4 8062 tcg_temp_free_i32(fp32);
b6d96bed 8063 }
6ea83fed
FB
8064 opn = "ceil.w.d";
8065 break;
bf4120ad 8066 case OPC_FLOOR_W_D:
5e755519 8067 check_cp1_registers(ctx, fs);
b6d96bed 8068 {
a7812ae4
PB
8069 TCGv_i32 fp32 = tcg_temp_new_i32();
8070 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8071
8072 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8073 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8074 tcg_temp_free_i64(fp64);
b6d96bed 8075 gen_store_fpr32(fp32, fd);
a7812ae4 8076 tcg_temp_free_i32(fp32);
b6d96bed 8077 }
7a387fff 8078 opn = "floor.w.d";
6ea83fed 8079 break;
bf4120ad 8080 case OPC_MOVCF_D:
b6d96bed 8081 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8082 opn = "movcf.d";
dd016883 8083 break;
bf4120ad 8084 case OPC_MOVZ_D:
a16336e4
TS
8085 {
8086 int l1 = gen_new_label();
c9297f4d 8087 TCGv_i64 fp0;
a16336e4 8088
c9297f4d
AJ
8089 if (ft != 0) {
8090 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8091 }
8092 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8093 gen_load_fpr64(ctx, fp0, fs);
8094 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8095 tcg_temp_free_i64(fp0);
a16336e4
TS
8096 gen_set_label(l1);
8097 }
5a5012ec
TS
8098 opn = "movz.d";
8099 break;
bf4120ad 8100 case OPC_MOVN_D:
a16336e4
TS
8101 {
8102 int l1 = gen_new_label();
c9297f4d
AJ
8103 TCGv_i64 fp0;
8104
8105 if (ft != 0) {
8106 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8107 fp0 = tcg_temp_new_i64();
8108 gen_load_fpr64(ctx, fp0, fs);
8109 gen_store_fpr64(ctx, fp0, fd);
8110 tcg_temp_free_i64(fp0);
8111 gen_set_label(l1);
8112 }
a16336e4 8113 }
5a5012ec 8114 opn = "movn.d";
6ea83fed 8115 break;
bf4120ad 8116 case OPC_RECIP_D:
b8aa4598 8117 check_cp1_64bitmode(ctx);
b6d96bed 8118 {
a7812ae4 8119 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8120
8121 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8122 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8123 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8124 tcg_temp_free_i64(fp0);
b6d96bed 8125 }
57fa1fb3
TS
8126 opn = "recip.d";
8127 break;
bf4120ad 8128 case OPC_RSQRT_D:
b8aa4598 8129 check_cp1_64bitmode(ctx);
b6d96bed 8130 {
a7812ae4 8131 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8132
8133 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8134 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8135 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8136 tcg_temp_free_i64(fp0);
b6d96bed 8137 }
57fa1fb3
TS
8138 opn = "rsqrt.d";
8139 break;
bf4120ad 8140 case OPC_RECIP2_D:
5e755519 8141 check_cp1_64bitmode(ctx);
b6d96bed 8142 {
a7812ae4
PB
8143 TCGv_i64 fp0 = tcg_temp_new_i64();
8144 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8145
8146 gen_load_fpr64(ctx, fp0, fs);
8147 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8148 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8149 tcg_temp_free_i64(fp1);
b6d96bed 8150 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8151 tcg_temp_free_i64(fp0);
b6d96bed 8152 }
57fa1fb3
TS
8153 opn = "recip2.d";
8154 break;
bf4120ad 8155 case OPC_RECIP1_D:
5e755519 8156 check_cp1_64bitmode(ctx);
b6d96bed 8157 {
a7812ae4 8158 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8159
8160 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8161 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8162 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8163 tcg_temp_free_i64(fp0);
b6d96bed 8164 }
57fa1fb3
TS
8165 opn = "recip1.d";
8166 break;
bf4120ad 8167 case OPC_RSQRT1_D:
5e755519 8168 check_cp1_64bitmode(ctx);
b6d96bed 8169 {
a7812ae4 8170 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8171
8172 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8173 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8174 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8175 tcg_temp_free_i64(fp0);
b6d96bed 8176 }
57fa1fb3
TS
8177 opn = "rsqrt1.d";
8178 break;
bf4120ad 8179 case OPC_RSQRT2_D:
5e755519 8180 check_cp1_64bitmode(ctx);
b6d96bed 8181 {
a7812ae4
PB
8182 TCGv_i64 fp0 = tcg_temp_new_i64();
8183 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8184
8185 gen_load_fpr64(ctx, fp0, fs);
8186 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8187 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8188 tcg_temp_free_i64(fp1);
b6d96bed 8189 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8190 tcg_temp_free_i64(fp0);
b6d96bed 8191 }
57fa1fb3
TS
8192 opn = "rsqrt2.d";
8193 break;
bf4120ad
NF
8194 case OPC_CMP_F_D:
8195 case OPC_CMP_UN_D:
8196 case OPC_CMP_EQ_D:
8197 case OPC_CMP_UEQ_D:
8198 case OPC_CMP_OLT_D:
8199 case OPC_CMP_ULT_D:
8200 case OPC_CMP_OLE_D:
8201 case OPC_CMP_ULE_D:
8202 case OPC_CMP_SF_D:
8203 case OPC_CMP_NGLE_D:
8204 case OPC_CMP_SEQ_D:
8205 case OPC_CMP_NGL_D:
8206 case OPC_CMP_LT_D:
8207 case OPC_CMP_NGE_D:
8208 case OPC_CMP_LE_D:
8209 case OPC_CMP_NGT_D:
8153667c
NF
8210 if (ctx->opcode & (1 << 6)) {
8211 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8212 opn = condnames_abs[func-48];
8213 } else {
8214 gen_cmp_d(ctx, func-48, ft, fs, cc);
8215 opn = condnames[func-48];
5a1e8ffb 8216 }
6ea83fed 8217 break;
bf4120ad 8218 case OPC_CVT_S_D:
5e755519 8219 check_cp1_registers(ctx, fs);
b6d96bed 8220 {
a7812ae4
PB
8221 TCGv_i32 fp32 = tcg_temp_new_i32();
8222 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8223
8224 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8225 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8226 tcg_temp_free_i64(fp64);
b6d96bed 8227 gen_store_fpr32(fp32, fd);
a7812ae4 8228 tcg_temp_free_i32(fp32);
b6d96bed 8229 }
5a5012ec
TS
8230 opn = "cvt.s.d";
8231 break;
bf4120ad 8232 case OPC_CVT_W_D:
5e755519 8233 check_cp1_registers(ctx, fs);
b6d96bed 8234 {
a7812ae4
PB
8235 TCGv_i32 fp32 = tcg_temp_new_i32();
8236 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8237
8238 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8239 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8240 tcg_temp_free_i64(fp64);
b6d96bed 8241 gen_store_fpr32(fp32, fd);
a7812ae4 8242 tcg_temp_free_i32(fp32);
b6d96bed 8243 }
5a5012ec
TS
8244 opn = "cvt.w.d";
8245 break;
bf4120ad 8246 case OPC_CVT_L_D:
5e755519 8247 check_cp1_64bitmode(ctx);
b6d96bed 8248 {
a7812ae4 8249 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8250
8251 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8252 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8253 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8254 tcg_temp_free_i64(fp0);
b6d96bed 8255 }
5a5012ec
TS
8256 opn = "cvt.l.d";
8257 break;
bf4120ad 8258 case OPC_CVT_S_W:
b6d96bed 8259 {
a7812ae4 8260 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8261
8262 gen_load_fpr32(fp0, fs);
895c2d04 8263 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8264 gen_store_fpr32(fp0, fd);
a7812ae4 8265 tcg_temp_free_i32(fp0);
b6d96bed 8266 }
5a5012ec 8267 opn = "cvt.s.w";
6ea83fed 8268 break;
bf4120ad 8269 case OPC_CVT_D_W:
5e755519 8270 check_cp1_registers(ctx, fd);
b6d96bed 8271 {
a7812ae4
PB
8272 TCGv_i32 fp32 = tcg_temp_new_i32();
8273 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8274
8275 gen_load_fpr32(fp32, fs);
895c2d04 8276 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8277 tcg_temp_free_i32(fp32);
b6d96bed 8278 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8279 tcg_temp_free_i64(fp64);
b6d96bed 8280 }
5a5012ec
TS
8281 opn = "cvt.d.w";
8282 break;
bf4120ad 8283 case OPC_CVT_S_L:
5e755519 8284 check_cp1_64bitmode(ctx);
b6d96bed 8285 {
a7812ae4
PB
8286 TCGv_i32 fp32 = tcg_temp_new_i32();
8287 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8288
8289 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8290 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8291 tcg_temp_free_i64(fp64);
b6d96bed 8292 gen_store_fpr32(fp32, fd);
a7812ae4 8293 tcg_temp_free_i32(fp32);
b6d96bed 8294 }
5a5012ec
TS
8295 opn = "cvt.s.l";
8296 break;
bf4120ad 8297 case OPC_CVT_D_L:
5e755519 8298 check_cp1_64bitmode(ctx);
b6d96bed 8299 {
a7812ae4 8300 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8301
8302 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8303 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8304 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8305 tcg_temp_free_i64(fp0);
b6d96bed 8306 }
5a5012ec
TS
8307 opn = "cvt.d.l";
8308 break;
bf4120ad 8309 case OPC_CVT_PS_PW:
5e755519 8310 check_cp1_64bitmode(ctx);
b6d96bed 8311 {
a7812ae4 8312 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8313
8314 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8315 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8316 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8317 tcg_temp_free_i64(fp0);
b6d96bed 8318 }
5a5012ec
TS
8319 opn = "cvt.ps.pw";
8320 break;
bf4120ad 8321 case OPC_ADD_PS:
5e755519 8322 check_cp1_64bitmode(ctx);
b6d96bed 8323 {
a7812ae4
PB
8324 TCGv_i64 fp0 = tcg_temp_new_i64();
8325 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8326
8327 gen_load_fpr64(ctx, fp0, fs);
8328 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8329 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8330 tcg_temp_free_i64(fp1);
b6d96bed 8331 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8332 tcg_temp_free_i64(fp0);
b6d96bed 8333 }
5a5012ec 8334 opn = "add.ps";
6ea83fed 8335 break;
bf4120ad 8336 case OPC_SUB_PS:
5e755519 8337 check_cp1_64bitmode(ctx);
b6d96bed 8338 {
a7812ae4
PB
8339 TCGv_i64 fp0 = tcg_temp_new_i64();
8340 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8341
8342 gen_load_fpr64(ctx, fp0, fs);
8343 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8344 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8345 tcg_temp_free_i64(fp1);
b6d96bed 8346 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8347 tcg_temp_free_i64(fp0);
b6d96bed 8348 }
5a5012ec 8349 opn = "sub.ps";
6ea83fed 8350 break;
bf4120ad 8351 case OPC_MUL_PS:
5e755519 8352 check_cp1_64bitmode(ctx);
b6d96bed 8353 {
a7812ae4
PB
8354 TCGv_i64 fp0 = tcg_temp_new_i64();
8355 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8356
8357 gen_load_fpr64(ctx, fp0, fs);
8358 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8359 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8360 tcg_temp_free_i64(fp1);
b6d96bed 8361 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8362 tcg_temp_free_i64(fp0);
b6d96bed 8363 }
5a5012ec 8364 opn = "mul.ps";
6ea83fed 8365 break;
bf4120ad 8366 case OPC_ABS_PS:
5e755519 8367 check_cp1_64bitmode(ctx);
b6d96bed 8368 {
a7812ae4 8369 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8370
8371 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8372 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8373 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8374 tcg_temp_free_i64(fp0);
b6d96bed 8375 }
5a5012ec 8376 opn = "abs.ps";
6ea83fed 8377 break;
bf4120ad 8378 case OPC_MOV_PS:
5e755519 8379 check_cp1_64bitmode(ctx);
b6d96bed 8380 {
a7812ae4 8381 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8382
8383 gen_load_fpr64(ctx, fp0, fs);
8384 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8385 tcg_temp_free_i64(fp0);
b6d96bed 8386 }
5a5012ec 8387 opn = "mov.ps";
6ea83fed 8388 break;
bf4120ad 8389 case OPC_NEG_PS:
5e755519 8390 check_cp1_64bitmode(ctx);
b6d96bed 8391 {
a7812ae4 8392 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8393
8394 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8395 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8396 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8397 tcg_temp_free_i64(fp0);
b6d96bed 8398 }
5a5012ec 8399 opn = "neg.ps";
6ea83fed 8400 break;
bf4120ad 8401 case OPC_MOVCF_PS:
5e755519 8402 check_cp1_64bitmode(ctx);
b6d96bed 8403 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8404 opn = "movcf.ps";
6ea83fed 8405 break;
bf4120ad 8406 case OPC_MOVZ_PS:
5e755519 8407 check_cp1_64bitmode(ctx);
a16336e4
TS
8408 {
8409 int l1 = gen_new_label();
30a3848b 8410 TCGv_i64 fp0;
a16336e4 8411
c9297f4d
AJ
8412 if (ft != 0)
8413 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8414 fp0 = tcg_temp_new_i64();
8415 gen_load_fpr64(ctx, fp0, fs);
8416 gen_store_fpr64(ctx, fp0, fd);
8417 tcg_temp_free_i64(fp0);
a16336e4
TS
8418 gen_set_label(l1);
8419 }
5a5012ec 8420 opn = "movz.ps";
6ea83fed 8421 break;
bf4120ad 8422 case OPC_MOVN_PS:
5e755519 8423 check_cp1_64bitmode(ctx);
a16336e4
TS
8424 {
8425 int l1 = gen_new_label();
30a3848b 8426 TCGv_i64 fp0;
c9297f4d
AJ
8427
8428 if (ft != 0) {
8429 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8430 fp0 = tcg_temp_new_i64();
8431 gen_load_fpr64(ctx, fp0, fs);
8432 gen_store_fpr64(ctx, fp0, fd);
8433 tcg_temp_free_i64(fp0);
8434 gen_set_label(l1);
8435 }
a16336e4 8436 }
5a5012ec 8437 opn = "movn.ps";
6ea83fed 8438 break;
bf4120ad 8439 case OPC_ADDR_PS:
5e755519 8440 check_cp1_64bitmode(ctx);
b6d96bed 8441 {
a7812ae4
PB
8442 TCGv_i64 fp0 = tcg_temp_new_i64();
8443 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8444
8445 gen_load_fpr64(ctx, fp0, ft);
8446 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8447 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8448 tcg_temp_free_i64(fp1);
b6d96bed 8449 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8450 tcg_temp_free_i64(fp0);
b6d96bed 8451 }
fbcc6828
TS
8452 opn = "addr.ps";
8453 break;
bf4120ad 8454 case OPC_MULR_PS:
5e755519 8455 check_cp1_64bitmode(ctx);
b6d96bed 8456 {
a7812ae4
PB
8457 TCGv_i64 fp0 = tcg_temp_new_i64();
8458 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8459
8460 gen_load_fpr64(ctx, fp0, ft);
8461 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8462 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8463 tcg_temp_free_i64(fp1);
b6d96bed 8464 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8465 tcg_temp_free_i64(fp0);
b6d96bed 8466 }
57fa1fb3
TS
8467 opn = "mulr.ps";
8468 break;
bf4120ad 8469 case OPC_RECIP2_PS:
5e755519 8470 check_cp1_64bitmode(ctx);
b6d96bed 8471 {
a7812ae4
PB
8472 TCGv_i64 fp0 = tcg_temp_new_i64();
8473 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8474
8475 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8476 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8477 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8478 tcg_temp_free_i64(fp1);
b6d96bed 8479 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8480 tcg_temp_free_i64(fp0);
b6d96bed 8481 }
57fa1fb3
TS
8482 opn = "recip2.ps";
8483 break;
bf4120ad 8484 case OPC_RECIP1_PS:
5e755519 8485 check_cp1_64bitmode(ctx);
b6d96bed 8486 {
a7812ae4 8487 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8488
8489 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8490 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8491 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8492 tcg_temp_free_i64(fp0);
b6d96bed 8493 }
57fa1fb3
TS
8494 opn = "recip1.ps";
8495 break;
bf4120ad 8496 case OPC_RSQRT1_PS:
5e755519 8497 check_cp1_64bitmode(ctx);
b6d96bed 8498 {
a7812ae4 8499 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8500
8501 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8502 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8503 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8504 tcg_temp_free_i64(fp0);
b6d96bed 8505 }
57fa1fb3
TS
8506 opn = "rsqrt1.ps";
8507 break;
bf4120ad 8508 case OPC_RSQRT2_PS:
5e755519 8509 check_cp1_64bitmode(ctx);
b6d96bed 8510 {
a7812ae4
PB
8511 TCGv_i64 fp0 = tcg_temp_new_i64();
8512 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8513
8514 gen_load_fpr64(ctx, fp0, fs);
8515 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8516 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8517 tcg_temp_free_i64(fp1);
b6d96bed 8518 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8519 tcg_temp_free_i64(fp0);
b6d96bed 8520 }
57fa1fb3
TS
8521 opn = "rsqrt2.ps";
8522 break;
bf4120ad 8523 case OPC_CVT_S_PU:
5e755519 8524 check_cp1_64bitmode(ctx);
b6d96bed 8525 {
a7812ae4 8526 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8527
8528 gen_load_fpr32h(fp0, fs);
895c2d04 8529 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8530 gen_store_fpr32(fp0, fd);
a7812ae4 8531 tcg_temp_free_i32(fp0);
b6d96bed 8532 }
5a5012ec 8533 opn = "cvt.s.pu";
dd016883 8534 break;
bf4120ad 8535 case OPC_CVT_PW_PS:
5e755519 8536 check_cp1_64bitmode(ctx);
b6d96bed 8537 {
a7812ae4 8538 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8539
8540 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8541 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8542 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8543 tcg_temp_free_i64(fp0);
b6d96bed 8544 }
5a5012ec 8545 opn = "cvt.pw.ps";
6ea83fed 8546 break;
bf4120ad 8547 case OPC_CVT_S_PL:
5e755519 8548 check_cp1_64bitmode(ctx);
b6d96bed 8549 {
a7812ae4 8550 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8551
8552 gen_load_fpr32(fp0, fs);
895c2d04 8553 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8554 gen_store_fpr32(fp0, fd);
a7812ae4 8555 tcg_temp_free_i32(fp0);
b6d96bed 8556 }
5a5012ec 8557 opn = "cvt.s.pl";
6ea83fed 8558 break;
bf4120ad 8559 case OPC_PLL_PS:
5e755519 8560 check_cp1_64bitmode(ctx);
b6d96bed 8561 {
a7812ae4
PB
8562 TCGv_i32 fp0 = tcg_temp_new_i32();
8563 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8564
8565 gen_load_fpr32(fp0, fs);
8566 gen_load_fpr32(fp1, ft);
8567 gen_store_fpr32h(fp0, fd);
8568 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8569 tcg_temp_free_i32(fp0);
8570 tcg_temp_free_i32(fp1);
b6d96bed 8571 }
5a5012ec 8572 opn = "pll.ps";
6ea83fed 8573 break;
bf4120ad 8574 case OPC_PLU_PS:
5e755519 8575 check_cp1_64bitmode(ctx);
b6d96bed 8576 {
a7812ae4
PB
8577 TCGv_i32 fp0 = tcg_temp_new_i32();
8578 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8579
8580 gen_load_fpr32(fp0, fs);
8581 gen_load_fpr32h(fp1, ft);
8582 gen_store_fpr32(fp1, fd);
8583 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8584 tcg_temp_free_i32(fp0);
8585 tcg_temp_free_i32(fp1);
b6d96bed 8586 }
5a5012ec
TS
8587 opn = "plu.ps";
8588 break;
bf4120ad 8589 case OPC_PUL_PS:
5e755519 8590 check_cp1_64bitmode(ctx);
b6d96bed 8591 {
a7812ae4
PB
8592 TCGv_i32 fp0 = tcg_temp_new_i32();
8593 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8594
8595 gen_load_fpr32h(fp0, fs);
8596 gen_load_fpr32(fp1, ft);
8597 gen_store_fpr32(fp1, fd);
8598 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8599 tcg_temp_free_i32(fp0);
8600 tcg_temp_free_i32(fp1);
b6d96bed 8601 }
5a5012ec
TS
8602 opn = "pul.ps";
8603 break;
bf4120ad 8604 case OPC_PUU_PS:
5e755519 8605 check_cp1_64bitmode(ctx);
b6d96bed 8606 {
a7812ae4
PB
8607 TCGv_i32 fp0 = tcg_temp_new_i32();
8608 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8609
8610 gen_load_fpr32h(fp0, fs);
8611 gen_load_fpr32h(fp1, ft);
8612 gen_store_fpr32(fp1, fd);
8613 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8614 tcg_temp_free_i32(fp0);
8615 tcg_temp_free_i32(fp1);
b6d96bed 8616 }
5a5012ec
TS
8617 opn = "puu.ps";
8618 break;
bf4120ad
NF
8619 case OPC_CMP_F_PS:
8620 case OPC_CMP_UN_PS:
8621 case OPC_CMP_EQ_PS:
8622 case OPC_CMP_UEQ_PS:
8623 case OPC_CMP_OLT_PS:
8624 case OPC_CMP_ULT_PS:
8625 case OPC_CMP_OLE_PS:
8626 case OPC_CMP_ULE_PS:
8627 case OPC_CMP_SF_PS:
8628 case OPC_CMP_NGLE_PS:
8629 case OPC_CMP_SEQ_PS:
8630 case OPC_CMP_NGL_PS:
8631 case OPC_CMP_LT_PS:
8632 case OPC_CMP_NGE_PS:
8633 case OPC_CMP_LE_PS:
8634 case OPC_CMP_NGT_PS:
8153667c
NF
8635 if (ctx->opcode & (1 << 6)) {
8636 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8637 opn = condnames_abs[func-48];
8638 } else {
8639 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8640 opn = condnames[func-48];
5a1e8ffb 8641 }
6ea83fed 8642 break;
5a5012ec 8643 default:
923617a3 8644 MIPS_INVAL(opn);
e397ee33 8645 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8646 return;
8647 }
2abf314d 8648 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8649 switch (optype) {
8650 case BINOP:
6ea83fed 8651 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8652 break;
8653 case CMPOP:
8654 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8655 break;
8656 default:
6ea83fed 8657 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8658 break;
8659 }
6ea83fed 8660}
6af0bf9c 8661
5a5012ec 8662/* Coprocessor 3 (FPU) */
5e755519
TS
8663static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8664 int fd, int fs, int base, int index)
7a387fff 8665{
923617a3 8666 const char *opn = "extended float load/store";
93b12ccc 8667 int store = 0;
4e2474d6 8668 TCGv t0 = tcg_temp_new();
7a387fff 8669
93b12ccc 8670 if (base == 0) {
6c5c1e20 8671 gen_load_gpr(t0, index);
93b12ccc 8672 } else if (index == 0) {
6c5c1e20 8673 gen_load_gpr(t0, base);
93b12ccc 8674 } else {
05168674 8675 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8676 }
5a5012ec 8677 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8678 memory access. */
5a5012ec
TS
8679 switch (opc) {
8680 case OPC_LWXC1:
8c0ab41f 8681 check_cop1x(ctx);
b6d96bed 8682 {
a7812ae4 8683 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8684
585c88d5
AJ
8685 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8686 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8687 gen_store_fpr32(fp0, fd);
a7812ae4 8688 tcg_temp_free_i32(fp0);
b6d96bed 8689 }
5a5012ec
TS
8690 opn = "lwxc1";
8691 break;
8692 case OPC_LDXC1:
8c0ab41f
AJ
8693 check_cop1x(ctx);
8694 check_cp1_registers(ctx, fd);
b6d96bed 8695 {
a7812ae4 8696 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8697
8698 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8699 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8700 tcg_temp_free_i64(fp0);
b6d96bed 8701 }
5a5012ec
TS
8702 opn = "ldxc1";
8703 break;
8704 case OPC_LUXC1:
8c0ab41f 8705 check_cp1_64bitmode(ctx);
6c5c1e20 8706 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8707 {
a7812ae4 8708 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8709
8710 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8711 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8712 tcg_temp_free_i64(fp0);
b6d96bed 8713 }
5a5012ec
TS
8714 opn = "luxc1";
8715 break;
8716 case OPC_SWXC1:
8c0ab41f 8717 check_cop1x(ctx);
b6d96bed 8718 {
a7812ae4 8719 TCGv_i32 fp0 = tcg_temp_new_i32();
585c88d5 8720 TCGv t1 = tcg_temp_new();
b6d96bed
TS
8721
8722 gen_load_fpr32(fp0, fs);
a7812ae4
PB
8723 tcg_gen_extu_i32_tl(t1, fp0);
8724 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8725 tcg_temp_free_i32(fp0);
a6035857 8726 tcg_temp_free(t1);
b6d96bed 8727 }
5a5012ec 8728 opn = "swxc1";
93b12ccc 8729 store = 1;
5a5012ec
TS
8730 break;
8731 case OPC_SDXC1:
8c0ab41f
AJ
8732 check_cop1x(ctx);
8733 check_cp1_registers(ctx, fs);
b6d96bed 8734 {
a7812ae4 8735 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8736
8737 gen_load_fpr64(ctx, fp0, fs);
8738 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8739 tcg_temp_free_i64(fp0);
b6d96bed 8740 }
5a5012ec 8741 opn = "sdxc1";
93b12ccc 8742 store = 1;
5a5012ec
TS
8743 break;
8744 case OPC_SUXC1:
8c0ab41f 8745 check_cp1_64bitmode(ctx);
6c5c1e20 8746 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8747 {
a7812ae4 8748 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8749
8750 gen_load_fpr64(ctx, fp0, fs);
8751 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8752 tcg_temp_free_i64(fp0);
b6d96bed 8753 }
5a5012ec 8754 opn = "suxc1";
93b12ccc 8755 store = 1;
5a5012ec 8756 break;
5a5012ec 8757 }
6c5c1e20 8758 tcg_temp_free(t0);
2abf314d 8759 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8760 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8761 regnames[index], regnames[base]);
5a5012ec
TS
8762}
8763
5e755519
TS
8764static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8765 int fd, int fr, int fs, int ft)
5a5012ec 8766{
923617a3 8767 const char *opn = "flt3_arith";
5a5012ec 8768
5a5012ec
TS
8769 switch (opc) {
8770 case OPC_ALNV_PS:
b8aa4598 8771 check_cp1_64bitmode(ctx);
a16336e4 8772 {
a7812ae4 8773 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8774 TCGv_i32 fp = tcg_temp_new_i32();
8775 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8776 int l1 = gen_new_label();
8777 int l2 = gen_new_label();
8778
6c5c1e20
TS
8779 gen_load_gpr(t0, fr);
8780 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8781
8782 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac
AJ
8783 gen_load_fpr32(fp, fs);
8784 gen_load_fpr32h(fph, fs);
8785 gen_store_fpr32(fp, fd);
8786 gen_store_fpr32h(fph, fd);
a16336e4
TS
8787 tcg_gen_br(l2);
8788 gen_set_label(l1);
6c5c1e20
TS
8789 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8790 tcg_temp_free(t0);
a16336e4 8791#ifdef TARGET_WORDS_BIGENDIAN
c905fdac
AJ
8792 gen_load_fpr32(fp, fs);
8793 gen_load_fpr32h(fph, ft);
8794 gen_store_fpr32h(fp, fd);
8795 gen_store_fpr32(fph, fd);
a16336e4 8796#else
c905fdac
AJ
8797 gen_load_fpr32h(fph, fs);
8798 gen_load_fpr32(fp, ft);
8799 gen_store_fpr32(fph, fd);
8800 gen_store_fpr32h(fp, fd);
a16336e4
TS
8801#endif
8802 gen_set_label(l2);
c905fdac
AJ
8803 tcg_temp_free_i32(fp);
8804 tcg_temp_free_i32(fph);
a16336e4 8805 }
5a5012ec
TS
8806 opn = "alnv.ps";
8807 break;
8808 case OPC_MADD_S:
b8aa4598 8809 check_cop1x(ctx);
b6d96bed 8810 {
a7812ae4
PB
8811 TCGv_i32 fp0 = tcg_temp_new_i32();
8812 TCGv_i32 fp1 = tcg_temp_new_i32();
8813 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8814
8815 gen_load_fpr32(fp0, fs);
8816 gen_load_fpr32(fp1, ft);
8817 gen_load_fpr32(fp2, fr);
b3d6cd44 8818 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8819 tcg_temp_free_i32(fp0);
8820 tcg_temp_free_i32(fp1);
b6d96bed 8821 gen_store_fpr32(fp2, fd);
a7812ae4 8822 tcg_temp_free_i32(fp2);
b6d96bed 8823 }
5a5012ec
TS
8824 opn = "madd.s";
8825 break;
8826 case OPC_MADD_D:
b8aa4598
TS
8827 check_cop1x(ctx);
8828 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8829 {
a7812ae4
PB
8830 TCGv_i64 fp0 = tcg_temp_new_i64();
8831 TCGv_i64 fp1 = tcg_temp_new_i64();
8832 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8833
8834 gen_load_fpr64(ctx, fp0, fs);
8835 gen_load_fpr64(ctx, fp1, ft);
8836 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8837 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8838 tcg_temp_free_i64(fp0);
8839 tcg_temp_free_i64(fp1);
b6d96bed 8840 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8841 tcg_temp_free_i64(fp2);
b6d96bed 8842 }
5a5012ec
TS
8843 opn = "madd.d";
8844 break;
8845 case OPC_MADD_PS:
b8aa4598 8846 check_cp1_64bitmode(ctx);
b6d96bed 8847 {
a7812ae4
PB
8848 TCGv_i64 fp0 = tcg_temp_new_i64();
8849 TCGv_i64 fp1 = tcg_temp_new_i64();
8850 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8851
8852 gen_load_fpr64(ctx, fp0, fs);
8853 gen_load_fpr64(ctx, fp1, ft);
8854 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8855 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8856 tcg_temp_free_i64(fp0);
8857 tcg_temp_free_i64(fp1);
b6d96bed 8858 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8859 tcg_temp_free_i64(fp2);
b6d96bed 8860 }
5a5012ec
TS
8861 opn = "madd.ps";
8862 break;
8863 case OPC_MSUB_S:
b8aa4598 8864 check_cop1x(ctx);
b6d96bed 8865 {
a7812ae4
PB
8866 TCGv_i32 fp0 = tcg_temp_new_i32();
8867 TCGv_i32 fp1 = tcg_temp_new_i32();
8868 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8869
8870 gen_load_fpr32(fp0, fs);
8871 gen_load_fpr32(fp1, ft);
8872 gen_load_fpr32(fp2, fr);
b3d6cd44 8873 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8874 tcg_temp_free_i32(fp0);
8875 tcg_temp_free_i32(fp1);
b6d96bed 8876 gen_store_fpr32(fp2, fd);
a7812ae4 8877 tcg_temp_free_i32(fp2);
b6d96bed 8878 }
5a5012ec
TS
8879 opn = "msub.s";
8880 break;
8881 case OPC_MSUB_D:
b8aa4598
TS
8882 check_cop1x(ctx);
8883 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8884 {
a7812ae4
PB
8885 TCGv_i64 fp0 = tcg_temp_new_i64();
8886 TCGv_i64 fp1 = tcg_temp_new_i64();
8887 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8888
8889 gen_load_fpr64(ctx, fp0, fs);
8890 gen_load_fpr64(ctx, fp1, ft);
8891 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8892 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8893 tcg_temp_free_i64(fp0);
8894 tcg_temp_free_i64(fp1);
b6d96bed 8895 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8896 tcg_temp_free_i64(fp2);
b6d96bed 8897 }
5a5012ec
TS
8898 opn = "msub.d";
8899 break;
8900 case OPC_MSUB_PS:
b8aa4598 8901 check_cp1_64bitmode(ctx);
b6d96bed 8902 {
a7812ae4
PB
8903 TCGv_i64 fp0 = tcg_temp_new_i64();
8904 TCGv_i64 fp1 = tcg_temp_new_i64();
8905 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8906
8907 gen_load_fpr64(ctx, fp0, fs);
8908 gen_load_fpr64(ctx, fp1, ft);
8909 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8910 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8911 tcg_temp_free_i64(fp0);
8912 tcg_temp_free_i64(fp1);
b6d96bed 8913 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8914 tcg_temp_free_i64(fp2);
b6d96bed 8915 }
5a5012ec
TS
8916 opn = "msub.ps";
8917 break;
8918 case OPC_NMADD_S:
b8aa4598 8919 check_cop1x(ctx);
b6d96bed 8920 {
a7812ae4
PB
8921 TCGv_i32 fp0 = tcg_temp_new_i32();
8922 TCGv_i32 fp1 = tcg_temp_new_i32();
8923 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8924
8925 gen_load_fpr32(fp0, fs);
8926 gen_load_fpr32(fp1, ft);
8927 gen_load_fpr32(fp2, fr);
b3d6cd44 8928 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8929 tcg_temp_free_i32(fp0);
8930 tcg_temp_free_i32(fp1);
b6d96bed 8931 gen_store_fpr32(fp2, fd);
a7812ae4 8932 tcg_temp_free_i32(fp2);
b6d96bed 8933 }
5a5012ec
TS
8934 opn = "nmadd.s";
8935 break;
8936 case OPC_NMADD_D:
b8aa4598
TS
8937 check_cop1x(ctx);
8938 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8939 {
a7812ae4
PB
8940 TCGv_i64 fp0 = tcg_temp_new_i64();
8941 TCGv_i64 fp1 = tcg_temp_new_i64();
8942 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8943
8944 gen_load_fpr64(ctx, fp0, fs);
8945 gen_load_fpr64(ctx, fp1, ft);
8946 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8947 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8948 tcg_temp_free_i64(fp0);
8949 tcg_temp_free_i64(fp1);
b6d96bed 8950 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8951 tcg_temp_free_i64(fp2);
b6d96bed 8952 }
5a5012ec
TS
8953 opn = "nmadd.d";
8954 break;
8955 case OPC_NMADD_PS:
b8aa4598 8956 check_cp1_64bitmode(ctx);
b6d96bed 8957 {
a7812ae4
PB
8958 TCGv_i64 fp0 = tcg_temp_new_i64();
8959 TCGv_i64 fp1 = tcg_temp_new_i64();
8960 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8961
8962 gen_load_fpr64(ctx, fp0, fs);
8963 gen_load_fpr64(ctx, fp1, ft);
8964 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8965 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8966 tcg_temp_free_i64(fp0);
8967 tcg_temp_free_i64(fp1);
b6d96bed 8968 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8969 tcg_temp_free_i64(fp2);
b6d96bed 8970 }
5a5012ec
TS
8971 opn = "nmadd.ps";
8972 break;
8973 case OPC_NMSUB_S:
b8aa4598 8974 check_cop1x(ctx);
b6d96bed 8975 {
a7812ae4
PB
8976 TCGv_i32 fp0 = tcg_temp_new_i32();
8977 TCGv_i32 fp1 = tcg_temp_new_i32();
8978 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8979
8980 gen_load_fpr32(fp0, fs);
8981 gen_load_fpr32(fp1, ft);
8982 gen_load_fpr32(fp2, fr);
b3d6cd44 8983 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8984 tcg_temp_free_i32(fp0);
8985 tcg_temp_free_i32(fp1);
b6d96bed 8986 gen_store_fpr32(fp2, fd);
a7812ae4 8987 tcg_temp_free_i32(fp2);
b6d96bed 8988 }
5a5012ec
TS
8989 opn = "nmsub.s";
8990 break;
8991 case OPC_NMSUB_D:
b8aa4598
TS
8992 check_cop1x(ctx);
8993 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8994 {
a7812ae4
PB
8995 TCGv_i64 fp0 = tcg_temp_new_i64();
8996 TCGv_i64 fp1 = tcg_temp_new_i64();
8997 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8998
8999 gen_load_fpr64(ctx, fp0, fs);
9000 gen_load_fpr64(ctx, fp1, ft);
9001 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9002 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9003 tcg_temp_free_i64(fp0);
9004 tcg_temp_free_i64(fp1);
b6d96bed 9005 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9006 tcg_temp_free_i64(fp2);
b6d96bed 9007 }
5a5012ec
TS
9008 opn = "nmsub.d";
9009 break;
9010 case OPC_NMSUB_PS:
b8aa4598 9011 check_cp1_64bitmode(ctx);
b6d96bed 9012 {
a7812ae4
PB
9013 TCGv_i64 fp0 = tcg_temp_new_i64();
9014 TCGv_i64 fp1 = tcg_temp_new_i64();
9015 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9016
9017 gen_load_fpr64(ctx, fp0, fs);
9018 gen_load_fpr64(ctx, fp1, ft);
9019 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9020 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9021 tcg_temp_free_i64(fp0);
9022 tcg_temp_free_i64(fp1);
b6d96bed 9023 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9024 tcg_temp_free_i64(fp2);
b6d96bed 9025 }
5a5012ec
TS
9026 opn = "nmsub.ps";
9027 break;
923617a3
TS
9028 default:
9029 MIPS_INVAL(opn);
5a5012ec
TS
9030 generate_exception (ctx, EXCP_RI);
9031 return;
9032 }
2abf314d 9033 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9034 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9035 fregnames[fs], fregnames[ft]);
7a387fff
TS
9036}
9037
d75c135e 9038static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9039{
9040 TCGv t0;
9041
b3167288
RH
9042#if !defined(CONFIG_USER_ONLY)
9043 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9044 Therefore only check the ISA in system mode. */
d75c135e 9045 check_insn(ctx, ISA_MIPS32R2);
b3167288 9046#endif
26ebe468
NF
9047 t0 = tcg_temp_new();
9048
9049 switch (rd) {
9050 case 0:
9051 save_cpu_state(ctx, 1);
895c2d04 9052 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9053 gen_store_gpr(t0, rt);
9054 break;
9055 case 1:
9056 save_cpu_state(ctx, 1);
895c2d04 9057 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9058 gen_store_gpr(t0, rt);
9059 break;
9060 case 2:
9061 save_cpu_state(ctx, 1);
895c2d04 9062 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9063 gen_store_gpr(t0, rt);
9064 break;
9065 case 3:
9066 save_cpu_state(ctx, 1);
895c2d04 9067 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9068 gen_store_gpr(t0, rt);
9069 break;
9070 case 29:
9071#if defined(CONFIG_USER_ONLY)
7db13fae 9072 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
26ebe468
NF
9073 gen_store_gpr(t0, rt);
9074 break;
9075#else
9076 /* XXX: Some CPUs implement this in hardware.
9077 Not supported yet. */
9078#endif
9079 default: /* Invalid */
9080 MIPS_INVAL("rdhwr");
9081 generate_exception(ctx, EXCP_RI);
9082 break;
9083 }
9084 tcg_temp_free(t0);
9085}
9086
d75c135e 9087static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9088{
9089 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9090 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9091 /* Branches completion */
9092 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9093 ctx->bstate = BS_BRANCH;
9094 save_cpu_state(ctx, 0);
9095 /* FIXME: Need to clear can_do_io. */
364d4831 9096 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9097 case MIPS_HFLAG_B:
9098 /* unconditional branch */
9099 MIPS_DEBUG("unconditional branch");
364d4831
NF
9100 if (proc_hflags & MIPS_HFLAG_BX) {
9101 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9102 }
c9602061
NF
9103 gen_goto_tb(ctx, 0, ctx->btarget);
9104 break;
9105 case MIPS_HFLAG_BL:
9106 /* blikely taken case */
9107 MIPS_DEBUG("blikely branch taken");
9108 gen_goto_tb(ctx, 0, ctx->btarget);
9109 break;
9110 case MIPS_HFLAG_BC:
9111 /* Conditional branch */
9112 MIPS_DEBUG("conditional branch");
9113 {
9114 int l1 = gen_new_label();
9115
9116 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9117 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9118 gen_set_label(l1);
9119 gen_goto_tb(ctx, 0, ctx->btarget);
9120 }
9121 break;
9122 case MIPS_HFLAG_BR:
9123 /* unconditional branch to register */
9124 MIPS_DEBUG("branch to register");
d75c135e 9125 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9126 TCGv t0 = tcg_temp_new();
9127 TCGv_i32 t1 = tcg_temp_new_i32();
9128
9129 tcg_gen_andi_tl(t0, btarget, 0x1);
9130 tcg_gen_trunc_tl_i32(t1, t0);
9131 tcg_temp_free(t0);
9132 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9133 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9134 tcg_gen_or_i32(hflags, hflags, t1);
9135 tcg_temp_free_i32(t1);
9136
9137 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9138 } else {
9139 tcg_gen_mov_tl(cpu_PC, btarget);
9140 }
c9602061
NF
9141 if (ctx->singlestep_enabled) {
9142 save_cpu_state(ctx, 0);
895c2d04 9143 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9144 }
9145 tcg_gen_exit_tb(0);
9146 break;
9147 default:
9148 MIPS_DEBUG("unknown branch");
9149 break;
9150 }
9151 }
9152}
9153
7a387fff 9154/* ISA extensions (ASEs) */
6af0bf9c 9155/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9156
9157/* MIPS16 major opcodes */
9158enum {
9159 M16_OPC_ADDIUSP = 0x00,
9160 M16_OPC_ADDIUPC = 0x01,
9161 M16_OPC_B = 0x02,
9162 M16_OPC_JAL = 0x03,
9163 M16_OPC_BEQZ = 0x04,
9164 M16_OPC_BNEQZ = 0x05,
9165 M16_OPC_SHIFT = 0x06,
9166 M16_OPC_LD = 0x07,
9167 M16_OPC_RRIA = 0x08,
9168 M16_OPC_ADDIU8 = 0x09,
9169 M16_OPC_SLTI = 0x0a,
9170 M16_OPC_SLTIU = 0x0b,
9171 M16_OPC_I8 = 0x0c,
9172 M16_OPC_LI = 0x0d,
9173 M16_OPC_CMPI = 0x0e,
9174 M16_OPC_SD = 0x0f,
9175 M16_OPC_LB = 0x10,
9176 M16_OPC_LH = 0x11,
9177 M16_OPC_LWSP = 0x12,
9178 M16_OPC_LW = 0x13,
9179 M16_OPC_LBU = 0x14,
9180 M16_OPC_LHU = 0x15,
9181 M16_OPC_LWPC = 0x16,
9182 M16_OPC_LWU = 0x17,
9183 M16_OPC_SB = 0x18,
9184 M16_OPC_SH = 0x19,
9185 M16_OPC_SWSP = 0x1a,
9186 M16_OPC_SW = 0x1b,
9187 M16_OPC_RRR = 0x1c,
9188 M16_OPC_RR = 0x1d,
9189 M16_OPC_EXTEND = 0x1e,
9190 M16_OPC_I64 = 0x1f
9191};
9192
9193/* I8 funct field */
9194enum {
9195 I8_BTEQZ = 0x0,
9196 I8_BTNEZ = 0x1,
9197 I8_SWRASP = 0x2,
9198 I8_ADJSP = 0x3,
9199 I8_SVRS = 0x4,
9200 I8_MOV32R = 0x5,
9201 I8_MOVR32 = 0x7
9202};
9203
9204/* RRR f field */
9205enum {
9206 RRR_DADDU = 0x0,
9207 RRR_ADDU = 0x1,
9208 RRR_DSUBU = 0x2,
9209 RRR_SUBU = 0x3
9210};
9211
9212/* RR funct field */
9213enum {
9214 RR_JR = 0x00,
9215 RR_SDBBP = 0x01,
9216 RR_SLT = 0x02,
9217 RR_SLTU = 0x03,
9218 RR_SLLV = 0x04,
9219 RR_BREAK = 0x05,
9220 RR_SRLV = 0x06,
9221 RR_SRAV = 0x07,
9222 RR_DSRL = 0x08,
9223 RR_CMP = 0x0a,
9224 RR_NEG = 0x0b,
9225 RR_AND = 0x0c,
9226 RR_OR = 0x0d,
9227 RR_XOR = 0x0e,
9228 RR_NOT = 0x0f,
9229 RR_MFHI = 0x10,
9230 RR_CNVT = 0x11,
9231 RR_MFLO = 0x12,
9232 RR_DSRA = 0x13,
9233 RR_DSLLV = 0x14,
9234 RR_DSRLV = 0x16,
9235 RR_DSRAV = 0x17,
9236 RR_MULT = 0x18,
9237 RR_MULTU = 0x19,
9238 RR_DIV = 0x1a,
9239 RR_DIVU = 0x1b,
9240 RR_DMULT = 0x1c,
9241 RR_DMULTU = 0x1d,
9242 RR_DDIV = 0x1e,
9243 RR_DDIVU = 0x1f
9244};
9245
9246/* I64 funct field */
9247enum {
9248 I64_LDSP = 0x0,
9249 I64_SDSP = 0x1,
9250 I64_SDRASP = 0x2,
9251 I64_DADJSP = 0x3,
9252 I64_LDPC = 0x4,
364d4831 9253 I64_DADDIU5 = 0x5,
6ea219d0
NF
9254 I64_DADDIUPC = 0x6,
9255 I64_DADDIUSP = 0x7
9256};
9257
9258/* RR ry field for CNVT */
9259enum {
9260 RR_RY_CNVT_ZEB = 0x0,
9261 RR_RY_CNVT_ZEH = 0x1,
9262 RR_RY_CNVT_ZEW = 0x2,
9263 RR_RY_CNVT_SEB = 0x4,
9264 RR_RY_CNVT_SEH = 0x5,
9265 RR_RY_CNVT_SEW = 0x6,
9266};
9267
364d4831
NF
9268static int xlat (int r)
9269{
9270 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9271
9272 return map[r];
9273}
9274
9275static void gen_mips16_save (DisasContext *ctx,
9276 int xsregs, int aregs,
9277 int do_ra, int do_s0, int do_s1,
9278 int framesize)
9279{
9280 TCGv t0 = tcg_temp_new();
9281 TCGv t1 = tcg_temp_new();
9282 int args, astatic;
9283
9284 switch (aregs) {
9285 case 0:
9286 case 1:
9287 case 2:
9288 case 3:
9289 case 11:
9290 args = 0;
9291 break;
9292 case 4:
9293 case 5:
9294 case 6:
9295 case 7:
9296 args = 1;
9297 break;
9298 case 8:
9299 case 9:
9300 case 10:
9301 args = 2;
9302 break;
9303 case 12:
9304 case 13:
9305 args = 3;
9306 break;
9307 case 14:
9308 args = 4;
9309 break;
9310 default:
9311 generate_exception(ctx, EXCP_RI);
9312 return;
9313 }
9314
9315 switch (args) {
9316 case 4:
9317 gen_base_offset_addr(ctx, t0, 29, 12);
9318 gen_load_gpr(t1, 7);
2910c6cb 9319 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9320 /* Fall through */
9321 case 3:
9322 gen_base_offset_addr(ctx, t0, 29, 8);
9323 gen_load_gpr(t1, 6);
2910c6cb 9324 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9325 /* Fall through */
9326 case 2:
9327 gen_base_offset_addr(ctx, t0, 29, 4);
9328 gen_load_gpr(t1, 5);
2910c6cb 9329 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9330 /* Fall through */
9331 case 1:
9332 gen_base_offset_addr(ctx, t0, 29, 0);
9333 gen_load_gpr(t1, 4);
2910c6cb 9334 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9335 }
9336
9337 gen_load_gpr(t0, 29);
9338
9339#define DECR_AND_STORE(reg) do { \
9340 tcg_gen_subi_tl(t0, t0, 4); \
9341 gen_load_gpr(t1, reg); \
2910c6cb 9342 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
364d4831
NF
9343 } while (0)
9344
9345 if (do_ra) {
9346 DECR_AND_STORE(31);
9347 }
9348
9349 switch (xsregs) {
9350 case 7:
9351 DECR_AND_STORE(30);
9352 /* Fall through */
9353 case 6:
9354 DECR_AND_STORE(23);
9355 /* Fall through */
9356 case 5:
9357 DECR_AND_STORE(22);
9358 /* Fall through */
9359 case 4:
9360 DECR_AND_STORE(21);
9361 /* Fall through */
9362 case 3:
9363 DECR_AND_STORE(20);
9364 /* Fall through */
9365 case 2:
9366 DECR_AND_STORE(19);
9367 /* Fall through */
9368 case 1:
9369 DECR_AND_STORE(18);
9370 }
9371
9372 if (do_s1) {
9373 DECR_AND_STORE(17);
9374 }
9375 if (do_s0) {
9376 DECR_AND_STORE(16);
9377 }
9378
9379 switch (aregs) {
9380 case 0:
9381 case 4:
9382 case 8:
9383 case 12:
9384 case 14:
9385 astatic = 0;
9386 break;
9387 case 1:
9388 case 5:
9389 case 9:
9390 case 13:
9391 astatic = 1;
9392 break;
9393 case 2:
9394 case 6:
9395 case 10:
9396 astatic = 2;
9397 break;
9398 case 3:
9399 case 7:
9400 astatic = 3;
9401 break;
9402 case 11:
9403 astatic = 4;
9404 break;
9405 default:
9406 generate_exception(ctx, EXCP_RI);
9407 return;
9408 }
9409
9410 if (astatic > 0) {
9411 DECR_AND_STORE(7);
9412 if (astatic > 1) {
9413 DECR_AND_STORE(6);
9414 if (astatic > 2) {
9415 DECR_AND_STORE(5);
9416 if (astatic > 3) {
9417 DECR_AND_STORE(4);
9418 }
9419 }
9420 }
9421 }
9422#undef DECR_AND_STORE
9423
9424 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9425 tcg_temp_free(t0);
9426 tcg_temp_free(t1);
9427}
9428
9429static void gen_mips16_restore (DisasContext *ctx,
9430 int xsregs, int aregs,
9431 int do_ra, int do_s0, int do_s1,
9432 int framesize)
9433{
9434 int astatic;
9435 TCGv t0 = tcg_temp_new();
9436 TCGv t1 = tcg_temp_new();
9437
9438 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9439
2910c6cb
AJ
9440#define DECR_AND_LOAD(reg) do { \
9441 tcg_gen_subi_tl(t0, t0, 4); \
17e8fef1 9442 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
2910c6cb 9443 gen_store_gpr(t1, reg); \
364d4831
NF
9444 } while (0)
9445
9446 if (do_ra) {
9447 DECR_AND_LOAD(31);
9448 }
9449
9450 switch (xsregs) {
9451 case 7:
9452 DECR_AND_LOAD(30);
9453 /* Fall through */
9454 case 6:
9455 DECR_AND_LOAD(23);
9456 /* Fall through */
9457 case 5:
9458 DECR_AND_LOAD(22);
9459 /* Fall through */
9460 case 4:
9461 DECR_AND_LOAD(21);
9462 /* Fall through */
9463 case 3:
9464 DECR_AND_LOAD(20);
9465 /* Fall through */
9466 case 2:
9467 DECR_AND_LOAD(19);
9468 /* Fall through */
9469 case 1:
9470 DECR_AND_LOAD(18);
9471 }
9472
9473 if (do_s1) {
9474 DECR_AND_LOAD(17);
9475 }
9476 if (do_s0) {
9477 DECR_AND_LOAD(16);
9478 }
9479
9480 switch (aregs) {
9481 case 0:
9482 case 4:
9483 case 8:
9484 case 12:
9485 case 14:
9486 astatic = 0;
9487 break;
9488 case 1:
9489 case 5:
9490 case 9:
9491 case 13:
9492 astatic = 1;
9493 break;
9494 case 2:
9495 case 6:
9496 case 10:
9497 astatic = 2;
9498 break;
9499 case 3:
9500 case 7:
9501 astatic = 3;
9502 break;
9503 case 11:
9504 astatic = 4;
9505 break;
9506 default:
9507 generate_exception(ctx, EXCP_RI);
9508 return;
9509 }
9510
9511 if (astatic > 0) {
9512 DECR_AND_LOAD(7);
9513 if (astatic > 1) {
9514 DECR_AND_LOAD(6);
9515 if (astatic > 2) {
9516 DECR_AND_LOAD(5);
9517 if (astatic > 3) {
9518 DECR_AND_LOAD(4);
9519 }
9520 }
9521 }
9522 }
9523#undef DECR_AND_LOAD
9524
9525 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9526 tcg_temp_free(t0);
9527 tcg_temp_free(t1);
9528}
9529
9530static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9531 int is_64_bit, int extended)
9532{
9533 TCGv t0;
9534
9535 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9536 generate_exception(ctx, EXCP_RI);
9537 return;
9538 }
9539
9540 t0 = tcg_temp_new();
9541
9542 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9543 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9544 if (!is_64_bit) {
9545 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9546 }
9547
9548 tcg_temp_free(t0);
9549}
9550
9551#if defined(TARGET_MIPS64)
d75c135e 9552static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9553 int ry, int funct, int16_t offset,
9554 int extended)
9555{
9556 switch (funct) {
9557 case I64_LDSP:
9558 check_mips_64(ctx);
9559 offset = extended ? offset : offset << 3;
d75c135e 9560 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9561 break;
9562 case I64_SDSP:
9563 check_mips_64(ctx);
9564 offset = extended ? offset : offset << 3;
5c13fdfd 9565 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9566 break;
9567 case I64_SDRASP:
9568 check_mips_64(ctx);
9569 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9570 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9571 break;
9572 case I64_DADJSP:
9573 check_mips_64(ctx);
9574 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9575 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9576 break;
9577 case I64_LDPC:
9578 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9579 generate_exception(ctx, EXCP_RI);
9580 } else {
9581 offset = extended ? offset : offset << 3;
d75c135e 9582 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9583 }
9584 break;
9585 case I64_DADDIU5:
9586 check_mips_64(ctx);
9587 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9588 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9589 break;
9590 case I64_DADDIUPC:
9591 check_mips_64(ctx);
9592 offset = extended ? offset : offset << 2;
9593 gen_addiupc(ctx, ry, offset, 1, extended);
9594 break;
9595 case I64_DADDIUSP:
9596 check_mips_64(ctx);
9597 offset = extended ? offset : offset << 2;
d75c135e 9598 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9599 break;
9600 }
9601}
9602#endif
9603
7db13fae 9604static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9605 int *is_branch)
9606{
895c2d04 9607 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9608 int op, rx, ry, funct, sa;
9609 int16_t imm, offset;
9610
9611 ctx->opcode = (ctx->opcode << 16) | extend;
9612 op = (ctx->opcode >> 11) & 0x1f;
9613 sa = (ctx->opcode >> 22) & 0x1f;
9614 funct = (ctx->opcode >> 8) & 0x7;
9615 rx = xlat((ctx->opcode >> 8) & 0x7);
9616 ry = xlat((ctx->opcode >> 5) & 0x7);
9617 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9618 | ((ctx->opcode >> 21) & 0x3f) << 5
9619 | (ctx->opcode & 0x1f));
9620
9621 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9622 counterparts. */
9623 switch (op) {
9624 case M16_OPC_ADDIUSP:
d75c135e 9625 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9626 break;
9627 case M16_OPC_ADDIUPC:
9628 gen_addiupc(ctx, rx, imm, 0, 1);
9629 break;
9630 case M16_OPC_B:
9631 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9632 /* No delay slot, so just process as a normal instruction */
9633 break;
9634 case M16_OPC_BEQZ:
9635 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9636 /* No delay slot, so just process as a normal instruction */
9637 break;
9638 case M16_OPC_BNEQZ:
9639 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9640 /* No delay slot, so just process as a normal instruction */
9641 break;
9642 case M16_OPC_SHIFT:
9643 switch (ctx->opcode & 0x3) {
9644 case 0x0:
d75c135e 9645 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9646 break;
9647 case 0x1:
9648#if defined(TARGET_MIPS64)
9649 check_mips_64(ctx);
d75c135e 9650 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9651#else
9652 generate_exception(ctx, EXCP_RI);
9653#endif
9654 break;
9655 case 0x2:
d75c135e 9656 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9657 break;
9658 case 0x3:
d75c135e 9659 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9660 break;
9661 }
9662 break;
9663#if defined(TARGET_MIPS64)
9664 case M16_OPC_LD:
9665 check_mips_64(ctx);
d75c135e 9666 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9667 break;
9668#endif
9669 case M16_OPC_RRIA:
9670 imm = ctx->opcode & 0xf;
9671 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9672 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9673 imm = (int16_t) (imm << 1) >> 1;
9674 if ((ctx->opcode >> 4) & 0x1) {
9675#if defined(TARGET_MIPS64)
9676 check_mips_64(ctx);
d75c135e 9677 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9678#else
9679 generate_exception(ctx, EXCP_RI);
9680#endif
9681 } else {
d75c135e 9682 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9683 }
9684 break;
9685 case M16_OPC_ADDIU8:
d75c135e 9686 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9687 break;
9688 case M16_OPC_SLTI:
d75c135e 9689 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9690 break;
9691 case M16_OPC_SLTIU:
d75c135e 9692 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9693 break;
9694 case M16_OPC_I8:
9695 switch (funct) {
9696 case I8_BTEQZ:
9697 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9698 break;
9699 case I8_BTNEZ:
9700 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9701 break;
9702 case I8_SWRASP:
5c13fdfd 9703 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9704 break;
9705 case I8_ADJSP:
d75c135e 9706 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
9707 break;
9708 case I8_SVRS:
9709 {
9710 int xsregs = (ctx->opcode >> 24) & 0x7;
9711 int aregs = (ctx->opcode >> 16) & 0xf;
9712 int do_ra = (ctx->opcode >> 6) & 0x1;
9713 int do_s0 = (ctx->opcode >> 5) & 0x1;
9714 int do_s1 = (ctx->opcode >> 4) & 0x1;
9715 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9716 | (ctx->opcode & 0xf)) << 3;
9717
9718 if (ctx->opcode & (1 << 7)) {
9719 gen_mips16_save(ctx, xsregs, aregs,
9720 do_ra, do_s0, do_s1,
9721 framesize);
9722 } else {
9723 gen_mips16_restore(ctx, xsregs, aregs,
9724 do_ra, do_s0, do_s1,
9725 framesize);
9726 }
9727 }
9728 break;
9729 default:
9730 generate_exception(ctx, EXCP_RI);
9731 break;
9732 }
9733 break;
9734 case M16_OPC_LI:
9735 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9736 break;
9737 case M16_OPC_CMPI:
9738 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9739 break;
9740#if defined(TARGET_MIPS64)
9741 case M16_OPC_SD:
5c13fdfd 9742 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9743 break;
9744#endif
9745 case M16_OPC_LB:
d75c135e 9746 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9747 break;
9748 case M16_OPC_LH:
d75c135e 9749 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9750 break;
9751 case M16_OPC_LWSP:
d75c135e 9752 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9753 break;
9754 case M16_OPC_LW:
d75c135e 9755 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9756 break;
9757 case M16_OPC_LBU:
d75c135e 9758 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9759 break;
9760 case M16_OPC_LHU:
d75c135e 9761 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9762 break;
9763 case M16_OPC_LWPC:
d75c135e 9764 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9765 break;
9766#if defined(TARGET_MIPS64)
9767 case M16_OPC_LWU:
d75c135e 9768 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9769 break;
9770#endif
9771 case M16_OPC_SB:
5c13fdfd 9772 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9773 break;
9774 case M16_OPC_SH:
5c13fdfd 9775 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9776 break;
9777 case M16_OPC_SWSP:
5c13fdfd 9778 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9779 break;
9780 case M16_OPC_SW:
5c13fdfd 9781 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9782 break;
9783#if defined(TARGET_MIPS64)
9784 case M16_OPC_I64:
d75c135e 9785 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
9786 break;
9787#endif
9788 default:
9789 generate_exception(ctx, EXCP_RI);
9790 break;
9791 }
9792
9793 return 4;
9794}
9795
7db13fae 9796static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9797 int *is_branch)
9798{
9799 int rx, ry;
9800 int sa;
9801 int op, cnvt_op, op1, offset;
9802 int funct;
9803 int n_bytes;
9804
9805 op = (ctx->opcode >> 11) & 0x1f;
9806 sa = (ctx->opcode >> 2) & 0x7;
9807 sa = sa == 0 ? 8 : sa;
9808 rx = xlat((ctx->opcode >> 8) & 0x7);
9809 cnvt_op = (ctx->opcode >> 5) & 0x7;
9810 ry = xlat((ctx->opcode >> 5) & 0x7);
9811 op1 = offset = ctx->opcode & 0x1f;
9812
9813 n_bytes = 2;
9814
9815 switch (op) {
9816 case M16_OPC_ADDIUSP:
9817 {
9818 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9819
d75c135e 9820 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9821 }
9822 break;
9823 case M16_OPC_ADDIUPC:
9824 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9825 break;
9826 case M16_OPC_B:
9827 offset = (ctx->opcode & 0x7ff) << 1;
9828 offset = (int16_t)(offset << 4) >> 4;
9829 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9830 /* No delay slot, so just process as a normal instruction */
9831 break;
9832 case M16_OPC_JAL:
895c2d04 9833 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9834 offset = (((ctx->opcode & 0x1f) << 21)
9835 | ((ctx->opcode >> 5) & 0x1f) << 16
9836 | offset) << 2;
620e48f6 9837 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9838 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9839 n_bytes = 4;
9840 *is_branch = 1;
9841 break;
9842 case M16_OPC_BEQZ:
9843 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9844 /* No delay slot, so just process as a normal instruction */
9845 break;
9846 case M16_OPC_BNEQZ:
9847 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9848 /* No delay slot, so just process as a normal instruction */
9849 break;
9850 case M16_OPC_SHIFT:
9851 switch (ctx->opcode & 0x3) {
9852 case 0x0:
d75c135e 9853 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9854 break;
9855 case 0x1:
9856#if defined(TARGET_MIPS64)
9857 check_mips_64(ctx);
d75c135e 9858 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9859#else
9860 generate_exception(ctx, EXCP_RI);
9861#endif
9862 break;
9863 case 0x2:
d75c135e 9864 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9865 break;
9866 case 0x3:
d75c135e 9867 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9868 break;
9869 }
9870 break;
9871#if defined(TARGET_MIPS64)
9872 case M16_OPC_LD:
9873 check_mips_64(ctx);
d75c135e 9874 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9875 break;
9876#endif
9877 case M16_OPC_RRIA:
9878 {
9879 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9880
9881 if ((ctx->opcode >> 4) & 1) {
9882#if defined(TARGET_MIPS64)
9883 check_mips_64(ctx);
d75c135e 9884 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9885#else
9886 generate_exception(ctx, EXCP_RI);
9887#endif
9888 } else {
d75c135e 9889 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9890 }
9891 }
9892 break;
9893 case M16_OPC_ADDIU8:
9894 {
9895 int16_t imm = (int8_t) ctx->opcode;
9896
d75c135e 9897 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9898 }
9899 break;
9900 case M16_OPC_SLTI:
9901 {
9902 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9903 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9904 }
9905 break;
9906 case M16_OPC_SLTIU:
9907 {
9908 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9909 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9910 }
9911 break;
9912 case M16_OPC_I8:
9913 {
9914 int reg32;
9915
9916 funct = (ctx->opcode >> 8) & 0x7;
9917 switch (funct) {
9918 case I8_BTEQZ:
9919 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9920 ((int8_t)ctx->opcode) << 1);
9921 break;
9922 case I8_BTNEZ:
9923 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9924 ((int8_t)ctx->opcode) << 1);
9925 break;
9926 case I8_SWRASP:
5c13fdfd 9927 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9928 break;
9929 case I8_ADJSP:
d75c135e 9930 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
9931 ((int8_t)ctx->opcode) << 3);
9932 break;
9933 case I8_SVRS:
9934 {
9935 int do_ra = ctx->opcode & (1 << 6);
9936 int do_s0 = ctx->opcode & (1 << 5);
9937 int do_s1 = ctx->opcode & (1 << 4);
9938 int framesize = ctx->opcode & 0xf;
9939
9940 if (framesize == 0) {
9941 framesize = 128;
9942 } else {
9943 framesize = framesize << 3;
9944 }
9945
9946 if (ctx->opcode & (1 << 7)) {
9947 gen_mips16_save(ctx, 0, 0,
9948 do_ra, do_s0, do_s1, framesize);
9949 } else {
9950 gen_mips16_restore(ctx, 0, 0,
9951 do_ra, do_s0, do_s1, framesize);
9952 }
9953 }
9954 break;
9955 case I8_MOV32R:
9956 {
9957 int rz = xlat(ctx->opcode & 0x7);
9958
9959 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9960 ((ctx->opcode >> 5) & 0x7);
d75c135e 9961 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
9962 }
9963 break;
9964 case I8_MOVR32:
9965 reg32 = ctx->opcode & 0x1f;
d75c135e 9966 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
9967 break;
9968 default:
9969 generate_exception(ctx, EXCP_RI);
9970 break;
9971 }
9972 }
9973 break;
9974 case M16_OPC_LI:
9975 {
9976 int16_t imm = (uint8_t) ctx->opcode;
9977
d75c135e 9978 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
9979 }
9980 break;
9981 case M16_OPC_CMPI:
9982 {
9983 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9984 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
9985 }
9986 break;
9987#if defined(TARGET_MIPS64)
9988 case M16_OPC_SD:
9989 check_mips_64(ctx);
5c13fdfd 9990 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
9991 break;
9992#endif
9993 case M16_OPC_LB:
d75c135e 9994 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9995 break;
9996 case M16_OPC_LH:
d75c135e 9997 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
9998 break;
9999 case M16_OPC_LWSP:
d75c135e 10000 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10001 break;
10002 case M16_OPC_LW:
d75c135e 10003 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10004 break;
10005 case M16_OPC_LBU:
d75c135e 10006 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10007 break;
10008 case M16_OPC_LHU:
d75c135e 10009 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10010 break;
10011 case M16_OPC_LWPC:
d75c135e 10012 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10013 break;
10014#if defined (TARGET_MIPS64)
10015 case M16_OPC_LWU:
10016 check_mips_64(ctx);
d75c135e 10017 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10018 break;
10019#endif
10020 case M16_OPC_SB:
5c13fdfd 10021 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10022 break;
10023 case M16_OPC_SH:
5c13fdfd 10024 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10025 break;
10026 case M16_OPC_SWSP:
5c13fdfd 10027 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10028 break;
10029 case M16_OPC_SW:
5c13fdfd 10030 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10031 break;
10032 case M16_OPC_RRR:
10033 {
10034 int rz = xlat((ctx->opcode >> 2) & 0x7);
10035 int mips32_op;
10036
10037 switch (ctx->opcode & 0x3) {
10038 case RRR_ADDU:
10039 mips32_op = OPC_ADDU;
10040 break;
10041 case RRR_SUBU:
10042 mips32_op = OPC_SUBU;
10043 break;
10044#if defined(TARGET_MIPS64)
10045 case RRR_DADDU:
10046 mips32_op = OPC_DADDU;
10047 check_mips_64(ctx);
10048 break;
10049 case RRR_DSUBU:
10050 mips32_op = OPC_DSUBU;
10051 check_mips_64(ctx);
10052 break;
10053#endif
10054 default:
10055 generate_exception(ctx, EXCP_RI);
10056 goto done;
10057 }
10058
d75c135e 10059 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10060 done:
10061 ;
10062 }
10063 break;
10064 case M16_OPC_RR:
10065 switch (op1) {
10066 case RR_JR:
10067 {
10068 int nd = (ctx->opcode >> 7) & 0x1;
10069 int link = (ctx->opcode >> 6) & 0x1;
10070 int ra = (ctx->opcode >> 5) & 0x1;
10071
10072 if (link) {
620e48f6 10073 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10074 } else {
10075 op = OPC_JR;
10076 }
10077
10078 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10079 if (!nd) {
10080 *is_branch = 1;
10081 }
10082 }
10083 break;
10084 case RR_SDBBP:
10085 /* XXX: not clear which exception should be raised
10086 * when in debug mode...
10087 */
d75c135e 10088 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10089 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10090 generate_exception(ctx, EXCP_DBp);
10091 } else {
10092 generate_exception(ctx, EXCP_DBp);
10093 }
10094 break;
10095 case RR_SLT:
d75c135e 10096 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10097 break;
10098 case RR_SLTU:
d75c135e 10099 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10100 break;
10101 case RR_BREAK:
10102 generate_exception(ctx, EXCP_BREAK);
10103 break;
10104 case RR_SLLV:
d75c135e 10105 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10106 break;
10107 case RR_SRLV:
d75c135e 10108 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10109 break;
10110 case RR_SRAV:
d75c135e 10111 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10112 break;
10113#if defined (TARGET_MIPS64)
10114 case RR_DSRL:
10115 check_mips_64(ctx);
d75c135e 10116 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10117 break;
10118#endif
10119 case RR_CMP:
d75c135e 10120 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10121 break;
10122 case RR_NEG:
d75c135e 10123 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10124 break;
10125 case RR_AND:
d75c135e 10126 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10127 break;
10128 case RR_OR:
d75c135e 10129 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10130 break;
10131 case RR_XOR:
d75c135e 10132 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10133 break;
10134 case RR_NOT:
d75c135e 10135 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10136 break;
10137 case RR_MFHI:
10138 gen_HILO(ctx, OPC_MFHI, rx);
10139 break;
10140 case RR_CNVT:
10141 switch (cnvt_op) {
10142 case RR_RY_CNVT_ZEB:
10143 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10144 break;
10145 case RR_RY_CNVT_ZEH:
10146 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10147 break;
10148 case RR_RY_CNVT_SEB:
10149 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10150 break;
10151 case RR_RY_CNVT_SEH:
10152 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10153 break;
10154#if defined (TARGET_MIPS64)
10155 case RR_RY_CNVT_ZEW:
10156 check_mips_64(ctx);
10157 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10158 break;
10159 case RR_RY_CNVT_SEW:
10160 check_mips_64(ctx);
10161 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10162 break;
10163#endif
10164 default:
10165 generate_exception(ctx, EXCP_RI);
10166 break;
10167 }
10168 break;
10169 case RR_MFLO:
10170 gen_HILO(ctx, OPC_MFLO, rx);
10171 break;
10172#if defined (TARGET_MIPS64)
10173 case RR_DSRA:
10174 check_mips_64(ctx);
d75c135e 10175 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10176 break;
10177 case RR_DSLLV:
10178 check_mips_64(ctx);
d75c135e 10179 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10180 break;
10181 case RR_DSRLV:
10182 check_mips_64(ctx);
d75c135e 10183 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10184 break;
10185 case RR_DSRAV:
10186 check_mips_64(ctx);
d75c135e 10187 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10188 break;
10189#endif
10190 case RR_MULT:
10191 gen_muldiv(ctx, OPC_MULT, rx, ry);
10192 break;
10193 case RR_MULTU:
10194 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10195 break;
10196 case RR_DIV:
10197 gen_muldiv(ctx, OPC_DIV, rx, ry);
10198 break;
10199 case RR_DIVU:
10200 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10201 break;
10202#if defined (TARGET_MIPS64)
10203 case RR_DMULT:
10204 check_mips_64(ctx);
10205 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10206 break;
10207 case RR_DMULTU:
10208 check_mips_64(ctx);
10209 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10210 break;
10211 case RR_DDIV:
10212 check_mips_64(ctx);
10213 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10214 break;
10215 case RR_DDIVU:
10216 check_mips_64(ctx);
10217 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10218 break;
10219#endif
10220 default:
10221 generate_exception(ctx, EXCP_RI);
10222 break;
10223 }
10224 break;
10225 case M16_OPC_EXTEND:
10226 decode_extended_mips16_opc(env, ctx, is_branch);
10227 n_bytes = 4;
10228 break;
10229#if defined(TARGET_MIPS64)
10230 case M16_OPC_I64:
10231 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10232 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10233 break;
10234#endif
10235 default:
10236 generate_exception(ctx, EXCP_RI);
10237 break;
10238 }
10239
10240 return n_bytes;
10241}
10242
211da992 10243/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10244
211da992
WRC
10245/*
10246 * microMIPS32/microMIPS64 major opcodes
10247 *
10248 * 1. MIPS Architecture for Programmers Volume II-B:
10249 * The microMIPS32 Instruction Set (Revision 3.05)
10250 *
10251 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10252 *
10253 * 2. MIPS Architecture For Programmers Volume II-A:
10254 * The MIPS64 Instruction Set (Revision 3.51)
10255 */
6af0bf9c 10256
3c824109
NF
10257enum {
10258 POOL32A = 0x00,
10259 POOL16A = 0x01,
10260 LBU16 = 0x02,
10261 MOVE16 = 0x03,
10262 ADDI32 = 0x04,
10263 LBU32 = 0x05,
10264 SB32 = 0x06,
10265 LB32 = 0x07,
10266
10267 POOL32B = 0x08,
10268 POOL16B = 0x09,
10269 LHU16 = 0x0a,
10270 ANDI16 = 0x0b,
10271 ADDIU32 = 0x0c,
10272 LHU32 = 0x0d,
10273 SH32 = 0x0e,
10274 LH32 = 0x0f,
10275
10276 POOL32I = 0x10,
10277 POOL16C = 0x11,
10278 LWSP16 = 0x12,
10279 POOL16D = 0x13,
10280 ORI32 = 0x14,
10281 POOL32F = 0x15,
211da992
WRC
10282 POOL32S = 0x16, /* MIPS64 */
10283 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10284
211da992 10285 /* 0x1f is reserved */
3c824109
NF
10286 POOL32C = 0x18,
10287 LWGP16 = 0x19,
10288 LW16 = 0x1a,
10289 POOL16E = 0x1b,
10290 XORI32 = 0x1c,
10291 JALS32 = 0x1d,
10292 ADDIUPC = 0x1e,
3c824109
NF
10293
10294 /* 0x20 is reserved */
10295 RES_20 = 0x20,
10296 POOL16F = 0x21,
10297 SB16 = 0x22,
10298 BEQZ16 = 0x23,
10299 SLTI32 = 0x24,
10300 BEQ32 = 0x25,
10301 SWC132 = 0x26,
10302 LWC132 = 0x27,
10303
10304 /* 0x28 and 0x29 are reserved */
10305 RES_28 = 0x28,
10306 RES_29 = 0x29,
10307 SH16 = 0x2a,
10308 BNEZ16 = 0x2b,
10309 SLTIU32 = 0x2c,
10310 BNE32 = 0x2d,
10311 SDC132 = 0x2e,
10312 LDC132 = 0x2f,
10313
10314 /* 0x30 and 0x31 are reserved */
10315 RES_30 = 0x30,
10316 RES_31 = 0x31,
10317 SWSP16 = 0x32,
10318 B16 = 0x33,
10319 ANDI32 = 0x34,
10320 J32 = 0x35,
211da992
WRC
10321 SD32 = 0x36, /* MIPS64 */
10322 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10323
10324 /* 0x38 and 0x39 are reserved */
10325 RES_38 = 0x38,
10326 RES_39 = 0x39,
10327 SW16 = 0x3a,
10328 LI16 = 0x3b,
10329 JALX32 = 0x3c,
10330 JAL32 = 0x3d,
10331 SW32 = 0x3e,
10332 LW32 = 0x3f
10333};
10334
10335/* POOL32A encoding of minor opcode field */
10336
10337enum {
10338 /* These opcodes are distinguished only by bits 9..6; those bits are
10339 * what are recorded below. */
10340 SLL32 = 0x0,
10341 SRL32 = 0x1,
10342 SRA = 0x2,
10343 ROTR = 0x3,
10344
10345 SLLV = 0x0,
10346 SRLV = 0x1,
10347 SRAV = 0x2,
10348 ROTRV = 0x3,
10349 ADD = 0x4,
10350 ADDU32 = 0x5,
10351 SUB = 0x6,
10352 SUBU32 = 0x7,
10353 MUL = 0x8,
10354 AND = 0x9,
10355 OR32 = 0xa,
10356 NOR = 0xb,
10357 XOR32 = 0xc,
10358 SLT = 0xd,
10359 SLTU = 0xe,
10360
10361 MOVN = 0x0,
10362 MOVZ = 0x1,
10363 LWXS = 0x4,
10364
10365 /* The following can be distinguished by their lower 6 bits. */
10366 INS = 0x0c,
10367 EXT = 0x2c,
10368 POOL32AXF = 0x3c
10369};
10370
10371/* POOL32AXF encoding of minor opcode field extension */
10372
d132c79f
WRC
10373/*
10374 * 1. MIPS Architecture for Programmers Volume II-B:
10375 * The microMIPS32 Instruction Set (Revision 3.05)
10376 *
10377 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10378 *
10379 * 2. MIPS Architecture for Programmers VolumeIV-e:
10380 * The MIPS DSP Application-Specific Extension
10381 * to the microMIPS32 Architecture (Revision 2.34)
10382 *
10383 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10384 */
10385
3c824109
NF
10386enum {
10387 /* bits 11..6 */
10388 TEQ = 0x00,
10389 TGE = 0x08,
10390 TGEU = 0x10,
10391 TLT = 0x20,
10392 TLTU = 0x28,
10393 TNE = 0x30,
10394
10395 MFC0 = 0x03,
10396 MTC0 = 0x0b,
10397
d132c79f
WRC
10398 /* begin of microMIPS32 DSP */
10399
3c824109
NF
10400 /* bits 13..12 for 0x01 */
10401 MFHI_ACC = 0x0,
10402 MFLO_ACC = 0x1,
10403 MTHI_ACC = 0x2,
10404 MTLO_ACC = 0x3,
10405
10406 /* bits 13..12 for 0x2a */
10407 MADD_ACC = 0x0,
10408 MADDU_ACC = 0x1,
10409 MSUB_ACC = 0x2,
10410 MSUBU_ACC = 0x3,
10411
10412 /* bits 13..12 for 0x32 */
10413 MULT_ACC = 0x0,
6801038b 10414 MULTU_ACC = 0x1,
3c824109 10415
d132c79f
WRC
10416 /* end of microMIPS32 DSP */
10417
3c824109
NF
10418 /* bits 15..12 for 0x2c */
10419 SEB = 0x2,
10420 SEH = 0x3,
10421 CLO = 0x4,
10422 CLZ = 0x5,
10423 RDHWR = 0x6,
10424 WSBH = 0x7,
10425 MULT = 0x8,
10426 MULTU = 0x9,
10427 DIV = 0xa,
10428 DIVU = 0xb,
10429 MADD = 0xc,
10430 MADDU = 0xd,
10431 MSUB = 0xe,
10432 MSUBU = 0xf,
10433
10434 /* bits 15..12 for 0x34 */
10435 MFC2 = 0x4,
10436 MTC2 = 0x5,
10437 MFHC2 = 0x8,
10438 MTHC2 = 0x9,
10439 CFC2 = 0xc,
10440 CTC2 = 0xd,
10441
10442 /* bits 15..12 for 0x3c */
10443 JALR = 0x0,
10444 JR = 0x0, /* alias */
10445 JALR_HB = 0x1,
10446 JALRS = 0x4,
10447 JALRS_HB = 0x5,
10448
10449 /* bits 15..12 for 0x05 */
10450 RDPGPR = 0xe,
10451 WRPGPR = 0xf,
10452
10453 /* bits 15..12 for 0x0d */
10454 TLBP = 0x0,
10455 TLBR = 0x1,
10456 TLBWI = 0x2,
10457 TLBWR = 0x3,
10458 WAIT = 0x9,
10459 IRET = 0xd,
10460 DERET = 0xe,
10461 ERET = 0xf,
10462
10463 /* bits 15..12 for 0x15 */
10464 DMT = 0x0,
10465 DVPE = 0x1,
10466 EMT = 0x2,
10467 EVPE = 0x3,
10468
10469 /* bits 15..12 for 0x1d */
10470 DI = 0x4,
10471 EI = 0x5,
10472
10473 /* bits 15..12 for 0x2d */
10474 SYNC = 0x6,
10475 SYSCALL = 0x8,
10476 SDBBP = 0xd,
10477
10478 /* bits 15..12 for 0x35 */
10479 MFHI32 = 0x0,
10480 MFLO32 = 0x1,
10481 MTHI32 = 0x2,
10482 MTLO32 = 0x3,
10483};
10484
10485/* POOL32B encoding of minor opcode field (bits 15..12) */
10486
10487enum {
10488 LWC2 = 0x0,
10489 LWP = 0x1,
10490 LDP = 0x4,
10491 LWM32 = 0x5,
10492 CACHE = 0x6,
10493 LDM = 0x7,
10494 SWC2 = 0x8,
10495 SWP = 0x9,
10496 SDP = 0xc,
10497 SWM32 = 0xd,
10498 SDM = 0xf
10499};
10500
10501/* POOL32C encoding of minor opcode field (bits 15..12) */
10502
10503enum {
10504 LWL = 0x0,
10505 SWL = 0x8,
10506 LWR = 0x1,
10507 SWR = 0x9,
10508 PREF = 0x2,
10509 /* 0xa is reserved */
10510 LL = 0x3,
10511 SC = 0xb,
10512 LDL = 0x4,
10513 SDL = 0xc,
10514 LDR = 0x5,
10515 SDR = 0xd,
10516 /* 0x6 is reserved */
10517 LWU = 0xe,
10518 LLD = 0x7,
10519 SCD = 0xf
10520};
10521
10522/* POOL32F encoding of minor opcode field (bits 5..0) */
10523
10524enum {
10525 /* These are the bit 7..6 values */
10526 ADD_FMT = 0x0,
10527 MOVN_FMT = 0x0,
10528
10529 SUB_FMT = 0x1,
10530 MOVZ_FMT = 0x1,
10531
10532 MUL_FMT = 0x2,
10533
10534 DIV_FMT = 0x3,
10535
10536 /* These are the bit 8..6 values */
10537 RSQRT2_FMT = 0x0,
10538 MOVF_FMT = 0x0,
10539
10540 LWXC1 = 0x1,
10541 MOVT_FMT = 0x1,
10542
10543 PLL_PS = 0x2,
10544 SWXC1 = 0x2,
10545
10546 PLU_PS = 0x3,
10547 LDXC1 = 0x3,
10548
10549 PUL_PS = 0x4,
10550 SDXC1 = 0x4,
10551 RECIP2_FMT = 0x4,
10552
10553 PUU_PS = 0x5,
10554 LUXC1 = 0x5,
10555
10556 CVT_PS_S = 0x6,
10557 SUXC1 = 0x6,
10558 ADDR_PS = 0x6,
10559 PREFX = 0x6,
10560
10561 MULR_PS = 0x7,
10562
10563 MADD_S = 0x01,
10564 MADD_D = 0x09,
10565 MADD_PS = 0x11,
10566 ALNV_PS = 0x19,
10567 MSUB_S = 0x21,
10568 MSUB_D = 0x29,
10569 MSUB_PS = 0x31,
10570
10571 NMADD_S = 0x02,
10572 NMADD_D = 0x0a,
10573 NMADD_PS = 0x12,
10574 NMSUB_S = 0x22,
10575 NMSUB_D = 0x2a,
10576 NMSUB_PS = 0x32,
10577
10578 POOL32FXF = 0x3b,
10579
10580 CABS_COND_FMT = 0x1c, /* MIPS3D */
10581 C_COND_FMT = 0x3c
10582};
10583
10584/* POOL32Fxf encoding of minor opcode extension field */
10585
10586enum {
10587 CVT_L = 0x04,
10588 RSQRT_FMT = 0x08,
10589 FLOOR_L = 0x0c,
10590 CVT_PW_PS = 0x1c,
10591 CVT_W = 0x24,
10592 SQRT_FMT = 0x28,
10593 FLOOR_W = 0x2c,
10594 CVT_PS_PW = 0x3c,
10595 CFC1 = 0x40,
10596 RECIP_FMT = 0x48,
10597 CEIL_L = 0x4c,
10598 CTC1 = 0x60,
10599 CEIL_W = 0x6c,
10600 MFC1 = 0x80,
10601 CVT_S_PL = 0x84,
10602 TRUNC_L = 0x8c,
10603 MTC1 = 0xa0,
10604 CVT_S_PU = 0xa4,
10605 TRUNC_W = 0xac,
10606 MFHC1 = 0xc0,
10607 ROUND_L = 0xcc,
10608 MTHC1 = 0xe0,
10609 ROUND_W = 0xec,
10610
10611 MOV_FMT = 0x01,
10612 MOVF = 0x05,
10613 ABS_FMT = 0x0d,
10614 RSQRT1_FMT = 0x1d,
10615 MOVT = 0x25,
10616 NEG_FMT = 0x2d,
10617 CVT_D = 0x4d,
10618 RECIP1_FMT = 0x5d,
10619 CVT_S = 0x6d
10620};
10621
10622/* POOL32I encoding of minor opcode field (bits 25..21) */
10623
10624enum {
10625 BLTZ = 0x00,
10626 BLTZAL = 0x01,
10627 BGEZ = 0x02,
10628 BGEZAL = 0x03,
10629 BLEZ = 0x04,
10630 BNEZC = 0x05,
10631 BGTZ = 0x06,
10632 BEQZC = 0x07,
10633 TLTI = 0x08,
10634 TGEI = 0x09,
10635 TLTIU = 0x0a,
10636 TGEIU = 0x0b,
10637 TNEI = 0x0c,
10638 LUI = 0x0d,
10639 TEQI = 0x0e,
10640 SYNCI = 0x10,
10641 BLTZALS = 0x11,
10642 BGEZALS = 0x13,
10643 BC2F = 0x14,
10644 BC2T = 0x15,
10645 BPOSGE64 = 0x1a,
10646 BPOSGE32 = 0x1b,
10647 /* These overlap and are distinguished by bit16 of the instruction */
10648 BC1F = 0x1c,
10649 BC1T = 0x1d,
10650 BC1ANY2F = 0x1c,
10651 BC1ANY2T = 0x1d,
10652 BC1ANY4F = 0x1e,
10653 BC1ANY4T = 0x1f
10654};
10655
10656/* POOL16A encoding of minor opcode field */
10657
10658enum {
10659 ADDU16 = 0x0,
10660 SUBU16 = 0x1
10661};
10662
10663/* POOL16B encoding of minor opcode field */
10664
10665enum {
10666 SLL16 = 0x0,
10667 SRL16 = 0x1
10668};
10669
10670/* POOL16C encoding of minor opcode field */
10671
10672enum {
10673 NOT16 = 0x00,
10674 XOR16 = 0x04,
10675 AND16 = 0x08,
10676 OR16 = 0x0c,
10677 LWM16 = 0x10,
10678 SWM16 = 0x14,
10679 JR16 = 0x18,
10680 JRC16 = 0x1a,
10681 JALR16 = 0x1c,
10682 JALR16S = 0x1e,
10683 MFHI16 = 0x20,
10684 MFLO16 = 0x24,
10685 BREAK16 = 0x28,
10686 SDBBP16 = 0x2c,
10687 JRADDIUSP = 0x30
10688};
10689
10690/* POOL16D encoding of minor opcode field */
10691
10692enum {
10693 ADDIUS5 = 0x0,
10694 ADDIUSP = 0x1
10695};
10696
10697/* POOL16E encoding of minor opcode field */
10698
10699enum {
10700 ADDIUR2 = 0x0,
10701 ADDIUR1SP = 0x1
10702};
10703
10704static int mmreg (int r)
10705{
10706 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10707
10708 return map[r];
10709}
10710
10711/* Used for 16-bit store instructions. */
10712static int mmreg2 (int r)
10713{
10714 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10715
10716 return map[r];
10717}
10718
10719#define uMIPS_RD(op) ((op >> 7) & 0x7)
10720#define uMIPS_RS(op) ((op >> 4) & 0x7)
10721#define uMIPS_RS2(op) uMIPS_RS(op)
10722#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10723#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10724#define uMIPS_RS5(op) (op & 0x1f)
10725
10726/* Signed immediate */
10727#define SIMM(op, start, width) \
10728 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10729 << (32-width)) \
10730 >> (32-width))
10731/* Zero-extended immediate */
10732#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10733
d75c135e 10734static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
10735{
10736 int rd = mmreg(uMIPS_RD(ctx->opcode));
10737
d75c135e 10738 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
10739}
10740
d75c135e 10741static void gen_addiur2(DisasContext *ctx)
3c824109
NF
10742{
10743 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10744 int rd = mmreg(uMIPS_RD(ctx->opcode));
10745 int rs = mmreg(uMIPS_RS(ctx->opcode));
10746
d75c135e 10747 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
10748}
10749
d75c135e 10750static void gen_addiusp(DisasContext *ctx)
3c824109
NF
10751{
10752 int encoded = ZIMM(ctx->opcode, 1, 9);
10753 int decoded;
10754
10755 if (encoded <= 1) {
10756 decoded = 256 + encoded;
10757 } else if (encoded <= 255) {
10758 decoded = encoded;
10759 } else if (encoded <= 509) {
10760 decoded = encoded - 512;
10761 } else {
10762 decoded = encoded - 768;
10763 }
10764
d75c135e 10765 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
10766}
10767
d75c135e 10768static void gen_addius5(DisasContext *ctx)
3c824109
NF
10769{
10770 int imm = SIMM(ctx->opcode, 1, 4);
10771 int rd = (ctx->opcode >> 5) & 0x1f;
10772
d75c135e 10773 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
10774}
10775
d75c135e 10776static void gen_andi16(DisasContext *ctx)
3c824109
NF
10777{
10778 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10779 31, 32, 63, 64, 255, 32768, 65535 };
10780 int rd = mmreg(uMIPS_RD(ctx->opcode));
10781 int rs = mmreg(uMIPS_RS(ctx->opcode));
10782 int encoded = ZIMM(ctx->opcode, 0, 4);
10783
d75c135e 10784 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10785}
10786
10787static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10788 int base, int16_t offset)
10789{
e1050a76 10790 const char *opn = "ldst_multiple";
3c824109
NF
10791 TCGv t0, t1;
10792 TCGv_i32 t2;
10793
10794 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10795 generate_exception(ctx, EXCP_RI);
10796 return;
10797 }
10798
10799 t0 = tcg_temp_new();
10800
10801 gen_base_offset_addr(ctx, t0, base, offset);
10802
10803 t1 = tcg_const_tl(reglist);
10804 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10805
3c824109
NF
10806 save_cpu_state(ctx, 1);
10807 switch (opc) {
10808 case LWM32:
895c2d04 10809 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10810 opn = "lwm";
3c824109
NF
10811 break;
10812 case SWM32:
895c2d04 10813 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10814 opn = "swm";
3c824109
NF
10815 break;
10816#ifdef TARGET_MIPS64
10817 case LDM:
895c2d04 10818 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10819 opn = "ldm";
3c824109
NF
10820 break;
10821 case SDM:
895c2d04 10822 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10823 opn = "sdm";
3c824109 10824 break;
6af0bf9c 10825#endif
3c824109 10826 }
e1050a76 10827 (void)opn;
3c824109
NF
10828 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10829 tcg_temp_free(t0);
33087598 10830 tcg_temp_free(t1);
3c824109
NF
10831 tcg_temp_free_i32(t2);
10832}
6af0bf9c 10833
3c824109 10834
d75c135e 10835static void gen_pool16c_insn(DisasContext *ctx, int *is_branch)
6af0bf9c 10836{
3c824109
NF
10837 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10838 int rs = mmreg(ctx->opcode & 0x7);
10839 int opc;
6af0bf9c 10840
3c824109
NF
10841 switch (((ctx->opcode) >> 4) & 0x3f) {
10842 case NOT16 + 0:
10843 case NOT16 + 1:
10844 case NOT16 + 2:
10845 case NOT16 + 3:
d75c135e 10846 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10847 break;
10848 case XOR16 + 0:
10849 case XOR16 + 1:
10850 case XOR16 + 2:
10851 case XOR16 + 3:
d75c135e 10852 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10853 break;
10854 case AND16 + 0:
10855 case AND16 + 1:
10856 case AND16 + 2:
10857 case AND16 + 3:
d75c135e 10858 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10859 break;
10860 case OR16 + 0:
10861 case OR16 + 1:
10862 case OR16 + 2:
10863 case OR16 + 3:
d75c135e 10864 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10865 break;
10866 case LWM16 + 0:
10867 case LWM16 + 1:
10868 case LWM16 + 2:
10869 case LWM16 + 3:
10870 {
10871 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10872 int offset = ZIMM(ctx->opcode, 0, 4);
10873
10874 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10875 29, offset << 2);
10876 }
10877 break;
10878 case SWM16 + 0:
10879 case SWM16 + 1:
10880 case SWM16 + 2:
10881 case SWM16 + 3:
10882 {
10883 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10884 int offset = ZIMM(ctx->opcode, 0, 4);
10885
10886 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10887 29, offset << 2);
10888 }
10889 break;
10890 case JR16 + 0:
10891 case JR16 + 1:
10892 {
10893 int reg = ctx->opcode & 0x1f;
10894
10895 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10896 }
10897 *is_branch = 1;
10898 break;
10899 case JRC16 + 0:
10900 case JRC16 + 1:
10901 {
10902 int reg = ctx->opcode & 0x1f;
10903
10904 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10905 /* Let normal delay slot handling in our caller take us
10906 to the branch target. */
10907 }
10908 break;
10909 case JALR16 + 0:
10910 case JALR16 + 1:
10911 opc = OPC_JALR;
10912 goto do_jalr;
10913 case JALR16S + 0:
10914 case JALR16S + 1:
10915 opc = OPC_JALRS;
10916 do_jalr:
10917 {
10918 int reg = ctx->opcode & 0x1f;
10919
10920 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10921 }
10922 *is_branch = 1;
10923 break;
10924 case MFHI16 + 0:
10925 case MFHI16 + 1:
10926 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10927 break;
10928 case MFLO16 + 0:
10929 case MFLO16 + 1:
10930 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10931 break;
10932 case BREAK16:
10933 generate_exception(ctx, EXCP_BREAK);
10934 break;
10935 case SDBBP16:
10936 /* XXX: not clear which exception should be raised
10937 * when in debug mode...
10938 */
d75c135e 10939 check_insn(ctx, ISA_MIPS32);
3c824109
NF
10940 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10941 generate_exception(ctx, EXCP_DBp);
10942 } else {
10943 generate_exception(ctx, EXCP_DBp);
10944 }
10945 break;
10946 case JRADDIUSP + 0:
10947 case JRADDIUSP + 1:
10948 {
10949 int imm = ZIMM(ctx->opcode, 0, 5);
10950
10951 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 10952 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
10953 /* Let normal delay slot handling in our caller take us
10954 to the branch target. */
10955 }
10956 break;
10957 default:
10958 generate_exception(ctx, EXCP_RI);
10959 break;
10960 }
10961}
10962
10963static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10964{
10965 TCGv t0 = tcg_temp_new();
10966 TCGv t1 = tcg_temp_new();
10967
10968 gen_load_gpr(t0, base);
10969
10970 if (index != 0) {
10971 gen_load_gpr(t1, index);
10972 tcg_gen_shli_tl(t1, t1, 2);
10973 gen_op_addr_add(ctx, t0, t1, t0);
10974 }
10975
2910c6cb 10976 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
10977 gen_store_gpr(t1, rd);
10978
10979 tcg_temp_free(t0);
10980 tcg_temp_free(t1);
10981}
10982
10983static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10984 int base, int16_t offset)
10985{
10986 const char *opn = "ldst_pair";
10987 TCGv t0, t1;
10988
36c6711b 10989 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 10990 generate_exception(ctx, EXCP_RI);
d796321b
FB
10991 return;
10992 }
10993
3c824109
NF
10994 t0 = tcg_temp_new();
10995 t1 = tcg_temp_new();
8e9ade68 10996
3c824109
NF
10997 gen_base_offset_addr(ctx, t0, base, offset);
10998
10999 switch (opc) {
11000 case LWP:
36c6711b
EJ
11001 if (rd == base) {
11002 generate_exception(ctx, EXCP_RI);
11003 return;
11004 }
2910c6cb 11005 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11006 gen_store_gpr(t1, rd);
11007 tcg_gen_movi_tl(t1, 4);
11008 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11009 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11010 gen_store_gpr(t1, rd+1);
11011 opn = "lwp";
11012 break;
11013 case SWP:
3c824109 11014 gen_load_gpr(t1, rd);
2910c6cb 11015 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11016 tcg_gen_movi_tl(t1, 4);
11017 gen_op_addr_add(ctx, t0, t0, t1);
11018 gen_load_gpr(t1, rd+1);
2910c6cb 11019 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11020 opn = "swp";
11021 break;
11022#ifdef TARGET_MIPS64
11023 case LDP:
36c6711b
EJ
11024 if (rd == base) {
11025 generate_exception(ctx, EXCP_RI);
11026 return;
11027 }
2910c6cb 11028 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11029 gen_store_gpr(t1, rd);
11030 tcg_gen_movi_tl(t1, 8);
11031 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11032 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11033 gen_store_gpr(t1, rd+1);
11034 opn = "ldp";
11035 break;
11036 case SDP:
3c824109 11037 gen_load_gpr(t1, rd);
2910c6cb 11038 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11039 tcg_gen_movi_tl(t1, 8);
11040 gen_op_addr_add(ctx, t0, t0, t1);
11041 gen_load_gpr(t1, rd+1);
2910c6cb 11042 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11043 opn = "sdp";
11044 break;
11045#endif
6af0bf9c 11046 }
2abf314d 11047 (void)opn; /* avoid a compiler warning */
3c824109
NF
11048 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11049 tcg_temp_free(t0);
11050 tcg_temp_free(t1);
11051}
618b0fe9 11052
7db13fae 11053static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
3c824109
NF
11054 int *is_branch)
11055{
11056 int extension = (ctx->opcode >> 6) & 0x3f;
11057 int minor = (ctx->opcode >> 12) & 0xf;
11058 uint32_t mips32_op;
11059
11060 switch (extension) {
11061 case TEQ:
11062 mips32_op = OPC_TEQ;
11063 goto do_trap;
11064 case TGE:
11065 mips32_op = OPC_TGE;
11066 goto do_trap;
11067 case TGEU:
11068 mips32_op = OPC_TGEU;
11069 goto do_trap;
11070 case TLT:
11071 mips32_op = OPC_TLT;
11072 goto do_trap;
11073 case TLTU:
11074 mips32_op = OPC_TLTU;
11075 goto do_trap;
11076 case TNE:
11077 mips32_op = OPC_TNE;
11078 do_trap:
11079 gen_trap(ctx, mips32_op, rs, rt, -1);
11080 break;
11081#ifndef CONFIG_USER_ONLY
11082 case MFC0:
11083 case MFC0 + 32:
2e15497c 11084 check_cp0_enabled(ctx);
3c824109
NF
11085 if (rt == 0) {
11086 /* Treat as NOP. */
11087 break;
11088 }
d75c135e 11089 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11090 break;
11091 case MTC0:
11092 case MTC0 + 32:
2e15497c 11093 check_cp0_enabled(ctx);
3c824109
NF
11094 {
11095 TCGv t0 = tcg_temp_new();
618b0fe9 11096
3c824109 11097 gen_load_gpr(t0, rt);
d75c135e 11098 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11099 tcg_temp_free(t0);
11100 }
11101 break;
11102#endif
11103 case 0x2c:
11104 switch (minor) {
11105 case SEB:
11106 gen_bshfl(ctx, OPC_SEB, rs, rt);
11107 break;
11108 case SEH:
11109 gen_bshfl(ctx, OPC_SEH, rs, rt);
11110 break;
11111 case CLO:
11112 mips32_op = OPC_CLO;
11113 goto do_cl;
11114 case CLZ:
11115 mips32_op = OPC_CLZ;
11116 do_cl:
d75c135e 11117 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11118 gen_cl(ctx, mips32_op, rt, rs);
11119 break;
11120 case RDHWR:
d75c135e 11121 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11122 break;
11123 case WSBH:
11124 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11125 break;
11126 case MULT:
11127 mips32_op = OPC_MULT;
11128 goto do_muldiv;
11129 case MULTU:
11130 mips32_op = OPC_MULTU;
11131 goto do_muldiv;
11132 case DIV:
11133 mips32_op = OPC_DIV;
11134 goto do_muldiv;
11135 case DIVU:
11136 mips32_op = OPC_DIVU;
11137 goto do_muldiv;
11138 case MADD:
11139 mips32_op = OPC_MADD;
11140 goto do_muldiv;
11141 case MADDU:
11142 mips32_op = OPC_MADDU;
11143 goto do_muldiv;
11144 case MSUB:
11145 mips32_op = OPC_MSUB;
11146 goto do_muldiv;
11147 case MSUBU:
11148 mips32_op = OPC_MSUBU;
11149 do_muldiv:
d75c135e 11150 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11151 gen_muldiv(ctx, mips32_op, rs, rt);
11152 break;
11153 default:
11154 goto pool32axf_invalid;
11155 }
11156 break;
11157 case 0x34:
11158 switch (minor) {
11159 case MFC2:
11160 case MTC2:
11161 case MFHC2:
11162 case MTHC2:
11163 case CFC2:
11164 case CTC2:
11165 generate_exception_err(ctx, EXCP_CpU, 2);
11166 break;
11167 default:
11168 goto pool32axf_invalid;
11169 }
11170 break;
11171 case 0x3c:
11172 switch (minor) {
11173 case JALR:
11174 case JALR_HB:
11175 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11176 *is_branch = 1;
11177 break;
11178 case JALRS:
11179 case JALRS_HB:
11180 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11181 *is_branch = 1;
11182 break;
11183 default:
11184 goto pool32axf_invalid;
11185 }
11186 break;
11187 case 0x05:
11188 switch (minor) {
11189 case RDPGPR:
2e15497c 11190 check_cp0_enabled(ctx);
d75c135e 11191 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11192 gen_load_srsgpr(rt, rs);
11193 break;
11194 case WRPGPR:
2e15497c 11195 check_cp0_enabled(ctx);
d75c135e 11196 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11197 gen_store_srsgpr(rt, rs);
11198 break;
11199 default:
11200 goto pool32axf_invalid;
11201 }
11202 break;
11203#ifndef CONFIG_USER_ONLY
11204 case 0x0d:
11205 switch (minor) {
11206 case TLBP:
11207 mips32_op = OPC_TLBP;
11208 goto do_cp0;
11209 case TLBR:
11210 mips32_op = OPC_TLBR;
11211 goto do_cp0;
11212 case TLBWI:
11213 mips32_op = OPC_TLBWI;
11214 goto do_cp0;
11215 case TLBWR:
11216 mips32_op = OPC_TLBWR;
11217 goto do_cp0;
11218 case WAIT:
11219 mips32_op = OPC_WAIT;
11220 goto do_cp0;
11221 case DERET:
11222 mips32_op = OPC_DERET;
11223 goto do_cp0;
11224 case ERET:
11225 mips32_op = OPC_ERET;
11226 do_cp0:
11227 gen_cp0(env, ctx, mips32_op, rt, rs);
11228 break;
11229 default:
11230 goto pool32axf_invalid;
11231 }
11232 break;
11233 case 0x1d:
11234 switch (minor) {
11235 case DI:
2e15497c 11236 check_cp0_enabled(ctx);
3c824109
NF
11237 {
11238 TCGv t0 = tcg_temp_new();
11239
11240 save_cpu_state(ctx, 1);
895c2d04 11241 gen_helper_di(t0, cpu_env);
3c824109
NF
11242 gen_store_gpr(t0, rs);
11243 /* Stop translation as we may have switched the execution mode */
11244 ctx->bstate = BS_STOP;
11245 tcg_temp_free(t0);
11246 }
11247 break;
11248 case EI:
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_ei(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 default:
11262 goto pool32axf_invalid;
11263 }
11264 break;
11265#endif
11266 case 0x2d:
11267 switch (minor) {
11268 case SYNC:
11269 /* NOP */
11270 break;
11271 case SYSCALL:
11272 generate_exception(ctx, EXCP_SYSCALL);
11273 ctx->bstate = BS_STOP;
11274 break;
11275 case SDBBP:
d75c135e 11276 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11277 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11278 generate_exception(ctx, EXCP_DBp);
11279 } else {
11280 generate_exception(ctx, EXCP_DBp);
11281 }
11282 break;
11283 default:
11284 goto pool32axf_invalid;
11285 }
11286 break;
11287 case 0x35:
11288 switch (minor) {
11289 case MFHI32:
11290 gen_HILO(ctx, OPC_MFHI, rs);
11291 break;
11292 case MFLO32:
11293 gen_HILO(ctx, OPC_MFLO, rs);
11294 break;
11295 case MTHI32:
11296 gen_HILO(ctx, OPC_MTHI, rs);
11297 break;
11298 case MTLO32:
11299 gen_HILO(ctx, OPC_MTLO, rs);
11300 break;
11301 default:
11302 goto pool32axf_invalid;
11303 }
11304 break;
11305 default:
11306 pool32axf_invalid:
11307 MIPS_INVAL("pool32axf");
11308 generate_exception(ctx, EXCP_RI);
11309 break;
11310 }
11311}
11312
11313/* Values for microMIPS fmt field. Variable-width, depending on which
11314 formats the instruction supports. */
11315
11316enum {
11317 FMT_SD_S = 0,
11318 FMT_SD_D = 1,
11319
11320 FMT_SDPS_S = 0,
11321 FMT_SDPS_D = 1,
11322 FMT_SDPS_PS = 2,
11323
11324 FMT_SWL_S = 0,
11325 FMT_SWL_W = 1,
11326 FMT_SWL_L = 2,
11327
11328 FMT_DWL_D = 0,
11329 FMT_DWL_W = 1,
11330 FMT_DWL_L = 2
11331};
11332
d75c135e 11333static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11334{
11335 int extension = (ctx->opcode >> 6) & 0x3ff;
11336 uint32_t mips32_op;
11337
11338#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11339#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11340#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11341
11342 switch (extension) {
11343 case FLOAT_1BIT_FMT(CFC1, 0):
11344 mips32_op = OPC_CFC1;
11345 goto do_cp1;
11346 case FLOAT_1BIT_FMT(CTC1, 0):
11347 mips32_op = OPC_CTC1;
11348 goto do_cp1;
11349 case FLOAT_1BIT_FMT(MFC1, 0):
11350 mips32_op = OPC_MFC1;
11351 goto do_cp1;
11352 case FLOAT_1BIT_FMT(MTC1, 0):
11353 mips32_op = OPC_MTC1;
11354 goto do_cp1;
11355 case FLOAT_1BIT_FMT(MFHC1, 0):
11356 mips32_op = OPC_MFHC1;
11357 goto do_cp1;
11358 case FLOAT_1BIT_FMT(MTHC1, 0):
11359 mips32_op = OPC_MTHC1;
11360 do_cp1:
11361 gen_cp1(ctx, mips32_op, rt, rs);
11362 break;
11363
11364 /* Reciprocal square root */
11365 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11366 mips32_op = OPC_RSQRT_S;
11367 goto do_unaryfp;
11368 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11369 mips32_op = OPC_RSQRT_D;
11370 goto do_unaryfp;
11371
11372 /* Square root */
11373 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11374 mips32_op = OPC_SQRT_S;
11375 goto do_unaryfp;
11376 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11377 mips32_op = OPC_SQRT_D;
11378 goto do_unaryfp;
11379
11380 /* Reciprocal */
11381 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11382 mips32_op = OPC_RECIP_S;
11383 goto do_unaryfp;
11384 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11385 mips32_op = OPC_RECIP_D;
11386 goto do_unaryfp;
11387
11388 /* Floor */
11389 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11390 mips32_op = OPC_FLOOR_L_S;
11391 goto do_unaryfp;
11392 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11393 mips32_op = OPC_FLOOR_L_D;
11394 goto do_unaryfp;
11395 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11396 mips32_op = OPC_FLOOR_W_S;
11397 goto do_unaryfp;
11398 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11399 mips32_op = OPC_FLOOR_W_D;
11400 goto do_unaryfp;
11401
11402 /* Ceiling */
11403 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11404 mips32_op = OPC_CEIL_L_S;
11405 goto do_unaryfp;
11406 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11407 mips32_op = OPC_CEIL_L_D;
11408 goto do_unaryfp;
11409 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11410 mips32_op = OPC_CEIL_W_S;
11411 goto do_unaryfp;
11412 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11413 mips32_op = OPC_CEIL_W_D;
11414 goto do_unaryfp;
11415
11416 /* Truncation */
11417 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11418 mips32_op = OPC_TRUNC_L_S;
11419 goto do_unaryfp;
11420 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11421 mips32_op = OPC_TRUNC_L_D;
11422 goto do_unaryfp;
11423 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11424 mips32_op = OPC_TRUNC_W_S;
11425 goto do_unaryfp;
11426 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11427 mips32_op = OPC_TRUNC_W_D;
11428 goto do_unaryfp;
11429
11430 /* Round */
11431 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11432 mips32_op = OPC_ROUND_L_S;
11433 goto do_unaryfp;
11434 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11435 mips32_op = OPC_ROUND_L_D;
11436 goto do_unaryfp;
11437 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11438 mips32_op = OPC_ROUND_W_S;
11439 goto do_unaryfp;
11440 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11441 mips32_op = OPC_ROUND_W_D;
11442 goto do_unaryfp;
11443
11444 /* Integer to floating-point conversion */
11445 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11446 mips32_op = OPC_CVT_L_S;
11447 goto do_unaryfp;
11448 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11449 mips32_op = OPC_CVT_L_D;
11450 goto do_unaryfp;
11451 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11452 mips32_op = OPC_CVT_W_S;
11453 goto do_unaryfp;
11454 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11455 mips32_op = OPC_CVT_W_D;
11456 goto do_unaryfp;
11457
11458 /* Paired-foo conversions */
11459 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11460 mips32_op = OPC_CVT_S_PL;
11461 goto do_unaryfp;
11462 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11463 mips32_op = OPC_CVT_S_PU;
11464 goto do_unaryfp;
11465 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11466 mips32_op = OPC_CVT_PW_PS;
11467 goto do_unaryfp;
11468 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11469 mips32_op = OPC_CVT_PS_PW;
11470 goto do_unaryfp;
11471
11472 /* Floating-point moves */
11473 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11474 mips32_op = OPC_MOV_S;
11475 goto do_unaryfp;
11476 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11477 mips32_op = OPC_MOV_D;
11478 goto do_unaryfp;
11479 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11480 mips32_op = OPC_MOV_PS;
11481 goto do_unaryfp;
11482
11483 /* Absolute value */
11484 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11485 mips32_op = OPC_ABS_S;
11486 goto do_unaryfp;
11487 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11488 mips32_op = OPC_ABS_D;
11489 goto do_unaryfp;
11490 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11491 mips32_op = OPC_ABS_PS;
11492 goto do_unaryfp;
11493
11494 /* Negation */
11495 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11496 mips32_op = OPC_NEG_S;
11497 goto do_unaryfp;
11498 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11499 mips32_op = OPC_NEG_D;
11500 goto do_unaryfp;
11501 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11502 mips32_op = OPC_NEG_PS;
11503 goto do_unaryfp;
11504
11505 /* Reciprocal square root step */
11506 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11507 mips32_op = OPC_RSQRT1_S;
11508 goto do_unaryfp;
11509 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11510 mips32_op = OPC_RSQRT1_D;
11511 goto do_unaryfp;
11512 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11513 mips32_op = OPC_RSQRT1_PS;
11514 goto do_unaryfp;
11515
11516 /* Reciprocal step */
11517 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11518 mips32_op = OPC_RECIP1_S;
11519 goto do_unaryfp;
11520 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11521 mips32_op = OPC_RECIP1_S;
11522 goto do_unaryfp;
11523 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11524 mips32_op = OPC_RECIP1_PS;
11525 goto do_unaryfp;
11526
11527 /* Conversions from double */
11528 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11529 mips32_op = OPC_CVT_D_S;
11530 goto do_unaryfp;
11531 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11532 mips32_op = OPC_CVT_D_W;
11533 goto do_unaryfp;
11534 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11535 mips32_op = OPC_CVT_D_L;
11536 goto do_unaryfp;
11537
11538 /* Conversions from single */
11539 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11540 mips32_op = OPC_CVT_S_D;
11541 goto do_unaryfp;
11542 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11543 mips32_op = OPC_CVT_S_W;
11544 goto do_unaryfp;
11545 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11546 mips32_op = OPC_CVT_S_L;
11547 do_unaryfp:
11548 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11549 break;
11550
11551 /* Conditional moves on floating-point codes */
11552 case COND_FLOAT_MOV(MOVT, 0):
11553 case COND_FLOAT_MOV(MOVT, 1):
11554 case COND_FLOAT_MOV(MOVT, 2):
11555 case COND_FLOAT_MOV(MOVT, 3):
11556 case COND_FLOAT_MOV(MOVT, 4):
11557 case COND_FLOAT_MOV(MOVT, 5):
11558 case COND_FLOAT_MOV(MOVT, 6):
11559 case COND_FLOAT_MOV(MOVT, 7):
11560 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11561 break;
11562 case COND_FLOAT_MOV(MOVF, 0):
11563 case COND_FLOAT_MOV(MOVF, 1):
11564 case COND_FLOAT_MOV(MOVF, 2):
11565 case COND_FLOAT_MOV(MOVF, 3):
11566 case COND_FLOAT_MOV(MOVF, 4):
11567 case COND_FLOAT_MOV(MOVF, 5):
11568 case COND_FLOAT_MOV(MOVF, 6):
11569 case COND_FLOAT_MOV(MOVF, 7):
11570 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11571 break;
11572 default:
11573 MIPS_INVAL("pool32fxf");
11574 generate_exception(ctx, EXCP_RI);
11575 break;
11576 }
11577}
11578
7db13fae 11579static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
3c824109
NF
11580 uint16_t insn_hw1, int *is_branch)
11581{
11582 int32_t offset;
11583 uint16_t insn;
11584 int rt, rs, rd, rr;
11585 int16_t imm;
11586 uint32_t op, minor, mips32_op;
11587 uint32_t cond, fmt, cc;
11588
895c2d04 11589 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11590 ctx->opcode = (ctx->opcode << 16) | insn;
11591
11592 rt = (ctx->opcode >> 21) & 0x1f;
11593 rs = (ctx->opcode >> 16) & 0x1f;
11594 rd = (ctx->opcode >> 11) & 0x1f;
11595 rr = (ctx->opcode >> 6) & 0x1f;
11596 imm = (int16_t) ctx->opcode;
11597
11598 op = (ctx->opcode >> 26) & 0x3f;
11599 switch (op) {
11600 case POOL32A:
11601 minor = ctx->opcode & 0x3f;
11602 switch (minor) {
11603 case 0x00:
11604 minor = (ctx->opcode >> 6) & 0xf;
11605 switch (minor) {
11606 case SLL32:
11607 mips32_op = OPC_SLL;
11608 goto do_shifti;
11609 case SRA:
11610 mips32_op = OPC_SRA;
11611 goto do_shifti;
11612 case SRL32:
11613 mips32_op = OPC_SRL;
11614 goto do_shifti;
11615 case ROTR:
11616 mips32_op = OPC_ROTR;
11617 do_shifti:
d75c135e 11618 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
11619 break;
11620 default:
11621 goto pool32a_invalid;
11622 }
11623 break;
11624 case 0x10:
11625 minor = (ctx->opcode >> 6) & 0xf;
11626 switch (minor) {
11627 /* Arithmetic */
11628 case ADD:
11629 mips32_op = OPC_ADD;
11630 goto do_arith;
11631 case ADDU32:
11632 mips32_op = OPC_ADDU;
11633 goto do_arith;
11634 case SUB:
11635 mips32_op = OPC_SUB;
11636 goto do_arith;
11637 case SUBU32:
11638 mips32_op = OPC_SUBU;
11639 goto do_arith;
11640 case MUL:
11641 mips32_op = OPC_MUL;
11642 do_arith:
d75c135e 11643 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11644 break;
11645 /* Shifts */
11646 case SLLV:
11647 mips32_op = OPC_SLLV;
11648 goto do_shift;
11649 case SRLV:
11650 mips32_op = OPC_SRLV;
11651 goto do_shift;
11652 case SRAV:
11653 mips32_op = OPC_SRAV;
11654 goto do_shift;
11655 case ROTRV:
11656 mips32_op = OPC_ROTRV;
11657 do_shift:
d75c135e 11658 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11659 break;
11660 /* Logical operations */
11661 case AND:
11662 mips32_op = OPC_AND;
11663 goto do_logic;
11664 case OR32:
11665 mips32_op = OPC_OR;
11666 goto do_logic;
11667 case NOR:
11668 mips32_op = OPC_NOR;
11669 goto do_logic;
11670 case XOR32:
11671 mips32_op = OPC_XOR;
11672 do_logic:
d75c135e 11673 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11674 break;
11675 /* Set less than */
11676 case SLT:
11677 mips32_op = OPC_SLT;
11678 goto do_slt;
11679 case SLTU:
11680 mips32_op = OPC_SLTU;
11681 do_slt:
d75c135e 11682 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11683 break;
11684 default:
11685 goto pool32a_invalid;
11686 }
11687 break;
11688 case 0x18:
11689 minor = (ctx->opcode >> 6) & 0xf;
11690 switch (minor) {
11691 /* Conditional moves */
11692 case MOVN:
11693 mips32_op = OPC_MOVN;
11694 goto do_cmov;
11695 case MOVZ:
11696 mips32_op = OPC_MOVZ;
11697 do_cmov:
d75c135e 11698 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11699 break;
11700 case LWXS:
11701 gen_ldxs(ctx, rs, rt, rd);
11702 break;
11703 default:
11704 goto pool32a_invalid;
11705 }
11706 break;
11707 case INS:
11708 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11709 return;
11710 case EXT:
11711 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11712 return;
11713 case POOL32AXF:
11714 gen_pool32axf(env, ctx, rt, rs, is_branch);
11715 break;
11716 case 0x07:
11717 generate_exception(ctx, EXCP_BREAK);
11718 break;
11719 default:
11720 pool32a_invalid:
11721 MIPS_INVAL("pool32a");
11722 generate_exception(ctx, EXCP_RI);
11723 break;
11724 }
11725 break;
11726 case POOL32B:
11727 minor = (ctx->opcode >> 12) & 0xf;
11728 switch (minor) {
11729 case CACHE:
2e15497c 11730 check_cp0_enabled(ctx);
3c824109
NF
11731 /* Treat as no-op. */
11732 break;
11733 case LWC2:
11734 case SWC2:
11735 /* COP2: Not implemented. */
11736 generate_exception_err(ctx, EXCP_CpU, 2);
11737 break;
11738 case LWP:
11739 case SWP:
11740#ifdef TARGET_MIPS64
11741 case LDP:
11742 case SDP:
11743#endif
11744 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11745 break;
11746 case LWM32:
11747 case SWM32:
11748#ifdef TARGET_MIPS64
11749 case LDM:
11750 case SDM:
11751#endif
11752 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11753 break;
11754 default:
11755 MIPS_INVAL("pool32b");
11756 generate_exception(ctx, EXCP_RI);
11757 break;
11758 }
11759 break;
11760 case POOL32F:
11761 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11762 minor = ctx->opcode & 0x3f;
11763 check_cp1_enabled(ctx);
11764 switch (minor) {
11765 case ALNV_PS:
11766 mips32_op = OPC_ALNV_PS;
11767 goto do_madd;
11768 case MADD_S:
11769 mips32_op = OPC_MADD_S;
11770 goto do_madd;
11771 case MADD_D:
11772 mips32_op = OPC_MADD_D;
11773 goto do_madd;
11774 case MADD_PS:
11775 mips32_op = OPC_MADD_PS;
11776 goto do_madd;
11777 case MSUB_S:
11778 mips32_op = OPC_MSUB_S;
11779 goto do_madd;
11780 case MSUB_D:
11781 mips32_op = OPC_MSUB_D;
11782 goto do_madd;
11783 case MSUB_PS:
11784 mips32_op = OPC_MSUB_PS;
11785 goto do_madd;
11786 case NMADD_S:
11787 mips32_op = OPC_NMADD_S;
11788 goto do_madd;
11789 case NMADD_D:
11790 mips32_op = OPC_NMADD_D;
11791 goto do_madd;
11792 case NMADD_PS:
11793 mips32_op = OPC_NMADD_PS;
11794 goto do_madd;
11795 case NMSUB_S:
11796 mips32_op = OPC_NMSUB_S;
11797 goto do_madd;
11798 case NMSUB_D:
11799 mips32_op = OPC_NMSUB_D;
11800 goto do_madd;
11801 case NMSUB_PS:
11802 mips32_op = OPC_NMSUB_PS;
11803 do_madd:
11804 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11805 break;
11806 case CABS_COND_FMT:
11807 cond = (ctx->opcode >> 6) & 0xf;
11808 cc = (ctx->opcode >> 13) & 0x7;
11809 fmt = (ctx->opcode >> 10) & 0x3;
11810 switch (fmt) {
11811 case 0x0:
11812 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11813 break;
11814 case 0x1:
11815 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11816 break;
11817 case 0x2:
11818 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11819 break;
11820 default:
11821 goto pool32f_invalid;
11822 }
11823 break;
11824 case C_COND_FMT:
11825 cond = (ctx->opcode >> 6) & 0xf;
11826 cc = (ctx->opcode >> 13) & 0x7;
11827 fmt = (ctx->opcode >> 10) & 0x3;
11828 switch (fmt) {
11829 case 0x0:
11830 gen_cmp_s(ctx, cond, rt, rs, cc);
11831 break;
11832 case 0x1:
11833 gen_cmp_d(ctx, cond, rt, rs, cc);
11834 break;
11835 case 0x2:
11836 gen_cmp_ps(ctx, cond, rt, rs, cc);
11837 break;
11838 default:
11839 goto pool32f_invalid;
11840 }
11841 break;
11842 case POOL32FXF:
d75c135e 11843 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
11844 break;
11845 case 0x00:
11846 /* PLL foo */
11847 switch ((ctx->opcode >> 6) & 0x7) {
11848 case PLL_PS:
11849 mips32_op = OPC_PLL_PS;
11850 goto do_ps;
11851 case PLU_PS:
11852 mips32_op = OPC_PLU_PS;
11853 goto do_ps;
11854 case PUL_PS:
11855 mips32_op = OPC_PUL_PS;
11856 goto do_ps;
11857 case PUU_PS:
11858 mips32_op = OPC_PUU_PS;
11859 goto do_ps;
11860 case CVT_PS_S:
11861 mips32_op = OPC_CVT_PS_S;
11862 do_ps:
11863 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11864 break;
11865 default:
11866 goto pool32f_invalid;
11867 }
11868 break;
11869 case 0x08:
11870 /* [LS][WDU]XC1 */
11871 switch ((ctx->opcode >> 6) & 0x7) {
11872 case LWXC1:
11873 mips32_op = OPC_LWXC1;
11874 goto do_ldst_cp1;
11875 case SWXC1:
11876 mips32_op = OPC_SWXC1;
11877 goto do_ldst_cp1;
11878 case LDXC1:
11879 mips32_op = OPC_LDXC1;
11880 goto do_ldst_cp1;
11881 case SDXC1:
11882 mips32_op = OPC_SDXC1;
11883 goto do_ldst_cp1;
11884 case LUXC1:
11885 mips32_op = OPC_LUXC1;
11886 goto do_ldst_cp1;
11887 case SUXC1:
11888 mips32_op = OPC_SUXC1;
11889 do_ldst_cp1:
11890 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11891 break;
11892 default:
11893 goto pool32f_invalid;
11894 }
11895 break;
11896 case 0x18:
11897 /* 3D insns */
11898 fmt = (ctx->opcode >> 9) & 0x3;
11899 switch ((ctx->opcode >> 6) & 0x7) {
11900 case RSQRT2_FMT:
11901 switch (fmt) {
11902 case FMT_SDPS_S:
11903 mips32_op = OPC_RSQRT2_S;
11904 goto do_3d;
11905 case FMT_SDPS_D:
11906 mips32_op = OPC_RSQRT2_D;
11907 goto do_3d;
11908 case FMT_SDPS_PS:
11909 mips32_op = OPC_RSQRT2_PS;
11910 goto do_3d;
11911 default:
11912 goto pool32f_invalid;
11913 }
11914 break;
11915 case RECIP2_FMT:
11916 switch (fmt) {
11917 case FMT_SDPS_S:
11918 mips32_op = OPC_RECIP2_S;
11919 goto do_3d;
11920 case FMT_SDPS_D:
11921 mips32_op = OPC_RECIP2_D;
11922 goto do_3d;
11923 case FMT_SDPS_PS:
11924 mips32_op = OPC_RECIP2_PS;
11925 goto do_3d;
11926 default:
11927 goto pool32f_invalid;
11928 }
11929 break;
11930 case ADDR_PS:
11931 mips32_op = OPC_ADDR_PS;
11932 goto do_3d;
11933 case MULR_PS:
11934 mips32_op = OPC_MULR_PS;
11935 do_3d:
11936 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11937 break;
11938 default:
11939 goto pool32f_invalid;
11940 }
11941 break;
11942 case 0x20:
11943 /* MOV[FT].fmt and PREFX */
11944 cc = (ctx->opcode >> 13) & 0x7;
11945 fmt = (ctx->opcode >> 9) & 0x3;
11946 switch ((ctx->opcode >> 6) & 0x7) {
11947 case MOVF_FMT:
11948 switch (fmt) {
11949 case FMT_SDPS_S:
11950 gen_movcf_s(rs, rt, cc, 0);
11951 break;
11952 case FMT_SDPS_D:
11953 gen_movcf_d(ctx, rs, rt, cc, 0);
11954 break;
11955 case FMT_SDPS_PS:
11956 gen_movcf_ps(rs, rt, cc, 0);
11957 break;
11958 default:
11959 goto pool32f_invalid;
11960 }
11961 break;
11962 case MOVT_FMT:
11963 switch (fmt) {
11964 case FMT_SDPS_S:
11965 gen_movcf_s(rs, rt, cc, 1);
11966 break;
11967 case FMT_SDPS_D:
11968 gen_movcf_d(ctx, rs, rt, cc, 1);
11969 break;
11970 case FMT_SDPS_PS:
11971 gen_movcf_ps(rs, rt, cc, 1);
11972 break;
11973 default:
11974 goto pool32f_invalid;
11975 }
11976 break;
11977 case PREFX:
11978 break;
11979 default:
11980 goto pool32f_invalid;
11981 }
11982 break;
11983#define FINSN_3ARG_SDPS(prfx) \
11984 switch ((ctx->opcode >> 8) & 0x3) { \
11985 case FMT_SDPS_S: \
11986 mips32_op = OPC_##prfx##_S; \
11987 goto do_fpop; \
11988 case FMT_SDPS_D: \
11989 mips32_op = OPC_##prfx##_D; \
11990 goto do_fpop; \
11991 case FMT_SDPS_PS: \
11992 mips32_op = OPC_##prfx##_PS; \
11993 goto do_fpop; \
11994 default: \
11995 goto pool32f_invalid; \
11996 }
11997 case 0x30:
11998 /* regular FP ops */
11999 switch ((ctx->opcode >> 6) & 0x3) {
12000 case ADD_FMT:
12001 FINSN_3ARG_SDPS(ADD);
12002 break;
12003 case SUB_FMT:
12004 FINSN_3ARG_SDPS(SUB);
12005 break;
12006 case MUL_FMT:
12007 FINSN_3ARG_SDPS(MUL);
12008 break;
12009 case DIV_FMT:
12010 fmt = (ctx->opcode >> 8) & 0x3;
12011 if (fmt == 1) {
12012 mips32_op = OPC_DIV_D;
12013 } else if (fmt == 0) {
12014 mips32_op = OPC_DIV_S;
12015 } else {
12016 goto pool32f_invalid;
12017 }
12018 goto do_fpop;
12019 default:
12020 goto pool32f_invalid;
12021 }
12022 break;
12023 case 0x38:
12024 /* cmovs */
12025 switch ((ctx->opcode >> 6) & 0x3) {
12026 case MOVN_FMT:
12027 FINSN_3ARG_SDPS(MOVN);
12028 break;
12029 case MOVZ_FMT:
12030 FINSN_3ARG_SDPS(MOVZ);
12031 break;
12032 default:
12033 goto pool32f_invalid;
12034 }
12035 break;
12036 do_fpop:
12037 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12038 break;
12039 default:
12040 pool32f_invalid:
12041 MIPS_INVAL("pool32f");
12042 generate_exception(ctx, EXCP_RI);
12043 break;
12044 }
12045 } else {
12046 generate_exception_err(ctx, EXCP_CpU, 1);
12047 }
12048 break;
12049 case POOL32I:
12050 minor = (ctx->opcode >> 21) & 0x1f;
12051 switch (minor) {
12052 case BLTZ:
12053 mips32_op = OPC_BLTZ;
12054 goto do_branch;
12055 case BLTZAL:
12056 mips32_op = OPC_BLTZAL;
12057 goto do_branch;
12058 case BLTZALS:
12059 mips32_op = OPC_BLTZALS;
12060 goto do_branch;
12061 case BGEZ:
12062 mips32_op = OPC_BGEZ;
12063 goto do_branch;
12064 case BGEZAL:
12065 mips32_op = OPC_BGEZAL;
12066 goto do_branch;
12067 case BGEZALS:
12068 mips32_op = OPC_BGEZALS;
12069 goto do_branch;
12070 case BLEZ:
12071 mips32_op = OPC_BLEZ;
12072 goto do_branch;
12073 case BGTZ:
12074 mips32_op = OPC_BGTZ;
12075 do_branch:
12076 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12077 *is_branch = 1;
12078 break;
12079
12080 /* Traps */
12081 case TLTI:
12082 mips32_op = OPC_TLTI;
12083 goto do_trapi;
12084 case TGEI:
12085 mips32_op = OPC_TGEI;
12086 goto do_trapi;
12087 case TLTIU:
12088 mips32_op = OPC_TLTIU;
12089 goto do_trapi;
12090 case TGEIU:
12091 mips32_op = OPC_TGEIU;
12092 goto do_trapi;
12093 case TNEI:
12094 mips32_op = OPC_TNEI;
12095 goto do_trapi;
12096 case TEQI:
12097 mips32_op = OPC_TEQI;
12098 do_trapi:
12099 gen_trap(ctx, mips32_op, rs, -1, imm);
12100 break;
12101
12102 case BNEZC:
12103 case BEQZC:
12104 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12105 4, rs, 0, imm << 1);
12106 /* Compact branches don't have a delay slot, so just let
12107 the normal delay slot handling take us to the branch
12108 target. */
12109 break;
12110 case LUI:
d75c135e 12111 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12112 break;
12113 case SYNCI:
12114 break;
12115 case BC2F:
12116 case BC2T:
12117 /* COP2: Not implemented. */
12118 generate_exception_err(ctx, EXCP_CpU, 2);
12119 break;
12120 case BC1F:
12121 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12122 goto do_cp1branch;
12123 case BC1T:
12124 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12125 goto do_cp1branch;
12126 case BC1ANY4F:
12127 mips32_op = OPC_BC1FANY4;
12128 goto do_cp1mips3d;
12129 case BC1ANY4T:
12130 mips32_op = OPC_BC1TANY4;
12131 do_cp1mips3d:
12132 check_cop1x(ctx);
d75c135e 12133 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12134 /* Fall through */
12135 do_cp1branch:
d75c135e 12136 gen_compute_branch1(ctx, mips32_op,
3c824109
NF
12137 (ctx->opcode >> 18) & 0x7, imm << 1);
12138 *is_branch = 1;
12139 break;
12140 case BPOSGE64:
12141 case BPOSGE32:
12142 /* MIPS DSP: not implemented */
12143 /* Fall through */
12144 default:
12145 MIPS_INVAL("pool32i");
12146 generate_exception(ctx, EXCP_RI);
12147 break;
12148 }
12149 break;
12150 case POOL32C:
12151 minor = (ctx->opcode >> 12) & 0xf;
12152 switch (minor) {
12153 case LWL:
12154 mips32_op = OPC_LWL;
5c13fdfd 12155 goto do_ld_lr;
3c824109
NF
12156 case SWL:
12157 mips32_op = OPC_SWL;
5c13fdfd 12158 goto do_st_lr;
3c824109
NF
12159 case LWR:
12160 mips32_op = OPC_LWR;
5c13fdfd 12161 goto do_ld_lr;
3c824109
NF
12162 case SWR:
12163 mips32_op = OPC_SWR;
5c13fdfd 12164 goto do_st_lr;
3c824109
NF
12165#if defined(TARGET_MIPS64)
12166 case LDL:
12167 mips32_op = OPC_LDL;
5c13fdfd 12168 goto do_ld_lr;
3c824109
NF
12169 case SDL:
12170 mips32_op = OPC_SDL;
5c13fdfd 12171 goto do_st_lr;
3c824109
NF
12172 case LDR:
12173 mips32_op = OPC_LDR;
5c13fdfd 12174 goto do_ld_lr;
3c824109
NF
12175 case SDR:
12176 mips32_op = OPC_SDR;
5c13fdfd 12177 goto do_st_lr;
3c824109
NF
12178 case LWU:
12179 mips32_op = OPC_LWU;
5c13fdfd 12180 goto do_ld_lr;
3c824109
NF
12181 case LLD:
12182 mips32_op = OPC_LLD;
5c13fdfd 12183 goto do_ld_lr;
3c824109
NF
12184#endif
12185 case LL:
12186 mips32_op = OPC_LL;
5c13fdfd
AJ
12187 goto do_ld_lr;
12188 do_ld_lr:
d75c135e 12189 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12190 break;
12191 do_st_lr:
12192 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12193 break;
12194 case SC:
12195 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12196 break;
12197#if defined(TARGET_MIPS64)
12198 case SCD:
12199 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12200 break;
12201#endif
12202 case PREF:
12203 /* Treat as no-op */
12204 break;
12205 default:
12206 MIPS_INVAL("pool32c");
12207 generate_exception(ctx, EXCP_RI);
12208 break;
12209 }
12210 break;
12211 case ADDI32:
12212 mips32_op = OPC_ADDI;
12213 goto do_addi;
12214 case ADDIU32:
12215 mips32_op = OPC_ADDIU;
12216 do_addi:
d75c135e 12217 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12218 break;
12219
12220 /* Logical operations */
12221 case ORI32:
12222 mips32_op = OPC_ORI;
12223 goto do_logici;
12224 case XORI32:
12225 mips32_op = OPC_XORI;
12226 goto do_logici;
12227 case ANDI32:
12228 mips32_op = OPC_ANDI;
12229 do_logici:
d75c135e 12230 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12231 break;
12232
12233 /* Set less than immediate */
12234 case SLTI32:
12235 mips32_op = OPC_SLTI;
12236 goto do_slti;
12237 case SLTIU32:
12238 mips32_op = OPC_SLTIU;
12239 do_slti:
d75c135e 12240 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12241 break;
12242 case JALX32:
12243 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12244 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12245 *is_branch = 1;
12246 break;
12247 case JALS32:
12248 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12249 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12250 *is_branch = 1;
12251 break;
12252 case BEQ32:
12253 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12254 *is_branch = 1;
12255 break;
12256 case BNE32:
12257 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12258 *is_branch = 1;
12259 break;
12260 case J32:
12261 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12262 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12263 *is_branch = 1;
12264 break;
12265 case JAL32:
12266 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12267 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12268 *is_branch = 1;
12269 break;
12270 /* Floating point (COP1) */
12271 case LWC132:
12272 mips32_op = OPC_LWC1;
12273 goto do_cop1;
12274 case LDC132:
12275 mips32_op = OPC_LDC1;
12276 goto do_cop1;
12277 case SWC132:
12278 mips32_op = OPC_SWC1;
12279 goto do_cop1;
12280 case SDC132:
12281 mips32_op = OPC_SDC1;
12282 do_cop1:
12283 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12284 break;
12285 case ADDIUPC:
12286 {
12287 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12288 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12289
12290 gen_addiupc(ctx, reg, offset, 0, 0);
12291 }
12292 break;
12293 /* Loads and stores */
12294 case LB32:
12295 mips32_op = OPC_LB;
5c13fdfd 12296 goto do_ld;
3c824109
NF
12297 case LBU32:
12298 mips32_op = OPC_LBU;
5c13fdfd 12299 goto do_ld;
3c824109
NF
12300 case LH32:
12301 mips32_op = OPC_LH;
5c13fdfd 12302 goto do_ld;
3c824109
NF
12303 case LHU32:
12304 mips32_op = OPC_LHU;
5c13fdfd 12305 goto do_ld;
3c824109
NF
12306 case LW32:
12307 mips32_op = OPC_LW;
5c13fdfd 12308 goto do_ld;
3c824109
NF
12309#ifdef TARGET_MIPS64
12310 case LD32:
12311 mips32_op = OPC_LD;
5c13fdfd 12312 goto do_ld;
3c824109
NF
12313 case SD32:
12314 mips32_op = OPC_SD;
5c13fdfd 12315 goto do_st;
3c824109
NF
12316#endif
12317 case SB32:
12318 mips32_op = OPC_SB;
5c13fdfd 12319 goto do_st;
3c824109
NF
12320 case SH32:
12321 mips32_op = OPC_SH;
5c13fdfd 12322 goto do_st;
3c824109
NF
12323 case SW32:
12324 mips32_op = OPC_SW;
5c13fdfd
AJ
12325 goto do_st;
12326 do_ld:
d75c135e 12327 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12328 break;
12329 do_st:
12330 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12331 break;
12332 default:
12333 generate_exception(ctx, EXCP_RI);
12334 break;
12335 }
12336}
12337
7db13fae 12338static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
12339{
12340 uint32_t op;
12341
12342 /* make sure instructions are on a halfword boundary */
12343 if (ctx->pc & 0x1) {
12344 env->CP0_BadVAddr = ctx->pc;
12345 generate_exception(ctx, EXCP_AdEL);
12346 ctx->bstate = BS_STOP;
12347 return 2;
12348 }
12349
12350 op = (ctx->opcode >> 10) & 0x3f;
12351 /* Enforce properly-sized instructions in a delay slot */
12352 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12353 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12354
12355 switch (op) {
12356 case POOL32A:
12357 case POOL32B:
12358 case POOL32I:
12359 case POOL32C:
12360 case ADDI32:
12361 case ADDIU32:
12362 case ORI32:
12363 case XORI32:
12364 case SLTI32:
12365 case SLTIU32:
12366 case ANDI32:
12367 case JALX32:
12368 case LBU32:
12369 case LHU32:
12370 case POOL32F:
12371 case JALS32:
12372 case BEQ32:
12373 case BNE32:
12374 case J32:
12375 case JAL32:
12376 case SB32:
12377 case SH32:
12378 case POOL32S:
12379 case ADDIUPC:
12380 case SWC132:
12381 case SDC132:
12382 case SD32:
12383 case SW32:
12384 case LB32:
12385 case LH32:
12386 case DADDIU32:
3c824109
NF
12387 case LWC132:
12388 case LDC132:
12389 case LD32:
12390 case LW32:
12391 if (bits & MIPS_HFLAG_BDS16) {
12392 generate_exception(ctx, EXCP_RI);
12393 /* Just stop translation; the user is confused. */
12394 ctx->bstate = BS_STOP;
12395 return 2;
12396 }
12397 break;
12398 case POOL16A:
12399 case POOL16B:
12400 case POOL16C:
12401 case LWGP16:
12402 case POOL16F:
12403 case LBU16:
12404 case LHU16:
12405 case LWSP16:
12406 case LW16:
12407 case SB16:
12408 case SH16:
12409 case SWSP16:
12410 case SW16:
12411 case MOVE16:
12412 case ANDI16:
12413 case POOL16D:
12414 case POOL16E:
12415 case BEQZ16:
12416 case BNEZ16:
12417 case B16:
12418 case LI16:
12419 if (bits & MIPS_HFLAG_BDS32) {
12420 generate_exception(ctx, EXCP_RI);
12421 /* Just stop translation; the user is confused. */
12422 ctx->bstate = BS_STOP;
12423 return 2;
12424 }
12425 break;
12426 default:
12427 break;
12428 }
12429 }
12430 switch (op) {
12431 case POOL16A:
12432 {
12433 int rd = mmreg(uMIPS_RD(ctx->opcode));
12434 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12435 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12436 uint32_t opc = 0;
12437
12438 switch (ctx->opcode & 0x1) {
12439 case ADDU16:
12440 opc = OPC_ADDU;
12441 break;
12442 case SUBU16:
12443 opc = OPC_SUBU;
12444 break;
12445 }
12446
d75c135e 12447 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12448 }
12449 break;
12450 case POOL16B:
12451 {
12452 int rd = mmreg(uMIPS_RD(ctx->opcode));
12453 int rs = mmreg(uMIPS_RS(ctx->opcode));
12454 int amount = (ctx->opcode >> 1) & 0x7;
12455 uint32_t opc = 0;
12456 amount = amount == 0 ? 8 : amount;
12457
12458 switch (ctx->opcode & 0x1) {
12459 case SLL16:
12460 opc = OPC_SLL;
12461 break;
12462 case SRL16:
12463 opc = OPC_SRL;
12464 break;
12465 }
12466
d75c135e 12467 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12468 }
12469 break;
12470 case POOL16C:
d75c135e 12471 gen_pool16c_insn(ctx, is_branch);
3c824109
NF
12472 break;
12473 case LWGP16:
12474 {
12475 int rd = mmreg(uMIPS_RD(ctx->opcode));
12476 int rb = 28; /* GP */
12477 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12478
d75c135e 12479 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12480 }
12481 break;
12482 case POOL16F:
12483 if (ctx->opcode & 1) {
12484 generate_exception(ctx, EXCP_RI);
12485 } else {
12486 /* MOVEP */
12487 int enc_dest = uMIPS_RD(ctx->opcode);
12488 int enc_rt = uMIPS_RS2(ctx->opcode);
12489 int enc_rs = uMIPS_RS1(ctx->opcode);
12490 int rd, rs, re, rt;
12491 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12492 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12493 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12494
12495 rd = rd_enc[enc_dest];
12496 re = re_enc[enc_dest];
12497 rs = rs_rt_enc[enc_rs];
12498 rt = rs_rt_enc[enc_rt];
12499
d75c135e
AJ
12500 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12501 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12502 }
12503 break;
12504 case LBU16:
12505 {
12506 int rd = mmreg(uMIPS_RD(ctx->opcode));
12507 int rb = mmreg(uMIPS_RS(ctx->opcode));
12508 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12509 offset = (offset == 0xf ? -1 : offset);
12510
d75c135e 12511 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12512 }
12513 break;
12514 case LHU16:
12515 {
12516 int rd = mmreg(uMIPS_RD(ctx->opcode));
12517 int rb = mmreg(uMIPS_RS(ctx->opcode));
12518 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12519
d75c135e 12520 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12521 }
12522 break;
12523 case LWSP16:
12524 {
12525 int rd = (ctx->opcode >> 5) & 0x1f;
12526 int rb = 29; /* SP */
12527 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12528
d75c135e 12529 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12530 }
12531 break;
12532 case LW16:
12533 {
12534 int rd = mmreg(uMIPS_RD(ctx->opcode));
12535 int rb = mmreg(uMIPS_RS(ctx->opcode));
12536 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12537
d75c135e 12538 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12539 }
12540 break;
12541 case SB16:
12542 {
12543 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12544 int rb = mmreg(uMIPS_RS(ctx->opcode));
12545 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12546
5c13fdfd 12547 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12548 }
12549 break;
12550 case SH16:
12551 {
12552 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12553 int rb = mmreg(uMIPS_RS(ctx->opcode));
12554 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12555
5c13fdfd 12556 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12557 }
12558 break;
12559 case SWSP16:
12560 {
12561 int rd = (ctx->opcode >> 5) & 0x1f;
12562 int rb = 29; /* SP */
12563 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12564
5c13fdfd 12565 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12566 }
12567 break;
12568 case SW16:
12569 {
12570 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12571 int rb = mmreg(uMIPS_RS(ctx->opcode));
12572 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12573
5c13fdfd 12574 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12575 }
12576 break;
12577 case MOVE16:
12578 {
12579 int rd = uMIPS_RD5(ctx->opcode);
12580 int rs = uMIPS_RS5(ctx->opcode);
12581
d75c135e 12582 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12583 }
12584 break;
12585 case ANDI16:
d75c135e 12586 gen_andi16(ctx);
3c824109
NF
12587 break;
12588 case POOL16D:
12589 switch (ctx->opcode & 0x1) {
12590 case ADDIUS5:
d75c135e 12591 gen_addius5(ctx);
3c824109
NF
12592 break;
12593 case ADDIUSP:
d75c135e 12594 gen_addiusp(ctx);
3c824109
NF
12595 break;
12596 }
12597 break;
12598 case POOL16E:
12599 switch (ctx->opcode & 0x1) {
12600 case ADDIUR2:
d75c135e 12601 gen_addiur2(ctx);
3c824109
NF
12602 break;
12603 case ADDIUR1SP:
d75c135e 12604 gen_addiur1sp(ctx);
3c824109
NF
12605 break;
12606 }
12607 break;
12608 case B16:
12609 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12610 SIMM(ctx->opcode, 0, 10) << 1);
12611 *is_branch = 1;
12612 break;
12613 case BNEZ16:
12614 case BEQZ16:
12615 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12616 mmreg(uMIPS_RD(ctx->opcode)),
12617 0, SIMM(ctx->opcode, 0, 7) << 1);
12618 *is_branch = 1;
12619 break;
12620 case LI16:
12621 {
12622 int reg = mmreg(uMIPS_RD(ctx->opcode));
12623 int imm = ZIMM(ctx->opcode, 0, 7);
12624
12625 imm = (imm == 0x7f ? -1 : imm);
12626 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12627 }
12628 break;
12629 case RES_20:
12630 case RES_28:
12631 case RES_29:
12632 case RES_30:
12633 case RES_31:
12634 case RES_38:
12635 case RES_39:
12636 generate_exception(ctx, EXCP_RI);
12637 break;
12638 default:
12639 decode_micromips32_opc (env, ctx, op, is_branch);
12640 return 4;
12641 }
12642
12643 return 2;
12644}
12645
12646/* SmartMIPS extension to MIPS32 */
12647
12648#if defined(TARGET_MIPS64)
12649
12650/* MDMX extension to MIPS64 */
12651
12652#endif
12653
9b1a1d68 12654/* MIPSDSP functions. */
d75c135e 12655static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12656 int rd, int base, int offset)
12657{
12658 const char *opn = "ldx";
12659 TCGv t0;
12660
9b1a1d68
JL
12661 check_dsp(ctx);
12662 t0 = tcg_temp_new();
12663
12664 if (base == 0) {
12665 gen_load_gpr(t0, offset);
12666 } else if (offset == 0) {
12667 gen_load_gpr(t0, base);
12668 } else {
12669 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12670 }
12671
9b1a1d68
JL
12672 switch (opc) {
12673 case OPC_LBUX:
2910c6cb 12674 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12675 gen_store_gpr(t0, rd);
12676 opn = "lbux";
12677 break;
12678 case OPC_LHX:
2910c6cb 12679 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12680 gen_store_gpr(t0, rd);
12681 opn = "lhx";
12682 break;
12683 case OPC_LWX:
2910c6cb 12684 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12685 gen_store_gpr(t0, rd);
12686 opn = "lwx";
12687 break;
12688#if defined(TARGET_MIPS64)
12689 case OPC_LDX:
2910c6cb 12690 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12691 gen_store_gpr(t0, rd);
12692 opn = "ldx";
12693 break;
12694#endif
12695 }
12696 (void)opn; /* avoid a compiler warning */
12697 MIPS_DEBUG("%s %s, %s(%s)", opn,
12698 regnames[rd], regnames[offset], regnames[base]);
12699 tcg_temp_free(t0);
12700}
12701
461c08df
JL
12702static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12703 int ret, int v1, int v2)
12704{
12705 const char *opn = "mipsdsp arith";
12706 TCGv v1_t;
12707 TCGv v2_t;
12708
12709 if (ret == 0) {
12710 /* Treat as NOP. */
12711 MIPS_DEBUG("NOP");
12712 return;
12713 }
12714
12715 v1_t = tcg_temp_new();
12716 v2_t = tcg_temp_new();
12717
12718 gen_load_gpr(v1_t, v1);
12719 gen_load_gpr(v2_t, v2);
12720
12721 switch (op1) {
12722 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12723 case OPC_MULT_G_2E:
12724 check_dspr2(ctx);
12725 switch (op2) {
12726 case OPC_ADDUH_QB:
12727 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12728 break;
12729 case OPC_ADDUH_R_QB:
12730 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12731 break;
12732 case OPC_ADDQH_PH:
12733 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12734 break;
12735 case OPC_ADDQH_R_PH:
12736 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12737 break;
12738 case OPC_ADDQH_W:
12739 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12740 break;
12741 case OPC_ADDQH_R_W:
12742 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12743 break;
12744 case OPC_SUBUH_QB:
12745 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12746 break;
12747 case OPC_SUBUH_R_QB:
12748 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12749 break;
12750 case OPC_SUBQH_PH:
12751 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12752 break;
12753 case OPC_SUBQH_R_PH:
12754 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12755 break;
12756 case OPC_SUBQH_W:
12757 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12758 break;
12759 case OPC_SUBQH_R_W:
12760 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12761 break;
12762 }
12763 break;
12764 case OPC_ABSQ_S_PH_DSP:
12765 switch (op2) {
12766 case OPC_ABSQ_S_QB:
12767 check_dspr2(ctx);
12768 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12769 break;
12770 case OPC_ABSQ_S_PH:
12771 check_dsp(ctx);
12772 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12773 break;
12774 case OPC_ABSQ_S_W:
12775 check_dsp(ctx);
12776 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12777 break;
12778 case OPC_PRECEQ_W_PHL:
12779 check_dsp(ctx);
12780 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12781 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12782 break;
12783 case OPC_PRECEQ_W_PHR:
12784 check_dsp(ctx);
12785 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12786 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12787 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12788 break;
12789 case OPC_PRECEQU_PH_QBL:
12790 check_dsp(ctx);
12791 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12792 break;
12793 case OPC_PRECEQU_PH_QBR:
12794 check_dsp(ctx);
12795 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12796 break;
12797 case OPC_PRECEQU_PH_QBLA:
12798 check_dsp(ctx);
12799 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12800 break;
12801 case OPC_PRECEQU_PH_QBRA:
12802 check_dsp(ctx);
12803 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12804 break;
12805 case OPC_PRECEU_PH_QBL:
12806 check_dsp(ctx);
12807 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12808 break;
12809 case OPC_PRECEU_PH_QBR:
12810 check_dsp(ctx);
12811 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12812 break;
12813 case OPC_PRECEU_PH_QBLA:
12814 check_dsp(ctx);
12815 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12816 break;
12817 case OPC_PRECEU_PH_QBRA:
12818 check_dsp(ctx);
12819 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12820 break;
12821 }
12822 break;
12823 case OPC_ADDU_QB_DSP:
12824 switch (op2) {
12825 case OPC_ADDQ_PH:
12826 check_dsp(ctx);
12827 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12828 break;
12829 case OPC_ADDQ_S_PH:
12830 check_dsp(ctx);
12831 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12832 break;
12833 case OPC_ADDQ_S_W:
12834 check_dsp(ctx);
12835 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12836 break;
12837 case OPC_ADDU_QB:
12838 check_dsp(ctx);
12839 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12840 break;
12841 case OPC_ADDU_S_QB:
12842 check_dsp(ctx);
12843 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12844 break;
12845 case OPC_ADDU_PH:
12846 check_dspr2(ctx);
12847 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12848 break;
12849 case OPC_ADDU_S_PH:
12850 check_dspr2(ctx);
12851 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12852 break;
12853 case OPC_SUBQ_PH:
12854 check_dsp(ctx);
12855 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12856 break;
12857 case OPC_SUBQ_S_PH:
12858 check_dsp(ctx);
12859 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12860 break;
12861 case OPC_SUBQ_S_W:
12862 check_dsp(ctx);
12863 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12864 break;
12865 case OPC_SUBU_QB:
12866 check_dsp(ctx);
12867 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12868 break;
12869 case OPC_SUBU_S_QB:
12870 check_dsp(ctx);
12871 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12872 break;
12873 case OPC_SUBU_PH:
12874 check_dspr2(ctx);
12875 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12876 break;
12877 case OPC_SUBU_S_PH:
12878 check_dspr2(ctx);
12879 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12880 break;
12881 case OPC_ADDSC:
12882 check_dsp(ctx);
12883 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12884 break;
12885 case OPC_ADDWC:
12886 check_dsp(ctx);
12887 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12888 break;
12889 case OPC_MODSUB:
12890 check_dsp(ctx);
12891 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12892 break;
12893 case OPC_RADDU_W_QB:
12894 check_dsp(ctx);
12895 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12896 break;
12897 }
12898 break;
12899 case OPC_CMPU_EQ_QB_DSP:
12900 switch (op2) {
12901 case OPC_PRECR_QB_PH:
12902 check_dspr2(ctx);
12903 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12904 break;
12905 case OPC_PRECRQ_QB_PH:
12906 check_dsp(ctx);
12907 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12908 break;
12909 case OPC_PRECR_SRA_PH_W:
12910 check_dspr2(ctx);
12911 {
12912 TCGv_i32 sa_t = tcg_const_i32(v2);
12913 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12914 cpu_gpr[ret]);
12915 tcg_temp_free_i32(sa_t);
12916 break;
12917 }
12918 case OPC_PRECR_SRA_R_PH_W:
12919 check_dspr2(ctx);
12920 {
12921 TCGv_i32 sa_t = tcg_const_i32(v2);
12922 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12923 cpu_gpr[ret]);
12924 tcg_temp_free_i32(sa_t);
12925 break;
12926 }
12927 case OPC_PRECRQ_PH_W:
12928 check_dsp(ctx);
12929 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12930 break;
12931 case OPC_PRECRQ_RS_PH_W:
12932 check_dsp(ctx);
12933 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12934 break;
12935 case OPC_PRECRQU_S_QB_PH:
12936 check_dsp(ctx);
12937 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12938 break;
12939 }
12940 break;
12941#ifdef TARGET_MIPS64
12942 case OPC_ABSQ_S_QH_DSP:
12943 switch (op2) {
12944 case OPC_PRECEQ_L_PWL:
12945 check_dsp(ctx);
12946 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12947 break;
12948 case OPC_PRECEQ_L_PWR:
12949 check_dsp(ctx);
12950 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12951 break;
12952 case OPC_PRECEQ_PW_QHL:
12953 check_dsp(ctx);
12954 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12955 break;
12956 case OPC_PRECEQ_PW_QHR:
12957 check_dsp(ctx);
12958 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12959 break;
12960 case OPC_PRECEQ_PW_QHLA:
12961 check_dsp(ctx);
12962 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12963 break;
12964 case OPC_PRECEQ_PW_QHRA:
12965 check_dsp(ctx);
12966 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12967 break;
12968 case OPC_PRECEQU_QH_OBL:
12969 check_dsp(ctx);
12970 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12971 break;
12972 case OPC_PRECEQU_QH_OBR:
12973 check_dsp(ctx);
12974 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12975 break;
12976 case OPC_PRECEQU_QH_OBLA:
12977 check_dsp(ctx);
12978 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12979 break;
12980 case OPC_PRECEQU_QH_OBRA:
12981 check_dsp(ctx);
12982 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12983 break;
12984 case OPC_PRECEU_QH_OBL:
12985 check_dsp(ctx);
12986 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12987 break;
12988 case OPC_PRECEU_QH_OBR:
12989 check_dsp(ctx);
12990 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12991 break;
12992 case OPC_PRECEU_QH_OBLA:
12993 check_dsp(ctx);
12994 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12995 break;
12996 case OPC_PRECEU_QH_OBRA:
12997 check_dsp(ctx);
12998 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12999 break;
13000 case OPC_ABSQ_S_OB:
13001 check_dspr2(ctx);
13002 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13003 break;
13004 case OPC_ABSQ_S_PW:
13005 check_dsp(ctx);
13006 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13007 break;
13008 case OPC_ABSQ_S_QH:
13009 check_dsp(ctx);
13010 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13011 break;
13012 }
13013 break;
13014 case OPC_ADDU_OB_DSP:
13015 switch (op2) {
13016 case OPC_RADDU_L_OB:
13017 check_dsp(ctx);
13018 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13019 break;
13020 case OPC_SUBQ_PW:
13021 check_dsp(ctx);
13022 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13023 break;
13024 case OPC_SUBQ_S_PW:
13025 check_dsp(ctx);
13026 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13027 break;
13028 case OPC_SUBQ_QH:
13029 check_dsp(ctx);
13030 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13031 break;
13032 case OPC_SUBQ_S_QH:
13033 check_dsp(ctx);
13034 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13035 break;
13036 case OPC_SUBU_OB:
13037 check_dsp(ctx);
13038 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13039 break;
13040 case OPC_SUBU_S_OB:
13041 check_dsp(ctx);
13042 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13043 break;
13044 case OPC_SUBU_QH:
13045 check_dspr2(ctx);
13046 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13047 break;
13048 case OPC_SUBU_S_QH:
13049 check_dspr2(ctx);
13050 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13051 break;
13052 case OPC_SUBUH_OB:
13053 check_dspr2(ctx);
13054 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13055 break;
13056 case OPC_SUBUH_R_OB:
13057 check_dspr2(ctx);
13058 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13059 break;
13060 case OPC_ADDQ_PW:
13061 check_dsp(ctx);
13062 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13063 break;
13064 case OPC_ADDQ_S_PW:
13065 check_dsp(ctx);
13066 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13067 break;
13068 case OPC_ADDQ_QH:
13069 check_dsp(ctx);
13070 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13071 break;
13072 case OPC_ADDQ_S_QH:
13073 check_dsp(ctx);
13074 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13075 break;
13076 case OPC_ADDU_OB:
13077 check_dsp(ctx);
13078 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13079 break;
13080 case OPC_ADDU_S_OB:
13081 check_dsp(ctx);
13082 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13083 break;
13084 case OPC_ADDU_QH:
13085 check_dspr2(ctx);
13086 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13087 break;
13088 case OPC_ADDU_S_QH:
13089 check_dspr2(ctx);
13090 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13091 break;
13092 case OPC_ADDUH_OB:
13093 check_dspr2(ctx);
13094 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13095 break;
13096 case OPC_ADDUH_R_OB:
13097 check_dspr2(ctx);
13098 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13099 break;
13100 }
13101 break;
13102 case OPC_CMPU_EQ_OB_DSP:
13103 switch (op2) {
13104 case OPC_PRECR_OB_QH:
13105 check_dspr2(ctx);
13106 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13107 break;
13108 case OPC_PRECR_SRA_QH_PW:
13109 check_dspr2(ctx);
13110 {
13111 TCGv_i32 ret_t = tcg_const_i32(ret);
13112 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13113 tcg_temp_free_i32(ret_t);
13114 break;
13115 }
13116 case OPC_PRECR_SRA_R_QH_PW:
13117 check_dspr2(ctx);
13118 {
13119 TCGv_i32 sa_v = tcg_const_i32(ret);
13120 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13121 tcg_temp_free_i32(sa_v);
13122 break;
13123 }
13124 case OPC_PRECRQ_OB_QH:
13125 check_dsp(ctx);
13126 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13127 break;
13128 case OPC_PRECRQ_PW_L:
13129 check_dsp(ctx);
13130 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13131 break;
13132 case OPC_PRECRQ_QH_PW:
13133 check_dsp(ctx);
13134 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13135 break;
13136 case OPC_PRECRQ_RS_QH_PW:
13137 check_dsp(ctx);
13138 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13139 break;
13140 case OPC_PRECRQU_S_OB_QH:
13141 check_dsp(ctx);
13142 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13143 break;
13144 }
13145 break;
13146#endif
13147 }
13148
13149 tcg_temp_free(v1_t);
13150 tcg_temp_free(v2_t);
13151
13152 (void)opn; /* avoid a compiler warning */
13153 MIPS_DEBUG("%s", opn);
13154}
9b1a1d68 13155
77c5fa8b
JL
13156static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13157 int ret, int v1, int v2)
13158{
13159 uint32_t op2;
13160 const char *opn = "mipsdsp shift";
13161 TCGv t0;
13162 TCGv v1_t;
13163 TCGv v2_t;
13164
13165 if (ret == 0) {
13166 /* Treat as NOP. */
13167 MIPS_DEBUG("NOP");
13168 return;
13169 }
13170
13171 t0 = tcg_temp_new();
13172 v1_t = tcg_temp_new();
13173 v2_t = tcg_temp_new();
13174
13175 tcg_gen_movi_tl(t0, v1);
13176 gen_load_gpr(v1_t, v1);
13177 gen_load_gpr(v2_t, v2);
13178
13179 switch (opc) {
13180 case OPC_SHLL_QB_DSP:
13181 {
13182 op2 = MASK_SHLL_QB(ctx->opcode);
13183 switch (op2) {
13184 case OPC_SHLL_QB:
13185 check_dsp(ctx);
13186 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13187 break;
13188 case OPC_SHLLV_QB:
13189 check_dsp(ctx);
13190 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13191 break;
13192 case OPC_SHLL_PH:
13193 check_dsp(ctx);
13194 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13195 break;
13196 case OPC_SHLLV_PH:
13197 check_dsp(ctx);
13198 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13199 break;
13200 case OPC_SHLL_S_PH:
13201 check_dsp(ctx);
13202 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13203 break;
13204 case OPC_SHLLV_S_PH:
13205 check_dsp(ctx);
13206 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13207 break;
13208 case OPC_SHLL_S_W:
13209 check_dsp(ctx);
13210 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13211 break;
13212 case OPC_SHLLV_S_W:
13213 check_dsp(ctx);
13214 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13215 break;
13216 case OPC_SHRL_QB:
13217 check_dsp(ctx);
13218 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13219 break;
13220 case OPC_SHRLV_QB:
13221 check_dsp(ctx);
13222 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13223 break;
13224 case OPC_SHRL_PH:
13225 check_dspr2(ctx);
13226 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13227 break;
13228 case OPC_SHRLV_PH:
13229 check_dspr2(ctx);
13230 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13231 break;
13232 case OPC_SHRA_QB:
13233 check_dspr2(ctx);
13234 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13235 break;
13236 case OPC_SHRA_R_QB:
13237 check_dspr2(ctx);
13238 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13239 break;
13240 case OPC_SHRAV_QB:
13241 check_dspr2(ctx);
13242 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13243 break;
13244 case OPC_SHRAV_R_QB:
13245 check_dspr2(ctx);
13246 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13247 break;
13248 case OPC_SHRA_PH:
13249 check_dsp(ctx);
13250 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13251 break;
13252 case OPC_SHRA_R_PH:
13253 check_dsp(ctx);
13254 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13255 break;
13256 case OPC_SHRAV_PH:
13257 check_dsp(ctx);
13258 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13259 break;
13260 case OPC_SHRAV_R_PH:
13261 check_dsp(ctx);
13262 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13263 break;
13264 case OPC_SHRA_R_W:
13265 check_dsp(ctx);
13266 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13267 break;
13268 case OPC_SHRAV_R_W:
13269 check_dsp(ctx);
13270 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13271 break;
13272 default: /* Invalid */
13273 MIPS_INVAL("MASK SHLL.QB");
13274 generate_exception(ctx, EXCP_RI);
13275 break;
13276 }
13277 break;
13278 }
13279#ifdef TARGET_MIPS64
13280 case OPC_SHLL_OB_DSP:
13281 op2 = MASK_SHLL_OB(ctx->opcode);
13282 switch (op2) {
13283 case OPC_SHLL_PW:
13284 check_dsp(ctx);
13285 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13286 break;
13287 case OPC_SHLLV_PW:
13288 check_dsp(ctx);
13289 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13290 break;
13291 case OPC_SHLL_S_PW:
13292 check_dsp(ctx);
13293 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13294 break;
13295 case OPC_SHLLV_S_PW:
13296 check_dsp(ctx);
13297 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13298 break;
13299 case OPC_SHLL_OB:
13300 check_dsp(ctx);
13301 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13302 break;
13303 case OPC_SHLLV_OB:
13304 check_dsp(ctx);
13305 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13306 break;
13307 case OPC_SHLL_QH:
13308 check_dsp(ctx);
13309 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13310 break;
13311 case OPC_SHLLV_QH:
13312 check_dsp(ctx);
13313 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13314 break;
13315 case OPC_SHLL_S_QH:
13316 check_dsp(ctx);
13317 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13318 break;
13319 case OPC_SHLLV_S_QH:
13320 check_dsp(ctx);
13321 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13322 break;
13323 case OPC_SHRA_OB:
13324 check_dspr2(ctx);
13325 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13326 break;
13327 case OPC_SHRAV_OB:
13328 check_dspr2(ctx);
13329 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13330 break;
13331 case OPC_SHRA_R_OB:
13332 check_dspr2(ctx);
13333 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13334 break;
13335 case OPC_SHRAV_R_OB:
13336 check_dspr2(ctx);
13337 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13338 break;
13339 case OPC_SHRA_PW:
13340 check_dsp(ctx);
13341 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13342 break;
13343 case OPC_SHRAV_PW:
13344 check_dsp(ctx);
13345 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13346 break;
13347 case OPC_SHRA_R_PW:
13348 check_dsp(ctx);
13349 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13350 break;
13351 case OPC_SHRAV_R_PW:
13352 check_dsp(ctx);
13353 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13354 break;
13355 case OPC_SHRA_QH:
13356 check_dsp(ctx);
13357 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13358 break;
13359 case OPC_SHRAV_QH:
13360 check_dsp(ctx);
13361 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13362 break;
13363 case OPC_SHRA_R_QH:
13364 check_dsp(ctx);
13365 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13366 break;
13367 case OPC_SHRAV_R_QH:
13368 check_dsp(ctx);
13369 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13370 break;
13371 case OPC_SHRL_OB:
13372 check_dsp(ctx);
13373 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13374 break;
13375 case OPC_SHRLV_OB:
13376 check_dsp(ctx);
13377 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13378 break;
13379 case OPC_SHRL_QH:
13380 check_dspr2(ctx);
13381 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13382 break;
13383 case OPC_SHRLV_QH:
13384 check_dspr2(ctx);
13385 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13386 break;
13387 default: /* Invalid */
13388 MIPS_INVAL("MASK SHLL.OB");
13389 generate_exception(ctx, EXCP_RI);
13390 break;
13391 }
13392 break;
13393#endif
13394 }
13395
13396 tcg_temp_free(t0);
13397 tcg_temp_free(v1_t);
13398 tcg_temp_free(v2_t);
13399 (void)opn; /* avoid a compiler warning */
13400 MIPS_DEBUG("%s", opn);
13401}
13402
a22260ae
JL
13403static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13404 int ret, int v1, int v2, int check_ret)
13405{
13406 const char *opn = "mipsdsp multiply";
13407 TCGv_i32 t0;
13408 TCGv v1_t;
13409 TCGv v2_t;
13410
13411 if ((ret == 0) && (check_ret == 1)) {
13412 /* Treat as NOP. */
13413 MIPS_DEBUG("NOP");
13414 return;
13415 }
13416
13417 t0 = tcg_temp_new_i32();
13418 v1_t = tcg_temp_new();
13419 v2_t = tcg_temp_new();
13420
13421 tcg_gen_movi_i32(t0, ret);
13422 gen_load_gpr(v1_t, v1);
13423 gen_load_gpr(v2_t, v2);
13424
13425 switch (op1) {
13426 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13427 * the same mask and op1. */
13428 case OPC_MULT_G_2E:
13429 switch (op2) {
13430 case OPC_MUL_PH:
13431 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13432 break;
13433 case OPC_MUL_S_PH:
13434 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13435 break;
13436 case OPC_MULQ_S_W:
13437 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13438 break;
13439 case OPC_MULQ_RS_W:
13440 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13441 break;
13442 }
13443 break;
13444 case OPC_DPA_W_PH_DSP:
13445 switch (op2) {
13446 case OPC_DPAU_H_QBL:
13447 check_dsp(ctx);
13448 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13449 break;
13450 case OPC_DPAU_H_QBR:
13451 check_dsp(ctx);
13452 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13453 break;
13454 case OPC_DPSU_H_QBL:
13455 check_dsp(ctx);
13456 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13457 break;
13458 case OPC_DPSU_H_QBR:
13459 check_dsp(ctx);
13460 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13461 break;
13462 case OPC_DPA_W_PH:
13463 check_dspr2(ctx);
13464 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13465 break;
13466 case OPC_DPAX_W_PH:
13467 check_dspr2(ctx);
13468 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13469 break;
13470 case OPC_DPAQ_S_W_PH:
13471 check_dsp(ctx);
13472 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13473 break;
13474 case OPC_DPAQX_S_W_PH:
13475 check_dspr2(ctx);
13476 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13477 break;
13478 case OPC_DPAQX_SA_W_PH:
13479 check_dspr2(ctx);
13480 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13481 break;
13482 case OPC_DPS_W_PH:
13483 check_dspr2(ctx);
13484 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13485 break;
13486 case OPC_DPSX_W_PH:
13487 check_dspr2(ctx);
13488 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13489 break;
13490 case OPC_DPSQ_S_W_PH:
13491 check_dsp(ctx);
13492 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13493 break;
13494 case OPC_DPSQX_S_W_PH:
13495 check_dspr2(ctx);
13496 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13497 break;
13498 case OPC_DPSQX_SA_W_PH:
13499 check_dspr2(ctx);
13500 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13501 break;
13502 case OPC_MULSAQ_S_W_PH:
13503 check_dsp(ctx);
13504 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13505 break;
13506 case OPC_DPAQ_SA_L_W:
13507 check_dsp(ctx);
13508 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13509 break;
13510 case OPC_DPSQ_SA_L_W:
13511 check_dsp(ctx);
13512 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13513 break;
13514 case OPC_MAQ_S_W_PHL:
13515 check_dsp(ctx);
13516 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13517 break;
13518 case OPC_MAQ_S_W_PHR:
13519 check_dsp(ctx);
13520 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13521 break;
13522 case OPC_MAQ_SA_W_PHL:
13523 check_dsp(ctx);
13524 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13525 break;
13526 case OPC_MAQ_SA_W_PHR:
13527 check_dsp(ctx);
13528 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13529 break;
13530 case OPC_MULSA_W_PH:
13531 check_dspr2(ctx);
13532 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13533 break;
13534 }
13535 break;
13536#ifdef TARGET_MIPS64
13537 case OPC_DPAQ_W_QH_DSP:
13538 {
13539 int ac = ret & 0x03;
13540 tcg_gen_movi_i32(t0, ac);
13541
13542 switch (op2) {
13543 case OPC_DMADD:
13544 check_dsp(ctx);
13545 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13546 break;
13547 case OPC_DMADDU:
13548 check_dsp(ctx);
13549 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13550 break;
13551 case OPC_DMSUB:
13552 check_dsp(ctx);
13553 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13554 break;
13555 case OPC_DMSUBU:
13556 check_dsp(ctx);
13557 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13558 break;
13559 case OPC_DPA_W_QH:
13560 check_dspr2(ctx);
13561 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13562 break;
13563 case OPC_DPAQ_S_W_QH:
13564 check_dsp(ctx);
13565 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13566 break;
13567 case OPC_DPAQ_SA_L_PW:
13568 check_dsp(ctx);
13569 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13570 break;
13571 case OPC_DPAU_H_OBL:
13572 check_dsp(ctx);
13573 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13574 break;
13575 case OPC_DPAU_H_OBR:
13576 check_dsp(ctx);
13577 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13578 break;
13579 case OPC_DPS_W_QH:
13580 check_dspr2(ctx);
13581 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13582 break;
13583 case OPC_DPSQ_S_W_QH:
13584 check_dsp(ctx);
13585 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13586 break;
13587 case OPC_DPSQ_SA_L_PW:
13588 check_dsp(ctx);
13589 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13590 break;
13591 case OPC_DPSU_H_OBL:
13592 check_dsp(ctx);
13593 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13594 break;
13595 case OPC_DPSU_H_OBR:
13596 check_dsp(ctx);
13597 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13598 break;
13599 case OPC_MAQ_S_L_PWL:
13600 check_dsp(ctx);
13601 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13602 break;
13603 case OPC_MAQ_S_L_PWR:
13604 check_dsp(ctx);
13605 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13606 break;
13607 case OPC_MAQ_S_W_QHLL:
13608 check_dsp(ctx);
13609 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13610 break;
13611 case OPC_MAQ_SA_W_QHLL:
13612 check_dsp(ctx);
13613 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13614 break;
13615 case OPC_MAQ_S_W_QHLR:
13616 check_dsp(ctx);
13617 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13618 break;
13619 case OPC_MAQ_SA_W_QHLR:
13620 check_dsp(ctx);
13621 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13622 break;
13623 case OPC_MAQ_S_W_QHRL:
13624 check_dsp(ctx);
13625 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13626 break;
13627 case OPC_MAQ_SA_W_QHRL:
13628 check_dsp(ctx);
13629 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13630 break;
13631 case OPC_MAQ_S_W_QHRR:
13632 check_dsp(ctx);
13633 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13634 break;
13635 case OPC_MAQ_SA_W_QHRR:
13636 check_dsp(ctx);
13637 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13638 break;
13639 case OPC_MULSAQ_S_L_PW:
13640 check_dsp(ctx);
13641 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13642 break;
13643 case OPC_MULSAQ_S_W_QH:
13644 check_dsp(ctx);
13645 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13646 break;
13647 }
13648 }
13649 break;
13650#endif
13651 case OPC_ADDU_QB_DSP:
13652 switch (op2) {
13653 case OPC_MULEU_S_PH_QBL:
13654 check_dsp(ctx);
13655 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13656 break;
13657 case OPC_MULEU_S_PH_QBR:
13658 check_dsp(ctx);
13659 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13660 break;
13661 case OPC_MULQ_RS_PH:
13662 check_dsp(ctx);
13663 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13664 break;
13665 case OPC_MULEQ_S_W_PHL:
13666 check_dsp(ctx);
13667 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 break;
13669 case OPC_MULEQ_S_W_PHR:
13670 check_dsp(ctx);
13671 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 break;
13673 case OPC_MULQ_S_PH:
13674 check_dspr2(ctx);
13675 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 break;
13677 }
13678 break;
13679#ifdef TARGET_MIPS64
13680 case OPC_ADDU_OB_DSP:
13681 switch (op2) {
13682 case OPC_MULEQ_S_PW_QHL:
13683 check_dsp(ctx);
13684 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13685 break;
13686 case OPC_MULEQ_S_PW_QHR:
13687 check_dsp(ctx);
13688 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13689 break;
13690 case OPC_MULEU_S_QH_OBL:
13691 check_dsp(ctx);
13692 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13693 break;
13694 case OPC_MULEU_S_QH_OBR:
13695 check_dsp(ctx);
13696 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13697 break;
13698 case OPC_MULQ_RS_QH:
13699 check_dsp(ctx);
13700 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13701 break;
13702 }
13703 break;
13704#endif
13705 }
13706
13707 tcg_temp_free_i32(t0);
13708 tcg_temp_free(v1_t);
13709 tcg_temp_free(v2_t);
13710
13711 (void)opn; /* avoid a compiler warning */
13712 MIPS_DEBUG("%s", opn);
13713
13714}
13715
d75c135e 13716static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13717 int ret, int val)
13718{
13719 const char *opn = "mipsdsp Bit/ Manipulation";
13720 int16_t imm;
13721 TCGv t0;
13722 TCGv val_t;
13723
13724 if (ret == 0) {
13725 /* Treat as NOP. */
13726 MIPS_DEBUG("NOP");
13727 return;
13728 }
13729
13730 t0 = tcg_temp_new();
13731 val_t = tcg_temp_new();
13732 gen_load_gpr(val_t, val);
13733
13734 switch (op1) {
13735 case OPC_ABSQ_S_PH_DSP:
13736 switch (op2) {
13737 case OPC_BITREV:
13738 check_dsp(ctx);
13739 gen_helper_bitrev(cpu_gpr[ret], val_t);
13740 break;
13741 case OPC_REPL_QB:
13742 check_dsp(ctx);
13743 {
13744 target_long result;
13745 imm = (ctx->opcode >> 16) & 0xFF;
13746 result = (uint32_t)imm << 24 |
13747 (uint32_t)imm << 16 |
13748 (uint32_t)imm << 8 |
13749 (uint32_t)imm;
13750 result = (int32_t)result;
13751 tcg_gen_movi_tl(cpu_gpr[ret], result);
13752 }
13753 break;
13754 case OPC_REPLV_QB:
13755 check_dsp(ctx);
13756 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13757 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13758 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13759 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13760 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13761 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13762 break;
13763 case OPC_REPL_PH:
13764 check_dsp(ctx);
13765 {
13766 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13767 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13768 tcg_gen_movi_tl(cpu_gpr[ret], \
13769 (target_long)((int32_t)imm << 16 | \
c4aaba92 13770 (uint16_t)imm));
1cb6686c
JL
13771 }
13772 break;
13773 case OPC_REPLV_PH:
13774 check_dsp(ctx);
13775 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13776 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13777 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13778 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13779 break;
13780 }
13781 break;
13782#ifdef TARGET_MIPS64
13783 case OPC_ABSQ_S_QH_DSP:
13784 switch (op2) {
13785 case OPC_REPL_OB:
13786 check_dsp(ctx);
13787 {
13788 target_long temp;
13789
13790 imm = (ctx->opcode >> 16) & 0xFF;
13791 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13792 temp = (temp << 16) | temp;
13793 temp = (temp << 32) | temp;
13794 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13795 break;
13796 }
13797 case OPC_REPL_PW:
13798 check_dsp(ctx);
13799 {
13800 target_long temp;
13801
13802 imm = (ctx->opcode >> 16) & 0x03FF;
13803 imm = (int16_t)(imm << 6) >> 6;
13804 temp = ((target_long)imm << 32) \
13805 | ((target_long)imm & 0xFFFFFFFF);
13806 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13807 break;
13808 }
13809 case OPC_REPL_QH:
13810 check_dsp(ctx);
13811 {
13812 target_long temp;
13813
13814 imm = (ctx->opcode >> 16) & 0x03FF;
13815 imm = (int16_t)(imm << 6) >> 6;
13816
13817 temp = ((uint64_t)(uint16_t)imm << 48) |
13818 ((uint64_t)(uint16_t)imm << 32) |
13819 ((uint64_t)(uint16_t)imm << 16) |
13820 (uint64_t)(uint16_t)imm;
13821 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13822 break;
13823 }
13824 case OPC_REPLV_OB:
13825 check_dsp(ctx);
13826 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13827 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13828 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13829 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13830 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13831 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13832 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13833 break;
13834 case OPC_REPLV_PW:
13835 check_dsp(ctx);
13836 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13837 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13838 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13839 break;
13840 case OPC_REPLV_QH:
13841 check_dsp(ctx);
13842 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13843 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13844 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13845 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13846 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13847 break;
13848 }
13849 break;
13850#endif
13851 }
13852 tcg_temp_free(t0);
13853 tcg_temp_free(val_t);
13854
13855 (void)opn; /* avoid a compiler warning */
13856 MIPS_DEBUG("%s", opn);
13857}
13858
26690560
JL
13859static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13860 uint32_t op1, uint32_t op2,
13861 int ret, int v1, int v2, int check_ret)
13862{
13863 const char *opn = "mipsdsp add compare pick";
26690560
JL
13864 TCGv t1;
13865 TCGv v1_t;
13866 TCGv v2_t;
13867
13868 if ((ret == 0) && (check_ret == 1)) {
13869 /* Treat as NOP. */
13870 MIPS_DEBUG("NOP");
13871 return;
13872 }
13873
26690560
JL
13874 t1 = tcg_temp_new();
13875 v1_t = tcg_temp_new();
13876 v2_t = tcg_temp_new();
13877
13878 gen_load_gpr(v1_t, v1);
13879 gen_load_gpr(v2_t, v2);
13880
13881 switch (op1) {
26690560
JL
13882 case OPC_CMPU_EQ_QB_DSP:
13883 switch (op2) {
13884 case OPC_CMPU_EQ_QB:
13885 check_dsp(ctx);
13886 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13887 break;
13888 case OPC_CMPU_LT_QB:
13889 check_dsp(ctx);
13890 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13891 break;
13892 case OPC_CMPU_LE_QB:
13893 check_dsp(ctx);
13894 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13895 break;
13896 case OPC_CMPGU_EQ_QB:
13897 check_dsp(ctx);
13898 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13899 break;
13900 case OPC_CMPGU_LT_QB:
13901 check_dsp(ctx);
13902 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13903 break;
13904 case OPC_CMPGU_LE_QB:
13905 check_dsp(ctx);
13906 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13907 break;
13908 case OPC_CMPGDU_EQ_QB:
13909 check_dspr2(ctx);
13910 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13911 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13912 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13913 tcg_gen_shli_tl(t1, t1, 24);
13914 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13915 break;
13916 case OPC_CMPGDU_LT_QB:
13917 check_dspr2(ctx);
13918 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13919 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13920 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13921 tcg_gen_shli_tl(t1, t1, 24);
13922 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13923 break;
13924 case OPC_CMPGDU_LE_QB:
13925 check_dspr2(ctx);
13926 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13927 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13928 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13929 tcg_gen_shli_tl(t1, t1, 24);
13930 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13931 break;
13932 case OPC_CMP_EQ_PH:
13933 check_dsp(ctx);
13934 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13935 break;
13936 case OPC_CMP_LT_PH:
13937 check_dsp(ctx);
13938 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13939 break;
13940 case OPC_CMP_LE_PH:
13941 check_dsp(ctx);
13942 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13943 break;
13944 case OPC_PICK_QB:
13945 check_dsp(ctx);
13946 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13947 break;
13948 case OPC_PICK_PH:
13949 check_dsp(ctx);
13950 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13951 break;
13952 case OPC_PACKRL_PH:
13953 check_dsp(ctx);
13954 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13955 break;
13956 }
13957 break;
13958#ifdef TARGET_MIPS64
13959 case OPC_CMPU_EQ_OB_DSP:
13960 switch (op2) {
13961 case OPC_CMP_EQ_PW:
13962 check_dsp(ctx);
13963 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13964 break;
13965 case OPC_CMP_LT_PW:
13966 check_dsp(ctx);
13967 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13968 break;
13969 case OPC_CMP_LE_PW:
13970 check_dsp(ctx);
13971 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13972 break;
13973 case OPC_CMP_EQ_QH:
13974 check_dsp(ctx);
13975 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13976 break;
13977 case OPC_CMP_LT_QH:
13978 check_dsp(ctx);
13979 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13980 break;
13981 case OPC_CMP_LE_QH:
13982 check_dsp(ctx);
13983 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13984 break;
13985 case OPC_CMPGDU_EQ_OB:
13986 check_dspr2(ctx);
13987 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13988 break;
13989 case OPC_CMPGDU_LT_OB:
13990 check_dspr2(ctx);
13991 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13992 break;
13993 case OPC_CMPGDU_LE_OB:
13994 check_dspr2(ctx);
13995 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13996 break;
13997 case OPC_CMPGU_EQ_OB:
13998 check_dsp(ctx);
13999 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14000 break;
14001 case OPC_CMPGU_LT_OB:
14002 check_dsp(ctx);
14003 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14004 break;
14005 case OPC_CMPGU_LE_OB:
14006 check_dsp(ctx);
14007 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14008 break;
14009 case OPC_CMPU_EQ_OB:
14010 check_dsp(ctx);
14011 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14012 break;
14013 case OPC_CMPU_LT_OB:
14014 check_dsp(ctx);
14015 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14016 break;
14017 case OPC_CMPU_LE_OB:
14018 check_dsp(ctx);
14019 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14020 break;
14021 case OPC_PACKRL_PW:
14022 check_dsp(ctx);
14023 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14024 break;
14025 case OPC_PICK_OB:
14026 check_dsp(ctx);
14027 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14028 break;
14029 case OPC_PICK_PW:
14030 check_dsp(ctx);
14031 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14032 break;
14033 case OPC_PICK_QH:
14034 check_dsp(ctx);
14035 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14036 break;
14037 }
14038 break;
df6126a7
AJ
14039#endif
14040 }
14041
14042 tcg_temp_free(t1);
14043 tcg_temp_free(v1_t);
14044 tcg_temp_free(v2_t);
14045
14046 (void)opn; /* avoid a compiler warning */
14047 MIPS_DEBUG("%s", opn);
14048}
14049
14050static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14051 uint32_t op1, int rt, int rs, int sa)
14052{
14053 const char *opn = "mipsdsp append/dappend";
14054 TCGv t0;
14055
14056 check_dspr2(ctx);
14057
14058 if (rt == 0) {
14059 /* Treat as NOP. */
14060 MIPS_DEBUG("NOP");
14061 return;
14062 }
14063
14064 t0 = tcg_temp_new();
14065 gen_load_gpr(t0, rs);
14066
14067 switch (op1) {
14068 case OPC_APPEND_DSP:
14069 switch (MASK_APPEND(ctx->opcode)) {
14070 case OPC_APPEND:
14071 if (sa != 0) {
14072 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14073 }
14074 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14075 break;
14076 case OPC_PREPEND:
14077 if (sa != 0) {
14078 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14079 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14080 tcg_gen_shli_tl(t0, t0, 32 - sa);
14081 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14082 }
14083 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14084 break;
14085 case OPC_BALIGN:
14086 sa &= 3;
14087 if (sa != 0 && sa != 2) {
14088 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14089 tcg_gen_ext32u_tl(t0, t0);
14090 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14091 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14092 }
14093 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14094 break;
14095 default: /* Invalid */
14096 MIPS_INVAL("MASK APPEND");
14097 generate_exception(ctx, EXCP_RI);
14098 break;
14099 }
14100 break;
14101#ifdef TARGET_MIPS64
26690560 14102 case OPC_DAPPEND_DSP:
df6126a7 14103 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 14104 case OPC_DAPPEND:
df6126a7
AJ
14105 if (sa != 0) {
14106 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14107 }
26690560
JL
14108 break;
14109 case OPC_PREPENDD:
df6126a7
AJ
14110 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14111 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14112 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
14113 break;
14114 case OPC_PREPENDW:
df6126a7
AJ
14115 if (sa != 0) {
14116 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14117 tcg_gen_shli_tl(t0, t0, 64 - sa);
14118 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14119 }
26690560
JL
14120 break;
14121 case OPC_DBALIGN:
df6126a7
AJ
14122 sa &= 7;
14123 if (sa != 0 && sa != 2 && sa != 4) {
14124 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14125 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14126 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14127 }
26690560
JL
14128 break;
14129 default: /* Invalid */
14130 MIPS_INVAL("MASK DAPPEND");
14131 generate_exception(ctx, EXCP_RI);
14132 break;
14133 }
14134 break;
14135#endif
14136 }
df6126a7 14137 tcg_temp_free(t0);
26690560
JL
14138 (void)opn; /* avoid a compiler warning */
14139 MIPS_DEBUG("%s", opn);
14140}
14141
b53371ed
JL
14142static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14143 int ret, int v1, int v2, int check_ret)
14144
14145{
14146 const char *opn = "mipsdsp accumulator";
14147 TCGv t0;
14148 TCGv t1;
14149 TCGv v1_t;
14150 TCGv v2_t;
14151 int16_t imm;
14152
14153 if ((ret == 0) && (check_ret == 1)) {
14154 /* Treat as NOP. */
14155 MIPS_DEBUG("NOP");
14156 return;
14157 }
14158
14159 t0 = tcg_temp_new();
14160 t1 = tcg_temp_new();
14161 v1_t = tcg_temp_new();
14162 v2_t = tcg_temp_new();
14163
14164 gen_load_gpr(v1_t, v1);
14165 gen_load_gpr(v2_t, v2);
14166
14167 switch (op1) {
14168 case OPC_EXTR_W_DSP:
14169 check_dsp(ctx);
14170 switch (op2) {
14171 case OPC_EXTR_W:
14172 tcg_gen_movi_tl(t0, v2);
14173 tcg_gen_movi_tl(t1, v1);
14174 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14175 break;
14176 case OPC_EXTR_R_W:
14177 tcg_gen_movi_tl(t0, v2);
14178 tcg_gen_movi_tl(t1, v1);
14179 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14180 break;
14181 case OPC_EXTR_RS_W:
14182 tcg_gen_movi_tl(t0, v2);
14183 tcg_gen_movi_tl(t1, v1);
14184 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14185 break;
14186 case OPC_EXTR_S_H:
14187 tcg_gen_movi_tl(t0, v2);
14188 tcg_gen_movi_tl(t1, v1);
14189 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14190 break;
14191 case OPC_EXTRV_S_H:
14192 tcg_gen_movi_tl(t0, v2);
14193 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14194 break;
14195 case OPC_EXTRV_W:
14196 tcg_gen_movi_tl(t0, v2);
14197 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14198 break;
14199 case OPC_EXTRV_R_W:
14200 tcg_gen_movi_tl(t0, v2);
14201 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14202 break;
14203 case OPC_EXTRV_RS_W:
14204 tcg_gen_movi_tl(t0, v2);
14205 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14206 break;
14207 case OPC_EXTP:
14208 tcg_gen_movi_tl(t0, v2);
14209 tcg_gen_movi_tl(t1, v1);
14210 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14211 break;
14212 case OPC_EXTPV:
14213 tcg_gen_movi_tl(t0, v2);
14214 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14215 break;
14216 case OPC_EXTPDP:
14217 tcg_gen_movi_tl(t0, v2);
14218 tcg_gen_movi_tl(t1, v1);
14219 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14220 break;
14221 case OPC_EXTPDPV:
14222 tcg_gen_movi_tl(t0, v2);
14223 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14224 break;
14225 case OPC_SHILO:
14226 imm = (ctx->opcode >> 20) & 0x3F;
14227 tcg_gen_movi_tl(t0, ret);
14228 tcg_gen_movi_tl(t1, imm);
14229 gen_helper_shilo(t0, t1, cpu_env);
14230 break;
14231 case OPC_SHILOV:
14232 tcg_gen_movi_tl(t0, ret);
14233 gen_helper_shilo(t0, v1_t, cpu_env);
14234 break;
14235 case OPC_MTHLIP:
14236 tcg_gen_movi_tl(t0, ret);
14237 gen_helper_mthlip(t0, v1_t, cpu_env);
14238 break;
14239 case OPC_WRDSP:
14240 imm = (ctx->opcode >> 11) & 0x3FF;
14241 tcg_gen_movi_tl(t0, imm);
14242 gen_helper_wrdsp(v1_t, t0, cpu_env);
14243 break;
14244 case OPC_RDDSP:
14245 imm = (ctx->opcode >> 16) & 0x03FF;
14246 tcg_gen_movi_tl(t0, imm);
14247 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14248 break;
14249 }
14250 break;
14251#ifdef TARGET_MIPS64
14252 case OPC_DEXTR_W_DSP:
14253 check_dsp(ctx);
14254 switch (op2) {
14255 case OPC_DMTHLIP:
14256 tcg_gen_movi_tl(t0, ret);
14257 gen_helper_dmthlip(v1_t, t0, cpu_env);
14258 break;
14259 case OPC_DSHILO:
14260 {
14261 int shift = (ctx->opcode >> 19) & 0x7F;
14262 int ac = (ctx->opcode >> 11) & 0x03;
14263 tcg_gen_movi_tl(t0, shift);
14264 tcg_gen_movi_tl(t1, ac);
14265 gen_helper_dshilo(t0, t1, cpu_env);
14266 break;
14267 }
14268 case OPC_DSHILOV:
14269 {
14270 int ac = (ctx->opcode >> 11) & 0x03;
14271 tcg_gen_movi_tl(t0, ac);
14272 gen_helper_dshilo(v1_t, t0, cpu_env);
14273 break;
14274 }
14275 case OPC_DEXTP:
14276 tcg_gen_movi_tl(t0, v2);
14277 tcg_gen_movi_tl(t1, v1);
14278
14279 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14280 break;
14281 case OPC_DEXTPV:
14282 tcg_gen_movi_tl(t0, v2);
14283 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14284 break;
14285 case OPC_DEXTPDP:
14286 tcg_gen_movi_tl(t0, v2);
14287 tcg_gen_movi_tl(t1, v1);
14288 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14289 break;
14290 case OPC_DEXTPDPV:
14291 tcg_gen_movi_tl(t0, v2);
14292 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14293 break;
14294 case OPC_DEXTR_L:
14295 tcg_gen_movi_tl(t0, v2);
14296 tcg_gen_movi_tl(t1, v1);
14297 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14298 break;
14299 case OPC_DEXTR_R_L:
14300 tcg_gen_movi_tl(t0, v2);
14301 tcg_gen_movi_tl(t1, v1);
14302 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14303 break;
14304 case OPC_DEXTR_RS_L:
14305 tcg_gen_movi_tl(t0, v2);
14306 tcg_gen_movi_tl(t1, v1);
14307 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14308 break;
14309 case OPC_DEXTR_W:
14310 tcg_gen_movi_tl(t0, v2);
14311 tcg_gen_movi_tl(t1, v1);
14312 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14313 break;
14314 case OPC_DEXTR_R_W:
14315 tcg_gen_movi_tl(t0, v2);
14316 tcg_gen_movi_tl(t1, v1);
14317 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14318 break;
14319 case OPC_DEXTR_RS_W:
14320 tcg_gen_movi_tl(t0, v2);
14321 tcg_gen_movi_tl(t1, v1);
14322 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14323 break;
14324 case OPC_DEXTR_S_H:
14325 tcg_gen_movi_tl(t0, v2);
14326 tcg_gen_movi_tl(t1, v1);
14327 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14328 break;
14329 case OPC_DEXTRV_S_H:
14330 tcg_gen_movi_tl(t0, v2);
14331 tcg_gen_movi_tl(t1, v1);
14332 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14333 break;
14334 case OPC_DEXTRV_L:
14335 tcg_gen_movi_tl(t0, v2);
14336 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14337 break;
14338 case OPC_DEXTRV_R_L:
14339 tcg_gen_movi_tl(t0, v2);
14340 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14341 break;
14342 case OPC_DEXTRV_RS_L:
14343 tcg_gen_movi_tl(t0, v2);
14344 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14345 break;
14346 case OPC_DEXTRV_W:
14347 tcg_gen_movi_tl(t0, v2);
14348 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14349 break;
14350 case OPC_DEXTRV_R_W:
14351 tcg_gen_movi_tl(t0, v2);
14352 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14353 break;
14354 case OPC_DEXTRV_RS_W:
14355 tcg_gen_movi_tl(t0, v2);
14356 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14357 break;
14358 }
14359 break;
14360#endif
14361 }
14362
14363 tcg_temp_free(t0);
14364 tcg_temp_free(t1);
14365 tcg_temp_free(v1_t);
14366 tcg_temp_free(v2_t);
14367
14368 (void)opn; /* avoid a compiler warning */
14369 MIPS_DEBUG("%s", opn);
14370}
14371
9b1a1d68
JL
14372/* End MIPSDSP functions. */
14373
7db13fae 14374static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
14375{
14376 int32_t offset;
14377 int rs, rt, rd, sa;
14378 uint32_t op, op1, op2;
14379 int16_t imm;
14380
14381 /* make sure instructions are on a word boundary */
14382 if (ctx->pc & 0x3) {
14383 env->CP0_BadVAddr = ctx->pc;
14384 generate_exception(ctx, EXCP_AdEL);
14385 return;
14386 }
14387
14388 /* Handle blikely not taken case */
14389 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14390 int l1 = gen_new_label();
14391
14392 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14393 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14394 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14395 gen_goto_tb(ctx, 1, ctx->pc + 4);
14396 gen_set_label(l1);
14397 }
14398
fdefe51c 14399 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14400 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14401 }
3c824109
NF
14402
14403 op = MASK_OP_MAJOR(ctx->opcode);
14404 rs = (ctx->opcode >> 21) & 0x1f;
14405 rt = (ctx->opcode >> 16) & 0x1f;
14406 rd = (ctx->opcode >> 11) & 0x1f;
14407 sa = (ctx->opcode >> 6) & 0x1f;
14408 imm = (int16_t)ctx->opcode;
14409 switch (op) {
7a387fff
TS
14410 case OPC_SPECIAL:
14411 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14412 switch (op1) {
324d9e32
AJ
14413 case OPC_SLL: /* Shift with immediate */
14414 case OPC_SRA:
d75c135e 14415 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14416 break;
ea63e2c3
NF
14417 case OPC_SRL:
14418 switch ((ctx->opcode >> 21) & 0x1f) {
14419 case 1:
14420 /* rotr is decoded as srl on non-R2 CPUs */
d75c135e 14421 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14422 op1 = OPC_ROTR;
14423 }
14424 /* Fallthrough */
14425 case 0:
d75c135e 14426 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14427 break;
14428 default:
14429 generate_exception(ctx, EXCP_RI);
14430 break;
14431 }
14432 break;
460f00c4
AJ
14433 case OPC_MOVN: /* Conditional move */
14434 case OPC_MOVZ:
d75c135e 14435 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
aa8f4009 14436 INSN_LOONGSON2E | INSN_LOONGSON2F);
d75c135e 14437 gen_cond_move(ctx, op1, rd, rs, rt);
460f00c4
AJ
14438 break;
14439 case OPC_ADD ... OPC_SUBU:
d75c135e 14440 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14441 break;
460f00c4 14442 case OPC_SLLV: /* Shifts */
460f00c4 14443 case OPC_SRAV:
d75c135e 14444 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14445 break;
ea63e2c3
NF
14446 case OPC_SRLV:
14447 switch ((ctx->opcode >> 6) & 0x1f) {
14448 case 1:
14449 /* rotrv is decoded as srlv on non-R2 CPUs */
d75c135e 14450 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14451 op1 = OPC_ROTRV;
14452 }
14453 /* Fallthrough */
14454 case 0:
d75c135e 14455 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14456 break;
14457 default:
14458 generate_exception(ctx, EXCP_RI);
14459 break;
14460 }
14461 break;
460f00c4
AJ
14462 case OPC_SLT: /* Set on less than */
14463 case OPC_SLTU:
d75c135e 14464 gen_slt(ctx, op1, rd, rs, rt);
460f00c4
AJ
14465 break;
14466 case OPC_AND: /* Logic*/
14467 case OPC_OR:
14468 case OPC_NOR:
14469 case OPC_XOR:
d75c135e 14470 gen_logic(ctx, op1, rd, rs, rt);
460f00c4 14471 break;
7a387fff 14472 case OPC_MULT ... OPC_DIVU:
e9c71dd1 14473 if (sa) {
d75c135e 14474 check_insn(ctx, INSN_VR54XX);
e9c71dd1
TS
14475 op1 = MASK_MUL_VR54XX(ctx->opcode);
14476 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14477 } else
14478 gen_muldiv(ctx, op1, rs, rt);
7a387fff
TS
14479 break;
14480 case OPC_JR ... OPC_JALR:
7dca4ad0 14481 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061
NF
14482 *is_branch = 1;
14483 break;
7a387fff
TS
14484 case OPC_TGE ... OPC_TEQ: /* Traps */
14485 case OPC_TNE:
14486 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14487 break;
7a387fff
TS
14488 case OPC_MFHI: /* Move from HI/LO */
14489 case OPC_MFLO:
14490 gen_HILO(ctx, op1, rd);
6af0bf9c 14491 break;
7a387fff
TS
14492 case OPC_MTHI:
14493 case OPC_MTLO: /* Move to HI/LO */
14494 gen_HILO(ctx, op1, rs);
6af0bf9c 14495 break;
b48cfdff
TS
14496 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14497#ifdef MIPS_STRICT_STANDARD
14498 MIPS_INVAL("PMON / selsl");
14499 generate_exception(ctx, EXCP_RI);
14500#else
895c2d04 14501 gen_helper_0e0i(pmon, sa);
b48cfdff 14502#endif
7a387fff
TS
14503 break;
14504 case OPC_SYSCALL:
6af0bf9c 14505 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14506 ctx->bstate = BS_STOP;
6af0bf9c 14507 break;
7a387fff 14508 case OPC_BREAK:
6af0bf9c
FB
14509 generate_exception(ctx, EXCP_BREAK);
14510 break;
b48cfdff
TS
14511 case OPC_SPIM:
14512#ifdef MIPS_STRICT_STANDARD
14513 MIPS_INVAL("SPIM");
14514 generate_exception(ctx, EXCP_RI);
14515#else
7a387fff
TS
14516 /* Implemented as RI exception for now. */
14517 MIPS_INVAL("spim (unofficial)");
14518 generate_exception(ctx, EXCP_RI);
b48cfdff 14519#endif
6af0bf9c 14520 break;
7a387fff 14521 case OPC_SYNC:
ead9360e 14522 /* Treat as NOP. */
6af0bf9c 14523 break;
4ad40f36 14524
7a387fff 14525 case OPC_MOVCI:
d75c135e 14526 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14527 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14528 check_cp1_enabled(ctx);
36d23958
TS
14529 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14530 (ctx->opcode >> 16) & 1);
14531 } else {
e397ee33 14532 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14533 }
4ad40f36
FB
14534 break;
14535
d26bc211 14536#if defined(TARGET_MIPS64)
7a387fff
TS
14537 /* MIPS64 specific opcodes */
14538 case OPC_DSLL:
324d9e32 14539 case OPC_DSRA:
7a387fff 14540 case OPC_DSLL32:
324d9e32 14541 case OPC_DSRA32:
d75c135e 14542 check_insn(ctx, ISA_MIPS3);
e189e748 14543 check_mips_64(ctx);
d75c135e 14544 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14545 break;
ea63e2c3
NF
14546 case OPC_DSRL:
14547 switch ((ctx->opcode >> 21) & 0x1f) {
14548 case 1:
14549 /* drotr is decoded as dsrl on non-R2 CPUs */
d75c135e 14550 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14551 op1 = OPC_DROTR;
14552 }
14553 /* Fallthrough */
14554 case 0:
d75c135e 14555 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14556 check_mips_64(ctx);
d75c135e 14557 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14558 break;
14559 default:
14560 generate_exception(ctx, EXCP_RI);
14561 break;
14562 }
14563 break;
14564 case OPC_DSRL32:
14565 switch ((ctx->opcode >> 21) & 0x1f) {
14566 case 1:
14567 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
d75c135e 14568 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14569 op1 = OPC_DROTR32;
14570 }
14571 /* Fallthrough */
14572 case 0:
d75c135e 14573 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14574 check_mips_64(ctx);
d75c135e 14575 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14576 break;
14577 default:
14578 generate_exception(ctx, EXCP_RI);
14579 break;
14580 }
14581 break;
7a387fff 14582 case OPC_DADD ... OPC_DSUBU:
d75c135e 14583 check_insn(ctx, ISA_MIPS3);
e189e748 14584 check_mips_64(ctx);
d75c135e 14585 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14586 break;
460f00c4
AJ
14587 case OPC_DSLLV:
14588 case OPC_DSRAV:
d75c135e 14589 check_insn(ctx, ISA_MIPS3);
460f00c4 14590 check_mips_64(ctx);
d75c135e 14591 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14592 break;
ea63e2c3
NF
14593 case OPC_DSRLV:
14594 switch ((ctx->opcode >> 6) & 0x1f) {
14595 case 1:
14596 /* drotrv is decoded as dsrlv on non-R2 CPUs */
d75c135e 14597 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14598 op1 = OPC_DROTRV;
14599 }
14600 /* Fallthrough */
14601 case 0:
d75c135e 14602 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14603 check_mips_64(ctx);
d75c135e 14604 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14605 break;
14606 default:
14607 generate_exception(ctx, EXCP_RI);
14608 break;
14609 }
14610 break;
7a387fff 14611 case OPC_DMULT ... OPC_DDIVU:
d75c135e 14612 check_insn(ctx, ISA_MIPS3);
e189e748 14613 check_mips_64(ctx);
7a387fff
TS
14614 gen_muldiv(ctx, op1, rs, rt);
14615 break;
6af0bf9c
FB
14616#endif
14617 default: /* Invalid */
14618 MIPS_INVAL("special");
14619 generate_exception(ctx, EXCP_RI);
14620 break;
14621 }
14622 break;
7a387fff
TS
14623 case OPC_SPECIAL2:
14624 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14625 switch (op1) {
7a387fff
TS
14626 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14627 case OPC_MSUB ... OPC_MSUBU:
d75c135e 14628 check_insn(ctx, ISA_MIPS32);
7a387fff 14629 gen_muldiv(ctx, op1, rs, rt);
6af0bf9c 14630 break;
7a387fff 14631 case OPC_MUL:
d75c135e 14632 gen_arith(ctx, op1, rd, rs, rt);
6af0bf9c 14633 break;
20e1fb52
AJ
14634 case OPC_CLO:
14635 case OPC_CLZ:
d75c135e 14636 check_insn(ctx, ISA_MIPS32);
7a387fff 14637 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14638 break;
7a387fff 14639 case OPC_SDBBP:
6af0bf9c
FB
14640 /* XXX: not clear which exception should be raised
14641 * when in debug mode...
14642 */
d75c135e 14643 check_insn(ctx, ISA_MIPS32);
6af0bf9c
FB
14644 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14645 generate_exception(ctx, EXCP_DBp);
14646 } else {
14647 generate_exception(ctx, EXCP_DBp);
14648 }
ead9360e 14649 /* Treat as NOP. */
6af0bf9c 14650 break;
161f85e6
AJ
14651 case OPC_DIV_G_2F:
14652 case OPC_DIVU_G_2F:
14653 case OPC_MULT_G_2F:
14654 case OPC_MULTU_G_2F:
14655 case OPC_MOD_G_2F:
14656 case OPC_MODU_G_2F:
d75c135e 14657 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14658 gen_loongson_integer(ctx, op1, rd, rs, rt);
14659 break;
d26bc211 14660#if defined(TARGET_MIPS64)
20e1fb52
AJ
14661 case OPC_DCLO:
14662 case OPC_DCLZ:
d75c135e 14663 check_insn(ctx, ISA_MIPS64);
e189e748 14664 check_mips_64(ctx);
7a387fff
TS
14665 gen_cl(ctx, op1, rd, rs);
14666 break;
161f85e6
AJ
14667 case OPC_DMULT_G_2F:
14668 case OPC_DMULTU_G_2F:
14669 case OPC_DDIV_G_2F:
14670 case OPC_DDIVU_G_2F:
14671 case OPC_DMOD_G_2F:
14672 case OPC_DMODU_G_2F:
d75c135e 14673 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14674 gen_loongson_integer(ctx, op1, rd, rs, rt);
14675 break;
7a387fff 14676#endif
6af0bf9c
FB
14677 default: /* Invalid */
14678 MIPS_INVAL("special2");
14679 generate_exception(ctx, EXCP_RI);
14680 break;
14681 }
14682 break;
7a387fff 14683 case OPC_SPECIAL3:
2b0233ab
TS
14684 op1 = MASK_SPECIAL3(ctx->opcode);
14685 switch (op1) {
14686 case OPC_EXT:
14687 case OPC_INS:
d75c135e 14688 check_insn(ctx, ISA_MIPS32R2);
2b0233ab
TS
14689 gen_bitops(ctx, op1, rt, rs, sa, rd);
14690 break;
14691 case OPC_BSHFL:
d75c135e 14692 check_insn(ctx, ISA_MIPS32R2);
2b0233ab 14693 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14694 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14695 break;
1579a72e 14696 case OPC_RDHWR:
d75c135e 14697 gen_rdhwr(ctx, rt, rd);
1579a72e 14698 break;
ead9360e 14699 case OPC_FORK:
d75c135e 14700 check_insn(ctx, ASE_MT);
6c5c1e20 14701 {
35fbce2c
AJ
14702 TCGv t0 = tcg_temp_new();
14703 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14704
14705 gen_load_gpr(t0, rt);
14706 gen_load_gpr(t1, rs);
a7812ae4 14707 gen_helper_fork(t0, t1);
6c5c1e20
TS
14708 tcg_temp_free(t0);
14709 tcg_temp_free(t1);
14710 }
ead9360e
TS
14711 break;
14712 case OPC_YIELD:
d75c135e 14713 check_insn(ctx, ASE_MT);
6c5c1e20 14714 {
35fbce2c 14715 TCGv t0 = tcg_temp_new();
6c5c1e20 14716
35fbce2c 14717 save_cpu_state(ctx, 1);
6c5c1e20 14718 gen_load_gpr(t0, rs);
895c2d04 14719 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14720 gen_store_gpr(t0, rd);
14721 tcg_temp_free(t0);
14722 }
ead9360e 14723 break;
161f85e6 14724 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14725 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14726 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14727 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14728 * the same mask and op1. */
d75c135e 14729 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
461c08df
JL
14730 op2 = MASK_ADDUH_QB(ctx->opcode);
14731 switch (op2) {
14732 case OPC_ADDUH_QB:
14733 case OPC_ADDUH_R_QB:
14734 case OPC_ADDQH_PH:
14735 case OPC_ADDQH_R_PH:
14736 case OPC_ADDQH_W:
14737 case OPC_ADDQH_R_W:
14738 case OPC_SUBUH_QB:
14739 case OPC_SUBUH_R_QB:
14740 case OPC_SUBQH_PH:
14741 case OPC_SUBQH_R_PH:
14742 case OPC_SUBQH_W:
14743 case OPC_SUBQH_R_W:
14744 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14745 break;
a22260ae
JL
14746 case OPC_MUL_PH:
14747 case OPC_MUL_S_PH:
14748 case OPC_MULQ_S_W:
14749 case OPC_MULQ_RS_W:
14750 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14751 break;
461c08df
JL
14752 default:
14753 MIPS_INVAL("MASK ADDUH.QB");
14754 generate_exception(ctx, EXCP_RI);
14755 break;
14756 }
d75c135e 14757 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
461c08df
JL
14758 gen_loongson_integer(ctx, op1, rd, rs, rt);
14759 } else {
14760 generate_exception(ctx, EXCP_RI);
14761 }
161f85e6 14762 break;
9b1a1d68
JL
14763 case OPC_LX_DSP:
14764 op2 = MASK_LX(ctx->opcode);
14765 switch (op2) {
14766#if defined(TARGET_MIPS64)
14767 case OPC_LDX:
14768#endif
14769 case OPC_LBUX:
14770 case OPC_LHX:
14771 case OPC_LWX:
d75c135e 14772 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
9b1a1d68
JL
14773 break;
14774 default: /* Invalid */
14775 MIPS_INVAL("MASK LX");
14776 generate_exception(ctx, EXCP_RI);
14777 break;
14778 }
14779 break;
461c08df
JL
14780 case OPC_ABSQ_S_PH_DSP:
14781 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14782 switch (op2) {
14783 case OPC_ABSQ_S_QB:
14784 case OPC_ABSQ_S_PH:
14785 case OPC_ABSQ_S_W:
14786 case OPC_PRECEQ_W_PHL:
14787 case OPC_PRECEQ_W_PHR:
14788 case OPC_PRECEQU_PH_QBL:
14789 case OPC_PRECEQU_PH_QBR:
14790 case OPC_PRECEQU_PH_QBLA:
14791 case OPC_PRECEQU_PH_QBRA:
14792 case OPC_PRECEU_PH_QBL:
14793 case OPC_PRECEU_PH_QBR:
14794 case OPC_PRECEU_PH_QBLA:
14795 case OPC_PRECEU_PH_QBRA:
14796 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14797 break;
1cb6686c
JL
14798 case OPC_BITREV:
14799 case OPC_REPL_QB:
14800 case OPC_REPLV_QB:
14801 case OPC_REPL_PH:
14802 case OPC_REPLV_PH:
d75c135e 14803 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 14804 break;
461c08df
JL
14805 default:
14806 MIPS_INVAL("MASK ABSQ_S.PH");
14807 generate_exception(ctx, EXCP_RI);
14808 break;
14809 }
14810 break;
14811 case OPC_ADDU_QB_DSP:
14812 op2 = MASK_ADDU_QB(ctx->opcode);
14813 switch (op2) {
14814 case OPC_ADDQ_PH:
14815 case OPC_ADDQ_S_PH:
14816 case OPC_ADDQ_S_W:
14817 case OPC_ADDU_QB:
14818 case OPC_ADDU_S_QB:
14819 case OPC_ADDU_PH:
14820 case OPC_ADDU_S_PH:
14821 case OPC_SUBQ_PH:
14822 case OPC_SUBQ_S_PH:
14823 case OPC_SUBQ_S_W:
14824 case OPC_SUBU_QB:
14825 case OPC_SUBU_S_QB:
14826 case OPC_SUBU_PH:
14827 case OPC_SUBU_S_PH:
14828 case OPC_ADDSC:
14829 case OPC_ADDWC:
14830 case OPC_MODSUB:
14831 case OPC_RADDU_W_QB:
14832 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14833 break;
a22260ae
JL
14834 case OPC_MULEU_S_PH_QBL:
14835 case OPC_MULEU_S_PH_QBR:
14836 case OPC_MULQ_RS_PH:
14837 case OPC_MULEQ_S_W_PHL:
14838 case OPC_MULEQ_S_W_PHR:
14839 case OPC_MULQ_S_PH:
14840 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14841 break;
461c08df
JL
14842 default: /* Invalid */
14843 MIPS_INVAL("MASK ADDU.QB");
14844 generate_exception(ctx, EXCP_RI);
14845 break;
14846
14847 }
14848 break;
14849 case OPC_CMPU_EQ_QB_DSP:
14850 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14851 switch (op2) {
14852 case OPC_PRECR_SRA_PH_W:
14853 case OPC_PRECR_SRA_R_PH_W:
14854 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14855 break;
14856 case OPC_PRECR_QB_PH:
14857 case OPC_PRECRQ_QB_PH:
14858 case OPC_PRECRQ_PH_W:
14859 case OPC_PRECRQ_RS_PH_W:
14860 case OPC_PRECRQU_S_QB_PH:
14861 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14862 break;
26690560
JL
14863 case OPC_CMPU_EQ_QB:
14864 case OPC_CMPU_LT_QB:
14865 case OPC_CMPU_LE_QB:
14866 case OPC_CMP_EQ_PH:
14867 case OPC_CMP_LT_PH:
14868 case OPC_CMP_LE_PH:
14869 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14870 break;
14871 case OPC_CMPGU_EQ_QB:
14872 case OPC_CMPGU_LT_QB:
14873 case OPC_CMPGU_LE_QB:
14874 case OPC_CMPGDU_EQ_QB:
14875 case OPC_CMPGDU_LT_QB:
14876 case OPC_CMPGDU_LE_QB:
14877 case OPC_PICK_QB:
14878 case OPC_PICK_PH:
14879 case OPC_PACKRL_PH:
14880 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14881 break;
461c08df
JL
14882 default: /* Invalid */
14883 MIPS_INVAL("MASK CMPU.EQ.QB");
14884 generate_exception(ctx, EXCP_RI);
14885 break;
14886 }
14887 break;
77c5fa8b
JL
14888 case OPC_SHLL_QB_DSP:
14889 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14890 break;
a22260ae
JL
14891 case OPC_DPA_W_PH_DSP:
14892 op2 = MASK_DPA_W_PH(ctx->opcode);
14893 switch (op2) {
14894 case OPC_DPAU_H_QBL:
14895 case OPC_DPAU_H_QBR:
14896 case OPC_DPSU_H_QBL:
14897 case OPC_DPSU_H_QBR:
14898 case OPC_DPA_W_PH:
14899 case OPC_DPAX_W_PH:
14900 case OPC_DPAQ_S_W_PH:
14901 case OPC_DPAQX_S_W_PH:
14902 case OPC_DPAQX_SA_W_PH:
14903 case OPC_DPS_W_PH:
14904 case OPC_DPSX_W_PH:
14905 case OPC_DPSQ_S_W_PH:
14906 case OPC_DPSQX_S_W_PH:
14907 case OPC_DPSQX_SA_W_PH:
14908 case OPC_MULSAQ_S_W_PH:
14909 case OPC_DPAQ_SA_L_W:
14910 case OPC_DPSQ_SA_L_W:
14911 case OPC_MAQ_S_W_PHL:
14912 case OPC_MAQ_S_W_PHR:
14913 case OPC_MAQ_SA_W_PHL:
14914 case OPC_MAQ_SA_W_PHR:
14915 case OPC_MULSA_W_PH:
14916 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14917 break;
14918 default: /* Invalid */
14919 MIPS_INVAL("MASK DPAW.PH");
14920 generate_exception(ctx, EXCP_RI);
14921 break;
14922 }
14923 break;
1cb6686c
JL
14924 case OPC_INSV_DSP:
14925 op2 = MASK_INSV(ctx->opcode);
14926 switch (op2) {
14927 case OPC_INSV:
14928 check_dsp(ctx);
14929 {
14930 TCGv t0, t1;
14931
14932 if (rt == 0) {
14933 MIPS_DEBUG("NOP");
14934 break;
14935 }
14936
14937 t0 = tcg_temp_new();
14938 t1 = tcg_temp_new();
14939
14940 gen_load_gpr(t0, rt);
14941 gen_load_gpr(t1, rs);
14942
14943 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14944
14945 tcg_temp_free(t0);
14946 tcg_temp_free(t1);
14947 break;
14948 }
14949 default: /* Invalid */
14950 MIPS_INVAL("MASK INSV");
14951 generate_exception(ctx, EXCP_RI);
14952 break;
14953 }
14954 break;
26690560 14955 case OPC_APPEND_DSP:
df6126a7 14956 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 14957 break;
b53371ed
JL
14958 case OPC_EXTR_W_DSP:
14959 op2 = MASK_EXTR_W(ctx->opcode);
14960 switch (op2) {
14961 case OPC_EXTR_W:
14962 case OPC_EXTR_R_W:
14963 case OPC_EXTR_RS_W:
14964 case OPC_EXTR_S_H:
14965 case OPC_EXTRV_S_H:
14966 case OPC_EXTRV_W:
14967 case OPC_EXTRV_R_W:
14968 case OPC_EXTRV_RS_W:
14969 case OPC_EXTP:
14970 case OPC_EXTPV:
14971 case OPC_EXTPDP:
14972 case OPC_EXTPDPV:
14973 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14974 break;
14975 case OPC_RDDSP:
14976 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14977 break;
14978 case OPC_SHILO:
14979 case OPC_SHILOV:
14980 case OPC_MTHLIP:
14981 case OPC_WRDSP:
14982 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14983 break;
14984 default: /* Invalid */
14985 MIPS_INVAL("MASK EXTR.W");
14986 generate_exception(ctx, EXCP_RI);
14987 break;
14988 }
14989 break;
d26bc211 14990#if defined(TARGET_MIPS64)
1579a72e
TS
14991 case OPC_DEXTM ... OPC_DEXT:
14992 case OPC_DINSM ... OPC_DINS:
d75c135e 14993 check_insn(ctx, ISA_MIPS64R2);
e189e748 14994 check_mips_64(ctx);
1579a72e 14995 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 14996 break;
1579a72e 14997 case OPC_DBSHFL:
d75c135e 14998 check_insn(ctx, ISA_MIPS64R2);
e189e748 14999 check_mips_64(ctx);
1579a72e 15000 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 15001 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 15002 break;
161f85e6
AJ
15003 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15004 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15005 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
d75c135e 15006 check_insn(ctx, INSN_LOONGSON2E);
161f85e6
AJ
15007 gen_loongson_integer(ctx, op1, rd, rs, rt);
15008 break;
461c08df
JL
15009 case OPC_ABSQ_S_QH_DSP:
15010 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15011 switch (op2) {
15012 case OPC_PRECEQ_L_PWL:
15013 case OPC_PRECEQ_L_PWR:
15014 case OPC_PRECEQ_PW_QHL:
15015 case OPC_PRECEQ_PW_QHR:
15016 case OPC_PRECEQ_PW_QHLA:
15017 case OPC_PRECEQ_PW_QHRA:
15018 case OPC_PRECEQU_QH_OBL:
15019 case OPC_PRECEQU_QH_OBR:
15020 case OPC_PRECEQU_QH_OBLA:
15021 case OPC_PRECEQU_QH_OBRA:
15022 case OPC_PRECEU_QH_OBL:
15023 case OPC_PRECEU_QH_OBR:
15024 case OPC_PRECEU_QH_OBLA:
15025 case OPC_PRECEU_QH_OBRA:
15026 case OPC_ABSQ_S_OB:
15027 case OPC_ABSQ_S_PW:
15028 case OPC_ABSQ_S_QH:
15029 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15030 break;
1cb6686c
JL
15031 case OPC_REPL_OB:
15032 case OPC_REPL_PW:
15033 case OPC_REPL_QH:
15034 case OPC_REPLV_OB:
15035 case OPC_REPLV_PW:
15036 case OPC_REPLV_QH:
d75c135e 15037 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 15038 break;
461c08df
JL
15039 default: /* Invalid */
15040 MIPS_INVAL("MASK ABSQ_S.QH");
15041 generate_exception(ctx, EXCP_RI);
15042 break;
15043 }
15044 break;
15045 case OPC_ADDU_OB_DSP:
15046 op2 = MASK_ADDU_OB(ctx->opcode);
15047 switch (op2) {
15048 case OPC_RADDU_L_OB:
15049 case OPC_SUBQ_PW:
15050 case OPC_SUBQ_S_PW:
15051 case OPC_SUBQ_QH:
15052 case OPC_SUBQ_S_QH:
15053 case OPC_SUBU_OB:
15054 case OPC_SUBU_S_OB:
15055 case OPC_SUBU_QH:
15056 case OPC_SUBU_S_QH:
15057 case OPC_SUBUH_OB:
15058 case OPC_SUBUH_R_OB:
15059 case OPC_ADDQ_PW:
15060 case OPC_ADDQ_S_PW:
15061 case OPC_ADDQ_QH:
15062 case OPC_ADDQ_S_QH:
15063 case OPC_ADDU_OB:
15064 case OPC_ADDU_S_OB:
15065 case OPC_ADDU_QH:
15066 case OPC_ADDU_S_QH:
15067 case OPC_ADDUH_OB:
15068 case OPC_ADDUH_R_OB:
15069 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15070 break;
a22260ae
JL
15071 case OPC_MULEQ_S_PW_QHL:
15072 case OPC_MULEQ_S_PW_QHR:
15073 case OPC_MULEU_S_QH_OBL:
15074 case OPC_MULEU_S_QH_OBR:
15075 case OPC_MULQ_RS_QH:
15076 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15077 break;
461c08df
JL
15078 default: /* Invalid */
15079 MIPS_INVAL("MASK ADDU.OB");
15080 generate_exception(ctx, EXCP_RI);
15081 break;
15082 }
15083 break;
15084 case OPC_CMPU_EQ_OB_DSP:
15085 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15086 switch (op2) {
15087 case OPC_PRECR_SRA_QH_PW:
15088 case OPC_PRECR_SRA_R_QH_PW:
15089 /* Return value is rt. */
15090 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15091 break;
15092 case OPC_PRECR_OB_QH:
15093 case OPC_PRECRQ_OB_QH:
15094 case OPC_PRECRQ_PW_L:
15095 case OPC_PRECRQ_QH_PW:
15096 case OPC_PRECRQ_RS_QH_PW:
15097 case OPC_PRECRQU_S_OB_QH:
15098 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15099 break;
26690560
JL
15100 case OPC_CMPU_EQ_OB:
15101 case OPC_CMPU_LT_OB:
15102 case OPC_CMPU_LE_OB:
15103 case OPC_CMP_EQ_QH:
15104 case OPC_CMP_LT_QH:
15105 case OPC_CMP_LE_QH:
15106 case OPC_CMP_EQ_PW:
15107 case OPC_CMP_LT_PW:
15108 case OPC_CMP_LE_PW:
15109 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15110 break;
15111 case OPC_CMPGDU_EQ_OB:
15112 case OPC_CMPGDU_LT_OB:
15113 case OPC_CMPGDU_LE_OB:
15114 case OPC_CMPGU_EQ_OB:
15115 case OPC_CMPGU_LT_OB:
15116 case OPC_CMPGU_LE_OB:
15117 case OPC_PACKRL_PW:
15118 case OPC_PICK_OB:
15119 case OPC_PICK_PW:
15120 case OPC_PICK_QH:
15121 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15122 break;
461c08df
JL
15123 default: /* Invalid */
15124 MIPS_INVAL("MASK CMPU_EQ.OB");
15125 generate_exception(ctx, EXCP_RI);
15126 break;
15127 }
15128 break;
26690560 15129 case OPC_DAPPEND_DSP:
df6126a7 15130 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 15131 break;
b53371ed
JL
15132 case OPC_DEXTR_W_DSP:
15133 op2 = MASK_DEXTR_W(ctx->opcode);
15134 switch (op2) {
15135 case OPC_DEXTP:
15136 case OPC_DEXTPDP:
15137 case OPC_DEXTPDPV:
15138 case OPC_DEXTPV:
15139 case OPC_DEXTR_L:
15140 case OPC_DEXTR_R_L:
15141 case OPC_DEXTR_RS_L:
15142 case OPC_DEXTR_W:
15143 case OPC_DEXTR_R_W:
15144 case OPC_DEXTR_RS_W:
15145 case OPC_DEXTR_S_H:
15146 case OPC_DEXTRV_L:
15147 case OPC_DEXTRV_R_L:
15148 case OPC_DEXTRV_RS_L:
15149 case OPC_DEXTRV_S_H:
15150 case OPC_DEXTRV_W:
15151 case OPC_DEXTRV_R_W:
15152 case OPC_DEXTRV_RS_W:
15153 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15154 break;
15155 case OPC_DMTHLIP:
15156 case OPC_DSHILO:
15157 case OPC_DSHILOV:
15158 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15159 break;
15160 default: /* Invalid */
15161 MIPS_INVAL("MASK EXTR.W");
15162 generate_exception(ctx, EXCP_RI);
15163 break;
15164 }
15165 break;
a22260ae
JL
15166 case OPC_DPAQ_W_QH_DSP:
15167 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15168 switch (op2) {
15169 case OPC_DPAU_H_OBL:
15170 case OPC_DPAU_H_OBR:
15171 case OPC_DPSU_H_OBL:
15172 case OPC_DPSU_H_OBR:
15173 case OPC_DPA_W_QH:
15174 case OPC_DPAQ_S_W_QH:
15175 case OPC_DPS_W_QH:
15176 case OPC_DPSQ_S_W_QH:
15177 case OPC_MULSAQ_S_W_QH:
15178 case OPC_DPAQ_SA_L_PW:
15179 case OPC_DPSQ_SA_L_PW:
15180 case OPC_MULSAQ_S_L_PW:
15181 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15182 break;
15183 case OPC_MAQ_S_W_QHLL:
15184 case OPC_MAQ_S_W_QHLR:
15185 case OPC_MAQ_S_W_QHRL:
15186 case OPC_MAQ_S_W_QHRR:
15187 case OPC_MAQ_SA_W_QHLL:
15188 case OPC_MAQ_SA_W_QHLR:
15189 case OPC_MAQ_SA_W_QHRL:
15190 case OPC_MAQ_SA_W_QHRR:
15191 case OPC_MAQ_S_L_PWL:
15192 case OPC_MAQ_S_L_PWR:
15193 case OPC_DMADD:
15194 case OPC_DMADDU:
15195 case OPC_DMSUB:
15196 case OPC_DMSUBU:
15197 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15198 break;
15199 default: /* Invalid */
15200 MIPS_INVAL("MASK DPAQ.W.QH");
15201 generate_exception(ctx, EXCP_RI);
15202 break;
15203 }
15204 break;
1cb6686c
JL
15205 case OPC_DINSV_DSP:
15206 op2 = MASK_INSV(ctx->opcode);
15207 switch (op2) {
15208 case OPC_DINSV:
15209 {
15210 TCGv t0, t1;
15211
15212 if (rt == 0) {
15213 MIPS_DEBUG("NOP");
15214 break;
15215 }
15216 check_dsp(ctx);
15217
15218 t0 = tcg_temp_new();
15219 t1 = tcg_temp_new();
15220
15221 gen_load_gpr(t0, rt);
15222 gen_load_gpr(t1, rs);
15223
15224 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15225 break;
15226 }
15227 default: /* Invalid */
15228 MIPS_INVAL("MASK DINSV");
15229 generate_exception(ctx, EXCP_RI);
15230 break;
15231 }
15232 break;
77c5fa8b
JL
15233 case OPC_SHLL_OB_DSP:
15234 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15235 break;
7a387fff
TS
15236#endif
15237 default: /* Invalid */
15238 MIPS_INVAL("special3");
15239 generate_exception(ctx, EXCP_RI);
15240 break;
15241 }
15242 break;
15243 case OPC_REGIMM:
15244 op1 = MASK_REGIMM(ctx->opcode);
15245 switch (op1) {
15246 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15247 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15248 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061
NF
15249 *is_branch = 1;
15250 break;
7a387fff
TS
15251 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15252 case OPC_TNEI:
15253 gen_trap(ctx, op1, rs, -1, imm);
15254 break;
15255 case OPC_SYNCI:
d75c135e 15256 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15257 /* Treat as NOP. */
6af0bf9c 15258 break;
e45a93e2
JL
15259 case OPC_BPOSGE32: /* MIPS DSP branch */
15260#if defined(TARGET_MIPS64)
15261 case OPC_BPOSGE64:
15262#endif
15263 check_dsp(ctx);
15264 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15265 *is_branch = 1;
15266 break;
6af0bf9c 15267 default: /* Invalid */
923617a3 15268 MIPS_INVAL("regimm");
6af0bf9c
FB
15269 generate_exception(ctx, EXCP_RI);
15270 break;
15271 }
15272 break;
7a387fff 15273 case OPC_CP0:
387a8fe5 15274 check_cp0_enabled(ctx);
7a387fff 15275 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15276 switch (op1) {
7a387fff
TS
15277 case OPC_MFC0:
15278 case OPC_MTC0:
ead9360e
TS
15279 case OPC_MFTR:
15280 case OPC_MTTR:
d26bc211 15281#if defined(TARGET_MIPS64)
7a387fff
TS
15282 case OPC_DMFC0:
15283 case OPC_DMTC0:
15284#endif
f1aa6320 15285#ifndef CONFIG_USER_ONLY
932e71cd 15286 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15287#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15288 break;
15289 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15290#ifndef CONFIG_USER_ONLY
932e71cd 15291 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15292#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15293 break;
15294 case OPC_MFMC0:
8706c382 15295#ifndef CONFIG_USER_ONLY
932e71cd 15296 {
35fbce2c 15297 TCGv t0 = tcg_temp_new();
6c5c1e20 15298
0eaef5aa 15299 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15300 switch (op2) {
15301 case OPC_DMT:
d75c135e 15302 check_insn(ctx, ASE_MT);
9ed5726c 15303 gen_helper_dmt(t0);
35fbce2c 15304 gen_store_gpr(t0, rt);
6c5c1e20
TS
15305 break;
15306 case OPC_EMT:
d75c135e 15307 check_insn(ctx, ASE_MT);
9ed5726c 15308 gen_helper_emt(t0);
35fbce2c 15309 gen_store_gpr(t0, rt);
da80682b 15310 break;
6c5c1e20 15311 case OPC_DVPE:
d75c135e 15312 check_insn(ctx, ASE_MT);
895c2d04 15313 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15314 gen_store_gpr(t0, rt);
6c5c1e20
TS
15315 break;
15316 case OPC_EVPE:
d75c135e 15317 check_insn(ctx, ASE_MT);
895c2d04 15318 gen_helper_evpe(t0, cpu_env);
35fbce2c 15319 gen_store_gpr(t0, rt);
6c5c1e20
TS
15320 break;
15321 case OPC_DI:
d75c135e 15322 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15323 save_cpu_state(ctx, 1);
895c2d04 15324 gen_helper_di(t0, cpu_env);
35fbce2c 15325 gen_store_gpr(t0, rt);
6c5c1e20
TS
15326 /* Stop translation as we may have switched the execution mode */
15327 ctx->bstate = BS_STOP;
15328 break;
15329 case OPC_EI:
d75c135e 15330 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15331 save_cpu_state(ctx, 1);
895c2d04 15332 gen_helper_ei(t0, cpu_env);
35fbce2c 15333 gen_store_gpr(t0, rt);
6c5c1e20
TS
15334 /* Stop translation as we may have switched the execution mode */
15335 ctx->bstate = BS_STOP;
15336 break;
15337 default: /* Invalid */
15338 MIPS_INVAL("mfmc0");
15339 generate_exception(ctx, EXCP_RI);
15340 break;
15341 }
6c5c1e20 15342 tcg_temp_free(t0);
7a387fff 15343 }
0eaef5aa 15344#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15345 break;
7a387fff 15346 case OPC_RDPGPR:
d75c135e 15347 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15348 gen_load_srsgpr(rt, rd);
ead9360e 15349 break;
7a387fff 15350 case OPC_WRPGPR:
d75c135e 15351 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15352 gen_store_srsgpr(rt, rd);
38121543 15353 break;
6af0bf9c 15354 default:
923617a3 15355 MIPS_INVAL("cp0");
7a387fff 15356 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15357 break;
15358 }
15359 break;
324d9e32
AJ
15360 case OPC_ADDI: /* Arithmetic with immediate opcode */
15361 case OPC_ADDIU:
d75c135e 15362 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15363 break;
324d9e32
AJ
15364 case OPC_SLTI: /* Set on less than with immediate opcode */
15365 case OPC_SLTIU:
d75c135e 15366 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15367 break;
15368 case OPC_ANDI: /* Arithmetic with immediate opcode */
15369 case OPC_LUI:
15370 case OPC_ORI:
15371 case OPC_XORI:
d75c135e 15372 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15373 break;
7a387fff
TS
15374 case OPC_J ... OPC_JAL: /* Jump */
15375 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15376 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061
NF
15377 *is_branch = 1;
15378 break;
7a387fff
TS
15379 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15380 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15381 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061
NF
15382 *is_branch = 1;
15383 break;
7a387fff 15384 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15385 case OPC_LL:
d75c135e 15386 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15387 break;
7a387fff
TS
15388 case OPC_SB ... OPC_SW:
15389 case OPC_SWR:
5c13fdfd 15390 gen_st(ctx, op, rt, rs, imm);
7a387fff 15391 break;
d66c7132
AJ
15392 case OPC_SC:
15393 gen_st_cond(ctx, op, rt, rs, imm);
15394 break;
7a387fff 15395 case OPC_CACHE:
2e15497c 15396 check_cp0_enabled(ctx);
d75c135e 15397 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15398 /* Treat as NOP. */
34ae7b51 15399 break;
7a387fff 15400 case OPC_PREF:
d75c135e 15401 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15402 /* Treat as NOP. */
6af0bf9c 15403 break;
4ad40f36 15404
923617a3 15405 /* Floating point (COP1). */
7a387fff
TS
15406 case OPC_LWC1:
15407 case OPC_LDC1:
15408 case OPC_SWC1:
15409 case OPC_SDC1:
26ebe468 15410 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15411 break;
15412
7a387fff 15413 case OPC_CP1:
36d23958 15414 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15415 check_cp1_enabled(ctx);
36d23958
TS
15416 op1 = MASK_CP1(ctx->opcode);
15417 switch (op1) {
3a95e3a7
TS
15418 case OPC_MFHC1:
15419 case OPC_MTHC1:
d75c135e 15420 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
15421 case OPC_MFC1:
15422 case OPC_CFC1:
15423 case OPC_MTC1:
15424 case OPC_CTC1:
e189e748
TS
15425 gen_cp1(ctx, op1, rt, rd);
15426 break;
d26bc211 15427#if defined(TARGET_MIPS64)
36d23958
TS
15428 case OPC_DMFC1:
15429 case OPC_DMTC1:
d75c135e 15430 check_insn(ctx, ISA_MIPS3);
36d23958
TS
15431 gen_cp1(ctx, op1, rt, rd);
15432 break;
e189e748 15433#endif
fbcc6828
TS
15434 case OPC_BC1ANY2:
15435 case OPC_BC1ANY4:
b8aa4598 15436 check_cop1x(ctx);
d75c135e 15437 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
15438 /* fall through */
15439 case OPC_BC1:
d75c135e 15440 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15441 (rt >> 2) & 0x7, imm << 2);
c9602061
NF
15442 *is_branch = 1;
15443 break;
36d23958
TS
15444 case OPC_S_FMT:
15445 case OPC_D_FMT:
15446 case OPC_W_FMT:
15447 case OPC_L_FMT:
5a5012ec 15448 case OPC_PS_FMT:
bf4120ad 15449 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15450 (imm >> 8) & 0x7);
36d23958
TS
15451 break;
15452 default:
923617a3 15453 MIPS_INVAL("cp1");
e397ee33 15454 generate_exception (ctx, EXCP_RI);
36d23958
TS
15455 break;
15456 }
15457 } else {
15458 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15459 }
4ad40f36
FB
15460 break;
15461
15462 /* COP2. */
7a387fff
TS
15463 case OPC_LWC2:
15464 case OPC_LDC2:
15465 case OPC_SWC2:
15466 case OPC_SDC2:
7a387fff 15467 /* COP2: Not implemented. */
4ad40f36
FB
15468 generate_exception_err(ctx, EXCP_CpU, 2);
15469 break;
bd277fa1 15470 case OPC_CP2:
d75c135e 15471 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
15472 /* Note that these instructions use different fields. */
15473 gen_loongson_multimedia(ctx, sa, rd, rt);
15474 break;
4ad40f36 15475
7a387fff 15476 case OPC_CP3:
36d23958 15477 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15478 check_cp1_enabled(ctx);
36d23958
TS
15479 op1 = MASK_CP3(ctx->opcode);
15480 switch (op1) {
5a5012ec
TS
15481 case OPC_LWXC1:
15482 case OPC_LDXC1:
15483 case OPC_LUXC1:
15484 case OPC_SWXC1:
15485 case OPC_SDXC1:
15486 case OPC_SUXC1:
93b12ccc 15487 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15488 break;
e0c84da7 15489 case OPC_PREFX:
ead9360e 15490 /* Treat as NOP. */
e0c84da7 15491 break;
5a5012ec
TS
15492 case OPC_ALNV_PS:
15493 case OPC_MADD_S:
15494 case OPC_MADD_D:
15495 case OPC_MADD_PS:
15496 case OPC_MSUB_S:
15497 case OPC_MSUB_D:
15498 case OPC_MSUB_PS:
15499 case OPC_NMADD_S:
15500 case OPC_NMADD_D:
15501 case OPC_NMADD_PS:
15502 case OPC_NMSUB_S:
15503 case OPC_NMSUB_D:
15504 case OPC_NMSUB_PS:
15505 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15506 break;
36d23958 15507 default:
923617a3 15508 MIPS_INVAL("cp3");
e397ee33 15509 generate_exception (ctx, EXCP_RI);
36d23958
TS
15510 break;
15511 }
15512 } else {
e397ee33 15513 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15514 }
4ad40f36
FB
15515 break;
15516
d26bc211 15517#if defined(TARGET_MIPS64)
7a387fff
TS
15518 /* MIPS64 opcodes */
15519 case OPC_LWU:
15520 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15521 case OPC_LLD:
15522 case OPC_LD:
d75c135e 15523 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15524 check_mips_64(ctx);
d75c135e 15525 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
15526 break;
15527 case OPC_SDL ... OPC_SDR:
7a387fff 15528 case OPC_SD:
d75c135e 15529 check_insn(ctx, ISA_MIPS3);
e189e748 15530 check_mips_64(ctx);
5c13fdfd 15531 gen_st(ctx, op, rt, rs, imm);
7a387fff 15532 break;
d66c7132 15533 case OPC_SCD:
d75c135e 15534 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
15535 check_mips_64(ctx);
15536 gen_st_cond(ctx, op, rt, rs, imm);
15537 break;
324d9e32
AJ
15538 case OPC_DADDI:
15539 case OPC_DADDIU:
d75c135e 15540 check_insn(ctx, ISA_MIPS3);
e189e748 15541 check_mips_64(ctx);
d75c135e 15542 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15543 break;
6af0bf9c 15544#endif
7a387fff 15545 case OPC_JALX:
d75c135e 15546 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15547 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15548 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15549 *is_branch = 1;
15550 break;
7a387fff 15551 case OPC_MDMX:
d75c135e 15552 check_insn(ctx, ASE_MDMX);
7a387fff 15553 /* MDMX: Not implemented. */
6af0bf9c 15554 default: /* Invalid */
923617a3 15555 MIPS_INVAL("major opcode");
6af0bf9c
FB
15556 generate_exception(ctx, EXCP_RI);
15557 break;
15558 }
6af0bf9c
FB
15559}
15560
2cfc5f17 15561static inline void
7db13fae 15562gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
820e00f2 15563 int search_pc)
6af0bf9c 15564{
278d0702 15565 DisasContext ctx;
6af0bf9c
FB
15566 target_ulong pc_start;
15567 uint16_t *gen_opc_end;
a1d1bb31 15568 CPUBreakpoint *bp;
6af0bf9c 15569 int j, lj = -1;
2e70f6ef
PB
15570 int num_insns;
15571 int max_insns;
c9602061
NF
15572 int insn_bytes;
15573 int is_branch;
6af0bf9c 15574
93fcfe39
AL
15575 if (search_pc)
15576 qemu_log("search pc %d\n", search_pc);
4ad40f36 15577
6af0bf9c 15578 pc_start = tb->pc;
92414b31 15579 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15580 ctx.pc = pc_start;
4ad40f36 15581 ctx.saved_pc = -1;
7b270ef2 15582 ctx.singlestep_enabled = env->singlestep_enabled;
d75c135e 15583 ctx.insn_flags = env->insn_flags;
6af0bf9c
FB
15584 ctx.tb = tb;
15585 ctx.bstate = BS_NONE;
4ad40f36 15586 /* Restore delay slot state from the tb context. */
c068688b 15587 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
fd4a04eb 15588 restore_cpu_state(env, &ctx);
932e71cd 15589#ifdef CONFIG_USER_ONLY
0eaef5aa 15590 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15591#else
0eaef5aa 15592 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15593#endif
2e70f6ef
PB
15594 num_insns = 0;
15595 max_insns = tb->cflags & CF_COUNT_MASK;
15596 if (max_insns == 0)
15597 max_insns = CF_COUNT_MASK;
d12d51d5 15598 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
2e70f6ef 15599 gen_icount_start();
faf7aaa9 15600 while (ctx.bstate == BS_NONE) {
72cf2d4f
BS
15601 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15602 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 15603 if (bp->pc == ctx.pc) {
278d0702 15604 save_cpu_state(&ctx, 1);
4ad40f36 15605 ctx.bstate = BS_BRANCH;
895c2d04 15606 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15607 /* Include the breakpoint location or the tb won't
15608 * be flushed when it must be. */
15609 ctx.pc += 4;
4ad40f36
FB
15610 goto done_generating;
15611 }
15612 }
15613 }
15614
6af0bf9c 15615 if (search_pc) {
92414b31 15616 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15617 if (lj < j) {
15618 lj++;
15619 while (lj < j)
ab1103de 15620 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 15621 }
25983cad 15622 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 15623 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15624 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 15625 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 15626 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 15627 }
2e70f6ef
PB
15628 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15629 gen_io_start();
c9602061
NF
15630
15631 is_branch = 0;
364d4831 15632 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15633 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061
NF
15634 insn_bytes = 4;
15635 decode_opc(env, &ctx, &is_branch);
d75c135e 15636 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 15637 ctx.opcode = cpu_lduw_code(env, ctx.pc);
3c824109 15638 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
d75c135e 15639 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 15640 ctx.opcode = cpu_lduw_code(env, ctx.pc);
364d4831 15641 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
c9602061
NF
15642 } else {
15643 generate_exception(&ctx, EXCP_RI);
3c824109 15644 ctx.bstate = BS_STOP;
c9602061
NF
15645 break;
15646 }
15647 if (!is_branch) {
d75c135e 15648 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
15649 }
15650 ctx.pc += insn_bytes;
15651
2e70f6ef 15652 num_insns++;
4ad40f36 15653
7b270ef2
NF
15654 /* Execute a branch and its delay slot as a single instruction.
15655 This is what GDB expects and is consistent with what the
15656 hardware does (e.g. if a delay slot instruction faults, the
15657 reported PC is the PC of the branch). */
15658 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
4ad40f36
FB
15659 break;
15660
6af0bf9c
FB
15661 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15662 break;
4ad40f36 15663
efd7f486 15664 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 15665 break;
efd7f486 15666 }
faf7aaa9 15667
2e70f6ef
PB
15668 if (num_insns >= max_insns)
15669 break;
1b530a6d
AJ
15670
15671 if (singlestep)
15672 break;
6af0bf9c 15673 }
2e70f6ef
PB
15674 if (tb->cflags & CF_LAST_IO)
15675 gen_io_end();
7b270ef2 15676 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15677 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15678 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15679 } else {
6958549d 15680 switch (ctx.bstate) {
16c00cb2 15681 case BS_STOP:
df1561e2
TS
15682 gen_goto_tb(&ctx, 0, ctx.pc);
15683 break;
16c00cb2 15684 case BS_NONE:
278d0702 15685 save_cpu_state(&ctx, 0);
16c00cb2
TS
15686 gen_goto_tb(&ctx, 0, ctx.pc);
15687 break;
5a5012ec 15688 case BS_EXCP:
57fec1fe 15689 tcg_gen_exit_tb(0);
16c00cb2 15690 break;
5a5012ec
TS
15691 case BS_BRANCH:
15692 default:
15693 break;
6958549d 15694 }
6af0bf9c 15695 }
4ad40f36 15696done_generating:
2e70f6ef 15697 gen_icount_end(tb, num_insns);
efd7f486 15698 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 15699 if (search_pc) {
92414b31 15700 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15701 lj++;
15702 while (lj <= j)
ab1103de 15703 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15704 } else {
15705 tb->size = ctx.pc - pc_start;
2e70f6ef 15706 tb->icount = num_insns;
6af0bf9c
FB
15707 }
15708#ifdef DEBUG_DISAS
d12d51d5 15709 LOG_DISAS("\n");
8fec2b8c 15710 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 15711 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 15712 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 15713 qemu_log("\n");
6af0bf9c
FB
15714 }
15715#endif
6af0bf9c
FB
15716}
15717
7db13fae 15718void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15719{
2cfc5f17 15720 gen_intermediate_code_internal(env, tb, 0);
6af0bf9c
FB
15721}
15722
7db13fae 15723void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15724{
2cfc5f17 15725 gen_intermediate_code_internal(env, tb, 1);
6af0bf9c
FB
15726}
15727
7db13fae 15728static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15729 int flags)
6ea83fed
FB
15730{
15731 int i;
5e755519 15732 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15733
2a5612e6
SW
15734#define printfpr(fp) \
15735 do { \
15736 if (is_fpu64) \
15737 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15738 " fd:%13g fs:%13g psu: %13g\n", \
15739 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15740 (double)(fp)->fd, \
15741 (double)(fp)->fs[FP_ENDIAN_IDX], \
15742 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15743 else { \
15744 fpr_t tmp; \
15745 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15746 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15747 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15748 " fd:%13g fs:%13g psu:%13g\n", \
15749 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15750 (double)tmp.fd, \
15751 (double)tmp.fs[FP_ENDIAN_IDX], \
15752 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15753 } \
6ea83fed
FB
15754 } while(0)
15755
5a5012ec 15756
9a78eead
SW
15757 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15758 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15759 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15760 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15761 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15762 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15763 }
15764
15765#undef printfpr
15766}
15767
d26bc211 15768#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15769/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15770 sign-extended values on 64bit machines. */
c570fd16
TS
15771
15772#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15773
8706c382 15774static void
7db13fae 15775cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15776 fprintf_function cpu_fprintf,
8706c382 15777 int flags)
c570fd16
TS
15778{
15779 int i;
15780
b5dc7732
TS
15781 if (!SIGN_EXT_P(env->active_tc.PC))
15782 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15783 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15784 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15785 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15786 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15787 if (!SIGN_EXT_P(env->btarget))
3594c774 15788 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15789
15790 for (i = 0; i < 32; i++) {
b5dc7732
TS
15791 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15792 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15793 }
15794
15795 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15796 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15797 if (!SIGN_EXT_P(env->lladdr))
15798 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15799}
15800#endif
15801
7db13fae 15802void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
6af0bf9c
FB
15803 int flags)
15804{
15805 int i;
3b46e624 15806
a7200c9f
SW
15807 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15808 " LO=0x" TARGET_FMT_lx " ds %04x "
15809 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15810 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15811 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15812 for (i = 0; i < 32; i++) {
15813 if ((i & 3) == 0)
15814 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15815 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15816 if ((i & 3) == 3)
15817 cpu_fprintf(f, "\n");
15818 }
568b600d 15819
3594c774 15820 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15821 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15822 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15823 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15824 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15825 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15826#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15827 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15828#endif
6af0bf9c
FB
15829}
15830
78ce64f4 15831void mips_tcg_init(void)
39454628 15832{
f01be154 15833 int i;
39454628
TS
15834 static int inited;
15835
15836 /* Initialize various static tables. */
15837 if (inited)
6958549d 15838 return;
39454628 15839
a7812ae4 15840 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15841 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15842 for (i = 1; i < 32; i++)
a7812ae4 15843 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15844 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15845 regnames[i]);
d73ee8a2
RH
15846
15847 for (i = 0; i < 32; i++) {
15848 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15849 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15850 }
15851
a7812ae4 15852 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15853 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15854 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15855 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15856 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15857 regnames_HI[i]);
a7812ae4 15858 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15859 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15860 regnames_LO[i]);
a7812ae4 15861 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15862 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15863 regnames_ACX[i]);
15864 }
a7812ae4 15865 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15866 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15867 "DSPControl");
1ba74fb8 15868 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15869 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15870 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15871 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15872 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15873 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15874
a7812ae4 15875 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15876 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15877 "fcr0");
15878 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15879 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15880 "fcr31");
39454628 15881
7dd9e556 15882 /* register helpers */
a7812ae4 15883#define GEN_HELPER 2
7dd9e556
TS
15884#include "helper.h"
15885
39454628
TS
15886 inited = 1;
15887}
15888
aaed909a
FB
15889#include "translate_init.c"
15890
30bf942d 15891MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15892{
0f71a709 15893 MIPSCPU *cpu;
6af0bf9c 15894 CPUMIPSState *env;
c227f099 15895 const mips_def_t *def;
6af0bf9c 15896
aaed909a
FB
15897 def = cpu_mips_find_by_name(cpu_model);
15898 if (!def)
15899 return NULL;
0f71a709
AF
15900 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15901 env = &cpu->env;
aaed909a 15902 env->cpu_model = def;
51cc2e78 15903 env->cpu_model_str = cpu_model;
aaed909a 15904
51cc2e78
BS
15905#ifndef CONFIG_USER_ONLY
15906 mmu_init(env, def);
15907#endif
15908 fpu_init(env, def);
15909 mvp_init(env, def);
c1caf1d9
AF
15910
15911 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15912
30bf942d 15913 return cpu;
6ae81775
TS
15914}
15915
1bba0dc9 15916void cpu_state_reset(CPUMIPSState *env)
6ae81775 15917{
55e5c285
AF
15918#ifndef CONFIG_USER_ONLY
15919 MIPSCPU *cpu = mips_env_get_cpu(env);
15920 CPUState *cs = CPU(cpu);
15921#endif
6ae81775 15922
51cc2e78
BS
15923 /* Reset registers to their default values */
15924 env->CP0_PRid = env->cpu_model->CP0_PRid;
15925 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15926#ifdef TARGET_WORDS_BIGENDIAN
15927 env->CP0_Config0 |= (1 << CP0C0_BE);
15928#endif
15929 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15930 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15931 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15932 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15933 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
15934 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15935 << env->cpu_model->CP0_LLAddr_shift;
15936 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
15937 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15938 env->CCRes = env->cpu_model->CCRes;
15939 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15940 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15941 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15942 env->current_tc = 0;
15943 env->SEGBITS = env->cpu_model->SEGBITS;
15944 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15945#if defined(TARGET_MIPS64)
15946 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15947 env->SEGMask |= 3ULL << 62;
15948 }
15949#endif
15950 env->PABITS = env->cpu_model->PABITS;
15951 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15952 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15953 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15954 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15955 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15956 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15957 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15958 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15959 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15960 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15961 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 15962 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
15963 env->insn_flags = env->cpu_model->insn_flags;
15964
0eaef5aa 15965#if defined(CONFIG_USER_ONLY)
03e6e501 15966 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
94159135
MI
15967 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15968 hardware registers. */
15969 env->CP0_HWREna |= 0x0000000F;
91a75935 15970 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 15971 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 15972 }
6f0af304
PJ
15973 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
15974 env->CP0_Status |= (1 << CP0St_MX);
853c3240 15975 }
932e71cd
AJ
15976#else
15977 if (env->hflags & MIPS_HFLAG_BMASK) {
15978 /* If the exception was raised from a delay slot,
15979 come back to the jump. */
15980 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 15981 } else {
932e71cd
AJ
15982 env->CP0_ErrorEPC = env->active_tc.PC;
15983 }
15984 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
15985 env->CP0_Random = env->tlb->nb_tlb - 1;
15986 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 15987 env->CP0_Wired = 0;
55e5c285 15988 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
932e71cd
AJ
15989 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15990 /* vectored interrupts not implemented, timer on int 7,
15991 no performance counters. */
15992 env->CP0_IntCtl = 0xe0000000;
15993 {
15994 int i;
15995
15996 for (i = 0; i < 7; i++) {
15997 env->CP0_WatchLo[i] = 0;
15998 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 15999 }
932e71cd
AJ
16000 env->CP0_WatchLo[7] = 0;
16001 env->CP0_WatchHi[7] = 0;
fd88b6ab 16002 }
932e71cd
AJ
16003 /* Count register increments in debug mode, EJTAG version 1 */
16004 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756
EI
16005
16006 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16007 int i;
16008
16009 /* Only TC0 on VPE 0 starts as active. */
16010 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 16011 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
16012 env->tcs[i].CP0_TCHalt = 1;
16013 }
16014 env->active_tc.CP0_TCHalt = 1;
16015 env->halted = 1;
16016
55e5c285 16017 if (cs->cpu_index == 0) {
9e56e756
EI
16018 /* VPE0 starts up enabled. */
16019 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16020 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16021
16022 /* TC0 starts up unhalted. */
16023 env->halted = 0;
16024 env->active_tc.CP0_TCHalt = 0;
16025 env->tcs[0].CP0_TCHalt = 0;
16026 /* With thread 0 active. */
16027 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16028 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16029 }
16030 }
51cc2e78 16031#endif
03e6e501 16032 compute_hflags(env);
6af0bf9c 16033 env->exception_index = EXCP_NONE;
6af0bf9c 16034}
d2856f1a 16035
7db13fae 16036void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16037{
25983cad 16038 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16039 env->hflags &= ~MIPS_HFLAG_BMASK;
16040 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16041 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16042 case MIPS_HFLAG_BR:
16043 break;
16044 case MIPS_HFLAG_BC:
16045 case MIPS_HFLAG_BL:
16046 case MIPS_HFLAG_B:
16047 env->btarget = gen_opc_btarget[pc_pos];
16048 break;
16049 }
d2856f1a 16050}