]> git.proxmox.com Git - qemu.git/blame - target-mips/translate.c
cpu: Turn cpu_dump_{state,statistics}() into CPUState hooks
[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 */
26135ead 2585static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 2586{
923617a3 2587 const char *opn = "hilo";
6af0bf9c
FB
2588
2589 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2590 /* Treat as NOP. */
6af0bf9c 2591 MIPS_DEBUG("NOP");
a1f6684d 2592 return;
6af0bf9c 2593 }
4133498f 2594
4133498f
JL
2595 if (acc != 0) {
2596 check_dsp(ctx);
2597 }
2598
6af0bf9c
FB
2599 switch (opc) {
2600 case OPC_MFHI:
4133498f
JL
2601#if defined(TARGET_MIPS64)
2602 if (acc != 0) {
2603 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2604 } else
2605#endif
2606 {
2607 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2608 }
6af0bf9c
FB
2609 opn = "mfhi";
2610 break;
2611 case OPC_MFLO:
4133498f
JL
2612#if defined(TARGET_MIPS64)
2613 if (acc != 0) {
2614 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2615 } else
2616#endif
2617 {
2618 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2619 }
6af0bf9c
FB
2620 opn = "mflo";
2621 break;
2622 case OPC_MTHI:
4133498f
JL
2623 if (reg != 0) {
2624#if defined(TARGET_MIPS64)
2625 if (acc != 0) {
2626 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2627 } else
2628#endif
2629 {
2630 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2631 }
2632 } else {
2633 tcg_gen_movi_tl(cpu_HI[acc], 0);
2634 }
6af0bf9c
FB
2635 opn = "mthi";
2636 break;
2637 case OPC_MTLO:
4133498f
JL
2638 if (reg != 0) {
2639#if defined(TARGET_MIPS64)
2640 if (acc != 0) {
2641 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2642 } else
2643#endif
2644 {
2645 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2646 }
2647 } else {
2648 tcg_gen_movi_tl(cpu_LO[acc], 0);
2649 }
6af0bf9c
FB
2650 opn = "mtlo";
2651 break;
6af0bf9c 2652 }
2abf314d 2653 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2654 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2655}
2656
26135ead
RS
2657static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2658 int acc, int rs, int rt)
6af0bf9c 2659{
923617a3 2660 const char *opn = "mul/div";
d45f89f4
AJ
2661 TCGv t0, t1;
2662
51127181
AJ
2663 t0 = tcg_temp_new();
2664 t1 = tcg_temp_new();
6af0bf9c 2665
78723684
TS
2666 gen_load_gpr(t0, rs);
2667 gen_load_gpr(t1, rt);
51127181 2668
26135ead
RS
2669 if (acc != 0) {
2670 check_dsp(ctx);
2671 }
2672
6af0bf9c
FB
2673 switch (opc) {
2674 case OPC_DIV:
48d38ca5 2675 {
51127181
AJ
2676 TCGv t2 = tcg_temp_new();
2677 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2678 tcg_gen_ext32s_tl(t0, t0);
2679 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2680 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2681 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2682 tcg_gen_and_tl(t2, t2, t3);
2683 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2684 tcg_gen_or_tl(t2, t2, t3);
2685 tcg_gen_movi_tl(t3, 0);
2686 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2687 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2688 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2689 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2690 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2691 tcg_temp_free(t3);
2692 tcg_temp_free(t2);
48d38ca5 2693 }
6af0bf9c
FB
2694 opn = "div";
2695 break;
2696 case OPC_DIVU:
48d38ca5 2697 {
51127181
AJ
2698 TCGv t2 = tcg_const_tl(0);
2699 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
2700 tcg_gen_ext32u_tl(t0, t0);
2701 tcg_gen_ext32u_tl(t1, t1);
51127181 2702 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2703 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2704 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2705 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2706 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2707 tcg_temp_free(t3);
2708 tcg_temp_free(t2);
48d38ca5 2709 }
6af0bf9c
FB
2710 opn = "divu";
2711 break;
2712 case OPC_MULT:
214c465f 2713 {
ce1dd5d1
RH
2714 TCGv_i32 t2 = tcg_temp_new_i32();
2715 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
2716 tcg_gen_trunc_tl_i32(t2, t0);
2717 tcg_gen_trunc_tl_i32(t3, t1);
2718 tcg_gen_muls2_i32(t2, t3, t2, t3);
2719 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2720 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2721 tcg_temp_free_i32(t2);
2722 tcg_temp_free_i32(t3);
214c465f 2723 }
6af0bf9c
FB
2724 opn = "mult";
2725 break;
2726 case OPC_MULTU:
214c465f 2727 {
ce1dd5d1
RH
2728 TCGv_i32 t2 = tcg_temp_new_i32();
2729 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
2730 tcg_gen_trunc_tl_i32(t2, t0);
2731 tcg_gen_trunc_tl_i32(t3, t1);
2732 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2733 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2734 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2735 tcg_temp_free_i32(t2);
2736 tcg_temp_free_i32(t3);
214c465f 2737 }
6af0bf9c
FB
2738 opn = "multu";
2739 break;
d26bc211 2740#if defined(TARGET_MIPS64)
7a387fff 2741 case OPC_DDIV:
48d38ca5 2742 {
51127181
AJ
2743 TCGv t2 = tcg_temp_new();
2744 TCGv t3 = tcg_temp_new();
2745 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2746 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2747 tcg_gen_and_tl(t2, t2, t3);
2748 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2749 tcg_gen_or_tl(t2, t2, t3);
2750 tcg_gen_movi_tl(t3, 0);
2751 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2752 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2753 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
2754 tcg_temp_free(t3);
2755 tcg_temp_free(t2);
48d38ca5 2756 }
7a387fff
TS
2757 opn = "ddiv";
2758 break;
2759 case OPC_DDIVU:
48d38ca5 2760 {
51127181
AJ
2761 TCGv t2 = tcg_const_tl(0);
2762 TCGv t3 = tcg_const_tl(1);
2763 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2764 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2765 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
2766 tcg_temp_free(t3);
2767 tcg_temp_free(t2);
48d38ca5 2768 }
7a387fff
TS
2769 opn = "ddivu";
2770 break;
2771 case OPC_DMULT:
26135ead 2772 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
2773 opn = "dmult";
2774 break;
2775 case OPC_DMULTU:
26135ead 2776 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
2777 opn = "dmultu";
2778 break;
2779#endif
6af0bf9c 2780 case OPC_MADD:
214c465f 2781 {
d45f89f4
AJ
2782 TCGv_i64 t2 = tcg_temp_new_i64();
2783 TCGv_i64 t3 = tcg_temp_new_i64();
2784
2785 tcg_gen_ext_tl_i64(t2, t0);
2786 tcg_gen_ext_tl_i64(t3, t1);
2787 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2788 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2789 tcg_gen_add_i64(t2, t2, t3);
2790 tcg_temp_free_i64(t3);
2791 tcg_gen_trunc_i64_tl(t0, t2);
2792 tcg_gen_shri_i64(t2, t2, 32);
2793 tcg_gen_trunc_i64_tl(t1, t2);
2794 tcg_temp_free_i64(t2);
4133498f
JL
2795 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2796 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2797 }
6af0bf9c
FB
2798 opn = "madd";
2799 break;
2800 case OPC_MADDU:
4133498f 2801 {
d45f89f4
AJ
2802 TCGv_i64 t2 = tcg_temp_new_i64();
2803 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 2804
78723684
TS
2805 tcg_gen_ext32u_tl(t0, t0);
2806 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2807 tcg_gen_extu_tl_i64(t2, t0);
2808 tcg_gen_extu_tl_i64(t3, t1);
2809 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2810 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2811 tcg_gen_add_i64(t2, t2, t3);
2812 tcg_temp_free_i64(t3);
2813 tcg_gen_trunc_i64_tl(t0, t2);
2814 tcg_gen_shri_i64(t2, t2, 32);
2815 tcg_gen_trunc_i64_tl(t1, t2);
2816 tcg_temp_free_i64(t2);
4133498f
JL
2817 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2818 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2819 }
6af0bf9c
FB
2820 opn = "maddu";
2821 break;
2822 case OPC_MSUB:
214c465f 2823 {
d45f89f4
AJ
2824 TCGv_i64 t2 = tcg_temp_new_i64();
2825 TCGv_i64 t3 = tcg_temp_new_i64();
2826
2827 tcg_gen_ext_tl_i64(t2, t0);
2828 tcg_gen_ext_tl_i64(t3, t1);
2829 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2830 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2831 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2832 tcg_temp_free_i64(t3);
2833 tcg_gen_trunc_i64_tl(t0, t2);
2834 tcg_gen_shri_i64(t2, t2, 32);
2835 tcg_gen_trunc_i64_tl(t1, t2);
2836 tcg_temp_free_i64(t2);
4133498f
JL
2837 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2838 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2839 }
6af0bf9c
FB
2840 opn = "msub";
2841 break;
2842 case OPC_MSUBU:
214c465f 2843 {
d45f89f4
AJ
2844 TCGv_i64 t2 = tcg_temp_new_i64();
2845 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 2846
78723684
TS
2847 tcg_gen_ext32u_tl(t0, t0);
2848 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2849 tcg_gen_extu_tl_i64(t2, t0);
2850 tcg_gen_extu_tl_i64(t3, t1);
2851 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2852 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2853 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2854 tcg_temp_free_i64(t3);
2855 tcg_gen_trunc_i64_tl(t0, t2);
2856 tcg_gen_shri_i64(t2, t2, 32);
2857 tcg_gen_trunc_i64_tl(t1, t2);
2858 tcg_temp_free_i64(t2);
4133498f
JL
2859 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2860 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2861 }
6af0bf9c
FB
2862 opn = "msubu";
2863 break;
2864 default:
923617a3 2865 MIPS_INVAL(opn);
6af0bf9c 2866 generate_exception(ctx, EXCP_RI);
78723684 2867 goto out;
6af0bf9c 2868 }
2abf314d 2869 (void)opn; /* avoid a compiler warning */
6af0bf9c 2870 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2871 out:
2872 tcg_temp_free(t0);
2873 tcg_temp_free(t1);
6af0bf9c
FB
2874}
2875
e9c71dd1
TS
2876static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2877 int rd, int rs, int rt)
2878{
2879 const char *opn = "mul vr54xx";
f157bfe1
AJ
2880 TCGv t0 = tcg_temp_new();
2881 TCGv t1 = tcg_temp_new();
e9c71dd1 2882
6c5c1e20
TS
2883 gen_load_gpr(t0, rs);
2884 gen_load_gpr(t1, rt);
e9c71dd1
TS
2885
2886 switch (opc) {
2887 case OPC_VR54XX_MULS:
895c2d04 2888 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2889 opn = "muls";
6958549d 2890 break;
e9c71dd1 2891 case OPC_VR54XX_MULSU:
895c2d04 2892 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2893 opn = "mulsu";
6958549d 2894 break;
e9c71dd1 2895 case OPC_VR54XX_MACC:
895c2d04 2896 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2897 opn = "macc";
6958549d 2898 break;
e9c71dd1 2899 case OPC_VR54XX_MACCU:
895c2d04 2900 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2901 opn = "maccu";
6958549d 2902 break;
e9c71dd1 2903 case OPC_VR54XX_MSAC:
895c2d04 2904 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2905 opn = "msac";
6958549d 2906 break;
e9c71dd1 2907 case OPC_VR54XX_MSACU:
895c2d04 2908 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2909 opn = "msacu";
6958549d 2910 break;
e9c71dd1 2911 case OPC_VR54XX_MULHI:
895c2d04 2912 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2913 opn = "mulhi";
6958549d 2914 break;
e9c71dd1 2915 case OPC_VR54XX_MULHIU:
895c2d04 2916 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2917 opn = "mulhiu";
6958549d 2918 break;
e9c71dd1 2919 case OPC_VR54XX_MULSHI:
895c2d04 2920 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2921 opn = "mulshi";
6958549d 2922 break;
e9c71dd1 2923 case OPC_VR54XX_MULSHIU:
895c2d04 2924 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2925 opn = "mulshiu";
6958549d 2926 break;
e9c71dd1 2927 case OPC_VR54XX_MACCHI:
895c2d04 2928 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2929 opn = "macchi";
6958549d 2930 break;
e9c71dd1 2931 case OPC_VR54XX_MACCHIU:
895c2d04 2932 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2933 opn = "macchiu";
6958549d 2934 break;
e9c71dd1 2935 case OPC_VR54XX_MSACHI:
895c2d04 2936 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2937 opn = "msachi";
6958549d 2938 break;
e9c71dd1 2939 case OPC_VR54XX_MSACHIU:
895c2d04 2940 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2941 opn = "msachiu";
6958549d 2942 break;
e9c71dd1
TS
2943 default:
2944 MIPS_INVAL("mul vr54xx");
2945 generate_exception(ctx, EXCP_RI);
6c5c1e20 2946 goto out;
e9c71dd1 2947 }
6c5c1e20 2948 gen_store_gpr(t0, rd);
2abf314d 2949 (void)opn; /* avoid a compiler warning */
e9c71dd1 2950 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2951
2952 out:
2953 tcg_temp_free(t0);
2954 tcg_temp_free(t1);
e9c71dd1
TS
2955}
2956
7a387fff 2957static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2958 int rd, int rs)
2959{
923617a3 2960 const char *opn = "CLx";
20e1fb52 2961 TCGv t0;
6c5c1e20 2962
6af0bf9c 2963 if (rd == 0) {
ead9360e 2964 /* Treat as NOP. */
6af0bf9c 2965 MIPS_DEBUG("NOP");
20e1fb52 2966 return;
6af0bf9c 2967 }
20e1fb52 2968 t0 = tcg_temp_new();
6c5c1e20 2969 gen_load_gpr(t0, rs);
6af0bf9c
FB
2970 switch (opc) {
2971 case OPC_CLO:
20e1fb52 2972 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
2973 opn = "clo";
2974 break;
2975 case OPC_CLZ:
20e1fb52 2976 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
2977 opn = "clz";
2978 break;
d26bc211 2979#if defined(TARGET_MIPS64)
7a387fff 2980 case OPC_DCLO:
20e1fb52 2981 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
2982 opn = "dclo";
2983 break;
2984 case OPC_DCLZ:
20e1fb52 2985 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
2986 opn = "dclz";
2987 break;
2988#endif
6af0bf9c 2989 }
2abf314d 2990 (void)opn; /* avoid a compiler warning */
6af0bf9c 2991 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 2992 tcg_temp_free(t0);
6af0bf9c
FB
2993}
2994
161f85e6 2995/* Godson integer instructions */
bd277fa1
RH
2996static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2997 int rd, int rs, int rt)
161f85e6
AJ
2998{
2999 const char *opn = "loongson";
3000 TCGv t0, t1;
3001
3002 if (rd == 0) {
3003 /* Treat as NOP. */
3004 MIPS_DEBUG("NOP");
3005 return;
3006 }
3007
3008 switch (opc) {
3009 case OPC_MULT_G_2E:
3010 case OPC_MULT_G_2F:
3011 case OPC_MULTU_G_2E:
3012 case OPC_MULTU_G_2F:
3013#if defined(TARGET_MIPS64)
3014 case OPC_DMULT_G_2E:
3015 case OPC_DMULT_G_2F:
3016 case OPC_DMULTU_G_2E:
3017 case OPC_DMULTU_G_2F:
3018#endif
3019 t0 = tcg_temp_new();
3020 t1 = tcg_temp_new();
3021 break;
3022 default:
3023 t0 = tcg_temp_local_new();
3024 t1 = tcg_temp_local_new();
3025 break;
3026 }
3027
3028 gen_load_gpr(t0, rs);
3029 gen_load_gpr(t1, rt);
3030
3031 switch (opc) {
3032 case OPC_MULT_G_2E:
3033 case OPC_MULT_G_2F:
3034 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3035 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3036 opn = "mult.g";
3037 break;
3038 case OPC_MULTU_G_2E:
3039 case OPC_MULTU_G_2F:
3040 tcg_gen_ext32u_tl(t0, t0);
3041 tcg_gen_ext32u_tl(t1, t1);
3042 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3043 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3044 opn = "multu.g";
3045 break;
3046 case OPC_DIV_G_2E:
3047 case OPC_DIV_G_2F:
3048 {
3049 int l1 = gen_new_label();
3050 int l2 = gen_new_label();
3051 int l3 = gen_new_label();
3052 tcg_gen_ext32s_tl(t0, t0);
3053 tcg_gen_ext32s_tl(t1, t1);
3054 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3055 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3056 tcg_gen_br(l3);
3057 gen_set_label(l1);
3058 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3059 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3060 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3061 tcg_gen_br(l3);
3062 gen_set_label(l2);
3063 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3064 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3065 gen_set_label(l3);
3066 }
3067 opn = "div.g";
3068 break;
3069 case OPC_DIVU_G_2E:
3070 case OPC_DIVU_G_2F:
3071 {
3072 int l1 = gen_new_label();
3073 int l2 = gen_new_label();
3074 tcg_gen_ext32u_tl(t0, t0);
3075 tcg_gen_ext32u_tl(t1, t1);
3076 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3077 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3078 tcg_gen_br(l2);
3079 gen_set_label(l1);
3080 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3081 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3082 gen_set_label(l2);
3083 }
3084 opn = "divu.g";
3085 break;
3086 case OPC_MOD_G_2E:
3087 case OPC_MOD_G_2F:
3088 {
3089 int l1 = gen_new_label();
3090 int l2 = gen_new_label();
3091 int l3 = gen_new_label();
3092 tcg_gen_ext32u_tl(t0, t0);
3093 tcg_gen_ext32u_tl(t1, t1);
3094 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3095 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3097 gen_set_label(l1);
3098 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3099 tcg_gen_br(l3);
3100 gen_set_label(l2);
3101 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3102 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3103 gen_set_label(l3);
3104 }
3105 opn = "mod.g";
3106 break;
3107 case OPC_MODU_G_2E:
3108 case OPC_MODU_G_2F:
3109 {
3110 int l1 = gen_new_label();
3111 int l2 = gen_new_label();
3112 tcg_gen_ext32u_tl(t0, t0);
3113 tcg_gen_ext32u_tl(t1, t1);
3114 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3115 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3116 tcg_gen_br(l2);
3117 gen_set_label(l1);
3118 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3119 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3120 gen_set_label(l2);
3121 }
3122 opn = "modu.g";
3123 break;
3124#if defined(TARGET_MIPS64)
3125 case OPC_DMULT_G_2E:
3126 case OPC_DMULT_G_2F:
3127 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3128 opn = "dmult.g";
3129 break;
3130 case OPC_DMULTU_G_2E:
3131 case OPC_DMULTU_G_2F:
3132 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3133 opn = "dmultu.g";
3134 break;
3135 case OPC_DDIV_G_2E:
3136 case OPC_DDIV_G_2F:
3137 {
3138 int l1 = gen_new_label();
3139 int l2 = gen_new_label();
3140 int l3 = gen_new_label();
3141 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3142 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3143 tcg_gen_br(l3);
3144 gen_set_label(l1);
3145 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3146 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3147 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3148 tcg_gen_br(l3);
3149 gen_set_label(l2);
3150 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3151 gen_set_label(l3);
3152 }
3153 opn = "ddiv.g";
3154 break;
3155 case OPC_DDIVU_G_2E:
3156 case OPC_DDIVU_G_2F:
3157 {
3158 int l1 = gen_new_label();
3159 int l2 = gen_new_label();
3160 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3161 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3162 tcg_gen_br(l2);
3163 gen_set_label(l1);
3164 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3165 gen_set_label(l2);
3166 }
3167 opn = "ddivu.g";
3168 break;
3169 case OPC_DMOD_G_2E:
3170 case OPC_DMOD_G_2F:
3171 {
3172 int l1 = gen_new_label();
3173 int l2 = gen_new_label();
3174 int l3 = gen_new_label();
3175 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3176 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3177 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3178 gen_set_label(l1);
3179 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3180 tcg_gen_br(l3);
3181 gen_set_label(l2);
3182 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3183 gen_set_label(l3);
3184 }
3185 opn = "dmod.g";
3186 break;
3187 case OPC_DMODU_G_2E:
3188 case OPC_DMODU_G_2F:
3189 {
3190 int l1 = gen_new_label();
3191 int l2 = gen_new_label();
3192 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3193 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3194 tcg_gen_br(l2);
3195 gen_set_label(l1);
3196 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3197 gen_set_label(l2);
3198 }
3199 opn = "dmodu.g";
3200 break;
3201#endif
3202 }
3203
2abf314d 3204 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3205 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3206 tcg_temp_free(t0);
3207 tcg_temp_free(t1);
3208}
3209
bd277fa1
RH
3210/* Loongson multimedia instructions */
3211static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3212{
3213 const char *opn = "loongson_cp2";
3214 uint32_t opc, shift_max;
3215 TCGv_i64 t0, t1;
3216
3217 opc = MASK_LMI(ctx->opcode);
3218 switch (opc) {
3219 case OPC_ADD_CP2:
3220 case OPC_SUB_CP2:
3221 case OPC_DADD_CP2:
3222 case OPC_DSUB_CP2:
3223 t0 = tcg_temp_local_new_i64();
3224 t1 = tcg_temp_local_new_i64();
3225 break;
3226 default:
3227 t0 = tcg_temp_new_i64();
3228 t1 = tcg_temp_new_i64();
3229 break;
3230 }
3231
3232 gen_load_fpr64(ctx, t0, rs);
3233 gen_load_fpr64(ctx, t1, rt);
3234
3235#define LMI_HELPER(UP, LO) \
3236 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3237#define LMI_HELPER_1(UP, LO) \
3238 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3239#define LMI_DIRECT(UP, LO, OP) \
3240 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3241
3242 switch (opc) {
3243 LMI_HELPER(PADDSH, paddsh);
3244 LMI_HELPER(PADDUSH, paddush);
3245 LMI_HELPER(PADDH, paddh);
3246 LMI_HELPER(PADDW, paddw);
3247 LMI_HELPER(PADDSB, paddsb);
3248 LMI_HELPER(PADDUSB, paddusb);
3249 LMI_HELPER(PADDB, paddb);
3250
3251 LMI_HELPER(PSUBSH, psubsh);
3252 LMI_HELPER(PSUBUSH, psubush);
3253 LMI_HELPER(PSUBH, psubh);
3254 LMI_HELPER(PSUBW, psubw);
3255 LMI_HELPER(PSUBSB, psubsb);
3256 LMI_HELPER(PSUBUSB, psubusb);
3257 LMI_HELPER(PSUBB, psubb);
3258
3259 LMI_HELPER(PSHUFH, pshufh);
3260 LMI_HELPER(PACKSSWH, packsswh);
3261 LMI_HELPER(PACKSSHB, packsshb);
3262 LMI_HELPER(PACKUSHB, packushb);
3263
3264 LMI_HELPER(PUNPCKLHW, punpcklhw);
3265 LMI_HELPER(PUNPCKHHW, punpckhhw);
3266 LMI_HELPER(PUNPCKLBH, punpcklbh);
3267 LMI_HELPER(PUNPCKHBH, punpckhbh);
3268 LMI_HELPER(PUNPCKLWD, punpcklwd);
3269 LMI_HELPER(PUNPCKHWD, punpckhwd);
3270
3271 LMI_HELPER(PAVGH, pavgh);
3272 LMI_HELPER(PAVGB, pavgb);
3273 LMI_HELPER(PMAXSH, pmaxsh);
3274 LMI_HELPER(PMINSH, pminsh);
3275 LMI_HELPER(PMAXUB, pmaxub);
3276 LMI_HELPER(PMINUB, pminub);
3277
3278 LMI_HELPER(PCMPEQW, pcmpeqw);
3279 LMI_HELPER(PCMPGTW, pcmpgtw);
3280 LMI_HELPER(PCMPEQH, pcmpeqh);
3281 LMI_HELPER(PCMPGTH, pcmpgth);
3282 LMI_HELPER(PCMPEQB, pcmpeqb);
3283 LMI_HELPER(PCMPGTB, pcmpgtb);
3284
3285 LMI_HELPER(PSLLW, psllw);
3286 LMI_HELPER(PSLLH, psllh);
3287 LMI_HELPER(PSRLW, psrlw);
3288 LMI_HELPER(PSRLH, psrlh);
3289 LMI_HELPER(PSRAW, psraw);
3290 LMI_HELPER(PSRAH, psrah);
3291
3292 LMI_HELPER(PMULLH, pmullh);
3293 LMI_HELPER(PMULHH, pmulhh);
3294 LMI_HELPER(PMULHUH, pmulhuh);
3295 LMI_HELPER(PMADDHW, pmaddhw);
3296
3297 LMI_HELPER(PASUBUB, pasubub);
3298 LMI_HELPER_1(BIADD, biadd);
3299 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3300
3301 LMI_DIRECT(PADDD, paddd, add);
3302 LMI_DIRECT(PSUBD, psubd, sub);
3303 LMI_DIRECT(XOR_CP2, xor, xor);
3304 LMI_DIRECT(NOR_CP2, nor, nor);
3305 LMI_DIRECT(AND_CP2, and, and);
3306 LMI_DIRECT(PANDN, pandn, andc);
3307 LMI_DIRECT(OR, or, or);
3308
3309 case OPC_PINSRH_0:
3310 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3311 opn = "pinsrh_0";
3312 break;
3313 case OPC_PINSRH_1:
3314 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3315 opn = "pinsrh_1";
3316 break;
3317 case OPC_PINSRH_2:
3318 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3319 opn = "pinsrh_2";
3320 break;
3321 case OPC_PINSRH_3:
3322 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3323 opn = "pinsrh_3";
3324 break;
3325
3326 case OPC_PEXTRH:
3327 tcg_gen_andi_i64(t1, t1, 3);
3328 tcg_gen_shli_i64(t1, t1, 4);
3329 tcg_gen_shr_i64(t0, t0, t1);
3330 tcg_gen_ext16u_i64(t0, t0);
3331 opn = "pextrh";
3332 break;
3333
3334 case OPC_ADDU_CP2:
3335 tcg_gen_add_i64(t0, t0, t1);
3336 tcg_gen_ext32s_i64(t0, t0);
3337 opn = "addu";
3338 break;
3339 case OPC_SUBU_CP2:
3340 tcg_gen_sub_i64(t0, t0, t1);
3341 tcg_gen_ext32s_i64(t0, t0);
3342 opn = "addu";
3343 break;
3344
3345 case OPC_SLL_CP2:
3346 opn = "sll";
3347 shift_max = 32;
3348 goto do_shift;
3349 case OPC_SRL_CP2:
3350 opn = "srl";
3351 shift_max = 32;
3352 goto do_shift;
3353 case OPC_SRA_CP2:
3354 opn = "sra";
3355 shift_max = 32;
3356 goto do_shift;
3357 case OPC_DSLL_CP2:
3358 opn = "dsll";
3359 shift_max = 64;
3360 goto do_shift;
3361 case OPC_DSRL_CP2:
3362 opn = "dsrl";
3363 shift_max = 64;
3364 goto do_shift;
3365 case OPC_DSRA_CP2:
3366 opn = "dsra";
3367 shift_max = 64;
3368 goto do_shift;
3369 do_shift:
3370 /* Make sure shift count isn't TCG undefined behaviour. */
3371 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3372
3373 switch (opc) {
3374 case OPC_SLL_CP2:
3375 case OPC_DSLL_CP2:
3376 tcg_gen_shl_i64(t0, t0, t1);
3377 break;
3378 case OPC_SRA_CP2:
3379 case OPC_DSRA_CP2:
3380 /* Since SRA is UndefinedResult without sign-extended inputs,
3381 we can treat SRA and DSRA the same. */
3382 tcg_gen_sar_i64(t0, t0, t1);
3383 break;
3384 case OPC_SRL_CP2:
3385 /* We want to shift in zeros for SRL; zero-extend first. */
3386 tcg_gen_ext32u_i64(t0, t0);
3387 /* FALLTHRU */
3388 case OPC_DSRL_CP2:
3389 tcg_gen_shr_i64(t0, t0, t1);
3390 break;
3391 }
3392
3393 if (shift_max == 32) {
3394 tcg_gen_ext32s_i64(t0, t0);
3395 }
3396
3397 /* Shifts larger than MAX produce zero. */
3398 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3399 tcg_gen_neg_i64(t1, t1);
3400 tcg_gen_and_i64(t0, t0, t1);
3401 break;
3402
3403 case OPC_ADD_CP2:
3404 case OPC_DADD_CP2:
3405 {
3406 TCGv_i64 t2 = tcg_temp_new_i64();
3407 int lab = gen_new_label();
3408
3409 tcg_gen_mov_i64(t2, t0);
3410 tcg_gen_add_i64(t0, t1, t2);
3411 if (opc == OPC_ADD_CP2) {
3412 tcg_gen_ext32s_i64(t0, t0);
3413 }
3414 tcg_gen_xor_i64(t1, t1, t2);
3415 tcg_gen_xor_i64(t2, t2, t0);
3416 tcg_gen_andc_i64(t1, t2, t1);
3417 tcg_temp_free_i64(t2);
3418 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3419 generate_exception(ctx, EXCP_OVERFLOW);
3420 gen_set_label(lab);
3421
3422 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3423 break;
3424 }
3425
3426 case OPC_SUB_CP2:
3427 case OPC_DSUB_CP2:
3428 {
3429 TCGv_i64 t2 = tcg_temp_new_i64();
3430 int lab = gen_new_label();
3431
3432 tcg_gen_mov_i64(t2, t0);
3433 tcg_gen_sub_i64(t0, t1, t2);
3434 if (opc == OPC_SUB_CP2) {
3435 tcg_gen_ext32s_i64(t0, t0);
3436 }
3437 tcg_gen_xor_i64(t1, t1, t2);
3438 tcg_gen_xor_i64(t2, t2, t0);
3439 tcg_gen_and_i64(t1, t1, t2);
3440 tcg_temp_free_i64(t2);
3441 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3442 generate_exception(ctx, EXCP_OVERFLOW);
3443 gen_set_label(lab);
3444
3445 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3446 break;
3447 }
3448
3449 case OPC_PMULUW:
3450 tcg_gen_ext32u_i64(t0, t0);
3451 tcg_gen_ext32u_i64(t1, t1);
3452 tcg_gen_mul_i64(t0, t0, t1);
3453 opn = "pmuluw";
3454 break;
3455
3456 case OPC_SEQU_CP2:
3457 case OPC_SEQ_CP2:
3458 case OPC_SLTU_CP2:
3459 case OPC_SLT_CP2:
3460 case OPC_SLEU_CP2:
3461 case OPC_SLE_CP2:
3462 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3463 FD field is the CC field? */
3464 default:
3465 MIPS_INVAL(opn);
3466 generate_exception(ctx, EXCP_RI);
3467 return;
3468 }
3469
3470#undef LMI_HELPER
3471#undef LMI_DIRECT
3472
3473 gen_store_fpr64(ctx, t0, rd);
3474
3475 (void)opn; /* avoid a compiler warning */
3476 MIPS_DEBUG("%s %s, %s, %s", opn,
3477 fregnames[rd], fregnames[rs], fregnames[rt]);
3478 tcg_temp_free_i64(t0);
3479 tcg_temp_free_i64(t1);
3480}
3481
6af0bf9c 3482/* Traps */
7a387fff 3483static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3484 int rs, int rt, int16_t imm)
3485{
3486 int cond;
cdc0faa6 3487 TCGv t0 = tcg_temp_new();
1ba74fb8 3488 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3489
3490 cond = 0;
3491 /* Load needed operands */
3492 switch (opc) {
3493 case OPC_TEQ:
3494 case OPC_TGE:
3495 case OPC_TGEU:
3496 case OPC_TLT:
3497 case OPC_TLTU:
3498 case OPC_TNE:
3499 /* Compare two registers */
3500 if (rs != rt) {
be24bb4f
TS
3501 gen_load_gpr(t0, rs);
3502 gen_load_gpr(t1, rt);
6af0bf9c
FB
3503 cond = 1;
3504 }
179e32bb 3505 break;
6af0bf9c
FB
3506 case OPC_TEQI:
3507 case OPC_TGEI:
3508 case OPC_TGEIU:
3509 case OPC_TLTI:
3510 case OPC_TLTIU:
3511 case OPC_TNEI:
3512 /* Compare register to immediate */
3513 if (rs != 0 || imm != 0) {
be24bb4f
TS
3514 gen_load_gpr(t0, rs);
3515 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3516 cond = 1;
3517 }
3518 break;
3519 }
3520 if (cond == 0) {
3521 switch (opc) {
3522 case OPC_TEQ: /* rs == rs */
3523 case OPC_TEQI: /* r0 == 0 */
3524 case OPC_TGE: /* rs >= rs */
3525 case OPC_TGEI: /* r0 >= 0 */
3526 case OPC_TGEU: /* rs >= rs unsigned */
3527 case OPC_TGEIU: /* r0 >= 0 unsigned */
3528 /* Always trap */
cdc0faa6 3529 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3530 break;
3531 case OPC_TLT: /* rs < rs */
3532 case OPC_TLTI: /* r0 < 0 */
3533 case OPC_TLTU: /* rs < rs unsigned */
3534 case OPC_TLTIU: /* r0 < 0 unsigned */
3535 case OPC_TNE: /* rs != rs */
3536 case OPC_TNEI: /* r0 != 0 */
ead9360e 3537 /* Never trap: treat as NOP. */
cdc0faa6 3538 break;
6af0bf9c
FB
3539 }
3540 } else {
cdc0faa6
AJ
3541 int l1 = gen_new_label();
3542
6af0bf9c
FB
3543 switch (opc) {
3544 case OPC_TEQ:
3545 case OPC_TEQI:
cdc0faa6 3546 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3547 break;
3548 case OPC_TGE:
3549 case OPC_TGEI:
cdc0faa6 3550 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3551 break;
3552 case OPC_TGEU:
3553 case OPC_TGEIU:
cdc0faa6 3554 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3555 break;
3556 case OPC_TLT:
3557 case OPC_TLTI:
cdc0faa6 3558 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3559 break;
3560 case OPC_TLTU:
3561 case OPC_TLTIU:
cdc0faa6 3562 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3563 break;
3564 case OPC_TNE:
3565 case OPC_TNEI:
cdc0faa6 3566 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3567 break;
6af0bf9c 3568 }
cdc0faa6 3569 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3570 gen_set_label(l1);
3571 }
be24bb4f
TS
3572 tcg_temp_free(t0);
3573 tcg_temp_free(t1);
6af0bf9c
FB
3574}
3575
356265ae 3576static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3577{
6e256c93
FB
3578 TranslationBlock *tb;
3579 tb = ctx->tb;
7b270ef2
NF
3580 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3581 likely(!ctx->singlestep_enabled)) {
57fec1fe 3582 tcg_gen_goto_tb(n);
9b9e4393 3583 gen_save_pc(dest);
4b4a72e5 3584 tcg_gen_exit_tb((tcg_target_long)tb + n);
6e256c93 3585 } else {
9b9e4393 3586 gen_save_pc(dest);
7b270ef2
NF
3587 if (ctx->singlestep_enabled) {
3588 save_cpu_state(ctx, 0);
895c2d04 3589 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3590 }
57fec1fe 3591 tcg_gen_exit_tb(0);
6e256c93 3592 }
c53be334
FB
3593}
3594
6af0bf9c 3595/* Branches (before delay slot) */
7a387fff 3596static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3597 int insn_bytes,
6af0bf9c
FB
3598 int rs, int rt, int32_t offset)
3599{
d077b6f7 3600 target_ulong btgt = -1;
3ad4bb2d 3601 int blink = 0;
2fdbad25 3602 int bcond_compute = 0;
1ba74fb8
AJ
3603 TCGv t0 = tcg_temp_new();
3604 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3605
3606 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3607#ifdef MIPS_DEBUG_DISAS
d12d51d5 3608 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3609#endif
3ad4bb2d 3610 generate_exception(ctx, EXCP_RI);
6c5c1e20 3611 goto out;
3ad4bb2d 3612 }
6af0bf9c 3613
6af0bf9c
FB
3614 /* Load needed operands */
3615 switch (opc) {
3616 case OPC_BEQ:
3617 case OPC_BEQL:
3618 case OPC_BNE:
3619 case OPC_BNEL:
3620 /* Compare two registers */
3621 if (rs != rt) {
6c5c1e20
TS
3622 gen_load_gpr(t0, rs);
3623 gen_load_gpr(t1, rt);
2fdbad25 3624 bcond_compute = 1;
6af0bf9c 3625 }
7dca4ad0 3626 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3627 break;
3628 case OPC_BGEZ:
3629 case OPC_BGEZAL:
3c824109 3630 case OPC_BGEZALS:
6af0bf9c
FB
3631 case OPC_BGEZALL:
3632 case OPC_BGEZL:
3633 case OPC_BGTZ:
3634 case OPC_BGTZL:
3635 case OPC_BLEZ:
3636 case OPC_BLEZL:
3637 case OPC_BLTZ:
3638 case OPC_BLTZAL:
3c824109 3639 case OPC_BLTZALS:
6af0bf9c
FB
3640 case OPC_BLTZALL:
3641 case OPC_BLTZL:
3642 /* Compare to zero */
3643 if (rs != 0) {
6c5c1e20 3644 gen_load_gpr(t0, rs);
2fdbad25 3645 bcond_compute = 1;
6af0bf9c 3646 }
7dca4ad0 3647 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3648 break;
e45a93e2
JL
3649 case OPC_BPOSGE32:
3650#if defined(TARGET_MIPS64)
3651 case OPC_BPOSGE64:
3652 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3653#else
3654 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3655#endif
3656 bcond_compute = 1;
3657 btgt = ctx->pc + insn_bytes + offset;
3658 break;
6af0bf9c
FB
3659 case OPC_J:
3660 case OPC_JAL:
364d4831 3661 case OPC_JALX:
620e48f6
NF
3662 case OPC_JALS:
3663 case OPC_JALXS:
6af0bf9c 3664 /* Jump to immediate */
7dca4ad0 3665 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3666 break;
3667 case OPC_JR:
3668 case OPC_JALR:
364d4831 3669 case OPC_JALRC:
620e48f6 3670 case OPC_JALRS:
6af0bf9c 3671 /* Jump to register */
7a387fff
TS
3672 if (offset != 0 && offset != 16) {
3673 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3674 others are reserved. */
923617a3 3675 MIPS_INVAL("jump hint");
6af0bf9c 3676 generate_exception(ctx, EXCP_RI);
6c5c1e20 3677 goto out;
6af0bf9c 3678 }
d077b6f7 3679 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3680 break;
3681 default:
3682 MIPS_INVAL("branch/jump");
3683 generate_exception(ctx, EXCP_RI);
6c5c1e20 3684 goto out;
6af0bf9c 3685 }
2fdbad25 3686 if (bcond_compute == 0) {
6af0bf9c
FB
3687 /* No condition to be computed */
3688 switch (opc) {
3689 case OPC_BEQ: /* rx == rx */
3690 case OPC_BEQL: /* rx == rx likely */
3691 case OPC_BGEZ: /* 0 >= 0 */
3692 case OPC_BGEZL: /* 0 >= 0 likely */
3693 case OPC_BLEZ: /* 0 <= 0 */
3694 case OPC_BLEZL: /* 0 <= 0 likely */
3695 /* Always take */
4ad40f36 3696 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3697 MIPS_DEBUG("balways");
3698 break;
3c824109 3699 case OPC_BGEZALS:
6af0bf9c
FB
3700 case OPC_BGEZAL: /* 0 >= 0 */
3701 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3702 ctx->hflags |= (opc == OPC_BGEZALS
3703 ? MIPS_HFLAG_BDS16
3704 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3705 /* Always take and link */
3706 blink = 31;
4ad40f36 3707 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3708 MIPS_DEBUG("balways and link");
3709 break;
3710 case OPC_BNE: /* rx != rx */
3711 case OPC_BGTZ: /* 0 > 0 */
3712 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3713 /* Treat as NOP. */
6af0bf9c 3714 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3715 goto out;
3c824109 3716 case OPC_BLTZALS:
eeef26cd 3717 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3718 ctx->hflags |= (opc == OPC_BLTZALS
3719 ? MIPS_HFLAG_BDS16
3720 : MIPS_HFLAG_BDS32);
3721 /* Handle as an unconditional branch to get correct delay
3722 slot checking. */
3723 blink = 31;
3724 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3725 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3726 MIPS_DEBUG("bnever and link");
3c824109 3727 break;
eeef26cd 3728 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3729 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3730 /* Skip the instruction in the delay slot */
3731 MIPS_DEBUG("bnever, link and skip");
3732 ctx->pc += 4;
6c5c1e20 3733 goto out;
6af0bf9c
FB
3734 case OPC_BNEL: /* rx != rx likely */
3735 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3736 case OPC_BLTZL: /* 0 < 0 likely */
3737 /* Skip the instruction in the delay slot */
3738 MIPS_DEBUG("bnever and skip");
9898128f 3739 ctx->pc += 4;
6c5c1e20 3740 goto out;
6af0bf9c 3741 case OPC_J:
4ad40f36 3742 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3743 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3744 break;
620e48f6 3745 case OPC_JALXS:
364d4831
NF
3746 case OPC_JALX:
3747 ctx->hflags |= MIPS_HFLAG_BX;
3748 /* Fallthrough */
620e48f6 3749 case OPC_JALS:
6af0bf9c
FB
3750 case OPC_JAL:
3751 blink = 31;
4ad40f36 3752 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3753 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3754 ? MIPS_HFLAG_BDS16
3755 : MIPS_HFLAG_BDS32);
d077b6f7 3756 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3757 break;
3758 case OPC_JR:
4ad40f36 3759 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3760 if (insn_bytes == 4)
3761 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3762 MIPS_DEBUG("jr %s", regnames[rs]);
3763 break;
620e48f6 3764 case OPC_JALRS:
6af0bf9c 3765 case OPC_JALR:
364d4831 3766 case OPC_JALRC:
6af0bf9c 3767 blink = rt;
4ad40f36 3768 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3769 ctx->hflags |= (opc == OPC_JALRS
3770 ? MIPS_HFLAG_BDS16
3771 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3772 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3773 break;
3774 default:
3775 MIPS_INVAL("branch/jump");
3776 generate_exception(ctx, EXCP_RI);
6c5c1e20 3777 goto out;
6af0bf9c
FB
3778 }
3779 } else {
3780 switch (opc) {
3781 case OPC_BEQ:
e68dd28f 3782 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3783 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3784 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3785 goto not_likely;
3786 case OPC_BEQL:
e68dd28f 3787 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3788 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3789 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3790 goto likely;
3791 case OPC_BNE:
e68dd28f 3792 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3793 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3794 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3795 goto not_likely;
3796 case OPC_BNEL:
e68dd28f 3797 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3798 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3799 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3800 goto likely;
3801 case OPC_BGEZ:
e68dd28f 3802 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3803 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3804 goto not_likely;
3805 case OPC_BGEZL:
e68dd28f 3806 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3807 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3808 goto likely;
3c824109 3809 case OPC_BGEZALS:
6af0bf9c 3810 case OPC_BGEZAL:
3c824109
NF
3811 ctx->hflags |= (opc == OPC_BGEZALS
3812 ? MIPS_HFLAG_BDS16
3813 : MIPS_HFLAG_BDS32);
e68dd28f 3814 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3815 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3816 blink = 31;
3817 goto not_likely;
3818 case OPC_BGEZALL:
e68dd28f 3819 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3820 blink = 31;
d077b6f7 3821 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3822 goto likely;
3823 case OPC_BGTZ:
e68dd28f 3824 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3825 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3826 goto not_likely;
3827 case OPC_BGTZL:
e68dd28f 3828 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3829 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3830 goto likely;
3831 case OPC_BLEZ:
e68dd28f 3832 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3833 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3834 goto not_likely;
3835 case OPC_BLEZL:
e68dd28f 3836 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3837 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3838 goto likely;
3839 case OPC_BLTZ:
e68dd28f 3840 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3841 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3842 goto not_likely;
3843 case OPC_BLTZL:
e68dd28f 3844 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3845 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3846 goto likely;
e45a93e2
JL
3847 case OPC_BPOSGE32:
3848 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3849 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3850 goto not_likely;
3851#if defined(TARGET_MIPS64)
3852 case OPC_BPOSGE64:
3853 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3854 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3855 goto not_likely;
3856#endif
3c824109 3857 case OPC_BLTZALS:
6af0bf9c 3858 case OPC_BLTZAL:
3c824109
NF
3859 ctx->hflags |= (opc == OPC_BLTZALS
3860 ? MIPS_HFLAG_BDS16
3861 : MIPS_HFLAG_BDS32);
e68dd28f 3862 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3863 blink = 31;
d077b6f7 3864 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3865 not_likely:
4ad40f36 3866 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3867 break;
3868 case OPC_BLTZALL:
e68dd28f 3869 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3870 blink = 31;
d077b6f7 3871 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3872 likely:
4ad40f36 3873 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3874 break;
c53f4a62
TS
3875 default:
3876 MIPS_INVAL("conditional branch/jump");
3877 generate_exception(ctx, EXCP_RI);
6c5c1e20 3878 goto out;
6af0bf9c 3879 }
6af0bf9c 3880 }
923617a3 3881 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3882 blink, ctx->hflags, btgt);
9b9e4393 3883
d077b6f7 3884 ctx->btarget = btgt;
6af0bf9c 3885 if (blink > 0) {
364d4831
NF
3886 int post_delay = insn_bytes;
3887 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3888
3889 if (opc != OPC_JALRC)
3890 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3891
3892 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3893 }
6c5c1e20
TS
3894
3895 out:
364d4831
NF
3896 if (insn_bytes == 2)
3897 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3898 tcg_temp_free(t0);
3899 tcg_temp_free(t1);
6af0bf9c
FB
3900}
3901
7a387fff
TS
3902/* special3 bitfield operations */
3903static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3904 int rs, int lsb, int msb)
7a387fff 3905{
a7812ae4
PB
3906 TCGv t0 = tcg_temp_new();
3907 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
3908
3909 gen_load_gpr(t1, rs);
7a387fff
TS
3910 switch (opc) {
3911 case OPC_EXT:
3912 if (lsb + msb > 31)
3913 goto fail;
505ad7c2
AJ
3914 tcg_gen_shri_tl(t0, t1, lsb);
3915 if (msb != 31) {
3916 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3917 } else {
3918 tcg_gen_ext32s_tl(t0, t0);
3919 }
7a387fff 3920 break;
c6d6dd7c 3921#if defined(TARGET_MIPS64)
7a387fff 3922 case OPC_DEXTM:
505ad7c2
AJ
3923 tcg_gen_shri_tl(t0, t1, lsb);
3924 if (msb != 31) {
3925 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3926 }
7a387fff
TS
3927 break;
3928 case OPC_DEXTU:
505ad7c2
AJ
3929 tcg_gen_shri_tl(t0, t1, lsb + 32);
3930 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3931 break;
3932 case OPC_DEXT:
505ad7c2
AJ
3933 tcg_gen_shri_tl(t0, t1, lsb);
3934 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3935 break;
c6d6dd7c 3936#endif
7a387fff
TS
3937 case OPC_INS:
3938 if (lsb > msb)
3939 goto fail;
6c5c1e20 3940 gen_load_gpr(t0, rt);
e0d002f1 3941 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 3942 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3943 break;
c6d6dd7c 3944#if defined(TARGET_MIPS64)
7a387fff 3945 case OPC_DINSM:
6c5c1e20 3946 gen_load_gpr(t0, rt);
e0d002f1 3947 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
3948 break;
3949 case OPC_DINSU:
6c5c1e20 3950 gen_load_gpr(t0, rt);
e0d002f1 3951 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
3952 break;
3953 case OPC_DINS:
6c5c1e20 3954 gen_load_gpr(t0, rt);
e0d002f1 3955 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 3956 break;
c6d6dd7c 3957#endif
7a387fff
TS
3958 default:
3959fail:
3960 MIPS_INVAL("bitops");
3961 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
3962 tcg_temp_free(t0);
3963 tcg_temp_free(t1);
7a387fff
TS
3964 return;
3965 }
6c5c1e20
TS
3966 gen_store_gpr(t0, rt);
3967 tcg_temp_free(t0);
3968 tcg_temp_free(t1);
7a387fff
TS
3969}
3970
49bcf33c
AJ
3971static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3972{
3a55fa47 3973 TCGv t0;
49bcf33c 3974
3a55fa47
AJ
3975 if (rd == 0) {
3976 /* If no destination, treat it as a NOP. */
3977 MIPS_DEBUG("NOP");
3978 return;
3979 }
3980
3981 t0 = tcg_temp_new();
3982 gen_load_gpr(t0, rt);
49bcf33c
AJ
3983 switch (op2) {
3984 case OPC_WSBH:
3a55fa47
AJ
3985 {
3986 TCGv t1 = tcg_temp_new();
3987
3988 tcg_gen_shri_tl(t1, t0, 8);
3989 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3990 tcg_gen_shli_tl(t0, t0, 8);
3991 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3992 tcg_gen_or_tl(t0, t0, t1);
3993 tcg_temp_free(t1);
3994 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3995 }
49bcf33c
AJ
3996 break;
3997 case OPC_SEB:
3a55fa47 3998 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
3999 break;
4000 case OPC_SEH:
3a55fa47 4001 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4002 break;
4003#if defined(TARGET_MIPS64)
4004 case OPC_DSBH:
3a55fa47
AJ
4005 {
4006 TCGv t1 = tcg_temp_new();
4007
4008 tcg_gen_shri_tl(t1, t0, 8);
4009 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4010 tcg_gen_shli_tl(t0, t0, 8);
4011 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4012 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4013 tcg_temp_free(t1);
4014 }
49bcf33c
AJ
4015 break;
4016 case OPC_DSHD:
3a55fa47
AJ
4017 {
4018 TCGv t1 = tcg_temp_new();
4019
4020 tcg_gen_shri_tl(t1, t0, 16);
4021 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4022 tcg_gen_shli_tl(t0, t0, 16);
4023 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4024 tcg_gen_or_tl(t0, t0, t1);
4025 tcg_gen_shri_tl(t1, t0, 32);
4026 tcg_gen_shli_tl(t0, t0, 32);
4027 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4028 tcg_temp_free(t1);
4029 }
49bcf33c
AJ
4030 break;
4031#endif
4032 default:
4033 MIPS_INVAL("bsfhl");
4034 generate_exception(ctx, EXCP_RI);
4035 tcg_temp_free(t0);
49bcf33c
AJ
4036 return;
4037 }
49bcf33c 4038 tcg_temp_free(t0);
49bcf33c
AJ
4039}
4040
f1aa6320 4041#ifndef CONFIG_USER_ONLY
0eaef5aa 4042/* CP0 (MMU and control) */
d9bea114 4043static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4044{
d9bea114 4045 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4046
d9bea114
AJ
4047 tcg_gen_ld_i32(t0, cpu_env, off);
4048 tcg_gen_ext_i32_tl(arg, t0);
4049 tcg_temp_free_i32(t0);
4f57689a
TS
4050}
4051
d9bea114 4052static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4053{
d9bea114
AJ
4054 tcg_gen_ld_tl(arg, cpu_env, off);
4055 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4056}
4057
d9bea114 4058static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4059{
d9bea114 4060 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4061
d9bea114
AJ
4062 tcg_gen_trunc_tl_i32(t0, arg);
4063 tcg_gen_st_i32(t0, cpu_env, off);
4064 tcg_temp_free_i32(t0);
f1aa6320
TS
4065}
4066
d9bea114 4067static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4068{
d9bea114
AJ
4069 tcg_gen_ext32s_tl(arg, arg);
4070 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4071}
4072
d75c135e 4073static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4074{
7a387fff 4075 const char *rn = "invalid";
873eb012 4076
e189e748 4077 if (sel != 0)
d75c135e 4078 check_insn(ctx, ISA_MIPS32);
e189e748 4079
873eb012
TS
4080 switch (reg) {
4081 case 0:
7a387fff
TS
4082 switch (sel) {
4083 case 0:
7db13fae 4084 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4085 rn = "Index";
4086 break;
4087 case 1:
d75c135e 4088 check_insn(ctx, ASE_MT);
895c2d04 4089 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4090 rn = "MVPControl";
ead9360e 4091 break;
7a387fff 4092 case 2:
d75c135e 4093 check_insn(ctx, ASE_MT);
895c2d04 4094 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4095 rn = "MVPConf0";
ead9360e 4096 break;
7a387fff 4097 case 3:
d75c135e 4098 check_insn(ctx, ASE_MT);
895c2d04 4099 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4100 rn = "MVPConf1";
ead9360e 4101 break;
7a387fff
TS
4102 default:
4103 goto die;
4104 }
873eb012
TS
4105 break;
4106 case 1:
7a387fff
TS
4107 switch (sel) {
4108 case 0:
895c2d04 4109 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4110 rn = "Random";
2423f660 4111 break;
7a387fff 4112 case 1:
d75c135e 4113 check_insn(ctx, ASE_MT);
7db13fae 4114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4115 rn = "VPEControl";
ead9360e 4116 break;
7a387fff 4117 case 2:
d75c135e 4118 check_insn(ctx, ASE_MT);
7db13fae 4119 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4120 rn = "VPEConf0";
ead9360e 4121 break;
7a387fff 4122 case 3:
d75c135e 4123 check_insn(ctx, ASE_MT);
7db13fae 4124 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4125 rn = "VPEConf1";
ead9360e 4126 break;
7a387fff 4127 case 4:
d75c135e 4128 check_insn(ctx, ASE_MT);
7db13fae 4129 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4130 rn = "YQMask";
ead9360e 4131 break;
7a387fff 4132 case 5:
d75c135e 4133 check_insn(ctx, ASE_MT);
7db13fae 4134 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4135 rn = "VPESchedule";
ead9360e 4136 break;
7a387fff 4137 case 6:
d75c135e 4138 check_insn(ctx, ASE_MT);
7db13fae 4139 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4140 rn = "VPEScheFBack";
ead9360e 4141 break;
7a387fff 4142 case 7:
d75c135e 4143 check_insn(ctx, ASE_MT);
7db13fae 4144 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4145 rn = "VPEOpt";
ead9360e 4146 break;
7a387fff
TS
4147 default:
4148 goto die;
4149 }
873eb012
TS
4150 break;
4151 case 2:
7a387fff
TS
4152 switch (sel) {
4153 case 0:
7db13fae 4154 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4155 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4156 rn = "EntryLo0";
4157 break;
7a387fff 4158 case 1:
d75c135e 4159 check_insn(ctx, ASE_MT);
895c2d04 4160 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4161 rn = "TCStatus";
ead9360e 4162 break;
7a387fff 4163 case 2:
d75c135e 4164 check_insn(ctx, ASE_MT);
895c2d04 4165 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4166 rn = "TCBind";
ead9360e 4167 break;
7a387fff 4168 case 3:
d75c135e 4169 check_insn(ctx, ASE_MT);
895c2d04 4170 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4171 rn = "TCRestart";
ead9360e 4172 break;
7a387fff 4173 case 4:
d75c135e 4174 check_insn(ctx, ASE_MT);
895c2d04 4175 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4176 rn = "TCHalt";
ead9360e 4177 break;
7a387fff 4178 case 5:
d75c135e 4179 check_insn(ctx, ASE_MT);
895c2d04 4180 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4181 rn = "TCContext";
ead9360e 4182 break;
7a387fff 4183 case 6:
d75c135e 4184 check_insn(ctx, ASE_MT);
895c2d04 4185 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4186 rn = "TCSchedule";
ead9360e 4187 break;
7a387fff 4188 case 7:
d75c135e 4189 check_insn(ctx, ASE_MT);
895c2d04 4190 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4191 rn = "TCScheFBack";
ead9360e 4192 break;
7a387fff
TS
4193 default:
4194 goto die;
4195 }
873eb012
TS
4196 break;
4197 case 3:
7a387fff
TS
4198 switch (sel) {
4199 case 0:
7db13fae 4200 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4201 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4202 rn = "EntryLo1";
4203 break;
7a387fff
TS
4204 default:
4205 goto die;
1579a72e 4206 }
873eb012
TS
4207 break;
4208 case 4:
7a387fff
TS
4209 switch (sel) {
4210 case 0:
7db13fae 4211 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4212 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4213 rn = "Context";
4214 break;
7a387fff 4215 case 1:
d9bea114 4216// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
4217 rn = "ContextConfig";
4218// break;
7a387fff
TS
4219 default:
4220 goto die;
1579a72e 4221 }
873eb012
TS
4222 break;
4223 case 5:
7a387fff
TS
4224 switch (sel) {
4225 case 0:
7db13fae 4226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4227 rn = "PageMask";
4228 break;
7a387fff 4229 case 1:
d75c135e 4230 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4232 rn = "PageGrain";
4233 break;
7a387fff
TS
4234 default:
4235 goto die;
1579a72e 4236 }
873eb012
TS
4237 break;
4238 case 6:
7a387fff
TS
4239 switch (sel) {
4240 case 0:
7db13fae 4241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4242 rn = "Wired";
4243 break;
7a387fff 4244 case 1:
d75c135e 4245 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4246 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4247 rn = "SRSConf0";
ead9360e 4248 break;
7a387fff 4249 case 2:
d75c135e 4250 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4252 rn = "SRSConf1";
ead9360e 4253 break;
7a387fff 4254 case 3:
d75c135e 4255 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4256 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4257 rn = "SRSConf2";
ead9360e 4258 break;
7a387fff 4259 case 4:
d75c135e 4260 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4262 rn = "SRSConf3";
ead9360e 4263 break;
7a387fff 4264 case 5:
d75c135e 4265 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4266 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4267 rn = "SRSConf4";
ead9360e 4268 break;
7a387fff
TS
4269 default:
4270 goto die;
1579a72e 4271 }
873eb012 4272 break;
8c0fdd85 4273 case 7:
7a387fff
TS
4274 switch (sel) {
4275 case 0:
d75c135e 4276 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4278 rn = "HWREna";
4279 break;
7a387fff
TS
4280 default:
4281 goto die;
1579a72e 4282 }
8c0fdd85 4283 break;
873eb012 4284 case 8:
7a387fff
TS
4285 switch (sel) {
4286 case 0:
7db13fae 4287 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4288 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4289 rn = "BadVAddr";
2423f660 4290 break;
7a387fff
TS
4291 default:
4292 goto die;
4293 }
873eb012
TS
4294 break;
4295 case 9:
7a387fff
TS
4296 switch (sel) {
4297 case 0:
2e70f6ef
PB
4298 /* Mark as an IO operation because we read the time. */
4299 if (use_icount)
4300 gen_io_start();
895c2d04 4301 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4302 if (use_icount) {
4303 gen_io_end();
2e70f6ef 4304 }
55807224
EI
4305 /* Break the TB to be able to take timer interrupts immediately
4306 after reading count. */
4307 ctx->bstate = BS_STOP;
2423f660
TS
4308 rn = "Count";
4309 break;
4310 /* 6,7 are implementation dependent */
7a387fff
TS
4311 default:
4312 goto die;
2423f660 4313 }
873eb012
TS
4314 break;
4315 case 10:
7a387fff
TS
4316 switch (sel) {
4317 case 0:
7db13fae 4318 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4319 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4320 rn = "EntryHi";
4321 break;
7a387fff
TS
4322 default:
4323 goto die;
1579a72e 4324 }
873eb012
TS
4325 break;
4326 case 11:
7a387fff
TS
4327 switch (sel) {
4328 case 0:
7db13fae 4329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4330 rn = "Compare";
4331 break;
4332 /* 6,7 are implementation dependent */
7a387fff
TS
4333 default:
4334 goto die;
2423f660 4335 }
873eb012
TS
4336 break;
4337 case 12:
7a387fff
TS
4338 switch (sel) {
4339 case 0:
7db13fae 4340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4341 rn = "Status";
4342 break;
7a387fff 4343 case 1:
d75c135e 4344 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4346 rn = "IntCtl";
4347 break;
7a387fff 4348 case 2:
d75c135e 4349 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4351 rn = "SRSCtl";
4352 break;
7a387fff 4353 case 3:
d75c135e 4354 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4355 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4356 rn = "SRSMap";
fd88b6ab 4357 break;
7a387fff
TS
4358 default:
4359 goto die;
4360 }
873eb012
TS
4361 break;
4362 case 13:
7a387fff
TS
4363 switch (sel) {
4364 case 0:
7db13fae 4365 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4366 rn = "Cause";
4367 break;
7a387fff
TS
4368 default:
4369 goto die;
4370 }
873eb012
TS
4371 break;
4372 case 14:
7a387fff
TS
4373 switch (sel) {
4374 case 0:
7db13fae 4375 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4376 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4377 rn = "EPC";
4378 break;
7a387fff
TS
4379 default:
4380 goto die;
1579a72e 4381 }
873eb012
TS
4382 break;
4383 case 15:
7a387fff
TS
4384 switch (sel) {
4385 case 0:
7db13fae 4386 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4387 rn = "PRid";
4388 break;
7a387fff 4389 case 1:
d75c135e 4390 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4391 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4392 rn = "EBase";
4393 break;
7a387fff
TS
4394 default:
4395 goto die;
4396 }
873eb012
TS
4397 break;
4398 case 16:
4399 switch (sel) {
4400 case 0:
7db13fae 4401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4402 rn = "Config";
4403 break;
4404 case 1:
7db13fae 4405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4406 rn = "Config1";
4407 break;
7a387fff 4408 case 2:
7db13fae 4409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4410 rn = "Config2";
4411 break;
4412 case 3:
7db13fae 4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4414 rn = "Config3";
4415 break;
e397ee33
TS
4416 /* 4,5 are reserved */
4417 /* 6,7 are implementation dependent */
4418 case 6:
7db13fae 4419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4420 rn = "Config6";
4421 break;
4422 case 7:
7db13fae 4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4424 rn = "Config7";
4425 break;
873eb012 4426 default:
873eb012
TS
4427 goto die;
4428 }
4429 break;
4430 case 17:
7a387fff
TS
4431 switch (sel) {
4432 case 0:
895c2d04 4433 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4434 rn = "LLAddr";
4435 break;
7a387fff
TS
4436 default:
4437 goto die;
4438 }
873eb012
TS
4439 break;
4440 case 18:
7a387fff 4441 switch (sel) {
fd88b6ab 4442 case 0 ... 7:
895c2d04 4443 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4444 rn = "WatchLo";
4445 break;
7a387fff
TS
4446 default:
4447 goto die;
4448 }
873eb012
TS
4449 break;
4450 case 19:
7a387fff 4451 switch (sel) {
fd88b6ab 4452 case 0 ...7:
895c2d04 4453 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4454 rn = "WatchHi";
4455 break;
7a387fff
TS
4456 default:
4457 goto die;
4458 }
873eb012 4459 break;
8c0fdd85 4460 case 20:
7a387fff
TS
4461 switch (sel) {
4462 case 0:
d26bc211 4463#if defined(TARGET_MIPS64)
d75c135e 4464 check_insn(ctx, ISA_MIPS3);
7db13fae 4465 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4466 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4467 rn = "XContext";
4468 break;
703eaf37 4469#endif
7a387fff
TS
4470 default:
4471 goto die;
4472 }
8c0fdd85
TS
4473 break;
4474 case 21:
7a387fff
TS
4475 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4476 switch (sel) {
4477 case 0:
7db13fae 4478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4479 rn = "Framemask";
4480 break;
7a387fff
TS
4481 default:
4482 goto die;
4483 }
8c0fdd85
TS
4484 break;
4485 case 22:
d9bea114 4486 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4487 rn = "'Diagnostic"; /* implementation dependent */
4488 break;
873eb012 4489 case 23:
7a387fff
TS
4490 switch (sel) {
4491 case 0:
895c2d04 4492 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4493 rn = "Debug";
4494 break;
7a387fff 4495 case 1:
d9bea114 4496// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4497 rn = "TraceControl";
4498// break;
7a387fff 4499 case 2:
d9bea114 4500// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4501 rn = "TraceControl2";
4502// break;
7a387fff 4503 case 3:
d9bea114 4504// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4505 rn = "UserTraceData";
4506// break;
7a387fff 4507 case 4:
d9bea114 4508// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4509 rn = "TraceBPC";
4510// break;
7a387fff
TS
4511 default:
4512 goto die;
4513 }
873eb012
TS
4514 break;
4515 case 24:
7a387fff
TS
4516 switch (sel) {
4517 case 0:
f0b3f3ae 4518 /* EJTAG support */
7db13fae 4519 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4520 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4521 rn = "DEPC";
4522 break;
7a387fff
TS
4523 default:
4524 goto die;
4525 }
873eb012 4526 break;
8c0fdd85 4527 case 25:
7a387fff
TS
4528 switch (sel) {
4529 case 0:
7db13fae 4530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4531 rn = "Performance0";
7a387fff
TS
4532 break;
4533 case 1:
d9bea114 4534// gen_helper_mfc0_performance1(arg);
2423f660
TS
4535 rn = "Performance1";
4536// break;
7a387fff 4537 case 2:
d9bea114 4538// gen_helper_mfc0_performance2(arg);
2423f660
TS
4539 rn = "Performance2";
4540// break;
7a387fff 4541 case 3:
d9bea114 4542// gen_helper_mfc0_performance3(arg);
2423f660
TS
4543 rn = "Performance3";
4544// break;
7a387fff 4545 case 4:
d9bea114 4546// gen_helper_mfc0_performance4(arg);
2423f660
TS
4547 rn = "Performance4";
4548// break;
7a387fff 4549 case 5:
d9bea114 4550// gen_helper_mfc0_performance5(arg);
2423f660
TS
4551 rn = "Performance5";
4552// break;
7a387fff 4553 case 6:
d9bea114 4554// gen_helper_mfc0_performance6(arg);
2423f660
TS
4555 rn = "Performance6";
4556// break;
7a387fff 4557 case 7:
d9bea114 4558// gen_helper_mfc0_performance7(arg);
2423f660
TS
4559 rn = "Performance7";
4560// break;
7a387fff
TS
4561 default:
4562 goto die;
4563 }
8c0fdd85
TS
4564 break;
4565 case 26:
d9bea114 4566 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4567 rn = "ECC";
4568 break;
8c0fdd85 4569 case 27:
7a387fff 4570 switch (sel) {
7a387fff 4571 case 0 ... 3:
d9bea114 4572 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4573 rn = "CacheErr";
4574 break;
7a387fff
TS
4575 default:
4576 goto die;
4577 }
8c0fdd85 4578 break;
873eb012
TS
4579 case 28:
4580 switch (sel) {
4581 case 0:
7a387fff
TS
4582 case 2:
4583 case 4:
4584 case 6:
7db13fae 4585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4586 rn = "TagLo";
4587 break;
4588 case 1:
7a387fff
TS
4589 case 3:
4590 case 5:
4591 case 7:
7db13fae 4592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4593 rn = "DataLo";
4594 break;
4595 default:
873eb012
TS
4596 goto die;
4597 }
4598 break;
8c0fdd85 4599 case 29:
7a387fff
TS
4600 switch (sel) {
4601 case 0:
4602 case 2:
4603 case 4:
4604 case 6:
7db13fae 4605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4606 rn = "TagHi";
4607 break;
4608 case 1:
4609 case 3:
4610 case 5:
4611 case 7:
7db13fae 4612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4613 rn = "DataHi";
4614 break;
4615 default:
4616 goto die;
4617 }
8c0fdd85 4618 break;
873eb012 4619 case 30:
7a387fff
TS
4620 switch (sel) {
4621 case 0:
7db13fae 4622 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4623 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4624 rn = "ErrorEPC";
4625 break;
7a387fff
TS
4626 default:
4627 goto die;
4628 }
873eb012
TS
4629 break;
4630 case 31:
7a387fff
TS
4631 switch (sel) {
4632 case 0:
f0b3f3ae 4633 /* EJTAG support */
7db13fae 4634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4635 rn = "DESAVE";
4636 break;
7a387fff
TS
4637 default:
4638 goto die;
4639 }
873eb012
TS
4640 break;
4641 default:
873eb012
TS
4642 goto die;
4643 }
2abf314d 4644 (void)rn; /* avoid a compiler warning */
d12d51d5 4645 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4646 return;
4647
4648die:
d12d51d5 4649 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4650 generate_exception(ctx, EXCP_RI);
4651}
4652
d75c135e 4653static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4654{
7a387fff
TS
4655 const char *rn = "invalid";
4656
e189e748 4657 if (sel != 0)
d75c135e 4658 check_insn(ctx, ISA_MIPS32);
e189e748 4659
2e70f6ef
PB
4660 if (use_icount)
4661 gen_io_start();
4662
8c0fdd85
TS
4663 switch (reg) {
4664 case 0:
7a387fff
TS
4665 switch (sel) {
4666 case 0:
895c2d04 4667 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4668 rn = "Index";
4669 break;
4670 case 1:
d75c135e 4671 check_insn(ctx, ASE_MT);
895c2d04 4672 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4673 rn = "MVPControl";
ead9360e 4674 break;
7a387fff 4675 case 2:
d75c135e 4676 check_insn(ctx, ASE_MT);
ead9360e 4677 /* ignored */
7a387fff 4678 rn = "MVPConf0";
ead9360e 4679 break;
7a387fff 4680 case 3:
d75c135e 4681 check_insn(ctx, ASE_MT);
ead9360e 4682 /* ignored */
7a387fff 4683 rn = "MVPConf1";
ead9360e 4684 break;
7a387fff
TS
4685 default:
4686 goto die;
4687 }
8c0fdd85
TS
4688 break;
4689 case 1:
7a387fff
TS
4690 switch (sel) {
4691 case 0:
2423f660 4692 /* ignored */
7a387fff 4693 rn = "Random";
2423f660 4694 break;
7a387fff 4695 case 1:
d75c135e 4696 check_insn(ctx, ASE_MT);
895c2d04 4697 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4698 rn = "VPEControl";
ead9360e 4699 break;
7a387fff 4700 case 2:
d75c135e 4701 check_insn(ctx, ASE_MT);
895c2d04 4702 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4703 rn = "VPEConf0";
ead9360e 4704 break;
7a387fff 4705 case 3:
d75c135e 4706 check_insn(ctx, ASE_MT);
895c2d04 4707 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4708 rn = "VPEConf1";
ead9360e 4709 break;
7a387fff 4710 case 4:
d75c135e 4711 check_insn(ctx, ASE_MT);
895c2d04 4712 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4713 rn = "YQMask";
ead9360e 4714 break;
7a387fff 4715 case 5:
d75c135e 4716 check_insn(ctx, ASE_MT);
7db13fae 4717 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4718 rn = "VPESchedule";
ead9360e 4719 break;
7a387fff 4720 case 6:
d75c135e 4721 check_insn(ctx, ASE_MT);
7db13fae 4722 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4723 rn = "VPEScheFBack";
ead9360e 4724 break;
7a387fff 4725 case 7:
d75c135e 4726 check_insn(ctx, ASE_MT);
895c2d04 4727 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4728 rn = "VPEOpt";
ead9360e 4729 break;
7a387fff
TS
4730 default:
4731 goto die;
4732 }
8c0fdd85
TS
4733 break;
4734 case 2:
7a387fff
TS
4735 switch (sel) {
4736 case 0:
895c2d04 4737 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4738 rn = "EntryLo0";
4739 break;
7a387fff 4740 case 1:
d75c135e 4741 check_insn(ctx, ASE_MT);
895c2d04 4742 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4743 rn = "TCStatus";
ead9360e 4744 break;
7a387fff 4745 case 2:
d75c135e 4746 check_insn(ctx, ASE_MT);
895c2d04 4747 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4748 rn = "TCBind";
ead9360e 4749 break;
7a387fff 4750 case 3:
d75c135e 4751 check_insn(ctx, ASE_MT);
895c2d04 4752 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4753 rn = "TCRestart";
ead9360e 4754 break;
7a387fff 4755 case 4:
d75c135e 4756 check_insn(ctx, ASE_MT);
895c2d04 4757 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4758 rn = "TCHalt";
ead9360e 4759 break;
7a387fff 4760 case 5:
d75c135e 4761 check_insn(ctx, ASE_MT);
895c2d04 4762 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4763 rn = "TCContext";
ead9360e 4764 break;
7a387fff 4765 case 6:
d75c135e 4766 check_insn(ctx, ASE_MT);
895c2d04 4767 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4768 rn = "TCSchedule";
ead9360e 4769 break;
7a387fff 4770 case 7:
d75c135e 4771 check_insn(ctx, ASE_MT);
895c2d04 4772 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4773 rn = "TCScheFBack";
ead9360e 4774 break;
7a387fff
TS
4775 default:
4776 goto die;
4777 }
8c0fdd85
TS
4778 break;
4779 case 3:
7a387fff
TS
4780 switch (sel) {
4781 case 0:
895c2d04 4782 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4783 rn = "EntryLo1";
4784 break;
7a387fff
TS
4785 default:
4786 goto die;
876d4b07 4787 }
8c0fdd85
TS
4788 break;
4789 case 4:
7a387fff
TS
4790 switch (sel) {
4791 case 0:
895c2d04 4792 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4793 rn = "Context";
4794 break;
7a387fff 4795 case 1:
895c2d04 4796// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
4797 rn = "ContextConfig";
4798// break;
7a387fff
TS
4799 default:
4800 goto die;
876d4b07 4801 }
8c0fdd85
TS
4802 break;
4803 case 5:
7a387fff
TS
4804 switch (sel) {
4805 case 0:
895c2d04 4806 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4807 rn = "PageMask";
4808 break;
7a387fff 4809 case 1:
d75c135e 4810 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4811 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4812 rn = "PageGrain";
4813 break;
7a387fff
TS
4814 default:
4815 goto die;
876d4b07 4816 }
8c0fdd85
TS
4817 break;
4818 case 6:
7a387fff
TS
4819 switch (sel) {
4820 case 0:
895c2d04 4821 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4822 rn = "Wired";
4823 break;
7a387fff 4824 case 1:
d75c135e 4825 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4826 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4827 rn = "SRSConf0";
ead9360e 4828 break;
7a387fff 4829 case 2:
d75c135e 4830 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4831 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4832 rn = "SRSConf1";
ead9360e 4833 break;
7a387fff 4834 case 3:
d75c135e 4835 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4836 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4837 rn = "SRSConf2";
ead9360e 4838 break;
7a387fff 4839 case 4:
d75c135e 4840 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4841 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4842 rn = "SRSConf3";
ead9360e 4843 break;
7a387fff 4844 case 5:
d75c135e 4845 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4846 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4847 rn = "SRSConf4";
ead9360e 4848 break;
7a387fff
TS
4849 default:
4850 goto die;
876d4b07 4851 }
8c0fdd85
TS
4852 break;
4853 case 7:
7a387fff
TS
4854 switch (sel) {
4855 case 0:
d75c135e 4856 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4857 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
4858 rn = "HWREna";
4859 break;
7a387fff
TS
4860 default:
4861 goto die;
876d4b07 4862 }
8c0fdd85
TS
4863 break;
4864 case 8:
7a387fff 4865 /* ignored */
f0b3f3ae 4866 rn = "BadVAddr";
8c0fdd85
TS
4867 break;
4868 case 9:
7a387fff
TS
4869 switch (sel) {
4870 case 0:
895c2d04 4871 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4872 rn = "Count";
4873 break;
876d4b07 4874 /* 6,7 are implementation dependent */
7a387fff
TS
4875 default:
4876 goto die;
876d4b07 4877 }
8c0fdd85
TS
4878 break;
4879 case 10:
7a387fff
TS
4880 switch (sel) {
4881 case 0:
895c2d04 4882 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4883 rn = "EntryHi";
4884 break;
7a387fff
TS
4885 default:
4886 goto die;
876d4b07 4887 }
8c0fdd85
TS
4888 break;
4889 case 11:
7a387fff
TS
4890 switch (sel) {
4891 case 0:
895c2d04 4892 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4893 rn = "Compare";
4894 break;
4895 /* 6,7 are implementation dependent */
7a387fff
TS
4896 default:
4897 goto die;
876d4b07 4898 }
8c0fdd85
TS
4899 break;
4900 case 12:
7a387fff
TS
4901 switch (sel) {
4902 case 0:
867abc7e 4903 save_cpu_state(ctx, 1);
895c2d04 4904 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4905 /* BS_STOP isn't good enough here, hflags may have changed. */
4906 gen_save_pc(ctx->pc + 4);
4907 ctx->bstate = BS_EXCP;
2423f660
TS
4908 rn = "Status";
4909 break;
7a387fff 4910 case 1:
d75c135e 4911 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4912 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4913 /* Stop translation as we may have switched the execution mode */
4914 ctx->bstate = BS_STOP;
2423f660
TS
4915 rn = "IntCtl";
4916 break;
7a387fff 4917 case 2:
d75c135e 4918 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4919 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4920 /* Stop translation as we may have switched the execution mode */
4921 ctx->bstate = BS_STOP;
2423f660
TS
4922 rn = "SRSCtl";
4923 break;
7a387fff 4924 case 3:
d75c135e 4925 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4926 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4927 /* Stop translation as we may have switched the execution mode */
4928 ctx->bstate = BS_STOP;
2423f660 4929 rn = "SRSMap";
fd88b6ab 4930 break;
7a387fff
TS
4931 default:
4932 goto die;
876d4b07 4933 }
8c0fdd85
TS
4934 break;
4935 case 13:
7a387fff
TS
4936 switch (sel) {
4937 case 0:
867abc7e 4938 save_cpu_state(ctx, 1);
895c2d04 4939 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4940 rn = "Cause";
4941 break;
7a387fff
TS
4942 default:
4943 goto die;
876d4b07 4944 }
8c0fdd85
TS
4945 break;
4946 case 14:
7a387fff
TS
4947 switch (sel) {
4948 case 0:
7db13fae 4949 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4950 rn = "EPC";
4951 break;
7a387fff
TS
4952 default:
4953 goto die;
876d4b07 4954 }
8c0fdd85
TS
4955 break;
4956 case 15:
7a387fff
TS
4957 switch (sel) {
4958 case 0:
2423f660
TS
4959 /* ignored */
4960 rn = "PRid";
4961 break;
7a387fff 4962 case 1:
d75c135e 4963 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4964 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
4965 rn = "EBase";
4966 break;
7a387fff
TS
4967 default:
4968 goto die;
1579a72e 4969 }
8c0fdd85
TS
4970 break;
4971 case 16:
4972 switch (sel) {
4973 case 0:
895c2d04 4974 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 4975 rn = "Config";
2423f660
TS
4976 /* Stop translation as we may have switched the execution mode */
4977 ctx->bstate = BS_STOP;
7a387fff
TS
4978 break;
4979 case 1:
e397ee33 4980 /* ignored, read only */
7a387fff
TS
4981 rn = "Config1";
4982 break;
4983 case 2:
895c2d04 4984 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 4985 rn = "Config2";
2423f660
TS
4986 /* Stop translation as we may have switched the execution mode */
4987 ctx->bstate = BS_STOP;
8c0fdd85 4988 break;
7a387fff 4989 case 3:
e397ee33 4990 /* ignored, read only */
7a387fff
TS
4991 rn = "Config3";
4992 break;
e397ee33
TS
4993 /* 4,5 are reserved */
4994 /* 6,7 are implementation dependent */
4995 case 6:
4996 /* ignored */
4997 rn = "Config6";
4998 break;
4999 case 7:
5000 /* ignored */
5001 rn = "Config7";
5002 break;
8c0fdd85
TS
5003 default:
5004 rn = "Invalid config selector";
5005 goto die;
5006 }
5007 break;
5008 case 17:
7a387fff
TS
5009 switch (sel) {
5010 case 0:
895c2d04 5011 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5012 rn = "LLAddr";
5013 break;
7a387fff
TS
5014 default:
5015 goto die;
5016 }
8c0fdd85
TS
5017 break;
5018 case 18:
7a387fff 5019 switch (sel) {
fd88b6ab 5020 case 0 ... 7:
895c2d04 5021 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5022 rn = "WatchLo";
5023 break;
7a387fff
TS
5024 default:
5025 goto die;
5026 }
8c0fdd85
TS
5027 break;
5028 case 19:
7a387fff 5029 switch (sel) {
fd88b6ab 5030 case 0 ... 7:
895c2d04 5031 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5032 rn = "WatchHi";
5033 break;
7a387fff
TS
5034 default:
5035 goto die;
5036 }
8c0fdd85
TS
5037 break;
5038 case 20:
7a387fff
TS
5039 switch (sel) {
5040 case 0:
d26bc211 5041#if defined(TARGET_MIPS64)
d75c135e 5042 check_insn(ctx, ISA_MIPS3);
895c2d04 5043 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5044 rn = "XContext";
5045 break;
703eaf37 5046#endif
7a387fff
TS
5047 default:
5048 goto die;
5049 }
8c0fdd85
TS
5050 break;
5051 case 21:
7a387fff
TS
5052 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5053 switch (sel) {
5054 case 0:
895c2d04 5055 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5056 rn = "Framemask";
5057 break;
7a387fff
TS
5058 default:
5059 goto die;
5060 }
5061 break;
8c0fdd85 5062 case 22:
7a387fff
TS
5063 /* ignored */
5064 rn = "Diagnostic"; /* implementation dependent */
2423f660 5065 break;
8c0fdd85 5066 case 23:
7a387fff
TS
5067 switch (sel) {
5068 case 0:
895c2d04 5069 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5070 /* BS_STOP isn't good enough here, hflags may have changed. */
5071 gen_save_pc(ctx->pc + 4);
5072 ctx->bstate = BS_EXCP;
2423f660
TS
5073 rn = "Debug";
5074 break;
7a387fff 5075 case 1:
895c2d04 5076// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5077 rn = "TraceControl";
8487327a
TS
5078 /* Stop translation as we may have switched the execution mode */
5079 ctx->bstate = BS_STOP;
2423f660 5080// break;
7a387fff 5081 case 2:
895c2d04 5082// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5083 rn = "TraceControl2";
8487327a
TS
5084 /* Stop translation as we may have switched the execution mode */
5085 ctx->bstate = BS_STOP;
2423f660 5086// break;
7a387fff 5087 case 3:
8487327a
TS
5088 /* Stop translation as we may have switched the execution mode */
5089 ctx->bstate = BS_STOP;
895c2d04 5090// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5091 rn = "UserTraceData";
8487327a
TS
5092 /* Stop translation as we may have switched the execution mode */
5093 ctx->bstate = BS_STOP;
2423f660 5094// break;
7a387fff 5095 case 4:
895c2d04 5096// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5097 /* Stop translation as we may have switched the execution mode */
5098 ctx->bstate = BS_STOP;
2423f660
TS
5099 rn = "TraceBPC";
5100// break;
7a387fff
TS
5101 default:
5102 goto die;
5103 }
8c0fdd85
TS
5104 break;
5105 case 24:
7a387fff
TS
5106 switch (sel) {
5107 case 0:
f1aa6320 5108 /* EJTAG support */
7db13fae 5109 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5110 rn = "DEPC";
5111 break;
7a387fff
TS
5112 default:
5113 goto die;
5114 }
8c0fdd85
TS
5115 break;
5116 case 25:
7a387fff
TS
5117 switch (sel) {
5118 case 0:
895c2d04 5119 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5120 rn = "Performance0";
5121 break;
7a387fff 5122 case 1:
d9bea114 5123// gen_helper_mtc0_performance1(arg);
2423f660
TS
5124 rn = "Performance1";
5125// break;
7a387fff 5126 case 2:
d9bea114 5127// gen_helper_mtc0_performance2(arg);
2423f660
TS
5128 rn = "Performance2";
5129// break;
7a387fff 5130 case 3:
d9bea114 5131// gen_helper_mtc0_performance3(arg);
2423f660
TS
5132 rn = "Performance3";
5133// break;
7a387fff 5134 case 4:
d9bea114 5135// gen_helper_mtc0_performance4(arg);
2423f660
TS
5136 rn = "Performance4";
5137// break;
7a387fff 5138 case 5:
d9bea114 5139// gen_helper_mtc0_performance5(arg);
2423f660
TS
5140 rn = "Performance5";
5141// break;
7a387fff 5142 case 6:
d9bea114 5143// gen_helper_mtc0_performance6(arg);
2423f660
TS
5144 rn = "Performance6";
5145// break;
7a387fff 5146 case 7:
d9bea114 5147// gen_helper_mtc0_performance7(arg);
2423f660
TS
5148 rn = "Performance7";
5149// break;
7a387fff
TS
5150 default:
5151 goto die;
5152 }
8c0fdd85
TS
5153 break;
5154 case 26:
2423f660 5155 /* ignored */
8c0fdd85 5156 rn = "ECC";
2423f660 5157 break;
8c0fdd85 5158 case 27:
7a387fff
TS
5159 switch (sel) {
5160 case 0 ... 3:
2423f660
TS
5161 /* ignored */
5162 rn = "CacheErr";
5163 break;
7a387fff
TS
5164 default:
5165 goto die;
5166 }
8c0fdd85
TS
5167 break;
5168 case 28:
5169 switch (sel) {
5170 case 0:
7a387fff
TS
5171 case 2:
5172 case 4:
5173 case 6:
895c2d04 5174 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5175 rn = "TagLo";
5176 break;
7a387fff
TS
5177 case 1:
5178 case 3:
5179 case 5:
5180 case 7:
895c2d04 5181 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5182 rn = "DataLo";
5183 break;
8c0fdd85 5184 default:
8c0fdd85
TS
5185 goto die;
5186 }
5187 break;
5188 case 29:
7a387fff
TS
5189 switch (sel) {
5190 case 0:
5191 case 2:
5192 case 4:
5193 case 6:
895c2d04 5194 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5195 rn = "TagHi";
5196 break;
5197 case 1:
5198 case 3:
5199 case 5:
5200 case 7:
895c2d04 5201 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5202 rn = "DataHi";
5203 break;
5204 default:
5205 rn = "invalid sel";
5206 goto die;
5207 }
8c0fdd85
TS
5208 break;
5209 case 30:
7a387fff
TS
5210 switch (sel) {
5211 case 0:
7db13fae 5212 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5213 rn = "ErrorEPC";
5214 break;
7a387fff
TS
5215 default:
5216 goto die;
5217 }
8c0fdd85
TS
5218 break;
5219 case 31:
7a387fff
TS
5220 switch (sel) {
5221 case 0:
f1aa6320 5222 /* EJTAG support */
7db13fae 5223 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5224 rn = "DESAVE";
5225 break;
7a387fff
TS
5226 default:
5227 goto die;
5228 }
2423f660
TS
5229 /* Stop translation as we may have switched the execution mode */
5230 ctx->bstate = BS_STOP;
8c0fdd85
TS
5231 break;
5232 default:
8c0fdd85
TS
5233 goto die;
5234 }
2abf314d 5235 (void)rn; /* avoid a compiler warning */
d12d51d5 5236 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5237 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5238 if (use_icount) {
5239 gen_io_end();
5240 ctx->bstate = BS_STOP;
5241 }
8c0fdd85
TS
5242 return;
5243
5244die:
d12d51d5 5245 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5246 generate_exception(ctx, EXCP_RI);
5247}
5248
d26bc211 5249#if defined(TARGET_MIPS64)
d75c135e 5250static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5251{
5252 const char *rn = "invalid";
5253
e189e748 5254 if (sel != 0)
d75c135e 5255 check_insn(ctx, ISA_MIPS64);
e189e748 5256
9c2149c8
TS
5257 switch (reg) {
5258 case 0:
5259 switch (sel) {
5260 case 0:
7db13fae 5261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5262 rn = "Index";
5263 break;
5264 case 1:
d75c135e 5265 check_insn(ctx, ASE_MT);
895c2d04 5266 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5267 rn = "MVPControl";
ead9360e 5268 break;
9c2149c8 5269 case 2:
d75c135e 5270 check_insn(ctx, ASE_MT);
895c2d04 5271 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5272 rn = "MVPConf0";
ead9360e 5273 break;
9c2149c8 5274 case 3:
d75c135e 5275 check_insn(ctx, ASE_MT);
895c2d04 5276 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5277 rn = "MVPConf1";
ead9360e 5278 break;
9c2149c8
TS
5279 default:
5280 goto die;
5281 }
5282 break;
5283 case 1:
5284 switch (sel) {
5285 case 0:
895c2d04 5286 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5287 rn = "Random";
2423f660 5288 break;
9c2149c8 5289 case 1:
d75c135e 5290 check_insn(ctx, ASE_MT);
7db13fae 5291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5292 rn = "VPEControl";
ead9360e 5293 break;
9c2149c8 5294 case 2:
d75c135e 5295 check_insn(ctx, ASE_MT);
7db13fae 5296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5297 rn = "VPEConf0";
ead9360e 5298 break;
9c2149c8 5299 case 3:
d75c135e 5300 check_insn(ctx, ASE_MT);
7db13fae 5301 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5302 rn = "VPEConf1";
ead9360e 5303 break;
9c2149c8 5304 case 4:
d75c135e 5305 check_insn(ctx, ASE_MT);
7db13fae 5306 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5307 rn = "YQMask";
ead9360e 5308 break;
9c2149c8 5309 case 5:
d75c135e 5310 check_insn(ctx, ASE_MT);
7db13fae 5311 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5312 rn = "VPESchedule";
ead9360e 5313 break;
9c2149c8 5314 case 6:
d75c135e 5315 check_insn(ctx, ASE_MT);
7db13fae 5316 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5317 rn = "VPEScheFBack";
ead9360e 5318 break;
9c2149c8 5319 case 7:
d75c135e 5320 check_insn(ctx, ASE_MT);
7db13fae 5321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5322 rn = "VPEOpt";
ead9360e 5323 break;
9c2149c8
TS
5324 default:
5325 goto die;
5326 }
5327 break;
5328 case 2:
5329 switch (sel) {
5330 case 0:
7db13fae 5331 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5332 rn = "EntryLo0";
5333 break;
9c2149c8 5334 case 1:
d75c135e 5335 check_insn(ctx, ASE_MT);
895c2d04 5336 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5337 rn = "TCStatus";
ead9360e 5338 break;
9c2149c8 5339 case 2:
d75c135e 5340 check_insn(ctx, ASE_MT);
895c2d04 5341 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5342 rn = "TCBind";
ead9360e 5343 break;
9c2149c8 5344 case 3:
d75c135e 5345 check_insn(ctx, ASE_MT);
895c2d04 5346 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5347 rn = "TCRestart";
ead9360e 5348 break;
9c2149c8 5349 case 4:
d75c135e 5350 check_insn(ctx, ASE_MT);
895c2d04 5351 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5352 rn = "TCHalt";
ead9360e 5353 break;
9c2149c8 5354 case 5:
d75c135e 5355 check_insn(ctx, ASE_MT);
895c2d04 5356 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5357 rn = "TCContext";
ead9360e 5358 break;
9c2149c8 5359 case 6:
d75c135e 5360 check_insn(ctx, ASE_MT);
895c2d04 5361 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5362 rn = "TCSchedule";
ead9360e 5363 break;
9c2149c8 5364 case 7:
d75c135e 5365 check_insn(ctx, ASE_MT);
895c2d04 5366 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5367 rn = "TCScheFBack";
ead9360e 5368 break;
9c2149c8
TS
5369 default:
5370 goto die;
5371 }
5372 break;
5373 case 3:
5374 switch (sel) {
5375 case 0:
7db13fae 5376 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5377 rn = "EntryLo1";
5378 break;
9c2149c8
TS
5379 default:
5380 goto die;
1579a72e 5381 }
9c2149c8
TS
5382 break;
5383 case 4:
5384 switch (sel) {
5385 case 0:
7db13fae 5386 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5387 rn = "Context";
5388 break;
9c2149c8 5389 case 1:
d9bea114 5390// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
5391 rn = "ContextConfig";
5392// break;
9c2149c8
TS
5393 default:
5394 goto die;
876d4b07 5395 }
9c2149c8
TS
5396 break;
5397 case 5:
5398 switch (sel) {
5399 case 0:
7db13fae 5400 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5401 rn = "PageMask";
5402 break;
9c2149c8 5403 case 1:
d75c135e 5404 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5406 rn = "PageGrain";
5407 break;
9c2149c8
TS
5408 default:
5409 goto die;
876d4b07 5410 }
9c2149c8
TS
5411 break;
5412 case 6:
5413 switch (sel) {
5414 case 0:
7db13fae 5415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5416 rn = "Wired";
5417 break;
9c2149c8 5418 case 1:
d75c135e 5419 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5421 rn = "SRSConf0";
ead9360e 5422 break;
9c2149c8 5423 case 2:
d75c135e 5424 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5426 rn = "SRSConf1";
ead9360e 5427 break;
9c2149c8 5428 case 3:
d75c135e 5429 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5431 rn = "SRSConf2";
ead9360e 5432 break;
9c2149c8 5433 case 4:
d75c135e 5434 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5436 rn = "SRSConf3";
ead9360e 5437 break;
9c2149c8 5438 case 5:
d75c135e 5439 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5441 rn = "SRSConf4";
ead9360e 5442 break;
9c2149c8
TS
5443 default:
5444 goto die;
876d4b07 5445 }
9c2149c8
TS
5446 break;
5447 case 7:
5448 switch (sel) {
5449 case 0:
d75c135e 5450 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5452 rn = "HWREna";
5453 break;
9c2149c8
TS
5454 default:
5455 goto die;
876d4b07 5456 }
9c2149c8
TS
5457 break;
5458 case 8:
5459 switch (sel) {
5460 case 0:
7db13fae 5461 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5462 rn = "BadVAddr";
2423f660 5463 break;
9c2149c8
TS
5464 default:
5465 goto die;
876d4b07 5466 }
9c2149c8
TS
5467 break;
5468 case 9:
5469 switch (sel) {
5470 case 0:
2e70f6ef
PB
5471 /* Mark as an IO operation because we read the time. */
5472 if (use_icount)
5473 gen_io_start();
895c2d04 5474 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5475 if (use_icount) {
5476 gen_io_end();
2e70f6ef 5477 }
55807224
EI
5478 /* Break the TB to be able to take timer interrupts immediately
5479 after reading count. */
5480 ctx->bstate = BS_STOP;
2423f660
TS
5481 rn = "Count";
5482 break;
5483 /* 6,7 are implementation dependent */
9c2149c8
TS
5484 default:
5485 goto die;
876d4b07 5486 }
9c2149c8
TS
5487 break;
5488 case 10:
5489 switch (sel) {
5490 case 0:
7db13fae 5491 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5492 rn = "EntryHi";
5493 break;
9c2149c8
TS
5494 default:
5495 goto die;
876d4b07 5496 }
9c2149c8
TS
5497 break;
5498 case 11:
5499 switch (sel) {
5500 case 0:
7db13fae 5501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5502 rn = "Compare";
5503 break;
876d4b07 5504 /* 6,7 are implementation dependent */
9c2149c8
TS
5505 default:
5506 goto die;
876d4b07 5507 }
9c2149c8
TS
5508 break;
5509 case 12:
5510 switch (sel) {
5511 case 0:
7db13fae 5512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5513 rn = "Status";
5514 break;
9c2149c8 5515 case 1:
d75c135e 5516 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5517 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5518 rn = "IntCtl";
5519 break;
9c2149c8 5520 case 2:
d75c135e 5521 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5523 rn = "SRSCtl";
5524 break;
9c2149c8 5525 case 3:
d75c135e 5526 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5527 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5528 rn = "SRSMap";
5529 break;
9c2149c8
TS
5530 default:
5531 goto die;
876d4b07 5532 }
9c2149c8
TS
5533 break;
5534 case 13:
5535 switch (sel) {
5536 case 0:
7db13fae 5537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5538 rn = "Cause";
5539 break;
9c2149c8
TS
5540 default:
5541 goto die;
876d4b07 5542 }
9c2149c8
TS
5543 break;
5544 case 14:
5545 switch (sel) {
5546 case 0:
7db13fae 5547 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5548 rn = "EPC";
5549 break;
9c2149c8
TS
5550 default:
5551 goto die;
876d4b07 5552 }
9c2149c8
TS
5553 break;
5554 case 15:
5555 switch (sel) {
5556 case 0:
7db13fae 5557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5558 rn = "PRid";
5559 break;
9c2149c8 5560 case 1:
d75c135e 5561 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5563 rn = "EBase";
5564 break;
9c2149c8
TS
5565 default:
5566 goto die;
876d4b07 5567 }
9c2149c8
TS
5568 break;
5569 case 16:
5570 switch (sel) {
5571 case 0:
7db13fae 5572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5573 rn = "Config";
5574 break;
5575 case 1:
7db13fae 5576 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5577 rn = "Config1";
5578 break;
5579 case 2:
7db13fae 5580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5581 rn = "Config2";
5582 break;
5583 case 3:
7db13fae 5584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5585 rn = "Config3";
5586 break;
5587 /* 6,7 are implementation dependent */
f0b3f3ae 5588 case 6:
7db13fae 5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5590 rn = "Config6";
5591 break;
5592 case 7:
7db13fae 5593 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5594 rn = "Config7";
5595 break;
9c2149c8
TS
5596 default:
5597 goto die;
5598 }
5599 break;
5600 case 17:
5601 switch (sel) {
5602 case 0:
895c2d04 5603 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5604 rn = "LLAddr";
5605 break;
9c2149c8
TS
5606 default:
5607 goto die;
5608 }
5609 break;
5610 case 18:
5611 switch (sel) {
fd88b6ab 5612 case 0 ... 7:
895c2d04 5613 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5614 rn = "WatchLo";
5615 break;
9c2149c8
TS
5616 default:
5617 goto die;
5618 }
5619 break;
5620 case 19:
5621 switch (sel) {
fd88b6ab 5622 case 0 ... 7:
895c2d04 5623 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5624 rn = "WatchHi";
5625 break;
9c2149c8
TS
5626 default:
5627 goto die;
5628 }
5629 break;
5630 case 20:
5631 switch (sel) {
5632 case 0:
d75c135e 5633 check_insn(ctx, ISA_MIPS3);
7db13fae 5634 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5635 rn = "XContext";
5636 break;
9c2149c8
TS
5637 default:
5638 goto die;
5639 }
5640 break;
5641 case 21:
5642 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5643 switch (sel) {
5644 case 0:
7db13fae 5645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5646 rn = "Framemask";
5647 break;
9c2149c8
TS
5648 default:
5649 goto die;
5650 }
5651 break;
5652 case 22:
d9bea114 5653 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5654 rn = "'Diagnostic"; /* implementation dependent */
5655 break;
9c2149c8
TS
5656 case 23:
5657 switch (sel) {
5658 case 0:
895c2d04 5659 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5660 rn = "Debug";
5661 break;
9c2149c8 5662 case 1:
895c2d04 5663// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5664 rn = "TraceControl";
5665// break;
9c2149c8 5666 case 2:
895c2d04 5667// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5668 rn = "TraceControl2";
5669// break;
9c2149c8 5670 case 3:
895c2d04 5671// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5672 rn = "UserTraceData";
5673// break;
9c2149c8 5674 case 4:
895c2d04 5675// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5676 rn = "TraceBPC";
5677// break;
9c2149c8
TS
5678 default:
5679 goto die;
5680 }
5681 break;
5682 case 24:
5683 switch (sel) {
5684 case 0:
f0b3f3ae 5685 /* EJTAG support */
7db13fae 5686 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5687 rn = "DEPC";
5688 break;
9c2149c8
TS
5689 default:
5690 goto die;
5691 }
5692 break;
5693 case 25:
5694 switch (sel) {
5695 case 0:
7db13fae 5696 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5697 rn = "Performance0";
9c2149c8
TS
5698 break;
5699 case 1:
d9bea114 5700// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5701 rn = "Performance1";
5702// break;
9c2149c8 5703 case 2:
d9bea114 5704// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5705 rn = "Performance2";
5706// break;
9c2149c8 5707 case 3:
d9bea114 5708// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5709 rn = "Performance3";
5710// break;
9c2149c8 5711 case 4:
d9bea114 5712// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5713 rn = "Performance4";
5714// break;
9c2149c8 5715 case 5:
d9bea114 5716// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5717 rn = "Performance5";
5718// break;
9c2149c8 5719 case 6:
d9bea114 5720// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5721 rn = "Performance6";
5722// break;
9c2149c8 5723 case 7:
d9bea114 5724// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5725 rn = "Performance7";
5726// break;
9c2149c8
TS
5727 default:
5728 goto die;
5729 }
5730 break;
5731 case 26:
d9bea114 5732 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5733 rn = "ECC";
5734 break;
9c2149c8
TS
5735 case 27:
5736 switch (sel) {
5737 /* ignored */
5738 case 0 ... 3:
d9bea114 5739 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5740 rn = "CacheErr";
5741 break;
9c2149c8
TS
5742 default:
5743 goto die;
5744 }
5745 break;
5746 case 28:
5747 switch (sel) {
5748 case 0:
5749 case 2:
5750 case 4:
5751 case 6:
7db13fae 5752 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5753 rn = "TagLo";
5754 break;
5755 case 1:
5756 case 3:
5757 case 5:
5758 case 7:
7db13fae 5759 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5760 rn = "DataLo";
5761 break;
5762 default:
5763 goto die;
5764 }
5765 break;
5766 case 29:
5767 switch (sel) {
5768 case 0:
5769 case 2:
5770 case 4:
5771 case 6:
7db13fae 5772 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5773 rn = "TagHi";
5774 break;
5775 case 1:
5776 case 3:
5777 case 5:
5778 case 7:
7db13fae 5779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5780 rn = "DataHi";
5781 break;
5782 default:
5783 goto die;
5784 }
5785 break;
5786 case 30:
5787 switch (sel) {
5788 case 0:
7db13fae 5789 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5790 rn = "ErrorEPC";
5791 break;
9c2149c8
TS
5792 default:
5793 goto die;
5794 }
5795 break;
5796 case 31:
5797 switch (sel) {
5798 case 0:
f0b3f3ae 5799 /* EJTAG support */
7db13fae 5800 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5801 rn = "DESAVE";
5802 break;
9c2149c8
TS
5803 default:
5804 goto die;
5805 }
5806 break;
5807 default:
876d4b07 5808 goto die;
9c2149c8 5809 }
2abf314d 5810 (void)rn; /* avoid a compiler warning */
d12d51d5 5811 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5812 return;
5813
5814die:
d12d51d5 5815 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5816 generate_exception(ctx, EXCP_RI);
5817}
5818
d75c135e 5819static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5820{
5821 const char *rn = "invalid";
5822
e189e748 5823 if (sel != 0)
d75c135e 5824 check_insn(ctx, ISA_MIPS64);
e189e748 5825
2e70f6ef
PB
5826 if (use_icount)
5827 gen_io_start();
5828
9c2149c8
TS
5829 switch (reg) {
5830 case 0:
5831 switch (sel) {
5832 case 0:
895c2d04 5833 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5834 rn = "Index";
5835 break;
5836 case 1:
d75c135e 5837 check_insn(ctx, ASE_MT);
895c2d04 5838 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5839 rn = "MVPControl";
ead9360e 5840 break;
9c2149c8 5841 case 2:
d75c135e 5842 check_insn(ctx, ASE_MT);
ead9360e 5843 /* ignored */
9c2149c8 5844 rn = "MVPConf0";
ead9360e 5845 break;
9c2149c8 5846 case 3:
d75c135e 5847 check_insn(ctx, ASE_MT);
ead9360e 5848 /* ignored */
9c2149c8 5849 rn = "MVPConf1";
ead9360e 5850 break;
9c2149c8
TS
5851 default:
5852 goto die;
5853 }
5854 break;
5855 case 1:
5856 switch (sel) {
5857 case 0:
2423f660 5858 /* ignored */
9c2149c8 5859 rn = "Random";
2423f660 5860 break;
9c2149c8 5861 case 1:
d75c135e 5862 check_insn(ctx, ASE_MT);
895c2d04 5863 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5864 rn = "VPEControl";
ead9360e 5865 break;
9c2149c8 5866 case 2:
d75c135e 5867 check_insn(ctx, ASE_MT);
895c2d04 5868 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5869 rn = "VPEConf0";
ead9360e 5870 break;
9c2149c8 5871 case 3:
d75c135e 5872 check_insn(ctx, ASE_MT);
895c2d04 5873 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5874 rn = "VPEConf1";
ead9360e 5875 break;
9c2149c8 5876 case 4:
d75c135e 5877 check_insn(ctx, ASE_MT);
895c2d04 5878 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5879 rn = "YQMask";
ead9360e 5880 break;
9c2149c8 5881 case 5:
d75c135e 5882 check_insn(ctx, ASE_MT);
7db13fae 5883 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5884 rn = "VPESchedule";
ead9360e 5885 break;
9c2149c8 5886 case 6:
d75c135e 5887 check_insn(ctx, ASE_MT);
7db13fae 5888 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5889 rn = "VPEScheFBack";
ead9360e 5890 break;
9c2149c8 5891 case 7:
d75c135e 5892 check_insn(ctx, ASE_MT);
895c2d04 5893 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5894 rn = "VPEOpt";
ead9360e 5895 break;
9c2149c8
TS
5896 default:
5897 goto die;
5898 }
5899 break;
5900 case 2:
5901 switch (sel) {
5902 case 0:
895c2d04 5903 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5904 rn = "EntryLo0";
5905 break;
9c2149c8 5906 case 1:
d75c135e 5907 check_insn(ctx, ASE_MT);
895c2d04 5908 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5909 rn = "TCStatus";
ead9360e 5910 break;
9c2149c8 5911 case 2:
d75c135e 5912 check_insn(ctx, ASE_MT);
895c2d04 5913 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5914 rn = "TCBind";
ead9360e 5915 break;
9c2149c8 5916 case 3:
d75c135e 5917 check_insn(ctx, ASE_MT);
895c2d04 5918 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5919 rn = "TCRestart";
ead9360e 5920 break;
9c2149c8 5921 case 4:
d75c135e 5922 check_insn(ctx, ASE_MT);
895c2d04 5923 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5924 rn = "TCHalt";
ead9360e 5925 break;
9c2149c8 5926 case 5:
d75c135e 5927 check_insn(ctx, ASE_MT);
895c2d04 5928 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5929 rn = "TCContext";
ead9360e 5930 break;
9c2149c8 5931 case 6:
d75c135e 5932 check_insn(ctx, ASE_MT);
895c2d04 5933 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5934 rn = "TCSchedule";
ead9360e 5935 break;
9c2149c8 5936 case 7:
d75c135e 5937 check_insn(ctx, ASE_MT);
895c2d04 5938 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5939 rn = "TCScheFBack";
ead9360e 5940 break;
9c2149c8
TS
5941 default:
5942 goto die;
5943 }
5944 break;
5945 case 3:
5946 switch (sel) {
5947 case 0:
895c2d04 5948 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5949 rn = "EntryLo1";
5950 break;
9c2149c8
TS
5951 default:
5952 goto die;
876d4b07 5953 }
9c2149c8
TS
5954 break;
5955 case 4:
5956 switch (sel) {
5957 case 0:
895c2d04 5958 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5959 rn = "Context";
5960 break;
9c2149c8 5961 case 1:
895c2d04 5962// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
5963 rn = "ContextConfig";
5964// break;
9c2149c8
TS
5965 default:
5966 goto die;
876d4b07 5967 }
9c2149c8
TS
5968 break;
5969 case 5:
5970 switch (sel) {
5971 case 0:
895c2d04 5972 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5973 rn = "PageMask";
5974 break;
9c2149c8 5975 case 1:
d75c135e 5976 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5977 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5978 rn = "PageGrain";
5979 break;
9c2149c8
TS
5980 default:
5981 goto die;
876d4b07 5982 }
9c2149c8
TS
5983 break;
5984 case 6:
5985 switch (sel) {
5986 case 0:
895c2d04 5987 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5988 rn = "Wired";
5989 break;
9c2149c8 5990 case 1:
d75c135e 5991 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5992 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5993 rn = "SRSConf0";
ead9360e 5994 break;
9c2149c8 5995 case 2:
d75c135e 5996 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5997 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5998 rn = "SRSConf1";
ead9360e 5999 break;
9c2149c8 6000 case 3:
d75c135e 6001 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6002 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6003 rn = "SRSConf2";
ead9360e 6004 break;
9c2149c8 6005 case 4:
d75c135e 6006 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6007 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6008 rn = "SRSConf3";
ead9360e 6009 break;
9c2149c8 6010 case 5:
d75c135e 6011 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6012 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6013 rn = "SRSConf4";
ead9360e 6014 break;
9c2149c8
TS
6015 default:
6016 goto die;
876d4b07 6017 }
9c2149c8
TS
6018 break;
6019 case 7:
6020 switch (sel) {
6021 case 0:
d75c135e 6022 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6023 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
6024 rn = "HWREna";
6025 break;
9c2149c8
TS
6026 default:
6027 goto die;
876d4b07 6028 }
9c2149c8
TS
6029 break;
6030 case 8:
6031 /* ignored */
f0b3f3ae 6032 rn = "BadVAddr";
9c2149c8
TS
6033 break;
6034 case 9:
6035 switch (sel) {
6036 case 0:
895c2d04 6037 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6038 rn = "Count";
6039 break;
876d4b07 6040 /* 6,7 are implementation dependent */
9c2149c8
TS
6041 default:
6042 goto die;
876d4b07
TS
6043 }
6044 /* Stop translation as we may have switched the execution mode */
6045 ctx->bstate = BS_STOP;
9c2149c8
TS
6046 break;
6047 case 10:
6048 switch (sel) {
6049 case 0:
895c2d04 6050 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6051 rn = "EntryHi";
6052 break;
9c2149c8
TS
6053 default:
6054 goto die;
876d4b07 6055 }
9c2149c8
TS
6056 break;
6057 case 11:
6058 switch (sel) {
6059 case 0:
895c2d04 6060 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6061 rn = "Compare";
6062 break;
876d4b07 6063 /* 6,7 are implementation dependent */
9c2149c8
TS
6064 default:
6065 goto die;
876d4b07 6066 }
de9a95f0
AJ
6067 /* Stop translation as we may have switched the execution mode */
6068 ctx->bstate = BS_STOP;
9c2149c8
TS
6069 break;
6070 case 12:
6071 switch (sel) {
6072 case 0:
867abc7e 6073 save_cpu_state(ctx, 1);
895c2d04 6074 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6075 /* BS_STOP isn't good enough here, hflags may have changed. */
6076 gen_save_pc(ctx->pc + 4);
6077 ctx->bstate = BS_EXCP;
2423f660
TS
6078 rn = "Status";
6079 break;
9c2149c8 6080 case 1:
d75c135e 6081 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6082 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6083 /* Stop translation as we may have switched the execution mode */
6084 ctx->bstate = BS_STOP;
2423f660
TS
6085 rn = "IntCtl";
6086 break;
9c2149c8 6087 case 2:
d75c135e 6088 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6089 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6090 /* Stop translation as we may have switched the execution mode */
6091 ctx->bstate = BS_STOP;
2423f660
TS
6092 rn = "SRSCtl";
6093 break;
9c2149c8 6094 case 3:
d75c135e 6095 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6096 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6097 /* Stop translation as we may have switched the execution mode */
6098 ctx->bstate = BS_STOP;
2423f660
TS
6099 rn = "SRSMap";
6100 break;
6101 default:
9c2149c8 6102 goto die;
876d4b07 6103 }
9c2149c8
TS
6104 break;
6105 case 13:
6106 switch (sel) {
6107 case 0:
867abc7e 6108 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6109 /* Mark as an IO operation because we may trigger a software
6110 interrupt. */
6111 if (use_icount) {
6112 gen_io_start();
6113 }
895c2d04 6114 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6115 if (use_icount) {
6116 gen_io_end();
6117 }
6118 /* Stop translation as we may have triggered an intetrupt */
6119 ctx->bstate = BS_STOP;
2423f660
TS
6120 rn = "Cause";
6121 break;
9c2149c8
TS
6122 default:
6123 goto die;
876d4b07 6124 }
9c2149c8
TS
6125 break;
6126 case 14:
6127 switch (sel) {
6128 case 0:
7db13fae 6129 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6130 rn = "EPC";
6131 break;
9c2149c8
TS
6132 default:
6133 goto die;
876d4b07 6134 }
9c2149c8
TS
6135 break;
6136 case 15:
6137 switch (sel) {
6138 case 0:
2423f660
TS
6139 /* ignored */
6140 rn = "PRid";
6141 break;
9c2149c8 6142 case 1:
d75c135e 6143 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6144 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6145 rn = "EBase";
6146 break;
9c2149c8
TS
6147 default:
6148 goto die;
876d4b07 6149 }
9c2149c8
TS
6150 break;
6151 case 16:
6152 switch (sel) {
6153 case 0:
895c2d04 6154 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6155 rn = "Config";
2423f660
TS
6156 /* Stop translation as we may have switched the execution mode */
6157 ctx->bstate = BS_STOP;
9c2149c8
TS
6158 break;
6159 case 1:
1fc7bf6e 6160 /* ignored, read only */
9c2149c8
TS
6161 rn = "Config1";
6162 break;
6163 case 2:
895c2d04 6164 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6165 rn = "Config2";
2423f660
TS
6166 /* Stop translation as we may have switched the execution mode */
6167 ctx->bstate = BS_STOP;
9c2149c8
TS
6168 break;
6169 case 3:
2423f660 6170 /* ignored */
9c2149c8
TS
6171 rn = "Config3";
6172 break;
6173 /* 6,7 are implementation dependent */
6174 default:
6175 rn = "Invalid config selector";
6176 goto die;
6177 }
9c2149c8
TS
6178 break;
6179 case 17:
6180 switch (sel) {
6181 case 0:
895c2d04 6182 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6183 rn = "LLAddr";
6184 break;
9c2149c8
TS
6185 default:
6186 goto die;
6187 }
6188 break;
6189 case 18:
6190 switch (sel) {
fd88b6ab 6191 case 0 ... 7:
895c2d04 6192 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6193 rn = "WatchLo";
6194 break;
9c2149c8
TS
6195 default:
6196 goto die;
6197 }
6198 break;
6199 case 19:
6200 switch (sel) {
fd88b6ab 6201 case 0 ... 7:
895c2d04 6202 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6203 rn = "WatchHi";
6204 break;
9c2149c8
TS
6205 default:
6206 goto die;
6207 }
6208 break;
6209 case 20:
6210 switch (sel) {
6211 case 0:
d75c135e 6212 check_insn(ctx, ISA_MIPS3);
895c2d04 6213 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6214 rn = "XContext";
6215 break;
9c2149c8
TS
6216 default:
6217 goto die;
6218 }
6219 break;
6220 case 21:
6221 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6222 switch (sel) {
6223 case 0:
895c2d04 6224 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6225 rn = "Framemask";
6226 break;
9c2149c8
TS
6227 default:
6228 goto die;
6229 }
6230 break;
6231 case 22:
6232 /* ignored */
6233 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6234 break;
9c2149c8
TS
6235 case 23:
6236 switch (sel) {
6237 case 0:
895c2d04 6238 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6239 /* BS_STOP isn't good enough here, hflags may have changed. */
6240 gen_save_pc(ctx->pc + 4);
6241 ctx->bstate = BS_EXCP;
2423f660
TS
6242 rn = "Debug";
6243 break;
9c2149c8 6244 case 1:
895c2d04 6245// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6246 /* Stop translation as we may have switched the execution mode */
6247 ctx->bstate = BS_STOP;
2423f660
TS
6248 rn = "TraceControl";
6249// break;
9c2149c8 6250 case 2:
895c2d04 6251// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6252 /* Stop translation as we may have switched the execution mode */
6253 ctx->bstate = BS_STOP;
2423f660
TS
6254 rn = "TraceControl2";
6255// break;
9c2149c8 6256 case 3:
895c2d04 6257// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6258 /* Stop translation as we may have switched the execution mode */
6259 ctx->bstate = BS_STOP;
2423f660
TS
6260 rn = "UserTraceData";
6261// break;
9c2149c8 6262 case 4:
895c2d04 6263// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6264 /* Stop translation as we may have switched the execution mode */
6265 ctx->bstate = BS_STOP;
2423f660
TS
6266 rn = "TraceBPC";
6267// break;
9c2149c8
TS
6268 default:
6269 goto die;
6270 }
9c2149c8
TS
6271 break;
6272 case 24:
6273 switch (sel) {
6274 case 0:
f1aa6320 6275 /* EJTAG support */
7db13fae 6276 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6277 rn = "DEPC";
6278 break;
9c2149c8
TS
6279 default:
6280 goto die;
6281 }
6282 break;
6283 case 25:
6284 switch (sel) {
6285 case 0:
895c2d04 6286 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6287 rn = "Performance0";
6288 break;
9c2149c8 6289 case 1:
895c2d04 6290// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6291 rn = "Performance1";
6292// break;
9c2149c8 6293 case 2:
895c2d04 6294// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6295 rn = "Performance2";
6296// break;
9c2149c8 6297 case 3:
895c2d04 6298// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6299 rn = "Performance3";
6300// break;
9c2149c8 6301 case 4:
895c2d04 6302// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6303 rn = "Performance4";
6304// break;
9c2149c8 6305 case 5:
895c2d04 6306// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6307 rn = "Performance5";
6308// break;
9c2149c8 6309 case 6:
895c2d04 6310// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6311 rn = "Performance6";
6312// break;
9c2149c8 6313 case 7:
895c2d04 6314// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6315 rn = "Performance7";
6316// break;
9c2149c8
TS
6317 default:
6318 goto die;
6319 }
876d4b07 6320 break;
9c2149c8 6321 case 26:
876d4b07 6322 /* ignored */
9c2149c8 6323 rn = "ECC";
876d4b07 6324 break;
9c2149c8
TS
6325 case 27:
6326 switch (sel) {
6327 case 0 ... 3:
2423f660
TS
6328 /* ignored */
6329 rn = "CacheErr";
6330 break;
9c2149c8
TS
6331 default:
6332 goto die;
6333 }
876d4b07 6334 break;
9c2149c8
TS
6335 case 28:
6336 switch (sel) {
6337 case 0:
6338 case 2:
6339 case 4:
6340 case 6:
895c2d04 6341 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6342 rn = "TagLo";
6343 break;
6344 case 1:
6345 case 3:
6346 case 5:
6347 case 7:
895c2d04 6348 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6349 rn = "DataLo";
6350 break;
6351 default:
6352 goto die;
6353 }
6354 break;
6355 case 29:
6356 switch (sel) {
6357 case 0:
6358 case 2:
6359 case 4:
6360 case 6:
895c2d04 6361 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6362 rn = "TagHi";
6363 break;
6364 case 1:
6365 case 3:
6366 case 5:
6367 case 7:
895c2d04 6368 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6369 rn = "DataHi";
6370 break;
6371 default:
6372 rn = "invalid sel";
6373 goto die;
6374 }
876d4b07 6375 break;
9c2149c8
TS
6376 case 30:
6377 switch (sel) {
6378 case 0:
7db13fae 6379 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6380 rn = "ErrorEPC";
6381 break;
9c2149c8
TS
6382 default:
6383 goto die;
6384 }
6385 break;
6386 case 31:
6387 switch (sel) {
6388 case 0:
f1aa6320 6389 /* EJTAG support */
7db13fae 6390 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6391 rn = "DESAVE";
6392 break;
9c2149c8
TS
6393 default:
6394 goto die;
6395 }
876d4b07
TS
6396 /* Stop translation as we may have switched the execution mode */
6397 ctx->bstate = BS_STOP;
9c2149c8
TS
6398 break;
6399 default:
876d4b07 6400 goto die;
9c2149c8 6401 }
2abf314d 6402 (void)rn; /* avoid a compiler warning */
d12d51d5 6403 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6404 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6405 if (use_icount) {
6406 gen_io_end();
6407 ctx->bstate = BS_STOP;
6408 }
9c2149c8
TS
6409 return;
6410
6411die:
d12d51d5 6412 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6413 generate_exception(ctx, EXCP_RI);
6414}
d26bc211 6415#endif /* TARGET_MIPS64 */
9c2149c8 6416
7db13fae 6417static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6418 int u, int sel, int h)
6419{
6420 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6421 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6422
6423 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6424 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6425 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6426 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6427 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6428 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6429 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6430 else if (u == 0) {
6431 switch (rt) {
5a25ce94
EI
6432 case 1:
6433 switch (sel) {
6434 case 1:
895c2d04 6435 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6436 break;
6437 case 2:
895c2d04 6438 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6439 break;
6440 default:
6441 goto die;
6442 break;
6443 }
6444 break;
ead9360e
TS
6445 case 2:
6446 switch (sel) {
6447 case 1:
895c2d04 6448 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6449 break;
6450 case 2:
895c2d04 6451 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6452 break;
6453 case 3:
895c2d04 6454 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6455 break;
6456 case 4:
895c2d04 6457 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6458 break;
6459 case 5:
895c2d04 6460 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6461 break;
6462 case 6:
895c2d04 6463 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6464 break;
6465 case 7:
895c2d04 6466 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6467 break;
6468 default:
d75c135e 6469 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6470 break;
6471 }
6472 break;
6473 case 10:
6474 switch (sel) {
6475 case 0:
895c2d04 6476 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6477 break;
6478 default:
d75c135e 6479 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6480 break;
6481 }
6482 case 12:
6483 switch (sel) {
6484 case 0:
895c2d04 6485 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6486 break;
6487 default:
d75c135e 6488 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6489 break;
6490 }
5a25ce94
EI
6491 case 13:
6492 switch (sel) {
6493 case 0:
895c2d04 6494 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6495 break;
6496 default:
6497 goto die;
6498 break;
6499 }
6500 break;
6501 case 14:
6502 switch (sel) {
6503 case 0:
895c2d04 6504 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6505 break;
6506 default:
6507 goto die;
6508 break;
6509 }
6510 break;
6511 case 15:
6512 switch (sel) {
6513 case 1:
895c2d04 6514 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6515 break;
6516 default:
6517 goto die;
6518 break;
6519 }
6520 break;
6521 case 16:
6522 switch (sel) {
6523 case 0 ... 7:
895c2d04 6524 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6525 break;
6526 default:
6527 goto die;
6528 break;
6529 }
6530 break;
ead9360e
TS
6531 case 23:
6532 switch (sel) {
6533 case 0:
895c2d04 6534 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6535 break;
6536 default:
d75c135e 6537 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6538 break;
6539 }
6540 break;
6541 default:
d75c135e 6542 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6543 }
6544 } else switch (sel) {
6545 /* GPR registers. */
6546 case 0:
895c2d04 6547 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6548 break;
6549 /* Auxiliary CPU registers */
6550 case 1:
6551 switch (rt) {
6552 case 0:
895c2d04 6553 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6554 break;
6555 case 1:
895c2d04 6556 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6557 break;
6558 case 2:
895c2d04 6559 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6560 break;
6561 case 4:
895c2d04 6562 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6563 break;
6564 case 5:
895c2d04 6565 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6566 break;
6567 case 6:
895c2d04 6568 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6569 break;
6570 case 8:
895c2d04 6571 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6572 break;
6573 case 9:
895c2d04 6574 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6575 break;
6576 case 10:
895c2d04 6577 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6578 break;
6579 case 12:
895c2d04 6580 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6581 break;
6582 case 13:
895c2d04 6583 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6584 break;
6585 case 14:
895c2d04 6586 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6587 break;
6588 case 16:
895c2d04 6589 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6590 break;
6591 default:
6592 goto die;
6593 }
6594 break;
6595 /* Floating point (COP1). */
6596 case 2:
6597 /* XXX: For now we support only a single FPU context. */
6598 if (h == 0) {
a7812ae4 6599 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6600
6601 gen_load_fpr32(fp0, rt);
6602 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6603 tcg_temp_free_i32(fp0);
ead9360e 6604 } else {
a7812ae4 6605 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6606
6607 gen_load_fpr32h(fp0, rt);
6608 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6609 tcg_temp_free_i32(fp0);
ead9360e
TS
6610 }
6611 break;
6612 case 3:
6613 /* XXX: For now we support only a single FPU context. */
895c2d04 6614 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6615 break;
6616 /* COP2: Not implemented. */
6617 case 4:
6618 case 5:
6619 /* fall through */
6620 default:
6621 goto die;
6622 }
d12d51d5 6623 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6624 gen_store_gpr(t0, rd);
6625 tcg_temp_free(t0);
ead9360e
TS
6626 return;
6627
6628die:
1a3fd9c3 6629 tcg_temp_free(t0);
d12d51d5 6630 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6631 generate_exception(ctx, EXCP_RI);
6632}
6633
7db13fae 6634static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6635 int u, int sel, int h)
6636{
6637 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6638 TCGv t0 = tcg_temp_local_new();
ead9360e 6639
1a3fd9c3 6640 gen_load_gpr(t0, rt);
ead9360e 6641 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6642 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6643 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6644 /* NOP */ ;
6645 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6646 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6647 /* NOP */ ;
6648 else if (u == 0) {
6649 switch (rd) {
5a25ce94
EI
6650 case 1:
6651 switch (sel) {
6652 case 1:
895c2d04 6653 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6654 break;
6655 case 2:
895c2d04 6656 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6657 break;
6658 default:
6659 goto die;
6660 break;
6661 }
6662 break;
ead9360e
TS
6663 case 2:
6664 switch (sel) {
6665 case 1:
895c2d04 6666 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6667 break;
6668 case 2:
895c2d04 6669 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6670 break;
6671 case 3:
895c2d04 6672 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6673 break;
6674 case 4:
895c2d04 6675 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6676 break;
6677 case 5:
895c2d04 6678 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6679 break;
6680 case 6:
895c2d04 6681 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6682 break;
6683 case 7:
895c2d04 6684 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6685 break;
6686 default:
d75c135e 6687 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6688 break;
6689 }
6690 break;
6691 case 10:
6692 switch (sel) {
6693 case 0:
895c2d04 6694 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6695 break;
6696 default:
d75c135e 6697 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6698 break;
6699 }
6700 case 12:
6701 switch (sel) {
6702 case 0:
895c2d04 6703 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6704 break;
6705 default:
d75c135e 6706 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6707 break;
6708 }
5a25ce94
EI
6709 case 13:
6710 switch (sel) {
6711 case 0:
895c2d04 6712 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6713 break;
6714 default:
6715 goto die;
6716 break;
6717 }
6718 break;
6719 case 15:
6720 switch (sel) {
6721 case 1:
895c2d04 6722 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6723 break;
6724 default:
6725 goto die;
6726 break;
6727 }
6728 break;
ead9360e
TS
6729 case 23:
6730 switch (sel) {
6731 case 0:
895c2d04 6732 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6733 break;
6734 default:
d75c135e 6735 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6736 break;
6737 }
6738 break;
6739 default:
d75c135e 6740 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6741 }
6742 } else switch (sel) {
6743 /* GPR registers. */
6744 case 0:
895c2d04 6745 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6746 break;
6747 /* Auxiliary CPU registers */
6748 case 1:
6749 switch (rd) {
6750 case 0:
895c2d04 6751 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6752 break;
6753 case 1:
895c2d04 6754 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6755 break;
6756 case 2:
895c2d04 6757 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6758 break;
6759 case 4:
895c2d04 6760 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6761 break;
6762 case 5:
895c2d04 6763 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6764 break;
6765 case 6:
895c2d04 6766 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6767 break;
6768 case 8:
895c2d04 6769 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6770 break;
6771 case 9:
895c2d04 6772 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6773 break;
6774 case 10:
895c2d04 6775 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6776 break;
6777 case 12:
895c2d04 6778 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6779 break;
6780 case 13:
895c2d04 6781 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6782 break;
6783 case 14:
895c2d04 6784 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6785 break;
6786 case 16:
895c2d04 6787 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6788 break;
6789 default:
6790 goto die;
6791 }
6792 break;
6793 /* Floating point (COP1). */
6794 case 2:
6795 /* XXX: For now we support only a single FPU context. */
6796 if (h == 0) {
a7812ae4 6797 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6798
6799 tcg_gen_trunc_tl_i32(fp0, t0);
6800 gen_store_fpr32(fp0, rd);
a7812ae4 6801 tcg_temp_free_i32(fp0);
ead9360e 6802 } else {
a7812ae4 6803 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6804
6805 tcg_gen_trunc_tl_i32(fp0, t0);
6806 gen_store_fpr32h(fp0, rd);
a7812ae4 6807 tcg_temp_free_i32(fp0);
ead9360e
TS
6808 }
6809 break;
6810 case 3:
6811 /* XXX: For now we support only a single FPU context. */
895c2d04 6812 gen_helper_0e1i(ctc1, t0, rd);
ead9360e
TS
6813 break;
6814 /* COP2: Not implemented. */
6815 case 4:
6816 case 5:
6817 /* fall through */
6818 default:
6819 goto die;
6820 }
d12d51d5 6821 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6822 tcg_temp_free(t0);
ead9360e
TS
6823 return;
6824
6825die:
1a3fd9c3 6826 tcg_temp_free(t0);
d12d51d5 6827 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6828 generate_exception(ctx, EXCP_RI);
6829}
6830
7db13fae 6831static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6832{
287c4b84 6833 const char *opn = "ldst";
6af0bf9c 6834
2e15497c 6835 check_cp0_enabled(ctx);
6af0bf9c
FB
6836 switch (opc) {
6837 case OPC_MFC0:
6838 if (rt == 0) {
ead9360e 6839 /* Treat as NOP. */
6af0bf9c
FB
6840 return;
6841 }
d75c135e 6842 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6843 opn = "mfc0";
6844 break;
6845 case OPC_MTC0:
1a3fd9c3 6846 {
1fc7bf6e 6847 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6848
6849 gen_load_gpr(t0, rt);
d75c135e 6850 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6851 tcg_temp_free(t0);
6852 }
6af0bf9c
FB
6853 opn = "mtc0";
6854 break;
d26bc211 6855#if defined(TARGET_MIPS64)
9c2149c8 6856 case OPC_DMFC0:
d75c135e 6857 check_insn(ctx, ISA_MIPS3);
9c2149c8 6858 if (rt == 0) {
ead9360e 6859 /* Treat as NOP. */
9c2149c8
TS
6860 return;
6861 }
d75c135e 6862 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6863 opn = "dmfc0";
6864 break;
6865 case OPC_DMTC0:
d75c135e 6866 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 6867 {
1fc7bf6e 6868 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6869
6870 gen_load_gpr(t0, rt);
d75c135e 6871 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6872 tcg_temp_free(t0);
6873 }
9c2149c8
TS
6874 opn = "dmtc0";
6875 break;
534ce69f 6876#endif
ead9360e 6877 case OPC_MFTR:
d75c135e 6878 check_insn(ctx, ASE_MT);
ead9360e
TS
6879 if (rd == 0) {
6880 /* Treat as NOP. */
6881 return;
6882 }
6c5c1e20 6883 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6884 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6885 opn = "mftr";
6886 break;
6887 case OPC_MTTR:
d75c135e 6888 check_insn(ctx, ASE_MT);
6c5c1e20 6889 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6890 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6891 opn = "mttr";
6892 break;
6af0bf9c 6893 case OPC_TLBWI:
6af0bf9c 6894 opn = "tlbwi";
c01fccd2 6895 if (!env->tlb->helper_tlbwi)
29929e34 6896 goto die;
895c2d04 6897 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6898 break;
6899 case OPC_TLBWR:
6af0bf9c 6900 opn = "tlbwr";
c01fccd2 6901 if (!env->tlb->helper_tlbwr)
29929e34 6902 goto die;
895c2d04 6903 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6904 break;
6905 case OPC_TLBP:
6af0bf9c 6906 opn = "tlbp";
c01fccd2 6907 if (!env->tlb->helper_tlbp)
29929e34 6908 goto die;
895c2d04 6909 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6910 break;
6911 case OPC_TLBR:
6af0bf9c 6912 opn = "tlbr";
c01fccd2 6913 if (!env->tlb->helper_tlbr)
29929e34 6914 goto die;
895c2d04 6915 gen_helper_tlbr(cpu_env);
6af0bf9c 6916 break;
6af0bf9c
FB
6917 case OPC_ERET:
6918 opn = "eret";
d75c135e 6919 check_insn(ctx, ISA_MIPS2);
895c2d04 6920 gen_helper_eret(cpu_env);
6af0bf9c
FB
6921 ctx->bstate = BS_EXCP;
6922 break;
6923 case OPC_DERET:
6924 opn = "deret";
d75c135e 6925 check_insn(ctx, ISA_MIPS32);
6af0bf9c 6926 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6927 MIPS_INVAL(opn);
6af0bf9c
FB
6928 generate_exception(ctx, EXCP_RI);
6929 } else {
895c2d04 6930 gen_helper_deret(cpu_env);
6af0bf9c
FB
6931 ctx->bstate = BS_EXCP;
6932 }
6933 break;
4ad40f36
FB
6934 case OPC_WAIT:
6935 opn = "wait";
d75c135e 6936 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6937 /* If we get an exception, we want to restart at next instruction */
6938 ctx->pc += 4;
6939 save_cpu_state(ctx, 1);
6940 ctx->pc -= 4;
895c2d04 6941 gen_helper_wait(cpu_env);
4ad40f36
FB
6942 ctx->bstate = BS_EXCP;
6943 break;
6af0bf9c 6944 default:
29929e34 6945 die:
923617a3 6946 MIPS_INVAL(opn);
6af0bf9c
FB
6947 generate_exception(ctx, EXCP_RI);
6948 return;
6949 }
2abf314d 6950 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
6951 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6952}
f1aa6320 6953#endif /* !CONFIG_USER_ONLY */
6af0bf9c 6954
6ea83fed 6955/* CP1 Branches (before delay slot) */
d75c135e
AJ
6956static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6957 int32_t cc, int32_t offset)
6ea83fed
FB
6958{
6959 target_ulong btarget;
923617a3 6960 const char *opn = "cp1 cond branch";
a7812ae4 6961 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 6962
e189e748 6963 if (cc != 0)
d75c135e 6964 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 6965
6ea83fed
FB
6966 btarget = ctx->pc + 4 + offset;
6967
7a387fff
TS
6968 switch (op) {
6969 case OPC_BC1F:
d94536f4
AJ
6970 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6971 tcg_gen_not_i32(t0, t0);
6972 tcg_gen_andi_i32(t0, t0, 1);
6973 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 6974 opn = "bc1f";
6ea83fed 6975 goto not_likely;
7a387fff 6976 case OPC_BC1FL:
d94536f4
AJ
6977 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6978 tcg_gen_not_i32(t0, t0);
6979 tcg_gen_andi_i32(t0, t0, 1);
6980 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 6981 opn = "bc1fl";
6ea83fed 6982 goto likely;
7a387fff 6983 case OPC_BC1T:
d94536f4
AJ
6984 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6985 tcg_gen_andi_i32(t0, t0, 1);
6986 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 6987 opn = "bc1t";
5a5012ec 6988 goto not_likely;
7a387fff 6989 case OPC_BC1TL:
d94536f4
AJ
6990 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6991 tcg_gen_andi_i32(t0, t0, 1);
6992 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 6993 opn = "bc1tl";
6ea83fed
FB
6994 likely:
6995 ctx->hflags |= MIPS_HFLAG_BL;
6996 break;
5a5012ec 6997 case OPC_BC1FANY2:
a16336e4 6998 {
d94536f4
AJ
6999 TCGv_i32 t1 = tcg_temp_new_i32();
7000 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7001 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7002 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7003 tcg_temp_free_i32(t1);
d94536f4
AJ
7004 tcg_gen_andi_i32(t0, t0, 1);
7005 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7006 }
fd4a04eb 7007 opn = "bc1any2f";
5a5012ec
TS
7008 goto not_likely;
7009 case OPC_BC1TANY2:
a16336e4 7010 {
d94536f4
AJ
7011 TCGv_i32 t1 = tcg_temp_new_i32();
7012 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7013 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7014 tcg_gen_or_i32(t0, t0, t1);
7015 tcg_temp_free_i32(t1);
7016 tcg_gen_andi_i32(t0, t0, 1);
7017 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7018 }
fd4a04eb 7019 opn = "bc1any2t";
5a5012ec
TS
7020 goto not_likely;
7021 case OPC_BC1FANY4:
a16336e4 7022 {
d94536f4
AJ
7023 TCGv_i32 t1 = tcg_temp_new_i32();
7024 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7025 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7026 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7027 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7028 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7029 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7030 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7031 tcg_temp_free_i32(t1);
d94536f4
AJ
7032 tcg_gen_andi_i32(t0, t0, 1);
7033 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7034 }
fd4a04eb 7035 opn = "bc1any4f";
5a5012ec
TS
7036 goto not_likely;
7037 case OPC_BC1TANY4:
a16336e4 7038 {
d94536f4
AJ
7039 TCGv_i32 t1 = tcg_temp_new_i32();
7040 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7041 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7042 tcg_gen_or_i32(t0, t0, t1);
7043 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7044 tcg_gen_or_i32(t0, t0, t1);
7045 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7046 tcg_gen_or_i32(t0, t0, t1);
7047 tcg_temp_free_i32(t1);
7048 tcg_gen_andi_i32(t0, t0, 1);
7049 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7050 }
fd4a04eb 7051 opn = "bc1any4t";
5a5012ec
TS
7052 not_likely:
7053 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7054 break;
7055 default:
923617a3 7056 MIPS_INVAL(opn);
e397ee33 7057 generate_exception (ctx, EXCP_RI);
6c5c1e20 7058 goto out;
6ea83fed 7059 }
2abf314d 7060 (void)opn; /* avoid a compiler warning */
923617a3 7061 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7062 ctx->hflags, btarget);
7063 ctx->btarget = btarget;
6c5c1e20
TS
7064
7065 out:
a7812ae4 7066 tcg_temp_free_i32(t0);
6ea83fed
FB
7067}
7068
6af0bf9c 7069/* Coprocessor 1 (FPU) */
5a5012ec 7070
5a5012ec
TS
7071#define FOP(func, fmt) (((fmt) << 21) | (func))
7072
bf4120ad
NF
7073enum fopcode {
7074 OPC_ADD_S = FOP(0, FMT_S),
7075 OPC_SUB_S = FOP(1, FMT_S),
7076 OPC_MUL_S = FOP(2, FMT_S),
7077 OPC_DIV_S = FOP(3, FMT_S),
7078 OPC_SQRT_S = FOP(4, FMT_S),
7079 OPC_ABS_S = FOP(5, FMT_S),
7080 OPC_MOV_S = FOP(6, FMT_S),
7081 OPC_NEG_S = FOP(7, FMT_S),
7082 OPC_ROUND_L_S = FOP(8, FMT_S),
7083 OPC_TRUNC_L_S = FOP(9, FMT_S),
7084 OPC_CEIL_L_S = FOP(10, FMT_S),
7085 OPC_FLOOR_L_S = FOP(11, FMT_S),
7086 OPC_ROUND_W_S = FOP(12, FMT_S),
7087 OPC_TRUNC_W_S = FOP(13, FMT_S),
7088 OPC_CEIL_W_S = FOP(14, FMT_S),
7089 OPC_FLOOR_W_S = FOP(15, FMT_S),
7090 OPC_MOVCF_S = FOP(17, FMT_S),
7091 OPC_MOVZ_S = FOP(18, FMT_S),
7092 OPC_MOVN_S = FOP(19, FMT_S),
7093 OPC_RECIP_S = FOP(21, FMT_S),
7094 OPC_RSQRT_S = FOP(22, FMT_S),
7095 OPC_RECIP2_S = FOP(28, FMT_S),
7096 OPC_RECIP1_S = FOP(29, FMT_S),
7097 OPC_RSQRT1_S = FOP(30, FMT_S),
7098 OPC_RSQRT2_S = FOP(31, FMT_S),
7099 OPC_CVT_D_S = FOP(33, FMT_S),
7100 OPC_CVT_W_S = FOP(36, FMT_S),
7101 OPC_CVT_L_S = FOP(37, FMT_S),
7102 OPC_CVT_PS_S = FOP(38, FMT_S),
7103 OPC_CMP_F_S = FOP (48, FMT_S),
7104 OPC_CMP_UN_S = FOP (49, FMT_S),
7105 OPC_CMP_EQ_S = FOP (50, FMT_S),
7106 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7107 OPC_CMP_OLT_S = FOP (52, FMT_S),
7108 OPC_CMP_ULT_S = FOP (53, FMT_S),
7109 OPC_CMP_OLE_S = FOP (54, FMT_S),
7110 OPC_CMP_ULE_S = FOP (55, FMT_S),
7111 OPC_CMP_SF_S = FOP (56, FMT_S),
7112 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7113 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7114 OPC_CMP_NGL_S = FOP (59, FMT_S),
7115 OPC_CMP_LT_S = FOP (60, FMT_S),
7116 OPC_CMP_NGE_S = FOP (61, FMT_S),
7117 OPC_CMP_LE_S = FOP (62, FMT_S),
7118 OPC_CMP_NGT_S = FOP (63, FMT_S),
7119
7120 OPC_ADD_D = FOP(0, FMT_D),
7121 OPC_SUB_D = FOP(1, FMT_D),
7122 OPC_MUL_D = FOP(2, FMT_D),
7123 OPC_DIV_D = FOP(3, FMT_D),
7124 OPC_SQRT_D = FOP(4, FMT_D),
7125 OPC_ABS_D = FOP(5, FMT_D),
7126 OPC_MOV_D = FOP(6, FMT_D),
7127 OPC_NEG_D = FOP(7, FMT_D),
7128 OPC_ROUND_L_D = FOP(8, FMT_D),
7129 OPC_TRUNC_L_D = FOP(9, FMT_D),
7130 OPC_CEIL_L_D = FOP(10, FMT_D),
7131 OPC_FLOOR_L_D = FOP(11, FMT_D),
7132 OPC_ROUND_W_D = FOP(12, FMT_D),
7133 OPC_TRUNC_W_D = FOP(13, FMT_D),
7134 OPC_CEIL_W_D = FOP(14, FMT_D),
7135 OPC_FLOOR_W_D = FOP(15, FMT_D),
7136 OPC_MOVCF_D = FOP(17, FMT_D),
7137 OPC_MOVZ_D = FOP(18, FMT_D),
7138 OPC_MOVN_D = FOP(19, FMT_D),
7139 OPC_RECIP_D = FOP(21, FMT_D),
7140 OPC_RSQRT_D = FOP(22, FMT_D),
7141 OPC_RECIP2_D = FOP(28, FMT_D),
7142 OPC_RECIP1_D = FOP(29, FMT_D),
7143 OPC_RSQRT1_D = FOP(30, FMT_D),
7144 OPC_RSQRT2_D = FOP(31, FMT_D),
7145 OPC_CVT_S_D = FOP(32, FMT_D),
7146 OPC_CVT_W_D = FOP(36, FMT_D),
7147 OPC_CVT_L_D = FOP(37, FMT_D),
7148 OPC_CMP_F_D = FOP (48, FMT_D),
7149 OPC_CMP_UN_D = FOP (49, FMT_D),
7150 OPC_CMP_EQ_D = FOP (50, FMT_D),
7151 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7152 OPC_CMP_OLT_D = FOP (52, FMT_D),
7153 OPC_CMP_ULT_D = FOP (53, FMT_D),
7154 OPC_CMP_OLE_D = FOP (54, FMT_D),
7155 OPC_CMP_ULE_D = FOP (55, FMT_D),
7156 OPC_CMP_SF_D = FOP (56, FMT_D),
7157 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7158 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7159 OPC_CMP_NGL_D = FOP (59, FMT_D),
7160 OPC_CMP_LT_D = FOP (60, FMT_D),
7161 OPC_CMP_NGE_D = FOP (61, FMT_D),
7162 OPC_CMP_LE_D = FOP (62, FMT_D),
7163 OPC_CMP_NGT_D = FOP (63, FMT_D),
7164
7165 OPC_CVT_S_W = FOP(32, FMT_W),
7166 OPC_CVT_D_W = FOP(33, FMT_W),
7167 OPC_CVT_S_L = FOP(32, FMT_L),
7168 OPC_CVT_D_L = FOP(33, FMT_L),
7169 OPC_CVT_PS_PW = FOP(38, FMT_W),
7170
7171 OPC_ADD_PS = FOP(0, FMT_PS),
7172 OPC_SUB_PS = FOP(1, FMT_PS),
7173 OPC_MUL_PS = FOP(2, FMT_PS),
7174 OPC_DIV_PS = FOP(3, FMT_PS),
7175 OPC_ABS_PS = FOP(5, FMT_PS),
7176 OPC_MOV_PS = FOP(6, FMT_PS),
7177 OPC_NEG_PS = FOP(7, FMT_PS),
7178 OPC_MOVCF_PS = FOP(17, FMT_PS),
7179 OPC_MOVZ_PS = FOP(18, FMT_PS),
7180 OPC_MOVN_PS = FOP(19, FMT_PS),
7181 OPC_ADDR_PS = FOP(24, FMT_PS),
7182 OPC_MULR_PS = FOP(26, FMT_PS),
7183 OPC_RECIP2_PS = FOP(28, FMT_PS),
7184 OPC_RECIP1_PS = FOP(29, FMT_PS),
7185 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7186 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7187
7188 OPC_CVT_S_PU = FOP(32, FMT_PS),
7189 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7190 OPC_CVT_S_PL = FOP(40, FMT_PS),
7191 OPC_PLL_PS = FOP(44, FMT_PS),
7192 OPC_PLU_PS = FOP(45, FMT_PS),
7193 OPC_PUL_PS = FOP(46, FMT_PS),
7194 OPC_PUU_PS = FOP(47, FMT_PS),
7195 OPC_CMP_F_PS = FOP (48, FMT_PS),
7196 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7197 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7198 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7199 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7200 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7201 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7202 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7203 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7204 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7205 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7206 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7207 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7208 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7209 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7210 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7211};
7212
7a387fff 7213static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7214{
923617a3 7215 const char *opn = "cp1 move";
72c3a3ee 7216 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7217
7218 switch (opc) {
7219 case OPC_MFC1:
b6d96bed 7220 {
a7812ae4 7221 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7222
7223 gen_load_fpr32(fp0, fs);
7224 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7225 tcg_temp_free_i32(fp0);
6958549d 7226 }
6c5c1e20 7227 gen_store_gpr(t0, rt);
6ea83fed
FB
7228 opn = "mfc1";
7229 break;
7230 case OPC_MTC1:
6c5c1e20 7231 gen_load_gpr(t0, rt);
b6d96bed 7232 {
a7812ae4 7233 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7234
7235 tcg_gen_trunc_tl_i32(fp0, t0);
7236 gen_store_fpr32(fp0, fs);
a7812ae4 7237 tcg_temp_free_i32(fp0);
6958549d 7238 }
6ea83fed
FB
7239 opn = "mtc1";
7240 break;
7241 case OPC_CFC1:
895c2d04 7242 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7243 gen_store_gpr(t0, rt);
6ea83fed
FB
7244 opn = "cfc1";
7245 break;
7246 case OPC_CTC1:
6c5c1e20 7247 gen_load_gpr(t0, rt);
895c2d04 7248 gen_helper_0e1i(ctc1, t0, fs);
6ea83fed
FB
7249 opn = "ctc1";
7250 break;
72c3a3ee 7251#if defined(TARGET_MIPS64)
9c2149c8 7252 case OPC_DMFC1:
72c3a3ee 7253 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7254 gen_store_gpr(t0, rt);
5a5012ec
TS
7255 opn = "dmfc1";
7256 break;
9c2149c8 7257 case OPC_DMTC1:
6c5c1e20 7258 gen_load_gpr(t0, rt);
72c3a3ee 7259 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7260 opn = "dmtc1";
7261 break;
72c3a3ee 7262#endif
5a5012ec 7263 case OPC_MFHC1:
b6d96bed 7264 {
a7812ae4 7265 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7266
7267 gen_load_fpr32h(fp0, fs);
7268 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7269 tcg_temp_free_i32(fp0);
6958549d 7270 }
6c5c1e20 7271 gen_store_gpr(t0, rt);
5a5012ec
TS
7272 opn = "mfhc1";
7273 break;
7274 case OPC_MTHC1:
6c5c1e20 7275 gen_load_gpr(t0, rt);
b6d96bed 7276 {
a7812ae4 7277 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7278
7279 tcg_gen_trunc_tl_i32(fp0, t0);
7280 gen_store_fpr32h(fp0, fs);
a7812ae4 7281 tcg_temp_free_i32(fp0);
6958549d 7282 }
5a5012ec
TS
7283 opn = "mthc1";
7284 break;
6ea83fed 7285 default:
923617a3 7286 MIPS_INVAL(opn);
e397ee33 7287 generate_exception (ctx, EXCP_RI);
6c5c1e20 7288 goto out;
6ea83fed 7289 }
2abf314d 7290 (void)opn; /* avoid a compiler warning */
6ea83fed 7291 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7292
7293 out:
7294 tcg_temp_free(t0);
6ea83fed
FB
7295}
7296
5a5012ec
TS
7297static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7298{
af58f9ca 7299 int l1;
e214b9bb 7300 TCGCond cond;
af58f9ca
AJ
7301 TCGv_i32 t0;
7302
7303 if (rd == 0) {
7304 /* Treat as NOP. */
7305 return;
7306 }
6ea83fed 7307
e214b9bb 7308 if (tf)
e214b9bb 7309 cond = TCG_COND_EQ;
27848470
TS
7310 else
7311 cond = TCG_COND_NE;
7312
af58f9ca
AJ
7313 l1 = gen_new_label();
7314 t0 = tcg_temp_new_i32();
fa31af0e 7315 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7316 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7317 tcg_temp_free_i32(t0);
af58f9ca
AJ
7318 if (rs == 0) {
7319 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7320 } else {
7321 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7322 }
e214b9bb 7323 gen_set_label(l1);
5a5012ec
TS
7324}
7325
b6d96bed 7326static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7327{
a16336e4 7328 int cond;
cbc37b28 7329 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7330 int l1 = gen_new_label();
7331
a16336e4
TS
7332 if (tf)
7333 cond = TCG_COND_EQ;
7334 else
7335 cond = TCG_COND_NE;
7336
fa31af0e 7337 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7338 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7339 gen_load_fpr32(t0, fs);
7340 gen_store_fpr32(t0, fd);
a16336e4 7341 gen_set_label(l1);
cbc37b28 7342 tcg_temp_free_i32(t0);
5a5012ec 7343}
a16336e4 7344
b6d96bed 7345static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7346{
a16336e4 7347 int cond;
cbc37b28
AJ
7348 TCGv_i32 t0 = tcg_temp_new_i32();
7349 TCGv_i64 fp0;
a16336e4
TS
7350 int l1 = gen_new_label();
7351
a16336e4
TS
7352 if (tf)
7353 cond = TCG_COND_EQ;
7354 else
7355 cond = TCG_COND_NE;
7356
fa31af0e 7357 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7358 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7359 tcg_temp_free_i32(t0);
11f94258 7360 fp0 = tcg_temp_new_i64();
9bf3eb2c 7361 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7362 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7363 tcg_temp_free_i64(fp0);
cbc37b28 7364 gen_set_label(l1);
a16336e4
TS
7365}
7366
b6d96bed 7367static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
a16336e4
TS
7368{
7369 int cond;
cbc37b28 7370 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7371 int l1 = gen_new_label();
7372 int l2 = gen_new_label();
7373
7374 if (tf)
7375 cond = TCG_COND_EQ;
7376 else
7377 cond = TCG_COND_NE;
7378
fa31af0e 7379 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7380 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7381 gen_load_fpr32(t0, fs);
7382 gen_store_fpr32(t0, fd);
a16336e4 7383 gen_set_label(l1);
9bf3eb2c 7384
fa31af0e 7385 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28
AJ
7386 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7387 gen_load_fpr32h(t0, fs);
7388 gen_store_fpr32h(t0, fd);
52a0e9eb 7389 tcg_temp_free_i32(t0);
a16336e4 7390 gen_set_label(l2);
a16336e4
TS
7391}
7392
6ea83fed 7393
bf4120ad 7394static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7395 int ft, int fs, int fd, int cc)
6ea83fed 7396{
923617a3 7397 const char *opn = "farith";
6ea83fed
FB
7398 const char *condnames[] = {
7399 "c.f",
7400 "c.un",
7401 "c.eq",
7402 "c.ueq",
7403 "c.olt",
7404 "c.ult",
7405 "c.ole",
7406 "c.ule",
7407 "c.sf",
7408 "c.ngle",
7409 "c.seq",
7410 "c.ngl",
7411 "c.lt",
7412 "c.nge",
7413 "c.le",
7414 "c.ngt",
7415 };
5a1e8ffb
TS
7416 const char *condnames_abs[] = {
7417 "cabs.f",
7418 "cabs.un",
7419 "cabs.eq",
7420 "cabs.ueq",
7421 "cabs.olt",
7422 "cabs.ult",
7423 "cabs.ole",
7424 "cabs.ule",
7425 "cabs.sf",
7426 "cabs.ngle",
7427 "cabs.seq",
7428 "cabs.ngl",
7429 "cabs.lt",
7430 "cabs.nge",
7431 "cabs.le",
7432 "cabs.ngt",
7433 };
7434 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7435 uint32_t func = ctx->opcode & 0x3f;
7436
bf4120ad
NF
7437 switch (op1) {
7438 case OPC_ADD_S:
b6d96bed 7439 {
a7812ae4
PB
7440 TCGv_i32 fp0 = tcg_temp_new_i32();
7441 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7442
7443 gen_load_fpr32(fp0, fs);
7444 gen_load_fpr32(fp1, ft);
895c2d04 7445 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7446 tcg_temp_free_i32(fp1);
b6d96bed 7447 gen_store_fpr32(fp0, fd);
a7812ae4 7448 tcg_temp_free_i32(fp0);
b6d96bed 7449 }
5a5012ec 7450 opn = "add.s";
5a1e8ffb 7451 optype = BINOP;
5a5012ec 7452 break;
bf4120ad 7453 case OPC_SUB_S:
b6d96bed 7454 {
a7812ae4
PB
7455 TCGv_i32 fp0 = tcg_temp_new_i32();
7456 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7457
7458 gen_load_fpr32(fp0, fs);
7459 gen_load_fpr32(fp1, ft);
895c2d04 7460 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7461 tcg_temp_free_i32(fp1);
b6d96bed 7462 gen_store_fpr32(fp0, fd);
a7812ae4 7463 tcg_temp_free_i32(fp0);
b6d96bed 7464 }
5a5012ec 7465 opn = "sub.s";
5a1e8ffb 7466 optype = BINOP;
5a5012ec 7467 break;
bf4120ad 7468 case OPC_MUL_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_mul_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 = "mul.s";
5a1e8ffb 7481 optype = BINOP;
5a5012ec 7482 break;
bf4120ad 7483 case OPC_DIV_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_div_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 = "div.s";
5a1e8ffb 7496 optype = BINOP;
5a5012ec 7497 break;
bf4120ad 7498 case OPC_SQRT_S:
b6d96bed 7499 {
a7812ae4 7500 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7501
7502 gen_load_fpr32(fp0, fs);
895c2d04 7503 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7504 gen_store_fpr32(fp0, fd);
a7812ae4 7505 tcg_temp_free_i32(fp0);
b6d96bed 7506 }
5a5012ec
TS
7507 opn = "sqrt.s";
7508 break;
bf4120ad 7509 case OPC_ABS_S:
b6d96bed 7510 {
a7812ae4 7511 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7512
7513 gen_load_fpr32(fp0, fs);
a7812ae4 7514 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7515 gen_store_fpr32(fp0, fd);
a7812ae4 7516 tcg_temp_free_i32(fp0);
b6d96bed 7517 }
5a5012ec
TS
7518 opn = "abs.s";
7519 break;
bf4120ad 7520 case OPC_MOV_S:
b6d96bed 7521 {
a7812ae4 7522 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7523
7524 gen_load_fpr32(fp0, fs);
7525 gen_store_fpr32(fp0, fd);
a7812ae4 7526 tcg_temp_free_i32(fp0);
b6d96bed 7527 }
5a5012ec
TS
7528 opn = "mov.s";
7529 break;
bf4120ad 7530 case OPC_NEG_S:
b6d96bed 7531 {
a7812ae4 7532 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7533
7534 gen_load_fpr32(fp0, fs);
a7812ae4 7535 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7536 gen_store_fpr32(fp0, fd);
a7812ae4 7537 tcg_temp_free_i32(fp0);
b6d96bed 7538 }
5a5012ec
TS
7539 opn = "neg.s";
7540 break;
bf4120ad 7541 case OPC_ROUND_L_S:
5e755519 7542 check_cp1_64bitmode(ctx);
b6d96bed 7543 {
a7812ae4
PB
7544 TCGv_i32 fp32 = tcg_temp_new_i32();
7545 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7546
7547 gen_load_fpr32(fp32, fs);
895c2d04 7548 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7549 tcg_temp_free_i32(fp32);
b6d96bed 7550 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7551 tcg_temp_free_i64(fp64);
b6d96bed 7552 }
5a5012ec
TS
7553 opn = "round.l.s";
7554 break;
bf4120ad 7555 case OPC_TRUNC_L_S:
5e755519 7556 check_cp1_64bitmode(ctx);
b6d96bed 7557 {
a7812ae4
PB
7558 TCGv_i32 fp32 = tcg_temp_new_i32();
7559 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7560
7561 gen_load_fpr32(fp32, fs);
895c2d04 7562 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7563 tcg_temp_free_i32(fp32);
b6d96bed 7564 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7565 tcg_temp_free_i64(fp64);
b6d96bed 7566 }
5a5012ec
TS
7567 opn = "trunc.l.s";
7568 break;
bf4120ad 7569 case OPC_CEIL_L_S:
5e755519 7570 check_cp1_64bitmode(ctx);
b6d96bed 7571 {
a7812ae4
PB
7572 TCGv_i32 fp32 = tcg_temp_new_i32();
7573 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7574
7575 gen_load_fpr32(fp32, fs);
895c2d04 7576 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7577 tcg_temp_free_i32(fp32);
b6d96bed 7578 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7579 tcg_temp_free_i64(fp64);
b6d96bed 7580 }
5a5012ec
TS
7581 opn = "ceil.l.s";
7582 break;
bf4120ad 7583 case OPC_FLOOR_L_S:
5e755519 7584 check_cp1_64bitmode(ctx);
b6d96bed 7585 {
a7812ae4
PB
7586 TCGv_i32 fp32 = tcg_temp_new_i32();
7587 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7588
7589 gen_load_fpr32(fp32, fs);
895c2d04 7590 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7591 tcg_temp_free_i32(fp32);
b6d96bed 7592 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7593 tcg_temp_free_i64(fp64);
b6d96bed 7594 }
5a5012ec
TS
7595 opn = "floor.l.s";
7596 break;
bf4120ad 7597 case OPC_ROUND_W_S:
b6d96bed 7598 {
a7812ae4 7599 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7600
7601 gen_load_fpr32(fp0, fs);
895c2d04 7602 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7603 gen_store_fpr32(fp0, fd);
a7812ae4 7604 tcg_temp_free_i32(fp0);
b6d96bed 7605 }
5a5012ec
TS
7606 opn = "round.w.s";
7607 break;
bf4120ad 7608 case OPC_TRUNC_W_S:
b6d96bed 7609 {
a7812ae4 7610 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7611
7612 gen_load_fpr32(fp0, fs);
895c2d04 7613 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7614 gen_store_fpr32(fp0, fd);
a7812ae4 7615 tcg_temp_free_i32(fp0);
b6d96bed 7616 }
5a5012ec
TS
7617 opn = "trunc.w.s";
7618 break;
bf4120ad 7619 case OPC_CEIL_W_S:
b6d96bed 7620 {
a7812ae4 7621 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7622
7623 gen_load_fpr32(fp0, fs);
895c2d04 7624 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7625 gen_store_fpr32(fp0, fd);
a7812ae4 7626 tcg_temp_free_i32(fp0);
b6d96bed 7627 }
5a5012ec
TS
7628 opn = "ceil.w.s";
7629 break;
bf4120ad 7630 case OPC_FLOOR_W_S:
b6d96bed 7631 {
a7812ae4 7632 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7633
7634 gen_load_fpr32(fp0, fs);
895c2d04 7635 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7636 gen_store_fpr32(fp0, fd);
a7812ae4 7637 tcg_temp_free_i32(fp0);
b6d96bed 7638 }
5a5012ec
TS
7639 opn = "floor.w.s";
7640 break;
bf4120ad 7641 case OPC_MOVCF_S:
b6d96bed 7642 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7643 opn = "movcf.s";
7644 break;
bf4120ad 7645 case OPC_MOVZ_S:
a16336e4
TS
7646 {
7647 int l1 = gen_new_label();
c9297f4d 7648 TCGv_i32 fp0;
a16336e4 7649
c9297f4d
AJ
7650 if (ft != 0) {
7651 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7652 }
7653 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7654 gen_load_fpr32(fp0, fs);
7655 gen_store_fpr32(fp0, fd);
a7812ae4 7656 tcg_temp_free_i32(fp0);
a16336e4
TS
7657 gen_set_label(l1);
7658 }
5a5012ec
TS
7659 opn = "movz.s";
7660 break;
bf4120ad 7661 case OPC_MOVN_S:
a16336e4
TS
7662 {
7663 int l1 = gen_new_label();
c9297f4d
AJ
7664 TCGv_i32 fp0;
7665
7666 if (ft != 0) {
7667 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7668 fp0 = tcg_temp_new_i32();
7669 gen_load_fpr32(fp0, fs);
7670 gen_store_fpr32(fp0, fd);
7671 tcg_temp_free_i32(fp0);
7672 gen_set_label(l1);
7673 }
a16336e4 7674 }
5a5012ec
TS
7675 opn = "movn.s";
7676 break;
bf4120ad 7677 case OPC_RECIP_S:
b8aa4598 7678 check_cop1x(ctx);
b6d96bed 7679 {
a7812ae4 7680 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7681
7682 gen_load_fpr32(fp0, fs);
895c2d04 7683 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 7684 gen_store_fpr32(fp0, fd);
a7812ae4 7685 tcg_temp_free_i32(fp0);
b6d96bed 7686 }
57fa1fb3
TS
7687 opn = "recip.s";
7688 break;
bf4120ad 7689 case OPC_RSQRT_S:
b8aa4598 7690 check_cop1x(ctx);
b6d96bed 7691 {
a7812ae4 7692 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7693
7694 gen_load_fpr32(fp0, fs);
895c2d04 7695 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7696 gen_store_fpr32(fp0, fd);
a7812ae4 7697 tcg_temp_free_i32(fp0);
b6d96bed 7698 }
57fa1fb3
TS
7699 opn = "rsqrt.s";
7700 break;
bf4120ad 7701 case OPC_RECIP2_S:
5e755519 7702 check_cp1_64bitmode(ctx);
b6d96bed 7703 {
a7812ae4
PB
7704 TCGv_i32 fp0 = tcg_temp_new_i32();
7705 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7706
7707 gen_load_fpr32(fp0, fs);
d22d7289 7708 gen_load_fpr32(fp1, ft);
895c2d04 7709 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7710 tcg_temp_free_i32(fp1);
b6d96bed 7711 gen_store_fpr32(fp0, fd);
a7812ae4 7712 tcg_temp_free_i32(fp0);
b6d96bed 7713 }
57fa1fb3
TS
7714 opn = "recip2.s";
7715 break;
bf4120ad 7716 case OPC_RECIP1_S:
5e755519 7717 check_cp1_64bitmode(ctx);
b6d96bed 7718 {
a7812ae4 7719 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7720
7721 gen_load_fpr32(fp0, fs);
895c2d04 7722 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7723 gen_store_fpr32(fp0, fd);
a7812ae4 7724 tcg_temp_free_i32(fp0);
b6d96bed 7725 }
57fa1fb3
TS
7726 opn = "recip1.s";
7727 break;
bf4120ad 7728 case OPC_RSQRT1_S:
5e755519 7729 check_cp1_64bitmode(ctx);
b6d96bed 7730 {
a7812ae4 7731 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7732
7733 gen_load_fpr32(fp0, fs);
895c2d04 7734 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7735 gen_store_fpr32(fp0, fd);
a7812ae4 7736 tcg_temp_free_i32(fp0);
b6d96bed 7737 }
57fa1fb3
TS
7738 opn = "rsqrt1.s";
7739 break;
bf4120ad 7740 case OPC_RSQRT2_S:
5e755519 7741 check_cp1_64bitmode(ctx);
b6d96bed 7742 {
a7812ae4
PB
7743 TCGv_i32 fp0 = tcg_temp_new_i32();
7744 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7745
7746 gen_load_fpr32(fp0, fs);
7747 gen_load_fpr32(fp1, ft);
895c2d04 7748 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7749 tcg_temp_free_i32(fp1);
b6d96bed 7750 gen_store_fpr32(fp0, fd);
a7812ae4 7751 tcg_temp_free_i32(fp0);
b6d96bed 7752 }
57fa1fb3
TS
7753 opn = "rsqrt2.s";
7754 break;
bf4120ad 7755 case OPC_CVT_D_S:
5e755519 7756 check_cp1_registers(ctx, fd);
b6d96bed 7757 {
a7812ae4
PB
7758 TCGv_i32 fp32 = tcg_temp_new_i32();
7759 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7760
7761 gen_load_fpr32(fp32, fs);
895c2d04 7762 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7763 tcg_temp_free_i32(fp32);
b6d96bed 7764 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7765 tcg_temp_free_i64(fp64);
b6d96bed 7766 }
5a5012ec
TS
7767 opn = "cvt.d.s";
7768 break;
bf4120ad 7769 case OPC_CVT_W_S:
b6d96bed 7770 {
a7812ae4 7771 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7772
7773 gen_load_fpr32(fp0, fs);
895c2d04 7774 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7775 gen_store_fpr32(fp0, fd);
a7812ae4 7776 tcg_temp_free_i32(fp0);
b6d96bed 7777 }
5a5012ec
TS
7778 opn = "cvt.w.s";
7779 break;
bf4120ad 7780 case OPC_CVT_L_S:
5e755519 7781 check_cp1_64bitmode(ctx);
b6d96bed 7782 {
a7812ae4
PB
7783 TCGv_i32 fp32 = tcg_temp_new_i32();
7784 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7785
7786 gen_load_fpr32(fp32, fs);
895c2d04 7787 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7788 tcg_temp_free_i32(fp32);
b6d96bed 7789 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7790 tcg_temp_free_i64(fp64);
b6d96bed 7791 }
5a5012ec
TS
7792 opn = "cvt.l.s";
7793 break;
bf4120ad 7794 case OPC_CVT_PS_S:
5e755519 7795 check_cp1_64bitmode(ctx);
b6d96bed 7796 {
a7812ae4
PB
7797 TCGv_i64 fp64 = tcg_temp_new_i64();
7798 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7799 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7800
7801 gen_load_fpr32(fp32_0, fs);
7802 gen_load_fpr32(fp32_1, ft);
13d24f49 7803 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7804 tcg_temp_free_i32(fp32_1);
7805 tcg_temp_free_i32(fp32_0);
36aa55dc 7806 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7807 tcg_temp_free_i64(fp64);
b6d96bed 7808 }
5a5012ec
TS
7809 opn = "cvt.ps.s";
7810 break;
bf4120ad
NF
7811 case OPC_CMP_F_S:
7812 case OPC_CMP_UN_S:
7813 case OPC_CMP_EQ_S:
7814 case OPC_CMP_UEQ_S:
7815 case OPC_CMP_OLT_S:
7816 case OPC_CMP_ULT_S:
7817 case OPC_CMP_OLE_S:
7818 case OPC_CMP_ULE_S:
7819 case OPC_CMP_SF_S:
7820 case OPC_CMP_NGLE_S:
7821 case OPC_CMP_SEQ_S:
7822 case OPC_CMP_NGL_S:
7823 case OPC_CMP_LT_S:
7824 case OPC_CMP_NGE_S:
7825 case OPC_CMP_LE_S:
7826 case OPC_CMP_NGT_S:
8153667c
NF
7827 if (ctx->opcode & (1 << 6)) {
7828 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7829 opn = condnames_abs[func-48];
7830 } else {
7831 gen_cmp_s(ctx, func-48, ft, fs, cc);
7832 opn = condnames[func-48];
5a1e8ffb 7833 }
5a5012ec 7834 break;
bf4120ad 7835 case OPC_ADD_D:
5e755519 7836 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7837 {
a7812ae4
PB
7838 TCGv_i64 fp0 = tcg_temp_new_i64();
7839 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7840
7841 gen_load_fpr64(ctx, fp0, fs);
7842 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7843 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7844 tcg_temp_free_i64(fp1);
b6d96bed 7845 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7846 tcg_temp_free_i64(fp0);
b6d96bed 7847 }
6ea83fed 7848 opn = "add.d";
5a1e8ffb 7849 optype = BINOP;
6ea83fed 7850 break;
bf4120ad 7851 case OPC_SUB_D:
5e755519 7852 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7853 {
a7812ae4
PB
7854 TCGv_i64 fp0 = tcg_temp_new_i64();
7855 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7856
7857 gen_load_fpr64(ctx, fp0, fs);
7858 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7859 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7860 tcg_temp_free_i64(fp1);
b6d96bed 7861 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7862 tcg_temp_free_i64(fp0);
b6d96bed 7863 }
6ea83fed 7864 opn = "sub.d";
5a1e8ffb 7865 optype = BINOP;
6ea83fed 7866 break;
bf4120ad 7867 case OPC_MUL_D:
5e755519 7868 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7869 {
a7812ae4
PB
7870 TCGv_i64 fp0 = tcg_temp_new_i64();
7871 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7872
7873 gen_load_fpr64(ctx, fp0, fs);
7874 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7875 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7876 tcg_temp_free_i64(fp1);
b6d96bed 7877 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7878 tcg_temp_free_i64(fp0);
b6d96bed 7879 }
6ea83fed 7880 opn = "mul.d";
5a1e8ffb 7881 optype = BINOP;
6ea83fed 7882 break;
bf4120ad 7883 case OPC_DIV_D:
5e755519 7884 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7885 {
a7812ae4
PB
7886 TCGv_i64 fp0 = tcg_temp_new_i64();
7887 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7888
7889 gen_load_fpr64(ctx, fp0, fs);
7890 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7891 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7892 tcg_temp_free_i64(fp1);
b6d96bed 7893 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7894 tcg_temp_free_i64(fp0);
b6d96bed 7895 }
6ea83fed 7896 opn = "div.d";
5a1e8ffb 7897 optype = BINOP;
6ea83fed 7898 break;
bf4120ad 7899 case OPC_SQRT_D:
5e755519 7900 check_cp1_registers(ctx, fs | fd);
b6d96bed 7901 {
a7812ae4 7902 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7903
7904 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7905 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7906 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7907 tcg_temp_free_i64(fp0);
b6d96bed 7908 }
6ea83fed
FB
7909 opn = "sqrt.d";
7910 break;
bf4120ad 7911 case OPC_ABS_D:
5e755519 7912 check_cp1_registers(ctx, fs | fd);
b6d96bed 7913 {
a7812ae4 7914 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7915
7916 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7917 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7918 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7919 tcg_temp_free_i64(fp0);
b6d96bed 7920 }
6ea83fed
FB
7921 opn = "abs.d";
7922 break;
bf4120ad 7923 case OPC_MOV_D:
5e755519 7924 check_cp1_registers(ctx, fs | fd);
b6d96bed 7925 {
a7812ae4 7926 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7927
7928 gen_load_fpr64(ctx, fp0, fs);
7929 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7930 tcg_temp_free_i64(fp0);
b6d96bed 7931 }
6ea83fed
FB
7932 opn = "mov.d";
7933 break;
bf4120ad 7934 case OPC_NEG_D:
5e755519 7935 check_cp1_registers(ctx, fs | fd);
b6d96bed 7936 {
a7812ae4 7937 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7938
7939 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7940 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 7941 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7942 tcg_temp_free_i64(fp0);
b6d96bed 7943 }
6ea83fed
FB
7944 opn = "neg.d";
7945 break;
bf4120ad 7946 case OPC_ROUND_L_D:
5e755519 7947 check_cp1_64bitmode(ctx);
b6d96bed 7948 {
a7812ae4 7949 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7950
7951 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7952 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 7953 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7954 tcg_temp_free_i64(fp0);
b6d96bed 7955 }
5a5012ec
TS
7956 opn = "round.l.d";
7957 break;
bf4120ad 7958 case OPC_TRUNC_L_D:
5e755519 7959 check_cp1_64bitmode(ctx);
b6d96bed 7960 {
a7812ae4 7961 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7962
7963 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7964 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 7965 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7966 tcg_temp_free_i64(fp0);
b6d96bed 7967 }
5a5012ec
TS
7968 opn = "trunc.l.d";
7969 break;
bf4120ad 7970 case OPC_CEIL_L_D:
5e755519 7971 check_cp1_64bitmode(ctx);
b6d96bed 7972 {
a7812ae4 7973 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7974
7975 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7976 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 7977 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7978 tcg_temp_free_i64(fp0);
b6d96bed 7979 }
5a5012ec
TS
7980 opn = "ceil.l.d";
7981 break;
bf4120ad 7982 case OPC_FLOOR_L_D:
5e755519 7983 check_cp1_64bitmode(ctx);
b6d96bed 7984 {
a7812ae4 7985 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7986
7987 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7988 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 7989 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7990 tcg_temp_free_i64(fp0);
b6d96bed 7991 }
5a5012ec
TS
7992 opn = "floor.l.d";
7993 break;
bf4120ad 7994 case OPC_ROUND_W_D:
5e755519 7995 check_cp1_registers(ctx, fs);
b6d96bed 7996 {
a7812ae4
PB
7997 TCGv_i32 fp32 = tcg_temp_new_i32();
7998 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7999
8000 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8001 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8002 tcg_temp_free_i64(fp64);
b6d96bed 8003 gen_store_fpr32(fp32, fd);
a7812ae4 8004 tcg_temp_free_i32(fp32);
b6d96bed 8005 }
6ea83fed
FB
8006 opn = "round.w.d";
8007 break;
bf4120ad 8008 case OPC_TRUNC_W_D:
5e755519 8009 check_cp1_registers(ctx, fs);
b6d96bed 8010 {
a7812ae4
PB
8011 TCGv_i32 fp32 = tcg_temp_new_i32();
8012 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8013
8014 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8015 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8016 tcg_temp_free_i64(fp64);
b6d96bed 8017 gen_store_fpr32(fp32, fd);
a7812ae4 8018 tcg_temp_free_i32(fp32);
b6d96bed 8019 }
6ea83fed
FB
8020 opn = "trunc.w.d";
8021 break;
bf4120ad 8022 case OPC_CEIL_W_D:
5e755519 8023 check_cp1_registers(ctx, fs);
b6d96bed 8024 {
a7812ae4
PB
8025 TCGv_i32 fp32 = tcg_temp_new_i32();
8026 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8027
8028 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8029 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8030 tcg_temp_free_i64(fp64);
b6d96bed 8031 gen_store_fpr32(fp32, fd);
a7812ae4 8032 tcg_temp_free_i32(fp32);
b6d96bed 8033 }
6ea83fed
FB
8034 opn = "ceil.w.d";
8035 break;
bf4120ad 8036 case OPC_FLOOR_W_D:
5e755519 8037 check_cp1_registers(ctx, fs);
b6d96bed 8038 {
a7812ae4
PB
8039 TCGv_i32 fp32 = tcg_temp_new_i32();
8040 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8041
8042 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8043 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8044 tcg_temp_free_i64(fp64);
b6d96bed 8045 gen_store_fpr32(fp32, fd);
a7812ae4 8046 tcg_temp_free_i32(fp32);
b6d96bed 8047 }
7a387fff 8048 opn = "floor.w.d";
6ea83fed 8049 break;
bf4120ad 8050 case OPC_MOVCF_D:
b6d96bed 8051 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8052 opn = "movcf.d";
dd016883 8053 break;
bf4120ad 8054 case OPC_MOVZ_D:
a16336e4
TS
8055 {
8056 int l1 = gen_new_label();
c9297f4d 8057 TCGv_i64 fp0;
a16336e4 8058
c9297f4d
AJ
8059 if (ft != 0) {
8060 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8061 }
8062 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8063 gen_load_fpr64(ctx, fp0, fs);
8064 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8065 tcg_temp_free_i64(fp0);
a16336e4
TS
8066 gen_set_label(l1);
8067 }
5a5012ec
TS
8068 opn = "movz.d";
8069 break;
bf4120ad 8070 case OPC_MOVN_D:
a16336e4
TS
8071 {
8072 int l1 = gen_new_label();
c9297f4d
AJ
8073 TCGv_i64 fp0;
8074
8075 if (ft != 0) {
8076 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8077 fp0 = tcg_temp_new_i64();
8078 gen_load_fpr64(ctx, fp0, fs);
8079 gen_store_fpr64(ctx, fp0, fd);
8080 tcg_temp_free_i64(fp0);
8081 gen_set_label(l1);
8082 }
a16336e4 8083 }
5a5012ec 8084 opn = "movn.d";
6ea83fed 8085 break;
bf4120ad 8086 case OPC_RECIP_D:
b8aa4598 8087 check_cp1_64bitmode(ctx);
b6d96bed 8088 {
a7812ae4 8089 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8090
8091 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8092 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8093 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8094 tcg_temp_free_i64(fp0);
b6d96bed 8095 }
57fa1fb3
TS
8096 opn = "recip.d";
8097 break;
bf4120ad 8098 case OPC_RSQRT_D:
b8aa4598 8099 check_cp1_64bitmode(ctx);
b6d96bed 8100 {
a7812ae4 8101 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8102
8103 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8104 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8105 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8106 tcg_temp_free_i64(fp0);
b6d96bed 8107 }
57fa1fb3
TS
8108 opn = "rsqrt.d";
8109 break;
bf4120ad 8110 case OPC_RECIP2_D:
5e755519 8111 check_cp1_64bitmode(ctx);
b6d96bed 8112 {
a7812ae4
PB
8113 TCGv_i64 fp0 = tcg_temp_new_i64();
8114 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8115
8116 gen_load_fpr64(ctx, fp0, fs);
8117 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8118 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8119 tcg_temp_free_i64(fp1);
b6d96bed 8120 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8121 tcg_temp_free_i64(fp0);
b6d96bed 8122 }
57fa1fb3
TS
8123 opn = "recip2.d";
8124 break;
bf4120ad 8125 case OPC_RECIP1_D:
5e755519 8126 check_cp1_64bitmode(ctx);
b6d96bed 8127 {
a7812ae4 8128 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8129
8130 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8131 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8132 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8133 tcg_temp_free_i64(fp0);
b6d96bed 8134 }
57fa1fb3
TS
8135 opn = "recip1.d";
8136 break;
bf4120ad 8137 case OPC_RSQRT1_D:
5e755519 8138 check_cp1_64bitmode(ctx);
b6d96bed 8139 {
a7812ae4 8140 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8141
8142 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8143 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8144 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8145 tcg_temp_free_i64(fp0);
b6d96bed 8146 }
57fa1fb3
TS
8147 opn = "rsqrt1.d";
8148 break;
bf4120ad 8149 case OPC_RSQRT2_D:
5e755519 8150 check_cp1_64bitmode(ctx);
b6d96bed 8151 {
a7812ae4
PB
8152 TCGv_i64 fp0 = tcg_temp_new_i64();
8153 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8154
8155 gen_load_fpr64(ctx, fp0, fs);
8156 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8157 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8158 tcg_temp_free_i64(fp1);
b6d96bed 8159 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8160 tcg_temp_free_i64(fp0);
b6d96bed 8161 }
57fa1fb3
TS
8162 opn = "rsqrt2.d";
8163 break;
bf4120ad
NF
8164 case OPC_CMP_F_D:
8165 case OPC_CMP_UN_D:
8166 case OPC_CMP_EQ_D:
8167 case OPC_CMP_UEQ_D:
8168 case OPC_CMP_OLT_D:
8169 case OPC_CMP_ULT_D:
8170 case OPC_CMP_OLE_D:
8171 case OPC_CMP_ULE_D:
8172 case OPC_CMP_SF_D:
8173 case OPC_CMP_NGLE_D:
8174 case OPC_CMP_SEQ_D:
8175 case OPC_CMP_NGL_D:
8176 case OPC_CMP_LT_D:
8177 case OPC_CMP_NGE_D:
8178 case OPC_CMP_LE_D:
8179 case OPC_CMP_NGT_D:
8153667c
NF
8180 if (ctx->opcode & (1 << 6)) {
8181 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8182 opn = condnames_abs[func-48];
8183 } else {
8184 gen_cmp_d(ctx, func-48, ft, fs, cc);
8185 opn = condnames[func-48];
5a1e8ffb 8186 }
6ea83fed 8187 break;
bf4120ad 8188 case OPC_CVT_S_D:
5e755519 8189 check_cp1_registers(ctx, fs);
b6d96bed 8190 {
a7812ae4
PB
8191 TCGv_i32 fp32 = tcg_temp_new_i32();
8192 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8193
8194 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8195 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8196 tcg_temp_free_i64(fp64);
b6d96bed 8197 gen_store_fpr32(fp32, fd);
a7812ae4 8198 tcg_temp_free_i32(fp32);
b6d96bed 8199 }
5a5012ec
TS
8200 opn = "cvt.s.d";
8201 break;
bf4120ad 8202 case OPC_CVT_W_D:
5e755519 8203 check_cp1_registers(ctx, fs);
b6d96bed 8204 {
a7812ae4
PB
8205 TCGv_i32 fp32 = tcg_temp_new_i32();
8206 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8207
8208 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8209 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8210 tcg_temp_free_i64(fp64);
b6d96bed 8211 gen_store_fpr32(fp32, fd);
a7812ae4 8212 tcg_temp_free_i32(fp32);
b6d96bed 8213 }
5a5012ec
TS
8214 opn = "cvt.w.d";
8215 break;
bf4120ad 8216 case OPC_CVT_L_D:
5e755519 8217 check_cp1_64bitmode(ctx);
b6d96bed 8218 {
a7812ae4 8219 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8220
8221 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8222 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8223 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8224 tcg_temp_free_i64(fp0);
b6d96bed 8225 }
5a5012ec
TS
8226 opn = "cvt.l.d";
8227 break;
bf4120ad 8228 case OPC_CVT_S_W:
b6d96bed 8229 {
a7812ae4 8230 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8231
8232 gen_load_fpr32(fp0, fs);
895c2d04 8233 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8234 gen_store_fpr32(fp0, fd);
a7812ae4 8235 tcg_temp_free_i32(fp0);
b6d96bed 8236 }
5a5012ec 8237 opn = "cvt.s.w";
6ea83fed 8238 break;
bf4120ad 8239 case OPC_CVT_D_W:
5e755519 8240 check_cp1_registers(ctx, fd);
b6d96bed 8241 {
a7812ae4
PB
8242 TCGv_i32 fp32 = tcg_temp_new_i32();
8243 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8244
8245 gen_load_fpr32(fp32, fs);
895c2d04 8246 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8247 tcg_temp_free_i32(fp32);
b6d96bed 8248 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8249 tcg_temp_free_i64(fp64);
b6d96bed 8250 }
5a5012ec
TS
8251 opn = "cvt.d.w";
8252 break;
bf4120ad 8253 case OPC_CVT_S_L:
5e755519 8254 check_cp1_64bitmode(ctx);
b6d96bed 8255 {
a7812ae4
PB
8256 TCGv_i32 fp32 = tcg_temp_new_i32();
8257 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8258
8259 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8260 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8261 tcg_temp_free_i64(fp64);
b6d96bed 8262 gen_store_fpr32(fp32, fd);
a7812ae4 8263 tcg_temp_free_i32(fp32);
b6d96bed 8264 }
5a5012ec
TS
8265 opn = "cvt.s.l";
8266 break;
bf4120ad 8267 case OPC_CVT_D_L:
5e755519 8268 check_cp1_64bitmode(ctx);
b6d96bed 8269 {
a7812ae4 8270 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8271
8272 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8273 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8274 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8275 tcg_temp_free_i64(fp0);
b6d96bed 8276 }
5a5012ec
TS
8277 opn = "cvt.d.l";
8278 break;
bf4120ad 8279 case OPC_CVT_PS_PW:
5e755519 8280 check_cp1_64bitmode(ctx);
b6d96bed 8281 {
a7812ae4 8282 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8283
8284 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8285 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8286 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8287 tcg_temp_free_i64(fp0);
b6d96bed 8288 }
5a5012ec
TS
8289 opn = "cvt.ps.pw";
8290 break;
bf4120ad 8291 case OPC_ADD_PS:
5e755519 8292 check_cp1_64bitmode(ctx);
b6d96bed 8293 {
a7812ae4
PB
8294 TCGv_i64 fp0 = tcg_temp_new_i64();
8295 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8296
8297 gen_load_fpr64(ctx, fp0, fs);
8298 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8299 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8300 tcg_temp_free_i64(fp1);
b6d96bed 8301 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8302 tcg_temp_free_i64(fp0);
b6d96bed 8303 }
5a5012ec 8304 opn = "add.ps";
6ea83fed 8305 break;
bf4120ad 8306 case OPC_SUB_PS:
5e755519 8307 check_cp1_64bitmode(ctx);
b6d96bed 8308 {
a7812ae4
PB
8309 TCGv_i64 fp0 = tcg_temp_new_i64();
8310 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8311
8312 gen_load_fpr64(ctx, fp0, fs);
8313 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8314 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8315 tcg_temp_free_i64(fp1);
b6d96bed 8316 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8317 tcg_temp_free_i64(fp0);
b6d96bed 8318 }
5a5012ec 8319 opn = "sub.ps";
6ea83fed 8320 break;
bf4120ad 8321 case OPC_MUL_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_mul_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 = "mul.ps";
6ea83fed 8335 break;
bf4120ad 8336 case OPC_ABS_PS:
5e755519 8337 check_cp1_64bitmode(ctx);
b6d96bed 8338 {
a7812ae4 8339 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8340
8341 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8342 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8343 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8344 tcg_temp_free_i64(fp0);
b6d96bed 8345 }
5a5012ec 8346 opn = "abs.ps";
6ea83fed 8347 break;
bf4120ad 8348 case OPC_MOV_PS:
5e755519 8349 check_cp1_64bitmode(ctx);
b6d96bed 8350 {
a7812ae4 8351 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8352
8353 gen_load_fpr64(ctx, fp0, fs);
8354 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8355 tcg_temp_free_i64(fp0);
b6d96bed 8356 }
5a5012ec 8357 opn = "mov.ps";
6ea83fed 8358 break;
bf4120ad 8359 case OPC_NEG_PS:
5e755519 8360 check_cp1_64bitmode(ctx);
b6d96bed 8361 {
a7812ae4 8362 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8363
8364 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8365 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8366 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8367 tcg_temp_free_i64(fp0);
b6d96bed 8368 }
5a5012ec 8369 opn = "neg.ps";
6ea83fed 8370 break;
bf4120ad 8371 case OPC_MOVCF_PS:
5e755519 8372 check_cp1_64bitmode(ctx);
b6d96bed 8373 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8374 opn = "movcf.ps";
6ea83fed 8375 break;
bf4120ad 8376 case OPC_MOVZ_PS:
5e755519 8377 check_cp1_64bitmode(ctx);
a16336e4
TS
8378 {
8379 int l1 = gen_new_label();
30a3848b 8380 TCGv_i64 fp0;
a16336e4 8381
c9297f4d
AJ
8382 if (ft != 0)
8383 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8384 fp0 = tcg_temp_new_i64();
8385 gen_load_fpr64(ctx, fp0, fs);
8386 gen_store_fpr64(ctx, fp0, fd);
8387 tcg_temp_free_i64(fp0);
a16336e4
TS
8388 gen_set_label(l1);
8389 }
5a5012ec 8390 opn = "movz.ps";
6ea83fed 8391 break;
bf4120ad 8392 case OPC_MOVN_PS:
5e755519 8393 check_cp1_64bitmode(ctx);
a16336e4
TS
8394 {
8395 int l1 = gen_new_label();
30a3848b 8396 TCGv_i64 fp0;
c9297f4d
AJ
8397
8398 if (ft != 0) {
8399 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8400 fp0 = tcg_temp_new_i64();
8401 gen_load_fpr64(ctx, fp0, fs);
8402 gen_store_fpr64(ctx, fp0, fd);
8403 tcg_temp_free_i64(fp0);
8404 gen_set_label(l1);
8405 }
a16336e4 8406 }
5a5012ec 8407 opn = "movn.ps";
6ea83fed 8408 break;
bf4120ad 8409 case OPC_ADDR_PS:
5e755519 8410 check_cp1_64bitmode(ctx);
b6d96bed 8411 {
a7812ae4
PB
8412 TCGv_i64 fp0 = tcg_temp_new_i64();
8413 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8414
8415 gen_load_fpr64(ctx, fp0, ft);
8416 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8417 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8418 tcg_temp_free_i64(fp1);
b6d96bed 8419 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8420 tcg_temp_free_i64(fp0);
b6d96bed 8421 }
fbcc6828
TS
8422 opn = "addr.ps";
8423 break;
bf4120ad 8424 case OPC_MULR_PS:
5e755519 8425 check_cp1_64bitmode(ctx);
b6d96bed 8426 {
a7812ae4
PB
8427 TCGv_i64 fp0 = tcg_temp_new_i64();
8428 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8429
8430 gen_load_fpr64(ctx, fp0, ft);
8431 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8432 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8433 tcg_temp_free_i64(fp1);
b6d96bed 8434 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8435 tcg_temp_free_i64(fp0);
b6d96bed 8436 }
57fa1fb3
TS
8437 opn = "mulr.ps";
8438 break;
bf4120ad 8439 case OPC_RECIP2_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, fs);
d22d7289 8446 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8447 gen_helper_float_recip2_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 }
57fa1fb3
TS
8452 opn = "recip2.ps";
8453 break;
bf4120ad 8454 case OPC_RECIP1_PS:
5e755519 8455 check_cp1_64bitmode(ctx);
b6d96bed 8456 {
a7812ae4 8457 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8458
8459 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8460 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8461 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8462 tcg_temp_free_i64(fp0);
b6d96bed 8463 }
57fa1fb3
TS
8464 opn = "recip1.ps";
8465 break;
bf4120ad 8466 case OPC_RSQRT1_PS:
5e755519 8467 check_cp1_64bitmode(ctx);
b6d96bed 8468 {
a7812ae4 8469 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8470
8471 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8472 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8473 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8474 tcg_temp_free_i64(fp0);
b6d96bed 8475 }
57fa1fb3
TS
8476 opn = "rsqrt1.ps";
8477 break;
bf4120ad 8478 case OPC_RSQRT2_PS:
5e755519 8479 check_cp1_64bitmode(ctx);
b6d96bed 8480 {
a7812ae4
PB
8481 TCGv_i64 fp0 = tcg_temp_new_i64();
8482 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8483
8484 gen_load_fpr64(ctx, fp0, fs);
8485 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8486 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8487 tcg_temp_free_i64(fp1);
b6d96bed 8488 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8489 tcg_temp_free_i64(fp0);
b6d96bed 8490 }
57fa1fb3
TS
8491 opn = "rsqrt2.ps";
8492 break;
bf4120ad 8493 case OPC_CVT_S_PU:
5e755519 8494 check_cp1_64bitmode(ctx);
b6d96bed 8495 {
a7812ae4 8496 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8497
8498 gen_load_fpr32h(fp0, fs);
895c2d04 8499 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8500 gen_store_fpr32(fp0, fd);
a7812ae4 8501 tcg_temp_free_i32(fp0);
b6d96bed 8502 }
5a5012ec 8503 opn = "cvt.s.pu";
dd016883 8504 break;
bf4120ad 8505 case OPC_CVT_PW_PS:
5e755519 8506 check_cp1_64bitmode(ctx);
b6d96bed 8507 {
a7812ae4 8508 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8509
8510 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8511 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8512 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8513 tcg_temp_free_i64(fp0);
b6d96bed 8514 }
5a5012ec 8515 opn = "cvt.pw.ps";
6ea83fed 8516 break;
bf4120ad 8517 case OPC_CVT_S_PL:
5e755519 8518 check_cp1_64bitmode(ctx);
b6d96bed 8519 {
a7812ae4 8520 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8521
8522 gen_load_fpr32(fp0, fs);
895c2d04 8523 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8524 gen_store_fpr32(fp0, fd);
a7812ae4 8525 tcg_temp_free_i32(fp0);
b6d96bed 8526 }
5a5012ec 8527 opn = "cvt.s.pl";
6ea83fed 8528 break;
bf4120ad 8529 case OPC_PLL_PS:
5e755519 8530 check_cp1_64bitmode(ctx);
b6d96bed 8531 {
a7812ae4
PB
8532 TCGv_i32 fp0 = tcg_temp_new_i32();
8533 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8534
8535 gen_load_fpr32(fp0, fs);
8536 gen_load_fpr32(fp1, ft);
8537 gen_store_fpr32h(fp0, fd);
8538 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8539 tcg_temp_free_i32(fp0);
8540 tcg_temp_free_i32(fp1);
b6d96bed 8541 }
5a5012ec 8542 opn = "pll.ps";
6ea83fed 8543 break;
bf4120ad 8544 case OPC_PLU_PS:
5e755519 8545 check_cp1_64bitmode(ctx);
b6d96bed 8546 {
a7812ae4
PB
8547 TCGv_i32 fp0 = tcg_temp_new_i32();
8548 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8549
8550 gen_load_fpr32(fp0, fs);
8551 gen_load_fpr32h(fp1, ft);
8552 gen_store_fpr32(fp1, fd);
8553 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8554 tcg_temp_free_i32(fp0);
8555 tcg_temp_free_i32(fp1);
b6d96bed 8556 }
5a5012ec
TS
8557 opn = "plu.ps";
8558 break;
bf4120ad 8559 case OPC_PUL_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_fpr32h(fp0, fs);
8566 gen_load_fpr32(fp1, ft);
8567 gen_store_fpr32(fp1, fd);
8568 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8569 tcg_temp_free_i32(fp0);
8570 tcg_temp_free_i32(fp1);
b6d96bed 8571 }
5a5012ec
TS
8572 opn = "pul.ps";
8573 break;
bf4120ad 8574 case OPC_PUU_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_fpr32h(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 = "puu.ps";
8588 break;
bf4120ad
NF
8589 case OPC_CMP_F_PS:
8590 case OPC_CMP_UN_PS:
8591 case OPC_CMP_EQ_PS:
8592 case OPC_CMP_UEQ_PS:
8593 case OPC_CMP_OLT_PS:
8594 case OPC_CMP_ULT_PS:
8595 case OPC_CMP_OLE_PS:
8596 case OPC_CMP_ULE_PS:
8597 case OPC_CMP_SF_PS:
8598 case OPC_CMP_NGLE_PS:
8599 case OPC_CMP_SEQ_PS:
8600 case OPC_CMP_NGL_PS:
8601 case OPC_CMP_LT_PS:
8602 case OPC_CMP_NGE_PS:
8603 case OPC_CMP_LE_PS:
8604 case OPC_CMP_NGT_PS:
8153667c
NF
8605 if (ctx->opcode & (1 << 6)) {
8606 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8607 opn = condnames_abs[func-48];
8608 } else {
8609 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8610 opn = condnames[func-48];
5a1e8ffb 8611 }
6ea83fed 8612 break;
5a5012ec 8613 default:
923617a3 8614 MIPS_INVAL(opn);
e397ee33 8615 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8616 return;
8617 }
2abf314d 8618 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8619 switch (optype) {
8620 case BINOP:
6ea83fed 8621 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8622 break;
8623 case CMPOP:
8624 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8625 break;
8626 default:
6ea83fed 8627 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8628 break;
8629 }
6ea83fed 8630}
6af0bf9c 8631
5a5012ec 8632/* Coprocessor 3 (FPU) */
5e755519
TS
8633static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8634 int fd, int fs, int base, int index)
7a387fff 8635{
923617a3 8636 const char *opn = "extended float load/store";
93b12ccc 8637 int store = 0;
4e2474d6 8638 TCGv t0 = tcg_temp_new();
7a387fff 8639
93b12ccc 8640 if (base == 0) {
6c5c1e20 8641 gen_load_gpr(t0, index);
93b12ccc 8642 } else if (index == 0) {
6c5c1e20 8643 gen_load_gpr(t0, base);
93b12ccc 8644 } else {
05168674 8645 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8646 }
5a5012ec 8647 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8648 memory access. */
5a5012ec
TS
8649 switch (opc) {
8650 case OPC_LWXC1:
8c0ab41f 8651 check_cop1x(ctx);
b6d96bed 8652 {
a7812ae4 8653 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8654
585c88d5
AJ
8655 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8656 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8657 gen_store_fpr32(fp0, fd);
a7812ae4 8658 tcg_temp_free_i32(fp0);
b6d96bed 8659 }
5a5012ec
TS
8660 opn = "lwxc1";
8661 break;
8662 case OPC_LDXC1:
8c0ab41f
AJ
8663 check_cop1x(ctx);
8664 check_cp1_registers(ctx, fd);
b6d96bed 8665 {
a7812ae4 8666 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8667
8668 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8669 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8670 tcg_temp_free_i64(fp0);
b6d96bed 8671 }
5a5012ec
TS
8672 opn = "ldxc1";
8673 break;
8674 case OPC_LUXC1:
8c0ab41f 8675 check_cp1_64bitmode(ctx);
6c5c1e20 8676 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8677 {
a7812ae4 8678 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8679
8680 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8681 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8682 tcg_temp_free_i64(fp0);
b6d96bed 8683 }
5a5012ec
TS
8684 opn = "luxc1";
8685 break;
8686 case OPC_SWXC1:
8c0ab41f 8687 check_cop1x(ctx);
b6d96bed 8688 {
a7812ae4 8689 TCGv_i32 fp0 = tcg_temp_new_i32();
585c88d5 8690 TCGv t1 = tcg_temp_new();
b6d96bed
TS
8691
8692 gen_load_fpr32(fp0, fs);
a7812ae4
PB
8693 tcg_gen_extu_i32_tl(t1, fp0);
8694 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8695 tcg_temp_free_i32(fp0);
a6035857 8696 tcg_temp_free(t1);
b6d96bed 8697 }
5a5012ec 8698 opn = "swxc1";
93b12ccc 8699 store = 1;
5a5012ec
TS
8700 break;
8701 case OPC_SDXC1:
8c0ab41f
AJ
8702 check_cop1x(ctx);
8703 check_cp1_registers(ctx, fs);
b6d96bed 8704 {
a7812ae4 8705 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8706
8707 gen_load_fpr64(ctx, fp0, fs);
8708 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8709 tcg_temp_free_i64(fp0);
b6d96bed 8710 }
5a5012ec 8711 opn = "sdxc1";
93b12ccc 8712 store = 1;
5a5012ec
TS
8713 break;
8714 case OPC_SUXC1:
8c0ab41f 8715 check_cp1_64bitmode(ctx);
6c5c1e20 8716 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8717 {
a7812ae4 8718 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8719
8720 gen_load_fpr64(ctx, fp0, fs);
8721 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8722 tcg_temp_free_i64(fp0);
b6d96bed 8723 }
5a5012ec 8724 opn = "suxc1";
93b12ccc 8725 store = 1;
5a5012ec 8726 break;
5a5012ec 8727 }
6c5c1e20 8728 tcg_temp_free(t0);
2abf314d 8729 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8730 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8731 regnames[index], regnames[base]);
5a5012ec
TS
8732}
8733
5e755519
TS
8734static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8735 int fd, int fr, int fs, int ft)
5a5012ec 8736{
923617a3 8737 const char *opn = "flt3_arith";
5a5012ec 8738
5a5012ec
TS
8739 switch (opc) {
8740 case OPC_ALNV_PS:
b8aa4598 8741 check_cp1_64bitmode(ctx);
a16336e4 8742 {
a7812ae4 8743 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8744 TCGv_i32 fp = tcg_temp_new_i32();
8745 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8746 int l1 = gen_new_label();
8747 int l2 = gen_new_label();
8748
6c5c1e20
TS
8749 gen_load_gpr(t0, fr);
8750 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8751
8752 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac
AJ
8753 gen_load_fpr32(fp, fs);
8754 gen_load_fpr32h(fph, fs);
8755 gen_store_fpr32(fp, fd);
8756 gen_store_fpr32h(fph, fd);
a16336e4
TS
8757 tcg_gen_br(l2);
8758 gen_set_label(l1);
6c5c1e20
TS
8759 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8760 tcg_temp_free(t0);
a16336e4 8761#ifdef TARGET_WORDS_BIGENDIAN
c905fdac
AJ
8762 gen_load_fpr32(fp, fs);
8763 gen_load_fpr32h(fph, ft);
8764 gen_store_fpr32h(fp, fd);
8765 gen_store_fpr32(fph, fd);
a16336e4 8766#else
c905fdac
AJ
8767 gen_load_fpr32h(fph, fs);
8768 gen_load_fpr32(fp, ft);
8769 gen_store_fpr32(fph, fd);
8770 gen_store_fpr32h(fp, fd);
a16336e4
TS
8771#endif
8772 gen_set_label(l2);
c905fdac
AJ
8773 tcg_temp_free_i32(fp);
8774 tcg_temp_free_i32(fph);
a16336e4 8775 }
5a5012ec
TS
8776 opn = "alnv.ps";
8777 break;
8778 case OPC_MADD_S:
b8aa4598 8779 check_cop1x(ctx);
b6d96bed 8780 {
a7812ae4
PB
8781 TCGv_i32 fp0 = tcg_temp_new_i32();
8782 TCGv_i32 fp1 = tcg_temp_new_i32();
8783 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8784
8785 gen_load_fpr32(fp0, fs);
8786 gen_load_fpr32(fp1, ft);
8787 gen_load_fpr32(fp2, fr);
b3d6cd44 8788 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8789 tcg_temp_free_i32(fp0);
8790 tcg_temp_free_i32(fp1);
b6d96bed 8791 gen_store_fpr32(fp2, fd);
a7812ae4 8792 tcg_temp_free_i32(fp2);
b6d96bed 8793 }
5a5012ec
TS
8794 opn = "madd.s";
8795 break;
8796 case OPC_MADD_D:
b8aa4598
TS
8797 check_cop1x(ctx);
8798 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8799 {
a7812ae4
PB
8800 TCGv_i64 fp0 = tcg_temp_new_i64();
8801 TCGv_i64 fp1 = tcg_temp_new_i64();
8802 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8803
8804 gen_load_fpr64(ctx, fp0, fs);
8805 gen_load_fpr64(ctx, fp1, ft);
8806 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8807 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8808 tcg_temp_free_i64(fp0);
8809 tcg_temp_free_i64(fp1);
b6d96bed 8810 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8811 tcg_temp_free_i64(fp2);
b6d96bed 8812 }
5a5012ec
TS
8813 opn = "madd.d";
8814 break;
8815 case OPC_MADD_PS:
b8aa4598 8816 check_cp1_64bitmode(ctx);
b6d96bed 8817 {
a7812ae4
PB
8818 TCGv_i64 fp0 = tcg_temp_new_i64();
8819 TCGv_i64 fp1 = tcg_temp_new_i64();
8820 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8821
8822 gen_load_fpr64(ctx, fp0, fs);
8823 gen_load_fpr64(ctx, fp1, ft);
8824 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8825 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8826 tcg_temp_free_i64(fp0);
8827 tcg_temp_free_i64(fp1);
b6d96bed 8828 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8829 tcg_temp_free_i64(fp2);
b6d96bed 8830 }
5a5012ec
TS
8831 opn = "madd.ps";
8832 break;
8833 case OPC_MSUB_S:
b8aa4598 8834 check_cop1x(ctx);
b6d96bed 8835 {
a7812ae4
PB
8836 TCGv_i32 fp0 = tcg_temp_new_i32();
8837 TCGv_i32 fp1 = tcg_temp_new_i32();
8838 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8839
8840 gen_load_fpr32(fp0, fs);
8841 gen_load_fpr32(fp1, ft);
8842 gen_load_fpr32(fp2, fr);
b3d6cd44 8843 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8844 tcg_temp_free_i32(fp0);
8845 tcg_temp_free_i32(fp1);
b6d96bed 8846 gen_store_fpr32(fp2, fd);
a7812ae4 8847 tcg_temp_free_i32(fp2);
b6d96bed 8848 }
5a5012ec
TS
8849 opn = "msub.s";
8850 break;
8851 case OPC_MSUB_D:
b8aa4598
TS
8852 check_cop1x(ctx);
8853 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8854 {
a7812ae4
PB
8855 TCGv_i64 fp0 = tcg_temp_new_i64();
8856 TCGv_i64 fp1 = tcg_temp_new_i64();
8857 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8858
8859 gen_load_fpr64(ctx, fp0, fs);
8860 gen_load_fpr64(ctx, fp1, ft);
8861 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8862 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8863 tcg_temp_free_i64(fp0);
8864 tcg_temp_free_i64(fp1);
b6d96bed 8865 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8866 tcg_temp_free_i64(fp2);
b6d96bed 8867 }
5a5012ec
TS
8868 opn = "msub.d";
8869 break;
8870 case OPC_MSUB_PS:
b8aa4598 8871 check_cp1_64bitmode(ctx);
b6d96bed 8872 {
a7812ae4
PB
8873 TCGv_i64 fp0 = tcg_temp_new_i64();
8874 TCGv_i64 fp1 = tcg_temp_new_i64();
8875 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8876
8877 gen_load_fpr64(ctx, fp0, fs);
8878 gen_load_fpr64(ctx, fp1, ft);
8879 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8880 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8881 tcg_temp_free_i64(fp0);
8882 tcg_temp_free_i64(fp1);
b6d96bed 8883 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8884 tcg_temp_free_i64(fp2);
b6d96bed 8885 }
5a5012ec
TS
8886 opn = "msub.ps";
8887 break;
8888 case OPC_NMADD_S:
b8aa4598 8889 check_cop1x(ctx);
b6d96bed 8890 {
a7812ae4
PB
8891 TCGv_i32 fp0 = tcg_temp_new_i32();
8892 TCGv_i32 fp1 = tcg_temp_new_i32();
8893 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8894
8895 gen_load_fpr32(fp0, fs);
8896 gen_load_fpr32(fp1, ft);
8897 gen_load_fpr32(fp2, fr);
b3d6cd44 8898 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8899 tcg_temp_free_i32(fp0);
8900 tcg_temp_free_i32(fp1);
b6d96bed 8901 gen_store_fpr32(fp2, fd);
a7812ae4 8902 tcg_temp_free_i32(fp2);
b6d96bed 8903 }
5a5012ec
TS
8904 opn = "nmadd.s";
8905 break;
8906 case OPC_NMADD_D:
b8aa4598
TS
8907 check_cop1x(ctx);
8908 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8909 {
a7812ae4
PB
8910 TCGv_i64 fp0 = tcg_temp_new_i64();
8911 TCGv_i64 fp1 = tcg_temp_new_i64();
8912 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8913
8914 gen_load_fpr64(ctx, fp0, fs);
8915 gen_load_fpr64(ctx, fp1, ft);
8916 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8917 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8918 tcg_temp_free_i64(fp0);
8919 tcg_temp_free_i64(fp1);
b6d96bed 8920 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8921 tcg_temp_free_i64(fp2);
b6d96bed 8922 }
5a5012ec
TS
8923 opn = "nmadd.d";
8924 break;
8925 case OPC_NMADD_PS:
b8aa4598 8926 check_cp1_64bitmode(ctx);
b6d96bed 8927 {
a7812ae4
PB
8928 TCGv_i64 fp0 = tcg_temp_new_i64();
8929 TCGv_i64 fp1 = tcg_temp_new_i64();
8930 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8931
8932 gen_load_fpr64(ctx, fp0, fs);
8933 gen_load_fpr64(ctx, fp1, ft);
8934 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8935 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8936 tcg_temp_free_i64(fp0);
8937 tcg_temp_free_i64(fp1);
b6d96bed 8938 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8939 tcg_temp_free_i64(fp2);
b6d96bed 8940 }
5a5012ec
TS
8941 opn = "nmadd.ps";
8942 break;
8943 case OPC_NMSUB_S:
b8aa4598 8944 check_cop1x(ctx);
b6d96bed 8945 {
a7812ae4
PB
8946 TCGv_i32 fp0 = tcg_temp_new_i32();
8947 TCGv_i32 fp1 = tcg_temp_new_i32();
8948 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8949
8950 gen_load_fpr32(fp0, fs);
8951 gen_load_fpr32(fp1, ft);
8952 gen_load_fpr32(fp2, fr);
b3d6cd44 8953 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8954 tcg_temp_free_i32(fp0);
8955 tcg_temp_free_i32(fp1);
b6d96bed 8956 gen_store_fpr32(fp2, fd);
a7812ae4 8957 tcg_temp_free_i32(fp2);
b6d96bed 8958 }
5a5012ec
TS
8959 opn = "nmsub.s";
8960 break;
8961 case OPC_NMSUB_D:
b8aa4598
TS
8962 check_cop1x(ctx);
8963 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8964 {
a7812ae4
PB
8965 TCGv_i64 fp0 = tcg_temp_new_i64();
8966 TCGv_i64 fp1 = tcg_temp_new_i64();
8967 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8968
8969 gen_load_fpr64(ctx, fp0, fs);
8970 gen_load_fpr64(ctx, fp1, ft);
8971 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8972 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8973 tcg_temp_free_i64(fp0);
8974 tcg_temp_free_i64(fp1);
b6d96bed 8975 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8976 tcg_temp_free_i64(fp2);
b6d96bed 8977 }
5a5012ec
TS
8978 opn = "nmsub.d";
8979 break;
8980 case OPC_NMSUB_PS:
b8aa4598 8981 check_cp1_64bitmode(ctx);
b6d96bed 8982 {
a7812ae4
PB
8983 TCGv_i64 fp0 = tcg_temp_new_i64();
8984 TCGv_i64 fp1 = tcg_temp_new_i64();
8985 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8986
8987 gen_load_fpr64(ctx, fp0, fs);
8988 gen_load_fpr64(ctx, fp1, ft);
8989 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8990 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8991 tcg_temp_free_i64(fp0);
8992 tcg_temp_free_i64(fp1);
b6d96bed 8993 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8994 tcg_temp_free_i64(fp2);
b6d96bed 8995 }
5a5012ec
TS
8996 opn = "nmsub.ps";
8997 break;
923617a3
TS
8998 default:
8999 MIPS_INVAL(opn);
5a5012ec
TS
9000 generate_exception (ctx, EXCP_RI);
9001 return;
9002 }
2abf314d 9003 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9004 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9005 fregnames[fs], fregnames[ft]);
7a387fff
TS
9006}
9007
d75c135e 9008static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9009{
9010 TCGv t0;
9011
b3167288
RH
9012#if !defined(CONFIG_USER_ONLY)
9013 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9014 Therefore only check the ISA in system mode. */
d75c135e 9015 check_insn(ctx, ISA_MIPS32R2);
b3167288 9016#endif
26ebe468
NF
9017 t0 = tcg_temp_new();
9018
9019 switch (rd) {
9020 case 0:
9021 save_cpu_state(ctx, 1);
895c2d04 9022 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9023 gen_store_gpr(t0, rt);
9024 break;
9025 case 1:
9026 save_cpu_state(ctx, 1);
895c2d04 9027 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9028 gen_store_gpr(t0, rt);
9029 break;
9030 case 2:
9031 save_cpu_state(ctx, 1);
895c2d04 9032 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9033 gen_store_gpr(t0, rt);
9034 break;
9035 case 3:
9036 save_cpu_state(ctx, 1);
895c2d04 9037 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9038 gen_store_gpr(t0, rt);
9039 break;
9040 case 29:
9041#if defined(CONFIG_USER_ONLY)
7db13fae 9042 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
26ebe468
NF
9043 gen_store_gpr(t0, rt);
9044 break;
9045#else
9046 /* XXX: Some CPUs implement this in hardware.
9047 Not supported yet. */
9048#endif
9049 default: /* Invalid */
9050 MIPS_INVAL("rdhwr");
9051 generate_exception(ctx, EXCP_RI);
9052 break;
9053 }
9054 tcg_temp_free(t0);
9055}
9056
d75c135e 9057static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9058{
9059 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9060 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9061 /* Branches completion */
9062 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9063 ctx->bstate = BS_BRANCH;
9064 save_cpu_state(ctx, 0);
9065 /* FIXME: Need to clear can_do_io. */
364d4831 9066 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9067 case MIPS_HFLAG_B:
9068 /* unconditional branch */
9069 MIPS_DEBUG("unconditional branch");
364d4831
NF
9070 if (proc_hflags & MIPS_HFLAG_BX) {
9071 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9072 }
c9602061
NF
9073 gen_goto_tb(ctx, 0, ctx->btarget);
9074 break;
9075 case MIPS_HFLAG_BL:
9076 /* blikely taken case */
9077 MIPS_DEBUG("blikely branch taken");
9078 gen_goto_tb(ctx, 0, ctx->btarget);
9079 break;
9080 case MIPS_HFLAG_BC:
9081 /* Conditional branch */
9082 MIPS_DEBUG("conditional branch");
9083 {
9084 int l1 = gen_new_label();
9085
9086 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9087 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9088 gen_set_label(l1);
9089 gen_goto_tb(ctx, 0, ctx->btarget);
9090 }
9091 break;
9092 case MIPS_HFLAG_BR:
9093 /* unconditional branch to register */
9094 MIPS_DEBUG("branch to register");
d75c135e 9095 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9096 TCGv t0 = tcg_temp_new();
9097 TCGv_i32 t1 = tcg_temp_new_i32();
9098
9099 tcg_gen_andi_tl(t0, btarget, 0x1);
9100 tcg_gen_trunc_tl_i32(t1, t0);
9101 tcg_temp_free(t0);
9102 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9103 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9104 tcg_gen_or_i32(hflags, hflags, t1);
9105 tcg_temp_free_i32(t1);
9106
9107 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9108 } else {
9109 tcg_gen_mov_tl(cpu_PC, btarget);
9110 }
c9602061
NF
9111 if (ctx->singlestep_enabled) {
9112 save_cpu_state(ctx, 0);
895c2d04 9113 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9114 }
9115 tcg_gen_exit_tb(0);
9116 break;
9117 default:
9118 MIPS_DEBUG("unknown branch");
9119 break;
9120 }
9121 }
9122}
9123
7a387fff 9124/* ISA extensions (ASEs) */
6af0bf9c 9125/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9126
9127/* MIPS16 major opcodes */
9128enum {
9129 M16_OPC_ADDIUSP = 0x00,
9130 M16_OPC_ADDIUPC = 0x01,
9131 M16_OPC_B = 0x02,
9132 M16_OPC_JAL = 0x03,
9133 M16_OPC_BEQZ = 0x04,
9134 M16_OPC_BNEQZ = 0x05,
9135 M16_OPC_SHIFT = 0x06,
9136 M16_OPC_LD = 0x07,
9137 M16_OPC_RRIA = 0x08,
9138 M16_OPC_ADDIU8 = 0x09,
9139 M16_OPC_SLTI = 0x0a,
9140 M16_OPC_SLTIU = 0x0b,
9141 M16_OPC_I8 = 0x0c,
9142 M16_OPC_LI = 0x0d,
9143 M16_OPC_CMPI = 0x0e,
9144 M16_OPC_SD = 0x0f,
9145 M16_OPC_LB = 0x10,
9146 M16_OPC_LH = 0x11,
9147 M16_OPC_LWSP = 0x12,
9148 M16_OPC_LW = 0x13,
9149 M16_OPC_LBU = 0x14,
9150 M16_OPC_LHU = 0x15,
9151 M16_OPC_LWPC = 0x16,
9152 M16_OPC_LWU = 0x17,
9153 M16_OPC_SB = 0x18,
9154 M16_OPC_SH = 0x19,
9155 M16_OPC_SWSP = 0x1a,
9156 M16_OPC_SW = 0x1b,
9157 M16_OPC_RRR = 0x1c,
9158 M16_OPC_RR = 0x1d,
9159 M16_OPC_EXTEND = 0x1e,
9160 M16_OPC_I64 = 0x1f
9161};
9162
9163/* I8 funct field */
9164enum {
9165 I8_BTEQZ = 0x0,
9166 I8_BTNEZ = 0x1,
9167 I8_SWRASP = 0x2,
9168 I8_ADJSP = 0x3,
9169 I8_SVRS = 0x4,
9170 I8_MOV32R = 0x5,
9171 I8_MOVR32 = 0x7
9172};
9173
9174/* RRR f field */
9175enum {
9176 RRR_DADDU = 0x0,
9177 RRR_ADDU = 0x1,
9178 RRR_DSUBU = 0x2,
9179 RRR_SUBU = 0x3
9180};
9181
9182/* RR funct field */
9183enum {
9184 RR_JR = 0x00,
9185 RR_SDBBP = 0x01,
9186 RR_SLT = 0x02,
9187 RR_SLTU = 0x03,
9188 RR_SLLV = 0x04,
9189 RR_BREAK = 0x05,
9190 RR_SRLV = 0x06,
9191 RR_SRAV = 0x07,
9192 RR_DSRL = 0x08,
9193 RR_CMP = 0x0a,
9194 RR_NEG = 0x0b,
9195 RR_AND = 0x0c,
9196 RR_OR = 0x0d,
9197 RR_XOR = 0x0e,
9198 RR_NOT = 0x0f,
9199 RR_MFHI = 0x10,
9200 RR_CNVT = 0x11,
9201 RR_MFLO = 0x12,
9202 RR_DSRA = 0x13,
9203 RR_DSLLV = 0x14,
9204 RR_DSRLV = 0x16,
9205 RR_DSRAV = 0x17,
9206 RR_MULT = 0x18,
9207 RR_MULTU = 0x19,
9208 RR_DIV = 0x1a,
9209 RR_DIVU = 0x1b,
9210 RR_DMULT = 0x1c,
9211 RR_DMULTU = 0x1d,
9212 RR_DDIV = 0x1e,
9213 RR_DDIVU = 0x1f
9214};
9215
9216/* I64 funct field */
9217enum {
9218 I64_LDSP = 0x0,
9219 I64_SDSP = 0x1,
9220 I64_SDRASP = 0x2,
9221 I64_DADJSP = 0x3,
9222 I64_LDPC = 0x4,
364d4831 9223 I64_DADDIU5 = 0x5,
6ea219d0
NF
9224 I64_DADDIUPC = 0x6,
9225 I64_DADDIUSP = 0x7
9226};
9227
9228/* RR ry field for CNVT */
9229enum {
9230 RR_RY_CNVT_ZEB = 0x0,
9231 RR_RY_CNVT_ZEH = 0x1,
9232 RR_RY_CNVT_ZEW = 0x2,
9233 RR_RY_CNVT_SEB = 0x4,
9234 RR_RY_CNVT_SEH = 0x5,
9235 RR_RY_CNVT_SEW = 0x6,
9236};
9237
364d4831
NF
9238static int xlat (int r)
9239{
9240 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9241
9242 return map[r];
9243}
9244
9245static void gen_mips16_save (DisasContext *ctx,
9246 int xsregs, int aregs,
9247 int do_ra, int do_s0, int do_s1,
9248 int framesize)
9249{
9250 TCGv t0 = tcg_temp_new();
9251 TCGv t1 = tcg_temp_new();
9252 int args, astatic;
9253
9254 switch (aregs) {
9255 case 0:
9256 case 1:
9257 case 2:
9258 case 3:
9259 case 11:
9260 args = 0;
9261 break;
9262 case 4:
9263 case 5:
9264 case 6:
9265 case 7:
9266 args = 1;
9267 break;
9268 case 8:
9269 case 9:
9270 case 10:
9271 args = 2;
9272 break;
9273 case 12:
9274 case 13:
9275 args = 3;
9276 break;
9277 case 14:
9278 args = 4;
9279 break;
9280 default:
9281 generate_exception(ctx, EXCP_RI);
9282 return;
9283 }
9284
9285 switch (args) {
9286 case 4:
9287 gen_base_offset_addr(ctx, t0, 29, 12);
9288 gen_load_gpr(t1, 7);
2910c6cb 9289 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9290 /* Fall through */
9291 case 3:
9292 gen_base_offset_addr(ctx, t0, 29, 8);
9293 gen_load_gpr(t1, 6);
2910c6cb 9294 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9295 /* Fall through */
9296 case 2:
9297 gen_base_offset_addr(ctx, t0, 29, 4);
9298 gen_load_gpr(t1, 5);
2910c6cb 9299 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9300 /* Fall through */
9301 case 1:
9302 gen_base_offset_addr(ctx, t0, 29, 0);
9303 gen_load_gpr(t1, 4);
2910c6cb 9304 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9305 }
9306
9307 gen_load_gpr(t0, 29);
9308
9309#define DECR_AND_STORE(reg) do { \
9310 tcg_gen_subi_tl(t0, t0, 4); \
9311 gen_load_gpr(t1, reg); \
2910c6cb 9312 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
364d4831
NF
9313 } while (0)
9314
9315 if (do_ra) {
9316 DECR_AND_STORE(31);
9317 }
9318
9319 switch (xsregs) {
9320 case 7:
9321 DECR_AND_STORE(30);
9322 /* Fall through */
9323 case 6:
9324 DECR_AND_STORE(23);
9325 /* Fall through */
9326 case 5:
9327 DECR_AND_STORE(22);
9328 /* Fall through */
9329 case 4:
9330 DECR_AND_STORE(21);
9331 /* Fall through */
9332 case 3:
9333 DECR_AND_STORE(20);
9334 /* Fall through */
9335 case 2:
9336 DECR_AND_STORE(19);
9337 /* Fall through */
9338 case 1:
9339 DECR_AND_STORE(18);
9340 }
9341
9342 if (do_s1) {
9343 DECR_AND_STORE(17);
9344 }
9345 if (do_s0) {
9346 DECR_AND_STORE(16);
9347 }
9348
9349 switch (aregs) {
9350 case 0:
9351 case 4:
9352 case 8:
9353 case 12:
9354 case 14:
9355 astatic = 0;
9356 break;
9357 case 1:
9358 case 5:
9359 case 9:
9360 case 13:
9361 astatic = 1;
9362 break;
9363 case 2:
9364 case 6:
9365 case 10:
9366 astatic = 2;
9367 break;
9368 case 3:
9369 case 7:
9370 astatic = 3;
9371 break;
9372 case 11:
9373 astatic = 4;
9374 break;
9375 default:
9376 generate_exception(ctx, EXCP_RI);
9377 return;
9378 }
9379
9380 if (astatic > 0) {
9381 DECR_AND_STORE(7);
9382 if (astatic > 1) {
9383 DECR_AND_STORE(6);
9384 if (astatic > 2) {
9385 DECR_AND_STORE(5);
9386 if (astatic > 3) {
9387 DECR_AND_STORE(4);
9388 }
9389 }
9390 }
9391 }
9392#undef DECR_AND_STORE
9393
9394 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9395 tcg_temp_free(t0);
9396 tcg_temp_free(t1);
9397}
9398
9399static void gen_mips16_restore (DisasContext *ctx,
9400 int xsregs, int aregs,
9401 int do_ra, int do_s0, int do_s1,
9402 int framesize)
9403{
9404 int astatic;
9405 TCGv t0 = tcg_temp_new();
9406 TCGv t1 = tcg_temp_new();
9407
9408 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9409
2910c6cb
AJ
9410#define DECR_AND_LOAD(reg) do { \
9411 tcg_gen_subi_tl(t0, t0, 4); \
17e8fef1 9412 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
2910c6cb 9413 gen_store_gpr(t1, reg); \
364d4831
NF
9414 } while (0)
9415
9416 if (do_ra) {
9417 DECR_AND_LOAD(31);
9418 }
9419
9420 switch (xsregs) {
9421 case 7:
9422 DECR_AND_LOAD(30);
9423 /* Fall through */
9424 case 6:
9425 DECR_AND_LOAD(23);
9426 /* Fall through */
9427 case 5:
9428 DECR_AND_LOAD(22);
9429 /* Fall through */
9430 case 4:
9431 DECR_AND_LOAD(21);
9432 /* Fall through */
9433 case 3:
9434 DECR_AND_LOAD(20);
9435 /* Fall through */
9436 case 2:
9437 DECR_AND_LOAD(19);
9438 /* Fall through */
9439 case 1:
9440 DECR_AND_LOAD(18);
9441 }
9442
9443 if (do_s1) {
9444 DECR_AND_LOAD(17);
9445 }
9446 if (do_s0) {
9447 DECR_AND_LOAD(16);
9448 }
9449
9450 switch (aregs) {
9451 case 0:
9452 case 4:
9453 case 8:
9454 case 12:
9455 case 14:
9456 astatic = 0;
9457 break;
9458 case 1:
9459 case 5:
9460 case 9:
9461 case 13:
9462 astatic = 1;
9463 break;
9464 case 2:
9465 case 6:
9466 case 10:
9467 astatic = 2;
9468 break;
9469 case 3:
9470 case 7:
9471 astatic = 3;
9472 break;
9473 case 11:
9474 astatic = 4;
9475 break;
9476 default:
9477 generate_exception(ctx, EXCP_RI);
9478 return;
9479 }
9480
9481 if (astatic > 0) {
9482 DECR_AND_LOAD(7);
9483 if (astatic > 1) {
9484 DECR_AND_LOAD(6);
9485 if (astatic > 2) {
9486 DECR_AND_LOAD(5);
9487 if (astatic > 3) {
9488 DECR_AND_LOAD(4);
9489 }
9490 }
9491 }
9492 }
9493#undef DECR_AND_LOAD
9494
9495 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9496 tcg_temp_free(t0);
9497 tcg_temp_free(t1);
9498}
9499
9500static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9501 int is_64_bit, int extended)
9502{
9503 TCGv t0;
9504
9505 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9506 generate_exception(ctx, EXCP_RI);
9507 return;
9508 }
9509
9510 t0 = tcg_temp_new();
9511
9512 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9513 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9514 if (!is_64_bit) {
9515 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9516 }
9517
9518 tcg_temp_free(t0);
9519}
9520
9521#if defined(TARGET_MIPS64)
d75c135e 9522static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9523 int ry, int funct, int16_t offset,
9524 int extended)
9525{
9526 switch (funct) {
9527 case I64_LDSP:
9528 check_mips_64(ctx);
9529 offset = extended ? offset : offset << 3;
d75c135e 9530 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9531 break;
9532 case I64_SDSP:
9533 check_mips_64(ctx);
9534 offset = extended ? offset : offset << 3;
5c13fdfd 9535 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9536 break;
9537 case I64_SDRASP:
9538 check_mips_64(ctx);
9539 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9540 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9541 break;
9542 case I64_DADJSP:
9543 check_mips_64(ctx);
9544 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9545 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9546 break;
9547 case I64_LDPC:
9548 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9549 generate_exception(ctx, EXCP_RI);
9550 } else {
9551 offset = extended ? offset : offset << 3;
d75c135e 9552 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9553 }
9554 break;
9555 case I64_DADDIU5:
9556 check_mips_64(ctx);
9557 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9558 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9559 break;
9560 case I64_DADDIUPC:
9561 check_mips_64(ctx);
9562 offset = extended ? offset : offset << 2;
9563 gen_addiupc(ctx, ry, offset, 1, extended);
9564 break;
9565 case I64_DADDIUSP:
9566 check_mips_64(ctx);
9567 offset = extended ? offset : offset << 2;
d75c135e 9568 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9569 break;
9570 }
9571}
9572#endif
9573
7db13fae 9574static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9575 int *is_branch)
9576{
895c2d04 9577 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9578 int op, rx, ry, funct, sa;
9579 int16_t imm, offset;
9580
9581 ctx->opcode = (ctx->opcode << 16) | extend;
9582 op = (ctx->opcode >> 11) & 0x1f;
9583 sa = (ctx->opcode >> 22) & 0x1f;
9584 funct = (ctx->opcode >> 8) & 0x7;
9585 rx = xlat((ctx->opcode >> 8) & 0x7);
9586 ry = xlat((ctx->opcode >> 5) & 0x7);
9587 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9588 | ((ctx->opcode >> 21) & 0x3f) << 5
9589 | (ctx->opcode & 0x1f));
9590
9591 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9592 counterparts. */
9593 switch (op) {
9594 case M16_OPC_ADDIUSP:
d75c135e 9595 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9596 break;
9597 case M16_OPC_ADDIUPC:
9598 gen_addiupc(ctx, rx, imm, 0, 1);
9599 break;
9600 case M16_OPC_B:
9601 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9602 /* No delay slot, so just process as a normal instruction */
9603 break;
9604 case M16_OPC_BEQZ:
9605 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9606 /* No delay slot, so just process as a normal instruction */
9607 break;
9608 case M16_OPC_BNEQZ:
9609 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9610 /* No delay slot, so just process as a normal instruction */
9611 break;
9612 case M16_OPC_SHIFT:
9613 switch (ctx->opcode & 0x3) {
9614 case 0x0:
d75c135e 9615 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9616 break;
9617 case 0x1:
9618#if defined(TARGET_MIPS64)
9619 check_mips_64(ctx);
d75c135e 9620 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9621#else
9622 generate_exception(ctx, EXCP_RI);
9623#endif
9624 break;
9625 case 0x2:
d75c135e 9626 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9627 break;
9628 case 0x3:
d75c135e 9629 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9630 break;
9631 }
9632 break;
9633#if defined(TARGET_MIPS64)
9634 case M16_OPC_LD:
9635 check_mips_64(ctx);
d75c135e 9636 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9637 break;
9638#endif
9639 case M16_OPC_RRIA:
9640 imm = ctx->opcode & 0xf;
9641 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9642 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9643 imm = (int16_t) (imm << 1) >> 1;
9644 if ((ctx->opcode >> 4) & 0x1) {
9645#if defined(TARGET_MIPS64)
9646 check_mips_64(ctx);
d75c135e 9647 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9648#else
9649 generate_exception(ctx, EXCP_RI);
9650#endif
9651 } else {
d75c135e 9652 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9653 }
9654 break;
9655 case M16_OPC_ADDIU8:
d75c135e 9656 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9657 break;
9658 case M16_OPC_SLTI:
d75c135e 9659 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9660 break;
9661 case M16_OPC_SLTIU:
d75c135e 9662 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9663 break;
9664 case M16_OPC_I8:
9665 switch (funct) {
9666 case I8_BTEQZ:
9667 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9668 break;
9669 case I8_BTNEZ:
9670 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9671 break;
9672 case I8_SWRASP:
5c13fdfd 9673 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9674 break;
9675 case I8_ADJSP:
d75c135e 9676 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
9677 break;
9678 case I8_SVRS:
9679 {
9680 int xsregs = (ctx->opcode >> 24) & 0x7;
9681 int aregs = (ctx->opcode >> 16) & 0xf;
9682 int do_ra = (ctx->opcode >> 6) & 0x1;
9683 int do_s0 = (ctx->opcode >> 5) & 0x1;
9684 int do_s1 = (ctx->opcode >> 4) & 0x1;
9685 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9686 | (ctx->opcode & 0xf)) << 3;
9687
9688 if (ctx->opcode & (1 << 7)) {
9689 gen_mips16_save(ctx, xsregs, aregs,
9690 do_ra, do_s0, do_s1,
9691 framesize);
9692 } else {
9693 gen_mips16_restore(ctx, xsregs, aregs,
9694 do_ra, do_s0, do_s1,
9695 framesize);
9696 }
9697 }
9698 break;
9699 default:
9700 generate_exception(ctx, EXCP_RI);
9701 break;
9702 }
9703 break;
9704 case M16_OPC_LI:
9705 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9706 break;
9707 case M16_OPC_CMPI:
9708 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9709 break;
9710#if defined(TARGET_MIPS64)
9711 case M16_OPC_SD:
5c13fdfd 9712 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9713 break;
9714#endif
9715 case M16_OPC_LB:
d75c135e 9716 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9717 break;
9718 case M16_OPC_LH:
d75c135e 9719 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9720 break;
9721 case M16_OPC_LWSP:
d75c135e 9722 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9723 break;
9724 case M16_OPC_LW:
d75c135e 9725 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9726 break;
9727 case M16_OPC_LBU:
d75c135e 9728 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9729 break;
9730 case M16_OPC_LHU:
d75c135e 9731 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9732 break;
9733 case M16_OPC_LWPC:
d75c135e 9734 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9735 break;
9736#if defined(TARGET_MIPS64)
9737 case M16_OPC_LWU:
d75c135e 9738 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9739 break;
9740#endif
9741 case M16_OPC_SB:
5c13fdfd 9742 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9743 break;
9744 case M16_OPC_SH:
5c13fdfd 9745 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9746 break;
9747 case M16_OPC_SWSP:
5c13fdfd 9748 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9749 break;
9750 case M16_OPC_SW:
5c13fdfd 9751 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9752 break;
9753#if defined(TARGET_MIPS64)
9754 case M16_OPC_I64:
d75c135e 9755 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
9756 break;
9757#endif
9758 default:
9759 generate_exception(ctx, EXCP_RI);
9760 break;
9761 }
9762
9763 return 4;
9764}
9765
7db13fae 9766static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9767 int *is_branch)
9768{
9769 int rx, ry;
9770 int sa;
9771 int op, cnvt_op, op1, offset;
9772 int funct;
9773 int n_bytes;
9774
9775 op = (ctx->opcode >> 11) & 0x1f;
9776 sa = (ctx->opcode >> 2) & 0x7;
9777 sa = sa == 0 ? 8 : sa;
9778 rx = xlat((ctx->opcode >> 8) & 0x7);
9779 cnvt_op = (ctx->opcode >> 5) & 0x7;
9780 ry = xlat((ctx->opcode >> 5) & 0x7);
9781 op1 = offset = ctx->opcode & 0x1f;
9782
9783 n_bytes = 2;
9784
9785 switch (op) {
9786 case M16_OPC_ADDIUSP:
9787 {
9788 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9789
d75c135e 9790 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9791 }
9792 break;
9793 case M16_OPC_ADDIUPC:
9794 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9795 break;
9796 case M16_OPC_B:
9797 offset = (ctx->opcode & 0x7ff) << 1;
9798 offset = (int16_t)(offset << 4) >> 4;
9799 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9800 /* No delay slot, so just process as a normal instruction */
9801 break;
9802 case M16_OPC_JAL:
895c2d04 9803 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9804 offset = (((ctx->opcode & 0x1f) << 21)
9805 | ((ctx->opcode >> 5) & 0x1f) << 16
9806 | offset) << 2;
620e48f6 9807 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9808 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9809 n_bytes = 4;
9810 *is_branch = 1;
9811 break;
9812 case M16_OPC_BEQZ:
9813 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9814 /* No delay slot, so just process as a normal instruction */
9815 break;
9816 case M16_OPC_BNEQZ:
9817 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9818 /* No delay slot, so just process as a normal instruction */
9819 break;
9820 case M16_OPC_SHIFT:
9821 switch (ctx->opcode & 0x3) {
9822 case 0x0:
d75c135e 9823 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9824 break;
9825 case 0x1:
9826#if defined(TARGET_MIPS64)
9827 check_mips_64(ctx);
d75c135e 9828 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9829#else
9830 generate_exception(ctx, EXCP_RI);
9831#endif
9832 break;
9833 case 0x2:
d75c135e 9834 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9835 break;
9836 case 0x3:
d75c135e 9837 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9838 break;
9839 }
9840 break;
9841#if defined(TARGET_MIPS64)
9842 case M16_OPC_LD:
9843 check_mips_64(ctx);
d75c135e 9844 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9845 break;
9846#endif
9847 case M16_OPC_RRIA:
9848 {
9849 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9850
9851 if ((ctx->opcode >> 4) & 1) {
9852#if defined(TARGET_MIPS64)
9853 check_mips_64(ctx);
d75c135e 9854 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9855#else
9856 generate_exception(ctx, EXCP_RI);
9857#endif
9858 } else {
d75c135e 9859 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9860 }
9861 }
9862 break;
9863 case M16_OPC_ADDIU8:
9864 {
9865 int16_t imm = (int8_t) ctx->opcode;
9866
d75c135e 9867 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9868 }
9869 break;
9870 case M16_OPC_SLTI:
9871 {
9872 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9873 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9874 }
9875 break;
9876 case M16_OPC_SLTIU:
9877 {
9878 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9879 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9880 }
9881 break;
9882 case M16_OPC_I8:
9883 {
9884 int reg32;
9885
9886 funct = (ctx->opcode >> 8) & 0x7;
9887 switch (funct) {
9888 case I8_BTEQZ:
9889 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9890 ((int8_t)ctx->opcode) << 1);
9891 break;
9892 case I8_BTNEZ:
9893 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9894 ((int8_t)ctx->opcode) << 1);
9895 break;
9896 case I8_SWRASP:
5c13fdfd 9897 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9898 break;
9899 case I8_ADJSP:
d75c135e 9900 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
9901 ((int8_t)ctx->opcode) << 3);
9902 break;
9903 case I8_SVRS:
9904 {
9905 int do_ra = ctx->opcode & (1 << 6);
9906 int do_s0 = ctx->opcode & (1 << 5);
9907 int do_s1 = ctx->opcode & (1 << 4);
9908 int framesize = ctx->opcode & 0xf;
9909
9910 if (framesize == 0) {
9911 framesize = 128;
9912 } else {
9913 framesize = framesize << 3;
9914 }
9915
9916 if (ctx->opcode & (1 << 7)) {
9917 gen_mips16_save(ctx, 0, 0,
9918 do_ra, do_s0, do_s1, framesize);
9919 } else {
9920 gen_mips16_restore(ctx, 0, 0,
9921 do_ra, do_s0, do_s1, framesize);
9922 }
9923 }
9924 break;
9925 case I8_MOV32R:
9926 {
9927 int rz = xlat(ctx->opcode & 0x7);
9928
9929 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9930 ((ctx->opcode >> 5) & 0x7);
d75c135e 9931 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
9932 }
9933 break;
9934 case I8_MOVR32:
9935 reg32 = ctx->opcode & 0x1f;
d75c135e 9936 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
9937 break;
9938 default:
9939 generate_exception(ctx, EXCP_RI);
9940 break;
9941 }
9942 }
9943 break;
9944 case M16_OPC_LI:
9945 {
9946 int16_t imm = (uint8_t) ctx->opcode;
9947
d75c135e 9948 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
9949 }
9950 break;
9951 case M16_OPC_CMPI:
9952 {
9953 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9954 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
9955 }
9956 break;
9957#if defined(TARGET_MIPS64)
9958 case M16_OPC_SD:
9959 check_mips_64(ctx);
5c13fdfd 9960 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
9961 break;
9962#endif
9963 case M16_OPC_LB:
d75c135e 9964 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9965 break;
9966 case M16_OPC_LH:
d75c135e 9967 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
9968 break;
9969 case M16_OPC_LWSP:
d75c135e 9970 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
9971 break;
9972 case M16_OPC_LW:
d75c135e 9973 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
9974 break;
9975 case M16_OPC_LBU:
d75c135e 9976 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9977 break;
9978 case M16_OPC_LHU:
d75c135e 9979 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
9980 break;
9981 case M16_OPC_LWPC:
d75c135e 9982 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
9983 break;
9984#if defined (TARGET_MIPS64)
9985 case M16_OPC_LWU:
9986 check_mips_64(ctx);
d75c135e 9987 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
9988 break;
9989#endif
9990 case M16_OPC_SB:
5c13fdfd 9991 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9992 break;
9993 case M16_OPC_SH:
5c13fdfd 9994 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
9995 break;
9996 case M16_OPC_SWSP:
5c13fdfd 9997 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
9998 break;
9999 case M16_OPC_SW:
5c13fdfd 10000 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10001 break;
10002 case M16_OPC_RRR:
10003 {
10004 int rz = xlat((ctx->opcode >> 2) & 0x7);
10005 int mips32_op;
10006
10007 switch (ctx->opcode & 0x3) {
10008 case RRR_ADDU:
10009 mips32_op = OPC_ADDU;
10010 break;
10011 case RRR_SUBU:
10012 mips32_op = OPC_SUBU;
10013 break;
10014#if defined(TARGET_MIPS64)
10015 case RRR_DADDU:
10016 mips32_op = OPC_DADDU;
10017 check_mips_64(ctx);
10018 break;
10019 case RRR_DSUBU:
10020 mips32_op = OPC_DSUBU;
10021 check_mips_64(ctx);
10022 break;
10023#endif
10024 default:
10025 generate_exception(ctx, EXCP_RI);
10026 goto done;
10027 }
10028
d75c135e 10029 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10030 done:
10031 ;
10032 }
10033 break;
10034 case M16_OPC_RR:
10035 switch (op1) {
10036 case RR_JR:
10037 {
10038 int nd = (ctx->opcode >> 7) & 0x1;
10039 int link = (ctx->opcode >> 6) & 0x1;
10040 int ra = (ctx->opcode >> 5) & 0x1;
10041
10042 if (link) {
620e48f6 10043 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10044 } else {
10045 op = OPC_JR;
10046 }
10047
10048 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10049 if (!nd) {
10050 *is_branch = 1;
10051 }
10052 }
10053 break;
10054 case RR_SDBBP:
10055 /* XXX: not clear which exception should be raised
10056 * when in debug mode...
10057 */
d75c135e 10058 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10059 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10060 generate_exception(ctx, EXCP_DBp);
10061 } else {
10062 generate_exception(ctx, EXCP_DBp);
10063 }
10064 break;
10065 case RR_SLT:
d75c135e 10066 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10067 break;
10068 case RR_SLTU:
d75c135e 10069 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10070 break;
10071 case RR_BREAK:
10072 generate_exception(ctx, EXCP_BREAK);
10073 break;
10074 case RR_SLLV:
d75c135e 10075 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10076 break;
10077 case RR_SRLV:
d75c135e 10078 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10079 break;
10080 case RR_SRAV:
d75c135e 10081 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10082 break;
10083#if defined (TARGET_MIPS64)
10084 case RR_DSRL:
10085 check_mips_64(ctx);
d75c135e 10086 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10087 break;
10088#endif
10089 case RR_CMP:
d75c135e 10090 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10091 break;
10092 case RR_NEG:
d75c135e 10093 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10094 break;
10095 case RR_AND:
d75c135e 10096 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10097 break;
10098 case RR_OR:
d75c135e 10099 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10100 break;
10101 case RR_XOR:
d75c135e 10102 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10103 break;
10104 case RR_NOT:
d75c135e 10105 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10106 break;
10107 case RR_MFHI:
26135ead 10108 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
10109 break;
10110 case RR_CNVT:
10111 switch (cnvt_op) {
10112 case RR_RY_CNVT_ZEB:
10113 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10114 break;
10115 case RR_RY_CNVT_ZEH:
10116 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10117 break;
10118 case RR_RY_CNVT_SEB:
10119 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10120 break;
10121 case RR_RY_CNVT_SEH:
10122 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10123 break;
10124#if defined (TARGET_MIPS64)
10125 case RR_RY_CNVT_ZEW:
10126 check_mips_64(ctx);
10127 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10128 break;
10129 case RR_RY_CNVT_SEW:
10130 check_mips_64(ctx);
10131 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10132 break;
10133#endif
10134 default:
10135 generate_exception(ctx, EXCP_RI);
10136 break;
10137 }
10138 break;
10139 case RR_MFLO:
26135ead 10140 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
10141 break;
10142#if defined (TARGET_MIPS64)
10143 case RR_DSRA:
10144 check_mips_64(ctx);
d75c135e 10145 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10146 break;
10147 case RR_DSLLV:
10148 check_mips_64(ctx);
d75c135e 10149 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10150 break;
10151 case RR_DSRLV:
10152 check_mips_64(ctx);
d75c135e 10153 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10154 break;
10155 case RR_DSRAV:
10156 check_mips_64(ctx);
d75c135e 10157 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10158 break;
10159#endif
10160 case RR_MULT:
26135ead 10161 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
10162 break;
10163 case RR_MULTU:
26135ead 10164 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
10165 break;
10166 case RR_DIV:
26135ead 10167 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
10168 break;
10169 case RR_DIVU:
26135ead 10170 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
10171 break;
10172#if defined (TARGET_MIPS64)
10173 case RR_DMULT:
10174 check_mips_64(ctx);
26135ead 10175 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
10176 break;
10177 case RR_DMULTU:
10178 check_mips_64(ctx);
26135ead 10179 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
10180 break;
10181 case RR_DDIV:
10182 check_mips_64(ctx);
26135ead 10183 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
10184 break;
10185 case RR_DDIVU:
10186 check_mips_64(ctx);
26135ead 10187 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
10188 break;
10189#endif
10190 default:
10191 generate_exception(ctx, EXCP_RI);
10192 break;
10193 }
10194 break;
10195 case M16_OPC_EXTEND:
10196 decode_extended_mips16_opc(env, ctx, is_branch);
10197 n_bytes = 4;
10198 break;
10199#if defined(TARGET_MIPS64)
10200 case M16_OPC_I64:
10201 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10202 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10203 break;
10204#endif
10205 default:
10206 generate_exception(ctx, EXCP_RI);
10207 break;
10208 }
10209
10210 return n_bytes;
10211}
10212
211da992 10213/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10214
211da992
WRC
10215/*
10216 * microMIPS32/microMIPS64 major opcodes
10217 *
10218 * 1. MIPS Architecture for Programmers Volume II-B:
10219 * The microMIPS32 Instruction Set (Revision 3.05)
10220 *
10221 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10222 *
10223 * 2. MIPS Architecture For Programmers Volume II-A:
10224 * The MIPS64 Instruction Set (Revision 3.51)
10225 */
6af0bf9c 10226
3c824109
NF
10227enum {
10228 POOL32A = 0x00,
10229 POOL16A = 0x01,
10230 LBU16 = 0x02,
10231 MOVE16 = 0x03,
10232 ADDI32 = 0x04,
10233 LBU32 = 0x05,
10234 SB32 = 0x06,
10235 LB32 = 0x07,
10236
10237 POOL32B = 0x08,
10238 POOL16B = 0x09,
10239 LHU16 = 0x0a,
10240 ANDI16 = 0x0b,
10241 ADDIU32 = 0x0c,
10242 LHU32 = 0x0d,
10243 SH32 = 0x0e,
10244 LH32 = 0x0f,
10245
10246 POOL32I = 0x10,
10247 POOL16C = 0x11,
10248 LWSP16 = 0x12,
10249 POOL16D = 0x13,
10250 ORI32 = 0x14,
10251 POOL32F = 0x15,
211da992
WRC
10252 POOL32S = 0x16, /* MIPS64 */
10253 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10254
211da992 10255 /* 0x1f is reserved */
3c824109
NF
10256 POOL32C = 0x18,
10257 LWGP16 = 0x19,
10258 LW16 = 0x1a,
10259 POOL16E = 0x1b,
10260 XORI32 = 0x1c,
10261 JALS32 = 0x1d,
10262 ADDIUPC = 0x1e,
3c824109
NF
10263
10264 /* 0x20 is reserved */
10265 RES_20 = 0x20,
10266 POOL16F = 0x21,
10267 SB16 = 0x22,
10268 BEQZ16 = 0x23,
10269 SLTI32 = 0x24,
10270 BEQ32 = 0x25,
10271 SWC132 = 0x26,
10272 LWC132 = 0x27,
10273
10274 /* 0x28 and 0x29 are reserved */
10275 RES_28 = 0x28,
10276 RES_29 = 0x29,
10277 SH16 = 0x2a,
10278 BNEZ16 = 0x2b,
10279 SLTIU32 = 0x2c,
10280 BNE32 = 0x2d,
10281 SDC132 = 0x2e,
10282 LDC132 = 0x2f,
10283
10284 /* 0x30 and 0x31 are reserved */
10285 RES_30 = 0x30,
10286 RES_31 = 0x31,
10287 SWSP16 = 0x32,
10288 B16 = 0x33,
10289 ANDI32 = 0x34,
10290 J32 = 0x35,
211da992
WRC
10291 SD32 = 0x36, /* MIPS64 */
10292 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10293
10294 /* 0x38 and 0x39 are reserved */
10295 RES_38 = 0x38,
10296 RES_39 = 0x39,
10297 SW16 = 0x3a,
10298 LI16 = 0x3b,
10299 JALX32 = 0x3c,
10300 JAL32 = 0x3d,
10301 SW32 = 0x3e,
10302 LW32 = 0x3f
10303};
10304
10305/* POOL32A encoding of minor opcode field */
10306
10307enum {
10308 /* These opcodes are distinguished only by bits 9..6; those bits are
10309 * what are recorded below. */
10310 SLL32 = 0x0,
10311 SRL32 = 0x1,
10312 SRA = 0x2,
10313 ROTR = 0x3,
10314
10315 SLLV = 0x0,
10316 SRLV = 0x1,
10317 SRAV = 0x2,
10318 ROTRV = 0x3,
10319 ADD = 0x4,
10320 ADDU32 = 0x5,
10321 SUB = 0x6,
10322 SUBU32 = 0x7,
10323 MUL = 0x8,
10324 AND = 0x9,
10325 OR32 = 0xa,
10326 NOR = 0xb,
10327 XOR32 = 0xc,
10328 SLT = 0xd,
10329 SLTU = 0xe,
10330
10331 MOVN = 0x0,
10332 MOVZ = 0x1,
10333 LWXS = 0x4,
10334
10335 /* The following can be distinguished by their lower 6 bits. */
10336 INS = 0x0c,
10337 EXT = 0x2c,
10338 POOL32AXF = 0x3c
10339};
10340
10341/* POOL32AXF encoding of minor opcode field extension */
10342
d132c79f
WRC
10343/*
10344 * 1. MIPS Architecture for Programmers Volume II-B:
10345 * The microMIPS32 Instruction Set (Revision 3.05)
10346 *
10347 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10348 *
10349 * 2. MIPS Architecture for Programmers VolumeIV-e:
10350 * The MIPS DSP Application-Specific Extension
10351 * to the microMIPS32 Architecture (Revision 2.34)
10352 *
10353 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10354 */
10355
3c824109
NF
10356enum {
10357 /* bits 11..6 */
10358 TEQ = 0x00,
10359 TGE = 0x08,
10360 TGEU = 0x10,
10361 TLT = 0x20,
10362 TLTU = 0x28,
10363 TNE = 0x30,
10364
10365 MFC0 = 0x03,
10366 MTC0 = 0x0b,
10367
d132c79f
WRC
10368 /* begin of microMIPS32 DSP */
10369
3c824109
NF
10370 /* bits 13..12 for 0x01 */
10371 MFHI_ACC = 0x0,
10372 MFLO_ACC = 0x1,
10373 MTHI_ACC = 0x2,
10374 MTLO_ACC = 0x3,
10375
10376 /* bits 13..12 for 0x2a */
10377 MADD_ACC = 0x0,
10378 MADDU_ACC = 0x1,
10379 MSUB_ACC = 0x2,
10380 MSUBU_ACC = 0x3,
10381
10382 /* bits 13..12 for 0x32 */
10383 MULT_ACC = 0x0,
6801038b 10384 MULTU_ACC = 0x1,
3c824109 10385
d132c79f
WRC
10386 /* end of microMIPS32 DSP */
10387
3c824109
NF
10388 /* bits 15..12 for 0x2c */
10389 SEB = 0x2,
10390 SEH = 0x3,
10391 CLO = 0x4,
10392 CLZ = 0x5,
10393 RDHWR = 0x6,
10394 WSBH = 0x7,
10395 MULT = 0x8,
10396 MULTU = 0x9,
10397 DIV = 0xa,
10398 DIVU = 0xb,
10399 MADD = 0xc,
10400 MADDU = 0xd,
10401 MSUB = 0xe,
10402 MSUBU = 0xf,
10403
10404 /* bits 15..12 for 0x34 */
10405 MFC2 = 0x4,
10406 MTC2 = 0x5,
10407 MFHC2 = 0x8,
10408 MTHC2 = 0x9,
10409 CFC2 = 0xc,
10410 CTC2 = 0xd,
10411
10412 /* bits 15..12 for 0x3c */
10413 JALR = 0x0,
10414 JR = 0x0, /* alias */
10415 JALR_HB = 0x1,
10416 JALRS = 0x4,
10417 JALRS_HB = 0x5,
10418
10419 /* bits 15..12 for 0x05 */
10420 RDPGPR = 0xe,
10421 WRPGPR = 0xf,
10422
10423 /* bits 15..12 for 0x0d */
10424 TLBP = 0x0,
10425 TLBR = 0x1,
10426 TLBWI = 0x2,
10427 TLBWR = 0x3,
10428 WAIT = 0x9,
10429 IRET = 0xd,
10430 DERET = 0xe,
10431 ERET = 0xf,
10432
10433 /* bits 15..12 for 0x15 */
10434 DMT = 0x0,
10435 DVPE = 0x1,
10436 EMT = 0x2,
10437 EVPE = 0x3,
10438
10439 /* bits 15..12 for 0x1d */
10440 DI = 0x4,
10441 EI = 0x5,
10442
10443 /* bits 15..12 for 0x2d */
10444 SYNC = 0x6,
10445 SYSCALL = 0x8,
10446 SDBBP = 0xd,
10447
10448 /* bits 15..12 for 0x35 */
10449 MFHI32 = 0x0,
10450 MFLO32 = 0x1,
10451 MTHI32 = 0x2,
10452 MTLO32 = 0x3,
10453};
10454
10455/* POOL32B encoding of minor opcode field (bits 15..12) */
10456
10457enum {
10458 LWC2 = 0x0,
10459 LWP = 0x1,
10460 LDP = 0x4,
10461 LWM32 = 0x5,
10462 CACHE = 0x6,
10463 LDM = 0x7,
10464 SWC2 = 0x8,
10465 SWP = 0x9,
10466 SDP = 0xc,
10467 SWM32 = 0xd,
10468 SDM = 0xf
10469};
10470
10471/* POOL32C encoding of minor opcode field (bits 15..12) */
10472
10473enum {
10474 LWL = 0x0,
10475 SWL = 0x8,
10476 LWR = 0x1,
10477 SWR = 0x9,
10478 PREF = 0x2,
10479 /* 0xa is reserved */
10480 LL = 0x3,
10481 SC = 0xb,
10482 LDL = 0x4,
10483 SDL = 0xc,
10484 LDR = 0x5,
10485 SDR = 0xd,
10486 /* 0x6 is reserved */
10487 LWU = 0xe,
10488 LLD = 0x7,
10489 SCD = 0xf
10490};
10491
10492/* POOL32F encoding of minor opcode field (bits 5..0) */
10493
10494enum {
10495 /* These are the bit 7..6 values */
10496 ADD_FMT = 0x0,
10497 MOVN_FMT = 0x0,
10498
10499 SUB_FMT = 0x1,
10500 MOVZ_FMT = 0x1,
10501
10502 MUL_FMT = 0x2,
10503
10504 DIV_FMT = 0x3,
10505
10506 /* These are the bit 8..6 values */
10507 RSQRT2_FMT = 0x0,
10508 MOVF_FMT = 0x0,
10509
10510 LWXC1 = 0x1,
10511 MOVT_FMT = 0x1,
10512
10513 PLL_PS = 0x2,
10514 SWXC1 = 0x2,
10515
10516 PLU_PS = 0x3,
10517 LDXC1 = 0x3,
10518
10519 PUL_PS = 0x4,
10520 SDXC1 = 0x4,
10521 RECIP2_FMT = 0x4,
10522
10523 PUU_PS = 0x5,
10524 LUXC1 = 0x5,
10525
10526 CVT_PS_S = 0x6,
10527 SUXC1 = 0x6,
10528 ADDR_PS = 0x6,
10529 PREFX = 0x6,
10530
10531 MULR_PS = 0x7,
10532
10533 MADD_S = 0x01,
10534 MADD_D = 0x09,
10535 MADD_PS = 0x11,
10536 ALNV_PS = 0x19,
10537 MSUB_S = 0x21,
10538 MSUB_D = 0x29,
10539 MSUB_PS = 0x31,
10540
10541 NMADD_S = 0x02,
10542 NMADD_D = 0x0a,
10543 NMADD_PS = 0x12,
10544 NMSUB_S = 0x22,
10545 NMSUB_D = 0x2a,
10546 NMSUB_PS = 0x32,
10547
10548 POOL32FXF = 0x3b,
10549
10550 CABS_COND_FMT = 0x1c, /* MIPS3D */
10551 C_COND_FMT = 0x3c
10552};
10553
10554/* POOL32Fxf encoding of minor opcode extension field */
10555
10556enum {
10557 CVT_L = 0x04,
10558 RSQRT_FMT = 0x08,
10559 FLOOR_L = 0x0c,
10560 CVT_PW_PS = 0x1c,
10561 CVT_W = 0x24,
10562 SQRT_FMT = 0x28,
10563 FLOOR_W = 0x2c,
10564 CVT_PS_PW = 0x3c,
10565 CFC1 = 0x40,
10566 RECIP_FMT = 0x48,
10567 CEIL_L = 0x4c,
10568 CTC1 = 0x60,
10569 CEIL_W = 0x6c,
10570 MFC1 = 0x80,
10571 CVT_S_PL = 0x84,
10572 TRUNC_L = 0x8c,
10573 MTC1 = 0xa0,
10574 CVT_S_PU = 0xa4,
10575 TRUNC_W = 0xac,
10576 MFHC1 = 0xc0,
10577 ROUND_L = 0xcc,
10578 MTHC1 = 0xe0,
10579 ROUND_W = 0xec,
10580
10581 MOV_FMT = 0x01,
10582 MOVF = 0x05,
10583 ABS_FMT = 0x0d,
10584 RSQRT1_FMT = 0x1d,
10585 MOVT = 0x25,
10586 NEG_FMT = 0x2d,
10587 CVT_D = 0x4d,
10588 RECIP1_FMT = 0x5d,
10589 CVT_S = 0x6d
10590};
10591
10592/* POOL32I encoding of minor opcode field (bits 25..21) */
10593
10594enum {
10595 BLTZ = 0x00,
10596 BLTZAL = 0x01,
10597 BGEZ = 0x02,
10598 BGEZAL = 0x03,
10599 BLEZ = 0x04,
10600 BNEZC = 0x05,
10601 BGTZ = 0x06,
10602 BEQZC = 0x07,
10603 TLTI = 0x08,
10604 TGEI = 0x09,
10605 TLTIU = 0x0a,
10606 TGEIU = 0x0b,
10607 TNEI = 0x0c,
10608 LUI = 0x0d,
10609 TEQI = 0x0e,
10610 SYNCI = 0x10,
10611 BLTZALS = 0x11,
10612 BGEZALS = 0x13,
10613 BC2F = 0x14,
10614 BC2T = 0x15,
10615 BPOSGE64 = 0x1a,
10616 BPOSGE32 = 0x1b,
10617 /* These overlap and are distinguished by bit16 of the instruction */
10618 BC1F = 0x1c,
10619 BC1T = 0x1d,
10620 BC1ANY2F = 0x1c,
10621 BC1ANY2T = 0x1d,
10622 BC1ANY4F = 0x1e,
10623 BC1ANY4T = 0x1f
10624};
10625
10626/* POOL16A encoding of minor opcode field */
10627
10628enum {
10629 ADDU16 = 0x0,
10630 SUBU16 = 0x1
10631};
10632
10633/* POOL16B encoding of minor opcode field */
10634
10635enum {
10636 SLL16 = 0x0,
10637 SRL16 = 0x1
10638};
10639
10640/* POOL16C encoding of minor opcode field */
10641
10642enum {
10643 NOT16 = 0x00,
10644 XOR16 = 0x04,
10645 AND16 = 0x08,
10646 OR16 = 0x0c,
10647 LWM16 = 0x10,
10648 SWM16 = 0x14,
10649 JR16 = 0x18,
10650 JRC16 = 0x1a,
10651 JALR16 = 0x1c,
10652 JALR16S = 0x1e,
10653 MFHI16 = 0x20,
10654 MFLO16 = 0x24,
10655 BREAK16 = 0x28,
10656 SDBBP16 = 0x2c,
10657 JRADDIUSP = 0x30
10658};
10659
10660/* POOL16D encoding of minor opcode field */
10661
10662enum {
10663 ADDIUS5 = 0x0,
10664 ADDIUSP = 0x1
10665};
10666
10667/* POOL16E encoding of minor opcode field */
10668
10669enum {
10670 ADDIUR2 = 0x0,
10671 ADDIUR1SP = 0x1
10672};
10673
10674static int mmreg (int r)
10675{
10676 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10677
10678 return map[r];
10679}
10680
10681/* Used for 16-bit store instructions. */
10682static int mmreg2 (int r)
10683{
10684 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10685
10686 return map[r];
10687}
10688
10689#define uMIPS_RD(op) ((op >> 7) & 0x7)
10690#define uMIPS_RS(op) ((op >> 4) & 0x7)
10691#define uMIPS_RS2(op) uMIPS_RS(op)
10692#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10693#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10694#define uMIPS_RS5(op) (op & 0x1f)
10695
10696/* Signed immediate */
10697#define SIMM(op, start, width) \
10698 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10699 << (32-width)) \
10700 >> (32-width))
10701/* Zero-extended immediate */
10702#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10703
d75c135e 10704static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
10705{
10706 int rd = mmreg(uMIPS_RD(ctx->opcode));
10707
d75c135e 10708 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
10709}
10710
d75c135e 10711static void gen_addiur2(DisasContext *ctx)
3c824109
NF
10712{
10713 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10714 int rd = mmreg(uMIPS_RD(ctx->opcode));
10715 int rs = mmreg(uMIPS_RS(ctx->opcode));
10716
d75c135e 10717 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
10718}
10719
d75c135e 10720static void gen_addiusp(DisasContext *ctx)
3c824109
NF
10721{
10722 int encoded = ZIMM(ctx->opcode, 1, 9);
10723 int decoded;
10724
10725 if (encoded <= 1) {
10726 decoded = 256 + encoded;
10727 } else if (encoded <= 255) {
10728 decoded = encoded;
10729 } else if (encoded <= 509) {
10730 decoded = encoded - 512;
10731 } else {
10732 decoded = encoded - 768;
10733 }
10734
d75c135e 10735 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
10736}
10737
d75c135e 10738static void gen_addius5(DisasContext *ctx)
3c824109
NF
10739{
10740 int imm = SIMM(ctx->opcode, 1, 4);
10741 int rd = (ctx->opcode >> 5) & 0x1f;
10742
d75c135e 10743 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
10744}
10745
d75c135e 10746static void gen_andi16(DisasContext *ctx)
3c824109
NF
10747{
10748 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10749 31, 32, 63, 64, 255, 32768, 65535 };
10750 int rd = mmreg(uMIPS_RD(ctx->opcode));
10751 int rs = mmreg(uMIPS_RS(ctx->opcode));
10752 int encoded = ZIMM(ctx->opcode, 0, 4);
10753
d75c135e 10754 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10755}
10756
10757static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10758 int base, int16_t offset)
10759{
e1050a76 10760 const char *opn = "ldst_multiple";
3c824109
NF
10761 TCGv t0, t1;
10762 TCGv_i32 t2;
10763
10764 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10765 generate_exception(ctx, EXCP_RI);
10766 return;
10767 }
10768
10769 t0 = tcg_temp_new();
10770
10771 gen_base_offset_addr(ctx, t0, base, offset);
10772
10773 t1 = tcg_const_tl(reglist);
10774 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10775
3c824109
NF
10776 save_cpu_state(ctx, 1);
10777 switch (opc) {
10778 case LWM32:
895c2d04 10779 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10780 opn = "lwm";
3c824109
NF
10781 break;
10782 case SWM32:
895c2d04 10783 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10784 opn = "swm";
3c824109
NF
10785 break;
10786#ifdef TARGET_MIPS64
10787 case LDM:
895c2d04 10788 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10789 opn = "ldm";
3c824109
NF
10790 break;
10791 case SDM:
895c2d04 10792 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10793 opn = "sdm";
3c824109 10794 break;
6af0bf9c 10795#endif
3c824109 10796 }
e1050a76 10797 (void)opn;
3c824109
NF
10798 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10799 tcg_temp_free(t0);
33087598 10800 tcg_temp_free(t1);
3c824109
NF
10801 tcg_temp_free_i32(t2);
10802}
6af0bf9c 10803
3c824109 10804
d75c135e 10805static void gen_pool16c_insn(DisasContext *ctx, int *is_branch)
6af0bf9c 10806{
3c824109
NF
10807 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10808 int rs = mmreg(ctx->opcode & 0x7);
10809 int opc;
6af0bf9c 10810
3c824109
NF
10811 switch (((ctx->opcode) >> 4) & 0x3f) {
10812 case NOT16 + 0:
10813 case NOT16 + 1:
10814 case NOT16 + 2:
10815 case NOT16 + 3:
d75c135e 10816 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10817 break;
10818 case XOR16 + 0:
10819 case XOR16 + 1:
10820 case XOR16 + 2:
10821 case XOR16 + 3:
d75c135e 10822 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10823 break;
10824 case AND16 + 0:
10825 case AND16 + 1:
10826 case AND16 + 2:
10827 case AND16 + 3:
d75c135e 10828 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10829 break;
10830 case OR16 + 0:
10831 case OR16 + 1:
10832 case OR16 + 2:
10833 case OR16 + 3:
d75c135e 10834 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10835 break;
10836 case LWM16 + 0:
10837 case LWM16 + 1:
10838 case LWM16 + 2:
10839 case LWM16 + 3:
10840 {
10841 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10842 int offset = ZIMM(ctx->opcode, 0, 4);
10843
10844 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10845 29, offset << 2);
10846 }
10847 break;
10848 case SWM16 + 0:
10849 case SWM16 + 1:
10850 case SWM16 + 2:
10851 case SWM16 + 3:
10852 {
10853 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10854 int offset = ZIMM(ctx->opcode, 0, 4);
10855
10856 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10857 29, offset << 2);
10858 }
10859 break;
10860 case JR16 + 0:
10861 case JR16 + 1:
10862 {
10863 int reg = ctx->opcode & 0x1f;
10864
10865 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10866 }
10867 *is_branch = 1;
10868 break;
10869 case JRC16 + 0:
10870 case JRC16 + 1:
10871 {
10872 int reg = ctx->opcode & 0x1f;
10873
10874 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10875 /* Let normal delay slot handling in our caller take us
10876 to the branch target. */
10877 }
10878 break;
10879 case JALR16 + 0:
10880 case JALR16 + 1:
10881 opc = OPC_JALR;
10882 goto do_jalr;
10883 case JALR16S + 0:
10884 case JALR16S + 1:
10885 opc = OPC_JALRS;
10886 do_jalr:
10887 {
10888 int reg = ctx->opcode & 0x1f;
10889
10890 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10891 }
10892 *is_branch = 1;
10893 break;
10894 case MFHI16 + 0:
10895 case MFHI16 + 1:
26135ead 10896 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
10897 break;
10898 case MFLO16 + 0:
10899 case MFLO16 + 1:
26135ead 10900 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
10901 break;
10902 case BREAK16:
10903 generate_exception(ctx, EXCP_BREAK);
10904 break;
10905 case SDBBP16:
10906 /* XXX: not clear which exception should be raised
10907 * when in debug mode...
10908 */
d75c135e 10909 check_insn(ctx, ISA_MIPS32);
3c824109
NF
10910 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10911 generate_exception(ctx, EXCP_DBp);
10912 } else {
10913 generate_exception(ctx, EXCP_DBp);
10914 }
10915 break;
10916 case JRADDIUSP + 0:
10917 case JRADDIUSP + 1:
10918 {
10919 int imm = ZIMM(ctx->opcode, 0, 5);
10920
10921 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 10922 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
10923 /* Let normal delay slot handling in our caller take us
10924 to the branch target. */
10925 }
10926 break;
10927 default:
10928 generate_exception(ctx, EXCP_RI);
10929 break;
10930 }
10931}
10932
10933static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10934{
10935 TCGv t0 = tcg_temp_new();
10936 TCGv t1 = tcg_temp_new();
10937
10938 gen_load_gpr(t0, base);
10939
10940 if (index != 0) {
10941 gen_load_gpr(t1, index);
10942 tcg_gen_shli_tl(t1, t1, 2);
10943 gen_op_addr_add(ctx, t0, t1, t0);
10944 }
10945
2910c6cb 10946 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
10947 gen_store_gpr(t1, rd);
10948
10949 tcg_temp_free(t0);
10950 tcg_temp_free(t1);
10951}
10952
10953static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10954 int base, int16_t offset)
10955{
10956 const char *opn = "ldst_pair";
10957 TCGv t0, t1;
10958
36c6711b 10959 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 10960 generate_exception(ctx, EXCP_RI);
d796321b
FB
10961 return;
10962 }
10963
3c824109
NF
10964 t0 = tcg_temp_new();
10965 t1 = tcg_temp_new();
8e9ade68 10966
3c824109
NF
10967 gen_base_offset_addr(ctx, t0, base, offset);
10968
10969 switch (opc) {
10970 case LWP:
36c6711b
EJ
10971 if (rd == base) {
10972 generate_exception(ctx, EXCP_RI);
10973 return;
10974 }
2910c6cb 10975 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
10976 gen_store_gpr(t1, rd);
10977 tcg_gen_movi_tl(t1, 4);
10978 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 10979 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
10980 gen_store_gpr(t1, rd+1);
10981 opn = "lwp";
10982 break;
10983 case SWP:
3c824109 10984 gen_load_gpr(t1, rd);
2910c6cb 10985 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
10986 tcg_gen_movi_tl(t1, 4);
10987 gen_op_addr_add(ctx, t0, t0, t1);
10988 gen_load_gpr(t1, rd+1);
2910c6cb 10989 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
10990 opn = "swp";
10991 break;
10992#ifdef TARGET_MIPS64
10993 case LDP:
36c6711b
EJ
10994 if (rd == base) {
10995 generate_exception(ctx, EXCP_RI);
10996 return;
10997 }
2910c6cb 10998 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
10999 gen_store_gpr(t1, rd);
11000 tcg_gen_movi_tl(t1, 8);
11001 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11002 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11003 gen_store_gpr(t1, rd+1);
11004 opn = "ldp";
11005 break;
11006 case SDP:
3c824109 11007 gen_load_gpr(t1, rd);
2910c6cb 11008 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11009 tcg_gen_movi_tl(t1, 8);
11010 gen_op_addr_add(ctx, t0, t0, t1);
11011 gen_load_gpr(t1, rd+1);
2910c6cb 11012 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11013 opn = "sdp";
11014 break;
11015#endif
6af0bf9c 11016 }
2abf314d 11017 (void)opn; /* avoid a compiler warning */
3c824109
NF
11018 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11019 tcg_temp_free(t0);
11020 tcg_temp_free(t1);
11021}
618b0fe9 11022
7db13fae 11023static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
3c824109
NF
11024 int *is_branch)
11025{
11026 int extension = (ctx->opcode >> 6) & 0x3f;
11027 int minor = (ctx->opcode >> 12) & 0xf;
11028 uint32_t mips32_op;
11029
11030 switch (extension) {
11031 case TEQ:
11032 mips32_op = OPC_TEQ;
11033 goto do_trap;
11034 case TGE:
11035 mips32_op = OPC_TGE;
11036 goto do_trap;
11037 case TGEU:
11038 mips32_op = OPC_TGEU;
11039 goto do_trap;
11040 case TLT:
11041 mips32_op = OPC_TLT;
11042 goto do_trap;
11043 case TLTU:
11044 mips32_op = OPC_TLTU;
11045 goto do_trap;
11046 case TNE:
11047 mips32_op = OPC_TNE;
11048 do_trap:
11049 gen_trap(ctx, mips32_op, rs, rt, -1);
11050 break;
11051#ifndef CONFIG_USER_ONLY
11052 case MFC0:
11053 case MFC0 + 32:
2e15497c 11054 check_cp0_enabled(ctx);
3c824109
NF
11055 if (rt == 0) {
11056 /* Treat as NOP. */
11057 break;
11058 }
d75c135e 11059 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11060 break;
11061 case MTC0:
11062 case MTC0 + 32:
2e15497c 11063 check_cp0_enabled(ctx);
3c824109
NF
11064 {
11065 TCGv t0 = tcg_temp_new();
618b0fe9 11066
3c824109 11067 gen_load_gpr(t0, rt);
d75c135e 11068 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11069 tcg_temp_free(t0);
11070 }
11071 break;
11072#endif
11073 case 0x2c:
11074 switch (minor) {
11075 case SEB:
11076 gen_bshfl(ctx, OPC_SEB, rs, rt);
11077 break;
11078 case SEH:
11079 gen_bshfl(ctx, OPC_SEH, rs, rt);
11080 break;
11081 case CLO:
11082 mips32_op = OPC_CLO;
11083 goto do_cl;
11084 case CLZ:
11085 mips32_op = OPC_CLZ;
11086 do_cl:
d75c135e 11087 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11088 gen_cl(ctx, mips32_op, rt, rs);
11089 break;
11090 case RDHWR:
d75c135e 11091 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11092 break;
11093 case WSBH:
11094 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11095 break;
11096 case MULT:
11097 mips32_op = OPC_MULT;
26135ead 11098 goto do_mul;
3c824109
NF
11099 case MULTU:
11100 mips32_op = OPC_MULTU;
26135ead 11101 goto do_mul;
3c824109
NF
11102 case DIV:
11103 mips32_op = OPC_DIV;
26135ead 11104 goto do_div;
3c824109
NF
11105 case DIVU:
11106 mips32_op = OPC_DIVU;
26135ead
RS
11107 goto do_div;
11108 do_div:
11109 check_insn(ctx, ISA_MIPS32);
11110 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11111 break;
3c824109
NF
11112 case MADD:
11113 mips32_op = OPC_MADD;
26135ead 11114 goto do_mul;
3c824109
NF
11115 case MADDU:
11116 mips32_op = OPC_MADDU;
26135ead 11117 goto do_mul;
3c824109
NF
11118 case MSUB:
11119 mips32_op = OPC_MSUB;
26135ead 11120 goto do_mul;
3c824109
NF
11121 case MSUBU:
11122 mips32_op = OPC_MSUBU;
26135ead 11123 do_mul:
d75c135e 11124 check_insn(ctx, ISA_MIPS32);
26135ead 11125 gen_muldiv(ctx, mips32_op, (ctx->opcode >> 14) & 3, rs, rt);
3c824109
NF
11126 break;
11127 default:
11128 goto pool32axf_invalid;
11129 }
11130 break;
11131 case 0x34:
11132 switch (minor) {
11133 case MFC2:
11134 case MTC2:
11135 case MFHC2:
11136 case MTHC2:
11137 case CFC2:
11138 case CTC2:
11139 generate_exception_err(ctx, EXCP_CpU, 2);
11140 break;
11141 default:
11142 goto pool32axf_invalid;
11143 }
11144 break;
11145 case 0x3c:
11146 switch (minor) {
11147 case JALR:
11148 case JALR_HB:
11149 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11150 *is_branch = 1;
11151 break;
11152 case JALRS:
11153 case JALRS_HB:
11154 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11155 *is_branch = 1;
11156 break;
11157 default:
11158 goto pool32axf_invalid;
11159 }
11160 break;
11161 case 0x05:
11162 switch (minor) {
11163 case RDPGPR:
2e15497c 11164 check_cp0_enabled(ctx);
d75c135e 11165 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11166 gen_load_srsgpr(rt, rs);
11167 break;
11168 case WRPGPR:
2e15497c 11169 check_cp0_enabled(ctx);
d75c135e 11170 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11171 gen_store_srsgpr(rt, rs);
11172 break;
11173 default:
11174 goto pool32axf_invalid;
11175 }
11176 break;
11177#ifndef CONFIG_USER_ONLY
11178 case 0x0d:
11179 switch (minor) {
11180 case TLBP:
11181 mips32_op = OPC_TLBP;
11182 goto do_cp0;
11183 case TLBR:
11184 mips32_op = OPC_TLBR;
11185 goto do_cp0;
11186 case TLBWI:
11187 mips32_op = OPC_TLBWI;
11188 goto do_cp0;
11189 case TLBWR:
11190 mips32_op = OPC_TLBWR;
11191 goto do_cp0;
11192 case WAIT:
11193 mips32_op = OPC_WAIT;
11194 goto do_cp0;
11195 case DERET:
11196 mips32_op = OPC_DERET;
11197 goto do_cp0;
11198 case ERET:
11199 mips32_op = OPC_ERET;
11200 do_cp0:
11201 gen_cp0(env, ctx, mips32_op, rt, rs);
11202 break;
11203 default:
11204 goto pool32axf_invalid;
11205 }
11206 break;
11207 case 0x1d:
11208 switch (minor) {
11209 case DI:
2e15497c 11210 check_cp0_enabled(ctx);
3c824109
NF
11211 {
11212 TCGv t0 = tcg_temp_new();
11213
11214 save_cpu_state(ctx, 1);
895c2d04 11215 gen_helper_di(t0, cpu_env);
3c824109
NF
11216 gen_store_gpr(t0, rs);
11217 /* Stop translation as we may have switched the execution mode */
11218 ctx->bstate = BS_STOP;
11219 tcg_temp_free(t0);
11220 }
11221 break;
11222 case EI:
2e15497c 11223 check_cp0_enabled(ctx);
3c824109
NF
11224 {
11225 TCGv t0 = tcg_temp_new();
11226
11227 save_cpu_state(ctx, 1);
895c2d04 11228 gen_helper_ei(t0, cpu_env);
3c824109
NF
11229 gen_store_gpr(t0, rs);
11230 /* Stop translation as we may have switched the execution mode */
11231 ctx->bstate = BS_STOP;
11232 tcg_temp_free(t0);
11233 }
11234 break;
11235 default:
11236 goto pool32axf_invalid;
11237 }
11238 break;
11239#endif
11240 case 0x2d:
11241 switch (minor) {
11242 case SYNC:
11243 /* NOP */
11244 break;
11245 case SYSCALL:
11246 generate_exception(ctx, EXCP_SYSCALL);
11247 ctx->bstate = BS_STOP;
11248 break;
11249 case SDBBP:
d75c135e 11250 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11251 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11252 generate_exception(ctx, EXCP_DBp);
11253 } else {
11254 generate_exception(ctx, EXCP_DBp);
11255 }
11256 break;
11257 default:
11258 goto pool32axf_invalid;
11259 }
11260 break;
11261 case 0x35:
26135ead 11262 switch (minor & 3) {
3c824109 11263 case MFHI32:
26135ead 11264 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109
NF
11265 break;
11266 case MFLO32:
26135ead 11267 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109
NF
11268 break;
11269 case MTHI32:
26135ead 11270 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109
NF
11271 break;
11272 case MTLO32:
26135ead 11273 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
11274 break;
11275 default:
11276 goto pool32axf_invalid;
11277 }
11278 break;
11279 default:
11280 pool32axf_invalid:
11281 MIPS_INVAL("pool32axf");
11282 generate_exception(ctx, EXCP_RI);
11283 break;
11284 }
11285}
11286
11287/* Values for microMIPS fmt field. Variable-width, depending on which
11288 formats the instruction supports. */
11289
11290enum {
11291 FMT_SD_S = 0,
11292 FMT_SD_D = 1,
11293
11294 FMT_SDPS_S = 0,
11295 FMT_SDPS_D = 1,
11296 FMT_SDPS_PS = 2,
11297
11298 FMT_SWL_S = 0,
11299 FMT_SWL_W = 1,
11300 FMT_SWL_L = 2,
11301
11302 FMT_DWL_D = 0,
11303 FMT_DWL_W = 1,
11304 FMT_DWL_L = 2
11305};
11306
d75c135e 11307static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11308{
11309 int extension = (ctx->opcode >> 6) & 0x3ff;
11310 uint32_t mips32_op;
11311
11312#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11313#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11314#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11315
11316 switch (extension) {
11317 case FLOAT_1BIT_FMT(CFC1, 0):
11318 mips32_op = OPC_CFC1;
11319 goto do_cp1;
11320 case FLOAT_1BIT_FMT(CTC1, 0):
11321 mips32_op = OPC_CTC1;
11322 goto do_cp1;
11323 case FLOAT_1BIT_FMT(MFC1, 0):
11324 mips32_op = OPC_MFC1;
11325 goto do_cp1;
11326 case FLOAT_1BIT_FMT(MTC1, 0):
11327 mips32_op = OPC_MTC1;
11328 goto do_cp1;
11329 case FLOAT_1BIT_FMT(MFHC1, 0):
11330 mips32_op = OPC_MFHC1;
11331 goto do_cp1;
11332 case FLOAT_1BIT_FMT(MTHC1, 0):
11333 mips32_op = OPC_MTHC1;
11334 do_cp1:
11335 gen_cp1(ctx, mips32_op, rt, rs);
11336 break;
11337
11338 /* Reciprocal square root */
11339 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11340 mips32_op = OPC_RSQRT_S;
11341 goto do_unaryfp;
11342 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11343 mips32_op = OPC_RSQRT_D;
11344 goto do_unaryfp;
11345
11346 /* Square root */
11347 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11348 mips32_op = OPC_SQRT_S;
11349 goto do_unaryfp;
11350 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11351 mips32_op = OPC_SQRT_D;
11352 goto do_unaryfp;
11353
11354 /* Reciprocal */
11355 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11356 mips32_op = OPC_RECIP_S;
11357 goto do_unaryfp;
11358 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11359 mips32_op = OPC_RECIP_D;
11360 goto do_unaryfp;
11361
11362 /* Floor */
11363 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11364 mips32_op = OPC_FLOOR_L_S;
11365 goto do_unaryfp;
11366 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11367 mips32_op = OPC_FLOOR_L_D;
11368 goto do_unaryfp;
11369 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11370 mips32_op = OPC_FLOOR_W_S;
11371 goto do_unaryfp;
11372 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11373 mips32_op = OPC_FLOOR_W_D;
11374 goto do_unaryfp;
11375
11376 /* Ceiling */
11377 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11378 mips32_op = OPC_CEIL_L_S;
11379 goto do_unaryfp;
11380 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11381 mips32_op = OPC_CEIL_L_D;
11382 goto do_unaryfp;
11383 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11384 mips32_op = OPC_CEIL_W_S;
11385 goto do_unaryfp;
11386 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11387 mips32_op = OPC_CEIL_W_D;
11388 goto do_unaryfp;
11389
11390 /* Truncation */
11391 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11392 mips32_op = OPC_TRUNC_L_S;
11393 goto do_unaryfp;
11394 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11395 mips32_op = OPC_TRUNC_L_D;
11396 goto do_unaryfp;
11397 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11398 mips32_op = OPC_TRUNC_W_S;
11399 goto do_unaryfp;
11400 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11401 mips32_op = OPC_TRUNC_W_D;
11402 goto do_unaryfp;
11403
11404 /* Round */
11405 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11406 mips32_op = OPC_ROUND_L_S;
11407 goto do_unaryfp;
11408 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11409 mips32_op = OPC_ROUND_L_D;
11410 goto do_unaryfp;
11411 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11412 mips32_op = OPC_ROUND_W_S;
11413 goto do_unaryfp;
11414 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11415 mips32_op = OPC_ROUND_W_D;
11416 goto do_unaryfp;
11417
11418 /* Integer to floating-point conversion */
11419 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11420 mips32_op = OPC_CVT_L_S;
11421 goto do_unaryfp;
11422 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11423 mips32_op = OPC_CVT_L_D;
11424 goto do_unaryfp;
11425 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11426 mips32_op = OPC_CVT_W_S;
11427 goto do_unaryfp;
11428 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11429 mips32_op = OPC_CVT_W_D;
11430 goto do_unaryfp;
11431
11432 /* Paired-foo conversions */
11433 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11434 mips32_op = OPC_CVT_S_PL;
11435 goto do_unaryfp;
11436 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11437 mips32_op = OPC_CVT_S_PU;
11438 goto do_unaryfp;
11439 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11440 mips32_op = OPC_CVT_PW_PS;
11441 goto do_unaryfp;
11442 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11443 mips32_op = OPC_CVT_PS_PW;
11444 goto do_unaryfp;
11445
11446 /* Floating-point moves */
11447 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11448 mips32_op = OPC_MOV_S;
11449 goto do_unaryfp;
11450 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11451 mips32_op = OPC_MOV_D;
11452 goto do_unaryfp;
11453 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11454 mips32_op = OPC_MOV_PS;
11455 goto do_unaryfp;
11456
11457 /* Absolute value */
11458 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11459 mips32_op = OPC_ABS_S;
11460 goto do_unaryfp;
11461 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11462 mips32_op = OPC_ABS_D;
11463 goto do_unaryfp;
11464 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11465 mips32_op = OPC_ABS_PS;
11466 goto do_unaryfp;
11467
11468 /* Negation */
11469 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11470 mips32_op = OPC_NEG_S;
11471 goto do_unaryfp;
11472 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11473 mips32_op = OPC_NEG_D;
11474 goto do_unaryfp;
11475 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11476 mips32_op = OPC_NEG_PS;
11477 goto do_unaryfp;
11478
11479 /* Reciprocal square root step */
11480 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11481 mips32_op = OPC_RSQRT1_S;
11482 goto do_unaryfp;
11483 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11484 mips32_op = OPC_RSQRT1_D;
11485 goto do_unaryfp;
11486 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11487 mips32_op = OPC_RSQRT1_PS;
11488 goto do_unaryfp;
11489
11490 /* Reciprocal step */
11491 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11492 mips32_op = OPC_RECIP1_S;
11493 goto do_unaryfp;
11494 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11495 mips32_op = OPC_RECIP1_S;
11496 goto do_unaryfp;
11497 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11498 mips32_op = OPC_RECIP1_PS;
11499 goto do_unaryfp;
11500
11501 /* Conversions from double */
11502 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11503 mips32_op = OPC_CVT_D_S;
11504 goto do_unaryfp;
11505 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11506 mips32_op = OPC_CVT_D_W;
11507 goto do_unaryfp;
11508 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11509 mips32_op = OPC_CVT_D_L;
11510 goto do_unaryfp;
11511
11512 /* Conversions from single */
11513 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11514 mips32_op = OPC_CVT_S_D;
11515 goto do_unaryfp;
11516 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11517 mips32_op = OPC_CVT_S_W;
11518 goto do_unaryfp;
11519 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11520 mips32_op = OPC_CVT_S_L;
11521 do_unaryfp:
11522 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11523 break;
11524
11525 /* Conditional moves on floating-point codes */
11526 case COND_FLOAT_MOV(MOVT, 0):
11527 case COND_FLOAT_MOV(MOVT, 1):
11528 case COND_FLOAT_MOV(MOVT, 2):
11529 case COND_FLOAT_MOV(MOVT, 3):
11530 case COND_FLOAT_MOV(MOVT, 4):
11531 case COND_FLOAT_MOV(MOVT, 5):
11532 case COND_FLOAT_MOV(MOVT, 6):
11533 case COND_FLOAT_MOV(MOVT, 7):
11534 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11535 break;
11536 case COND_FLOAT_MOV(MOVF, 0):
11537 case COND_FLOAT_MOV(MOVF, 1):
11538 case COND_FLOAT_MOV(MOVF, 2):
11539 case COND_FLOAT_MOV(MOVF, 3):
11540 case COND_FLOAT_MOV(MOVF, 4):
11541 case COND_FLOAT_MOV(MOVF, 5):
11542 case COND_FLOAT_MOV(MOVF, 6):
11543 case COND_FLOAT_MOV(MOVF, 7):
11544 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11545 break;
11546 default:
11547 MIPS_INVAL("pool32fxf");
11548 generate_exception(ctx, EXCP_RI);
11549 break;
11550 }
11551}
11552
7db13fae 11553static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
3c824109
NF
11554 uint16_t insn_hw1, int *is_branch)
11555{
11556 int32_t offset;
11557 uint16_t insn;
11558 int rt, rs, rd, rr;
11559 int16_t imm;
11560 uint32_t op, minor, mips32_op;
11561 uint32_t cond, fmt, cc;
11562
895c2d04 11563 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11564 ctx->opcode = (ctx->opcode << 16) | insn;
11565
11566 rt = (ctx->opcode >> 21) & 0x1f;
11567 rs = (ctx->opcode >> 16) & 0x1f;
11568 rd = (ctx->opcode >> 11) & 0x1f;
11569 rr = (ctx->opcode >> 6) & 0x1f;
11570 imm = (int16_t) ctx->opcode;
11571
11572 op = (ctx->opcode >> 26) & 0x3f;
11573 switch (op) {
11574 case POOL32A:
11575 minor = ctx->opcode & 0x3f;
11576 switch (minor) {
11577 case 0x00:
11578 minor = (ctx->opcode >> 6) & 0xf;
11579 switch (minor) {
11580 case SLL32:
11581 mips32_op = OPC_SLL;
11582 goto do_shifti;
11583 case SRA:
11584 mips32_op = OPC_SRA;
11585 goto do_shifti;
11586 case SRL32:
11587 mips32_op = OPC_SRL;
11588 goto do_shifti;
11589 case ROTR:
11590 mips32_op = OPC_ROTR;
11591 do_shifti:
d75c135e 11592 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
11593 break;
11594 default:
11595 goto pool32a_invalid;
11596 }
11597 break;
11598 case 0x10:
11599 minor = (ctx->opcode >> 6) & 0xf;
11600 switch (minor) {
11601 /* Arithmetic */
11602 case ADD:
11603 mips32_op = OPC_ADD;
11604 goto do_arith;
11605 case ADDU32:
11606 mips32_op = OPC_ADDU;
11607 goto do_arith;
11608 case SUB:
11609 mips32_op = OPC_SUB;
11610 goto do_arith;
11611 case SUBU32:
11612 mips32_op = OPC_SUBU;
11613 goto do_arith;
11614 case MUL:
11615 mips32_op = OPC_MUL;
11616 do_arith:
d75c135e 11617 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11618 break;
11619 /* Shifts */
11620 case SLLV:
11621 mips32_op = OPC_SLLV;
11622 goto do_shift;
11623 case SRLV:
11624 mips32_op = OPC_SRLV;
11625 goto do_shift;
11626 case SRAV:
11627 mips32_op = OPC_SRAV;
11628 goto do_shift;
11629 case ROTRV:
11630 mips32_op = OPC_ROTRV;
11631 do_shift:
d75c135e 11632 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11633 break;
11634 /* Logical operations */
11635 case AND:
11636 mips32_op = OPC_AND;
11637 goto do_logic;
11638 case OR32:
11639 mips32_op = OPC_OR;
11640 goto do_logic;
11641 case NOR:
11642 mips32_op = OPC_NOR;
11643 goto do_logic;
11644 case XOR32:
11645 mips32_op = OPC_XOR;
11646 do_logic:
d75c135e 11647 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11648 break;
11649 /* Set less than */
11650 case SLT:
11651 mips32_op = OPC_SLT;
11652 goto do_slt;
11653 case SLTU:
11654 mips32_op = OPC_SLTU;
11655 do_slt:
d75c135e 11656 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11657 break;
11658 default:
11659 goto pool32a_invalid;
11660 }
11661 break;
11662 case 0x18:
11663 minor = (ctx->opcode >> 6) & 0xf;
11664 switch (minor) {
11665 /* Conditional moves */
11666 case MOVN:
11667 mips32_op = OPC_MOVN;
11668 goto do_cmov;
11669 case MOVZ:
11670 mips32_op = OPC_MOVZ;
11671 do_cmov:
d75c135e 11672 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11673 break;
11674 case LWXS:
11675 gen_ldxs(ctx, rs, rt, rd);
11676 break;
11677 default:
11678 goto pool32a_invalid;
11679 }
11680 break;
11681 case INS:
11682 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11683 return;
11684 case EXT:
11685 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11686 return;
11687 case POOL32AXF:
11688 gen_pool32axf(env, ctx, rt, rs, is_branch);
11689 break;
11690 case 0x07:
11691 generate_exception(ctx, EXCP_BREAK);
11692 break;
11693 default:
11694 pool32a_invalid:
11695 MIPS_INVAL("pool32a");
11696 generate_exception(ctx, EXCP_RI);
11697 break;
11698 }
11699 break;
11700 case POOL32B:
11701 minor = (ctx->opcode >> 12) & 0xf;
11702 switch (minor) {
11703 case CACHE:
2e15497c 11704 check_cp0_enabled(ctx);
3c824109
NF
11705 /* Treat as no-op. */
11706 break;
11707 case LWC2:
11708 case SWC2:
11709 /* COP2: Not implemented. */
11710 generate_exception_err(ctx, EXCP_CpU, 2);
11711 break;
11712 case LWP:
11713 case SWP:
11714#ifdef TARGET_MIPS64
11715 case LDP:
11716 case SDP:
11717#endif
11718 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11719 break;
11720 case LWM32:
11721 case SWM32:
11722#ifdef TARGET_MIPS64
11723 case LDM:
11724 case SDM:
11725#endif
11726 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11727 break;
11728 default:
11729 MIPS_INVAL("pool32b");
11730 generate_exception(ctx, EXCP_RI);
11731 break;
11732 }
11733 break;
11734 case POOL32F:
11735 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11736 minor = ctx->opcode & 0x3f;
11737 check_cp1_enabled(ctx);
11738 switch (minor) {
11739 case ALNV_PS:
11740 mips32_op = OPC_ALNV_PS;
11741 goto do_madd;
11742 case MADD_S:
11743 mips32_op = OPC_MADD_S;
11744 goto do_madd;
11745 case MADD_D:
11746 mips32_op = OPC_MADD_D;
11747 goto do_madd;
11748 case MADD_PS:
11749 mips32_op = OPC_MADD_PS;
11750 goto do_madd;
11751 case MSUB_S:
11752 mips32_op = OPC_MSUB_S;
11753 goto do_madd;
11754 case MSUB_D:
11755 mips32_op = OPC_MSUB_D;
11756 goto do_madd;
11757 case MSUB_PS:
11758 mips32_op = OPC_MSUB_PS;
11759 goto do_madd;
11760 case NMADD_S:
11761 mips32_op = OPC_NMADD_S;
11762 goto do_madd;
11763 case NMADD_D:
11764 mips32_op = OPC_NMADD_D;
11765 goto do_madd;
11766 case NMADD_PS:
11767 mips32_op = OPC_NMADD_PS;
11768 goto do_madd;
11769 case NMSUB_S:
11770 mips32_op = OPC_NMSUB_S;
11771 goto do_madd;
11772 case NMSUB_D:
11773 mips32_op = OPC_NMSUB_D;
11774 goto do_madd;
11775 case NMSUB_PS:
11776 mips32_op = OPC_NMSUB_PS;
11777 do_madd:
11778 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11779 break;
11780 case CABS_COND_FMT:
11781 cond = (ctx->opcode >> 6) & 0xf;
11782 cc = (ctx->opcode >> 13) & 0x7;
11783 fmt = (ctx->opcode >> 10) & 0x3;
11784 switch (fmt) {
11785 case 0x0:
11786 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11787 break;
11788 case 0x1:
11789 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11790 break;
11791 case 0x2:
11792 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11793 break;
11794 default:
11795 goto pool32f_invalid;
11796 }
11797 break;
11798 case C_COND_FMT:
11799 cond = (ctx->opcode >> 6) & 0xf;
11800 cc = (ctx->opcode >> 13) & 0x7;
11801 fmt = (ctx->opcode >> 10) & 0x3;
11802 switch (fmt) {
11803 case 0x0:
11804 gen_cmp_s(ctx, cond, rt, rs, cc);
11805 break;
11806 case 0x1:
11807 gen_cmp_d(ctx, cond, rt, rs, cc);
11808 break;
11809 case 0x2:
11810 gen_cmp_ps(ctx, cond, rt, rs, cc);
11811 break;
11812 default:
11813 goto pool32f_invalid;
11814 }
11815 break;
11816 case POOL32FXF:
d75c135e 11817 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
11818 break;
11819 case 0x00:
11820 /* PLL foo */
11821 switch ((ctx->opcode >> 6) & 0x7) {
11822 case PLL_PS:
11823 mips32_op = OPC_PLL_PS;
11824 goto do_ps;
11825 case PLU_PS:
11826 mips32_op = OPC_PLU_PS;
11827 goto do_ps;
11828 case PUL_PS:
11829 mips32_op = OPC_PUL_PS;
11830 goto do_ps;
11831 case PUU_PS:
11832 mips32_op = OPC_PUU_PS;
11833 goto do_ps;
11834 case CVT_PS_S:
11835 mips32_op = OPC_CVT_PS_S;
11836 do_ps:
11837 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11838 break;
11839 default:
11840 goto pool32f_invalid;
11841 }
11842 break;
11843 case 0x08:
11844 /* [LS][WDU]XC1 */
11845 switch ((ctx->opcode >> 6) & 0x7) {
11846 case LWXC1:
11847 mips32_op = OPC_LWXC1;
11848 goto do_ldst_cp1;
11849 case SWXC1:
11850 mips32_op = OPC_SWXC1;
11851 goto do_ldst_cp1;
11852 case LDXC1:
11853 mips32_op = OPC_LDXC1;
11854 goto do_ldst_cp1;
11855 case SDXC1:
11856 mips32_op = OPC_SDXC1;
11857 goto do_ldst_cp1;
11858 case LUXC1:
11859 mips32_op = OPC_LUXC1;
11860 goto do_ldst_cp1;
11861 case SUXC1:
11862 mips32_op = OPC_SUXC1;
11863 do_ldst_cp1:
11864 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11865 break;
11866 default:
11867 goto pool32f_invalid;
11868 }
11869 break;
11870 case 0x18:
11871 /* 3D insns */
11872 fmt = (ctx->opcode >> 9) & 0x3;
11873 switch ((ctx->opcode >> 6) & 0x7) {
11874 case RSQRT2_FMT:
11875 switch (fmt) {
11876 case FMT_SDPS_S:
11877 mips32_op = OPC_RSQRT2_S;
11878 goto do_3d;
11879 case FMT_SDPS_D:
11880 mips32_op = OPC_RSQRT2_D;
11881 goto do_3d;
11882 case FMT_SDPS_PS:
11883 mips32_op = OPC_RSQRT2_PS;
11884 goto do_3d;
11885 default:
11886 goto pool32f_invalid;
11887 }
11888 break;
11889 case RECIP2_FMT:
11890 switch (fmt) {
11891 case FMT_SDPS_S:
11892 mips32_op = OPC_RECIP2_S;
11893 goto do_3d;
11894 case FMT_SDPS_D:
11895 mips32_op = OPC_RECIP2_D;
11896 goto do_3d;
11897 case FMT_SDPS_PS:
11898 mips32_op = OPC_RECIP2_PS;
11899 goto do_3d;
11900 default:
11901 goto pool32f_invalid;
11902 }
11903 break;
11904 case ADDR_PS:
11905 mips32_op = OPC_ADDR_PS;
11906 goto do_3d;
11907 case MULR_PS:
11908 mips32_op = OPC_MULR_PS;
11909 do_3d:
11910 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11911 break;
11912 default:
11913 goto pool32f_invalid;
11914 }
11915 break;
11916 case 0x20:
11917 /* MOV[FT].fmt and PREFX */
11918 cc = (ctx->opcode >> 13) & 0x7;
11919 fmt = (ctx->opcode >> 9) & 0x3;
11920 switch ((ctx->opcode >> 6) & 0x7) {
11921 case MOVF_FMT:
11922 switch (fmt) {
11923 case FMT_SDPS_S:
11924 gen_movcf_s(rs, rt, cc, 0);
11925 break;
11926 case FMT_SDPS_D:
11927 gen_movcf_d(ctx, rs, rt, cc, 0);
11928 break;
11929 case FMT_SDPS_PS:
11930 gen_movcf_ps(rs, rt, cc, 0);
11931 break;
11932 default:
11933 goto pool32f_invalid;
11934 }
11935 break;
11936 case MOVT_FMT:
11937 switch (fmt) {
11938 case FMT_SDPS_S:
11939 gen_movcf_s(rs, rt, cc, 1);
11940 break;
11941 case FMT_SDPS_D:
11942 gen_movcf_d(ctx, rs, rt, cc, 1);
11943 break;
11944 case FMT_SDPS_PS:
11945 gen_movcf_ps(rs, rt, cc, 1);
11946 break;
11947 default:
11948 goto pool32f_invalid;
11949 }
11950 break;
11951 case PREFX:
11952 break;
11953 default:
11954 goto pool32f_invalid;
11955 }
11956 break;
11957#define FINSN_3ARG_SDPS(prfx) \
11958 switch ((ctx->opcode >> 8) & 0x3) { \
11959 case FMT_SDPS_S: \
11960 mips32_op = OPC_##prfx##_S; \
11961 goto do_fpop; \
11962 case FMT_SDPS_D: \
11963 mips32_op = OPC_##prfx##_D; \
11964 goto do_fpop; \
11965 case FMT_SDPS_PS: \
11966 mips32_op = OPC_##prfx##_PS; \
11967 goto do_fpop; \
11968 default: \
11969 goto pool32f_invalid; \
11970 }
11971 case 0x30:
11972 /* regular FP ops */
11973 switch ((ctx->opcode >> 6) & 0x3) {
11974 case ADD_FMT:
11975 FINSN_3ARG_SDPS(ADD);
11976 break;
11977 case SUB_FMT:
11978 FINSN_3ARG_SDPS(SUB);
11979 break;
11980 case MUL_FMT:
11981 FINSN_3ARG_SDPS(MUL);
11982 break;
11983 case DIV_FMT:
11984 fmt = (ctx->opcode >> 8) & 0x3;
11985 if (fmt == 1) {
11986 mips32_op = OPC_DIV_D;
11987 } else if (fmt == 0) {
11988 mips32_op = OPC_DIV_S;
11989 } else {
11990 goto pool32f_invalid;
11991 }
11992 goto do_fpop;
11993 default:
11994 goto pool32f_invalid;
11995 }
11996 break;
11997 case 0x38:
11998 /* cmovs */
11999 switch ((ctx->opcode >> 6) & 0x3) {
12000 case MOVN_FMT:
12001 FINSN_3ARG_SDPS(MOVN);
12002 break;
12003 case MOVZ_FMT:
12004 FINSN_3ARG_SDPS(MOVZ);
12005 break;
12006 default:
12007 goto pool32f_invalid;
12008 }
12009 break;
12010 do_fpop:
12011 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12012 break;
12013 default:
12014 pool32f_invalid:
12015 MIPS_INVAL("pool32f");
12016 generate_exception(ctx, EXCP_RI);
12017 break;
12018 }
12019 } else {
12020 generate_exception_err(ctx, EXCP_CpU, 1);
12021 }
12022 break;
12023 case POOL32I:
12024 minor = (ctx->opcode >> 21) & 0x1f;
12025 switch (minor) {
12026 case BLTZ:
12027 mips32_op = OPC_BLTZ;
12028 goto do_branch;
12029 case BLTZAL:
12030 mips32_op = OPC_BLTZAL;
12031 goto do_branch;
12032 case BLTZALS:
12033 mips32_op = OPC_BLTZALS;
12034 goto do_branch;
12035 case BGEZ:
12036 mips32_op = OPC_BGEZ;
12037 goto do_branch;
12038 case BGEZAL:
12039 mips32_op = OPC_BGEZAL;
12040 goto do_branch;
12041 case BGEZALS:
12042 mips32_op = OPC_BGEZALS;
12043 goto do_branch;
12044 case BLEZ:
12045 mips32_op = OPC_BLEZ;
12046 goto do_branch;
12047 case BGTZ:
12048 mips32_op = OPC_BGTZ;
12049 do_branch:
12050 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12051 *is_branch = 1;
12052 break;
12053
12054 /* Traps */
12055 case TLTI:
12056 mips32_op = OPC_TLTI;
12057 goto do_trapi;
12058 case TGEI:
12059 mips32_op = OPC_TGEI;
12060 goto do_trapi;
12061 case TLTIU:
12062 mips32_op = OPC_TLTIU;
12063 goto do_trapi;
12064 case TGEIU:
12065 mips32_op = OPC_TGEIU;
12066 goto do_trapi;
12067 case TNEI:
12068 mips32_op = OPC_TNEI;
12069 goto do_trapi;
12070 case TEQI:
12071 mips32_op = OPC_TEQI;
12072 do_trapi:
12073 gen_trap(ctx, mips32_op, rs, -1, imm);
12074 break;
12075
12076 case BNEZC:
12077 case BEQZC:
12078 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12079 4, rs, 0, imm << 1);
12080 /* Compact branches don't have a delay slot, so just let
12081 the normal delay slot handling take us to the branch
12082 target. */
12083 break;
12084 case LUI:
d75c135e 12085 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12086 break;
12087 case SYNCI:
12088 break;
12089 case BC2F:
12090 case BC2T:
12091 /* COP2: Not implemented. */
12092 generate_exception_err(ctx, EXCP_CpU, 2);
12093 break;
12094 case BC1F:
12095 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12096 goto do_cp1branch;
12097 case BC1T:
12098 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12099 goto do_cp1branch;
12100 case BC1ANY4F:
12101 mips32_op = OPC_BC1FANY4;
12102 goto do_cp1mips3d;
12103 case BC1ANY4T:
12104 mips32_op = OPC_BC1TANY4;
12105 do_cp1mips3d:
12106 check_cop1x(ctx);
d75c135e 12107 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12108 /* Fall through */
12109 do_cp1branch:
d75c135e 12110 gen_compute_branch1(ctx, mips32_op,
3c824109
NF
12111 (ctx->opcode >> 18) & 0x7, imm << 1);
12112 *is_branch = 1;
12113 break;
12114 case BPOSGE64:
12115 case BPOSGE32:
12116 /* MIPS DSP: not implemented */
12117 /* Fall through */
12118 default:
12119 MIPS_INVAL("pool32i");
12120 generate_exception(ctx, EXCP_RI);
12121 break;
12122 }
12123 break;
12124 case POOL32C:
12125 minor = (ctx->opcode >> 12) & 0xf;
12126 switch (minor) {
12127 case LWL:
12128 mips32_op = OPC_LWL;
5c13fdfd 12129 goto do_ld_lr;
3c824109
NF
12130 case SWL:
12131 mips32_op = OPC_SWL;
5c13fdfd 12132 goto do_st_lr;
3c824109
NF
12133 case LWR:
12134 mips32_op = OPC_LWR;
5c13fdfd 12135 goto do_ld_lr;
3c824109
NF
12136 case SWR:
12137 mips32_op = OPC_SWR;
5c13fdfd 12138 goto do_st_lr;
3c824109
NF
12139#if defined(TARGET_MIPS64)
12140 case LDL:
12141 mips32_op = OPC_LDL;
5c13fdfd 12142 goto do_ld_lr;
3c824109
NF
12143 case SDL:
12144 mips32_op = OPC_SDL;
5c13fdfd 12145 goto do_st_lr;
3c824109
NF
12146 case LDR:
12147 mips32_op = OPC_LDR;
5c13fdfd 12148 goto do_ld_lr;
3c824109
NF
12149 case SDR:
12150 mips32_op = OPC_SDR;
5c13fdfd 12151 goto do_st_lr;
3c824109
NF
12152 case LWU:
12153 mips32_op = OPC_LWU;
5c13fdfd 12154 goto do_ld_lr;
3c824109
NF
12155 case LLD:
12156 mips32_op = OPC_LLD;
5c13fdfd 12157 goto do_ld_lr;
3c824109
NF
12158#endif
12159 case LL:
12160 mips32_op = OPC_LL;
5c13fdfd
AJ
12161 goto do_ld_lr;
12162 do_ld_lr:
d75c135e 12163 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12164 break;
12165 do_st_lr:
12166 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12167 break;
12168 case SC:
12169 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12170 break;
12171#if defined(TARGET_MIPS64)
12172 case SCD:
12173 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12174 break;
12175#endif
12176 case PREF:
12177 /* Treat as no-op */
12178 break;
12179 default:
12180 MIPS_INVAL("pool32c");
12181 generate_exception(ctx, EXCP_RI);
12182 break;
12183 }
12184 break;
12185 case ADDI32:
12186 mips32_op = OPC_ADDI;
12187 goto do_addi;
12188 case ADDIU32:
12189 mips32_op = OPC_ADDIU;
12190 do_addi:
d75c135e 12191 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12192 break;
12193
12194 /* Logical operations */
12195 case ORI32:
12196 mips32_op = OPC_ORI;
12197 goto do_logici;
12198 case XORI32:
12199 mips32_op = OPC_XORI;
12200 goto do_logici;
12201 case ANDI32:
12202 mips32_op = OPC_ANDI;
12203 do_logici:
d75c135e 12204 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12205 break;
12206
12207 /* Set less than immediate */
12208 case SLTI32:
12209 mips32_op = OPC_SLTI;
12210 goto do_slti;
12211 case SLTIU32:
12212 mips32_op = OPC_SLTIU;
12213 do_slti:
d75c135e 12214 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12215 break;
12216 case JALX32:
12217 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12218 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12219 *is_branch = 1;
12220 break;
12221 case JALS32:
12222 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12223 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12224 *is_branch = 1;
12225 break;
12226 case BEQ32:
12227 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12228 *is_branch = 1;
12229 break;
12230 case BNE32:
12231 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12232 *is_branch = 1;
12233 break;
12234 case J32:
12235 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12236 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12237 *is_branch = 1;
12238 break;
12239 case JAL32:
12240 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12241 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12242 *is_branch = 1;
12243 break;
12244 /* Floating point (COP1) */
12245 case LWC132:
12246 mips32_op = OPC_LWC1;
12247 goto do_cop1;
12248 case LDC132:
12249 mips32_op = OPC_LDC1;
12250 goto do_cop1;
12251 case SWC132:
12252 mips32_op = OPC_SWC1;
12253 goto do_cop1;
12254 case SDC132:
12255 mips32_op = OPC_SDC1;
12256 do_cop1:
12257 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12258 break;
12259 case ADDIUPC:
12260 {
12261 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12262 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12263
12264 gen_addiupc(ctx, reg, offset, 0, 0);
12265 }
12266 break;
12267 /* Loads and stores */
12268 case LB32:
12269 mips32_op = OPC_LB;
5c13fdfd 12270 goto do_ld;
3c824109
NF
12271 case LBU32:
12272 mips32_op = OPC_LBU;
5c13fdfd 12273 goto do_ld;
3c824109
NF
12274 case LH32:
12275 mips32_op = OPC_LH;
5c13fdfd 12276 goto do_ld;
3c824109
NF
12277 case LHU32:
12278 mips32_op = OPC_LHU;
5c13fdfd 12279 goto do_ld;
3c824109
NF
12280 case LW32:
12281 mips32_op = OPC_LW;
5c13fdfd 12282 goto do_ld;
3c824109
NF
12283#ifdef TARGET_MIPS64
12284 case LD32:
12285 mips32_op = OPC_LD;
5c13fdfd 12286 goto do_ld;
3c824109
NF
12287 case SD32:
12288 mips32_op = OPC_SD;
5c13fdfd 12289 goto do_st;
3c824109
NF
12290#endif
12291 case SB32:
12292 mips32_op = OPC_SB;
5c13fdfd 12293 goto do_st;
3c824109
NF
12294 case SH32:
12295 mips32_op = OPC_SH;
5c13fdfd 12296 goto do_st;
3c824109
NF
12297 case SW32:
12298 mips32_op = OPC_SW;
5c13fdfd
AJ
12299 goto do_st;
12300 do_ld:
d75c135e 12301 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12302 break;
12303 do_st:
12304 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12305 break;
12306 default:
12307 generate_exception(ctx, EXCP_RI);
12308 break;
12309 }
12310}
12311
7db13fae 12312static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
12313{
12314 uint32_t op;
12315
12316 /* make sure instructions are on a halfword boundary */
12317 if (ctx->pc & 0x1) {
12318 env->CP0_BadVAddr = ctx->pc;
12319 generate_exception(ctx, EXCP_AdEL);
12320 ctx->bstate = BS_STOP;
12321 return 2;
12322 }
12323
12324 op = (ctx->opcode >> 10) & 0x3f;
12325 /* Enforce properly-sized instructions in a delay slot */
12326 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12327 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12328
12329 switch (op) {
12330 case POOL32A:
12331 case POOL32B:
12332 case POOL32I:
12333 case POOL32C:
12334 case ADDI32:
12335 case ADDIU32:
12336 case ORI32:
12337 case XORI32:
12338 case SLTI32:
12339 case SLTIU32:
12340 case ANDI32:
12341 case JALX32:
12342 case LBU32:
12343 case LHU32:
12344 case POOL32F:
12345 case JALS32:
12346 case BEQ32:
12347 case BNE32:
12348 case J32:
12349 case JAL32:
12350 case SB32:
12351 case SH32:
12352 case POOL32S:
12353 case ADDIUPC:
12354 case SWC132:
12355 case SDC132:
12356 case SD32:
12357 case SW32:
12358 case LB32:
12359 case LH32:
12360 case DADDIU32:
3c824109
NF
12361 case LWC132:
12362 case LDC132:
12363 case LD32:
12364 case LW32:
12365 if (bits & MIPS_HFLAG_BDS16) {
12366 generate_exception(ctx, EXCP_RI);
12367 /* Just stop translation; the user is confused. */
12368 ctx->bstate = BS_STOP;
12369 return 2;
12370 }
12371 break;
12372 case POOL16A:
12373 case POOL16B:
12374 case POOL16C:
12375 case LWGP16:
12376 case POOL16F:
12377 case LBU16:
12378 case LHU16:
12379 case LWSP16:
12380 case LW16:
12381 case SB16:
12382 case SH16:
12383 case SWSP16:
12384 case SW16:
12385 case MOVE16:
12386 case ANDI16:
12387 case POOL16D:
12388 case POOL16E:
12389 case BEQZ16:
12390 case BNEZ16:
12391 case B16:
12392 case LI16:
12393 if (bits & MIPS_HFLAG_BDS32) {
12394 generate_exception(ctx, EXCP_RI);
12395 /* Just stop translation; the user is confused. */
12396 ctx->bstate = BS_STOP;
12397 return 2;
12398 }
12399 break;
12400 default:
12401 break;
12402 }
12403 }
12404 switch (op) {
12405 case POOL16A:
12406 {
12407 int rd = mmreg(uMIPS_RD(ctx->opcode));
12408 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12409 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12410 uint32_t opc = 0;
12411
12412 switch (ctx->opcode & 0x1) {
12413 case ADDU16:
12414 opc = OPC_ADDU;
12415 break;
12416 case SUBU16:
12417 opc = OPC_SUBU;
12418 break;
12419 }
12420
d75c135e 12421 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12422 }
12423 break;
12424 case POOL16B:
12425 {
12426 int rd = mmreg(uMIPS_RD(ctx->opcode));
12427 int rs = mmreg(uMIPS_RS(ctx->opcode));
12428 int amount = (ctx->opcode >> 1) & 0x7;
12429 uint32_t opc = 0;
12430 amount = amount == 0 ? 8 : amount;
12431
12432 switch (ctx->opcode & 0x1) {
12433 case SLL16:
12434 opc = OPC_SLL;
12435 break;
12436 case SRL16:
12437 opc = OPC_SRL;
12438 break;
12439 }
12440
d75c135e 12441 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12442 }
12443 break;
12444 case POOL16C:
d75c135e 12445 gen_pool16c_insn(ctx, is_branch);
3c824109
NF
12446 break;
12447 case LWGP16:
12448 {
12449 int rd = mmreg(uMIPS_RD(ctx->opcode));
12450 int rb = 28; /* GP */
12451 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12452
d75c135e 12453 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12454 }
12455 break;
12456 case POOL16F:
12457 if (ctx->opcode & 1) {
12458 generate_exception(ctx, EXCP_RI);
12459 } else {
12460 /* MOVEP */
12461 int enc_dest = uMIPS_RD(ctx->opcode);
12462 int enc_rt = uMIPS_RS2(ctx->opcode);
12463 int enc_rs = uMIPS_RS1(ctx->opcode);
12464 int rd, rs, re, rt;
12465 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12466 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12467 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12468
12469 rd = rd_enc[enc_dest];
12470 re = re_enc[enc_dest];
12471 rs = rs_rt_enc[enc_rs];
12472 rt = rs_rt_enc[enc_rt];
12473
d75c135e
AJ
12474 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12475 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12476 }
12477 break;
12478 case LBU16:
12479 {
12480 int rd = mmreg(uMIPS_RD(ctx->opcode));
12481 int rb = mmreg(uMIPS_RS(ctx->opcode));
12482 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12483 offset = (offset == 0xf ? -1 : offset);
12484
d75c135e 12485 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12486 }
12487 break;
12488 case LHU16:
12489 {
12490 int rd = mmreg(uMIPS_RD(ctx->opcode));
12491 int rb = mmreg(uMIPS_RS(ctx->opcode));
12492 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12493
d75c135e 12494 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12495 }
12496 break;
12497 case LWSP16:
12498 {
12499 int rd = (ctx->opcode >> 5) & 0x1f;
12500 int rb = 29; /* SP */
12501 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12502
d75c135e 12503 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12504 }
12505 break;
12506 case LW16:
12507 {
12508 int rd = mmreg(uMIPS_RD(ctx->opcode));
12509 int rb = mmreg(uMIPS_RS(ctx->opcode));
12510 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12511
d75c135e 12512 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12513 }
12514 break;
12515 case SB16:
12516 {
12517 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12518 int rb = mmreg(uMIPS_RS(ctx->opcode));
12519 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12520
5c13fdfd 12521 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12522 }
12523 break;
12524 case SH16:
12525 {
12526 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12527 int rb = mmreg(uMIPS_RS(ctx->opcode));
12528 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12529
5c13fdfd 12530 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12531 }
12532 break;
12533 case SWSP16:
12534 {
12535 int rd = (ctx->opcode >> 5) & 0x1f;
12536 int rb = 29; /* SP */
12537 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12538
5c13fdfd 12539 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12540 }
12541 break;
12542 case SW16:
12543 {
12544 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12545 int rb = mmreg(uMIPS_RS(ctx->opcode));
12546 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12547
5c13fdfd 12548 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12549 }
12550 break;
12551 case MOVE16:
12552 {
12553 int rd = uMIPS_RD5(ctx->opcode);
12554 int rs = uMIPS_RS5(ctx->opcode);
12555
d75c135e 12556 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12557 }
12558 break;
12559 case ANDI16:
d75c135e 12560 gen_andi16(ctx);
3c824109
NF
12561 break;
12562 case POOL16D:
12563 switch (ctx->opcode & 0x1) {
12564 case ADDIUS5:
d75c135e 12565 gen_addius5(ctx);
3c824109
NF
12566 break;
12567 case ADDIUSP:
d75c135e 12568 gen_addiusp(ctx);
3c824109
NF
12569 break;
12570 }
12571 break;
12572 case POOL16E:
12573 switch (ctx->opcode & 0x1) {
12574 case ADDIUR2:
d75c135e 12575 gen_addiur2(ctx);
3c824109
NF
12576 break;
12577 case ADDIUR1SP:
d75c135e 12578 gen_addiur1sp(ctx);
3c824109
NF
12579 break;
12580 }
12581 break;
12582 case B16:
12583 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12584 SIMM(ctx->opcode, 0, 10) << 1);
12585 *is_branch = 1;
12586 break;
12587 case BNEZ16:
12588 case BEQZ16:
12589 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12590 mmreg(uMIPS_RD(ctx->opcode)),
12591 0, SIMM(ctx->opcode, 0, 7) << 1);
12592 *is_branch = 1;
12593 break;
12594 case LI16:
12595 {
12596 int reg = mmreg(uMIPS_RD(ctx->opcode));
12597 int imm = ZIMM(ctx->opcode, 0, 7);
12598
12599 imm = (imm == 0x7f ? -1 : imm);
12600 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12601 }
12602 break;
12603 case RES_20:
12604 case RES_28:
12605 case RES_29:
12606 case RES_30:
12607 case RES_31:
12608 case RES_38:
12609 case RES_39:
12610 generate_exception(ctx, EXCP_RI);
12611 break;
12612 default:
12613 decode_micromips32_opc (env, ctx, op, is_branch);
12614 return 4;
12615 }
12616
12617 return 2;
12618}
12619
12620/* SmartMIPS extension to MIPS32 */
12621
12622#if defined(TARGET_MIPS64)
12623
12624/* MDMX extension to MIPS64 */
12625
12626#endif
12627
9b1a1d68 12628/* MIPSDSP functions. */
d75c135e 12629static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12630 int rd, int base, int offset)
12631{
12632 const char *opn = "ldx";
12633 TCGv t0;
12634
9b1a1d68
JL
12635 check_dsp(ctx);
12636 t0 = tcg_temp_new();
12637
12638 if (base == 0) {
12639 gen_load_gpr(t0, offset);
12640 } else if (offset == 0) {
12641 gen_load_gpr(t0, base);
12642 } else {
12643 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12644 }
12645
9b1a1d68
JL
12646 switch (opc) {
12647 case OPC_LBUX:
2910c6cb 12648 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12649 gen_store_gpr(t0, rd);
12650 opn = "lbux";
12651 break;
12652 case OPC_LHX:
2910c6cb 12653 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12654 gen_store_gpr(t0, rd);
12655 opn = "lhx";
12656 break;
12657 case OPC_LWX:
2910c6cb 12658 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12659 gen_store_gpr(t0, rd);
12660 opn = "lwx";
12661 break;
12662#if defined(TARGET_MIPS64)
12663 case OPC_LDX:
2910c6cb 12664 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12665 gen_store_gpr(t0, rd);
12666 opn = "ldx";
12667 break;
12668#endif
12669 }
12670 (void)opn; /* avoid a compiler warning */
12671 MIPS_DEBUG("%s %s, %s(%s)", opn,
12672 regnames[rd], regnames[offset], regnames[base]);
12673 tcg_temp_free(t0);
12674}
12675
461c08df
JL
12676static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12677 int ret, int v1, int v2)
12678{
12679 const char *opn = "mipsdsp arith";
12680 TCGv v1_t;
12681 TCGv v2_t;
12682
12683 if (ret == 0) {
12684 /* Treat as NOP. */
12685 MIPS_DEBUG("NOP");
12686 return;
12687 }
12688
12689 v1_t = tcg_temp_new();
12690 v2_t = tcg_temp_new();
12691
12692 gen_load_gpr(v1_t, v1);
12693 gen_load_gpr(v2_t, v2);
12694
12695 switch (op1) {
12696 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12697 case OPC_MULT_G_2E:
12698 check_dspr2(ctx);
12699 switch (op2) {
12700 case OPC_ADDUH_QB:
12701 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12702 break;
12703 case OPC_ADDUH_R_QB:
12704 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12705 break;
12706 case OPC_ADDQH_PH:
12707 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12708 break;
12709 case OPC_ADDQH_R_PH:
12710 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12711 break;
12712 case OPC_ADDQH_W:
12713 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12714 break;
12715 case OPC_ADDQH_R_W:
12716 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12717 break;
12718 case OPC_SUBUH_QB:
12719 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12720 break;
12721 case OPC_SUBUH_R_QB:
12722 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12723 break;
12724 case OPC_SUBQH_PH:
12725 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12726 break;
12727 case OPC_SUBQH_R_PH:
12728 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12729 break;
12730 case OPC_SUBQH_W:
12731 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12732 break;
12733 case OPC_SUBQH_R_W:
12734 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12735 break;
12736 }
12737 break;
12738 case OPC_ABSQ_S_PH_DSP:
12739 switch (op2) {
12740 case OPC_ABSQ_S_QB:
12741 check_dspr2(ctx);
12742 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12743 break;
12744 case OPC_ABSQ_S_PH:
12745 check_dsp(ctx);
12746 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12747 break;
12748 case OPC_ABSQ_S_W:
12749 check_dsp(ctx);
12750 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12751 break;
12752 case OPC_PRECEQ_W_PHL:
12753 check_dsp(ctx);
12754 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12755 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12756 break;
12757 case OPC_PRECEQ_W_PHR:
12758 check_dsp(ctx);
12759 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12760 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12761 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12762 break;
12763 case OPC_PRECEQU_PH_QBL:
12764 check_dsp(ctx);
12765 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12766 break;
12767 case OPC_PRECEQU_PH_QBR:
12768 check_dsp(ctx);
12769 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12770 break;
12771 case OPC_PRECEQU_PH_QBLA:
12772 check_dsp(ctx);
12773 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12774 break;
12775 case OPC_PRECEQU_PH_QBRA:
12776 check_dsp(ctx);
12777 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12778 break;
12779 case OPC_PRECEU_PH_QBL:
12780 check_dsp(ctx);
12781 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12782 break;
12783 case OPC_PRECEU_PH_QBR:
12784 check_dsp(ctx);
12785 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12786 break;
12787 case OPC_PRECEU_PH_QBLA:
12788 check_dsp(ctx);
12789 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12790 break;
12791 case OPC_PRECEU_PH_QBRA:
12792 check_dsp(ctx);
12793 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12794 break;
12795 }
12796 break;
12797 case OPC_ADDU_QB_DSP:
12798 switch (op2) {
12799 case OPC_ADDQ_PH:
12800 check_dsp(ctx);
12801 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12802 break;
12803 case OPC_ADDQ_S_PH:
12804 check_dsp(ctx);
12805 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12806 break;
12807 case OPC_ADDQ_S_W:
12808 check_dsp(ctx);
12809 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12810 break;
12811 case OPC_ADDU_QB:
12812 check_dsp(ctx);
12813 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12814 break;
12815 case OPC_ADDU_S_QB:
12816 check_dsp(ctx);
12817 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12818 break;
12819 case OPC_ADDU_PH:
12820 check_dspr2(ctx);
12821 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12822 break;
12823 case OPC_ADDU_S_PH:
12824 check_dspr2(ctx);
12825 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12826 break;
12827 case OPC_SUBQ_PH:
12828 check_dsp(ctx);
12829 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12830 break;
12831 case OPC_SUBQ_S_PH:
12832 check_dsp(ctx);
12833 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12834 break;
12835 case OPC_SUBQ_S_W:
12836 check_dsp(ctx);
12837 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12838 break;
12839 case OPC_SUBU_QB:
12840 check_dsp(ctx);
12841 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12842 break;
12843 case OPC_SUBU_S_QB:
12844 check_dsp(ctx);
12845 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12846 break;
12847 case OPC_SUBU_PH:
12848 check_dspr2(ctx);
12849 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12850 break;
12851 case OPC_SUBU_S_PH:
12852 check_dspr2(ctx);
12853 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12854 break;
12855 case OPC_ADDSC:
12856 check_dsp(ctx);
12857 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12858 break;
12859 case OPC_ADDWC:
12860 check_dsp(ctx);
12861 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12862 break;
12863 case OPC_MODSUB:
12864 check_dsp(ctx);
12865 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12866 break;
12867 case OPC_RADDU_W_QB:
12868 check_dsp(ctx);
12869 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12870 break;
12871 }
12872 break;
12873 case OPC_CMPU_EQ_QB_DSP:
12874 switch (op2) {
12875 case OPC_PRECR_QB_PH:
12876 check_dspr2(ctx);
12877 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12878 break;
12879 case OPC_PRECRQ_QB_PH:
12880 check_dsp(ctx);
12881 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12882 break;
12883 case OPC_PRECR_SRA_PH_W:
12884 check_dspr2(ctx);
12885 {
12886 TCGv_i32 sa_t = tcg_const_i32(v2);
12887 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12888 cpu_gpr[ret]);
12889 tcg_temp_free_i32(sa_t);
12890 break;
12891 }
12892 case OPC_PRECR_SRA_R_PH_W:
12893 check_dspr2(ctx);
12894 {
12895 TCGv_i32 sa_t = tcg_const_i32(v2);
12896 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12897 cpu_gpr[ret]);
12898 tcg_temp_free_i32(sa_t);
12899 break;
12900 }
12901 case OPC_PRECRQ_PH_W:
12902 check_dsp(ctx);
12903 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12904 break;
12905 case OPC_PRECRQ_RS_PH_W:
12906 check_dsp(ctx);
12907 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12908 break;
12909 case OPC_PRECRQU_S_QB_PH:
12910 check_dsp(ctx);
12911 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12912 break;
12913 }
12914 break;
12915#ifdef TARGET_MIPS64
12916 case OPC_ABSQ_S_QH_DSP:
12917 switch (op2) {
12918 case OPC_PRECEQ_L_PWL:
12919 check_dsp(ctx);
12920 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12921 break;
12922 case OPC_PRECEQ_L_PWR:
12923 check_dsp(ctx);
12924 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12925 break;
12926 case OPC_PRECEQ_PW_QHL:
12927 check_dsp(ctx);
12928 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12929 break;
12930 case OPC_PRECEQ_PW_QHR:
12931 check_dsp(ctx);
12932 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12933 break;
12934 case OPC_PRECEQ_PW_QHLA:
12935 check_dsp(ctx);
12936 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12937 break;
12938 case OPC_PRECEQ_PW_QHRA:
12939 check_dsp(ctx);
12940 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12941 break;
12942 case OPC_PRECEQU_QH_OBL:
12943 check_dsp(ctx);
12944 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12945 break;
12946 case OPC_PRECEQU_QH_OBR:
12947 check_dsp(ctx);
12948 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12949 break;
12950 case OPC_PRECEQU_QH_OBLA:
12951 check_dsp(ctx);
12952 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12953 break;
12954 case OPC_PRECEQU_QH_OBRA:
12955 check_dsp(ctx);
12956 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12957 break;
12958 case OPC_PRECEU_QH_OBL:
12959 check_dsp(ctx);
12960 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12961 break;
12962 case OPC_PRECEU_QH_OBR:
12963 check_dsp(ctx);
12964 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12965 break;
12966 case OPC_PRECEU_QH_OBLA:
12967 check_dsp(ctx);
12968 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12969 break;
12970 case OPC_PRECEU_QH_OBRA:
12971 check_dsp(ctx);
12972 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12973 break;
12974 case OPC_ABSQ_S_OB:
12975 check_dspr2(ctx);
12976 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12977 break;
12978 case OPC_ABSQ_S_PW:
12979 check_dsp(ctx);
12980 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12981 break;
12982 case OPC_ABSQ_S_QH:
12983 check_dsp(ctx);
12984 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12985 break;
12986 }
12987 break;
12988 case OPC_ADDU_OB_DSP:
12989 switch (op2) {
12990 case OPC_RADDU_L_OB:
12991 check_dsp(ctx);
12992 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12993 break;
12994 case OPC_SUBQ_PW:
12995 check_dsp(ctx);
12996 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12997 break;
12998 case OPC_SUBQ_S_PW:
12999 check_dsp(ctx);
13000 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13001 break;
13002 case OPC_SUBQ_QH:
13003 check_dsp(ctx);
13004 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13005 break;
13006 case OPC_SUBQ_S_QH:
13007 check_dsp(ctx);
13008 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13009 break;
13010 case OPC_SUBU_OB:
13011 check_dsp(ctx);
13012 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13013 break;
13014 case OPC_SUBU_S_OB:
13015 check_dsp(ctx);
13016 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13017 break;
13018 case OPC_SUBU_QH:
13019 check_dspr2(ctx);
13020 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13021 break;
13022 case OPC_SUBU_S_QH:
13023 check_dspr2(ctx);
13024 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13025 break;
13026 case OPC_SUBUH_OB:
13027 check_dspr2(ctx);
13028 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13029 break;
13030 case OPC_SUBUH_R_OB:
13031 check_dspr2(ctx);
13032 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13033 break;
13034 case OPC_ADDQ_PW:
13035 check_dsp(ctx);
13036 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13037 break;
13038 case OPC_ADDQ_S_PW:
13039 check_dsp(ctx);
13040 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13041 break;
13042 case OPC_ADDQ_QH:
13043 check_dsp(ctx);
13044 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13045 break;
13046 case OPC_ADDQ_S_QH:
13047 check_dsp(ctx);
13048 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13049 break;
13050 case OPC_ADDU_OB:
13051 check_dsp(ctx);
13052 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13053 break;
13054 case OPC_ADDU_S_OB:
13055 check_dsp(ctx);
13056 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13057 break;
13058 case OPC_ADDU_QH:
13059 check_dspr2(ctx);
13060 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13061 break;
13062 case OPC_ADDU_S_QH:
13063 check_dspr2(ctx);
13064 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13065 break;
13066 case OPC_ADDUH_OB:
13067 check_dspr2(ctx);
13068 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13069 break;
13070 case OPC_ADDUH_R_OB:
13071 check_dspr2(ctx);
13072 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13073 break;
13074 }
13075 break;
13076 case OPC_CMPU_EQ_OB_DSP:
13077 switch (op2) {
13078 case OPC_PRECR_OB_QH:
13079 check_dspr2(ctx);
13080 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13081 break;
13082 case OPC_PRECR_SRA_QH_PW:
13083 check_dspr2(ctx);
13084 {
13085 TCGv_i32 ret_t = tcg_const_i32(ret);
13086 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13087 tcg_temp_free_i32(ret_t);
13088 break;
13089 }
13090 case OPC_PRECR_SRA_R_QH_PW:
13091 check_dspr2(ctx);
13092 {
13093 TCGv_i32 sa_v = tcg_const_i32(ret);
13094 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13095 tcg_temp_free_i32(sa_v);
13096 break;
13097 }
13098 case OPC_PRECRQ_OB_QH:
13099 check_dsp(ctx);
13100 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13101 break;
13102 case OPC_PRECRQ_PW_L:
13103 check_dsp(ctx);
13104 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13105 break;
13106 case OPC_PRECRQ_QH_PW:
13107 check_dsp(ctx);
13108 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13109 break;
13110 case OPC_PRECRQ_RS_QH_PW:
13111 check_dsp(ctx);
13112 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13113 break;
13114 case OPC_PRECRQU_S_OB_QH:
13115 check_dsp(ctx);
13116 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13117 break;
13118 }
13119 break;
13120#endif
13121 }
13122
13123 tcg_temp_free(v1_t);
13124 tcg_temp_free(v2_t);
13125
13126 (void)opn; /* avoid a compiler warning */
13127 MIPS_DEBUG("%s", opn);
13128}
9b1a1d68 13129
77c5fa8b
JL
13130static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13131 int ret, int v1, int v2)
13132{
13133 uint32_t op2;
13134 const char *opn = "mipsdsp shift";
13135 TCGv t0;
13136 TCGv v1_t;
13137 TCGv v2_t;
13138
13139 if (ret == 0) {
13140 /* Treat as NOP. */
13141 MIPS_DEBUG("NOP");
13142 return;
13143 }
13144
13145 t0 = tcg_temp_new();
13146 v1_t = tcg_temp_new();
13147 v2_t = tcg_temp_new();
13148
13149 tcg_gen_movi_tl(t0, v1);
13150 gen_load_gpr(v1_t, v1);
13151 gen_load_gpr(v2_t, v2);
13152
13153 switch (opc) {
13154 case OPC_SHLL_QB_DSP:
13155 {
13156 op2 = MASK_SHLL_QB(ctx->opcode);
13157 switch (op2) {
13158 case OPC_SHLL_QB:
13159 check_dsp(ctx);
13160 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13161 break;
13162 case OPC_SHLLV_QB:
13163 check_dsp(ctx);
13164 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13165 break;
13166 case OPC_SHLL_PH:
13167 check_dsp(ctx);
13168 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13169 break;
13170 case OPC_SHLLV_PH:
13171 check_dsp(ctx);
13172 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13173 break;
13174 case OPC_SHLL_S_PH:
13175 check_dsp(ctx);
13176 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13177 break;
13178 case OPC_SHLLV_S_PH:
13179 check_dsp(ctx);
13180 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13181 break;
13182 case OPC_SHLL_S_W:
13183 check_dsp(ctx);
13184 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13185 break;
13186 case OPC_SHLLV_S_W:
13187 check_dsp(ctx);
13188 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13189 break;
13190 case OPC_SHRL_QB:
13191 check_dsp(ctx);
13192 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13193 break;
13194 case OPC_SHRLV_QB:
13195 check_dsp(ctx);
13196 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13197 break;
13198 case OPC_SHRL_PH:
13199 check_dspr2(ctx);
13200 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13201 break;
13202 case OPC_SHRLV_PH:
13203 check_dspr2(ctx);
13204 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13205 break;
13206 case OPC_SHRA_QB:
13207 check_dspr2(ctx);
13208 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13209 break;
13210 case OPC_SHRA_R_QB:
13211 check_dspr2(ctx);
13212 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13213 break;
13214 case OPC_SHRAV_QB:
13215 check_dspr2(ctx);
13216 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13217 break;
13218 case OPC_SHRAV_R_QB:
13219 check_dspr2(ctx);
13220 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13221 break;
13222 case OPC_SHRA_PH:
13223 check_dsp(ctx);
13224 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13225 break;
13226 case OPC_SHRA_R_PH:
13227 check_dsp(ctx);
13228 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13229 break;
13230 case OPC_SHRAV_PH:
13231 check_dsp(ctx);
13232 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13233 break;
13234 case OPC_SHRAV_R_PH:
13235 check_dsp(ctx);
13236 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13237 break;
13238 case OPC_SHRA_R_W:
13239 check_dsp(ctx);
13240 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13241 break;
13242 case OPC_SHRAV_R_W:
13243 check_dsp(ctx);
13244 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13245 break;
13246 default: /* Invalid */
13247 MIPS_INVAL("MASK SHLL.QB");
13248 generate_exception(ctx, EXCP_RI);
13249 break;
13250 }
13251 break;
13252 }
13253#ifdef TARGET_MIPS64
13254 case OPC_SHLL_OB_DSP:
13255 op2 = MASK_SHLL_OB(ctx->opcode);
13256 switch (op2) {
13257 case OPC_SHLL_PW:
13258 check_dsp(ctx);
13259 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13260 break;
13261 case OPC_SHLLV_PW:
13262 check_dsp(ctx);
13263 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13264 break;
13265 case OPC_SHLL_S_PW:
13266 check_dsp(ctx);
13267 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13268 break;
13269 case OPC_SHLLV_S_PW:
13270 check_dsp(ctx);
13271 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13272 break;
13273 case OPC_SHLL_OB:
13274 check_dsp(ctx);
13275 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13276 break;
13277 case OPC_SHLLV_OB:
13278 check_dsp(ctx);
13279 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13280 break;
13281 case OPC_SHLL_QH:
13282 check_dsp(ctx);
13283 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13284 break;
13285 case OPC_SHLLV_QH:
13286 check_dsp(ctx);
13287 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13288 break;
13289 case OPC_SHLL_S_QH:
13290 check_dsp(ctx);
13291 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13292 break;
13293 case OPC_SHLLV_S_QH:
13294 check_dsp(ctx);
13295 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13296 break;
13297 case OPC_SHRA_OB:
13298 check_dspr2(ctx);
13299 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13300 break;
13301 case OPC_SHRAV_OB:
13302 check_dspr2(ctx);
13303 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13304 break;
13305 case OPC_SHRA_R_OB:
13306 check_dspr2(ctx);
13307 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13308 break;
13309 case OPC_SHRAV_R_OB:
13310 check_dspr2(ctx);
13311 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13312 break;
13313 case OPC_SHRA_PW:
13314 check_dsp(ctx);
13315 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13316 break;
13317 case OPC_SHRAV_PW:
13318 check_dsp(ctx);
13319 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13320 break;
13321 case OPC_SHRA_R_PW:
13322 check_dsp(ctx);
13323 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13324 break;
13325 case OPC_SHRAV_R_PW:
13326 check_dsp(ctx);
13327 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13328 break;
13329 case OPC_SHRA_QH:
13330 check_dsp(ctx);
13331 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13332 break;
13333 case OPC_SHRAV_QH:
13334 check_dsp(ctx);
13335 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13336 break;
13337 case OPC_SHRA_R_QH:
13338 check_dsp(ctx);
13339 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13340 break;
13341 case OPC_SHRAV_R_QH:
13342 check_dsp(ctx);
13343 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13344 break;
13345 case OPC_SHRL_OB:
13346 check_dsp(ctx);
13347 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13348 break;
13349 case OPC_SHRLV_OB:
13350 check_dsp(ctx);
13351 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13352 break;
13353 case OPC_SHRL_QH:
13354 check_dspr2(ctx);
13355 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13356 break;
13357 case OPC_SHRLV_QH:
13358 check_dspr2(ctx);
13359 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13360 break;
13361 default: /* Invalid */
13362 MIPS_INVAL("MASK SHLL.OB");
13363 generate_exception(ctx, EXCP_RI);
13364 break;
13365 }
13366 break;
13367#endif
13368 }
13369
13370 tcg_temp_free(t0);
13371 tcg_temp_free(v1_t);
13372 tcg_temp_free(v2_t);
13373 (void)opn; /* avoid a compiler warning */
13374 MIPS_DEBUG("%s", opn);
13375}
13376
a22260ae
JL
13377static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13378 int ret, int v1, int v2, int check_ret)
13379{
13380 const char *opn = "mipsdsp multiply";
13381 TCGv_i32 t0;
13382 TCGv v1_t;
13383 TCGv v2_t;
13384
13385 if ((ret == 0) && (check_ret == 1)) {
13386 /* Treat as NOP. */
13387 MIPS_DEBUG("NOP");
13388 return;
13389 }
13390
13391 t0 = tcg_temp_new_i32();
13392 v1_t = tcg_temp_new();
13393 v2_t = tcg_temp_new();
13394
13395 tcg_gen_movi_i32(t0, ret);
13396 gen_load_gpr(v1_t, v1);
13397 gen_load_gpr(v2_t, v2);
13398
13399 switch (op1) {
13400 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13401 * the same mask and op1. */
13402 case OPC_MULT_G_2E:
639eadb9 13403 check_dspr2(ctx);
a22260ae
JL
13404 switch (op2) {
13405 case OPC_MUL_PH:
13406 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13407 break;
13408 case OPC_MUL_S_PH:
13409 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13410 break;
13411 case OPC_MULQ_S_W:
13412 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13413 break;
13414 case OPC_MULQ_RS_W:
13415 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13416 break;
13417 }
13418 break;
13419 case OPC_DPA_W_PH_DSP:
13420 switch (op2) {
13421 case OPC_DPAU_H_QBL:
13422 check_dsp(ctx);
13423 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13424 break;
13425 case OPC_DPAU_H_QBR:
13426 check_dsp(ctx);
13427 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13428 break;
13429 case OPC_DPSU_H_QBL:
13430 check_dsp(ctx);
13431 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13432 break;
13433 case OPC_DPSU_H_QBR:
13434 check_dsp(ctx);
13435 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13436 break;
13437 case OPC_DPA_W_PH:
13438 check_dspr2(ctx);
13439 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13440 break;
13441 case OPC_DPAX_W_PH:
13442 check_dspr2(ctx);
13443 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13444 break;
13445 case OPC_DPAQ_S_W_PH:
13446 check_dsp(ctx);
13447 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13448 break;
13449 case OPC_DPAQX_S_W_PH:
13450 check_dspr2(ctx);
13451 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13452 break;
13453 case OPC_DPAQX_SA_W_PH:
13454 check_dspr2(ctx);
13455 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13456 break;
13457 case OPC_DPS_W_PH:
13458 check_dspr2(ctx);
13459 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13460 break;
13461 case OPC_DPSX_W_PH:
13462 check_dspr2(ctx);
13463 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13464 break;
13465 case OPC_DPSQ_S_W_PH:
13466 check_dsp(ctx);
13467 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13468 break;
13469 case OPC_DPSQX_S_W_PH:
13470 check_dspr2(ctx);
13471 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13472 break;
13473 case OPC_DPSQX_SA_W_PH:
13474 check_dspr2(ctx);
13475 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13476 break;
13477 case OPC_MULSAQ_S_W_PH:
13478 check_dsp(ctx);
13479 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13480 break;
13481 case OPC_DPAQ_SA_L_W:
13482 check_dsp(ctx);
13483 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13484 break;
13485 case OPC_DPSQ_SA_L_W:
13486 check_dsp(ctx);
13487 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13488 break;
13489 case OPC_MAQ_S_W_PHL:
13490 check_dsp(ctx);
13491 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13492 break;
13493 case OPC_MAQ_S_W_PHR:
13494 check_dsp(ctx);
13495 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13496 break;
13497 case OPC_MAQ_SA_W_PHL:
13498 check_dsp(ctx);
13499 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13500 break;
13501 case OPC_MAQ_SA_W_PHR:
13502 check_dsp(ctx);
13503 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13504 break;
13505 case OPC_MULSA_W_PH:
13506 check_dspr2(ctx);
13507 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13508 break;
13509 }
13510 break;
13511#ifdef TARGET_MIPS64
13512 case OPC_DPAQ_W_QH_DSP:
13513 {
13514 int ac = ret & 0x03;
13515 tcg_gen_movi_i32(t0, ac);
13516
13517 switch (op2) {
13518 case OPC_DMADD:
13519 check_dsp(ctx);
13520 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13521 break;
13522 case OPC_DMADDU:
13523 check_dsp(ctx);
13524 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13525 break;
13526 case OPC_DMSUB:
13527 check_dsp(ctx);
13528 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13529 break;
13530 case OPC_DMSUBU:
13531 check_dsp(ctx);
13532 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13533 break;
13534 case OPC_DPA_W_QH:
13535 check_dspr2(ctx);
13536 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13537 break;
13538 case OPC_DPAQ_S_W_QH:
13539 check_dsp(ctx);
13540 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13541 break;
13542 case OPC_DPAQ_SA_L_PW:
13543 check_dsp(ctx);
13544 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13545 break;
13546 case OPC_DPAU_H_OBL:
13547 check_dsp(ctx);
13548 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13549 break;
13550 case OPC_DPAU_H_OBR:
13551 check_dsp(ctx);
13552 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13553 break;
13554 case OPC_DPS_W_QH:
13555 check_dspr2(ctx);
13556 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13557 break;
13558 case OPC_DPSQ_S_W_QH:
13559 check_dsp(ctx);
13560 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13561 break;
13562 case OPC_DPSQ_SA_L_PW:
13563 check_dsp(ctx);
13564 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13565 break;
13566 case OPC_DPSU_H_OBL:
13567 check_dsp(ctx);
13568 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13569 break;
13570 case OPC_DPSU_H_OBR:
13571 check_dsp(ctx);
13572 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13573 break;
13574 case OPC_MAQ_S_L_PWL:
13575 check_dsp(ctx);
13576 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13577 break;
13578 case OPC_MAQ_S_L_PWR:
13579 check_dsp(ctx);
13580 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13581 break;
13582 case OPC_MAQ_S_W_QHLL:
13583 check_dsp(ctx);
13584 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13585 break;
13586 case OPC_MAQ_SA_W_QHLL:
13587 check_dsp(ctx);
13588 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13589 break;
13590 case OPC_MAQ_S_W_QHLR:
13591 check_dsp(ctx);
13592 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13593 break;
13594 case OPC_MAQ_SA_W_QHLR:
13595 check_dsp(ctx);
13596 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13597 break;
13598 case OPC_MAQ_S_W_QHRL:
13599 check_dsp(ctx);
13600 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13601 break;
13602 case OPC_MAQ_SA_W_QHRL:
13603 check_dsp(ctx);
13604 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13605 break;
13606 case OPC_MAQ_S_W_QHRR:
13607 check_dsp(ctx);
13608 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13609 break;
13610 case OPC_MAQ_SA_W_QHRR:
13611 check_dsp(ctx);
13612 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13613 break;
13614 case OPC_MULSAQ_S_L_PW:
13615 check_dsp(ctx);
13616 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13617 break;
13618 case OPC_MULSAQ_S_W_QH:
13619 check_dsp(ctx);
13620 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13621 break;
13622 }
13623 }
13624 break;
13625#endif
13626 case OPC_ADDU_QB_DSP:
13627 switch (op2) {
13628 case OPC_MULEU_S_PH_QBL:
13629 check_dsp(ctx);
13630 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13631 break;
13632 case OPC_MULEU_S_PH_QBR:
13633 check_dsp(ctx);
13634 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13635 break;
13636 case OPC_MULQ_RS_PH:
13637 check_dsp(ctx);
13638 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13639 break;
13640 case OPC_MULEQ_S_W_PHL:
13641 check_dsp(ctx);
13642 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13643 break;
13644 case OPC_MULEQ_S_W_PHR:
13645 check_dsp(ctx);
13646 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13647 break;
13648 case OPC_MULQ_S_PH:
13649 check_dspr2(ctx);
13650 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13651 break;
13652 }
13653 break;
13654#ifdef TARGET_MIPS64
13655 case OPC_ADDU_OB_DSP:
13656 switch (op2) {
13657 case OPC_MULEQ_S_PW_QHL:
13658 check_dsp(ctx);
13659 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13660 break;
13661 case OPC_MULEQ_S_PW_QHR:
13662 check_dsp(ctx);
13663 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13664 break;
13665 case OPC_MULEU_S_QH_OBL:
13666 check_dsp(ctx);
13667 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 break;
13669 case OPC_MULEU_S_QH_OBR:
13670 check_dsp(ctx);
13671 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 break;
13673 case OPC_MULQ_RS_QH:
13674 check_dsp(ctx);
13675 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 break;
13677 }
13678 break;
13679#endif
13680 }
13681
13682 tcg_temp_free_i32(t0);
13683 tcg_temp_free(v1_t);
13684 tcg_temp_free(v2_t);
13685
13686 (void)opn; /* avoid a compiler warning */
13687 MIPS_DEBUG("%s", opn);
13688
13689}
13690
d75c135e 13691static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13692 int ret, int val)
13693{
13694 const char *opn = "mipsdsp Bit/ Manipulation";
13695 int16_t imm;
13696 TCGv t0;
13697 TCGv val_t;
13698
13699 if (ret == 0) {
13700 /* Treat as NOP. */
13701 MIPS_DEBUG("NOP");
13702 return;
13703 }
13704
13705 t0 = tcg_temp_new();
13706 val_t = tcg_temp_new();
13707 gen_load_gpr(val_t, val);
13708
13709 switch (op1) {
13710 case OPC_ABSQ_S_PH_DSP:
13711 switch (op2) {
13712 case OPC_BITREV:
13713 check_dsp(ctx);
13714 gen_helper_bitrev(cpu_gpr[ret], val_t);
13715 break;
13716 case OPC_REPL_QB:
13717 check_dsp(ctx);
13718 {
13719 target_long result;
13720 imm = (ctx->opcode >> 16) & 0xFF;
13721 result = (uint32_t)imm << 24 |
13722 (uint32_t)imm << 16 |
13723 (uint32_t)imm << 8 |
13724 (uint32_t)imm;
13725 result = (int32_t)result;
13726 tcg_gen_movi_tl(cpu_gpr[ret], result);
13727 }
13728 break;
13729 case OPC_REPLV_QB:
13730 check_dsp(ctx);
13731 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13732 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13733 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13734 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13735 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13736 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13737 break;
13738 case OPC_REPL_PH:
13739 check_dsp(ctx);
13740 {
13741 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13742 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13743 tcg_gen_movi_tl(cpu_gpr[ret], \
13744 (target_long)((int32_t)imm << 16 | \
c4aaba92 13745 (uint16_t)imm));
1cb6686c
JL
13746 }
13747 break;
13748 case OPC_REPLV_PH:
13749 check_dsp(ctx);
13750 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13751 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13752 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13753 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13754 break;
13755 }
13756 break;
13757#ifdef TARGET_MIPS64
13758 case OPC_ABSQ_S_QH_DSP:
13759 switch (op2) {
13760 case OPC_REPL_OB:
13761 check_dsp(ctx);
13762 {
13763 target_long temp;
13764
13765 imm = (ctx->opcode >> 16) & 0xFF;
13766 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13767 temp = (temp << 16) | temp;
13768 temp = (temp << 32) | temp;
13769 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13770 break;
13771 }
13772 case OPC_REPL_PW:
13773 check_dsp(ctx);
13774 {
13775 target_long temp;
13776
13777 imm = (ctx->opcode >> 16) & 0x03FF;
13778 imm = (int16_t)(imm << 6) >> 6;
13779 temp = ((target_long)imm << 32) \
13780 | ((target_long)imm & 0xFFFFFFFF);
13781 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13782 break;
13783 }
13784 case OPC_REPL_QH:
13785 check_dsp(ctx);
13786 {
13787 target_long temp;
13788
13789 imm = (ctx->opcode >> 16) & 0x03FF;
13790 imm = (int16_t)(imm << 6) >> 6;
13791
13792 temp = ((uint64_t)(uint16_t)imm << 48) |
13793 ((uint64_t)(uint16_t)imm << 32) |
13794 ((uint64_t)(uint16_t)imm << 16) |
13795 (uint64_t)(uint16_t)imm;
13796 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13797 break;
13798 }
13799 case OPC_REPLV_OB:
13800 check_dsp(ctx);
13801 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13802 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13803 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13804 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13805 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13806 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13807 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13808 break;
13809 case OPC_REPLV_PW:
13810 check_dsp(ctx);
13811 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13812 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13813 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13814 break;
13815 case OPC_REPLV_QH:
13816 check_dsp(ctx);
13817 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13818 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13819 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13820 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13821 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13822 break;
13823 }
13824 break;
13825#endif
13826 }
13827 tcg_temp_free(t0);
13828 tcg_temp_free(val_t);
13829
13830 (void)opn; /* avoid a compiler warning */
13831 MIPS_DEBUG("%s", opn);
13832}
13833
26690560
JL
13834static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13835 uint32_t op1, uint32_t op2,
13836 int ret, int v1, int v2, int check_ret)
13837{
13838 const char *opn = "mipsdsp add compare pick";
26690560
JL
13839 TCGv t1;
13840 TCGv v1_t;
13841 TCGv v2_t;
13842
13843 if ((ret == 0) && (check_ret == 1)) {
13844 /* Treat as NOP. */
13845 MIPS_DEBUG("NOP");
13846 return;
13847 }
13848
26690560
JL
13849 t1 = tcg_temp_new();
13850 v1_t = tcg_temp_new();
13851 v2_t = tcg_temp_new();
13852
13853 gen_load_gpr(v1_t, v1);
13854 gen_load_gpr(v2_t, v2);
13855
13856 switch (op1) {
26690560
JL
13857 case OPC_CMPU_EQ_QB_DSP:
13858 switch (op2) {
13859 case OPC_CMPU_EQ_QB:
13860 check_dsp(ctx);
13861 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13862 break;
13863 case OPC_CMPU_LT_QB:
13864 check_dsp(ctx);
13865 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13866 break;
13867 case OPC_CMPU_LE_QB:
13868 check_dsp(ctx);
13869 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13870 break;
13871 case OPC_CMPGU_EQ_QB:
13872 check_dsp(ctx);
13873 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13874 break;
13875 case OPC_CMPGU_LT_QB:
13876 check_dsp(ctx);
13877 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13878 break;
13879 case OPC_CMPGU_LE_QB:
13880 check_dsp(ctx);
13881 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13882 break;
13883 case OPC_CMPGDU_EQ_QB:
13884 check_dspr2(ctx);
13885 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13886 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13887 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13888 tcg_gen_shli_tl(t1, t1, 24);
13889 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13890 break;
13891 case OPC_CMPGDU_LT_QB:
13892 check_dspr2(ctx);
13893 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13894 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13895 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13896 tcg_gen_shli_tl(t1, t1, 24);
13897 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13898 break;
13899 case OPC_CMPGDU_LE_QB:
13900 check_dspr2(ctx);
13901 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13902 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13903 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13904 tcg_gen_shli_tl(t1, t1, 24);
13905 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13906 break;
13907 case OPC_CMP_EQ_PH:
13908 check_dsp(ctx);
13909 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13910 break;
13911 case OPC_CMP_LT_PH:
13912 check_dsp(ctx);
13913 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13914 break;
13915 case OPC_CMP_LE_PH:
13916 check_dsp(ctx);
13917 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13918 break;
13919 case OPC_PICK_QB:
13920 check_dsp(ctx);
13921 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13922 break;
13923 case OPC_PICK_PH:
13924 check_dsp(ctx);
13925 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13926 break;
13927 case OPC_PACKRL_PH:
13928 check_dsp(ctx);
13929 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13930 break;
13931 }
13932 break;
13933#ifdef TARGET_MIPS64
13934 case OPC_CMPU_EQ_OB_DSP:
13935 switch (op2) {
13936 case OPC_CMP_EQ_PW:
13937 check_dsp(ctx);
13938 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13939 break;
13940 case OPC_CMP_LT_PW:
13941 check_dsp(ctx);
13942 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13943 break;
13944 case OPC_CMP_LE_PW:
13945 check_dsp(ctx);
13946 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13947 break;
13948 case OPC_CMP_EQ_QH:
13949 check_dsp(ctx);
13950 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13951 break;
13952 case OPC_CMP_LT_QH:
13953 check_dsp(ctx);
13954 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13955 break;
13956 case OPC_CMP_LE_QH:
13957 check_dsp(ctx);
13958 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13959 break;
13960 case OPC_CMPGDU_EQ_OB:
13961 check_dspr2(ctx);
13962 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13963 break;
13964 case OPC_CMPGDU_LT_OB:
13965 check_dspr2(ctx);
13966 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13967 break;
13968 case OPC_CMPGDU_LE_OB:
13969 check_dspr2(ctx);
13970 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13971 break;
13972 case OPC_CMPGU_EQ_OB:
13973 check_dsp(ctx);
13974 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13975 break;
13976 case OPC_CMPGU_LT_OB:
13977 check_dsp(ctx);
13978 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13979 break;
13980 case OPC_CMPGU_LE_OB:
13981 check_dsp(ctx);
13982 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13983 break;
13984 case OPC_CMPU_EQ_OB:
13985 check_dsp(ctx);
13986 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13987 break;
13988 case OPC_CMPU_LT_OB:
13989 check_dsp(ctx);
13990 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13991 break;
13992 case OPC_CMPU_LE_OB:
13993 check_dsp(ctx);
13994 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13995 break;
13996 case OPC_PACKRL_PW:
13997 check_dsp(ctx);
13998 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
13999 break;
14000 case OPC_PICK_OB:
14001 check_dsp(ctx);
14002 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14003 break;
14004 case OPC_PICK_PW:
14005 check_dsp(ctx);
14006 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14007 break;
14008 case OPC_PICK_QH:
14009 check_dsp(ctx);
14010 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14011 break;
14012 }
14013 break;
df6126a7
AJ
14014#endif
14015 }
14016
14017 tcg_temp_free(t1);
14018 tcg_temp_free(v1_t);
14019 tcg_temp_free(v2_t);
14020
14021 (void)opn; /* avoid a compiler warning */
14022 MIPS_DEBUG("%s", opn);
14023}
14024
14025static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14026 uint32_t op1, int rt, int rs, int sa)
14027{
14028 const char *opn = "mipsdsp append/dappend";
14029 TCGv t0;
14030
14031 check_dspr2(ctx);
14032
14033 if (rt == 0) {
14034 /* Treat as NOP. */
14035 MIPS_DEBUG("NOP");
14036 return;
14037 }
14038
14039 t0 = tcg_temp_new();
14040 gen_load_gpr(t0, rs);
14041
14042 switch (op1) {
14043 case OPC_APPEND_DSP:
14044 switch (MASK_APPEND(ctx->opcode)) {
14045 case OPC_APPEND:
14046 if (sa != 0) {
14047 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14048 }
14049 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14050 break;
14051 case OPC_PREPEND:
14052 if (sa != 0) {
14053 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14054 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14055 tcg_gen_shli_tl(t0, t0, 32 - sa);
14056 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14057 }
14058 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14059 break;
14060 case OPC_BALIGN:
14061 sa &= 3;
14062 if (sa != 0 && sa != 2) {
14063 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14064 tcg_gen_ext32u_tl(t0, t0);
14065 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14066 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14067 }
14068 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14069 break;
14070 default: /* Invalid */
14071 MIPS_INVAL("MASK APPEND");
14072 generate_exception(ctx, EXCP_RI);
14073 break;
14074 }
14075 break;
14076#ifdef TARGET_MIPS64
26690560 14077 case OPC_DAPPEND_DSP:
df6126a7 14078 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 14079 case OPC_DAPPEND:
df6126a7
AJ
14080 if (sa != 0) {
14081 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14082 }
26690560
JL
14083 break;
14084 case OPC_PREPENDD:
df6126a7
AJ
14085 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14086 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14087 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
14088 break;
14089 case OPC_PREPENDW:
df6126a7
AJ
14090 if (sa != 0) {
14091 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14092 tcg_gen_shli_tl(t0, t0, 64 - sa);
14093 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14094 }
26690560
JL
14095 break;
14096 case OPC_DBALIGN:
df6126a7
AJ
14097 sa &= 7;
14098 if (sa != 0 && sa != 2 && sa != 4) {
14099 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14100 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14101 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14102 }
26690560
JL
14103 break;
14104 default: /* Invalid */
14105 MIPS_INVAL("MASK DAPPEND");
14106 generate_exception(ctx, EXCP_RI);
14107 break;
14108 }
14109 break;
14110#endif
14111 }
df6126a7 14112 tcg_temp_free(t0);
26690560
JL
14113 (void)opn; /* avoid a compiler warning */
14114 MIPS_DEBUG("%s", opn);
14115}
14116
b53371ed
JL
14117static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14118 int ret, int v1, int v2, int check_ret)
14119
14120{
14121 const char *opn = "mipsdsp accumulator";
14122 TCGv t0;
14123 TCGv t1;
14124 TCGv v1_t;
14125 TCGv v2_t;
14126 int16_t imm;
14127
14128 if ((ret == 0) && (check_ret == 1)) {
14129 /* Treat as NOP. */
14130 MIPS_DEBUG("NOP");
14131 return;
14132 }
14133
14134 t0 = tcg_temp_new();
14135 t1 = tcg_temp_new();
14136 v1_t = tcg_temp_new();
14137 v2_t = tcg_temp_new();
14138
14139 gen_load_gpr(v1_t, v1);
14140 gen_load_gpr(v2_t, v2);
14141
14142 switch (op1) {
14143 case OPC_EXTR_W_DSP:
14144 check_dsp(ctx);
14145 switch (op2) {
14146 case OPC_EXTR_W:
14147 tcg_gen_movi_tl(t0, v2);
14148 tcg_gen_movi_tl(t1, v1);
14149 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14150 break;
14151 case OPC_EXTR_R_W:
14152 tcg_gen_movi_tl(t0, v2);
14153 tcg_gen_movi_tl(t1, v1);
14154 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14155 break;
14156 case OPC_EXTR_RS_W:
14157 tcg_gen_movi_tl(t0, v2);
14158 tcg_gen_movi_tl(t1, v1);
14159 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14160 break;
14161 case OPC_EXTR_S_H:
14162 tcg_gen_movi_tl(t0, v2);
14163 tcg_gen_movi_tl(t1, v1);
14164 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14165 break;
14166 case OPC_EXTRV_S_H:
14167 tcg_gen_movi_tl(t0, v2);
14168 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14169 break;
14170 case OPC_EXTRV_W:
14171 tcg_gen_movi_tl(t0, v2);
14172 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14173 break;
14174 case OPC_EXTRV_R_W:
14175 tcg_gen_movi_tl(t0, v2);
14176 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14177 break;
14178 case OPC_EXTRV_RS_W:
14179 tcg_gen_movi_tl(t0, v2);
14180 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14181 break;
14182 case OPC_EXTP:
14183 tcg_gen_movi_tl(t0, v2);
14184 tcg_gen_movi_tl(t1, v1);
14185 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14186 break;
14187 case OPC_EXTPV:
14188 tcg_gen_movi_tl(t0, v2);
14189 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14190 break;
14191 case OPC_EXTPDP:
14192 tcg_gen_movi_tl(t0, v2);
14193 tcg_gen_movi_tl(t1, v1);
14194 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14195 break;
14196 case OPC_EXTPDPV:
14197 tcg_gen_movi_tl(t0, v2);
14198 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14199 break;
14200 case OPC_SHILO:
14201 imm = (ctx->opcode >> 20) & 0x3F;
14202 tcg_gen_movi_tl(t0, ret);
14203 tcg_gen_movi_tl(t1, imm);
14204 gen_helper_shilo(t0, t1, cpu_env);
14205 break;
14206 case OPC_SHILOV:
14207 tcg_gen_movi_tl(t0, ret);
14208 gen_helper_shilo(t0, v1_t, cpu_env);
14209 break;
14210 case OPC_MTHLIP:
14211 tcg_gen_movi_tl(t0, ret);
14212 gen_helper_mthlip(t0, v1_t, cpu_env);
14213 break;
14214 case OPC_WRDSP:
14215 imm = (ctx->opcode >> 11) & 0x3FF;
14216 tcg_gen_movi_tl(t0, imm);
14217 gen_helper_wrdsp(v1_t, t0, cpu_env);
14218 break;
14219 case OPC_RDDSP:
14220 imm = (ctx->opcode >> 16) & 0x03FF;
14221 tcg_gen_movi_tl(t0, imm);
14222 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14223 break;
14224 }
14225 break;
14226#ifdef TARGET_MIPS64
14227 case OPC_DEXTR_W_DSP:
14228 check_dsp(ctx);
14229 switch (op2) {
14230 case OPC_DMTHLIP:
14231 tcg_gen_movi_tl(t0, ret);
14232 gen_helper_dmthlip(v1_t, t0, cpu_env);
14233 break;
14234 case OPC_DSHILO:
14235 {
14236 int shift = (ctx->opcode >> 19) & 0x7F;
14237 int ac = (ctx->opcode >> 11) & 0x03;
14238 tcg_gen_movi_tl(t0, shift);
14239 tcg_gen_movi_tl(t1, ac);
14240 gen_helper_dshilo(t0, t1, cpu_env);
14241 break;
14242 }
14243 case OPC_DSHILOV:
14244 {
14245 int ac = (ctx->opcode >> 11) & 0x03;
14246 tcg_gen_movi_tl(t0, ac);
14247 gen_helper_dshilo(v1_t, t0, cpu_env);
14248 break;
14249 }
14250 case OPC_DEXTP:
14251 tcg_gen_movi_tl(t0, v2);
14252 tcg_gen_movi_tl(t1, v1);
14253
14254 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14255 break;
14256 case OPC_DEXTPV:
14257 tcg_gen_movi_tl(t0, v2);
14258 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14259 break;
14260 case OPC_DEXTPDP:
14261 tcg_gen_movi_tl(t0, v2);
14262 tcg_gen_movi_tl(t1, v1);
14263 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14264 break;
14265 case OPC_DEXTPDPV:
14266 tcg_gen_movi_tl(t0, v2);
14267 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14268 break;
14269 case OPC_DEXTR_L:
14270 tcg_gen_movi_tl(t0, v2);
14271 tcg_gen_movi_tl(t1, v1);
14272 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14273 break;
14274 case OPC_DEXTR_R_L:
14275 tcg_gen_movi_tl(t0, v2);
14276 tcg_gen_movi_tl(t1, v1);
14277 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14278 break;
14279 case OPC_DEXTR_RS_L:
14280 tcg_gen_movi_tl(t0, v2);
14281 tcg_gen_movi_tl(t1, v1);
14282 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14283 break;
14284 case OPC_DEXTR_W:
14285 tcg_gen_movi_tl(t0, v2);
14286 tcg_gen_movi_tl(t1, v1);
14287 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14288 break;
14289 case OPC_DEXTR_R_W:
14290 tcg_gen_movi_tl(t0, v2);
14291 tcg_gen_movi_tl(t1, v1);
14292 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14293 break;
14294 case OPC_DEXTR_RS_W:
14295 tcg_gen_movi_tl(t0, v2);
14296 tcg_gen_movi_tl(t1, v1);
14297 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14298 break;
14299 case OPC_DEXTR_S_H:
14300 tcg_gen_movi_tl(t0, v2);
14301 tcg_gen_movi_tl(t1, v1);
14302 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14303 break;
14304 case OPC_DEXTRV_S_H:
14305 tcg_gen_movi_tl(t0, v2);
14306 tcg_gen_movi_tl(t1, v1);
14307 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14308 break;
14309 case OPC_DEXTRV_L:
14310 tcg_gen_movi_tl(t0, v2);
14311 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14312 break;
14313 case OPC_DEXTRV_R_L:
14314 tcg_gen_movi_tl(t0, v2);
14315 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14316 break;
14317 case OPC_DEXTRV_RS_L:
14318 tcg_gen_movi_tl(t0, v2);
14319 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14320 break;
14321 case OPC_DEXTRV_W:
14322 tcg_gen_movi_tl(t0, v2);
14323 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14324 break;
14325 case OPC_DEXTRV_R_W:
14326 tcg_gen_movi_tl(t0, v2);
14327 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14328 break;
14329 case OPC_DEXTRV_RS_W:
14330 tcg_gen_movi_tl(t0, v2);
14331 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14332 break;
14333 }
14334 break;
14335#endif
14336 }
14337
14338 tcg_temp_free(t0);
14339 tcg_temp_free(t1);
14340 tcg_temp_free(v1_t);
14341 tcg_temp_free(v2_t);
14342
14343 (void)opn; /* avoid a compiler warning */
14344 MIPS_DEBUG("%s", opn);
14345}
14346
9b1a1d68
JL
14347/* End MIPSDSP functions. */
14348
7db13fae 14349static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
14350{
14351 int32_t offset;
14352 int rs, rt, rd, sa;
14353 uint32_t op, op1, op2;
14354 int16_t imm;
14355
14356 /* make sure instructions are on a word boundary */
14357 if (ctx->pc & 0x3) {
14358 env->CP0_BadVAddr = ctx->pc;
14359 generate_exception(ctx, EXCP_AdEL);
14360 return;
14361 }
14362
14363 /* Handle blikely not taken case */
14364 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14365 int l1 = gen_new_label();
14366
14367 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14368 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14369 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14370 gen_goto_tb(ctx, 1, ctx->pc + 4);
14371 gen_set_label(l1);
14372 }
14373
fdefe51c 14374 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14375 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14376 }
3c824109
NF
14377
14378 op = MASK_OP_MAJOR(ctx->opcode);
14379 rs = (ctx->opcode >> 21) & 0x1f;
14380 rt = (ctx->opcode >> 16) & 0x1f;
14381 rd = (ctx->opcode >> 11) & 0x1f;
14382 sa = (ctx->opcode >> 6) & 0x1f;
14383 imm = (int16_t)ctx->opcode;
14384 switch (op) {
7a387fff
TS
14385 case OPC_SPECIAL:
14386 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14387 switch (op1) {
324d9e32
AJ
14388 case OPC_SLL: /* Shift with immediate */
14389 case OPC_SRA:
d75c135e 14390 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14391 break;
ea63e2c3
NF
14392 case OPC_SRL:
14393 switch ((ctx->opcode >> 21) & 0x1f) {
14394 case 1:
14395 /* rotr is decoded as srl on non-R2 CPUs */
d75c135e 14396 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14397 op1 = OPC_ROTR;
14398 }
14399 /* Fallthrough */
14400 case 0:
d75c135e 14401 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14402 break;
14403 default:
14404 generate_exception(ctx, EXCP_RI);
14405 break;
14406 }
14407 break;
460f00c4
AJ
14408 case OPC_MOVN: /* Conditional move */
14409 case OPC_MOVZ:
d75c135e 14410 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
aa8f4009 14411 INSN_LOONGSON2E | INSN_LOONGSON2F);
d75c135e 14412 gen_cond_move(ctx, op1, rd, rs, rt);
460f00c4
AJ
14413 break;
14414 case OPC_ADD ... OPC_SUBU:
d75c135e 14415 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14416 break;
460f00c4 14417 case OPC_SLLV: /* Shifts */
460f00c4 14418 case OPC_SRAV:
d75c135e 14419 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14420 break;
ea63e2c3
NF
14421 case OPC_SRLV:
14422 switch ((ctx->opcode >> 6) & 0x1f) {
14423 case 1:
14424 /* rotrv is decoded as srlv on non-R2 CPUs */
d75c135e 14425 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14426 op1 = OPC_ROTRV;
14427 }
14428 /* Fallthrough */
14429 case 0:
d75c135e 14430 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14431 break;
14432 default:
14433 generate_exception(ctx, EXCP_RI);
14434 break;
14435 }
14436 break;
460f00c4
AJ
14437 case OPC_SLT: /* Set on less than */
14438 case OPC_SLTU:
d75c135e 14439 gen_slt(ctx, op1, rd, rs, rt);
460f00c4
AJ
14440 break;
14441 case OPC_AND: /* Logic*/
14442 case OPC_OR:
14443 case OPC_NOR:
14444 case OPC_XOR:
d75c135e 14445 gen_logic(ctx, op1, rd, rs, rt);
460f00c4 14446 break;
26135ead
RS
14447 case OPC_MULT:
14448 case OPC_MULTU:
e9c71dd1 14449 if (sa) {
d75c135e 14450 check_insn(ctx, INSN_VR54XX);
e9c71dd1
TS
14451 op1 = MASK_MUL_VR54XX(ctx->opcode);
14452 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
26135ead
RS
14453 } else {
14454 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14455 }
14456 break;
14457 case OPC_DIV:
14458 case OPC_DIVU:
14459 gen_muldiv(ctx, op1, 0, rs, rt);
7a387fff
TS
14460 break;
14461 case OPC_JR ... OPC_JALR:
7dca4ad0 14462 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061
NF
14463 *is_branch = 1;
14464 break;
7a387fff
TS
14465 case OPC_TGE ... OPC_TEQ: /* Traps */
14466 case OPC_TNE:
14467 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14468 break;
7a387fff
TS
14469 case OPC_MFHI: /* Move from HI/LO */
14470 case OPC_MFLO:
26135ead 14471 gen_HILO(ctx, op1, rs & 3, rd);
6af0bf9c 14472 break;
7a387fff
TS
14473 case OPC_MTHI:
14474 case OPC_MTLO: /* Move to HI/LO */
26135ead 14475 gen_HILO(ctx, op1, rd & 3, rs);
6af0bf9c 14476 break;
b48cfdff
TS
14477 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14478#ifdef MIPS_STRICT_STANDARD
14479 MIPS_INVAL("PMON / selsl");
14480 generate_exception(ctx, EXCP_RI);
14481#else
895c2d04 14482 gen_helper_0e0i(pmon, sa);
b48cfdff 14483#endif
7a387fff
TS
14484 break;
14485 case OPC_SYSCALL:
6af0bf9c 14486 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14487 ctx->bstate = BS_STOP;
6af0bf9c 14488 break;
7a387fff 14489 case OPC_BREAK:
6af0bf9c
FB
14490 generate_exception(ctx, EXCP_BREAK);
14491 break;
b48cfdff
TS
14492 case OPC_SPIM:
14493#ifdef MIPS_STRICT_STANDARD
14494 MIPS_INVAL("SPIM");
14495 generate_exception(ctx, EXCP_RI);
14496#else
7a387fff
TS
14497 /* Implemented as RI exception for now. */
14498 MIPS_INVAL("spim (unofficial)");
14499 generate_exception(ctx, EXCP_RI);
b48cfdff 14500#endif
6af0bf9c 14501 break;
7a387fff 14502 case OPC_SYNC:
ead9360e 14503 /* Treat as NOP. */
6af0bf9c 14504 break;
4ad40f36 14505
7a387fff 14506 case OPC_MOVCI:
d75c135e 14507 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14508 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14509 check_cp1_enabled(ctx);
36d23958
TS
14510 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14511 (ctx->opcode >> 16) & 1);
14512 } else {
e397ee33 14513 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14514 }
4ad40f36
FB
14515 break;
14516
d26bc211 14517#if defined(TARGET_MIPS64)
7a387fff
TS
14518 /* MIPS64 specific opcodes */
14519 case OPC_DSLL:
324d9e32 14520 case OPC_DSRA:
7a387fff 14521 case OPC_DSLL32:
324d9e32 14522 case OPC_DSRA32:
d75c135e 14523 check_insn(ctx, ISA_MIPS3);
e189e748 14524 check_mips_64(ctx);
d75c135e 14525 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14526 break;
ea63e2c3
NF
14527 case OPC_DSRL:
14528 switch ((ctx->opcode >> 21) & 0x1f) {
14529 case 1:
14530 /* drotr is decoded as dsrl on non-R2 CPUs */
d75c135e 14531 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14532 op1 = OPC_DROTR;
14533 }
14534 /* Fallthrough */
14535 case 0:
d75c135e 14536 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14537 check_mips_64(ctx);
d75c135e 14538 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14539 break;
14540 default:
14541 generate_exception(ctx, EXCP_RI);
14542 break;
14543 }
14544 break;
14545 case OPC_DSRL32:
14546 switch ((ctx->opcode >> 21) & 0x1f) {
14547 case 1:
14548 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
d75c135e 14549 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14550 op1 = OPC_DROTR32;
14551 }
14552 /* Fallthrough */
14553 case 0:
d75c135e 14554 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14555 check_mips_64(ctx);
d75c135e 14556 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14557 break;
14558 default:
14559 generate_exception(ctx, EXCP_RI);
14560 break;
14561 }
14562 break;
7a387fff 14563 case OPC_DADD ... OPC_DSUBU:
d75c135e 14564 check_insn(ctx, ISA_MIPS3);
e189e748 14565 check_mips_64(ctx);
d75c135e 14566 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14567 break;
460f00c4
AJ
14568 case OPC_DSLLV:
14569 case OPC_DSRAV:
d75c135e 14570 check_insn(ctx, ISA_MIPS3);
460f00c4 14571 check_mips_64(ctx);
d75c135e 14572 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14573 break;
ea63e2c3
NF
14574 case OPC_DSRLV:
14575 switch ((ctx->opcode >> 6) & 0x1f) {
14576 case 1:
14577 /* drotrv is decoded as dsrlv on non-R2 CPUs */
d75c135e 14578 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14579 op1 = OPC_DROTRV;
14580 }
14581 /* Fallthrough */
14582 case 0:
d75c135e 14583 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14584 check_mips_64(ctx);
d75c135e 14585 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14586 break;
14587 default:
14588 generate_exception(ctx, EXCP_RI);
14589 break;
14590 }
14591 break;
7a387fff 14592 case OPC_DMULT ... OPC_DDIVU:
d75c135e 14593 check_insn(ctx, ISA_MIPS3);
e189e748 14594 check_mips_64(ctx);
26135ead 14595 gen_muldiv(ctx, op1, 0, rs, rt);
7a387fff 14596 break;
6af0bf9c
FB
14597#endif
14598 default: /* Invalid */
14599 MIPS_INVAL("special");
14600 generate_exception(ctx, EXCP_RI);
14601 break;
14602 }
14603 break;
7a387fff
TS
14604 case OPC_SPECIAL2:
14605 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14606 switch (op1) {
7a387fff
TS
14607 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14608 case OPC_MSUB ... OPC_MSUBU:
d75c135e 14609 check_insn(ctx, ISA_MIPS32);
26135ead 14610 gen_muldiv(ctx, op1, rd & 3, rs, rt);
6af0bf9c 14611 break;
7a387fff 14612 case OPC_MUL:
d75c135e 14613 gen_arith(ctx, op1, rd, rs, rt);
6af0bf9c 14614 break;
20e1fb52
AJ
14615 case OPC_CLO:
14616 case OPC_CLZ:
d75c135e 14617 check_insn(ctx, ISA_MIPS32);
7a387fff 14618 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14619 break;
7a387fff 14620 case OPC_SDBBP:
6af0bf9c
FB
14621 /* XXX: not clear which exception should be raised
14622 * when in debug mode...
14623 */
d75c135e 14624 check_insn(ctx, ISA_MIPS32);
6af0bf9c
FB
14625 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14626 generate_exception(ctx, EXCP_DBp);
14627 } else {
14628 generate_exception(ctx, EXCP_DBp);
14629 }
ead9360e 14630 /* Treat as NOP. */
6af0bf9c 14631 break;
161f85e6
AJ
14632 case OPC_DIV_G_2F:
14633 case OPC_DIVU_G_2F:
14634 case OPC_MULT_G_2F:
14635 case OPC_MULTU_G_2F:
14636 case OPC_MOD_G_2F:
14637 case OPC_MODU_G_2F:
d75c135e 14638 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14639 gen_loongson_integer(ctx, op1, rd, rs, rt);
14640 break;
d26bc211 14641#if defined(TARGET_MIPS64)
20e1fb52
AJ
14642 case OPC_DCLO:
14643 case OPC_DCLZ:
d75c135e 14644 check_insn(ctx, ISA_MIPS64);
e189e748 14645 check_mips_64(ctx);
7a387fff
TS
14646 gen_cl(ctx, op1, rd, rs);
14647 break;
161f85e6
AJ
14648 case OPC_DMULT_G_2F:
14649 case OPC_DMULTU_G_2F:
14650 case OPC_DDIV_G_2F:
14651 case OPC_DDIVU_G_2F:
14652 case OPC_DMOD_G_2F:
14653 case OPC_DMODU_G_2F:
d75c135e 14654 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14655 gen_loongson_integer(ctx, op1, rd, rs, rt);
14656 break;
7a387fff 14657#endif
6af0bf9c
FB
14658 default: /* Invalid */
14659 MIPS_INVAL("special2");
14660 generate_exception(ctx, EXCP_RI);
14661 break;
14662 }
14663 break;
7a387fff 14664 case OPC_SPECIAL3:
2b0233ab
TS
14665 op1 = MASK_SPECIAL3(ctx->opcode);
14666 switch (op1) {
14667 case OPC_EXT:
14668 case OPC_INS:
d75c135e 14669 check_insn(ctx, ISA_MIPS32R2);
2b0233ab
TS
14670 gen_bitops(ctx, op1, rt, rs, sa, rd);
14671 break;
14672 case OPC_BSHFL:
d75c135e 14673 check_insn(ctx, ISA_MIPS32R2);
2b0233ab 14674 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14675 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14676 break;
1579a72e 14677 case OPC_RDHWR:
d75c135e 14678 gen_rdhwr(ctx, rt, rd);
1579a72e 14679 break;
ead9360e 14680 case OPC_FORK:
d75c135e 14681 check_insn(ctx, ASE_MT);
6c5c1e20 14682 {
35fbce2c
AJ
14683 TCGv t0 = tcg_temp_new();
14684 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14685
14686 gen_load_gpr(t0, rt);
14687 gen_load_gpr(t1, rs);
a7812ae4 14688 gen_helper_fork(t0, t1);
6c5c1e20
TS
14689 tcg_temp_free(t0);
14690 tcg_temp_free(t1);
14691 }
ead9360e
TS
14692 break;
14693 case OPC_YIELD:
d75c135e 14694 check_insn(ctx, ASE_MT);
6c5c1e20 14695 {
35fbce2c 14696 TCGv t0 = tcg_temp_new();
6c5c1e20 14697
35fbce2c 14698 save_cpu_state(ctx, 1);
6c5c1e20 14699 gen_load_gpr(t0, rs);
895c2d04 14700 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14701 gen_store_gpr(t0, rd);
14702 tcg_temp_free(t0);
14703 }
ead9360e 14704 break;
161f85e6 14705 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14706 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14707 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14708 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14709 * the same mask and op1. */
d75c135e 14710 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
461c08df
JL
14711 op2 = MASK_ADDUH_QB(ctx->opcode);
14712 switch (op2) {
14713 case OPC_ADDUH_QB:
14714 case OPC_ADDUH_R_QB:
14715 case OPC_ADDQH_PH:
14716 case OPC_ADDQH_R_PH:
14717 case OPC_ADDQH_W:
14718 case OPC_ADDQH_R_W:
14719 case OPC_SUBUH_QB:
14720 case OPC_SUBUH_R_QB:
14721 case OPC_SUBQH_PH:
14722 case OPC_SUBQH_R_PH:
14723 case OPC_SUBQH_W:
14724 case OPC_SUBQH_R_W:
14725 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14726 break;
a22260ae
JL
14727 case OPC_MUL_PH:
14728 case OPC_MUL_S_PH:
14729 case OPC_MULQ_S_W:
14730 case OPC_MULQ_RS_W:
14731 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14732 break;
461c08df
JL
14733 default:
14734 MIPS_INVAL("MASK ADDUH.QB");
14735 generate_exception(ctx, EXCP_RI);
14736 break;
14737 }
d75c135e 14738 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
461c08df
JL
14739 gen_loongson_integer(ctx, op1, rd, rs, rt);
14740 } else {
14741 generate_exception(ctx, EXCP_RI);
14742 }
161f85e6 14743 break;
9b1a1d68
JL
14744 case OPC_LX_DSP:
14745 op2 = MASK_LX(ctx->opcode);
14746 switch (op2) {
14747#if defined(TARGET_MIPS64)
14748 case OPC_LDX:
14749#endif
14750 case OPC_LBUX:
14751 case OPC_LHX:
14752 case OPC_LWX:
d75c135e 14753 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
9b1a1d68
JL
14754 break;
14755 default: /* Invalid */
14756 MIPS_INVAL("MASK LX");
14757 generate_exception(ctx, EXCP_RI);
14758 break;
14759 }
14760 break;
461c08df
JL
14761 case OPC_ABSQ_S_PH_DSP:
14762 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14763 switch (op2) {
14764 case OPC_ABSQ_S_QB:
14765 case OPC_ABSQ_S_PH:
14766 case OPC_ABSQ_S_W:
14767 case OPC_PRECEQ_W_PHL:
14768 case OPC_PRECEQ_W_PHR:
14769 case OPC_PRECEQU_PH_QBL:
14770 case OPC_PRECEQU_PH_QBR:
14771 case OPC_PRECEQU_PH_QBLA:
14772 case OPC_PRECEQU_PH_QBRA:
14773 case OPC_PRECEU_PH_QBL:
14774 case OPC_PRECEU_PH_QBR:
14775 case OPC_PRECEU_PH_QBLA:
14776 case OPC_PRECEU_PH_QBRA:
14777 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14778 break;
1cb6686c
JL
14779 case OPC_BITREV:
14780 case OPC_REPL_QB:
14781 case OPC_REPLV_QB:
14782 case OPC_REPL_PH:
14783 case OPC_REPLV_PH:
d75c135e 14784 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 14785 break;
461c08df
JL
14786 default:
14787 MIPS_INVAL("MASK ABSQ_S.PH");
14788 generate_exception(ctx, EXCP_RI);
14789 break;
14790 }
14791 break;
14792 case OPC_ADDU_QB_DSP:
14793 op2 = MASK_ADDU_QB(ctx->opcode);
14794 switch (op2) {
14795 case OPC_ADDQ_PH:
14796 case OPC_ADDQ_S_PH:
14797 case OPC_ADDQ_S_W:
14798 case OPC_ADDU_QB:
14799 case OPC_ADDU_S_QB:
14800 case OPC_ADDU_PH:
14801 case OPC_ADDU_S_PH:
14802 case OPC_SUBQ_PH:
14803 case OPC_SUBQ_S_PH:
14804 case OPC_SUBQ_S_W:
14805 case OPC_SUBU_QB:
14806 case OPC_SUBU_S_QB:
14807 case OPC_SUBU_PH:
14808 case OPC_SUBU_S_PH:
14809 case OPC_ADDSC:
14810 case OPC_ADDWC:
14811 case OPC_MODSUB:
14812 case OPC_RADDU_W_QB:
14813 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14814 break;
a22260ae
JL
14815 case OPC_MULEU_S_PH_QBL:
14816 case OPC_MULEU_S_PH_QBR:
14817 case OPC_MULQ_RS_PH:
14818 case OPC_MULEQ_S_W_PHL:
14819 case OPC_MULEQ_S_W_PHR:
14820 case OPC_MULQ_S_PH:
14821 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14822 break;
461c08df
JL
14823 default: /* Invalid */
14824 MIPS_INVAL("MASK ADDU.QB");
14825 generate_exception(ctx, EXCP_RI);
14826 break;
14827
14828 }
14829 break;
14830 case OPC_CMPU_EQ_QB_DSP:
14831 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14832 switch (op2) {
14833 case OPC_PRECR_SRA_PH_W:
14834 case OPC_PRECR_SRA_R_PH_W:
14835 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14836 break;
14837 case OPC_PRECR_QB_PH:
14838 case OPC_PRECRQ_QB_PH:
14839 case OPC_PRECRQ_PH_W:
14840 case OPC_PRECRQ_RS_PH_W:
14841 case OPC_PRECRQU_S_QB_PH:
14842 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14843 break;
26690560
JL
14844 case OPC_CMPU_EQ_QB:
14845 case OPC_CMPU_LT_QB:
14846 case OPC_CMPU_LE_QB:
14847 case OPC_CMP_EQ_PH:
14848 case OPC_CMP_LT_PH:
14849 case OPC_CMP_LE_PH:
14850 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14851 break;
14852 case OPC_CMPGU_EQ_QB:
14853 case OPC_CMPGU_LT_QB:
14854 case OPC_CMPGU_LE_QB:
14855 case OPC_CMPGDU_EQ_QB:
14856 case OPC_CMPGDU_LT_QB:
14857 case OPC_CMPGDU_LE_QB:
14858 case OPC_PICK_QB:
14859 case OPC_PICK_PH:
14860 case OPC_PACKRL_PH:
14861 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14862 break;
461c08df
JL
14863 default: /* Invalid */
14864 MIPS_INVAL("MASK CMPU.EQ.QB");
14865 generate_exception(ctx, EXCP_RI);
14866 break;
14867 }
14868 break;
77c5fa8b
JL
14869 case OPC_SHLL_QB_DSP:
14870 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14871 break;
a22260ae
JL
14872 case OPC_DPA_W_PH_DSP:
14873 op2 = MASK_DPA_W_PH(ctx->opcode);
14874 switch (op2) {
14875 case OPC_DPAU_H_QBL:
14876 case OPC_DPAU_H_QBR:
14877 case OPC_DPSU_H_QBL:
14878 case OPC_DPSU_H_QBR:
14879 case OPC_DPA_W_PH:
14880 case OPC_DPAX_W_PH:
14881 case OPC_DPAQ_S_W_PH:
14882 case OPC_DPAQX_S_W_PH:
14883 case OPC_DPAQX_SA_W_PH:
14884 case OPC_DPS_W_PH:
14885 case OPC_DPSX_W_PH:
14886 case OPC_DPSQ_S_W_PH:
14887 case OPC_DPSQX_S_W_PH:
14888 case OPC_DPSQX_SA_W_PH:
14889 case OPC_MULSAQ_S_W_PH:
14890 case OPC_DPAQ_SA_L_W:
14891 case OPC_DPSQ_SA_L_W:
14892 case OPC_MAQ_S_W_PHL:
14893 case OPC_MAQ_S_W_PHR:
14894 case OPC_MAQ_SA_W_PHL:
14895 case OPC_MAQ_SA_W_PHR:
14896 case OPC_MULSA_W_PH:
14897 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14898 break;
14899 default: /* Invalid */
14900 MIPS_INVAL("MASK DPAW.PH");
14901 generate_exception(ctx, EXCP_RI);
14902 break;
14903 }
14904 break;
1cb6686c
JL
14905 case OPC_INSV_DSP:
14906 op2 = MASK_INSV(ctx->opcode);
14907 switch (op2) {
14908 case OPC_INSV:
14909 check_dsp(ctx);
14910 {
14911 TCGv t0, t1;
14912
14913 if (rt == 0) {
14914 MIPS_DEBUG("NOP");
14915 break;
14916 }
14917
14918 t0 = tcg_temp_new();
14919 t1 = tcg_temp_new();
14920
14921 gen_load_gpr(t0, rt);
14922 gen_load_gpr(t1, rs);
14923
14924 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14925
14926 tcg_temp_free(t0);
14927 tcg_temp_free(t1);
14928 break;
14929 }
14930 default: /* Invalid */
14931 MIPS_INVAL("MASK INSV");
14932 generate_exception(ctx, EXCP_RI);
14933 break;
14934 }
14935 break;
26690560 14936 case OPC_APPEND_DSP:
df6126a7 14937 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 14938 break;
b53371ed
JL
14939 case OPC_EXTR_W_DSP:
14940 op2 = MASK_EXTR_W(ctx->opcode);
14941 switch (op2) {
14942 case OPC_EXTR_W:
14943 case OPC_EXTR_R_W:
14944 case OPC_EXTR_RS_W:
14945 case OPC_EXTR_S_H:
14946 case OPC_EXTRV_S_H:
14947 case OPC_EXTRV_W:
14948 case OPC_EXTRV_R_W:
14949 case OPC_EXTRV_RS_W:
14950 case OPC_EXTP:
14951 case OPC_EXTPV:
14952 case OPC_EXTPDP:
14953 case OPC_EXTPDPV:
14954 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14955 break;
14956 case OPC_RDDSP:
14957 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14958 break;
14959 case OPC_SHILO:
14960 case OPC_SHILOV:
14961 case OPC_MTHLIP:
14962 case OPC_WRDSP:
14963 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14964 break;
14965 default: /* Invalid */
14966 MIPS_INVAL("MASK EXTR.W");
14967 generate_exception(ctx, EXCP_RI);
14968 break;
14969 }
14970 break;
d26bc211 14971#if defined(TARGET_MIPS64)
1579a72e
TS
14972 case OPC_DEXTM ... OPC_DEXT:
14973 case OPC_DINSM ... OPC_DINS:
d75c135e 14974 check_insn(ctx, ISA_MIPS64R2);
e189e748 14975 check_mips_64(ctx);
1579a72e 14976 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 14977 break;
1579a72e 14978 case OPC_DBSHFL:
d75c135e 14979 check_insn(ctx, ISA_MIPS64R2);
e189e748 14980 check_mips_64(ctx);
1579a72e 14981 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 14982 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 14983 break;
161f85e6
AJ
14984 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14985 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14986 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
d75c135e 14987 check_insn(ctx, INSN_LOONGSON2E);
161f85e6
AJ
14988 gen_loongson_integer(ctx, op1, rd, rs, rt);
14989 break;
461c08df
JL
14990 case OPC_ABSQ_S_QH_DSP:
14991 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14992 switch (op2) {
14993 case OPC_PRECEQ_L_PWL:
14994 case OPC_PRECEQ_L_PWR:
14995 case OPC_PRECEQ_PW_QHL:
14996 case OPC_PRECEQ_PW_QHR:
14997 case OPC_PRECEQ_PW_QHLA:
14998 case OPC_PRECEQ_PW_QHRA:
14999 case OPC_PRECEQU_QH_OBL:
15000 case OPC_PRECEQU_QH_OBR:
15001 case OPC_PRECEQU_QH_OBLA:
15002 case OPC_PRECEQU_QH_OBRA:
15003 case OPC_PRECEU_QH_OBL:
15004 case OPC_PRECEU_QH_OBR:
15005 case OPC_PRECEU_QH_OBLA:
15006 case OPC_PRECEU_QH_OBRA:
15007 case OPC_ABSQ_S_OB:
15008 case OPC_ABSQ_S_PW:
15009 case OPC_ABSQ_S_QH:
15010 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15011 break;
1cb6686c
JL
15012 case OPC_REPL_OB:
15013 case OPC_REPL_PW:
15014 case OPC_REPL_QH:
15015 case OPC_REPLV_OB:
15016 case OPC_REPLV_PW:
15017 case OPC_REPLV_QH:
d75c135e 15018 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 15019 break;
461c08df
JL
15020 default: /* Invalid */
15021 MIPS_INVAL("MASK ABSQ_S.QH");
15022 generate_exception(ctx, EXCP_RI);
15023 break;
15024 }
15025 break;
15026 case OPC_ADDU_OB_DSP:
15027 op2 = MASK_ADDU_OB(ctx->opcode);
15028 switch (op2) {
15029 case OPC_RADDU_L_OB:
15030 case OPC_SUBQ_PW:
15031 case OPC_SUBQ_S_PW:
15032 case OPC_SUBQ_QH:
15033 case OPC_SUBQ_S_QH:
15034 case OPC_SUBU_OB:
15035 case OPC_SUBU_S_OB:
15036 case OPC_SUBU_QH:
15037 case OPC_SUBU_S_QH:
15038 case OPC_SUBUH_OB:
15039 case OPC_SUBUH_R_OB:
15040 case OPC_ADDQ_PW:
15041 case OPC_ADDQ_S_PW:
15042 case OPC_ADDQ_QH:
15043 case OPC_ADDQ_S_QH:
15044 case OPC_ADDU_OB:
15045 case OPC_ADDU_S_OB:
15046 case OPC_ADDU_QH:
15047 case OPC_ADDU_S_QH:
15048 case OPC_ADDUH_OB:
15049 case OPC_ADDUH_R_OB:
15050 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15051 break;
a22260ae
JL
15052 case OPC_MULEQ_S_PW_QHL:
15053 case OPC_MULEQ_S_PW_QHR:
15054 case OPC_MULEU_S_QH_OBL:
15055 case OPC_MULEU_S_QH_OBR:
15056 case OPC_MULQ_RS_QH:
15057 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15058 break;
461c08df
JL
15059 default: /* Invalid */
15060 MIPS_INVAL("MASK ADDU.OB");
15061 generate_exception(ctx, EXCP_RI);
15062 break;
15063 }
15064 break;
15065 case OPC_CMPU_EQ_OB_DSP:
15066 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15067 switch (op2) {
15068 case OPC_PRECR_SRA_QH_PW:
15069 case OPC_PRECR_SRA_R_QH_PW:
15070 /* Return value is rt. */
15071 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15072 break;
15073 case OPC_PRECR_OB_QH:
15074 case OPC_PRECRQ_OB_QH:
15075 case OPC_PRECRQ_PW_L:
15076 case OPC_PRECRQ_QH_PW:
15077 case OPC_PRECRQ_RS_QH_PW:
15078 case OPC_PRECRQU_S_OB_QH:
15079 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15080 break;
26690560
JL
15081 case OPC_CMPU_EQ_OB:
15082 case OPC_CMPU_LT_OB:
15083 case OPC_CMPU_LE_OB:
15084 case OPC_CMP_EQ_QH:
15085 case OPC_CMP_LT_QH:
15086 case OPC_CMP_LE_QH:
15087 case OPC_CMP_EQ_PW:
15088 case OPC_CMP_LT_PW:
15089 case OPC_CMP_LE_PW:
15090 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15091 break;
15092 case OPC_CMPGDU_EQ_OB:
15093 case OPC_CMPGDU_LT_OB:
15094 case OPC_CMPGDU_LE_OB:
15095 case OPC_CMPGU_EQ_OB:
15096 case OPC_CMPGU_LT_OB:
15097 case OPC_CMPGU_LE_OB:
15098 case OPC_PACKRL_PW:
15099 case OPC_PICK_OB:
15100 case OPC_PICK_PW:
15101 case OPC_PICK_QH:
15102 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15103 break;
461c08df
JL
15104 default: /* Invalid */
15105 MIPS_INVAL("MASK CMPU_EQ.OB");
15106 generate_exception(ctx, EXCP_RI);
15107 break;
15108 }
15109 break;
26690560 15110 case OPC_DAPPEND_DSP:
df6126a7 15111 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 15112 break;
b53371ed
JL
15113 case OPC_DEXTR_W_DSP:
15114 op2 = MASK_DEXTR_W(ctx->opcode);
15115 switch (op2) {
15116 case OPC_DEXTP:
15117 case OPC_DEXTPDP:
15118 case OPC_DEXTPDPV:
15119 case OPC_DEXTPV:
15120 case OPC_DEXTR_L:
15121 case OPC_DEXTR_R_L:
15122 case OPC_DEXTR_RS_L:
15123 case OPC_DEXTR_W:
15124 case OPC_DEXTR_R_W:
15125 case OPC_DEXTR_RS_W:
15126 case OPC_DEXTR_S_H:
15127 case OPC_DEXTRV_L:
15128 case OPC_DEXTRV_R_L:
15129 case OPC_DEXTRV_RS_L:
15130 case OPC_DEXTRV_S_H:
15131 case OPC_DEXTRV_W:
15132 case OPC_DEXTRV_R_W:
15133 case OPC_DEXTRV_RS_W:
15134 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15135 break;
15136 case OPC_DMTHLIP:
15137 case OPC_DSHILO:
15138 case OPC_DSHILOV:
15139 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15140 break;
15141 default: /* Invalid */
15142 MIPS_INVAL("MASK EXTR.W");
15143 generate_exception(ctx, EXCP_RI);
15144 break;
15145 }
15146 break;
a22260ae
JL
15147 case OPC_DPAQ_W_QH_DSP:
15148 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15149 switch (op2) {
15150 case OPC_DPAU_H_OBL:
15151 case OPC_DPAU_H_OBR:
15152 case OPC_DPSU_H_OBL:
15153 case OPC_DPSU_H_OBR:
15154 case OPC_DPA_W_QH:
15155 case OPC_DPAQ_S_W_QH:
15156 case OPC_DPS_W_QH:
15157 case OPC_DPSQ_S_W_QH:
15158 case OPC_MULSAQ_S_W_QH:
15159 case OPC_DPAQ_SA_L_PW:
15160 case OPC_DPSQ_SA_L_PW:
15161 case OPC_MULSAQ_S_L_PW:
15162 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15163 break;
15164 case OPC_MAQ_S_W_QHLL:
15165 case OPC_MAQ_S_W_QHLR:
15166 case OPC_MAQ_S_W_QHRL:
15167 case OPC_MAQ_S_W_QHRR:
15168 case OPC_MAQ_SA_W_QHLL:
15169 case OPC_MAQ_SA_W_QHLR:
15170 case OPC_MAQ_SA_W_QHRL:
15171 case OPC_MAQ_SA_W_QHRR:
15172 case OPC_MAQ_S_L_PWL:
15173 case OPC_MAQ_S_L_PWR:
15174 case OPC_DMADD:
15175 case OPC_DMADDU:
15176 case OPC_DMSUB:
15177 case OPC_DMSUBU:
15178 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15179 break;
15180 default: /* Invalid */
15181 MIPS_INVAL("MASK DPAQ.W.QH");
15182 generate_exception(ctx, EXCP_RI);
15183 break;
15184 }
15185 break;
1cb6686c
JL
15186 case OPC_DINSV_DSP:
15187 op2 = MASK_INSV(ctx->opcode);
15188 switch (op2) {
15189 case OPC_DINSV:
15190 {
15191 TCGv t0, t1;
15192
15193 if (rt == 0) {
15194 MIPS_DEBUG("NOP");
15195 break;
15196 }
15197 check_dsp(ctx);
15198
15199 t0 = tcg_temp_new();
15200 t1 = tcg_temp_new();
15201
15202 gen_load_gpr(t0, rt);
15203 gen_load_gpr(t1, rs);
15204
15205 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15206 break;
15207 }
15208 default: /* Invalid */
15209 MIPS_INVAL("MASK DINSV");
15210 generate_exception(ctx, EXCP_RI);
15211 break;
15212 }
15213 break;
77c5fa8b
JL
15214 case OPC_SHLL_OB_DSP:
15215 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15216 break;
7a387fff
TS
15217#endif
15218 default: /* Invalid */
15219 MIPS_INVAL("special3");
15220 generate_exception(ctx, EXCP_RI);
15221 break;
15222 }
15223 break;
15224 case OPC_REGIMM:
15225 op1 = MASK_REGIMM(ctx->opcode);
15226 switch (op1) {
15227 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15228 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15229 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061
NF
15230 *is_branch = 1;
15231 break;
7a387fff
TS
15232 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15233 case OPC_TNEI:
15234 gen_trap(ctx, op1, rs, -1, imm);
15235 break;
15236 case OPC_SYNCI:
d75c135e 15237 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15238 /* Treat as NOP. */
6af0bf9c 15239 break;
e45a93e2
JL
15240 case OPC_BPOSGE32: /* MIPS DSP branch */
15241#if defined(TARGET_MIPS64)
15242 case OPC_BPOSGE64:
15243#endif
15244 check_dsp(ctx);
15245 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15246 *is_branch = 1;
15247 break;
6af0bf9c 15248 default: /* Invalid */
923617a3 15249 MIPS_INVAL("regimm");
6af0bf9c
FB
15250 generate_exception(ctx, EXCP_RI);
15251 break;
15252 }
15253 break;
7a387fff 15254 case OPC_CP0:
387a8fe5 15255 check_cp0_enabled(ctx);
7a387fff 15256 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15257 switch (op1) {
7a387fff
TS
15258 case OPC_MFC0:
15259 case OPC_MTC0:
ead9360e
TS
15260 case OPC_MFTR:
15261 case OPC_MTTR:
d26bc211 15262#if defined(TARGET_MIPS64)
7a387fff
TS
15263 case OPC_DMFC0:
15264 case OPC_DMTC0:
15265#endif
f1aa6320 15266#ifndef CONFIG_USER_ONLY
932e71cd 15267 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15268#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15269 break;
15270 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15271#ifndef CONFIG_USER_ONLY
932e71cd 15272 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15273#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15274 break;
15275 case OPC_MFMC0:
8706c382 15276#ifndef CONFIG_USER_ONLY
932e71cd 15277 {
35fbce2c 15278 TCGv t0 = tcg_temp_new();
6c5c1e20 15279
0eaef5aa 15280 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15281 switch (op2) {
15282 case OPC_DMT:
d75c135e 15283 check_insn(ctx, ASE_MT);
9ed5726c 15284 gen_helper_dmt(t0);
35fbce2c 15285 gen_store_gpr(t0, rt);
6c5c1e20
TS
15286 break;
15287 case OPC_EMT:
d75c135e 15288 check_insn(ctx, ASE_MT);
9ed5726c 15289 gen_helper_emt(t0);
35fbce2c 15290 gen_store_gpr(t0, rt);
da80682b 15291 break;
6c5c1e20 15292 case OPC_DVPE:
d75c135e 15293 check_insn(ctx, ASE_MT);
895c2d04 15294 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15295 gen_store_gpr(t0, rt);
6c5c1e20
TS
15296 break;
15297 case OPC_EVPE:
d75c135e 15298 check_insn(ctx, ASE_MT);
895c2d04 15299 gen_helper_evpe(t0, cpu_env);
35fbce2c 15300 gen_store_gpr(t0, rt);
6c5c1e20
TS
15301 break;
15302 case OPC_DI:
d75c135e 15303 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15304 save_cpu_state(ctx, 1);
895c2d04 15305 gen_helper_di(t0, cpu_env);
35fbce2c 15306 gen_store_gpr(t0, rt);
6c5c1e20
TS
15307 /* Stop translation as we may have switched the execution mode */
15308 ctx->bstate = BS_STOP;
15309 break;
15310 case OPC_EI:
d75c135e 15311 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15312 save_cpu_state(ctx, 1);
895c2d04 15313 gen_helper_ei(t0, cpu_env);
35fbce2c 15314 gen_store_gpr(t0, rt);
6c5c1e20
TS
15315 /* Stop translation as we may have switched the execution mode */
15316 ctx->bstate = BS_STOP;
15317 break;
15318 default: /* Invalid */
15319 MIPS_INVAL("mfmc0");
15320 generate_exception(ctx, EXCP_RI);
15321 break;
15322 }
6c5c1e20 15323 tcg_temp_free(t0);
7a387fff 15324 }
0eaef5aa 15325#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15326 break;
7a387fff 15327 case OPC_RDPGPR:
d75c135e 15328 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15329 gen_load_srsgpr(rt, rd);
ead9360e 15330 break;
7a387fff 15331 case OPC_WRPGPR:
d75c135e 15332 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15333 gen_store_srsgpr(rt, rd);
38121543 15334 break;
6af0bf9c 15335 default:
923617a3 15336 MIPS_INVAL("cp0");
7a387fff 15337 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15338 break;
15339 }
15340 break;
324d9e32
AJ
15341 case OPC_ADDI: /* Arithmetic with immediate opcode */
15342 case OPC_ADDIU:
d75c135e 15343 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15344 break;
324d9e32
AJ
15345 case OPC_SLTI: /* Set on less than with immediate opcode */
15346 case OPC_SLTIU:
d75c135e 15347 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15348 break;
15349 case OPC_ANDI: /* Arithmetic with immediate opcode */
15350 case OPC_LUI:
15351 case OPC_ORI:
15352 case OPC_XORI:
d75c135e 15353 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15354 break;
7a387fff
TS
15355 case OPC_J ... OPC_JAL: /* Jump */
15356 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15357 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061
NF
15358 *is_branch = 1;
15359 break;
7a387fff
TS
15360 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15361 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15362 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061
NF
15363 *is_branch = 1;
15364 break;
7a387fff 15365 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15366 case OPC_LL:
d75c135e 15367 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15368 break;
7a387fff
TS
15369 case OPC_SB ... OPC_SW:
15370 case OPC_SWR:
5c13fdfd 15371 gen_st(ctx, op, rt, rs, imm);
7a387fff 15372 break;
d66c7132
AJ
15373 case OPC_SC:
15374 gen_st_cond(ctx, op, rt, rs, imm);
15375 break;
7a387fff 15376 case OPC_CACHE:
2e15497c 15377 check_cp0_enabled(ctx);
d75c135e 15378 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15379 /* Treat as NOP. */
34ae7b51 15380 break;
7a387fff 15381 case OPC_PREF:
d75c135e 15382 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15383 /* Treat as NOP. */
6af0bf9c 15384 break;
4ad40f36 15385
923617a3 15386 /* Floating point (COP1). */
7a387fff
TS
15387 case OPC_LWC1:
15388 case OPC_LDC1:
15389 case OPC_SWC1:
15390 case OPC_SDC1:
26ebe468 15391 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15392 break;
15393
7a387fff 15394 case OPC_CP1:
36d23958 15395 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15396 check_cp1_enabled(ctx);
36d23958
TS
15397 op1 = MASK_CP1(ctx->opcode);
15398 switch (op1) {
3a95e3a7
TS
15399 case OPC_MFHC1:
15400 case OPC_MTHC1:
d75c135e 15401 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
15402 case OPC_MFC1:
15403 case OPC_CFC1:
15404 case OPC_MTC1:
15405 case OPC_CTC1:
e189e748
TS
15406 gen_cp1(ctx, op1, rt, rd);
15407 break;
d26bc211 15408#if defined(TARGET_MIPS64)
36d23958
TS
15409 case OPC_DMFC1:
15410 case OPC_DMTC1:
d75c135e 15411 check_insn(ctx, ISA_MIPS3);
36d23958
TS
15412 gen_cp1(ctx, op1, rt, rd);
15413 break;
e189e748 15414#endif
fbcc6828
TS
15415 case OPC_BC1ANY2:
15416 case OPC_BC1ANY4:
b8aa4598 15417 check_cop1x(ctx);
d75c135e 15418 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
15419 /* fall through */
15420 case OPC_BC1:
d75c135e 15421 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15422 (rt >> 2) & 0x7, imm << 2);
c9602061
NF
15423 *is_branch = 1;
15424 break;
36d23958
TS
15425 case OPC_S_FMT:
15426 case OPC_D_FMT:
15427 case OPC_W_FMT:
15428 case OPC_L_FMT:
5a5012ec 15429 case OPC_PS_FMT:
bf4120ad 15430 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15431 (imm >> 8) & 0x7);
36d23958
TS
15432 break;
15433 default:
923617a3 15434 MIPS_INVAL("cp1");
e397ee33 15435 generate_exception (ctx, EXCP_RI);
36d23958
TS
15436 break;
15437 }
15438 } else {
15439 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15440 }
4ad40f36
FB
15441 break;
15442
15443 /* COP2. */
7a387fff
TS
15444 case OPC_LWC2:
15445 case OPC_LDC2:
15446 case OPC_SWC2:
15447 case OPC_SDC2:
7a387fff 15448 /* COP2: Not implemented. */
4ad40f36
FB
15449 generate_exception_err(ctx, EXCP_CpU, 2);
15450 break;
bd277fa1 15451 case OPC_CP2:
d75c135e 15452 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
15453 /* Note that these instructions use different fields. */
15454 gen_loongson_multimedia(ctx, sa, rd, rt);
15455 break;
4ad40f36 15456
7a387fff 15457 case OPC_CP3:
36d23958 15458 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15459 check_cp1_enabled(ctx);
36d23958
TS
15460 op1 = MASK_CP3(ctx->opcode);
15461 switch (op1) {
5a5012ec
TS
15462 case OPC_LWXC1:
15463 case OPC_LDXC1:
15464 case OPC_LUXC1:
15465 case OPC_SWXC1:
15466 case OPC_SDXC1:
15467 case OPC_SUXC1:
93b12ccc 15468 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15469 break;
e0c84da7 15470 case OPC_PREFX:
ead9360e 15471 /* Treat as NOP. */
e0c84da7 15472 break;
5a5012ec
TS
15473 case OPC_ALNV_PS:
15474 case OPC_MADD_S:
15475 case OPC_MADD_D:
15476 case OPC_MADD_PS:
15477 case OPC_MSUB_S:
15478 case OPC_MSUB_D:
15479 case OPC_MSUB_PS:
15480 case OPC_NMADD_S:
15481 case OPC_NMADD_D:
15482 case OPC_NMADD_PS:
15483 case OPC_NMSUB_S:
15484 case OPC_NMSUB_D:
15485 case OPC_NMSUB_PS:
15486 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15487 break;
36d23958 15488 default:
923617a3 15489 MIPS_INVAL("cp3");
e397ee33 15490 generate_exception (ctx, EXCP_RI);
36d23958
TS
15491 break;
15492 }
15493 } else {
e397ee33 15494 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15495 }
4ad40f36
FB
15496 break;
15497
d26bc211 15498#if defined(TARGET_MIPS64)
7a387fff
TS
15499 /* MIPS64 opcodes */
15500 case OPC_LWU:
15501 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15502 case OPC_LLD:
15503 case OPC_LD:
d75c135e 15504 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15505 check_mips_64(ctx);
d75c135e 15506 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
15507 break;
15508 case OPC_SDL ... OPC_SDR:
7a387fff 15509 case OPC_SD:
d75c135e 15510 check_insn(ctx, ISA_MIPS3);
e189e748 15511 check_mips_64(ctx);
5c13fdfd 15512 gen_st(ctx, op, rt, rs, imm);
7a387fff 15513 break;
d66c7132 15514 case OPC_SCD:
d75c135e 15515 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
15516 check_mips_64(ctx);
15517 gen_st_cond(ctx, op, rt, rs, imm);
15518 break;
324d9e32
AJ
15519 case OPC_DADDI:
15520 case OPC_DADDIU:
d75c135e 15521 check_insn(ctx, ISA_MIPS3);
e189e748 15522 check_mips_64(ctx);
d75c135e 15523 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15524 break;
6af0bf9c 15525#endif
7a387fff 15526 case OPC_JALX:
d75c135e 15527 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15528 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15529 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15530 *is_branch = 1;
15531 break;
7a387fff 15532 case OPC_MDMX:
d75c135e 15533 check_insn(ctx, ASE_MDMX);
7a387fff 15534 /* MDMX: Not implemented. */
6af0bf9c 15535 default: /* Invalid */
923617a3 15536 MIPS_INVAL("major opcode");
6af0bf9c
FB
15537 generate_exception(ctx, EXCP_RI);
15538 break;
15539 }
6af0bf9c
FB
15540}
15541
2cfc5f17 15542static inline void
7db13fae 15543gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
820e00f2 15544 int search_pc)
6af0bf9c 15545{
278d0702 15546 DisasContext ctx;
6af0bf9c
FB
15547 target_ulong pc_start;
15548 uint16_t *gen_opc_end;
a1d1bb31 15549 CPUBreakpoint *bp;
6af0bf9c 15550 int j, lj = -1;
2e70f6ef
PB
15551 int num_insns;
15552 int max_insns;
c9602061
NF
15553 int insn_bytes;
15554 int is_branch;
6af0bf9c 15555
93fcfe39
AL
15556 if (search_pc)
15557 qemu_log("search pc %d\n", search_pc);
4ad40f36 15558
6af0bf9c 15559 pc_start = tb->pc;
92414b31 15560 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15561 ctx.pc = pc_start;
4ad40f36 15562 ctx.saved_pc = -1;
7b270ef2 15563 ctx.singlestep_enabled = env->singlestep_enabled;
d75c135e 15564 ctx.insn_flags = env->insn_flags;
6af0bf9c
FB
15565 ctx.tb = tb;
15566 ctx.bstate = BS_NONE;
4ad40f36 15567 /* Restore delay slot state from the tb context. */
c068688b 15568 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
fd4a04eb 15569 restore_cpu_state(env, &ctx);
932e71cd 15570#ifdef CONFIG_USER_ONLY
0eaef5aa 15571 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15572#else
0eaef5aa 15573 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15574#endif
2e70f6ef
PB
15575 num_insns = 0;
15576 max_insns = tb->cflags & CF_COUNT_MASK;
15577 if (max_insns == 0)
15578 max_insns = CF_COUNT_MASK;
d12d51d5 15579 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 15580 gen_tb_start();
faf7aaa9 15581 while (ctx.bstate == BS_NONE) {
72cf2d4f
BS
15582 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15583 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 15584 if (bp->pc == ctx.pc) {
278d0702 15585 save_cpu_state(&ctx, 1);
4ad40f36 15586 ctx.bstate = BS_BRANCH;
895c2d04 15587 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15588 /* Include the breakpoint location or the tb won't
15589 * be flushed when it must be. */
15590 ctx.pc += 4;
4ad40f36
FB
15591 goto done_generating;
15592 }
15593 }
15594 }
15595
6af0bf9c 15596 if (search_pc) {
92414b31 15597 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15598 if (lj < j) {
15599 lj++;
15600 while (lj < j)
ab1103de 15601 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 15602 }
25983cad 15603 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 15604 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15605 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 15606 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 15607 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 15608 }
2e70f6ef
PB
15609 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15610 gen_io_start();
c9602061
NF
15611
15612 is_branch = 0;
364d4831 15613 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15614 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061
NF
15615 insn_bytes = 4;
15616 decode_opc(env, &ctx, &is_branch);
d75c135e 15617 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 15618 ctx.opcode = cpu_lduw_code(env, ctx.pc);
3c824109 15619 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
d75c135e 15620 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 15621 ctx.opcode = cpu_lduw_code(env, ctx.pc);
364d4831 15622 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
c9602061
NF
15623 } else {
15624 generate_exception(&ctx, EXCP_RI);
3c824109 15625 ctx.bstate = BS_STOP;
c9602061
NF
15626 break;
15627 }
15628 if (!is_branch) {
d75c135e 15629 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
15630 }
15631 ctx.pc += insn_bytes;
15632
2e70f6ef 15633 num_insns++;
4ad40f36 15634
7b270ef2
NF
15635 /* Execute a branch and its delay slot as a single instruction.
15636 This is what GDB expects and is consistent with what the
15637 hardware does (e.g. if a delay slot instruction faults, the
15638 reported PC is the PC of the branch). */
15639 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
4ad40f36
FB
15640 break;
15641
6af0bf9c
FB
15642 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15643 break;
4ad40f36 15644
efd7f486 15645 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 15646 break;
efd7f486 15647 }
faf7aaa9 15648
2e70f6ef
PB
15649 if (num_insns >= max_insns)
15650 break;
1b530a6d
AJ
15651
15652 if (singlestep)
15653 break;
6af0bf9c 15654 }
2e70f6ef
PB
15655 if (tb->cflags & CF_LAST_IO)
15656 gen_io_end();
7b270ef2 15657 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15658 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15659 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15660 } else {
6958549d 15661 switch (ctx.bstate) {
16c00cb2 15662 case BS_STOP:
df1561e2
TS
15663 gen_goto_tb(&ctx, 0, ctx.pc);
15664 break;
16c00cb2 15665 case BS_NONE:
278d0702 15666 save_cpu_state(&ctx, 0);
16c00cb2
TS
15667 gen_goto_tb(&ctx, 0, ctx.pc);
15668 break;
5a5012ec 15669 case BS_EXCP:
57fec1fe 15670 tcg_gen_exit_tb(0);
16c00cb2 15671 break;
5a5012ec
TS
15672 case BS_BRANCH:
15673 default:
15674 break;
6958549d 15675 }
6af0bf9c 15676 }
4ad40f36 15677done_generating:
806f352d 15678 gen_tb_end(tb, num_insns);
efd7f486 15679 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 15680 if (search_pc) {
92414b31 15681 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15682 lj++;
15683 while (lj <= j)
ab1103de 15684 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15685 } else {
15686 tb->size = ctx.pc - pc_start;
2e70f6ef 15687 tb->icount = num_insns;
6af0bf9c
FB
15688 }
15689#ifdef DEBUG_DISAS
d12d51d5 15690 LOG_DISAS("\n");
8fec2b8c 15691 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 15692 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 15693 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 15694 qemu_log("\n");
6af0bf9c
FB
15695 }
15696#endif
6af0bf9c
FB
15697}
15698
7db13fae 15699void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15700{
2cfc5f17 15701 gen_intermediate_code_internal(env, tb, 0);
6af0bf9c
FB
15702}
15703
7db13fae 15704void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15705{
2cfc5f17 15706 gen_intermediate_code_internal(env, tb, 1);
6af0bf9c
FB
15707}
15708
7db13fae 15709static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15710 int flags)
6ea83fed
FB
15711{
15712 int i;
5e755519 15713 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15714
2a5612e6
SW
15715#define printfpr(fp) \
15716 do { \
15717 if (is_fpu64) \
15718 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15719 " fd:%13g fs:%13g psu: %13g\n", \
15720 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15721 (double)(fp)->fd, \
15722 (double)(fp)->fs[FP_ENDIAN_IDX], \
15723 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15724 else { \
15725 fpr_t tmp; \
15726 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15727 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15728 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15729 " fd:%13g fs:%13g psu:%13g\n", \
15730 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15731 (double)tmp.fd, \
15732 (double)tmp.fs[FP_ENDIAN_IDX], \
15733 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15734 } \
6ea83fed
FB
15735 } while(0)
15736
5a5012ec 15737
9a78eead
SW
15738 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15739 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15740 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15741 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15742 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15743 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15744 }
15745
15746#undef printfpr
15747}
15748
d26bc211 15749#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15750/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15751 sign-extended values on 64bit machines. */
c570fd16
TS
15752
15753#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15754
8706c382 15755static void
7db13fae 15756cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15757 fprintf_function cpu_fprintf,
8706c382 15758 int flags)
c570fd16
TS
15759{
15760 int i;
15761
b5dc7732
TS
15762 if (!SIGN_EXT_P(env->active_tc.PC))
15763 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15764 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15765 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15766 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15767 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15768 if (!SIGN_EXT_P(env->btarget))
3594c774 15769 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15770
15771 for (i = 0; i < 32; i++) {
b5dc7732
TS
15772 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15773 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15774 }
15775
15776 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15777 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15778 if (!SIGN_EXT_P(env->lladdr))
15779 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15780}
15781#endif
15782
878096ee
AF
15783void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15784 int flags)
6af0bf9c 15785{
878096ee
AF
15786 MIPSCPU *cpu = MIPS_CPU(cs);
15787 CPUMIPSState *env = &cpu->env;
6af0bf9c 15788 int i;
3b46e624 15789
a7200c9f
SW
15790 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15791 " LO=0x" TARGET_FMT_lx " ds %04x "
15792 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15793 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15794 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15795 for (i = 0; i < 32; i++) {
15796 if ((i & 3) == 0)
15797 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15798 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15799 if ((i & 3) == 3)
15800 cpu_fprintf(f, "\n");
15801 }
568b600d 15802
3594c774 15803 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15804 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15805 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15806 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15807 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15808 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15809#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15810 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15811#endif
6af0bf9c
FB
15812}
15813
78ce64f4 15814void mips_tcg_init(void)
39454628 15815{
f01be154 15816 int i;
39454628
TS
15817 static int inited;
15818
15819 /* Initialize various static tables. */
15820 if (inited)
6958549d 15821 return;
39454628 15822
a7812ae4 15823 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15824 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15825 for (i = 1; i < 32; i++)
a7812ae4 15826 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15827 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15828 regnames[i]);
d73ee8a2
RH
15829
15830 for (i = 0; i < 32; i++) {
15831 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15832 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15833 }
15834
a7812ae4 15835 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15836 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15837 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15838 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15839 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15840 regnames_HI[i]);
a7812ae4 15841 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15842 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15843 regnames_LO[i]);
a7812ae4 15844 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15845 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15846 regnames_ACX[i]);
15847 }
a7812ae4 15848 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15849 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15850 "DSPControl");
1ba74fb8 15851 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15852 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15853 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15854 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15855 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15856 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15857
a7812ae4 15858 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15859 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15860 "fcr0");
15861 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15862 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15863 "fcr31");
39454628 15864
7dd9e556 15865 /* register helpers */
a7812ae4 15866#define GEN_HELPER 2
7dd9e556
TS
15867#include "helper.h"
15868
39454628
TS
15869 inited = 1;
15870}
15871
aaed909a
FB
15872#include "translate_init.c"
15873
30bf942d 15874MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15875{
0f71a709 15876 MIPSCPU *cpu;
6af0bf9c 15877 CPUMIPSState *env;
c227f099 15878 const mips_def_t *def;
6af0bf9c 15879
aaed909a
FB
15880 def = cpu_mips_find_by_name(cpu_model);
15881 if (!def)
15882 return NULL;
0f71a709
AF
15883 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15884 env = &cpu->env;
aaed909a 15885 env->cpu_model = def;
51cc2e78 15886 env->cpu_model_str = cpu_model;
aaed909a 15887
51cc2e78
BS
15888#ifndef CONFIG_USER_ONLY
15889 mmu_init(env, def);
15890#endif
15891 fpu_init(env, def);
15892 mvp_init(env, def);
c1caf1d9
AF
15893
15894 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15895
30bf942d 15896 return cpu;
6ae81775
TS
15897}
15898
1bba0dc9 15899void cpu_state_reset(CPUMIPSState *env)
6ae81775 15900{
55e5c285
AF
15901#ifndef CONFIG_USER_ONLY
15902 MIPSCPU *cpu = mips_env_get_cpu(env);
15903 CPUState *cs = CPU(cpu);
15904#endif
6ae81775 15905
51cc2e78
BS
15906 /* Reset registers to their default values */
15907 env->CP0_PRid = env->cpu_model->CP0_PRid;
15908 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15909#ifdef TARGET_WORDS_BIGENDIAN
15910 env->CP0_Config0 |= (1 << CP0C0_BE);
15911#endif
15912 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15913 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15914 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15915 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15916 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
15917 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15918 << env->cpu_model->CP0_LLAddr_shift;
15919 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
15920 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15921 env->CCRes = env->cpu_model->CCRes;
15922 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15923 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15924 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15925 env->current_tc = 0;
15926 env->SEGBITS = env->cpu_model->SEGBITS;
15927 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15928#if defined(TARGET_MIPS64)
15929 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15930 env->SEGMask |= 3ULL << 62;
15931 }
15932#endif
15933 env->PABITS = env->cpu_model->PABITS;
15934 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15935 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15936 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15937 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15938 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15939 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15940 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15941 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15942 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15943 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15944 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 15945 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
15946 env->insn_flags = env->cpu_model->insn_flags;
15947
0eaef5aa 15948#if defined(CONFIG_USER_ONLY)
03e6e501 15949 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
15950# ifdef TARGET_MIPS64
15951 /* Enable 64-bit register mode. */
15952 env->CP0_Status |= (1 << CP0St_PX);
15953# endif
15954# ifdef TARGET_ABI_MIPSN64
15955 /* Enable 64-bit address mode. */
15956 env->CP0_Status |= (1 << CP0St_UX);
15957# endif
94159135
MI
15958 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15959 hardware registers. */
15960 env->CP0_HWREna |= 0x0000000F;
91a75935 15961 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 15962 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 15963 }
6f0af304
PJ
15964 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
15965 env->CP0_Status |= (1 << CP0St_MX);
853c3240 15966 }
68473f15
RH
15967 /* Enable 64-bit FPU if the target cpu supports it. */
15968 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
15969 env->CP0_Status |= (1 << CP0St_FR);
15970 }
932e71cd
AJ
15971#else
15972 if (env->hflags & MIPS_HFLAG_BMASK) {
15973 /* If the exception was raised from a delay slot,
15974 come back to the jump. */
15975 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 15976 } else {
932e71cd
AJ
15977 env->CP0_ErrorEPC = env->active_tc.PC;
15978 }
15979 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
15980 env->CP0_Random = env->tlb->nb_tlb - 1;
15981 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 15982 env->CP0_Wired = 0;
55e5c285 15983 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
932e71cd
AJ
15984 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15985 /* vectored interrupts not implemented, timer on int 7,
15986 no performance counters. */
15987 env->CP0_IntCtl = 0xe0000000;
15988 {
15989 int i;
15990
15991 for (i = 0; i < 7; i++) {
15992 env->CP0_WatchLo[i] = 0;
15993 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 15994 }
932e71cd
AJ
15995 env->CP0_WatchLo[7] = 0;
15996 env->CP0_WatchHi[7] = 0;
fd88b6ab 15997 }
932e71cd
AJ
15998 /* Count register increments in debug mode, EJTAG version 1 */
15999 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756
EI
16000
16001 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16002 int i;
16003
16004 /* Only TC0 on VPE 0 starts as active. */
16005 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 16006 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
16007 env->tcs[i].CP0_TCHalt = 1;
16008 }
16009 env->active_tc.CP0_TCHalt = 1;
259186a7 16010 cs->halted = 1;
9e56e756 16011
55e5c285 16012 if (cs->cpu_index == 0) {
9e56e756
EI
16013 /* VPE0 starts up enabled. */
16014 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16015 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16016
16017 /* TC0 starts up unhalted. */
259186a7 16018 cs->halted = 0;
9e56e756
EI
16019 env->active_tc.CP0_TCHalt = 0;
16020 env->tcs[0].CP0_TCHalt = 0;
16021 /* With thread 0 active. */
16022 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16023 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16024 }
16025 }
51cc2e78 16026#endif
03e6e501 16027 compute_hflags(env);
6af0bf9c 16028 env->exception_index = EXCP_NONE;
6af0bf9c 16029}
d2856f1a 16030
7db13fae 16031void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16032{
25983cad 16033 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16034 env->hflags &= ~MIPS_HFLAG_BMASK;
16035 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16036 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16037 case MIPS_HFLAG_BR:
16038 break;
16039 case MIPS_HFLAG_BC:
16040 case MIPS_HFLAG_BL:
16041 case MIPS_HFLAG_B:
16042 env->btarget = gen_opc_btarget[pc_pos];
16043 break;
16044 }
d2856f1a 16045}