]> Git Repo - qemu.git/blame - target-mips/translate.c
target-mips: add user-mode FR switch support for MIPS32r5
[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:
5f68f5ae 1609 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 1610 gen_store_gpr(t0, rt);
6e473128
TS
1611 opn = "lwu";
1612 break;
6af0bf9c 1613 case OPC_LD:
5f68f5ae 1614 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
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);
5f68f5ae 1632 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
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);
5f68f5ae 1653 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
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);
5f68f5ae 1670 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
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);
5f68f5ae 1679 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 1680 gen_store_gpr(t0, rt);
5c13fdfd 1681 opn = "lwpc";
364d4831 1682 break;
6af0bf9c 1683 case OPC_LW:
5f68f5ae 1684 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 1685 gen_store_gpr(t0, rt);
6af0bf9c
FB
1686 opn = "lw";
1687 break;
6af0bf9c 1688 case OPC_LH:
5f68f5ae 1689 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 1690 gen_store_gpr(t0, rt);
6af0bf9c
FB
1691 opn = "lh";
1692 break;
6af0bf9c 1693 case OPC_LHU:
5f68f5ae 1694 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 1695 gen_store_gpr(t0, rt);
6af0bf9c
FB
1696 opn = "lhu";
1697 break;
1698 case OPC_LB:
5f68f5ae 1699 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 1700 gen_store_gpr(t0, rt);
6af0bf9c
FB
1701 opn = "lb";
1702 break;
6af0bf9c 1703 case OPC_LBU:
5f68f5ae 1704 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
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);
5f68f5ae 1716 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
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);
5f68f5ae 1738 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
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:
5f68f5ae 1777 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
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:
5f68f5ae 1792 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
1793 opn = "sw";
1794 break;
1795 case OPC_SH:
5f68f5ae 1796 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
1797 opn = "sh";
1798 break;
1799 case OPC_SB:
5f68f5ae 1800 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
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();
5f68f5ae 1871 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 1872 gen_store_fpr32(fp0, ft);
a7812ae4 1873 tcg_temp_free_i32(fp0);
b6d96bed 1874 }
6ea83fed
FB
1875 opn = "lwc1";
1876 break;
1877 case OPC_SWC1:
b6d96bed 1878 {
a7812ae4 1879 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1880 gen_load_fpr32(fp0, ft);
5f68f5ae 1881 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 1882 tcg_temp_free_i32(fp0);
b6d96bed 1883 }
6ea83fed
FB
1884 opn = "swc1";
1885 break;
1886 case OPC_LDC1:
b6d96bed 1887 {
a7812ae4 1888 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 1889 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 1890 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1891 tcg_temp_free_i64(fp0);
b6d96bed 1892 }
6ea83fed
FB
1893 opn = "ldc1";
1894 break;
1895 case OPC_SDC1:
b6d96bed 1896 {
a7812ae4 1897 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 1898 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 1899 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 1900 tcg_temp_free_i64(fp0);
b6d96bed 1901 }
6ea83fed
FB
1902 opn = "sdc1";
1903 break;
1904 default:
923617a3 1905 MIPS_INVAL(opn);
e397ee33 1906 generate_exception(ctx, EXCP_RI);
78723684 1907 goto out;
6ea83fed 1908 }
2abf314d 1909 (void)opn; /* avoid a compiler warning */
6ea83fed 1910 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1911 out:
1912 tcg_temp_free(t0);
6ea83fed 1913}
6ea83fed 1914
7db13fae 1915static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
26ebe468
NF
1916 uint32_t op, int rt, int rs, int16_t imm)
1917{
1918 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1919 check_cp1_enabled(ctx);
1920 gen_flt_ldst(ctx, op, rt, rs, imm);
1921 } else {
1922 generate_exception_err(ctx, EXCP_CpU, 1);
1923 }
1924}
1925
6af0bf9c 1926/* Arithmetic with immediate operand */
d75c135e
AJ
1927static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1928 int rt, int rs, int16_t imm)
6af0bf9c 1929{
324d9e32 1930 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1931 const char *opn = "imm arith";
6af0bf9c 1932
7a387fff 1933 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1934 /* If no destination, treat it as a NOP.
1935 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1936 MIPS_DEBUG("NOP");
324d9e32 1937 return;
6af0bf9c
FB
1938 }
1939 switch (opc) {
1940 case OPC_ADDI:
48d38ca5 1941 {
324d9e32
AJ
1942 TCGv t0 = tcg_temp_local_new();
1943 TCGv t1 = tcg_temp_new();
1944 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1945 int l1 = gen_new_label();
1946
324d9e32
AJ
1947 gen_load_gpr(t1, rs);
1948 tcg_gen_addi_tl(t0, t1, uimm);
1949 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1950
324d9e32
AJ
1951 tcg_gen_xori_tl(t1, t1, ~uimm);
1952 tcg_gen_xori_tl(t2, t0, uimm);
1953 tcg_gen_and_tl(t1, t1, t2);
1954 tcg_temp_free(t2);
1955 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1956 tcg_temp_free(t1);
48d38ca5
TS
1957 /* operands of same sign, result different sign */
1958 generate_exception(ctx, EXCP_OVERFLOW);
1959 gen_set_label(l1);
78723684 1960 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1961 gen_store_gpr(t0, rt);
1962 tcg_temp_free(t0);
48d38ca5 1963 }
6af0bf9c
FB
1964 opn = "addi";
1965 break;
1966 case OPC_ADDIU:
324d9e32
AJ
1967 if (rs != 0) {
1968 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1969 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1970 } else {
1971 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1972 }
6af0bf9c
FB
1973 opn = "addiu";
1974 break;
d26bc211 1975#if defined(TARGET_MIPS64)
7a387fff 1976 case OPC_DADDI:
48d38ca5 1977 {
324d9e32
AJ
1978 TCGv t0 = tcg_temp_local_new();
1979 TCGv t1 = tcg_temp_new();
1980 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1981 int l1 = gen_new_label();
1982
324d9e32
AJ
1983 gen_load_gpr(t1, rs);
1984 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1985
324d9e32
AJ
1986 tcg_gen_xori_tl(t1, t1, ~uimm);
1987 tcg_gen_xori_tl(t2, t0, uimm);
1988 tcg_gen_and_tl(t1, t1, t2);
1989 tcg_temp_free(t2);
1990 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1991 tcg_temp_free(t1);
48d38ca5
TS
1992 /* operands of same sign, result different sign */
1993 generate_exception(ctx, EXCP_OVERFLOW);
1994 gen_set_label(l1);
324d9e32
AJ
1995 gen_store_gpr(t0, rt);
1996 tcg_temp_free(t0);
48d38ca5 1997 }
7a387fff
TS
1998 opn = "daddi";
1999 break;
2000 case OPC_DADDIU:
324d9e32
AJ
2001 if (rs != 0) {
2002 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2003 } else {
2004 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2005 }
7a387fff
TS
2006 opn = "daddiu";
2007 break;
2008#endif
324d9e32 2009 }
2abf314d 2010 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2011 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2012}
2013
2014/* Logic with immediate operand */
d75c135e 2015static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2016 int rt, int rs, int16_t imm)
324d9e32
AJ
2017{
2018 target_ulong uimm;
324d9e32
AJ
2019
2020 if (rt == 0) {
2021 /* If no destination, treat it as a NOP. */
2022 MIPS_DEBUG("NOP");
2023 return;
2024 }
2025 uimm = (uint16_t)imm;
2026 switch (opc) {
6af0bf9c 2027 case OPC_ANDI:
324d9e32
AJ
2028 if (likely(rs != 0))
2029 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2030 else
2031 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2032 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2033 regnames[rs], uimm);
6af0bf9c
FB
2034 break;
2035 case OPC_ORI:
324d9e32
AJ
2036 if (rs != 0)
2037 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2038 else
2039 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2040 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2041 regnames[rs], uimm);
6af0bf9c
FB
2042 break;
2043 case OPC_XORI:
324d9e32
AJ
2044 if (likely(rs != 0))
2045 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2046 else
2047 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2048 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2049 regnames[rs], uimm);
6af0bf9c
FB
2050 break;
2051 case OPC_LUI:
324d9e32 2052 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2053 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2054 break;
2055
2056 default:
2057 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2058 break;
324d9e32 2059 }
324d9e32
AJ
2060}
2061
2062/* Set on less than with immediate operand */
d75c135e 2063static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2064 int rt, int rs, int16_t imm)
324d9e32
AJ
2065{
2066 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2067 const char *opn = "imm arith";
2068 TCGv t0;
2069
2070 if (rt == 0) {
2071 /* If no destination, treat it as a NOP. */
2072 MIPS_DEBUG("NOP");
2073 return;
2074 }
2075 t0 = tcg_temp_new();
2076 gen_load_gpr(t0, rs);
2077 switch (opc) {
2078 case OPC_SLTI:
e68dd28f 2079 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2080 opn = "slti";
2081 break;
2082 case OPC_SLTIU:
e68dd28f 2083 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2084 opn = "sltiu";
2085 break;
2086 }
2abf314d 2087 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2088 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2089 tcg_temp_free(t0);
2090}
2091
2092/* Shifts with immediate operand */
d75c135e 2093static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2094 int rt, int rs, int16_t imm)
2095{
2096 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2097 const char *opn = "imm shift";
2098 TCGv t0;
2099
2100 if (rt == 0) {
2101 /* If no destination, treat it as a NOP. */
2102 MIPS_DEBUG("NOP");
2103 return;
2104 }
2105
2106 t0 = tcg_temp_new();
2107 gen_load_gpr(t0, rs);
2108 switch (opc) {
6af0bf9c 2109 case OPC_SLL:
78723684 2110 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2111 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2112 opn = "sll";
2113 break;
2114 case OPC_SRA:
324d9e32 2115 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2116 opn = "sra";
2117 break;
2118 case OPC_SRL:
ea63e2c3
NF
2119 if (uimm != 0) {
2120 tcg_gen_ext32u_tl(t0, t0);
2121 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2122 } else {
2123 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2124 }
ea63e2c3
NF
2125 opn = "srl";
2126 break;
2127 case OPC_ROTR:
2128 if (uimm != 0) {
2129 TCGv_i32 t1 = tcg_temp_new_i32();
2130
2131 tcg_gen_trunc_tl_i32(t1, t0);
2132 tcg_gen_rotri_i32(t1, t1, uimm);
2133 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2134 tcg_temp_free_i32(t1);
3399e30f
NF
2135 } else {
2136 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2137 }
2138 opn = "rotr";
7a387fff 2139 break;
d26bc211 2140#if defined(TARGET_MIPS64)
7a387fff 2141 case OPC_DSLL:
324d9e32 2142 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2143 opn = "dsll";
2144 break;
2145 case OPC_DSRA:
324d9e32 2146 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2147 opn = "dsra";
2148 break;
2149 case OPC_DSRL:
ea63e2c3
NF
2150 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2151 opn = "dsrl";
2152 break;
2153 case OPC_DROTR:
2154 if (uimm != 0) {
2155 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2156 } else {
2157 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2158 }
ea63e2c3 2159 opn = "drotr";
7a387fff
TS
2160 break;
2161 case OPC_DSLL32:
324d9e32 2162 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2163 opn = "dsll32";
2164 break;
2165 case OPC_DSRA32:
324d9e32 2166 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2167 opn = "dsra32";
2168 break;
2169 case OPC_DSRL32:
ea63e2c3
NF
2170 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2171 opn = "dsrl32";
2172 break;
2173 case OPC_DROTR32:
2174 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2175 opn = "drotr32";
6af0bf9c 2176 break;
7a387fff 2177#endif
6af0bf9c 2178 }
2abf314d 2179 (void)opn; /* avoid a compiler warning */
93b12ccc 2180 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2181 tcg_temp_free(t0);
6af0bf9c
FB
2182}
2183
2184/* Arithmetic */
d75c135e
AJ
2185static void gen_arith(DisasContext *ctx, uint32_t opc,
2186 int rd, int rs, int rt)
6af0bf9c 2187{
923617a3 2188 const char *opn = "arith";
6af0bf9c 2189
7a387fff
TS
2190 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2191 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2192 /* If no destination, treat it as a NOP.
2193 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2194 MIPS_DEBUG("NOP");
460f00c4 2195 return;
185f0762 2196 }
460f00c4 2197
6af0bf9c
FB
2198 switch (opc) {
2199 case OPC_ADD:
48d38ca5 2200 {
460f00c4
AJ
2201 TCGv t0 = tcg_temp_local_new();
2202 TCGv t1 = tcg_temp_new();
2203 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2204 int l1 = gen_new_label();
2205
460f00c4
AJ
2206 gen_load_gpr(t1, rs);
2207 gen_load_gpr(t2, rt);
2208 tcg_gen_add_tl(t0, t1, t2);
2209 tcg_gen_ext32s_tl(t0, t0);
2210 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2211 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2212 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2213 tcg_temp_free(t2);
2214 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2215 tcg_temp_free(t1);
48d38ca5
TS
2216 /* operands of same sign, result different sign */
2217 generate_exception(ctx, EXCP_OVERFLOW);
2218 gen_set_label(l1);
460f00c4
AJ
2219 gen_store_gpr(t0, rd);
2220 tcg_temp_free(t0);
48d38ca5 2221 }
6af0bf9c
FB
2222 opn = "add";
2223 break;
2224 case OPC_ADDU:
460f00c4
AJ
2225 if (rs != 0 && rt != 0) {
2226 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2227 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2228 } else if (rs == 0 && rt != 0) {
2229 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2230 } else if (rs != 0 && rt == 0) {
2231 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2232 } else {
2233 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2234 }
6af0bf9c
FB
2235 opn = "addu";
2236 break;
2237 case OPC_SUB:
48d38ca5 2238 {
460f00c4
AJ
2239 TCGv t0 = tcg_temp_local_new();
2240 TCGv t1 = tcg_temp_new();
2241 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2242 int l1 = gen_new_label();
2243
460f00c4
AJ
2244 gen_load_gpr(t1, rs);
2245 gen_load_gpr(t2, rt);
2246 tcg_gen_sub_tl(t0, t1, t2);
2247 tcg_gen_ext32s_tl(t0, t0);
2248 tcg_gen_xor_tl(t2, t1, t2);
2249 tcg_gen_xor_tl(t1, t0, t1);
2250 tcg_gen_and_tl(t1, t1, t2);
2251 tcg_temp_free(t2);
2252 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2253 tcg_temp_free(t1);
31e3104f 2254 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2255 generate_exception(ctx, EXCP_OVERFLOW);
2256 gen_set_label(l1);
460f00c4
AJ
2257 gen_store_gpr(t0, rd);
2258 tcg_temp_free(t0);
48d38ca5 2259 }
6af0bf9c
FB
2260 opn = "sub";
2261 break;
2262 case OPC_SUBU:
460f00c4
AJ
2263 if (rs != 0 && rt != 0) {
2264 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2265 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2266 } else if (rs == 0 && rt != 0) {
2267 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2268 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2269 } else if (rs != 0 && rt == 0) {
2270 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2271 } else {
2272 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2273 }
6af0bf9c
FB
2274 opn = "subu";
2275 break;
d26bc211 2276#if defined(TARGET_MIPS64)
7a387fff 2277 case OPC_DADD:
48d38ca5 2278 {
460f00c4
AJ
2279 TCGv t0 = tcg_temp_local_new();
2280 TCGv t1 = tcg_temp_new();
2281 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2282 int l1 = gen_new_label();
2283
460f00c4
AJ
2284 gen_load_gpr(t1, rs);
2285 gen_load_gpr(t2, rt);
2286 tcg_gen_add_tl(t0, t1, t2);
2287 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2288 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2289 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2290 tcg_temp_free(t2);
2291 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2292 tcg_temp_free(t1);
48d38ca5
TS
2293 /* operands of same sign, result different sign */
2294 generate_exception(ctx, EXCP_OVERFLOW);
2295 gen_set_label(l1);
460f00c4
AJ
2296 gen_store_gpr(t0, rd);
2297 tcg_temp_free(t0);
48d38ca5 2298 }
7a387fff
TS
2299 opn = "dadd";
2300 break;
2301 case OPC_DADDU:
460f00c4
AJ
2302 if (rs != 0 && rt != 0) {
2303 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2304 } else if (rs == 0 && rt != 0) {
2305 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2306 } else if (rs != 0 && rt == 0) {
2307 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2308 } else {
2309 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2310 }
7a387fff
TS
2311 opn = "daddu";
2312 break;
2313 case OPC_DSUB:
48d38ca5 2314 {
460f00c4
AJ
2315 TCGv t0 = tcg_temp_local_new();
2316 TCGv t1 = tcg_temp_new();
2317 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2318 int l1 = gen_new_label();
2319
460f00c4
AJ
2320 gen_load_gpr(t1, rs);
2321 gen_load_gpr(t2, rt);
2322 tcg_gen_sub_tl(t0, t1, t2);
2323 tcg_gen_xor_tl(t2, t1, t2);
2324 tcg_gen_xor_tl(t1, t0, t1);
2325 tcg_gen_and_tl(t1, t1, t2);
2326 tcg_temp_free(t2);
2327 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2328 tcg_temp_free(t1);
31e3104f 2329 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2330 generate_exception(ctx, EXCP_OVERFLOW);
2331 gen_set_label(l1);
460f00c4
AJ
2332 gen_store_gpr(t0, rd);
2333 tcg_temp_free(t0);
48d38ca5 2334 }
7a387fff
TS
2335 opn = "dsub";
2336 break;
2337 case OPC_DSUBU:
460f00c4
AJ
2338 if (rs != 0 && rt != 0) {
2339 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2340 } else if (rs == 0 && rt != 0) {
2341 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2342 } else if (rs != 0 && rt == 0) {
2343 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2344 } else {
2345 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2346 }
7a387fff
TS
2347 opn = "dsubu";
2348 break;
2349#endif
460f00c4
AJ
2350 case OPC_MUL:
2351 if (likely(rs != 0 && rt != 0)) {
2352 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2353 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2354 } else {
2355 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2356 }
2357 opn = "mul";
6af0bf9c 2358 break;
460f00c4 2359 }
2abf314d 2360 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2361 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2362}
2363
2364/* Conditional move */
d75c135e 2365static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2366 int rd, int rs, int rt)
460f00c4
AJ
2367{
2368 const char *opn = "cond move";
acf12465 2369 TCGv t0, t1, t2;
460f00c4
AJ
2370
2371 if (rd == 0) {
acf12465 2372 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2373 MIPS_DEBUG("NOP");
2374 return;
2375 }
2376
acf12465
AJ
2377 t0 = tcg_temp_new();
2378 gen_load_gpr(t0, rt);
2379 t1 = tcg_const_tl(0);
2380 t2 = tcg_temp_new();
2381 gen_load_gpr(t2, rs);
460f00c4
AJ
2382 switch (opc) {
2383 case OPC_MOVN:
acf12465 2384 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2385 opn = "movn";
6af0bf9c 2386 break;
460f00c4 2387 case OPC_MOVZ:
acf12465 2388 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2389 opn = "movz";
2390 break;
2391 }
acf12465
AJ
2392 tcg_temp_free(t2);
2393 tcg_temp_free(t1);
2394 tcg_temp_free(t0);
460f00c4 2395
2abf314d 2396 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2397 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2398}
2399
2400/* Logic */
d75c135e 2401static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2402 int rd, int rs, int rt)
460f00c4
AJ
2403{
2404 const char *opn = "logic";
2405
2406 if (rd == 0) {
2407 /* If no destination, treat it as a NOP. */
2408 MIPS_DEBUG("NOP");
2409 return;
2410 }
2411
2412 switch (opc) {
6af0bf9c 2413 case OPC_AND:
460f00c4
AJ
2414 if (likely(rs != 0 && rt != 0)) {
2415 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2416 } else {
2417 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2418 }
6af0bf9c
FB
2419 opn = "and";
2420 break;
2421 case OPC_NOR:
460f00c4
AJ
2422 if (rs != 0 && rt != 0) {
2423 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2424 } else if (rs == 0 && rt != 0) {
2425 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2426 } else if (rs != 0 && rt == 0) {
2427 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2428 } else {
2429 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2430 }
6af0bf9c
FB
2431 opn = "nor";
2432 break;
2433 case OPC_OR:
460f00c4
AJ
2434 if (likely(rs != 0 && rt != 0)) {
2435 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2436 } else if (rs == 0 && rt != 0) {
2437 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2438 } else if (rs != 0 && rt == 0) {
2439 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2440 } else {
2441 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2442 }
6af0bf9c
FB
2443 opn = "or";
2444 break;
2445 case OPC_XOR:
460f00c4
AJ
2446 if (likely(rs != 0 && rt != 0)) {
2447 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2448 } else if (rs == 0 && rt != 0) {
2449 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2450 } else if (rs != 0 && rt == 0) {
2451 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2452 } else {
2453 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2454 }
6af0bf9c
FB
2455 opn = "xor";
2456 break;
460f00c4 2457 }
2abf314d 2458 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2459 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2460}
2461
2462/* Set on lower than */
d75c135e 2463static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2464 int rd, int rs, int rt)
460f00c4
AJ
2465{
2466 const char *opn = "slt";
2467 TCGv t0, t1;
2468
2469 if (rd == 0) {
2470 /* If no destination, treat it as a NOP. */
2471 MIPS_DEBUG("NOP");
2472 return;
2473 }
2474
2475 t0 = tcg_temp_new();
2476 t1 = tcg_temp_new();
2477 gen_load_gpr(t0, rs);
2478 gen_load_gpr(t1, rt);
2479 switch (opc) {
2480 case OPC_SLT:
e68dd28f 2481 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2482 opn = "slt";
6af0bf9c 2483 break;
460f00c4 2484 case OPC_SLTU:
e68dd28f 2485 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2486 opn = "sltu";
2487 break;
2488 }
2abf314d 2489 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2490 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2491 tcg_temp_free(t0);
2492 tcg_temp_free(t1);
2493}
20c4c97c 2494
460f00c4 2495/* Shifts */
d75c135e
AJ
2496static void gen_shift(DisasContext *ctx, uint32_t opc,
2497 int rd, int rs, int rt)
460f00c4
AJ
2498{
2499 const char *opn = "shifts";
2500 TCGv t0, t1;
20c4c97c 2501
460f00c4
AJ
2502 if (rd == 0) {
2503 /* If no destination, treat it as a NOP.
2504 For add & sub, we must generate the overflow exception when needed. */
2505 MIPS_DEBUG("NOP");
2506 return;
2507 }
2508
2509 t0 = tcg_temp_new();
2510 t1 = tcg_temp_new();
2511 gen_load_gpr(t0, rs);
2512 gen_load_gpr(t1, rt);
2513 switch (opc) {
6af0bf9c 2514 case OPC_SLLV:
78723684
TS
2515 tcg_gen_andi_tl(t0, t0, 0x1f);
2516 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2517 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2518 opn = "sllv";
2519 break;
2520 case OPC_SRAV:
78723684 2521 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2522 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2523 opn = "srav";
2524 break;
2525 case OPC_SRLV:
ea63e2c3
NF
2526 tcg_gen_ext32u_tl(t1, t1);
2527 tcg_gen_andi_tl(t0, t0, 0x1f);
2528 tcg_gen_shr_tl(t0, t1, t0);
2529 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2530 opn = "srlv";
2531 break;
2532 case OPC_ROTRV:
2533 {
2534 TCGv_i32 t2 = tcg_temp_new_i32();
2535 TCGv_i32 t3 = tcg_temp_new_i32();
2536
2537 tcg_gen_trunc_tl_i32(t2, t0);
2538 tcg_gen_trunc_tl_i32(t3, t1);
2539 tcg_gen_andi_i32(t2, t2, 0x1f);
2540 tcg_gen_rotr_i32(t2, t3, t2);
2541 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2542 tcg_temp_free_i32(t2);
2543 tcg_temp_free_i32(t3);
2544 opn = "rotrv";
5a63bcb2 2545 }
7a387fff 2546 break;
d26bc211 2547#if defined(TARGET_MIPS64)
7a387fff 2548 case OPC_DSLLV:
78723684 2549 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2550 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2551 opn = "dsllv";
2552 break;
2553 case OPC_DSRAV:
78723684 2554 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2555 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2556 opn = "dsrav";
2557 break;
2558 case OPC_DSRLV:
ea63e2c3
NF
2559 tcg_gen_andi_tl(t0, t0, 0x3f);
2560 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2561 opn = "dsrlv";
2562 break;
2563 case OPC_DROTRV:
2564 tcg_gen_andi_tl(t0, t0, 0x3f);
2565 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2566 opn = "drotrv";
6af0bf9c 2567 break;
7a387fff 2568#endif
6af0bf9c 2569 }
2abf314d 2570 (void)opn; /* avoid a compiler warning */
6af0bf9c 2571 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2572 tcg_temp_free(t0);
2573 tcg_temp_free(t1);
6af0bf9c
FB
2574}
2575
2576/* Arithmetic on HI/LO registers */
26135ead 2577static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 2578{
923617a3 2579 const char *opn = "hilo";
6af0bf9c
FB
2580
2581 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2582 /* Treat as NOP. */
6af0bf9c 2583 MIPS_DEBUG("NOP");
a1f6684d 2584 return;
6af0bf9c 2585 }
4133498f 2586
4133498f
JL
2587 if (acc != 0) {
2588 check_dsp(ctx);
2589 }
2590
6af0bf9c
FB
2591 switch (opc) {
2592 case OPC_MFHI:
4133498f
JL
2593#if defined(TARGET_MIPS64)
2594 if (acc != 0) {
2595 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2596 } else
2597#endif
2598 {
2599 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2600 }
6af0bf9c
FB
2601 opn = "mfhi";
2602 break;
2603 case OPC_MFLO:
4133498f
JL
2604#if defined(TARGET_MIPS64)
2605 if (acc != 0) {
2606 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2607 } else
2608#endif
2609 {
2610 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2611 }
6af0bf9c
FB
2612 opn = "mflo";
2613 break;
2614 case OPC_MTHI:
4133498f
JL
2615 if (reg != 0) {
2616#if defined(TARGET_MIPS64)
2617 if (acc != 0) {
2618 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2619 } else
2620#endif
2621 {
2622 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2623 }
2624 } else {
2625 tcg_gen_movi_tl(cpu_HI[acc], 0);
2626 }
6af0bf9c
FB
2627 opn = "mthi";
2628 break;
2629 case OPC_MTLO:
4133498f
JL
2630 if (reg != 0) {
2631#if defined(TARGET_MIPS64)
2632 if (acc != 0) {
2633 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2634 } else
2635#endif
2636 {
2637 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2638 }
2639 } else {
2640 tcg_gen_movi_tl(cpu_LO[acc], 0);
2641 }
6af0bf9c
FB
2642 opn = "mtlo";
2643 break;
6af0bf9c 2644 }
2abf314d 2645 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2646 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2647}
2648
26135ead
RS
2649static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2650 int acc, int rs, int rt)
6af0bf9c 2651{
923617a3 2652 const char *opn = "mul/div";
d45f89f4
AJ
2653 TCGv t0, t1;
2654
51127181
AJ
2655 t0 = tcg_temp_new();
2656 t1 = tcg_temp_new();
6af0bf9c 2657
78723684
TS
2658 gen_load_gpr(t0, rs);
2659 gen_load_gpr(t1, rt);
51127181 2660
26135ead
RS
2661 if (acc != 0) {
2662 check_dsp(ctx);
2663 }
2664
6af0bf9c
FB
2665 switch (opc) {
2666 case OPC_DIV:
48d38ca5 2667 {
51127181
AJ
2668 TCGv t2 = tcg_temp_new();
2669 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2670 tcg_gen_ext32s_tl(t0, t0);
2671 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2672 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2673 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2674 tcg_gen_and_tl(t2, t2, t3);
2675 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2676 tcg_gen_or_tl(t2, t2, t3);
2677 tcg_gen_movi_tl(t3, 0);
2678 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2679 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2680 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2681 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2682 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2683 tcg_temp_free(t3);
2684 tcg_temp_free(t2);
48d38ca5 2685 }
6af0bf9c
FB
2686 opn = "div";
2687 break;
2688 case OPC_DIVU:
48d38ca5 2689 {
51127181
AJ
2690 TCGv t2 = tcg_const_tl(0);
2691 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
2692 tcg_gen_ext32u_tl(t0, t0);
2693 tcg_gen_ext32u_tl(t1, t1);
51127181 2694 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2695 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2696 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2697 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2698 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2699 tcg_temp_free(t3);
2700 tcg_temp_free(t2);
48d38ca5 2701 }
6af0bf9c
FB
2702 opn = "divu";
2703 break;
2704 case OPC_MULT:
214c465f 2705 {
ce1dd5d1
RH
2706 TCGv_i32 t2 = tcg_temp_new_i32();
2707 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
2708 tcg_gen_trunc_tl_i32(t2, t0);
2709 tcg_gen_trunc_tl_i32(t3, t1);
2710 tcg_gen_muls2_i32(t2, t3, t2, t3);
2711 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2712 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2713 tcg_temp_free_i32(t2);
2714 tcg_temp_free_i32(t3);
214c465f 2715 }
6af0bf9c
FB
2716 opn = "mult";
2717 break;
2718 case OPC_MULTU:
214c465f 2719 {
ce1dd5d1
RH
2720 TCGv_i32 t2 = tcg_temp_new_i32();
2721 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
2722 tcg_gen_trunc_tl_i32(t2, t0);
2723 tcg_gen_trunc_tl_i32(t3, t1);
2724 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2725 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2726 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2727 tcg_temp_free_i32(t2);
2728 tcg_temp_free_i32(t3);
214c465f 2729 }
6af0bf9c
FB
2730 opn = "multu";
2731 break;
d26bc211 2732#if defined(TARGET_MIPS64)
7a387fff 2733 case OPC_DDIV:
48d38ca5 2734 {
51127181
AJ
2735 TCGv t2 = tcg_temp_new();
2736 TCGv t3 = tcg_temp_new();
2737 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2738 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2739 tcg_gen_and_tl(t2, t2, t3);
2740 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2741 tcg_gen_or_tl(t2, t2, t3);
2742 tcg_gen_movi_tl(t3, 0);
2743 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2744 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2745 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
2746 tcg_temp_free(t3);
2747 tcg_temp_free(t2);
48d38ca5 2748 }
7a387fff
TS
2749 opn = "ddiv";
2750 break;
2751 case OPC_DDIVU:
48d38ca5 2752 {
51127181
AJ
2753 TCGv t2 = tcg_const_tl(0);
2754 TCGv t3 = tcg_const_tl(1);
2755 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2756 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2757 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
2758 tcg_temp_free(t3);
2759 tcg_temp_free(t2);
48d38ca5 2760 }
7a387fff
TS
2761 opn = "ddivu";
2762 break;
2763 case OPC_DMULT:
26135ead 2764 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
2765 opn = "dmult";
2766 break;
2767 case OPC_DMULTU:
26135ead 2768 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
2769 opn = "dmultu";
2770 break;
2771#endif
6af0bf9c 2772 case OPC_MADD:
214c465f 2773 {
d45f89f4
AJ
2774 TCGv_i64 t2 = tcg_temp_new_i64();
2775 TCGv_i64 t3 = tcg_temp_new_i64();
2776
2777 tcg_gen_ext_tl_i64(t2, t0);
2778 tcg_gen_ext_tl_i64(t3, t1);
2779 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2780 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2781 tcg_gen_add_i64(t2, t2, t3);
2782 tcg_temp_free_i64(t3);
2783 tcg_gen_trunc_i64_tl(t0, t2);
2784 tcg_gen_shri_i64(t2, t2, 32);
2785 tcg_gen_trunc_i64_tl(t1, t2);
2786 tcg_temp_free_i64(t2);
4133498f
JL
2787 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2788 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2789 }
6af0bf9c
FB
2790 opn = "madd";
2791 break;
2792 case OPC_MADDU:
4133498f 2793 {
d45f89f4
AJ
2794 TCGv_i64 t2 = tcg_temp_new_i64();
2795 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 2796
78723684
TS
2797 tcg_gen_ext32u_tl(t0, t0);
2798 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2799 tcg_gen_extu_tl_i64(t2, t0);
2800 tcg_gen_extu_tl_i64(t3, t1);
2801 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2802 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2803 tcg_gen_add_i64(t2, t2, t3);
2804 tcg_temp_free_i64(t3);
2805 tcg_gen_trunc_i64_tl(t0, t2);
2806 tcg_gen_shri_i64(t2, t2, 32);
2807 tcg_gen_trunc_i64_tl(t1, t2);
2808 tcg_temp_free_i64(t2);
4133498f
JL
2809 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2810 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2811 }
6af0bf9c
FB
2812 opn = "maddu";
2813 break;
2814 case OPC_MSUB:
214c465f 2815 {
d45f89f4
AJ
2816 TCGv_i64 t2 = tcg_temp_new_i64();
2817 TCGv_i64 t3 = tcg_temp_new_i64();
2818
2819 tcg_gen_ext_tl_i64(t2, t0);
2820 tcg_gen_ext_tl_i64(t3, t1);
2821 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2822 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2823 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2824 tcg_temp_free_i64(t3);
2825 tcg_gen_trunc_i64_tl(t0, t2);
2826 tcg_gen_shri_i64(t2, t2, 32);
2827 tcg_gen_trunc_i64_tl(t1, t2);
2828 tcg_temp_free_i64(t2);
4133498f
JL
2829 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2830 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2831 }
6af0bf9c
FB
2832 opn = "msub";
2833 break;
2834 case OPC_MSUBU:
214c465f 2835 {
d45f89f4
AJ
2836 TCGv_i64 t2 = tcg_temp_new_i64();
2837 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 2838
78723684
TS
2839 tcg_gen_ext32u_tl(t0, t0);
2840 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2841 tcg_gen_extu_tl_i64(t2, t0);
2842 tcg_gen_extu_tl_i64(t3, t1);
2843 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2844 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2845 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2846 tcg_temp_free_i64(t3);
2847 tcg_gen_trunc_i64_tl(t0, t2);
2848 tcg_gen_shri_i64(t2, t2, 32);
2849 tcg_gen_trunc_i64_tl(t1, t2);
2850 tcg_temp_free_i64(t2);
4133498f
JL
2851 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2852 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2853 }
6af0bf9c
FB
2854 opn = "msubu";
2855 break;
2856 default:
923617a3 2857 MIPS_INVAL(opn);
6af0bf9c 2858 generate_exception(ctx, EXCP_RI);
78723684 2859 goto out;
6af0bf9c 2860 }
2abf314d 2861 (void)opn; /* avoid a compiler warning */
6af0bf9c 2862 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2863 out:
2864 tcg_temp_free(t0);
2865 tcg_temp_free(t1);
6af0bf9c
FB
2866}
2867
e9c71dd1
TS
2868static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2869 int rd, int rs, int rt)
2870{
2871 const char *opn = "mul vr54xx";
f157bfe1
AJ
2872 TCGv t0 = tcg_temp_new();
2873 TCGv t1 = tcg_temp_new();
e9c71dd1 2874
6c5c1e20
TS
2875 gen_load_gpr(t0, rs);
2876 gen_load_gpr(t1, rt);
e9c71dd1
TS
2877
2878 switch (opc) {
2879 case OPC_VR54XX_MULS:
895c2d04 2880 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2881 opn = "muls";
6958549d 2882 break;
e9c71dd1 2883 case OPC_VR54XX_MULSU:
895c2d04 2884 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2885 opn = "mulsu";
6958549d 2886 break;
e9c71dd1 2887 case OPC_VR54XX_MACC:
895c2d04 2888 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2889 opn = "macc";
6958549d 2890 break;
e9c71dd1 2891 case OPC_VR54XX_MACCU:
895c2d04 2892 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2893 opn = "maccu";
6958549d 2894 break;
e9c71dd1 2895 case OPC_VR54XX_MSAC:
895c2d04 2896 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2897 opn = "msac";
6958549d 2898 break;
e9c71dd1 2899 case OPC_VR54XX_MSACU:
895c2d04 2900 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2901 opn = "msacu";
6958549d 2902 break;
e9c71dd1 2903 case OPC_VR54XX_MULHI:
895c2d04 2904 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2905 opn = "mulhi";
6958549d 2906 break;
e9c71dd1 2907 case OPC_VR54XX_MULHIU:
895c2d04 2908 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2909 opn = "mulhiu";
6958549d 2910 break;
e9c71dd1 2911 case OPC_VR54XX_MULSHI:
895c2d04 2912 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2913 opn = "mulshi";
6958549d 2914 break;
e9c71dd1 2915 case OPC_VR54XX_MULSHIU:
895c2d04 2916 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2917 opn = "mulshiu";
6958549d 2918 break;
e9c71dd1 2919 case OPC_VR54XX_MACCHI:
895c2d04 2920 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2921 opn = "macchi";
6958549d 2922 break;
e9c71dd1 2923 case OPC_VR54XX_MACCHIU:
895c2d04 2924 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2925 opn = "macchiu";
6958549d 2926 break;
e9c71dd1 2927 case OPC_VR54XX_MSACHI:
895c2d04 2928 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2929 opn = "msachi";
6958549d 2930 break;
e9c71dd1 2931 case OPC_VR54XX_MSACHIU:
895c2d04 2932 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2933 opn = "msachiu";
6958549d 2934 break;
e9c71dd1
TS
2935 default:
2936 MIPS_INVAL("mul vr54xx");
2937 generate_exception(ctx, EXCP_RI);
6c5c1e20 2938 goto out;
e9c71dd1 2939 }
6c5c1e20 2940 gen_store_gpr(t0, rd);
2abf314d 2941 (void)opn; /* avoid a compiler warning */
e9c71dd1 2942 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2943
2944 out:
2945 tcg_temp_free(t0);
2946 tcg_temp_free(t1);
e9c71dd1
TS
2947}
2948
7a387fff 2949static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2950 int rd, int rs)
2951{
923617a3 2952 const char *opn = "CLx";
20e1fb52 2953 TCGv t0;
6c5c1e20 2954
6af0bf9c 2955 if (rd == 0) {
ead9360e 2956 /* Treat as NOP. */
6af0bf9c 2957 MIPS_DEBUG("NOP");
20e1fb52 2958 return;
6af0bf9c 2959 }
20e1fb52 2960 t0 = tcg_temp_new();
6c5c1e20 2961 gen_load_gpr(t0, rs);
6af0bf9c
FB
2962 switch (opc) {
2963 case OPC_CLO:
20e1fb52 2964 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
2965 opn = "clo";
2966 break;
2967 case OPC_CLZ:
20e1fb52 2968 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
2969 opn = "clz";
2970 break;
d26bc211 2971#if defined(TARGET_MIPS64)
7a387fff 2972 case OPC_DCLO:
20e1fb52 2973 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
2974 opn = "dclo";
2975 break;
2976 case OPC_DCLZ:
20e1fb52 2977 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
2978 opn = "dclz";
2979 break;
2980#endif
6af0bf9c 2981 }
2abf314d 2982 (void)opn; /* avoid a compiler warning */
6af0bf9c 2983 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 2984 tcg_temp_free(t0);
6af0bf9c
FB
2985}
2986
161f85e6 2987/* Godson integer instructions */
bd277fa1
RH
2988static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2989 int rd, int rs, int rt)
161f85e6
AJ
2990{
2991 const char *opn = "loongson";
2992 TCGv t0, t1;
2993
2994 if (rd == 0) {
2995 /* Treat as NOP. */
2996 MIPS_DEBUG("NOP");
2997 return;
2998 }
2999
3000 switch (opc) {
3001 case OPC_MULT_G_2E:
3002 case OPC_MULT_G_2F:
3003 case OPC_MULTU_G_2E:
3004 case OPC_MULTU_G_2F:
3005#if defined(TARGET_MIPS64)
3006 case OPC_DMULT_G_2E:
3007 case OPC_DMULT_G_2F:
3008 case OPC_DMULTU_G_2E:
3009 case OPC_DMULTU_G_2F:
3010#endif
3011 t0 = tcg_temp_new();
3012 t1 = tcg_temp_new();
3013 break;
3014 default:
3015 t0 = tcg_temp_local_new();
3016 t1 = tcg_temp_local_new();
3017 break;
3018 }
3019
3020 gen_load_gpr(t0, rs);
3021 gen_load_gpr(t1, rt);
3022
3023 switch (opc) {
3024 case OPC_MULT_G_2E:
3025 case OPC_MULT_G_2F:
3026 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3027 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3028 opn = "mult.g";
3029 break;
3030 case OPC_MULTU_G_2E:
3031 case OPC_MULTU_G_2F:
3032 tcg_gen_ext32u_tl(t0, t0);
3033 tcg_gen_ext32u_tl(t1, t1);
3034 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3035 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3036 opn = "multu.g";
3037 break;
3038 case OPC_DIV_G_2E:
3039 case OPC_DIV_G_2F:
3040 {
3041 int l1 = gen_new_label();
3042 int l2 = gen_new_label();
3043 int l3 = gen_new_label();
3044 tcg_gen_ext32s_tl(t0, t0);
3045 tcg_gen_ext32s_tl(t1, t1);
3046 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3047 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3048 tcg_gen_br(l3);
3049 gen_set_label(l1);
3050 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3051 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3052 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3053 tcg_gen_br(l3);
3054 gen_set_label(l2);
3055 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3056 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3057 gen_set_label(l3);
3058 }
3059 opn = "div.g";
3060 break;
3061 case OPC_DIVU_G_2E:
3062 case OPC_DIVU_G_2F:
3063 {
3064 int l1 = gen_new_label();
3065 int l2 = gen_new_label();
3066 tcg_gen_ext32u_tl(t0, t0);
3067 tcg_gen_ext32u_tl(t1, t1);
3068 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3069 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3070 tcg_gen_br(l2);
3071 gen_set_label(l1);
3072 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3073 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3074 gen_set_label(l2);
3075 }
3076 opn = "divu.g";
3077 break;
3078 case OPC_MOD_G_2E:
3079 case OPC_MOD_G_2F:
3080 {
3081 int l1 = gen_new_label();
3082 int l2 = gen_new_label();
3083 int l3 = gen_new_label();
3084 tcg_gen_ext32u_tl(t0, t0);
3085 tcg_gen_ext32u_tl(t1, t1);
3086 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3087 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3088 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3089 gen_set_label(l1);
3090 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3091 tcg_gen_br(l3);
3092 gen_set_label(l2);
3093 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3094 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3095 gen_set_label(l3);
3096 }
3097 opn = "mod.g";
3098 break;
3099 case OPC_MODU_G_2E:
3100 case OPC_MODU_G_2F:
3101 {
3102 int l1 = gen_new_label();
3103 int l2 = gen_new_label();
3104 tcg_gen_ext32u_tl(t0, t0);
3105 tcg_gen_ext32u_tl(t1, t1);
3106 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3107 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3108 tcg_gen_br(l2);
3109 gen_set_label(l1);
3110 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3111 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3112 gen_set_label(l2);
3113 }
3114 opn = "modu.g";
3115 break;
3116#if defined(TARGET_MIPS64)
3117 case OPC_DMULT_G_2E:
3118 case OPC_DMULT_G_2F:
3119 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3120 opn = "dmult.g";
3121 break;
3122 case OPC_DMULTU_G_2E:
3123 case OPC_DMULTU_G_2F:
3124 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3125 opn = "dmultu.g";
3126 break;
3127 case OPC_DDIV_G_2E:
3128 case OPC_DDIV_G_2F:
3129 {
3130 int l1 = gen_new_label();
3131 int l2 = gen_new_label();
3132 int l3 = gen_new_label();
3133 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3134 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3135 tcg_gen_br(l3);
3136 gen_set_label(l1);
3137 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3138 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3139 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3140 tcg_gen_br(l3);
3141 gen_set_label(l2);
3142 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3143 gen_set_label(l3);
3144 }
3145 opn = "ddiv.g";
3146 break;
3147 case OPC_DDIVU_G_2E:
3148 case OPC_DDIVU_G_2F:
3149 {
3150 int l1 = gen_new_label();
3151 int l2 = gen_new_label();
3152 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3153 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3154 tcg_gen_br(l2);
3155 gen_set_label(l1);
3156 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3157 gen_set_label(l2);
3158 }
3159 opn = "ddivu.g";
3160 break;
3161 case OPC_DMOD_G_2E:
3162 case OPC_DMOD_G_2F:
3163 {
3164 int l1 = gen_new_label();
3165 int l2 = gen_new_label();
3166 int l3 = gen_new_label();
3167 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3168 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3169 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3170 gen_set_label(l1);
3171 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3172 tcg_gen_br(l3);
3173 gen_set_label(l2);
3174 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3175 gen_set_label(l3);
3176 }
3177 opn = "dmod.g";
3178 break;
3179 case OPC_DMODU_G_2E:
3180 case OPC_DMODU_G_2F:
3181 {
3182 int l1 = gen_new_label();
3183 int l2 = gen_new_label();
3184 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3185 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3186 tcg_gen_br(l2);
3187 gen_set_label(l1);
3188 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3189 gen_set_label(l2);
3190 }
3191 opn = "dmodu.g";
3192 break;
3193#endif
3194 }
3195
2abf314d 3196 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3197 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3198 tcg_temp_free(t0);
3199 tcg_temp_free(t1);
3200}
3201
bd277fa1
RH
3202/* Loongson multimedia instructions */
3203static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3204{
3205 const char *opn = "loongson_cp2";
3206 uint32_t opc, shift_max;
3207 TCGv_i64 t0, t1;
3208
3209 opc = MASK_LMI(ctx->opcode);
3210 switch (opc) {
3211 case OPC_ADD_CP2:
3212 case OPC_SUB_CP2:
3213 case OPC_DADD_CP2:
3214 case OPC_DSUB_CP2:
3215 t0 = tcg_temp_local_new_i64();
3216 t1 = tcg_temp_local_new_i64();
3217 break;
3218 default:
3219 t0 = tcg_temp_new_i64();
3220 t1 = tcg_temp_new_i64();
3221 break;
3222 }
3223
3224 gen_load_fpr64(ctx, t0, rs);
3225 gen_load_fpr64(ctx, t1, rt);
3226
3227#define LMI_HELPER(UP, LO) \
3228 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3229#define LMI_HELPER_1(UP, LO) \
3230 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3231#define LMI_DIRECT(UP, LO, OP) \
3232 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3233
3234 switch (opc) {
3235 LMI_HELPER(PADDSH, paddsh);
3236 LMI_HELPER(PADDUSH, paddush);
3237 LMI_HELPER(PADDH, paddh);
3238 LMI_HELPER(PADDW, paddw);
3239 LMI_HELPER(PADDSB, paddsb);
3240 LMI_HELPER(PADDUSB, paddusb);
3241 LMI_HELPER(PADDB, paddb);
3242
3243 LMI_HELPER(PSUBSH, psubsh);
3244 LMI_HELPER(PSUBUSH, psubush);
3245 LMI_HELPER(PSUBH, psubh);
3246 LMI_HELPER(PSUBW, psubw);
3247 LMI_HELPER(PSUBSB, psubsb);
3248 LMI_HELPER(PSUBUSB, psubusb);
3249 LMI_HELPER(PSUBB, psubb);
3250
3251 LMI_HELPER(PSHUFH, pshufh);
3252 LMI_HELPER(PACKSSWH, packsswh);
3253 LMI_HELPER(PACKSSHB, packsshb);
3254 LMI_HELPER(PACKUSHB, packushb);
3255
3256 LMI_HELPER(PUNPCKLHW, punpcklhw);
3257 LMI_HELPER(PUNPCKHHW, punpckhhw);
3258 LMI_HELPER(PUNPCKLBH, punpcklbh);
3259 LMI_HELPER(PUNPCKHBH, punpckhbh);
3260 LMI_HELPER(PUNPCKLWD, punpcklwd);
3261 LMI_HELPER(PUNPCKHWD, punpckhwd);
3262
3263 LMI_HELPER(PAVGH, pavgh);
3264 LMI_HELPER(PAVGB, pavgb);
3265 LMI_HELPER(PMAXSH, pmaxsh);
3266 LMI_HELPER(PMINSH, pminsh);
3267 LMI_HELPER(PMAXUB, pmaxub);
3268 LMI_HELPER(PMINUB, pminub);
3269
3270 LMI_HELPER(PCMPEQW, pcmpeqw);
3271 LMI_HELPER(PCMPGTW, pcmpgtw);
3272 LMI_HELPER(PCMPEQH, pcmpeqh);
3273 LMI_HELPER(PCMPGTH, pcmpgth);
3274 LMI_HELPER(PCMPEQB, pcmpeqb);
3275 LMI_HELPER(PCMPGTB, pcmpgtb);
3276
3277 LMI_HELPER(PSLLW, psllw);
3278 LMI_HELPER(PSLLH, psllh);
3279 LMI_HELPER(PSRLW, psrlw);
3280 LMI_HELPER(PSRLH, psrlh);
3281 LMI_HELPER(PSRAW, psraw);
3282 LMI_HELPER(PSRAH, psrah);
3283
3284 LMI_HELPER(PMULLH, pmullh);
3285 LMI_HELPER(PMULHH, pmulhh);
3286 LMI_HELPER(PMULHUH, pmulhuh);
3287 LMI_HELPER(PMADDHW, pmaddhw);
3288
3289 LMI_HELPER(PASUBUB, pasubub);
3290 LMI_HELPER_1(BIADD, biadd);
3291 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3292
3293 LMI_DIRECT(PADDD, paddd, add);
3294 LMI_DIRECT(PSUBD, psubd, sub);
3295 LMI_DIRECT(XOR_CP2, xor, xor);
3296 LMI_DIRECT(NOR_CP2, nor, nor);
3297 LMI_DIRECT(AND_CP2, and, and);
3298 LMI_DIRECT(PANDN, pandn, andc);
3299 LMI_DIRECT(OR, or, or);
3300
3301 case OPC_PINSRH_0:
3302 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3303 opn = "pinsrh_0";
3304 break;
3305 case OPC_PINSRH_1:
3306 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3307 opn = "pinsrh_1";
3308 break;
3309 case OPC_PINSRH_2:
3310 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3311 opn = "pinsrh_2";
3312 break;
3313 case OPC_PINSRH_3:
3314 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3315 opn = "pinsrh_3";
3316 break;
3317
3318 case OPC_PEXTRH:
3319 tcg_gen_andi_i64(t1, t1, 3);
3320 tcg_gen_shli_i64(t1, t1, 4);
3321 tcg_gen_shr_i64(t0, t0, t1);
3322 tcg_gen_ext16u_i64(t0, t0);
3323 opn = "pextrh";
3324 break;
3325
3326 case OPC_ADDU_CP2:
3327 tcg_gen_add_i64(t0, t0, t1);
3328 tcg_gen_ext32s_i64(t0, t0);
3329 opn = "addu";
3330 break;
3331 case OPC_SUBU_CP2:
3332 tcg_gen_sub_i64(t0, t0, t1);
3333 tcg_gen_ext32s_i64(t0, t0);
3334 opn = "addu";
3335 break;
3336
3337 case OPC_SLL_CP2:
3338 opn = "sll";
3339 shift_max = 32;
3340 goto do_shift;
3341 case OPC_SRL_CP2:
3342 opn = "srl";
3343 shift_max = 32;
3344 goto do_shift;
3345 case OPC_SRA_CP2:
3346 opn = "sra";
3347 shift_max = 32;
3348 goto do_shift;
3349 case OPC_DSLL_CP2:
3350 opn = "dsll";
3351 shift_max = 64;
3352 goto do_shift;
3353 case OPC_DSRL_CP2:
3354 opn = "dsrl";
3355 shift_max = 64;
3356 goto do_shift;
3357 case OPC_DSRA_CP2:
3358 opn = "dsra";
3359 shift_max = 64;
3360 goto do_shift;
3361 do_shift:
3362 /* Make sure shift count isn't TCG undefined behaviour. */
3363 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3364
3365 switch (opc) {
3366 case OPC_SLL_CP2:
3367 case OPC_DSLL_CP2:
3368 tcg_gen_shl_i64(t0, t0, t1);
3369 break;
3370 case OPC_SRA_CP2:
3371 case OPC_DSRA_CP2:
3372 /* Since SRA is UndefinedResult without sign-extended inputs,
3373 we can treat SRA and DSRA the same. */
3374 tcg_gen_sar_i64(t0, t0, t1);
3375 break;
3376 case OPC_SRL_CP2:
3377 /* We want to shift in zeros for SRL; zero-extend first. */
3378 tcg_gen_ext32u_i64(t0, t0);
3379 /* FALLTHRU */
3380 case OPC_DSRL_CP2:
3381 tcg_gen_shr_i64(t0, t0, t1);
3382 break;
3383 }
3384
3385 if (shift_max == 32) {
3386 tcg_gen_ext32s_i64(t0, t0);
3387 }
3388
3389 /* Shifts larger than MAX produce zero. */
3390 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3391 tcg_gen_neg_i64(t1, t1);
3392 tcg_gen_and_i64(t0, t0, t1);
3393 break;
3394
3395 case OPC_ADD_CP2:
3396 case OPC_DADD_CP2:
3397 {
3398 TCGv_i64 t2 = tcg_temp_new_i64();
3399 int lab = gen_new_label();
3400
3401 tcg_gen_mov_i64(t2, t0);
3402 tcg_gen_add_i64(t0, t1, t2);
3403 if (opc == OPC_ADD_CP2) {
3404 tcg_gen_ext32s_i64(t0, t0);
3405 }
3406 tcg_gen_xor_i64(t1, t1, t2);
3407 tcg_gen_xor_i64(t2, t2, t0);
3408 tcg_gen_andc_i64(t1, t2, t1);
3409 tcg_temp_free_i64(t2);
3410 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3411 generate_exception(ctx, EXCP_OVERFLOW);
3412 gen_set_label(lab);
3413
3414 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3415 break;
3416 }
3417
3418 case OPC_SUB_CP2:
3419 case OPC_DSUB_CP2:
3420 {
3421 TCGv_i64 t2 = tcg_temp_new_i64();
3422 int lab = gen_new_label();
3423
3424 tcg_gen_mov_i64(t2, t0);
3425 tcg_gen_sub_i64(t0, t1, t2);
3426 if (opc == OPC_SUB_CP2) {
3427 tcg_gen_ext32s_i64(t0, t0);
3428 }
3429 tcg_gen_xor_i64(t1, t1, t2);
3430 tcg_gen_xor_i64(t2, t2, t0);
3431 tcg_gen_and_i64(t1, t1, t2);
3432 tcg_temp_free_i64(t2);
3433 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3434 generate_exception(ctx, EXCP_OVERFLOW);
3435 gen_set_label(lab);
3436
3437 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3438 break;
3439 }
3440
3441 case OPC_PMULUW:
3442 tcg_gen_ext32u_i64(t0, t0);
3443 tcg_gen_ext32u_i64(t1, t1);
3444 tcg_gen_mul_i64(t0, t0, t1);
3445 opn = "pmuluw";
3446 break;
3447
3448 case OPC_SEQU_CP2:
3449 case OPC_SEQ_CP2:
3450 case OPC_SLTU_CP2:
3451 case OPC_SLT_CP2:
3452 case OPC_SLEU_CP2:
3453 case OPC_SLE_CP2:
3454 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3455 FD field is the CC field? */
3456 default:
3457 MIPS_INVAL(opn);
3458 generate_exception(ctx, EXCP_RI);
3459 return;
3460 }
3461
3462#undef LMI_HELPER
3463#undef LMI_DIRECT
3464
3465 gen_store_fpr64(ctx, t0, rd);
3466
3467 (void)opn; /* avoid a compiler warning */
3468 MIPS_DEBUG("%s %s, %s, %s", opn,
3469 fregnames[rd], fregnames[rs], fregnames[rt]);
3470 tcg_temp_free_i64(t0);
3471 tcg_temp_free_i64(t1);
3472}
3473
6af0bf9c 3474/* Traps */
7a387fff 3475static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3476 int rs, int rt, int16_t imm)
3477{
3478 int cond;
cdc0faa6 3479 TCGv t0 = tcg_temp_new();
1ba74fb8 3480 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3481
3482 cond = 0;
3483 /* Load needed operands */
3484 switch (opc) {
3485 case OPC_TEQ:
3486 case OPC_TGE:
3487 case OPC_TGEU:
3488 case OPC_TLT:
3489 case OPC_TLTU:
3490 case OPC_TNE:
3491 /* Compare two registers */
3492 if (rs != rt) {
be24bb4f
TS
3493 gen_load_gpr(t0, rs);
3494 gen_load_gpr(t1, rt);
6af0bf9c
FB
3495 cond = 1;
3496 }
179e32bb 3497 break;
6af0bf9c
FB
3498 case OPC_TEQI:
3499 case OPC_TGEI:
3500 case OPC_TGEIU:
3501 case OPC_TLTI:
3502 case OPC_TLTIU:
3503 case OPC_TNEI:
3504 /* Compare register to immediate */
3505 if (rs != 0 || imm != 0) {
be24bb4f
TS
3506 gen_load_gpr(t0, rs);
3507 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3508 cond = 1;
3509 }
3510 break;
3511 }
3512 if (cond == 0) {
3513 switch (opc) {
3514 case OPC_TEQ: /* rs == rs */
3515 case OPC_TEQI: /* r0 == 0 */
3516 case OPC_TGE: /* rs >= rs */
3517 case OPC_TGEI: /* r0 >= 0 */
3518 case OPC_TGEU: /* rs >= rs unsigned */
3519 case OPC_TGEIU: /* r0 >= 0 unsigned */
3520 /* Always trap */
cdc0faa6 3521 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3522 break;
3523 case OPC_TLT: /* rs < rs */
3524 case OPC_TLTI: /* r0 < 0 */
3525 case OPC_TLTU: /* rs < rs unsigned */
3526 case OPC_TLTIU: /* r0 < 0 unsigned */
3527 case OPC_TNE: /* rs != rs */
3528 case OPC_TNEI: /* r0 != 0 */
ead9360e 3529 /* Never trap: treat as NOP. */
cdc0faa6 3530 break;
6af0bf9c
FB
3531 }
3532 } else {
cdc0faa6
AJ
3533 int l1 = gen_new_label();
3534
6af0bf9c
FB
3535 switch (opc) {
3536 case OPC_TEQ:
3537 case OPC_TEQI:
cdc0faa6 3538 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3539 break;
3540 case OPC_TGE:
3541 case OPC_TGEI:
cdc0faa6 3542 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3543 break;
3544 case OPC_TGEU:
3545 case OPC_TGEIU:
cdc0faa6 3546 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3547 break;
3548 case OPC_TLT:
3549 case OPC_TLTI:
cdc0faa6 3550 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3551 break;
3552 case OPC_TLTU:
3553 case OPC_TLTIU:
cdc0faa6 3554 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3555 break;
3556 case OPC_TNE:
3557 case OPC_TNEI:
cdc0faa6 3558 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3559 break;
6af0bf9c 3560 }
cdc0faa6 3561 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3562 gen_set_label(l1);
3563 }
be24bb4f
TS
3564 tcg_temp_free(t0);
3565 tcg_temp_free(t1);
6af0bf9c
FB
3566}
3567
356265ae 3568static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3569{
6e256c93
FB
3570 TranslationBlock *tb;
3571 tb = ctx->tb;
7b270ef2
NF
3572 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3573 likely(!ctx->singlestep_enabled)) {
57fec1fe 3574 tcg_gen_goto_tb(n);
9b9e4393 3575 gen_save_pc(dest);
8cfd0495 3576 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 3577 } else {
9b9e4393 3578 gen_save_pc(dest);
7b270ef2
NF
3579 if (ctx->singlestep_enabled) {
3580 save_cpu_state(ctx, 0);
895c2d04 3581 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3582 }
57fec1fe 3583 tcg_gen_exit_tb(0);
6e256c93 3584 }
c53be334
FB
3585}
3586
6af0bf9c 3587/* Branches (before delay slot) */
7a387fff 3588static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3589 int insn_bytes,
6af0bf9c
FB
3590 int rs, int rt, int32_t offset)
3591{
d077b6f7 3592 target_ulong btgt = -1;
3ad4bb2d 3593 int blink = 0;
2fdbad25 3594 int bcond_compute = 0;
1ba74fb8
AJ
3595 TCGv t0 = tcg_temp_new();
3596 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3597
3598 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3599#ifdef MIPS_DEBUG_DISAS
d12d51d5 3600 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3601#endif
3ad4bb2d 3602 generate_exception(ctx, EXCP_RI);
6c5c1e20 3603 goto out;
3ad4bb2d 3604 }
6af0bf9c 3605
6af0bf9c
FB
3606 /* Load needed operands */
3607 switch (opc) {
3608 case OPC_BEQ:
3609 case OPC_BEQL:
3610 case OPC_BNE:
3611 case OPC_BNEL:
3612 /* Compare two registers */
3613 if (rs != rt) {
6c5c1e20
TS
3614 gen_load_gpr(t0, rs);
3615 gen_load_gpr(t1, rt);
2fdbad25 3616 bcond_compute = 1;
6af0bf9c 3617 }
7dca4ad0 3618 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3619 break;
3620 case OPC_BGEZ:
3621 case OPC_BGEZAL:
3c824109 3622 case OPC_BGEZALS:
6af0bf9c
FB
3623 case OPC_BGEZALL:
3624 case OPC_BGEZL:
3625 case OPC_BGTZ:
3626 case OPC_BGTZL:
3627 case OPC_BLEZ:
3628 case OPC_BLEZL:
3629 case OPC_BLTZ:
3630 case OPC_BLTZAL:
3c824109 3631 case OPC_BLTZALS:
6af0bf9c
FB
3632 case OPC_BLTZALL:
3633 case OPC_BLTZL:
3634 /* Compare to zero */
3635 if (rs != 0) {
6c5c1e20 3636 gen_load_gpr(t0, rs);
2fdbad25 3637 bcond_compute = 1;
6af0bf9c 3638 }
7dca4ad0 3639 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3640 break;
e45a93e2
JL
3641 case OPC_BPOSGE32:
3642#if defined(TARGET_MIPS64)
3643 case OPC_BPOSGE64:
3644 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3645#else
3646 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3647#endif
3648 bcond_compute = 1;
3649 btgt = ctx->pc + insn_bytes + offset;
3650 break;
6af0bf9c
FB
3651 case OPC_J:
3652 case OPC_JAL:
364d4831 3653 case OPC_JALX:
620e48f6
NF
3654 case OPC_JALS:
3655 case OPC_JALXS:
6af0bf9c 3656 /* Jump to immediate */
7dca4ad0 3657 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3658 break;
3659 case OPC_JR:
3660 case OPC_JALR:
364d4831 3661 case OPC_JALRC:
620e48f6 3662 case OPC_JALRS:
6af0bf9c 3663 /* Jump to register */
7a387fff
TS
3664 if (offset != 0 && offset != 16) {
3665 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3666 others are reserved. */
923617a3 3667 MIPS_INVAL("jump hint");
6af0bf9c 3668 generate_exception(ctx, EXCP_RI);
6c5c1e20 3669 goto out;
6af0bf9c 3670 }
d077b6f7 3671 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3672 break;
3673 default:
3674 MIPS_INVAL("branch/jump");
3675 generate_exception(ctx, EXCP_RI);
6c5c1e20 3676 goto out;
6af0bf9c 3677 }
2fdbad25 3678 if (bcond_compute == 0) {
6af0bf9c
FB
3679 /* No condition to be computed */
3680 switch (opc) {
3681 case OPC_BEQ: /* rx == rx */
3682 case OPC_BEQL: /* rx == rx likely */
3683 case OPC_BGEZ: /* 0 >= 0 */
3684 case OPC_BGEZL: /* 0 >= 0 likely */
3685 case OPC_BLEZ: /* 0 <= 0 */
3686 case OPC_BLEZL: /* 0 <= 0 likely */
3687 /* Always take */
4ad40f36 3688 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3689 MIPS_DEBUG("balways");
3690 break;
3c824109 3691 case OPC_BGEZALS:
6af0bf9c
FB
3692 case OPC_BGEZAL: /* 0 >= 0 */
3693 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3694 ctx->hflags |= (opc == OPC_BGEZALS
3695 ? MIPS_HFLAG_BDS16
3696 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3697 /* Always take and link */
3698 blink = 31;
4ad40f36 3699 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3700 MIPS_DEBUG("balways and link");
3701 break;
3702 case OPC_BNE: /* rx != rx */
3703 case OPC_BGTZ: /* 0 > 0 */
3704 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3705 /* Treat as NOP. */
6af0bf9c 3706 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3707 goto out;
3c824109 3708 case OPC_BLTZALS:
eeef26cd 3709 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3710 ctx->hflags |= (opc == OPC_BLTZALS
3711 ? MIPS_HFLAG_BDS16
3712 : MIPS_HFLAG_BDS32);
3713 /* Handle as an unconditional branch to get correct delay
3714 slot checking. */
3715 blink = 31;
3716 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3717 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3718 MIPS_DEBUG("bnever and link");
3c824109 3719 break;
eeef26cd 3720 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3721 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3722 /* Skip the instruction in the delay slot */
3723 MIPS_DEBUG("bnever, link and skip");
3724 ctx->pc += 4;
6c5c1e20 3725 goto out;
6af0bf9c
FB
3726 case OPC_BNEL: /* rx != rx likely */
3727 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3728 case OPC_BLTZL: /* 0 < 0 likely */
3729 /* Skip the instruction in the delay slot */
3730 MIPS_DEBUG("bnever and skip");
9898128f 3731 ctx->pc += 4;
6c5c1e20 3732 goto out;
6af0bf9c 3733 case OPC_J:
4ad40f36 3734 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3735 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3736 break;
620e48f6 3737 case OPC_JALXS:
364d4831
NF
3738 case OPC_JALX:
3739 ctx->hflags |= MIPS_HFLAG_BX;
3740 /* Fallthrough */
620e48f6 3741 case OPC_JALS:
6af0bf9c
FB
3742 case OPC_JAL:
3743 blink = 31;
4ad40f36 3744 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3745 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3746 ? MIPS_HFLAG_BDS16
3747 : MIPS_HFLAG_BDS32);
d077b6f7 3748 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3749 break;
3750 case OPC_JR:
4ad40f36 3751 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3752 if (insn_bytes == 4)
3753 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3754 MIPS_DEBUG("jr %s", regnames[rs]);
3755 break;
620e48f6 3756 case OPC_JALRS:
6af0bf9c 3757 case OPC_JALR:
364d4831 3758 case OPC_JALRC:
6af0bf9c 3759 blink = rt;
4ad40f36 3760 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3761 ctx->hflags |= (opc == OPC_JALRS
3762 ? MIPS_HFLAG_BDS16
3763 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3764 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3765 break;
3766 default:
3767 MIPS_INVAL("branch/jump");
3768 generate_exception(ctx, EXCP_RI);
6c5c1e20 3769 goto out;
6af0bf9c
FB
3770 }
3771 } else {
3772 switch (opc) {
3773 case OPC_BEQ:
e68dd28f 3774 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3775 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3776 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3777 goto not_likely;
3778 case OPC_BEQL:
e68dd28f 3779 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3780 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3781 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3782 goto likely;
3783 case OPC_BNE:
e68dd28f 3784 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3785 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3786 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3787 goto not_likely;
3788 case OPC_BNEL:
e68dd28f 3789 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3790 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3791 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3792 goto likely;
3793 case OPC_BGEZ:
e68dd28f 3794 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3795 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3796 goto not_likely;
3797 case OPC_BGEZL:
e68dd28f 3798 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3799 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3800 goto likely;
3c824109 3801 case OPC_BGEZALS:
6af0bf9c 3802 case OPC_BGEZAL:
3c824109
NF
3803 ctx->hflags |= (opc == OPC_BGEZALS
3804 ? MIPS_HFLAG_BDS16
3805 : MIPS_HFLAG_BDS32);
e68dd28f 3806 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3807 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3808 blink = 31;
3809 goto not_likely;
3810 case OPC_BGEZALL:
e68dd28f 3811 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3812 blink = 31;
d077b6f7 3813 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3814 goto likely;
3815 case OPC_BGTZ:
e68dd28f 3816 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3817 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3818 goto not_likely;
3819 case OPC_BGTZL:
e68dd28f 3820 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3821 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3822 goto likely;
3823 case OPC_BLEZ:
e68dd28f 3824 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3825 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3826 goto not_likely;
3827 case OPC_BLEZL:
e68dd28f 3828 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3829 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3830 goto likely;
3831 case OPC_BLTZ:
e68dd28f 3832 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3833 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3834 goto not_likely;
3835 case OPC_BLTZL:
e68dd28f 3836 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3837 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3838 goto likely;
e45a93e2
JL
3839 case OPC_BPOSGE32:
3840 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3841 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3842 goto not_likely;
3843#if defined(TARGET_MIPS64)
3844 case OPC_BPOSGE64:
3845 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3846 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3847 goto not_likely;
3848#endif
3c824109 3849 case OPC_BLTZALS:
6af0bf9c 3850 case OPC_BLTZAL:
3c824109
NF
3851 ctx->hflags |= (opc == OPC_BLTZALS
3852 ? MIPS_HFLAG_BDS16
3853 : MIPS_HFLAG_BDS32);
e68dd28f 3854 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3855 blink = 31;
d077b6f7 3856 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3857 not_likely:
4ad40f36 3858 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3859 break;
3860 case OPC_BLTZALL:
e68dd28f 3861 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3862 blink = 31;
d077b6f7 3863 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3864 likely:
4ad40f36 3865 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3866 break;
c53f4a62
TS
3867 default:
3868 MIPS_INVAL("conditional branch/jump");
3869 generate_exception(ctx, EXCP_RI);
6c5c1e20 3870 goto out;
6af0bf9c 3871 }
6af0bf9c 3872 }
923617a3 3873 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3874 blink, ctx->hflags, btgt);
9b9e4393 3875
d077b6f7 3876 ctx->btarget = btgt;
6af0bf9c 3877 if (blink > 0) {
364d4831
NF
3878 int post_delay = insn_bytes;
3879 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3880
3881 if (opc != OPC_JALRC)
3882 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3883
3884 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3885 }
6c5c1e20
TS
3886
3887 out:
364d4831
NF
3888 if (insn_bytes == 2)
3889 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3890 tcg_temp_free(t0);
3891 tcg_temp_free(t1);
6af0bf9c
FB
3892}
3893
7a387fff
TS
3894/* special3 bitfield operations */
3895static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3896 int rs, int lsb, int msb)
7a387fff 3897{
a7812ae4
PB
3898 TCGv t0 = tcg_temp_new();
3899 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
3900
3901 gen_load_gpr(t1, rs);
7a387fff
TS
3902 switch (opc) {
3903 case OPC_EXT:
3904 if (lsb + msb > 31)
3905 goto fail;
505ad7c2
AJ
3906 tcg_gen_shri_tl(t0, t1, lsb);
3907 if (msb != 31) {
3908 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3909 } else {
3910 tcg_gen_ext32s_tl(t0, t0);
3911 }
7a387fff 3912 break;
c6d6dd7c 3913#if defined(TARGET_MIPS64)
7a387fff 3914 case OPC_DEXTM:
505ad7c2
AJ
3915 tcg_gen_shri_tl(t0, t1, lsb);
3916 if (msb != 31) {
3917 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3918 }
7a387fff
TS
3919 break;
3920 case OPC_DEXTU:
505ad7c2
AJ
3921 tcg_gen_shri_tl(t0, t1, lsb + 32);
3922 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3923 break;
3924 case OPC_DEXT:
505ad7c2
AJ
3925 tcg_gen_shri_tl(t0, t1, lsb);
3926 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3927 break;
c6d6dd7c 3928#endif
7a387fff
TS
3929 case OPC_INS:
3930 if (lsb > msb)
3931 goto fail;
6c5c1e20 3932 gen_load_gpr(t0, rt);
e0d002f1 3933 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 3934 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3935 break;
c6d6dd7c 3936#if defined(TARGET_MIPS64)
7a387fff 3937 case OPC_DINSM:
6c5c1e20 3938 gen_load_gpr(t0, rt);
e0d002f1 3939 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
3940 break;
3941 case OPC_DINSU:
6c5c1e20 3942 gen_load_gpr(t0, rt);
e0d002f1 3943 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
3944 break;
3945 case OPC_DINS:
6c5c1e20 3946 gen_load_gpr(t0, rt);
e0d002f1 3947 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 3948 break;
c6d6dd7c 3949#endif
7a387fff
TS
3950 default:
3951fail:
3952 MIPS_INVAL("bitops");
3953 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
3954 tcg_temp_free(t0);
3955 tcg_temp_free(t1);
7a387fff
TS
3956 return;
3957 }
6c5c1e20
TS
3958 gen_store_gpr(t0, rt);
3959 tcg_temp_free(t0);
3960 tcg_temp_free(t1);
7a387fff
TS
3961}
3962
49bcf33c
AJ
3963static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3964{
3a55fa47 3965 TCGv t0;
49bcf33c 3966
3a55fa47
AJ
3967 if (rd == 0) {
3968 /* If no destination, treat it as a NOP. */
3969 MIPS_DEBUG("NOP");
3970 return;
3971 }
3972
3973 t0 = tcg_temp_new();
3974 gen_load_gpr(t0, rt);
49bcf33c
AJ
3975 switch (op2) {
3976 case OPC_WSBH:
3a55fa47
AJ
3977 {
3978 TCGv t1 = tcg_temp_new();
3979
3980 tcg_gen_shri_tl(t1, t0, 8);
3981 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3982 tcg_gen_shli_tl(t0, t0, 8);
3983 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3984 tcg_gen_or_tl(t0, t0, t1);
3985 tcg_temp_free(t1);
3986 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3987 }
49bcf33c
AJ
3988 break;
3989 case OPC_SEB:
3a55fa47 3990 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
3991 break;
3992 case OPC_SEH:
3a55fa47 3993 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
3994 break;
3995#if defined(TARGET_MIPS64)
3996 case OPC_DSBH:
3a55fa47
AJ
3997 {
3998 TCGv t1 = tcg_temp_new();
3999
4000 tcg_gen_shri_tl(t1, t0, 8);
4001 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4002 tcg_gen_shli_tl(t0, t0, 8);
4003 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4004 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4005 tcg_temp_free(t1);
4006 }
49bcf33c
AJ
4007 break;
4008 case OPC_DSHD:
3a55fa47
AJ
4009 {
4010 TCGv t1 = tcg_temp_new();
4011
4012 tcg_gen_shri_tl(t1, t0, 16);
4013 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4014 tcg_gen_shli_tl(t0, t0, 16);
4015 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4016 tcg_gen_or_tl(t0, t0, t1);
4017 tcg_gen_shri_tl(t1, t0, 32);
4018 tcg_gen_shli_tl(t0, t0, 32);
4019 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4020 tcg_temp_free(t1);
4021 }
49bcf33c
AJ
4022 break;
4023#endif
4024 default:
4025 MIPS_INVAL("bsfhl");
4026 generate_exception(ctx, EXCP_RI);
4027 tcg_temp_free(t0);
49bcf33c
AJ
4028 return;
4029 }
49bcf33c 4030 tcg_temp_free(t0);
49bcf33c
AJ
4031}
4032
f1aa6320 4033#ifndef CONFIG_USER_ONLY
0eaef5aa 4034/* CP0 (MMU and control) */
d9bea114 4035static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4036{
d9bea114 4037 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4038
d9bea114
AJ
4039 tcg_gen_ld_i32(t0, cpu_env, off);
4040 tcg_gen_ext_i32_tl(arg, t0);
4041 tcg_temp_free_i32(t0);
4f57689a
TS
4042}
4043
d9bea114 4044static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4045{
d9bea114
AJ
4046 tcg_gen_ld_tl(arg, cpu_env, off);
4047 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4048}
4049
d9bea114 4050static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4051{
d9bea114 4052 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4053
d9bea114
AJ
4054 tcg_gen_trunc_tl_i32(t0, arg);
4055 tcg_gen_st_i32(t0, cpu_env, off);
4056 tcg_temp_free_i32(t0);
f1aa6320
TS
4057}
4058
d9bea114 4059static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4060{
d9bea114
AJ
4061 tcg_gen_ext32s_tl(arg, arg);
4062 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4063}
4064
d75c135e 4065static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4066{
7a387fff 4067 const char *rn = "invalid";
873eb012 4068
e189e748 4069 if (sel != 0)
d75c135e 4070 check_insn(ctx, ISA_MIPS32);
e189e748 4071
873eb012
TS
4072 switch (reg) {
4073 case 0:
7a387fff
TS
4074 switch (sel) {
4075 case 0:
7db13fae 4076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4077 rn = "Index";
4078 break;
4079 case 1:
d75c135e 4080 check_insn(ctx, ASE_MT);
895c2d04 4081 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4082 rn = "MVPControl";
ead9360e 4083 break;
7a387fff 4084 case 2:
d75c135e 4085 check_insn(ctx, ASE_MT);
895c2d04 4086 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4087 rn = "MVPConf0";
ead9360e 4088 break;
7a387fff 4089 case 3:
d75c135e 4090 check_insn(ctx, ASE_MT);
895c2d04 4091 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4092 rn = "MVPConf1";
ead9360e 4093 break;
7a387fff
TS
4094 default:
4095 goto die;
4096 }
873eb012
TS
4097 break;
4098 case 1:
7a387fff
TS
4099 switch (sel) {
4100 case 0:
895c2d04 4101 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4102 rn = "Random";
2423f660 4103 break;
7a387fff 4104 case 1:
d75c135e 4105 check_insn(ctx, ASE_MT);
7db13fae 4106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4107 rn = "VPEControl";
ead9360e 4108 break;
7a387fff 4109 case 2:
d75c135e 4110 check_insn(ctx, ASE_MT);
7db13fae 4111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4112 rn = "VPEConf0";
ead9360e 4113 break;
7a387fff 4114 case 3:
d75c135e 4115 check_insn(ctx, ASE_MT);
7db13fae 4116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4117 rn = "VPEConf1";
ead9360e 4118 break;
7a387fff 4119 case 4:
d75c135e 4120 check_insn(ctx, ASE_MT);
7db13fae 4121 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4122 rn = "YQMask";
ead9360e 4123 break;
7a387fff 4124 case 5:
d75c135e 4125 check_insn(ctx, ASE_MT);
7db13fae 4126 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4127 rn = "VPESchedule";
ead9360e 4128 break;
7a387fff 4129 case 6:
d75c135e 4130 check_insn(ctx, ASE_MT);
7db13fae 4131 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4132 rn = "VPEScheFBack";
ead9360e 4133 break;
7a387fff 4134 case 7:
d75c135e 4135 check_insn(ctx, ASE_MT);
7db13fae 4136 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4137 rn = "VPEOpt";
ead9360e 4138 break;
7a387fff
TS
4139 default:
4140 goto die;
4141 }
873eb012
TS
4142 break;
4143 case 2:
7a387fff
TS
4144 switch (sel) {
4145 case 0:
7db13fae 4146 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4147 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4148 rn = "EntryLo0";
4149 break;
7a387fff 4150 case 1:
d75c135e 4151 check_insn(ctx, ASE_MT);
895c2d04 4152 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4153 rn = "TCStatus";
ead9360e 4154 break;
7a387fff 4155 case 2:
d75c135e 4156 check_insn(ctx, ASE_MT);
895c2d04 4157 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4158 rn = "TCBind";
ead9360e 4159 break;
7a387fff 4160 case 3:
d75c135e 4161 check_insn(ctx, ASE_MT);
895c2d04 4162 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4163 rn = "TCRestart";
ead9360e 4164 break;
7a387fff 4165 case 4:
d75c135e 4166 check_insn(ctx, ASE_MT);
895c2d04 4167 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4168 rn = "TCHalt";
ead9360e 4169 break;
7a387fff 4170 case 5:
d75c135e 4171 check_insn(ctx, ASE_MT);
895c2d04 4172 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4173 rn = "TCContext";
ead9360e 4174 break;
7a387fff 4175 case 6:
d75c135e 4176 check_insn(ctx, ASE_MT);
895c2d04 4177 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4178 rn = "TCSchedule";
ead9360e 4179 break;
7a387fff 4180 case 7:
d75c135e 4181 check_insn(ctx, ASE_MT);
895c2d04 4182 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4183 rn = "TCScheFBack";
ead9360e 4184 break;
7a387fff
TS
4185 default:
4186 goto die;
4187 }
873eb012
TS
4188 break;
4189 case 3:
7a387fff
TS
4190 switch (sel) {
4191 case 0:
7db13fae 4192 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4193 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4194 rn = "EntryLo1";
4195 break;
7a387fff
TS
4196 default:
4197 goto die;
1579a72e 4198 }
873eb012
TS
4199 break;
4200 case 4:
7a387fff
TS
4201 switch (sel) {
4202 case 0:
7db13fae 4203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4204 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4205 rn = "Context";
4206 break;
7a387fff 4207 case 1:
d9bea114 4208// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
4209 rn = "ContextConfig";
4210// break;
7a387fff
TS
4211 default:
4212 goto die;
1579a72e 4213 }
873eb012
TS
4214 break;
4215 case 5:
7a387fff
TS
4216 switch (sel) {
4217 case 0:
7db13fae 4218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4219 rn = "PageMask";
4220 break;
7a387fff 4221 case 1:
d75c135e 4222 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4223 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4224 rn = "PageGrain";
4225 break;
7a387fff
TS
4226 default:
4227 goto die;
1579a72e 4228 }
873eb012
TS
4229 break;
4230 case 6:
7a387fff
TS
4231 switch (sel) {
4232 case 0:
7db13fae 4233 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4234 rn = "Wired";
4235 break;
7a387fff 4236 case 1:
d75c135e 4237 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4239 rn = "SRSConf0";
ead9360e 4240 break;
7a387fff 4241 case 2:
d75c135e 4242 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4244 rn = "SRSConf1";
ead9360e 4245 break;
7a387fff 4246 case 3:
d75c135e 4247 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4249 rn = "SRSConf2";
ead9360e 4250 break;
7a387fff 4251 case 4:
d75c135e 4252 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4254 rn = "SRSConf3";
ead9360e 4255 break;
7a387fff 4256 case 5:
d75c135e 4257 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4259 rn = "SRSConf4";
ead9360e 4260 break;
7a387fff
TS
4261 default:
4262 goto die;
1579a72e 4263 }
873eb012 4264 break;
8c0fdd85 4265 case 7:
7a387fff
TS
4266 switch (sel) {
4267 case 0:
d75c135e 4268 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4269 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4270 rn = "HWREna";
4271 break;
7a387fff
TS
4272 default:
4273 goto die;
1579a72e 4274 }
8c0fdd85 4275 break;
873eb012 4276 case 8:
7a387fff
TS
4277 switch (sel) {
4278 case 0:
7db13fae 4279 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4280 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4281 rn = "BadVAddr";
2423f660 4282 break;
7a387fff
TS
4283 default:
4284 goto die;
4285 }
873eb012
TS
4286 break;
4287 case 9:
7a387fff
TS
4288 switch (sel) {
4289 case 0:
2e70f6ef
PB
4290 /* Mark as an IO operation because we read the time. */
4291 if (use_icount)
4292 gen_io_start();
895c2d04 4293 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4294 if (use_icount) {
4295 gen_io_end();
2e70f6ef 4296 }
55807224
EI
4297 /* Break the TB to be able to take timer interrupts immediately
4298 after reading count. */
4299 ctx->bstate = BS_STOP;
2423f660
TS
4300 rn = "Count";
4301 break;
4302 /* 6,7 are implementation dependent */
7a387fff
TS
4303 default:
4304 goto die;
2423f660 4305 }
873eb012
TS
4306 break;
4307 case 10:
7a387fff
TS
4308 switch (sel) {
4309 case 0:
7db13fae 4310 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4311 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4312 rn = "EntryHi";
4313 break;
7a387fff
TS
4314 default:
4315 goto die;
1579a72e 4316 }
873eb012
TS
4317 break;
4318 case 11:
7a387fff
TS
4319 switch (sel) {
4320 case 0:
7db13fae 4321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4322 rn = "Compare";
4323 break;
4324 /* 6,7 are implementation dependent */
7a387fff
TS
4325 default:
4326 goto die;
2423f660 4327 }
873eb012
TS
4328 break;
4329 case 12:
7a387fff
TS
4330 switch (sel) {
4331 case 0:
7db13fae 4332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4333 rn = "Status";
4334 break;
7a387fff 4335 case 1:
d75c135e 4336 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4338 rn = "IntCtl";
4339 break;
7a387fff 4340 case 2:
d75c135e 4341 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4342 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4343 rn = "SRSCtl";
4344 break;
7a387fff 4345 case 3:
d75c135e 4346 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4348 rn = "SRSMap";
fd88b6ab 4349 break;
7a387fff
TS
4350 default:
4351 goto die;
4352 }
873eb012
TS
4353 break;
4354 case 13:
7a387fff
TS
4355 switch (sel) {
4356 case 0:
7db13fae 4357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4358 rn = "Cause";
4359 break;
7a387fff
TS
4360 default:
4361 goto die;
4362 }
873eb012
TS
4363 break;
4364 case 14:
7a387fff
TS
4365 switch (sel) {
4366 case 0:
7db13fae 4367 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4368 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4369 rn = "EPC";
4370 break;
7a387fff
TS
4371 default:
4372 goto die;
1579a72e 4373 }
873eb012
TS
4374 break;
4375 case 15:
7a387fff
TS
4376 switch (sel) {
4377 case 0:
7db13fae 4378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4379 rn = "PRid";
4380 break;
7a387fff 4381 case 1:
d75c135e 4382 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4383 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4384 rn = "EBase";
4385 break;
7a387fff
TS
4386 default:
4387 goto die;
4388 }
873eb012
TS
4389 break;
4390 case 16:
4391 switch (sel) {
4392 case 0:
7db13fae 4393 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4394 rn = "Config";
4395 break;
4396 case 1:
7db13fae 4397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4398 rn = "Config1";
4399 break;
7a387fff 4400 case 2:
7db13fae 4401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4402 rn = "Config2";
4403 break;
4404 case 3:
7db13fae 4405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4406 rn = "Config3";
4407 break;
b4160af1
PJ
4408 case 4:
4409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4410 rn = "Config4";
4411 break;
b4dd99a3
PJ
4412 case 5:
4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4414 rn = "Config5";
4415 break;
e397ee33
TS
4416 /* 6,7 are implementation dependent */
4417 case 6:
7db13fae 4418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4419 rn = "Config6";
4420 break;
4421 case 7:
7db13fae 4422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4423 rn = "Config7";
4424 break;
873eb012 4425 default:
873eb012
TS
4426 goto die;
4427 }
4428 break;
4429 case 17:
7a387fff
TS
4430 switch (sel) {
4431 case 0:
895c2d04 4432 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4433 rn = "LLAddr";
4434 break;
7a387fff
TS
4435 default:
4436 goto die;
4437 }
873eb012
TS
4438 break;
4439 case 18:
7a387fff 4440 switch (sel) {
fd88b6ab 4441 case 0 ... 7:
895c2d04 4442 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4443 rn = "WatchLo";
4444 break;
7a387fff
TS
4445 default:
4446 goto die;
4447 }
873eb012
TS
4448 break;
4449 case 19:
7a387fff 4450 switch (sel) {
fd88b6ab 4451 case 0 ...7:
895c2d04 4452 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4453 rn = "WatchHi";
4454 break;
7a387fff
TS
4455 default:
4456 goto die;
4457 }
873eb012 4458 break;
8c0fdd85 4459 case 20:
7a387fff
TS
4460 switch (sel) {
4461 case 0:
d26bc211 4462#if defined(TARGET_MIPS64)
d75c135e 4463 check_insn(ctx, ISA_MIPS3);
7db13fae 4464 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4465 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4466 rn = "XContext";
4467 break;
703eaf37 4468#endif
7a387fff
TS
4469 default:
4470 goto die;
4471 }
8c0fdd85
TS
4472 break;
4473 case 21:
7a387fff
TS
4474 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4475 switch (sel) {
4476 case 0:
7db13fae 4477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4478 rn = "Framemask";
4479 break;
7a387fff
TS
4480 default:
4481 goto die;
4482 }
8c0fdd85
TS
4483 break;
4484 case 22:
d9bea114 4485 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4486 rn = "'Diagnostic"; /* implementation dependent */
4487 break;
873eb012 4488 case 23:
7a387fff
TS
4489 switch (sel) {
4490 case 0:
895c2d04 4491 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4492 rn = "Debug";
4493 break;
7a387fff 4494 case 1:
d9bea114 4495// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4496 rn = "TraceControl";
4497// break;
7a387fff 4498 case 2:
d9bea114 4499// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4500 rn = "TraceControl2";
4501// break;
7a387fff 4502 case 3:
d9bea114 4503// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4504 rn = "UserTraceData";
4505// break;
7a387fff 4506 case 4:
d9bea114 4507// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4508 rn = "TraceBPC";
4509// break;
7a387fff
TS
4510 default:
4511 goto die;
4512 }
873eb012
TS
4513 break;
4514 case 24:
7a387fff
TS
4515 switch (sel) {
4516 case 0:
f0b3f3ae 4517 /* EJTAG support */
7db13fae 4518 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4519 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4520 rn = "DEPC";
4521 break;
7a387fff
TS
4522 default:
4523 goto die;
4524 }
873eb012 4525 break;
8c0fdd85 4526 case 25:
7a387fff
TS
4527 switch (sel) {
4528 case 0:
7db13fae 4529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4530 rn = "Performance0";
7a387fff
TS
4531 break;
4532 case 1:
d9bea114 4533// gen_helper_mfc0_performance1(arg);
2423f660
TS
4534 rn = "Performance1";
4535// break;
7a387fff 4536 case 2:
d9bea114 4537// gen_helper_mfc0_performance2(arg);
2423f660
TS
4538 rn = "Performance2";
4539// break;
7a387fff 4540 case 3:
d9bea114 4541// gen_helper_mfc0_performance3(arg);
2423f660
TS
4542 rn = "Performance3";
4543// break;
7a387fff 4544 case 4:
d9bea114 4545// gen_helper_mfc0_performance4(arg);
2423f660
TS
4546 rn = "Performance4";
4547// break;
7a387fff 4548 case 5:
d9bea114 4549// gen_helper_mfc0_performance5(arg);
2423f660
TS
4550 rn = "Performance5";
4551// break;
7a387fff 4552 case 6:
d9bea114 4553// gen_helper_mfc0_performance6(arg);
2423f660
TS
4554 rn = "Performance6";
4555// break;
7a387fff 4556 case 7:
d9bea114 4557// gen_helper_mfc0_performance7(arg);
2423f660
TS
4558 rn = "Performance7";
4559// break;
7a387fff
TS
4560 default:
4561 goto die;
4562 }
8c0fdd85
TS
4563 break;
4564 case 26:
d9bea114 4565 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4566 rn = "ECC";
4567 break;
8c0fdd85 4568 case 27:
7a387fff 4569 switch (sel) {
7a387fff 4570 case 0 ... 3:
d9bea114 4571 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4572 rn = "CacheErr";
4573 break;
7a387fff
TS
4574 default:
4575 goto die;
4576 }
8c0fdd85 4577 break;
873eb012
TS
4578 case 28:
4579 switch (sel) {
4580 case 0:
7a387fff
TS
4581 case 2:
4582 case 4:
4583 case 6:
7db13fae 4584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4585 rn = "TagLo";
4586 break;
4587 case 1:
7a387fff
TS
4588 case 3:
4589 case 5:
4590 case 7:
7db13fae 4591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4592 rn = "DataLo";
4593 break;
4594 default:
873eb012
TS
4595 goto die;
4596 }
4597 break;
8c0fdd85 4598 case 29:
7a387fff
TS
4599 switch (sel) {
4600 case 0:
4601 case 2:
4602 case 4:
4603 case 6:
7db13fae 4604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4605 rn = "TagHi";
4606 break;
4607 case 1:
4608 case 3:
4609 case 5:
4610 case 7:
7db13fae 4611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4612 rn = "DataHi";
4613 break;
4614 default:
4615 goto die;
4616 }
8c0fdd85 4617 break;
873eb012 4618 case 30:
7a387fff
TS
4619 switch (sel) {
4620 case 0:
7db13fae 4621 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4622 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4623 rn = "ErrorEPC";
4624 break;
7a387fff
TS
4625 default:
4626 goto die;
4627 }
873eb012
TS
4628 break;
4629 case 31:
7a387fff
TS
4630 switch (sel) {
4631 case 0:
f0b3f3ae 4632 /* EJTAG support */
7db13fae 4633 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4634 rn = "DESAVE";
4635 break;
7a387fff
TS
4636 default:
4637 goto die;
4638 }
873eb012
TS
4639 break;
4640 default:
873eb012
TS
4641 goto die;
4642 }
2abf314d 4643 (void)rn; /* avoid a compiler warning */
d12d51d5 4644 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4645 return;
4646
4647die:
d12d51d5 4648 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4649 generate_exception(ctx, EXCP_RI);
4650}
4651
d75c135e 4652static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4653{
7a387fff
TS
4654 const char *rn = "invalid";
4655
e189e748 4656 if (sel != 0)
d75c135e 4657 check_insn(ctx, ISA_MIPS32);
e189e748 4658
2e70f6ef
PB
4659 if (use_icount)
4660 gen_io_start();
4661
8c0fdd85
TS
4662 switch (reg) {
4663 case 0:
7a387fff
TS
4664 switch (sel) {
4665 case 0:
895c2d04 4666 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4667 rn = "Index";
4668 break;
4669 case 1:
d75c135e 4670 check_insn(ctx, ASE_MT);
895c2d04 4671 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4672 rn = "MVPControl";
ead9360e 4673 break;
7a387fff 4674 case 2:
d75c135e 4675 check_insn(ctx, ASE_MT);
ead9360e 4676 /* ignored */
7a387fff 4677 rn = "MVPConf0";
ead9360e 4678 break;
7a387fff 4679 case 3:
d75c135e 4680 check_insn(ctx, ASE_MT);
ead9360e 4681 /* ignored */
7a387fff 4682 rn = "MVPConf1";
ead9360e 4683 break;
7a387fff
TS
4684 default:
4685 goto die;
4686 }
8c0fdd85
TS
4687 break;
4688 case 1:
7a387fff
TS
4689 switch (sel) {
4690 case 0:
2423f660 4691 /* ignored */
7a387fff 4692 rn = "Random";
2423f660 4693 break;
7a387fff 4694 case 1:
d75c135e 4695 check_insn(ctx, ASE_MT);
895c2d04 4696 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4697 rn = "VPEControl";
ead9360e 4698 break;
7a387fff 4699 case 2:
d75c135e 4700 check_insn(ctx, ASE_MT);
895c2d04 4701 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4702 rn = "VPEConf0";
ead9360e 4703 break;
7a387fff 4704 case 3:
d75c135e 4705 check_insn(ctx, ASE_MT);
895c2d04 4706 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4707 rn = "VPEConf1";
ead9360e 4708 break;
7a387fff 4709 case 4:
d75c135e 4710 check_insn(ctx, ASE_MT);
895c2d04 4711 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4712 rn = "YQMask";
ead9360e 4713 break;
7a387fff 4714 case 5:
d75c135e 4715 check_insn(ctx, ASE_MT);
7db13fae 4716 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4717 rn = "VPESchedule";
ead9360e 4718 break;
7a387fff 4719 case 6:
d75c135e 4720 check_insn(ctx, ASE_MT);
7db13fae 4721 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4722 rn = "VPEScheFBack";
ead9360e 4723 break;
7a387fff 4724 case 7:
d75c135e 4725 check_insn(ctx, ASE_MT);
895c2d04 4726 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4727 rn = "VPEOpt";
ead9360e 4728 break;
7a387fff
TS
4729 default:
4730 goto die;
4731 }
8c0fdd85
TS
4732 break;
4733 case 2:
7a387fff
TS
4734 switch (sel) {
4735 case 0:
895c2d04 4736 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4737 rn = "EntryLo0";
4738 break;
7a387fff 4739 case 1:
d75c135e 4740 check_insn(ctx, ASE_MT);
895c2d04 4741 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4742 rn = "TCStatus";
ead9360e 4743 break;
7a387fff 4744 case 2:
d75c135e 4745 check_insn(ctx, ASE_MT);
895c2d04 4746 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4747 rn = "TCBind";
ead9360e 4748 break;
7a387fff 4749 case 3:
d75c135e 4750 check_insn(ctx, ASE_MT);
895c2d04 4751 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4752 rn = "TCRestart";
ead9360e 4753 break;
7a387fff 4754 case 4:
d75c135e 4755 check_insn(ctx, ASE_MT);
895c2d04 4756 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4757 rn = "TCHalt";
ead9360e 4758 break;
7a387fff 4759 case 5:
d75c135e 4760 check_insn(ctx, ASE_MT);
895c2d04 4761 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4762 rn = "TCContext";
ead9360e 4763 break;
7a387fff 4764 case 6:
d75c135e 4765 check_insn(ctx, ASE_MT);
895c2d04 4766 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4767 rn = "TCSchedule";
ead9360e 4768 break;
7a387fff 4769 case 7:
d75c135e 4770 check_insn(ctx, ASE_MT);
895c2d04 4771 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4772 rn = "TCScheFBack";
ead9360e 4773 break;
7a387fff
TS
4774 default:
4775 goto die;
4776 }
8c0fdd85
TS
4777 break;
4778 case 3:
7a387fff
TS
4779 switch (sel) {
4780 case 0:
895c2d04 4781 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4782 rn = "EntryLo1";
4783 break;
7a387fff
TS
4784 default:
4785 goto die;
876d4b07 4786 }
8c0fdd85
TS
4787 break;
4788 case 4:
7a387fff
TS
4789 switch (sel) {
4790 case 0:
895c2d04 4791 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4792 rn = "Context";
4793 break;
7a387fff 4794 case 1:
895c2d04 4795// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
4796 rn = "ContextConfig";
4797// break;
7a387fff
TS
4798 default:
4799 goto die;
876d4b07 4800 }
8c0fdd85
TS
4801 break;
4802 case 5:
7a387fff
TS
4803 switch (sel) {
4804 case 0:
895c2d04 4805 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4806 rn = "PageMask";
4807 break;
7a387fff 4808 case 1:
d75c135e 4809 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4810 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4811 rn = "PageGrain";
4812 break;
7a387fff
TS
4813 default:
4814 goto die;
876d4b07 4815 }
8c0fdd85
TS
4816 break;
4817 case 6:
7a387fff
TS
4818 switch (sel) {
4819 case 0:
895c2d04 4820 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4821 rn = "Wired";
4822 break;
7a387fff 4823 case 1:
d75c135e 4824 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4825 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4826 rn = "SRSConf0";
ead9360e 4827 break;
7a387fff 4828 case 2:
d75c135e 4829 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4830 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4831 rn = "SRSConf1";
ead9360e 4832 break;
7a387fff 4833 case 3:
d75c135e 4834 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4835 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4836 rn = "SRSConf2";
ead9360e 4837 break;
7a387fff 4838 case 4:
d75c135e 4839 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4840 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4841 rn = "SRSConf3";
ead9360e 4842 break;
7a387fff 4843 case 5:
d75c135e 4844 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4845 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4846 rn = "SRSConf4";
ead9360e 4847 break;
7a387fff
TS
4848 default:
4849 goto die;
876d4b07 4850 }
8c0fdd85
TS
4851 break;
4852 case 7:
7a387fff
TS
4853 switch (sel) {
4854 case 0:
d75c135e 4855 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4856 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
4857 rn = "HWREna";
4858 break;
7a387fff
TS
4859 default:
4860 goto die;
876d4b07 4861 }
8c0fdd85
TS
4862 break;
4863 case 8:
7a387fff 4864 /* ignored */
f0b3f3ae 4865 rn = "BadVAddr";
8c0fdd85
TS
4866 break;
4867 case 9:
7a387fff
TS
4868 switch (sel) {
4869 case 0:
895c2d04 4870 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4871 rn = "Count";
4872 break;
876d4b07 4873 /* 6,7 are implementation dependent */
7a387fff
TS
4874 default:
4875 goto die;
876d4b07 4876 }
8c0fdd85
TS
4877 break;
4878 case 10:
7a387fff
TS
4879 switch (sel) {
4880 case 0:
895c2d04 4881 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4882 rn = "EntryHi";
4883 break;
7a387fff
TS
4884 default:
4885 goto die;
876d4b07 4886 }
8c0fdd85
TS
4887 break;
4888 case 11:
7a387fff
TS
4889 switch (sel) {
4890 case 0:
895c2d04 4891 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4892 rn = "Compare";
4893 break;
4894 /* 6,7 are implementation dependent */
7a387fff
TS
4895 default:
4896 goto die;
876d4b07 4897 }
8c0fdd85
TS
4898 break;
4899 case 12:
7a387fff
TS
4900 switch (sel) {
4901 case 0:
867abc7e 4902 save_cpu_state(ctx, 1);
895c2d04 4903 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4904 /* BS_STOP isn't good enough here, hflags may have changed. */
4905 gen_save_pc(ctx->pc + 4);
4906 ctx->bstate = BS_EXCP;
2423f660
TS
4907 rn = "Status";
4908 break;
7a387fff 4909 case 1:
d75c135e 4910 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4911 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4912 /* Stop translation as we may have switched the execution mode */
4913 ctx->bstate = BS_STOP;
2423f660
TS
4914 rn = "IntCtl";
4915 break;
7a387fff 4916 case 2:
d75c135e 4917 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4918 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4919 /* Stop translation as we may have switched the execution mode */
4920 ctx->bstate = BS_STOP;
2423f660
TS
4921 rn = "SRSCtl";
4922 break;
7a387fff 4923 case 3:
d75c135e 4924 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4925 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4926 /* Stop translation as we may have switched the execution mode */
4927 ctx->bstate = BS_STOP;
2423f660 4928 rn = "SRSMap";
fd88b6ab 4929 break;
7a387fff
TS
4930 default:
4931 goto die;
876d4b07 4932 }
8c0fdd85
TS
4933 break;
4934 case 13:
7a387fff
TS
4935 switch (sel) {
4936 case 0:
867abc7e 4937 save_cpu_state(ctx, 1);
895c2d04 4938 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4939 rn = "Cause";
4940 break;
7a387fff
TS
4941 default:
4942 goto die;
876d4b07 4943 }
8c0fdd85
TS
4944 break;
4945 case 14:
7a387fff
TS
4946 switch (sel) {
4947 case 0:
7db13fae 4948 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4949 rn = "EPC";
4950 break;
7a387fff
TS
4951 default:
4952 goto die;
876d4b07 4953 }
8c0fdd85
TS
4954 break;
4955 case 15:
7a387fff
TS
4956 switch (sel) {
4957 case 0:
2423f660
TS
4958 /* ignored */
4959 rn = "PRid";
4960 break;
7a387fff 4961 case 1:
d75c135e 4962 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4963 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
4964 rn = "EBase";
4965 break;
7a387fff
TS
4966 default:
4967 goto die;
1579a72e 4968 }
8c0fdd85
TS
4969 break;
4970 case 16:
4971 switch (sel) {
4972 case 0:
895c2d04 4973 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 4974 rn = "Config";
2423f660
TS
4975 /* Stop translation as we may have switched the execution mode */
4976 ctx->bstate = BS_STOP;
7a387fff
TS
4977 break;
4978 case 1:
e397ee33 4979 /* ignored, read only */
7a387fff
TS
4980 rn = "Config1";
4981 break;
4982 case 2:
895c2d04 4983 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 4984 rn = "Config2";
2423f660
TS
4985 /* Stop translation as we may have switched the execution mode */
4986 ctx->bstate = BS_STOP;
8c0fdd85 4987 break;
7a387fff 4988 case 3:
e397ee33 4989 /* ignored, read only */
7a387fff
TS
4990 rn = "Config3";
4991 break;
b4160af1
PJ
4992 case 4:
4993 gen_helper_mtc0_config4(cpu_env, arg);
4994 rn = "Config4";
4995 ctx->bstate = BS_STOP;
4996 break;
b4dd99a3
PJ
4997 case 5:
4998 gen_helper_mtc0_config5(cpu_env, arg);
4999 rn = "Config5";
5000 /* Stop translation as we may have switched the execution mode */
5001 ctx->bstate = BS_STOP;
5002 break;
e397ee33
TS
5003 /* 6,7 are implementation dependent */
5004 case 6:
5005 /* ignored */
5006 rn = "Config6";
5007 break;
5008 case 7:
5009 /* ignored */
5010 rn = "Config7";
5011 break;
8c0fdd85
TS
5012 default:
5013 rn = "Invalid config selector";
5014 goto die;
5015 }
5016 break;
5017 case 17:
7a387fff
TS
5018 switch (sel) {
5019 case 0:
895c2d04 5020 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5021 rn = "LLAddr";
5022 break;
7a387fff
TS
5023 default:
5024 goto die;
5025 }
8c0fdd85
TS
5026 break;
5027 case 18:
7a387fff 5028 switch (sel) {
fd88b6ab 5029 case 0 ... 7:
895c2d04 5030 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5031 rn = "WatchLo";
5032 break;
7a387fff
TS
5033 default:
5034 goto die;
5035 }
8c0fdd85
TS
5036 break;
5037 case 19:
7a387fff 5038 switch (sel) {
fd88b6ab 5039 case 0 ... 7:
895c2d04 5040 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5041 rn = "WatchHi";
5042 break;
7a387fff
TS
5043 default:
5044 goto die;
5045 }
8c0fdd85
TS
5046 break;
5047 case 20:
7a387fff
TS
5048 switch (sel) {
5049 case 0:
d26bc211 5050#if defined(TARGET_MIPS64)
d75c135e 5051 check_insn(ctx, ISA_MIPS3);
895c2d04 5052 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5053 rn = "XContext";
5054 break;
703eaf37 5055#endif
7a387fff
TS
5056 default:
5057 goto die;
5058 }
8c0fdd85
TS
5059 break;
5060 case 21:
7a387fff
TS
5061 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5062 switch (sel) {
5063 case 0:
895c2d04 5064 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5065 rn = "Framemask";
5066 break;
7a387fff
TS
5067 default:
5068 goto die;
5069 }
5070 break;
8c0fdd85 5071 case 22:
7a387fff
TS
5072 /* ignored */
5073 rn = "Diagnostic"; /* implementation dependent */
2423f660 5074 break;
8c0fdd85 5075 case 23:
7a387fff
TS
5076 switch (sel) {
5077 case 0:
895c2d04 5078 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5079 /* BS_STOP isn't good enough here, hflags may have changed. */
5080 gen_save_pc(ctx->pc + 4);
5081 ctx->bstate = BS_EXCP;
2423f660
TS
5082 rn = "Debug";
5083 break;
7a387fff 5084 case 1:
895c2d04 5085// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5086 rn = "TraceControl";
8487327a
TS
5087 /* Stop translation as we may have switched the execution mode */
5088 ctx->bstate = BS_STOP;
2423f660 5089// break;
7a387fff 5090 case 2:
895c2d04 5091// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5092 rn = "TraceControl2";
8487327a
TS
5093 /* Stop translation as we may have switched the execution mode */
5094 ctx->bstate = BS_STOP;
2423f660 5095// break;
7a387fff 5096 case 3:
8487327a
TS
5097 /* Stop translation as we may have switched the execution mode */
5098 ctx->bstate = BS_STOP;
895c2d04 5099// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5100 rn = "UserTraceData";
8487327a
TS
5101 /* Stop translation as we may have switched the execution mode */
5102 ctx->bstate = BS_STOP;
2423f660 5103// break;
7a387fff 5104 case 4:
895c2d04 5105// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5106 /* Stop translation as we may have switched the execution mode */
5107 ctx->bstate = BS_STOP;
2423f660
TS
5108 rn = "TraceBPC";
5109// break;
7a387fff
TS
5110 default:
5111 goto die;
5112 }
8c0fdd85
TS
5113 break;
5114 case 24:
7a387fff
TS
5115 switch (sel) {
5116 case 0:
f1aa6320 5117 /* EJTAG support */
7db13fae 5118 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5119 rn = "DEPC";
5120 break;
7a387fff
TS
5121 default:
5122 goto die;
5123 }
8c0fdd85
TS
5124 break;
5125 case 25:
7a387fff
TS
5126 switch (sel) {
5127 case 0:
895c2d04 5128 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5129 rn = "Performance0";
5130 break;
7a387fff 5131 case 1:
d9bea114 5132// gen_helper_mtc0_performance1(arg);
2423f660
TS
5133 rn = "Performance1";
5134// break;
7a387fff 5135 case 2:
d9bea114 5136// gen_helper_mtc0_performance2(arg);
2423f660
TS
5137 rn = "Performance2";
5138// break;
7a387fff 5139 case 3:
d9bea114 5140// gen_helper_mtc0_performance3(arg);
2423f660
TS
5141 rn = "Performance3";
5142// break;
7a387fff 5143 case 4:
d9bea114 5144// gen_helper_mtc0_performance4(arg);
2423f660
TS
5145 rn = "Performance4";
5146// break;
7a387fff 5147 case 5:
d9bea114 5148// gen_helper_mtc0_performance5(arg);
2423f660
TS
5149 rn = "Performance5";
5150// break;
7a387fff 5151 case 6:
d9bea114 5152// gen_helper_mtc0_performance6(arg);
2423f660
TS
5153 rn = "Performance6";
5154// break;
7a387fff 5155 case 7:
d9bea114 5156// gen_helper_mtc0_performance7(arg);
2423f660
TS
5157 rn = "Performance7";
5158// break;
7a387fff
TS
5159 default:
5160 goto die;
5161 }
8c0fdd85
TS
5162 break;
5163 case 26:
2423f660 5164 /* ignored */
8c0fdd85 5165 rn = "ECC";
2423f660 5166 break;
8c0fdd85 5167 case 27:
7a387fff
TS
5168 switch (sel) {
5169 case 0 ... 3:
2423f660
TS
5170 /* ignored */
5171 rn = "CacheErr";
5172 break;
7a387fff
TS
5173 default:
5174 goto die;
5175 }
8c0fdd85
TS
5176 break;
5177 case 28:
5178 switch (sel) {
5179 case 0:
7a387fff
TS
5180 case 2:
5181 case 4:
5182 case 6:
895c2d04 5183 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5184 rn = "TagLo";
5185 break;
7a387fff
TS
5186 case 1:
5187 case 3:
5188 case 5:
5189 case 7:
895c2d04 5190 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5191 rn = "DataLo";
5192 break;
8c0fdd85 5193 default:
8c0fdd85
TS
5194 goto die;
5195 }
5196 break;
5197 case 29:
7a387fff
TS
5198 switch (sel) {
5199 case 0:
5200 case 2:
5201 case 4:
5202 case 6:
895c2d04 5203 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5204 rn = "TagHi";
5205 break;
5206 case 1:
5207 case 3:
5208 case 5:
5209 case 7:
895c2d04 5210 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5211 rn = "DataHi";
5212 break;
5213 default:
5214 rn = "invalid sel";
5215 goto die;
5216 }
8c0fdd85
TS
5217 break;
5218 case 30:
7a387fff
TS
5219 switch (sel) {
5220 case 0:
7db13fae 5221 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5222 rn = "ErrorEPC";
5223 break;
7a387fff
TS
5224 default:
5225 goto die;
5226 }
8c0fdd85
TS
5227 break;
5228 case 31:
7a387fff
TS
5229 switch (sel) {
5230 case 0:
f1aa6320 5231 /* EJTAG support */
7db13fae 5232 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5233 rn = "DESAVE";
5234 break;
7a387fff
TS
5235 default:
5236 goto die;
5237 }
2423f660
TS
5238 /* Stop translation as we may have switched the execution mode */
5239 ctx->bstate = BS_STOP;
8c0fdd85
TS
5240 break;
5241 default:
8c0fdd85
TS
5242 goto die;
5243 }
2abf314d 5244 (void)rn; /* avoid a compiler warning */
d12d51d5 5245 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5246 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5247 if (use_icount) {
5248 gen_io_end();
5249 ctx->bstate = BS_STOP;
5250 }
8c0fdd85
TS
5251 return;
5252
5253die:
d12d51d5 5254 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5255 generate_exception(ctx, EXCP_RI);
5256}
5257
d26bc211 5258#if defined(TARGET_MIPS64)
d75c135e 5259static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5260{
5261 const char *rn = "invalid";
5262
e189e748 5263 if (sel != 0)
d75c135e 5264 check_insn(ctx, ISA_MIPS64);
e189e748 5265
9c2149c8
TS
5266 switch (reg) {
5267 case 0:
5268 switch (sel) {
5269 case 0:
7db13fae 5270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5271 rn = "Index";
5272 break;
5273 case 1:
d75c135e 5274 check_insn(ctx, ASE_MT);
895c2d04 5275 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5276 rn = "MVPControl";
ead9360e 5277 break;
9c2149c8 5278 case 2:
d75c135e 5279 check_insn(ctx, ASE_MT);
895c2d04 5280 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5281 rn = "MVPConf0";
ead9360e 5282 break;
9c2149c8 5283 case 3:
d75c135e 5284 check_insn(ctx, ASE_MT);
895c2d04 5285 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5286 rn = "MVPConf1";
ead9360e 5287 break;
9c2149c8
TS
5288 default:
5289 goto die;
5290 }
5291 break;
5292 case 1:
5293 switch (sel) {
5294 case 0:
895c2d04 5295 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5296 rn = "Random";
2423f660 5297 break;
9c2149c8 5298 case 1:
d75c135e 5299 check_insn(ctx, ASE_MT);
7db13fae 5300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5301 rn = "VPEControl";
ead9360e 5302 break;
9c2149c8 5303 case 2:
d75c135e 5304 check_insn(ctx, ASE_MT);
7db13fae 5305 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5306 rn = "VPEConf0";
ead9360e 5307 break;
9c2149c8 5308 case 3:
d75c135e 5309 check_insn(ctx, ASE_MT);
7db13fae 5310 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5311 rn = "VPEConf1";
ead9360e 5312 break;
9c2149c8 5313 case 4:
d75c135e 5314 check_insn(ctx, ASE_MT);
7db13fae 5315 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5316 rn = "YQMask";
ead9360e 5317 break;
9c2149c8 5318 case 5:
d75c135e 5319 check_insn(ctx, ASE_MT);
7db13fae 5320 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5321 rn = "VPESchedule";
ead9360e 5322 break;
9c2149c8 5323 case 6:
d75c135e 5324 check_insn(ctx, ASE_MT);
7db13fae 5325 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5326 rn = "VPEScheFBack";
ead9360e 5327 break;
9c2149c8 5328 case 7:
d75c135e 5329 check_insn(ctx, ASE_MT);
7db13fae 5330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5331 rn = "VPEOpt";
ead9360e 5332 break;
9c2149c8
TS
5333 default:
5334 goto die;
5335 }
5336 break;
5337 case 2:
5338 switch (sel) {
5339 case 0:
7db13fae 5340 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5341 rn = "EntryLo0";
5342 break;
9c2149c8 5343 case 1:
d75c135e 5344 check_insn(ctx, ASE_MT);
895c2d04 5345 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5346 rn = "TCStatus";
ead9360e 5347 break;
9c2149c8 5348 case 2:
d75c135e 5349 check_insn(ctx, ASE_MT);
895c2d04 5350 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5351 rn = "TCBind";
ead9360e 5352 break;
9c2149c8 5353 case 3:
d75c135e 5354 check_insn(ctx, ASE_MT);
895c2d04 5355 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5356 rn = "TCRestart";
ead9360e 5357 break;
9c2149c8 5358 case 4:
d75c135e 5359 check_insn(ctx, ASE_MT);
895c2d04 5360 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5361 rn = "TCHalt";
ead9360e 5362 break;
9c2149c8 5363 case 5:
d75c135e 5364 check_insn(ctx, ASE_MT);
895c2d04 5365 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5366 rn = "TCContext";
ead9360e 5367 break;
9c2149c8 5368 case 6:
d75c135e 5369 check_insn(ctx, ASE_MT);
895c2d04 5370 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5371 rn = "TCSchedule";
ead9360e 5372 break;
9c2149c8 5373 case 7:
d75c135e 5374 check_insn(ctx, ASE_MT);
895c2d04 5375 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5376 rn = "TCScheFBack";
ead9360e 5377 break;
9c2149c8
TS
5378 default:
5379 goto die;
5380 }
5381 break;
5382 case 3:
5383 switch (sel) {
5384 case 0:
7db13fae 5385 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5386 rn = "EntryLo1";
5387 break;
9c2149c8
TS
5388 default:
5389 goto die;
1579a72e 5390 }
9c2149c8
TS
5391 break;
5392 case 4:
5393 switch (sel) {
5394 case 0:
7db13fae 5395 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5396 rn = "Context";
5397 break;
9c2149c8 5398 case 1:
d9bea114 5399// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
5400 rn = "ContextConfig";
5401// break;
9c2149c8
TS
5402 default:
5403 goto die;
876d4b07 5404 }
9c2149c8
TS
5405 break;
5406 case 5:
5407 switch (sel) {
5408 case 0:
7db13fae 5409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5410 rn = "PageMask";
5411 break;
9c2149c8 5412 case 1:
d75c135e 5413 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5414 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5415 rn = "PageGrain";
5416 break;
9c2149c8
TS
5417 default:
5418 goto die;
876d4b07 5419 }
9c2149c8
TS
5420 break;
5421 case 6:
5422 switch (sel) {
5423 case 0:
7db13fae 5424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5425 rn = "Wired";
5426 break;
9c2149c8 5427 case 1:
d75c135e 5428 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5430 rn = "SRSConf0";
ead9360e 5431 break;
9c2149c8 5432 case 2:
d75c135e 5433 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5435 rn = "SRSConf1";
ead9360e 5436 break;
9c2149c8 5437 case 3:
d75c135e 5438 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5440 rn = "SRSConf2";
ead9360e 5441 break;
9c2149c8 5442 case 4:
d75c135e 5443 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5445 rn = "SRSConf3";
ead9360e 5446 break;
9c2149c8 5447 case 5:
d75c135e 5448 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5450 rn = "SRSConf4";
ead9360e 5451 break;
9c2149c8
TS
5452 default:
5453 goto die;
876d4b07 5454 }
9c2149c8
TS
5455 break;
5456 case 7:
5457 switch (sel) {
5458 case 0:
d75c135e 5459 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5461 rn = "HWREna";
5462 break;
9c2149c8
TS
5463 default:
5464 goto die;
876d4b07 5465 }
9c2149c8
TS
5466 break;
5467 case 8:
5468 switch (sel) {
5469 case 0:
7db13fae 5470 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5471 rn = "BadVAddr";
2423f660 5472 break;
9c2149c8
TS
5473 default:
5474 goto die;
876d4b07 5475 }
9c2149c8
TS
5476 break;
5477 case 9:
5478 switch (sel) {
5479 case 0:
2e70f6ef
PB
5480 /* Mark as an IO operation because we read the time. */
5481 if (use_icount)
5482 gen_io_start();
895c2d04 5483 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5484 if (use_icount) {
5485 gen_io_end();
2e70f6ef 5486 }
55807224
EI
5487 /* Break the TB to be able to take timer interrupts immediately
5488 after reading count. */
5489 ctx->bstate = BS_STOP;
2423f660
TS
5490 rn = "Count";
5491 break;
5492 /* 6,7 are implementation dependent */
9c2149c8
TS
5493 default:
5494 goto die;
876d4b07 5495 }
9c2149c8
TS
5496 break;
5497 case 10:
5498 switch (sel) {
5499 case 0:
7db13fae 5500 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5501 rn = "EntryHi";
5502 break;
9c2149c8
TS
5503 default:
5504 goto die;
876d4b07 5505 }
9c2149c8
TS
5506 break;
5507 case 11:
5508 switch (sel) {
5509 case 0:
7db13fae 5510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5511 rn = "Compare";
5512 break;
876d4b07 5513 /* 6,7 are implementation dependent */
9c2149c8
TS
5514 default:
5515 goto die;
876d4b07 5516 }
9c2149c8
TS
5517 break;
5518 case 12:
5519 switch (sel) {
5520 case 0:
7db13fae 5521 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5522 rn = "Status";
5523 break;
9c2149c8 5524 case 1:
d75c135e 5525 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5527 rn = "IntCtl";
5528 break;
9c2149c8 5529 case 2:
d75c135e 5530 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5532 rn = "SRSCtl";
5533 break;
9c2149c8 5534 case 3:
d75c135e 5535 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5537 rn = "SRSMap";
5538 break;
9c2149c8
TS
5539 default:
5540 goto die;
876d4b07 5541 }
9c2149c8
TS
5542 break;
5543 case 13:
5544 switch (sel) {
5545 case 0:
7db13fae 5546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5547 rn = "Cause";
5548 break;
9c2149c8
TS
5549 default:
5550 goto die;
876d4b07 5551 }
9c2149c8
TS
5552 break;
5553 case 14:
5554 switch (sel) {
5555 case 0:
7db13fae 5556 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5557 rn = "EPC";
5558 break;
9c2149c8
TS
5559 default:
5560 goto die;
876d4b07 5561 }
9c2149c8
TS
5562 break;
5563 case 15:
5564 switch (sel) {
5565 case 0:
7db13fae 5566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5567 rn = "PRid";
5568 break;
9c2149c8 5569 case 1:
d75c135e 5570 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5571 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5572 rn = "EBase";
5573 break;
9c2149c8
TS
5574 default:
5575 goto die;
876d4b07 5576 }
9c2149c8
TS
5577 break;
5578 case 16:
5579 switch (sel) {
5580 case 0:
7db13fae 5581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5582 rn = "Config";
5583 break;
5584 case 1:
7db13fae 5585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5586 rn = "Config1";
5587 break;
5588 case 2:
7db13fae 5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5590 rn = "Config2";
5591 break;
5592 case 3:
7db13fae 5593 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5594 rn = "Config3";
5595 break;
5596 /* 6,7 are implementation dependent */
f0b3f3ae 5597 case 6:
7db13fae 5598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5599 rn = "Config6";
5600 break;
5601 case 7:
7db13fae 5602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5603 rn = "Config7";
5604 break;
9c2149c8
TS
5605 default:
5606 goto die;
5607 }
5608 break;
5609 case 17:
5610 switch (sel) {
5611 case 0:
895c2d04 5612 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5613 rn = "LLAddr";
5614 break;
9c2149c8
TS
5615 default:
5616 goto die;
5617 }
5618 break;
5619 case 18:
5620 switch (sel) {
fd88b6ab 5621 case 0 ... 7:
895c2d04 5622 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5623 rn = "WatchLo";
5624 break;
9c2149c8
TS
5625 default:
5626 goto die;
5627 }
5628 break;
5629 case 19:
5630 switch (sel) {
fd88b6ab 5631 case 0 ... 7:
895c2d04 5632 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5633 rn = "WatchHi";
5634 break;
9c2149c8
TS
5635 default:
5636 goto die;
5637 }
5638 break;
5639 case 20:
5640 switch (sel) {
5641 case 0:
d75c135e 5642 check_insn(ctx, ISA_MIPS3);
7db13fae 5643 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5644 rn = "XContext";
5645 break;
9c2149c8
TS
5646 default:
5647 goto die;
5648 }
5649 break;
5650 case 21:
5651 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5652 switch (sel) {
5653 case 0:
7db13fae 5654 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5655 rn = "Framemask";
5656 break;
9c2149c8
TS
5657 default:
5658 goto die;
5659 }
5660 break;
5661 case 22:
d9bea114 5662 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5663 rn = "'Diagnostic"; /* implementation dependent */
5664 break;
9c2149c8
TS
5665 case 23:
5666 switch (sel) {
5667 case 0:
895c2d04 5668 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5669 rn = "Debug";
5670 break;
9c2149c8 5671 case 1:
895c2d04 5672// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5673 rn = "TraceControl";
5674// break;
9c2149c8 5675 case 2:
895c2d04 5676// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5677 rn = "TraceControl2";
5678// break;
9c2149c8 5679 case 3:
895c2d04 5680// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5681 rn = "UserTraceData";
5682// break;
9c2149c8 5683 case 4:
895c2d04 5684// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5685 rn = "TraceBPC";
5686// break;
9c2149c8
TS
5687 default:
5688 goto die;
5689 }
5690 break;
5691 case 24:
5692 switch (sel) {
5693 case 0:
f0b3f3ae 5694 /* EJTAG support */
7db13fae 5695 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5696 rn = "DEPC";
5697 break;
9c2149c8
TS
5698 default:
5699 goto die;
5700 }
5701 break;
5702 case 25:
5703 switch (sel) {
5704 case 0:
7db13fae 5705 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5706 rn = "Performance0";
9c2149c8
TS
5707 break;
5708 case 1:
d9bea114 5709// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5710 rn = "Performance1";
5711// break;
9c2149c8 5712 case 2:
d9bea114 5713// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5714 rn = "Performance2";
5715// break;
9c2149c8 5716 case 3:
d9bea114 5717// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5718 rn = "Performance3";
5719// break;
9c2149c8 5720 case 4:
d9bea114 5721// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5722 rn = "Performance4";
5723// break;
9c2149c8 5724 case 5:
d9bea114 5725// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5726 rn = "Performance5";
5727// break;
9c2149c8 5728 case 6:
d9bea114 5729// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5730 rn = "Performance6";
5731// break;
9c2149c8 5732 case 7:
d9bea114 5733// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5734 rn = "Performance7";
5735// break;
9c2149c8
TS
5736 default:
5737 goto die;
5738 }
5739 break;
5740 case 26:
d9bea114 5741 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5742 rn = "ECC";
5743 break;
9c2149c8
TS
5744 case 27:
5745 switch (sel) {
5746 /* ignored */
5747 case 0 ... 3:
d9bea114 5748 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5749 rn = "CacheErr";
5750 break;
9c2149c8
TS
5751 default:
5752 goto die;
5753 }
5754 break;
5755 case 28:
5756 switch (sel) {
5757 case 0:
5758 case 2:
5759 case 4:
5760 case 6:
7db13fae 5761 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5762 rn = "TagLo";
5763 break;
5764 case 1:
5765 case 3:
5766 case 5:
5767 case 7:
7db13fae 5768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5769 rn = "DataLo";
5770 break;
5771 default:
5772 goto die;
5773 }
5774 break;
5775 case 29:
5776 switch (sel) {
5777 case 0:
5778 case 2:
5779 case 4:
5780 case 6:
7db13fae 5781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5782 rn = "TagHi";
5783 break;
5784 case 1:
5785 case 3:
5786 case 5:
5787 case 7:
7db13fae 5788 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5789 rn = "DataHi";
5790 break;
5791 default:
5792 goto die;
5793 }
5794 break;
5795 case 30:
5796 switch (sel) {
5797 case 0:
7db13fae 5798 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5799 rn = "ErrorEPC";
5800 break;
9c2149c8
TS
5801 default:
5802 goto die;
5803 }
5804 break;
5805 case 31:
5806 switch (sel) {
5807 case 0:
f0b3f3ae 5808 /* EJTAG support */
7db13fae 5809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5810 rn = "DESAVE";
5811 break;
9c2149c8
TS
5812 default:
5813 goto die;
5814 }
5815 break;
5816 default:
876d4b07 5817 goto die;
9c2149c8 5818 }
2abf314d 5819 (void)rn; /* avoid a compiler warning */
d12d51d5 5820 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5821 return;
5822
5823die:
d12d51d5 5824 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5825 generate_exception(ctx, EXCP_RI);
5826}
5827
d75c135e 5828static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5829{
5830 const char *rn = "invalid";
5831
e189e748 5832 if (sel != 0)
d75c135e 5833 check_insn(ctx, ISA_MIPS64);
e189e748 5834
2e70f6ef
PB
5835 if (use_icount)
5836 gen_io_start();
5837
9c2149c8
TS
5838 switch (reg) {
5839 case 0:
5840 switch (sel) {
5841 case 0:
895c2d04 5842 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5843 rn = "Index";
5844 break;
5845 case 1:
d75c135e 5846 check_insn(ctx, ASE_MT);
895c2d04 5847 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5848 rn = "MVPControl";
ead9360e 5849 break;
9c2149c8 5850 case 2:
d75c135e 5851 check_insn(ctx, ASE_MT);
ead9360e 5852 /* ignored */
9c2149c8 5853 rn = "MVPConf0";
ead9360e 5854 break;
9c2149c8 5855 case 3:
d75c135e 5856 check_insn(ctx, ASE_MT);
ead9360e 5857 /* ignored */
9c2149c8 5858 rn = "MVPConf1";
ead9360e 5859 break;
9c2149c8
TS
5860 default:
5861 goto die;
5862 }
5863 break;
5864 case 1:
5865 switch (sel) {
5866 case 0:
2423f660 5867 /* ignored */
9c2149c8 5868 rn = "Random";
2423f660 5869 break;
9c2149c8 5870 case 1:
d75c135e 5871 check_insn(ctx, ASE_MT);
895c2d04 5872 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5873 rn = "VPEControl";
ead9360e 5874 break;
9c2149c8 5875 case 2:
d75c135e 5876 check_insn(ctx, ASE_MT);
895c2d04 5877 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5878 rn = "VPEConf0";
ead9360e 5879 break;
9c2149c8 5880 case 3:
d75c135e 5881 check_insn(ctx, ASE_MT);
895c2d04 5882 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5883 rn = "VPEConf1";
ead9360e 5884 break;
9c2149c8 5885 case 4:
d75c135e 5886 check_insn(ctx, ASE_MT);
895c2d04 5887 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5888 rn = "YQMask";
ead9360e 5889 break;
9c2149c8 5890 case 5:
d75c135e 5891 check_insn(ctx, ASE_MT);
7db13fae 5892 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5893 rn = "VPESchedule";
ead9360e 5894 break;
9c2149c8 5895 case 6:
d75c135e 5896 check_insn(ctx, ASE_MT);
7db13fae 5897 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5898 rn = "VPEScheFBack";
ead9360e 5899 break;
9c2149c8 5900 case 7:
d75c135e 5901 check_insn(ctx, ASE_MT);
895c2d04 5902 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5903 rn = "VPEOpt";
ead9360e 5904 break;
9c2149c8
TS
5905 default:
5906 goto die;
5907 }
5908 break;
5909 case 2:
5910 switch (sel) {
5911 case 0:
895c2d04 5912 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5913 rn = "EntryLo0";
5914 break;
9c2149c8 5915 case 1:
d75c135e 5916 check_insn(ctx, ASE_MT);
895c2d04 5917 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5918 rn = "TCStatus";
ead9360e 5919 break;
9c2149c8 5920 case 2:
d75c135e 5921 check_insn(ctx, ASE_MT);
895c2d04 5922 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5923 rn = "TCBind";
ead9360e 5924 break;
9c2149c8 5925 case 3:
d75c135e 5926 check_insn(ctx, ASE_MT);
895c2d04 5927 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5928 rn = "TCRestart";
ead9360e 5929 break;
9c2149c8 5930 case 4:
d75c135e 5931 check_insn(ctx, ASE_MT);
895c2d04 5932 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5933 rn = "TCHalt";
ead9360e 5934 break;
9c2149c8 5935 case 5:
d75c135e 5936 check_insn(ctx, ASE_MT);
895c2d04 5937 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5938 rn = "TCContext";
ead9360e 5939 break;
9c2149c8 5940 case 6:
d75c135e 5941 check_insn(ctx, ASE_MT);
895c2d04 5942 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5943 rn = "TCSchedule";
ead9360e 5944 break;
9c2149c8 5945 case 7:
d75c135e 5946 check_insn(ctx, ASE_MT);
895c2d04 5947 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5948 rn = "TCScheFBack";
ead9360e 5949 break;
9c2149c8
TS
5950 default:
5951 goto die;
5952 }
5953 break;
5954 case 3:
5955 switch (sel) {
5956 case 0:
895c2d04 5957 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5958 rn = "EntryLo1";
5959 break;
9c2149c8
TS
5960 default:
5961 goto die;
876d4b07 5962 }
9c2149c8
TS
5963 break;
5964 case 4:
5965 switch (sel) {
5966 case 0:
895c2d04 5967 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5968 rn = "Context";
5969 break;
9c2149c8 5970 case 1:
895c2d04 5971// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
5972 rn = "ContextConfig";
5973// break;
9c2149c8
TS
5974 default:
5975 goto die;
876d4b07 5976 }
9c2149c8
TS
5977 break;
5978 case 5:
5979 switch (sel) {
5980 case 0:
895c2d04 5981 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5982 rn = "PageMask";
5983 break;
9c2149c8 5984 case 1:
d75c135e 5985 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5986 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5987 rn = "PageGrain";
5988 break;
9c2149c8
TS
5989 default:
5990 goto die;
876d4b07 5991 }
9c2149c8
TS
5992 break;
5993 case 6:
5994 switch (sel) {
5995 case 0:
895c2d04 5996 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5997 rn = "Wired";
5998 break;
9c2149c8 5999 case 1:
d75c135e 6000 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6001 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6002 rn = "SRSConf0";
ead9360e 6003 break;
9c2149c8 6004 case 2:
d75c135e 6005 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6006 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6007 rn = "SRSConf1";
ead9360e 6008 break;
9c2149c8 6009 case 3:
d75c135e 6010 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6011 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6012 rn = "SRSConf2";
ead9360e 6013 break;
9c2149c8 6014 case 4:
d75c135e 6015 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6016 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6017 rn = "SRSConf3";
ead9360e 6018 break;
9c2149c8 6019 case 5:
d75c135e 6020 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6021 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6022 rn = "SRSConf4";
ead9360e 6023 break;
9c2149c8
TS
6024 default:
6025 goto die;
876d4b07 6026 }
9c2149c8
TS
6027 break;
6028 case 7:
6029 switch (sel) {
6030 case 0:
d75c135e 6031 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6032 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
6033 rn = "HWREna";
6034 break;
9c2149c8
TS
6035 default:
6036 goto die;
876d4b07 6037 }
9c2149c8
TS
6038 break;
6039 case 8:
6040 /* ignored */
f0b3f3ae 6041 rn = "BadVAddr";
9c2149c8
TS
6042 break;
6043 case 9:
6044 switch (sel) {
6045 case 0:
895c2d04 6046 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6047 rn = "Count";
6048 break;
876d4b07 6049 /* 6,7 are implementation dependent */
9c2149c8
TS
6050 default:
6051 goto die;
876d4b07
TS
6052 }
6053 /* Stop translation as we may have switched the execution mode */
6054 ctx->bstate = BS_STOP;
9c2149c8
TS
6055 break;
6056 case 10:
6057 switch (sel) {
6058 case 0:
895c2d04 6059 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6060 rn = "EntryHi";
6061 break;
9c2149c8
TS
6062 default:
6063 goto die;
876d4b07 6064 }
9c2149c8
TS
6065 break;
6066 case 11:
6067 switch (sel) {
6068 case 0:
895c2d04 6069 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6070 rn = "Compare";
6071 break;
876d4b07 6072 /* 6,7 are implementation dependent */
9c2149c8
TS
6073 default:
6074 goto die;
876d4b07 6075 }
de9a95f0
AJ
6076 /* Stop translation as we may have switched the execution mode */
6077 ctx->bstate = BS_STOP;
9c2149c8
TS
6078 break;
6079 case 12:
6080 switch (sel) {
6081 case 0:
867abc7e 6082 save_cpu_state(ctx, 1);
895c2d04 6083 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6084 /* BS_STOP isn't good enough here, hflags may have changed. */
6085 gen_save_pc(ctx->pc + 4);
6086 ctx->bstate = BS_EXCP;
2423f660
TS
6087 rn = "Status";
6088 break;
9c2149c8 6089 case 1:
d75c135e 6090 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6091 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6092 /* Stop translation as we may have switched the execution mode */
6093 ctx->bstate = BS_STOP;
2423f660
TS
6094 rn = "IntCtl";
6095 break;
9c2149c8 6096 case 2:
d75c135e 6097 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6098 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6099 /* Stop translation as we may have switched the execution mode */
6100 ctx->bstate = BS_STOP;
2423f660
TS
6101 rn = "SRSCtl";
6102 break;
9c2149c8 6103 case 3:
d75c135e 6104 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6105 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6106 /* Stop translation as we may have switched the execution mode */
6107 ctx->bstate = BS_STOP;
2423f660
TS
6108 rn = "SRSMap";
6109 break;
6110 default:
9c2149c8 6111 goto die;
876d4b07 6112 }
9c2149c8
TS
6113 break;
6114 case 13:
6115 switch (sel) {
6116 case 0:
867abc7e 6117 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6118 /* Mark as an IO operation because we may trigger a software
6119 interrupt. */
6120 if (use_icount) {
6121 gen_io_start();
6122 }
895c2d04 6123 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6124 if (use_icount) {
6125 gen_io_end();
6126 }
6127 /* Stop translation as we may have triggered an intetrupt */
6128 ctx->bstate = BS_STOP;
2423f660
TS
6129 rn = "Cause";
6130 break;
9c2149c8
TS
6131 default:
6132 goto die;
876d4b07 6133 }
9c2149c8
TS
6134 break;
6135 case 14:
6136 switch (sel) {
6137 case 0:
7db13fae 6138 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6139 rn = "EPC";
6140 break;
9c2149c8
TS
6141 default:
6142 goto die;
876d4b07 6143 }
9c2149c8
TS
6144 break;
6145 case 15:
6146 switch (sel) {
6147 case 0:
2423f660
TS
6148 /* ignored */
6149 rn = "PRid";
6150 break;
9c2149c8 6151 case 1:
d75c135e 6152 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6153 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6154 rn = "EBase";
6155 break;
9c2149c8
TS
6156 default:
6157 goto die;
876d4b07 6158 }
9c2149c8
TS
6159 break;
6160 case 16:
6161 switch (sel) {
6162 case 0:
895c2d04 6163 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6164 rn = "Config";
2423f660
TS
6165 /* Stop translation as we may have switched the execution mode */
6166 ctx->bstate = BS_STOP;
9c2149c8
TS
6167 break;
6168 case 1:
1fc7bf6e 6169 /* ignored, read only */
9c2149c8
TS
6170 rn = "Config1";
6171 break;
6172 case 2:
895c2d04 6173 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6174 rn = "Config2";
2423f660
TS
6175 /* Stop translation as we may have switched the execution mode */
6176 ctx->bstate = BS_STOP;
9c2149c8
TS
6177 break;
6178 case 3:
2423f660 6179 /* ignored */
9c2149c8
TS
6180 rn = "Config3";
6181 break;
6182 /* 6,7 are implementation dependent */
6183 default:
6184 rn = "Invalid config selector";
6185 goto die;
6186 }
9c2149c8
TS
6187 break;
6188 case 17:
6189 switch (sel) {
6190 case 0:
895c2d04 6191 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6192 rn = "LLAddr";
6193 break;
9c2149c8
TS
6194 default:
6195 goto die;
6196 }
6197 break;
6198 case 18:
6199 switch (sel) {
fd88b6ab 6200 case 0 ... 7:
895c2d04 6201 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6202 rn = "WatchLo";
6203 break;
9c2149c8
TS
6204 default:
6205 goto die;
6206 }
6207 break;
6208 case 19:
6209 switch (sel) {
fd88b6ab 6210 case 0 ... 7:
895c2d04 6211 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6212 rn = "WatchHi";
6213 break;
9c2149c8
TS
6214 default:
6215 goto die;
6216 }
6217 break;
6218 case 20:
6219 switch (sel) {
6220 case 0:
d75c135e 6221 check_insn(ctx, ISA_MIPS3);
895c2d04 6222 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6223 rn = "XContext";
6224 break;
9c2149c8
TS
6225 default:
6226 goto die;
6227 }
6228 break;
6229 case 21:
6230 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6231 switch (sel) {
6232 case 0:
895c2d04 6233 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6234 rn = "Framemask";
6235 break;
9c2149c8
TS
6236 default:
6237 goto die;
6238 }
6239 break;
6240 case 22:
6241 /* ignored */
6242 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6243 break;
9c2149c8
TS
6244 case 23:
6245 switch (sel) {
6246 case 0:
895c2d04 6247 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6248 /* BS_STOP isn't good enough here, hflags may have changed. */
6249 gen_save_pc(ctx->pc + 4);
6250 ctx->bstate = BS_EXCP;
2423f660
TS
6251 rn = "Debug";
6252 break;
9c2149c8 6253 case 1:
895c2d04 6254// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6255 /* Stop translation as we may have switched the execution mode */
6256 ctx->bstate = BS_STOP;
2423f660
TS
6257 rn = "TraceControl";
6258// break;
9c2149c8 6259 case 2:
895c2d04 6260// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6261 /* Stop translation as we may have switched the execution mode */
6262 ctx->bstate = BS_STOP;
2423f660
TS
6263 rn = "TraceControl2";
6264// break;
9c2149c8 6265 case 3:
895c2d04 6266// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6267 /* Stop translation as we may have switched the execution mode */
6268 ctx->bstate = BS_STOP;
2423f660
TS
6269 rn = "UserTraceData";
6270// break;
9c2149c8 6271 case 4:
895c2d04 6272// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6273 /* Stop translation as we may have switched the execution mode */
6274 ctx->bstate = BS_STOP;
2423f660
TS
6275 rn = "TraceBPC";
6276// break;
9c2149c8
TS
6277 default:
6278 goto die;
6279 }
9c2149c8
TS
6280 break;
6281 case 24:
6282 switch (sel) {
6283 case 0:
f1aa6320 6284 /* EJTAG support */
7db13fae 6285 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6286 rn = "DEPC";
6287 break;
9c2149c8
TS
6288 default:
6289 goto die;
6290 }
6291 break;
6292 case 25:
6293 switch (sel) {
6294 case 0:
895c2d04 6295 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6296 rn = "Performance0";
6297 break;
9c2149c8 6298 case 1:
895c2d04 6299// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6300 rn = "Performance1";
6301// break;
9c2149c8 6302 case 2:
895c2d04 6303// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6304 rn = "Performance2";
6305// break;
9c2149c8 6306 case 3:
895c2d04 6307// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6308 rn = "Performance3";
6309// break;
9c2149c8 6310 case 4:
895c2d04 6311// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6312 rn = "Performance4";
6313// break;
9c2149c8 6314 case 5:
895c2d04 6315// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6316 rn = "Performance5";
6317// break;
9c2149c8 6318 case 6:
895c2d04 6319// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6320 rn = "Performance6";
6321// break;
9c2149c8 6322 case 7:
895c2d04 6323// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6324 rn = "Performance7";
6325// break;
9c2149c8
TS
6326 default:
6327 goto die;
6328 }
876d4b07 6329 break;
9c2149c8 6330 case 26:
876d4b07 6331 /* ignored */
9c2149c8 6332 rn = "ECC";
876d4b07 6333 break;
9c2149c8
TS
6334 case 27:
6335 switch (sel) {
6336 case 0 ... 3:
2423f660
TS
6337 /* ignored */
6338 rn = "CacheErr";
6339 break;
9c2149c8
TS
6340 default:
6341 goto die;
6342 }
876d4b07 6343 break;
9c2149c8
TS
6344 case 28:
6345 switch (sel) {
6346 case 0:
6347 case 2:
6348 case 4:
6349 case 6:
895c2d04 6350 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6351 rn = "TagLo";
6352 break;
6353 case 1:
6354 case 3:
6355 case 5:
6356 case 7:
895c2d04 6357 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6358 rn = "DataLo";
6359 break;
6360 default:
6361 goto die;
6362 }
6363 break;
6364 case 29:
6365 switch (sel) {
6366 case 0:
6367 case 2:
6368 case 4:
6369 case 6:
895c2d04 6370 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6371 rn = "TagHi";
6372 break;
6373 case 1:
6374 case 3:
6375 case 5:
6376 case 7:
895c2d04 6377 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6378 rn = "DataHi";
6379 break;
6380 default:
6381 rn = "invalid sel";
6382 goto die;
6383 }
876d4b07 6384 break;
9c2149c8
TS
6385 case 30:
6386 switch (sel) {
6387 case 0:
7db13fae 6388 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6389 rn = "ErrorEPC";
6390 break;
9c2149c8
TS
6391 default:
6392 goto die;
6393 }
6394 break;
6395 case 31:
6396 switch (sel) {
6397 case 0:
f1aa6320 6398 /* EJTAG support */
7db13fae 6399 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6400 rn = "DESAVE";
6401 break;
9c2149c8
TS
6402 default:
6403 goto die;
6404 }
876d4b07
TS
6405 /* Stop translation as we may have switched the execution mode */
6406 ctx->bstate = BS_STOP;
9c2149c8
TS
6407 break;
6408 default:
876d4b07 6409 goto die;
9c2149c8 6410 }
2abf314d 6411 (void)rn; /* avoid a compiler warning */
d12d51d5 6412 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6413 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6414 if (use_icount) {
6415 gen_io_end();
6416 ctx->bstate = BS_STOP;
6417 }
9c2149c8
TS
6418 return;
6419
6420die:
d12d51d5 6421 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6422 generate_exception(ctx, EXCP_RI);
6423}
d26bc211 6424#endif /* TARGET_MIPS64 */
9c2149c8 6425
7db13fae 6426static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6427 int u, int sel, int h)
6428{
6429 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6430 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6431
6432 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6433 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6434 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6435 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6436 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6437 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6438 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6439 else if (u == 0) {
6440 switch (rt) {
5a25ce94
EI
6441 case 1:
6442 switch (sel) {
6443 case 1:
895c2d04 6444 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6445 break;
6446 case 2:
895c2d04 6447 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6448 break;
6449 default:
6450 goto die;
6451 break;
6452 }
6453 break;
ead9360e
TS
6454 case 2:
6455 switch (sel) {
6456 case 1:
895c2d04 6457 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6458 break;
6459 case 2:
895c2d04 6460 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6461 break;
6462 case 3:
895c2d04 6463 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6464 break;
6465 case 4:
895c2d04 6466 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6467 break;
6468 case 5:
895c2d04 6469 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6470 break;
6471 case 6:
895c2d04 6472 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6473 break;
6474 case 7:
895c2d04 6475 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6476 break;
6477 default:
d75c135e 6478 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6479 break;
6480 }
6481 break;
6482 case 10:
6483 switch (sel) {
6484 case 0:
895c2d04 6485 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6486 break;
6487 default:
d75c135e 6488 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6489 break;
6490 }
6491 case 12:
6492 switch (sel) {
6493 case 0:
895c2d04 6494 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6495 break;
6496 default:
d75c135e 6497 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6498 break;
6499 }
5a25ce94
EI
6500 case 13:
6501 switch (sel) {
6502 case 0:
895c2d04 6503 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6504 break;
6505 default:
6506 goto die;
6507 break;
6508 }
6509 break;
6510 case 14:
6511 switch (sel) {
6512 case 0:
895c2d04 6513 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6514 break;
6515 default:
6516 goto die;
6517 break;
6518 }
6519 break;
6520 case 15:
6521 switch (sel) {
6522 case 1:
895c2d04 6523 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6524 break;
6525 default:
6526 goto die;
6527 break;
6528 }
6529 break;
6530 case 16:
6531 switch (sel) {
6532 case 0 ... 7:
895c2d04 6533 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6534 break;
6535 default:
6536 goto die;
6537 break;
6538 }
6539 break;
ead9360e
TS
6540 case 23:
6541 switch (sel) {
6542 case 0:
895c2d04 6543 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6544 break;
6545 default:
d75c135e 6546 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6547 break;
6548 }
6549 break;
6550 default:
d75c135e 6551 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6552 }
6553 } else switch (sel) {
6554 /* GPR registers. */
6555 case 0:
895c2d04 6556 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6557 break;
6558 /* Auxiliary CPU registers */
6559 case 1:
6560 switch (rt) {
6561 case 0:
895c2d04 6562 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6563 break;
6564 case 1:
895c2d04 6565 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6566 break;
6567 case 2:
895c2d04 6568 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6569 break;
6570 case 4:
895c2d04 6571 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6572 break;
6573 case 5:
895c2d04 6574 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6575 break;
6576 case 6:
895c2d04 6577 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6578 break;
6579 case 8:
895c2d04 6580 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6581 break;
6582 case 9:
895c2d04 6583 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6584 break;
6585 case 10:
895c2d04 6586 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6587 break;
6588 case 12:
895c2d04 6589 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6590 break;
6591 case 13:
895c2d04 6592 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6593 break;
6594 case 14:
895c2d04 6595 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6596 break;
6597 case 16:
895c2d04 6598 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6599 break;
6600 default:
6601 goto die;
6602 }
6603 break;
6604 /* Floating point (COP1). */
6605 case 2:
6606 /* XXX: For now we support only a single FPU context. */
6607 if (h == 0) {
a7812ae4 6608 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6609
6610 gen_load_fpr32(fp0, rt);
6611 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6612 tcg_temp_free_i32(fp0);
ead9360e 6613 } else {
a7812ae4 6614 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6615
6616 gen_load_fpr32h(fp0, rt);
6617 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6618 tcg_temp_free_i32(fp0);
ead9360e
TS
6619 }
6620 break;
6621 case 3:
6622 /* XXX: For now we support only a single FPU context. */
895c2d04 6623 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6624 break;
6625 /* COP2: Not implemented. */
6626 case 4:
6627 case 5:
6628 /* fall through */
6629 default:
6630 goto die;
6631 }
d12d51d5 6632 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6633 gen_store_gpr(t0, rd);
6634 tcg_temp_free(t0);
ead9360e
TS
6635 return;
6636
6637die:
1a3fd9c3 6638 tcg_temp_free(t0);
d12d51d5 6639 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6640 generate_exception(ctx, EXCP_RI);
6641}
6642
7db13fae 6643static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6644 int u, int sel, int h)
6645{
6646 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6647 TCGv t0 = tcg_temp_local_new();
ead9360e 6648
1a3fd9c3 6649 gen_load_gpr(t0, rt);
ead9360e 6650 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6651 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6652 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6653 /* NOP */ ;
6654 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6655 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6656 /* NOP */ ;
6657 else if (u == 0) {
6658 switch (rd) {
5a25ce94
EI
6659 case 1:
6660 switch (sel) {
6661 case 1:
895c2d04 6662 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6663 break;
6664 case 2:
895c2d04 6665 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6666 break;
6667 default:
6668 goto die;
6669 break;
6670 }
6671 break;
ead9360e
TS
6672 case 2:
6673 switch (sel) {
6674 case 1:
895c2d04 6675 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6676 break;
6677 case 2:
895c2d04 6678 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6679 break;
6680 case 3:
895c2d04 6681 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6682 break;
6683 case 4:
895c2d04 6684 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6685 break;
6686 case 5:
895c2d04 6687 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6688 break;
6689 case 6:
895c2d04 6690 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6691 break;
6692 case 7:
895c2d04 6693 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6694 break;
6695 default:
d75c135e 6696 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6697 break;
6698 }
6699 break;
6700 case 10:
6701 switch (sel) {
6702 case 0:
895c2d04 6703 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6704 break;
6705 default:
d75c135e 6706 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6707 break;
6708 }
6709 case 12:
6710 switch (sel) {
6711 case 0:
895c2d04 6712 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6713 break;
6714 default:
d75c135e 6715 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6716 break;
6717 }
5a25ce94
EI
6718 case 13:
6719 switch (sel) {
6720 case 0:
895c2d04 6721 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6722 break;
6723 default:
6724 goto die;
6725 break;
6726 }
6727 break;
6728 case 15:
6729 switch (sel) {
6730 case 1:
895c2d04 6731 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6732 break;
6733 default:
6734 goto die;
6735 break;
6736 }
6737 break;
ead9360e
TS
6738 case 23:
6739 switch (sel) {
6740 case 0:
895c2d04 6741 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6742 break;
6743 default:
d75c135e 6744 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6745 break;
6746 }
6747 break;
6748 default:
d75c135e 6749 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6750 }
6751 } else switch (sel) {
6752 /* GPR registers. */
6753 case 0:
895c2d04 6754 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6755 break;
6756 /* Auxiliary CPU registers */
6757 case 1:
6758 switch (rd) {
6759 case 0:
895c2d04 6760 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6761 break;
6762 case 1:
895c2d04 6763 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6764 break;
6765 case 2:
895c2d04 6766 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6767 break;
6768 case 4:
895c2d04 6769 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6770 break;
6771 case 5:
895c2d04 6772 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6773 break;
6774 case 6:
895c2d04 6775 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6776 break;
6777 case 8:
895c2d04 6778 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6779 break;
6780 case 9:
895c2d04 6781 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6782 break;
6783 case 10:
895c2d04 6784 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6785 break;
6786 case 12:
895c2d04 6787 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6788 break;
6789 case 13:
895c2d04 6790 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6791 break;
6792 case 14:
895c2d04 6793 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6794 break;
6795 case 16:
895c2d04 6796 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6797 break;
6798 default:
6799 goto die;
6800 }
6801 break;
6802 /* Floating point (COP1). */
6803 case 2:
6804 /* XXX: For now we support only a single FPU context. */
6805 if (h == 0) {
a7812ae4 6806 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6807
6808 tcg_gen_trunc_tl_i32(fp0, t0);
6809 gen_store_fpr32(fp0, rd);
a7812ae4 6810 tcg_temp_free_i32(fp0);
ead9360e 6811 } else {
a7812ae4 6812 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6813
6814 tcg_gen_trunc_tl_i32(fp0, t0);
6815 gen_store_fpr32h(fp0, rd);
a7812ae4 6816 tcg_temp_free_i32(fp0);
ead9360e
TS
6817 }
6818 break;
6819 case 3:
6820 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
6821 {
6822 TCGv_i32 fs_tmp = tcg_const_i32(rd);
6823
6824 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
6825 tcg_temp_free_i32(fs_tmp);
6826 }
ead9360e
TS
6827 break;
6828 /* COP2: Not implemented. */
6829 case 4:
6830 case 5:
6831 /* fall through */
6832 default:
6833 goto die;
6834 }
d12d51d5 6835 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6836 tcg_temp_free(t0);
ead9360e
TS
6837 return;
6838
6839die:
1a3fd9c3 6840 tcg_temp_free(t0);
d12d51d5 6841 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6842 generate_exception(ctx, EXCP_RI);
6843}
6844
7db13fae 6845static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6846{
287c4b84 6847 const char *opn = "ldst";
6af0bf9c 6848
2e15497c 6849 check_cp0_enabled(ctx);
6af0bf9c
FB
6850 switch (opc) {
6851 case OPC_MFC0:
6852 if (rt == 0) {
ead9360e 6853 /* Treat as NOP. */
6af0bf9c
FB
6854 return;
6855 }
d75c135e 6856 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6857 opn = "mfc0";
6858 break;
6859 case OPC_MTC0:
1a3fd9c3 6860 {
1fc7bf6e 6861 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6862
6863 gen_load_gpr(t0, rt);
d75c135e 6864 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6865 tcg_temp_free(t0);
6866 }
6af0bf9c
FB
6867 opn = "mtc0";
6868 break;
d26bc211 6869#if defined(TARGET_MIPS64)
9c2149c8 6870 case OPC_DMFC0:
d75c135e 6871 check_insn(ctx, ISA_MIPS3);
9c2149c8 6872 if (rt == 0) {
ead9360e 6873 /* Treat as NOP. */
9c2149c8
TS
6874 return;
6875 }
d75c135e 6876 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6877 opn = "dmfc0";
6878 break;
6879 case OPC_DMTC0:
d75c135e 6880 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 6881 {
1fc7bf6e 6882 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6883
6884 gen_load_gpr(t0, rt);
d75c135e 6885 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6886 tcg_temp_free(t0);
6887 }
9c2149c8
TS
6888 opn = "dmtc0";
6889 break;
534ce69f 6890#endif
ead9360e 6891 case OPC_MFTR:
d75c135e 6892 check_insn(ctx, ASE_MT);
ead9360e
TS
6893 if (rd == 0) {
6894 /* Treat as NOP. */
6895 return;
6896 }
6c5c1e20 6897 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6898 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6899 opn = "mftr";
6900 break;
6901 case OPC_MTTR:
d75c135e 6902 check_insn(ctx, ASE_MT);
6c5c1e20 6903 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6904 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6905 opn = "mttr";
6906 break;
6af0bf9c 6907 case OPC_TLBWI:
6af0bf9c 6908 opn = "tlbwi";
c01fccd2 6909 if (!env->tlb->helper_tlbwi)
29929e34 6910 goto die;
895c2d04 6911 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6912 break;
6913 case OPC_TLBWR:
6af0bf9c 6914 opn = "tlbwr";
c01fccd2 6915 if (!env->tlb->helper_tlbwr)
29929e34 6916 goto die;
895c2d04 6917 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6918 break;
6919 case OPC_TLBP:
6af0bf9c 6920 opn = "tlbp";
c01fccd2 6921 if (!env->tlb->helper_tlbp)
29929e34 6922 goto die;
895c2d04 6923 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6924 break;
6925 case OPC_TLBR:
6af0bf9c 6926 opn = "tlbr";
c01fccd2 6927 if (!env->tlb->helper_tlbr)
29929e34 6928 goto die;
895c2d04 6929 gen_helper_tlbr(cpu_env);
6af0bf9c 6930 break;
6af0bf9c
FB
6931 case OPC_ERET:
6932 opn = "eret";
d75c135e 6933 check_insn(ctx, ISA_MIPS2);
895c2d04 6934 gen_helper_eret(cpu_env);
6af0bf9c
FB
6935 ctx->bstate = BS_EXCP;
6936 break;
6937 case OPC_DERET:
6938 opn = "deret";
d75c135e 6939 check_insn(ctx, ISA_MIPS32);
6af0bf9c 6940 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6941 MIPS_INVAL(opn);
6af0bf9c
FB
6942 generate_exception(ctx, EXCP_RI);
6943 } else {
895c2d04 6944 gen_helper_deret(cpu_env);
6af0bf9c
FB
6945 ctx->bstate = BS_EXCP;
6946 }
6947 break;
4ad40f36
FB
6948 case OPC_WAIT:
6949 opn = "wait";
d75c135e 6950 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6951 /* If we get an exception, we want to restart at next instruction */
6952 ctx->pc += 4;
6953 save_cpu_state(ctx, 1);
6954 ctx->pc -= 4;
895c2d04 6955 gen_helper_wait(cpu_env);
4ad40f36
FB
6956 ctx->bstate = BS_EXCP;
6957 break;
6af0bf9c 6958 default:
29929e34 6959 die:
923617a3 6960 MIPS_INVAL(opn);
6af0bf9c
FB
6961 generate_exception(ctx, EXCP_RI);
6962 return;
6963 }
2abf314d 6964 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
6965 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6966}
f1aa6320 6967#endif /* !CONFIG_USER_ONLY */
6af0bf9c 6968
6ea83fed 6969/* CP1 Branches (before delay slot) */
d75c135e
AJ
6970static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6971 int32_t cc, int32_t offset)
6ea83fed
FB
6972{
6973 target_ulong btarget;
923617a3 6974 const char *opn = "cp1 cond branch";
a7812ae4 6975 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 6976
e189e748 6977 if (cc != 0)
d75c135e 6978 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 6979
6ea83fed
FB
6980 btarget = ctx->pc + 4 + offset;
6981
7a387fff
TS
6982 switch (op) {
6983 case OPC_BC1F:
d94536f4
AJ
6984 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6985 tcg_gen_not_i32(t0, t0);
6986 tcg_gen_andi_i32(t0, t0, 1);
6987 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 6988 opn = "bc1f";
6ea83fed 6989 goto not_likely;
7a387fff 6990 case OPC_BC1FL:
d94536f4
AJ
6991 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6992 tcg_gen_not_i32(t0, t0);
6993 tcg_gen_andi_i32(t0, t0, 1);
6994 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 6995 opn = "bc1fl";
6ea83fed 6996 goto likely;
7a387fff 6997 case OPC_BC1T:
d94536f4
AJ
6998 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6999 tcg_gen_andi_i32(t0, t0, 1);
7000 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7001 opn = "bc1t";
5a5012ec 7002 goto not_likely;
7a387fff 7003 case OPC_BC1TL:
d94536f4
AJ
7004 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7005 tcg_gen_andi_i32(t0, t0, 1);
7006 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7007 opn = "bc1tl";
6ea83fed
FB
7008 likely:
7009 ctx->hflags |= MIPS_HFLAG_BL;
7010 break;
5a5012ec 7011 case OPC_BC1FANY2:
a16336e4 7012 {
d94536f4
AJ
7013 TCGv_i32 t1 = tcg_temp_new_i32();
7014 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7015 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7016 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7017 tcg_temp_free_i32(t1);
d94536f4
AJ
7018 tcg_gen_andi_i32(t0, t0, 1);
7019 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7020 }
fd4a04eb 7021 opn = "bc1any2f";
5a5012ec
TS
7022 goto not_likely;
7023 case OPC_BC1TANY2:
a16336e4 7024 {
d94536f4
AJ
7025 TCGv_i32 t1 = tcg_temp_new_i32();
7026 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7027 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7028 tcg_gen_or_i32(t0, t0, t1);
7029 tcg_temp_free_i32(t1);
7030 tcg_gen_andi_i32(t0, t0, 1);
7031 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7032 }
fd4a04eb 7033 opn = "bc1any2t";
5a5012ec
TS
7034 goto not_likely;
7035 case OPC_BC1FANY4:
a16336e4 7036 {
d94536f4
AJ
7037 TCGv_i32 t1 = tcg_temp_new_i32();
7038 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7039 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7040 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7041 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7042 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7043 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7044 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7045 tcg_temp_free_i32(t1);
d94536f4
AJ
7046 tcg_gen_andi_i32(t0, t0, 1);
7047 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7048 }
fd4a04eb 7049 opn = "bc1any4f";
5a5012ec
TS
7050 goto not_likely;
7051 case OPC_BC1TANY4:
a16336e4 7052 {
d94536f4
AJ
7053 TCGv_i32 t1 = tcg_temp_new_i32();
7054 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7055 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7056 tcg_gen_or_i32(t0, t0, t1);
7057 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7058 tcg_gen_or_i32(t0, t0, t1);
7059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7060 tcg_gen_or_i32(t0, t0, t1);
7061 tcg_temp_free_i32(t1);
7062 tcg_gen_andi_i32(t0, t0, 1);
7063 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7064 }
fd4a04eb 7065 opn = "bc1any4t";
5a5012ec
TS
7066 not_likely:
7067 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7068 break;
7069 default:
923617a3 7070 MIPS_INVAL(opn);
e397ee33 7071 generate_exception (ctx, EXCP_RI);
6c5c1e20 7072 goto out;
6ea83fed 7073 }
2abf314d 7074 (void)opn; /* avoid a compiler warning */
923617a3 7075 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7076 ctx->hflags, btarget);
7077 ctx->btarget = btarget;
6c5c1e20
TS
7078
7079 out:
a7812ae4 7080 tcg_temp_free_i32(t0);
6ea83fed
FB
7081}
7082
6af0bf9c 7083/* Coprocessor 1 (FPU) */
5a5012ec 7084
5a5012ec
TS
7085#define FOP(func, fmt) (((fmt) << 21) | (func))
7086
bf4120ad
NF
7087enum fopcode {
7088 OPC_ADD_S = FOP(0, FMT_S),
7089 OPC_SUB_S = FOP(1, FMT_S),
7090 OPC_MUL_S = FOP(2, FMT_S),
7091 OPC_DIV_S = FOP(3, FMT_S),
7092 OPC_SQRT_S = FOP(4, FMT_S),
7093 OPC_ABS_S = FOP(5, FMT_S),
7094 OPC_MOV_S = FOP(6, FMT_S),
7095 OPC_NEG_S = FOP(7, FMT_S),
7096 OPC_ROUND_L_S = FOP(8, FMT_S),
7097 OPC_TRUNC_L_S = FOP(9, FMT_S),
7098 OPC_CEIL_L_S = FOP(10, FMT_S),
7099 OPC_FLOOR_L_S = FOP(11, FMT_S),
7100 OPC_ROUND_W_S = FOP(12, FMT_S),
7101 OPC_TRUNC_W_S = FOP(13, FMT_S),
7102 OPC_CEIL_W_S = FOP(14, FMT_S),
7103 OPC_FLOOR_W_S = FOP(15, FMT_S),
7104 OPC_MOVCF_S = FOP(17, FMT_S),
7105 OPC_MOVZ_S = FOP(18, FMT_S),
7106 OPC_MOVN_S = FOP(19, FMT_S),
7107 OPC_RECIP_S = FOP(21, FMT_S),
7108 OPC_RSQRT_S = FOP(22, FMT_S),
7109 OPC_RECIP2_S = FOP(28, FMT_S),
7110 OPC_RECIP1_S = FOP(29, FMT_S),
7111 OPC_RSQRT1_S = FOP(30, FMT_S),
7112 OPC_RSQRT2_S = FOP(31, FMT_S),
7113 OPC_CVT_D_S = FOP(33, FMT_S),
7114 OPC_CVT_W_S = FOP(36, FMT_S),
7115 OPC_CVT_L_S = FOP(37, FMT_S),
7116 OPC_CVT_PS_S = FOP(38, FMT_S),
7117 OPC_CMP_F_S = FOP (48, FMT_S),
7118 OPC_CMP_UN_S = FOP (49, FMT_S),
7119 OPC_CMP_EQ_S = FOP (50, FMT_S),
7120 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7121 OPC_CMP_OLT_S = FOP (52, FMT_S),
7122 OPC_CMP_ULT_S = FOP (53, FMT_S),
7123 OPC_CMP_OLE_S = FOP (54, FMT_S),
7124 OPC_CMP_ULE_S = FOP (55, FMT_S),
7125 OPC_CMP_SF_S = FOP (56, FMT_S),
7126 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7127 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7128 OPC_CMP_NGL_S = FOP (59, FMT_S),
7129 OPC_CMP_LT_S = FOP (60, FMT_S),
7130 OPC_CMP_NGE_S = FOP (61, FMT_S),
7131 OPC_CMP_LE_S = FOP (62, FMT_S),
7132 OPC_CMP_NGT_S = FOP (63, FMT_S),
7133
7134 OPC_ADD_D = FOP(0, FMT_D),
7135 OPC_SUB_D = FOP(1, FMT_D),
7136 OPC_MUL_D = FOP(2, FMT_D),
7137 OPC_DIV_D = FOP(3, FMT_D),
7138 OPC_SQRT_D = FOP(4, FMT_D),
7139 OPC_ABS_D = FOP(5, FMT_D),
7140 OPC_MOV_D = FOP(6, FMT_D),
7141 OPC_NEG_D = FOP(7, FMT_D),
7142 OPC_ROUND_L_D = FOP(8, FMT_D),
7143 OPC_TRUNC_L_D = FOP(9, FMT_D),
7144 OPC_CEIL_L_D = FOP(10, FMT_D),
7145 OPC_FLOOR_L_D = FOP(11, FMT_D),
7146 OPC_ROUND_W_D = FOP(12, FMT_D),
7147 OPC_TRUNC_W_D = FOP(13, FMT_D),
7148 OPC_CEIL_W_D = FOP(14, FMT_D),
7149 OPC_FLOOR_W_D = FOP(15, FMT_D),
7150 OPC_MOVCF_D = FOP(17, FMT_D),
7151 OPC_MOVZ_D = FOP(18, FMT_D),
7152 OPC_MOVN_D = FOP(19, FMT_D),
7153 OPC_RECIP_D = FOP(21, FMT_D),
7154 OPC_RSQRT_D = FOP(22, FMT_D),
7155 OPC_RECIP2_D = FOP(28, FMT_D),
7156 OPC_RECIP1_D = FOP(29, FMT_D),
7157 OPC_RSQRT1_D = FOP(30, FMT_D),
7158 OPC_RSQRT2_D = FOP(31, FMT_D),
7159 OPC_CVT_S_D = FOP(32, FMT_D),
7160 OPC_CVT_W_D = FOP(36, FMT_D),
7161 OPC_CVT_L_D = FOP(37, FMT_D),
7162 OPC_CMP_F_D = FOP (48, FMT_D),
7163 OPC_CMP_UN_D = FOP (49, FMT_D),
7164 OPC_CMP_EQ_D = FOP (50, FMT_D),
7165 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7166 OPC_CMP_OLT_D = FOP (52, FMT_D),
7167 OPC_CMP_ULT_D = FOP (53, FMT_D),
7168 OPC_CMP_OLE_D = FOP (54, FMT_D),
7169 OPC_CMP_ULE_D = FOP (55, FMT_D),
7170 OPC_CMP_SF_D = FOP (56, FMT_D),
7171 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7172 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7173 OPC_CMP_NGL_D = FOP (59, FMT_D),
7174 OPC_CMP_LT_D = FOP (60, FMT_D),
7175 OPC_CMP_NGE_D = FOP (61, FMT_D),
7176 OPC_CMP_LE_D = FOP (62, FMT_D),
7177 OPC_CMP_NGT_D = FOP (63, FMT_D),
7178
7179 OPC_CVT_S_W = FOP(32, FMT_W),
7180 OPC_CVT_D_W = FOP(33, FMT_W),
7181 OPC_CVT_S_L = FOP(32, FMT_L),
7182 OPC_CVT_D_L = FOP(33, FMT_L),
7183 OPC_CVT_PS_PW = FOP(38, FMT_W),
7184
7185 OPC_ADD_PS = FOP(0, FMT_PS),
7186 OPC_SUB_PS = FOP(1, FMT_PS),
7187 OPC_MUL_PS = FOP(2, FMT_PS),
7188 OPC_DIV_PS = FOP(3, FMT_PS),
7189 OPC_ABS_PS = FOP(5, FMT_PS),
7190 OPC_MOV_PS = FOP(6, FMT_PS),
7191 OPC_NEG_PS = FOP(7, FMT_PS),
7192 OPC_MOVCF_PS = FOP(17, FMT_PS),
7193 OPC_MOVZ_PS = FOP(18, FMT_PS),
7194 OPC_MOVN_PS = FOP(19, FMT_PS),
7195 OPC_ADDR_PS = FOP(24, FMT_PS),
7196 OPC_MULR_PS = FOP(26, FMT_PS),
7197 OPC_RECIP2_PS = FOP(28, FMT_PS),
7198 OPC_RECIP1_PS = FOP(29, FMT_PS),
7199 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7200 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7201
7202 OPC_CVT_S_PU = FOP(32, FMT_PS),
7203 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7204 OPC_CVT_S_PL = FOP(40, FMT_PS),
7205 OPC_PLL_PS = FOP(44, FMT_PS),
7206 OPC_PLU_PS = FOP(45, FMT_PS),
7207 OPC_PUL_PS = FOP(46, FMT_PS),
7208 OPC_PUU_PS = FOP(47, FMT_PS),
7209 OPC_CMP_F_PS = FOP (48, FMT_PS),
7210 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7211 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7212 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7213 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7214 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7215 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7216 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7217 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7218 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7219 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7220 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7221 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7222 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7223 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7224 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7225};
7226
7a387fff 7227static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7228{
923617a3 7229 const char *opn = "cp1 move";
72c3a3ee 7230 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7231
7232 switch (opc) {
7233 case OPC_MFC1:
b6d96bed 7234 {
a7812ae4 7235 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7236
7237 gen_load_fpr32(fp0, fs);
7238 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7239 tcg_temp_free_i32(fp0);
6958549d 7240 }
6c5c1e20 7241 gen_store_gpr(t0, rt);
6ea83fed
FB
7242 opn = "mfc1";
7243 break;
7244 case OPC_MTC1:
6c5c1e20 7245 gen_load_gpr(t0, rt);
b6d96bed 7246 {
a7812ae4 7247 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7248
7249 tcg_gen_trunc_tl_i32(fp0, t0);
7250 gen_store_fpr32(fp0, fs);
a7812ae4 7251 tcg_temp_free_i32(fp0);
6958549d 7252 }
6ea83fed
FB
7253 opn = "mtc1";
7254 break;
7255 case OPC_CFC1:
895c2d04 7256 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7257 gen_store_gpr(t0, rt);
6ea83fed
FB
7258 opn = "cfc1";
7259 break;
7260 case OPC_CTC1:
6c5c1e20 7261 gen_load_gpr(t0, rt);
736d120a
PJ
7262 {
7263 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7264
7265 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7266 tcg_temp_free_i32(fs_tmp);
7267 }
6ea83fed
FB
7268 opn = "ctc1";
7269 break;
72c3a3ee 7270#if defined(TARGET_MIPS64)
9c2149c8 7271 case OPC_DMFC1:
72c3a3ee 7272 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7273 gen_store_gpr(t0, rt);
5a5012ec
TS
7274 opn = "dmfc1";
7275 break;
9c2149c8 7276 case OPC_DMTC1:
6c5c1e20 7277 gen_load_gpr(t0, rt);
72c3a3ee 7278 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7279 opn = "dmtc1";
7280 break;
72c3a3ee 7281#endif
5a5012ec 7282 case OPC_MFHC1:
b6d96bed 7283 {
a7812ae4 7284 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7285
7286 gen_load_fpr32h(fp0, fs);
7287 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7288 tcg_temp_free_i32(fp0);
6958549d 7289 }
6c5c1e20 7290 gen_store_gpr(t0, rt);
5a5012ec
TS
7291 opn = "mfhc1";
7292 break;
7293 case OPC_MTHC1:
6c5c1e20 7294 gen_load_gpr(t0, rt);
b6d96bed 7295 {
a7812ae4 7296 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7297
7298 tcg_gen_trunc_tl_i32(fp0, t0);
7299 gen_store_fpr32h(fp0, fs);
a7812ae4 7300 tcg_temp_free_i32(fp0);
6958549d 7301 }
5a5012ec
TS
7302 opn = "mthc1";
7303 break;
6ea83fed 7304 default:
923617a3 7305 MIPS_INVAL(opn);
e397ee33 7306 generate_exception (ctx, EXCP_RI);
6c5c1e20 7307 goto out;
6ea83fed 7308 }
2abf314d 7309 (void)opn; /* avoid a compiler warning */
6ea83fed 7310 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7311
7312 out:
7313 tcg_temp_free(t0);
6ea83fed
FB
7314}
7315
5a5012ec
TS
7316static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7317{
af58f9ca 7318 int l1;
e214b9bb 7319 TCGCond cond;
af58f9ca
AJ
7320 TCGv_i32 t0;
7321
7322 if (rd == 0) {
7323 /* Treat as NOP. */
7324 return;
7325 }
6ea83fed 7326
e214b9bb 7327 if (tf)
e214b9bb 7328 cond = TCG_COND_EQ;
27848470
TS
7329 else
7330 cond = TCG_COND_NE;
7331
af58f9ca
AJ
7332 l1 = gen_new_label();
7333 t0 = tcg_temp_new_i32();
fa31af0e 7334 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7335 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7336 tcg_temp_free_i32(t0);
af58f9ca
AJ
7337 if (rs == 0) {
7338 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7339 } else {
7340 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7341 }
e214b9bb 7342 gen_set_label(l1);
5a5012ec
TS
7343}
7344
b6d96bed 7345static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7346{
a16336e4 7347 int cond;
cbc37b28 7348 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7349 int l1 = gen_new_label();
7350
a16336e4
TS
7351 if (tf)
7352 cond = TCG_COND_EQ;
7353 else
7354 cond = TCG_COND_NE;
7355
fa31af0e 7356 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7357 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7358 gen_load_fpr32(t0, fs);
7359 gen_store_fpr32(t0, fd);
a16336e4 7360 gen_set_label(l1);
cbc37b28 7361 tcg_temp_free_i32(t0);
5a5012ec 7362}
a16336e4 7363
b6d96bed 7364static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7365{
a16336e4 7366 int cond;
cbc37b28
AJ
7367 TCGv_i32 t0 = tcg_temp_new_i32();
7368 TCGv_i64 fp0;
a16336e4
TS
7369 int l1 = gen_new_label();
7370
a16336e4
TS
7371 if (tf)
7372 cond = TCG_COND_EQ;
7373 else
7374 cond = TCG_COND_NE;
7375
fa31af0e 7376 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7377 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7378 tcg_temp_free_i32(t0);
11f94258 7379 fp0 = tcg_temp_new_i64();
9bf3eb2c 7380 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7381 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7382 tcg_temp_free_i64(fp0);
cbc37b28 7383 gen_set_label(l1);
a16336e4
TS
7384}
7385
b6d96bed 7386static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
a16336e4
TS
7387{
7388 int cond;
cbc37b28 7389 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7390 int l1 = gen_new_label();
7391 int l2 = gen_new_label();
7392
7393 if (tf)
7394 cond = TCG_COND_EQ;
7395 else
7396 cond = TCG_COND_NE;
7397
fa31af0e 7398 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7399 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7400 gen_load_fpr32(t0, fs);
7401 gen_store_fpr32(t0, fd);
a16336e4 7402 gen_set_label(l1);
9bf3eb2c 7403
fa31af0e 7404 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28
AJ
7405 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7406 gen_load_fpr32h(t0, fs);
7407 gen_store_fpr32h(t0, fd);
52a0e9eb 7408 tcg_temp_free_i32(t0);
a16336e4 7409 gen_set_label(l2);
a16336e4
TS
7410}
7411
6ea83fed 7412
bf4120ad 7413static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7414 int ft, int fs, int fd, int cc)
6ea83fed 7415{
923617a3 7416 const char *opn = "farith";
6ea83fed
FB
7417 const char *condnames[] = {
7418 "c.f",
7419 "c.un",
7420 "c.eq",
7421 "c.ueq",
7422 "c.olt",
7423 "c.ult",
7424 "c.ole",
7425 "c.ule",
7426 "c.sf",
7427 "c.ngle",
7428 "c.seq",
7429 "c.ngl",
7430 "c.lt",
7431 "c.nge",
7432 "c.le",
7433 "c.ngt",
7434 };
5a1e8ffb
TS
7435 const char *condnames_abs[] = {
7436 "cabs.f",
7437 "cabs.un",
7438 "cabs.eq",
7439 "cabs.ueq",
7440 "cabs.olt",
7441 "cabs.ult",
7442 "cabs.ole",
7443 "cabs.ule",
7444 "cabs.sf",
7445 "cabs.ngle",
7446 "cabs.seq",
7447 "cabs.ngl",
7448 "cabs.lt",
7449 "cabs.nge",
7450 "cabs.le",
7451 "cabs.ngt",
7452 };
7453 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7454 uint32_t func = ctx->opcode & 0x3f;
7455
bf4120ad
NF
7456 switch (op1) {
7457 case OPC_ADD_S:
b6d96bed 7458 {
a7812ae4
PB
7459 TCGv_i32 fp0 = tcg_temp_new_i32();
7460 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7461
7462 gen_load_fpr32(fp0, fs);
7463 gen_load_fpr32(fp1, ft);
895c2d04 7464 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7465 tcg_temp_free_i32(fp1);
b6d96bed 7466 gen_store_fpr32(fp0, fd);
a7812ae4 7467 tcg_temp_free_i32(fp0);
b6d96bed 7468 }
5a5012ec 7469 opn = "add.s";
5a1e8ffb 7470 optype = BINOP;
5a5012ec 7471 break;
bf4120ad 7472 case OPC_SUB_S:
b6d96bed 7473 {
a7812ae4
PB
7474 TCGv_i32 fp0 = tcg_temp_new_i32();
7475 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7476
7477 gen_load_fpr32(fp0, fs);
7478 gen_load_fpr32(fp1, ft);
895c2d04 7479 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7480 tcg_temp_free_i32(fp1);
b6d96bed 7481 gen_store_fpr32(fp0, fd);
a7812ae4 7482 tcg_temp_free_i32(fp0);
b6d96bed 7483 }
5a5012ec 7484 opn = "sub.s";
5a1e8ffb 7485 optype = BINOP;
5a5012ec 7486 break;
bf4120ad 7487 case OPC_MUL_S:
b6d96bed 7488 {
a7812ae4
PB
7489 TCGv_i32 fp0 = tcg_temp_new_i32();
7490 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7491
7492 gen_load_fpr32(fp0, fs);
7493 gen_load_fpr32(fp1, ft);
895c2d04 7494 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7495 tcg_temp_free_i32(fp1);
b6d96bed 7496 gen_store_fpr32(fp0, fd);
a7812ae4 7497 tcg_temp_free_i32(fp0);
b6d96bed 7498 }
5a5012ec 7499 opn = "mul.s";
5a1e8ffb 7500 optype = BINOP;
5a5012ec 7501 break;
bf4120ad 7502 case OPC_DIV_S:
b6d96bed 7503 {
a7812ae4
PB
7504 TCGv_i32 fp0 = tcg_temp_new_i32();
7505 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7506
7507 gen_load_fpr32(fp0, fs);
7508 gen_load_fpr32(fp1, ft);
895c2d04 7509 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7510 tcg_temp_free_i32(fp1);
b6d96bed 7511 gen_store_fpr32(fp0, fd);
a7812ae4 7512 tcg_temp_free_i32(fp0);
b6d96bed 7513 }
5a5012ec 7514 opn = "div.s";
5a1e8ffb 7515 optype = BINOP;
5a5012ec 7516 break;
bf4120ad 7517 case OPC_SQRT_S:
b6d96bed 7518 {
a7812ae4 7519 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7520
7521 gen_load_fpr32(fp0, fs);
895c2d04 7522 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7523 gen_store_fpr32(fp0, fd);
a7812ae4 7524 tcg_temp_free_i32(fp0);
b6d96bed 7525 }
5a5012ec
TS
7526 opn = "sqrt.s";
7527 break;
bf4120ad 7528 case OPC_ABS_S:
b6d96bed 7529 {
a7812ae4 7530 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7531
7532 gen_load_fpr32(fp0, fs);
a7812ae4 7533 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7534 gen_store_fpr32(fp0, fd);
a7812ae4 7535 tcg_temp_free_i32(fp0);
b6d96bed 7536 }
5a5012ec
TS
7537 opn = "abs.s";
7538 break;
bf4120ad 7539 case OPC_MOV_S:
b6d96bed 7540 {
a7812ae4 7541 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7542
7543 gen_load_fpr32(fp0, fs);
7544 gen_store_fpr32(fp0, fd);
a7812ae4 7545 tcg_temp_free_i32(fp0);
b6d96bed 7546 }
5a5012ec
TS
7547 opn = "mov.s";
7548 break;
bf4120ad 7549 case OPC_NEG_S:
b6d96bed 7550 {
a7812ae4 7551 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7552
7553 gen_load_fpr32(fp0, fs);
a7812ae4 7554 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7555 gen_store_fpr32(fp0, fd);
a7812ae4 7556 tcg_temp_free_i32(fp0);
b6d96bed 7557 }
5a5012ec
TS
7558 opn = "neg.s";
7559 break;
bf4120ad 7560 case OPC_ROUND_L_S:
5e755519 7561 check_cp1_64bitmode(ctx);
b6d96bed 7562 {
a7812ae4
PB
7563 TCGv_i32 fp32 = tcg_temp_new_i32();
7564 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7565
7566 gen_load_fpr32(fp32, fs);
895c2d04 7567 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7568 tcg_temp_free_i32(fp32);
b6d96bed 7569 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7570 tcg_temp_free_i64(fp64);
b6d96bed 7571 }
5a5012ec
TS
7572 opn = "round.l.s";
7573 break;
bf4120ad 7574 case OPC_TRUNC_L_S:
5e755519 7575 check_cp1_64bitmode(ctx);
b6d96bed 7576 {
a7812ae4
PB
7577 TCGv_i32 fp32 = tcg_temp_new_i32();
7578 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7579
7580 gen_load_fpr32(fp32, fs);
895c2d04 7581 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7582 tcg_temp_free_i32(fp32);
b6d96bed 7583 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7584 tcg_temp_free_i64(fp64);
b6d96bed 7585 }
5a5012ec
TS
7586 opn = "trunc.l.s";
7587 break;
bf4120ad 7588 case OPC_CEIL_L_S:
5e755519 7589 check_cp1_64bitmode(ctx);
b6d96bed 7590 {
a7812ae4
PB
7591 TCGv_i32 fp32 = tcg_temp_new_i32();
7592 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7593
7594 gen_load_fpr32(fp32, fs);
895c2d04 7595 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7596 tcg_temp_free_i32(fp32);
b6d96bed 7597 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7598 tcg_temp_free_i64(fp64);
b6d96bed 7599 }
5a5012ec
TS
7600 opn = "ceil.l.s";
7601 break;
bf4120ad 7602 case OPC_FLOOR_L_S:
5e755519 7603 check_cp1_64bitmode(ctx);
b6d96bed 7604 {
a7812ae4
PB
7605 TCGv_i32 fp32 = tcg_temp_new_i32();
7606 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7607
7608 gen_load_fpr32(fp32, fs);
895c2d04 7609 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7610 tcg_temp_free_i32(fp32);
b6d96bed 7611 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7612 tcg_temp_free_i64(fp64);
b6d96bed 7613 }
5a5012ec
TS
7614 opn = "floor.l.s";
7615 break;
bf4120ad 7616 case OPC_ROUND_W_S:
b6d96bed 7617 {
a7812ae4 7618 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7619
7620 gen_load_fpr32(fp0, fs);
895c2d04 7621 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7622 gen_store_fpr32(fp0, fd);
a7812ae4 7623 tcg_temp_free_i32(fp0);
b6d96bed 7624 }
5a5012ec
TS
7625 opn = "round.w.s";
7626 break;
bf4120ad 7627 case OPC_TRUNC_W_S:
b6d96bed 7628 {
a7812ae4 7629 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7630
7631 gen_load_fpr32(fp0, fs);
895c2d04 7632 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7633 gen_store_fpr32(fp0, fd);
a7812ae4 7634 tcg_temp_free_i32(fp0);
b6d96bed 7635 }
5a5012ec
TS
7636 opn = "trunc.w.s";
7637 break;
bf4120ad 7638 case OPC_CEIL_W_S:
b6d96bed 7639 {
a7812ae4 7640 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7641
7642 gen_load_fpr32(fp0, fs);
895c2d04 7643 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7644 gen_store_fpr32(fp0, fd);
a7812ae4 7645 tcg_temp_free_i32(fp0);
b6d96bed 7646 }
5a5012ec
TS
7647 opn = "ceil.w.s";
7648 break;
bf4120ad 7649 case OPC_FLOOR_W_S:
b6d96bed 7650 {
a7812ae4 7651 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7652
7653 gen_load_fpr32(fp0, fs);
895c2d04 7654 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7655 gen_store_fpr32(fp0, fd);
a7812ae4 7656 tcg_temp_free_i32(fp0);
b6d96bed 7657 }
5a5012ec
TS
7658 opn = "floor.w.s";
7659 break;
bf4120ad 7660 case OPC_MOVCF_S:
b6d96bed 7661 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7662 opn = "movcf.s";
7663 break;
bf4120ad 7664 case OPC_MOVZ_S:
a16336e4
TS
7665 {
7666 int l1 = gen_new_label();
c9297f4d 7667 TCGv_i32 fp0;
a16336e4 7668
c9297f4d
AJ
7669 if (ft != 0) {
7670 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7671 }
7672 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7673 gen_load_fpr32(fp0, fs);
7674 gen_store_fpr32(fp0, fd);
a7812ae4 7675 tcg_temp_free_i32(fp0);
a16336e4
TS
7676 gen_set_label(l1);
7677 }
5a5012ec
TS
7678 opn = "movz.s";
7679 break;
bf4120ad 7680 case OPC_MOVN_S:
a16336e4
TS
7681 {
7682 int l1 = gen_new_label();
c9297f4d
AJ
7683 TCGv_i32 fp0;
7684
7685 if (ft != 0) {
7686 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7687 fp0 = tcg_temp_new_i32();
7688 gen_load_fpr32(fp0, fs);
7689 gen_store_fpr32(fp0, fd);
7690 tcg_temp_free_i32(fp0);
7691 gen_set_label(l1);
7692 }
a16336e4 7693 }
5a5012ec
TS
7694 opn = "movn.s";
7695 break;
bf4120ad 7696 case OPC_RECIP_S:
b8aa4598 7697 check_cop1x(ctx);
b6d96bed 7698 {
a7812ae4 7699 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7700
7701 gen_load_fpr32(fp0, fs);
895c2d04 7702 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 7703 gen_store_fpr32(fp0, fd);
a7812ae4 7704 tcg_temp_free_i32(fp0);
b6d96bed 7705 }
57fa1fb3
TS
7706 opn = "recip.s";
7707 break;
bf4120ad 7708 case OPC_RSQRT_S:
b8aa4598 7709 check_cop1x(ctx);
b6d96bed 7710 {
a7812ae4 7711 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7712
7713 gen_load_fpr32(fp0, fs);
895c2d04 7714 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7715 gen_store_fpr32(fp0, fd);
a7812ae4 7716 tcg_temp_free_i32(fp0);
b6d96bed 7717 }
57fa1fb3
TS
7718 opn = "rsqrt.s";
7719 break;
bf4120ad 7720 case OPC_RECIP2_S:
5e755519 7721 check_cp1_64bitmode(ctx);
b6d96bed 7722 {
a7812ae4
PB
7723 TCGv_i32 fp0 = tcg_temp_new_i32();
7724 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7725
7726 gen_load_fpr32(fp0, fs);
d22d7289 7727 gen_load_fpr32(fp1, ft);
895c2d04 7728 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7729 tcg_temp_free_i32(fp1);
b6d96bed 7730 gen_store_fpr32(fp0, fd);
a7812ae4 7731 tcg_temp_free_i32(fp0);
b6d96bed 7732 }
57fa1fb3
TS
7733 opn = "recip2.s";
7734 break;
bf4120ad 7735 case OPC_RECIP1_S:
5e755519 7736 check_cp1_64bitmode(ctx);
b6d96bed 7737 {
a7812ae4 7738 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7739
7740 gen_load_fpr32(fp0, fs);
895c2d04 7741 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7742 gen_store_fpr32(fp0, fd);
a7812ae4 7743 tcg_temp_free_i32(fp0);
b6d96bed 7744 }
57fa1fb3
TS
7745 opn = "recip1.s";
7746 break;
bf4120ad 7747 case OPC_RSQRT1_S:
5e755519 7748 check_cp1_64bitmode(ctx);
b6d96bed 7749 {
a7812ae4 7750 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7751
7752 gen_load_fpr32(fp0, fs);
895c2d04 7753 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7754 gen_store_fpr32(fp0, fd);
a7812ae4 7755 tcg_temp_free_i32(fp0);
b6d96bed 7756 }
57fa1fb3
TS
7757 opn = "rsqrt1.s";
7758 break;
bf4120ad 7759 case OPC_RSQRT2_S:
5e755519 7760 check_cp1_64bitmode(ctx);
b6d96bed 7761 {
a7812ae4
PB
7762 TCGv_i32 fp0 = tcg_temp_new_i32();
7763 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7764
7765 gen_load_fpr32(fp0, fs);
7766 gen_load_fpr32(fp1, ft);
895c2d04 7767 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7768 tcg_temp_free_i32(fp1);
b6d96bed 7769 gen_store_fpr32(fp0, fd);
a7812ae4 7770 tcg_temp_free_i32(fp0);
b6d96bed 7771 }
57fa1fb3
TS
7772 opn = "rsqrt2.s";
7773 break;
bf4120ad 7774 case OPC_CVT_D_S:
5e755519 7775 check_cp1_registers(ctx, fd);
b6d96bed 7776 {
a7812ae4
PB
7777 TCGv_i32 fp32 = tcg_temp_new_i32();
7778 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7779
7780 gen_load_fpr32(fp32, fs);
895c2d04 7781 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7782 tcg_temp_free_i32(fp32);
b6d96bed 7783 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7784 tcg_temp_free_i64(fp64);
b6d96bed 7785 }
5a5012ec
TS
7786 opn = "cvt.d.s";
7787 break;
bf4120ad 7788 case OPC_CVT_W_S:
b6d96bed 7789 {
a7812ae4 7790 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7791
7792 gen_load_fpr32(fp0, fs);
895c2d04 7793 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7794 gen_store_fpr32(fp0, fd);
a7812ae4 7795 tcg_temp_free_i32(fp0);
b6d96bed 7796 }
5a5012ec
TS
7797 opn = "cvt.w.s";
7798 break;
bf4120ad 7799 case OPC_CVT_L_S:
5e755519 7800 check_cp1_64bitmode(ctx);
b6d96bed 7801 {
a7812ae4
PB
7802 TCGv_i32 fp32 = tcg_temp_new_i32();
7803 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7804
7805 gen_load_fpr32(fp32, fs);
895c2d04 7806 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7807 tcg_temp_free_i32(fp32);
b6d96bed 7808 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7809 tcg_temp_free_i64(fp64);
b6d96bed 7810 }
5a5012ec
TS
7811 opn = "cvt.l.s";
7812 break;
bf4120ad 7813 case OPC_CVT_PS_S:
5e755519 7814 check_cp1_64bitmode(ctx);
b6d96bed 7815 {
a7812ae4
PB
7816 TCGv_i64 fp64 = tcg_temp_new_i64();
7817 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7818 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7819
7820 gen_load_fpr32(fp32_0, fs);
7821 gen_load_fpr32(fp32_1, ft);
13d24f49 7822 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7823 tcg_temp_free_i32(fp32_1);
7824 tcg_temp_free_i32(fp32_0);
36aa55dc 7825 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7826 tcg_temp_free_i64(fp64);
b6d96bed 7827 }
5a5012ec
TS
7828 opn = "cvt.ps.s";
7829 break;
bf4120ad
NF
7830 case OPC_CMP_F_S:
7831 case OPC_CMP_UN_S:
7832 case OPC_CMP_EQ_S:
7833 case OPC_CMP_UEQ_S:
7834 case OPC_CMP_OLT_S:
7835 case OPC_CMP_ULT_S:
7836 case OPC_CMP_OLE_S:
7837 case OPC_CMP_ULE_S:
7838 case OPC_CMP_SF_S:
7839 case OPC_CMP_NGLE_S:
7840 case OPC_CMP_SEQ_S:
7841 case OPC_CMP_NGL_S:
7842 case OPC_CMP_LT_S:
7843 case OPC_CMP_NGE_S:
7844 case OPC_CMP_LE_S:
7845 case OPC_CMP_NGT_S:
8153667c
NF
7846 if (ctx->opcode & (1 << 6)) {
7847 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7848 opn = condnames_abs[func-48];
7849 } else {
7850 gen_cmp_s(ctx, func-48, ft, fs, cc);
7851 opn = condnames[func-48];
5a1e8ffb 7852 }
5a5012ec 7853 break;
bf4120ad 7854 case OPC_ADD_D:
5e755519 7855 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7856 {
a7812ae4
PB
7857 TCGv_i64 fp0 = tcg_temp_new_i64();
7858 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7859
7860 gen_load_fpr64(ctx, fp0, fs);
7861 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7862 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7863 tcg_temp_free_i64(fp1);
b6d96bed 7864 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7865 tcg_temp_free_i64(fp0);
b6d96bed 7866 }
6ea83fed 7867 opn = "add.d";
5a1e8ffb 7868 optype = BINOP;
6ea83fed 7869 break;
bf4120ad 7870 case OPC_SUB_D:
5e755519 7871 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7872 {
a7812ae4
PB
7873 TCGv_i64 fp0 = tcg_temp_new_i64();
7874 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7875
7876 gen_load_fpr64(ctx, fp0, fs);
7877 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7878 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7879 tcg_temp_free_i64(fp1);
b6d96bed 7880 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7881 tcg_temp_free_i64(fp0);
b6d96bed 7882 }
6ea83fed 7883 opn = "sub.d";
5a1e8ffb 7884 optype = BINOP;
6ea83fed 7885 break;
bf4120ad 7886 case OPC_MUL_D:
5e755519 7887 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7888 {
a7812ae4
PB
7889 TCGv_i64 fp0 = tcg_temp_new_i64();
7890 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7891
7892 gen_load_fpr64(ctx, fp0, fs);
7893 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7894 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7895 tcg_temp_free_i64(fp1);
b6d96bed 7896 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7897 tcg_temp_free_i64(fp0);
b6d96bed 7898 }
6ea83fed 7899 opn = "mul.d";
5a1e8ffb 7900 optype = BINOP;
6ea83fed 7901 break;
bf4120ad 7902 case OPC_DIV_D:
5e755519 7903 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7904 {
a7812ae4
PB
7905 TCGv_i64 fp0 = tcg_temp_new_i64();
7906 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7907
7908 gen_load_fpr64(ctx, fp0, fs);
7909 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7910 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7911 tcg_temp_free_i64(fp1);
b6d96bed 7912 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7913 tcg_temp_free_i64(fp0);
b6d96bed 7914 }
6ea83fed 7915 opn = "div.d";
5a1e8ffb 7916 optype = BINOP;
6ea83fed 7917 break;
bf4120ad 7918 case OPC_SQRT_D:
5e755519 7919 check_cp1_registers(ctx, fs | fd);
b6d96bed 7920 {
a7812ae4 7921 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7922
7923 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7924 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7925 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7926 tcg_temp_free_i64(fp0);
b6d96bed 7927 }
6ea83fed
FB
7928 opn = "sqrt.d";
7929 break;
bf4120ad 7930 case OPC_ABS_D:
5e755519 7931 check_cp1_registers(ctx, fs | fd);
b6d96bed 7932 {
a7812ae4 7933 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7934
7935 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7936 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7937 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7938 tcg_temp_free_i64(fp0);
b6d96bed 7939 }
6ea83fed
FB
7940 opn = "abs.d";
7941 break;
bf4120ad 7942 case OPC_MOV_D:
5e755519 7943 check_cp1_registers(ctx, fs | fd);
b6d96bed 7944 {
a7812ae4 7945 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7946
7947 gen_load_fpr64(ctx, fp0, fs);
7948 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7949 tcg_temp_free_i64(fp0);
b6d96bed 7950 }
6ea83fed
FB
7951 opn = "mov.d";
7952 break;
bf4120ad 7953 case OPC_NEG_D:
5e755519 7954 check_cp1_registers(ctx, fs | fd);
b6d96bed 7955 {
a7812ae4 7956 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7957
7958 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7959 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 7960 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7961 tcg_temp_free_i64(fp0);
b6d96bed 7962 }
6ea83fed
FB
7963 opn = "neg.d";
7964 break;
bf4120ad 7965 case OPC_ROUND_L_D:
5e755519 7966 check_cp1_64bitmode(ctx);
b6d96bed 7967 {
a7812ae4 7968 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7969
7970 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7971 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 7972 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7973 tcg_temp_free_i64(fp0);
b6d96bed 7974 }
5a5012ec
TS
7975 opn = "round.l.d";
7976 break;
bf4120ad 7977 case OPC_TRUNC_L_D:
5e755519 7978 check_cp1_64bitmode(ctx);
b6d96bed 7979 {
a7812ae4 7980 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7981
7982 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7983 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 7984 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7985 tcg_temp_free_i64(fp0);
b6d96bed 7986 }
5a5012ec
TS
7987 opn = "trunc.l.d";
7988 break;
bf4120ad 7989 case OPC_CEIL_L_D:
5e755519 7990 check_cp1_64bitmode(ctx);
b6d96bed 7991 {
a7812ae4 7992 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7993
7994 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7995 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 7996 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7997 tcg_temp_free_i64(fp0);
b6d96bed 7998 }
5a5012ec
TS
7999 opn = "ceil.l.d";
8000 break;
bf4120ad 8001 case OPC_FLOOR_L_D:
5e755519 8002 check_cp1_64bitmode(ctx);
b6d96bed 8003 {
a7812ae4 8004 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8005
8006 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8007 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8008 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8009 tcg_temp_free_i64(fp0);
b6d96bed 8010 }
5a5012ec
TS
8011 opn = "floor.l.d";
8012 break;
bf4120ad 8013 case OPC_ROUND_W_D:
5e755519 8014 check_cp1_registers(ctx, fs);
b6d96bed 8015 {
a7812ae4
PB
8016 TCGv_i32 fp32 = tcg_temp_new_i32();
8017 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8018
8019 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8020 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8021 tcg_temp_free_i64(fp64);
b6d96bed 8022 gen_store_fpr32(fp32, fd);
a7812ae4 8023 tcg_temp_free_i32(fp32);
b6d96bed 8024 }
6ea83fed
FB
8025 opn = "round.w.d";
8026 break;
bf4120ad 8027 case OPC_TRUNC_W_D:
5e755519 8028 check_cp1_registers(ctx, fs);
b6d96bed 8029 {
a7812ae4
PB
8030 TCGv_i32 fp32 = tcg_temp_new_i32();
8031 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8032
8033 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8034 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8035 tcg_temp_free_i64(fp64);
b6d96bed 8036 gen_store_fpr32(fp32, fd);
a7812ae4 8037 tcg_temp_free_i32(fp32);
b6d96bed 8038 }
6ea83fed
FB
8039 opn = "trunc.w.d";
8040 break;
bf4120ad 8041 case OPC_CEIL_W_D:
5e755519 8042 check_cp1_registers(ctx, fs);
b6d96bed 8043 {
a7812ae4
PB
8044 TCGv_i32 fp32 = tcg_temp_new_i32();
8045 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8046
8047 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8048 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8049 tcg_temp_free_i64(fp64);
b6d96bed 8050 gen_store_fpr32(fp32, fd);
a7812ae4 8051 tcg_temp_free_i32(fp32);
b6d96bed 8052 }
6ea83fed
FB
8053 opn = "ceil.w.d";
8054 break;
bf4120ad 8055 case OPC_FLOOR_W_D:
5e755519 8056 check_cp1_registers(ctx, fs);
b6d96bed 8057 {
a7812ae4
PB
8058 TCGv_i32 fp32 = tcg_temp_new_i32();
8059 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8060
8061 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8062 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8063 tcg_temp_free_i64(fp64);
b6d96bed 8064 gen_store_fpr32(fp32, fd);
a7812ae4 8065 tcg_temp_free_i32(fp32);
b6d96bed 8066 }
7a387fff 8067 opn = "floor.w.d";
6ea83fed 8068 break;
bf4120ad 8069 case OPC_MOVCF_D:
b6d96bed 8070 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8071 opn = "movcf.d";
dd016883 8072 break;
bf4120ad 8073 case OPC_MOVZ_D:
a16336e4
TS
8074 {
8075 int l1 = gen_new_label();
c9297f4d 8076 TCGv_i64 fp0;
a16336e4 8077
c9297f4d
AJ
8078 if (ft != 0) {
8079 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8080 }
8081 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8082 gen_load_fpr64(ctx, fp0, fs);
8083 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8084 tcg_temp_free_i64(fp0);
a16336e4
TS
8085 gen_set_label(l1);
8086 }
5a5012ec
TS
8087 opn = "movz.d";
8088 break;
bf4120ad 8089 case OPC_MOVN_D:
a16336e4
TS
8090 {
8091 int l1 = gen_new_label();
c9297f4d
AJ
8092 TCGv_i64 fp0;
8093
8094 if (ft != 0) {
8095 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8096 fp0 = tcg_temp_new_i64();
8097 gen_load_fpr64(ctx, fp0, fs);
8098 gen_store_fpr64(ctx, fp0, fd);
8099 tcg_temp_free_i64(fp0);
8100 gen_set_label(l1);
8101 }
a16336e4 8102 }
5a5012ec 8103 opn = "movn.d";
6ea83fed 8104 break;
bf4120ad 8105 case OPC_RECIP_D:
b8aa4598 8106 check_cp1_64bitmode(ctx);
b6d96bed 8107 {
a7812ae4 8108 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8109
8110 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8111 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8112 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8113 tcg_temp_free_i64(fp0);
b6d96bed 8114 }
57fa1fb3
TS
8115 opn = "recip.d";
8116 break;
bf4120ad 8117 case OPC_RSQRT_D:
b8aa4598 8118 check_cp1_64bitmode(ctx);
b6d96bed 8119 {
a7812ae4 8120 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8121
8122 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8123 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8124 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8125 tcg_temp_free_i64(fp0);
b6d96bed 8126 }
57fa1fb3
TS
8127 opn = "rsqrt.d";
8128 break;
bf4120ad 8129 case OPC_RECIP2_D:
5e755519 8130 check_cp1_64bitmode(ctx);
b6d96bed 8131 {
a7812ae4
PB
8132 TCGv_i64 fp0 = tcg_temp_new_i64();
8133 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8134
8135 gen_load_fpr64(ctx, fp0, fs);
8136 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8137 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8138 tcg_temp_free_i64(fp1);
b6d96bed 8139 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8140 tcg_temp_free_i64(fp0);
b6d96bed 8141 }
57fa1fb3
TS
8142 opn = "recip2.d";
8143 break;
bf4120ad 8144 case OPC_RECIP1_D:
5e755519 8145 check_cp1_64bitmode(ctx);
b6d96bed 8146 {
a7812ae4 8147 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8148
8149 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8150 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8151 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8152 tcg_temp_free_i64(fp0);
b6d96bed 8153 }
57fa1fb3
TS
8154 opn = "recip1.d";
8155 break;
bf4120ad 8156 case OPC_RSQRT1_D:
5e755519 8157 check_cp1_64bitmode(ctx);
b6d96bed 8158 {
a7812ae4 8159 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8160
8161 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8162 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8163 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8164 tcg_temp_free_i64(fp0);
b6d96bed 8165 }
57fa1fb3
TS
8166 opn = "rsqrt1.d";
8167 break;
bf4120ad 8168 case OPC_RSQRT2_D:
5e755519 8169 check_cp1_64bitmode(ctx);
b6d96bed 8170 {
a7812ae4
PB
8171 TCGv_i64 fp0 = tcg_temp_new_i64();
8172 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8173
8174 gen_load_fpr64(ctx, fp0, fs);
8175 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8176 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8177 tcg_temp_free_i64(fp1);
b6d96bed 8178 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8179 tcg_temp_free_i64(fp0);
b6d96bed 8180 }
57fa1fb3
TS
8181 opn = "rsqrt2.d";
8182 break;
bf4120ad
NF
8183 case OPC_CMP_F_D:
8184 case OPC_CMP_UN_D:
8185 case OPC_CMP_EQ_D:
8186 case OPC_CMP_UEQ_D:
8187 case OPC_CMP_OLT_D:
8188 case OPC_CMP_ULT_D:
8189 case OPC_CMP_OLE_D:
8190 case OPC_CMP_ULE_D:
8191 case OPC_CMP_SF_D:
8192 case OPC_CMP_NGLE_D:
8193 case OPC_CMP_SEQ_D:
8194 case OPC_CMP_NGL_D:
8195 case OPC_CMP_LT_D:
8196 case OPC_CMP_NGE_D:
8197 case OPC_CMP_LE_D:
8198 case OPC_CMP_NGT_D:
8153667c
NF
8199 if (ctx->opcode & (1 << 6)) {
8200 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8201 opn = condnames_abs[func-48];
8202 } else {
8203 gen_cmp_d(ctx, func-48, ft, fs, cc);
8204 opn = condnames[func-48];
5a1e8ffb 8205 }
6ea83fed 8206 break;
bf4120ad 8207 case OPC_CVT_S_D:
5e755519 8208 check_cp1_registers(ctx, fs);
b6d96bed 8209 {
a7812ae4
PB
8210 TCGv_i32 fp32 = tcg_temp_new_i32();
8211 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8212
8213 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8214 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8215 tcg_temp_free_i64(fp64);
b6d96bed 8216 gen_store_fpr32(fp32, fd);
a7812ae4 8217 tcg_temp_free_i32(fp32);
b6d96bed 8218 }
5a5012ec
TS
8219 opn = "cvt.s.d";
8220 break;
bf4120ad 8221 case OPC_CVT_W_D:
5e755519 8222 check_cp1_registers(ctx, fs);
b6d96bed 8223 {
a7812ae4
PB
8224 TCGv_i32 fp32 = tcg_temp_new_i32();
8225 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8226
8227 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8228 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8229 tcg_temp_free_i64(fp64);
b6d96bed 8230 gen_store_fpr32(fp32, fd);
a7812ae4 8231 tcg_temp_free_i32(fp32);
b6d96bed 8232 }
5a5012ec
TS
8233 opn = "cvt.w.d";
8234 break;
bf4120ad 8235 case OPC_CVT_L_D:
5e755519 8236 check_cp1_64bitmode(ctx);
b6d96bed 8237 {
a7812ae4 8238 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8239
8240 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8241 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8242 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8243 tcg_temp_free_i64(fp0);
b6d96bed 8244 }
5a5012ec
TS
8245 opn = "cvt.l.d";
8246 break;
bf4120ad 8247 case OPC_CVT_S_W:
b6d96bed 8248 {
a7812ae4 8249 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8250
8251 gen_load_fpr32(fp0, fs);
895c2d04 8252 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8253 gen_store_fpr32(fp0, fd);
a7812ae4 8254 tcg_temp_free_i32(fp0);
b6d96bed 8255 }
5a5012ec 8256 opn = "cvt.s.w";
6ea83fed 8257 break;
bf4120ad 8258 case OPC_CVT_D_W:
5e755519 8259 check_cp1_registers(ctx, fd);
b6d96bed 8260 {
a7812ae4
PB
8261 TCGv_i32 fp32 = tcg_temp_new_i32();
8262 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8263
8264 gen_load_fpr32(fp32, fs);
895c2d04 8265 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8266 tcg_temp_free_i32(fp32);
b6d96bed 8267 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8268 tcg_temp_free_i64(fp64);
b6d96bed 8269 }
5a5012ec
TS
8270 opn = "cvt.d.w";
8271 break;
bf4120ad 8272 case OPC_CVT_S_L:
5e755519 8273 check_cp1_64bitmode(ctx);
b6d96bed 8274 {
a7812ae4
PB
8275 TCGv_i32 fp32 = tcg_temp_new_i32();
8276 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8277
8278 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8279 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8280 tcg_temp_free_i64(fp64);
b6d96bed 8281 gen_store_fpr32(fp32, fd);
a7812ae4 8282 tcg_temp_free_i32(fp32);
b6d96bed 8283 }
5a5012ec
TS
8284 opn = "cvt.s.l";
8285 break;
bf4120ad 8286 case OPC_CVT_D_L:
5e755519 8287 check_cp1_64bitmode(ctx);
b6d96bed 8288 {
a7812ae4 8289 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8290
8291 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8292 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8293 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8294 tcg_temp_free_i64(fp0);
b6d96bed 8295 }
5a5012ec
TS
8296 opn = "cvt.d.l";
8297 break;
bf4120ad 8298 case OPC_CVT_PS_PW:
5e755519 8299 check_cp1_64bitmode(ctx);
b6d96bed 8300 {
a7812ae4 8301 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8302
8303 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8304 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8305 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8306 tcg_temp_free_i64(fp0);
b6d96bed 8307 }
5a5012ec
TS
8308 opn = "cvt.ps.pw";
8309 break;
bf4120ad 8310 case OPC_ADD_PS:
5e755519 8311 check_cp1_64bitmode(ctx);
b6d96bed 8312 {
a7812ae4
PB
8313 TCGv_i64 fp0 = tcg_temp_new_i64();
8314 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8315
8316 gen_load_fpr64(ctx, fp0, fs);
8317 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8318 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8319 tcg_temp_free_i64(fp1);
b6d96bed 8320 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8321 tcg_temp_free_i64(fp0);
b6d96bed 8322 }
5a5012ec 8323 opn = "add.ps";
6ea83fed 8324 break;
bf4120ad 8325 case OPC_SUB_PS:
5e755519 8326 check_cp1_64bitmode(ctx);
b6d96bed 8327 {
a7812ae4
PB
8328 TCGv_i64 fp0 = tcg_temp_new_i64();
8329 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8330
8331 gen_load_fpr64(ctx, fp0, fs);
8332 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8333 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8334 tcg_temp_free_i64(fp1);
b6d96bed 8335 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8336 tcg_temp_free_i64(fp0);
b6d96bed 8337 }
5a5012ec 8338 opn = "sub.ps";
6ea83fed 8339 break;
bf4120ad 8340 case OPC_MUL_PS:
5e755519 8341 check_cp1_64bitmode(ctx);
b6d96bed 8342 {
a7812ae4
PB
8343 TCGv_i64 fp0 = tcg_temp_new_i64();
8344 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8345
8346 gen_load_fpr64(ctx, fp0, fs);
8347 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8348 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8349 tcg_temp_free_i64(fp1);
b6d96bed 8350 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8351 tcg_temp_free_i64(fp0);
b6d96bed 8352 }
5a5012ec 8353 opn = "mul.ps";
6ea83fed 8354 break;
bf4120ad 8355 case OPC_ABS_PS:
5e755519 8356 check_cp1_64bitmode(ctx);
b6d96bed 8357 {
a7812ae4 8358 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8359
8360 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8361 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8362 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8363 tcg_temp_free_i64(fp0);
b6d96bed 8364 }
5a5012ec 8365 opn = "abs.ps";
6ea83fed 8366 break;
bf4120ad 8367 case OPC_MOV_PS:
5e755519 8368 check_cp1_64bitmode(ctx);
b6d96bed 8369 {
a7812ae4 8370 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8371
8372 gen_load_fpr64(ctx, fp0, fs);
8373 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8374 tcg_temp_free_i64(fp0);
b6d96bed 8375 }
5a5012ec 8376 opn = "mov.ps";
6ea83fed 8377 break;
bf4120ad 8378 case OPC_NEG_PS:
5e755519 8379 check_cp1_64bitmode(ctx);
b6d96bed 8380 {
a7812ae4 8381 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8382
8383 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8384 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8385 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8386 tcg_temp_free_i64(fp0);
b6d96bed 8387 }
5a5012ec 8388 opn = "neg.ps";
6ea83fed 8389 break;
bf4120ad 8390 case OPC_MOVCF_PS:
5e755519 8391 check_cp1_64bitmode(ctx);
b6d96bed 8392 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8393 opn = "movcf.ps";
6ea83fed 8394 break;
bf4120ad 8395 case OPC_MOVZ_PS:
5e755519 8396 check_cp1_64bitmode(ctx);
a16336e4
TS
8397 {
8398 int l1 = gen_new_label();
30a3848b 8399 TCGv_i64 fp0;
a16336e4 8400
c9297f4d
AJ
8401 if (ft != 0)
8402 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8403 fp0 = tcg_temp_new_i64();
8404 gen_load_fpr64(ctx, fp0, fs);
8405 gen_store_fpr64(ctx, fp0, fd);
8406 tcg_temp_free_i64(fp0);
a16336e4
TS
8407 gen_set_label(l1);
8408 }
5a5012ec 8409 opn = "movz.ps";
6ea83fed 8410 break;
bf4120ad 8411 case OPC_MOVN_PS:
5e755519 8412 check_cp1_64bitmode(ctx);
a16336e4
TS
8413 {
8414 int l1 = gen_new_label();
30a3848b 8415 TCGv_i64 fp0;
c9297f4d
AJ
8416
8417 if (ft != 0) {
8418 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8419 fp0 = tcg_temp_new_i64();
8420 gen_load_fpr64(ctx, fp0, fs);
8421 gen_store_fpr64(ctx, fp0, fd);
8422 tcg_temp_free_i64(fp0);
8423 gen_set_label(l1);
8424 }
a16336e4 8425 }
5a5012ec 8426 opn = "movn.ps";
6ea83fed 8427 break;
bf4120ad 8428 case OPC_ADDR_PS:
5e755519 8429 check_cp1_64bitmode(ctx);
b6d96bed 8430 {
a7812ae4
PB
8431 TCGv_i64 fp0 = tcg_temp_new_i64();
8432 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8433
8434 gen_load_fpr64(ctx, fp0, ft);
8435 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8436 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8437 tcg_temp_free_i64(fp1);
b6d96bed 8438 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8439 tcg_temp_free_i64(fp0);
b6d96bed 8440 }
fbcc6828
TS
8441 opn = "addr.ps";
8442 break;
bf4120ad 8443 case OPC_MULR_PS:
5e755519 8444 check_cp1_64bitmode(ctx);
b6d96bed 8445 {
a7812ae4
PB
8446 TCGv_i64 fp0 = tcg_temp_new_i64();
8447 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8448
8449 gen_load_fpr64(ctx, fp0, ft);
8450 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8451 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8452 tcg_temp_free_i64(fp1);
b6d96bed 8453 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8454 tcg_temp_free_i64(fp0);
b6d96bed 8455 }
57fa1fb3
TS
8456 opn = "mulr.ps";
8457 break;
bf4120ad 8458 case OPC_RECIP2_PS:
5e755519 8459 check_cp1_64bitmode(ctx);
b6d96bed 8460 {
a7812ae4
PB
8461 TCGv_i64 fp0 = tcg_temp_new_i64();
8462 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8463
8464 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8465 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8466 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8467 tcg_temp_free_i64(fp1);
b6d96bed 8468 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8469 tcg_temp_free_i64(fp0);
b6d96bed 8470 }
57fa1fb3
TS
8471 opn = "recip2.ps";
8472 break;
bf4120ad 8473 case OPC_RECIP1_PS:
5e755519 8474 check_cp1_64bitmode(ctx);
b6d96bed 8475 {
a7812ae4 8476 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8477
8478 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8479 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8480 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8481 tcg_temp_free_i64(fp0);
b6d96bed 8482 }
57fa1fb3
TS
8483 opn = "recip1.ps";
8484 break;
bf4120ad 8485 case OPC_RSQRT1_PS:
5e755519 8486 check_cp1_64bitmode(ctx);
b6d96bed 8487 {
a7812ae4 8488 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8489
8490 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8491 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8492 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8493 tcg_temp_free_i64(fp0);
b6d96bed 8494 }
57fa1fb3
TS
8495 opn = "rsqrt1.ps";
8496 break;
bf4120ad 8497 case OPC_RSQRT2_PS:
5e755519 8498 check_cp1_64bitmode(ctx);
b6d96bed 8499 {
a7812ae4
PB
8500 TCGv_i64 fp0 = tcg_temp_new_i64();
8501 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8502
8503 gen_load_fpr64(ctx, fp0, fs);
8504 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8505 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8506 tcg_temp_free_i64(fp1);
b6d96bed 8507 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8508 tcg_temp_free_i64(fp0);
b6d96bed 8509 }
57fa1fb3
TS
8510 opn = "rsqrt2.ps";
8511 break;
bf4120ad 8512 case OPC_CVT_S_PU:
5e755519 8513 check_cp1_64bitmode(ctx);
b6d96bed 8514 {
a7812ae4 8515 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8516
8517 gen_load_fpr32h(fp0, fs);
895c2d04 8518 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8519 gen_store_fpr32(fp0, fd);
a7812ae4 8520 tcg_temp_free_i32(fp0);
b6d96bed 8521 }
5a5012ec 8522 opn = "cvt.s.pu";
dd016883 8523 break;
bf4120ad 8524 case OPC_CVT_PW_PS:
5e755519 8525 check_cp1_64bitmode(ctx);
b6d96bed 8526 {
a7812ae4 8527 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8528
8529 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8530 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8531 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8532 tcg_temp_free_i64(fp0);
b6d96bed 8533 }
5a5012ec 8534 opn = "cvt.pw.ps";
6ea83fed 8535 break;
bf4120ad 8536 case OPC_CVT_S_PL:
5e755519 8537 check_cp1_64bitmode(ctx);
b6d96bed 8538 {
a7812ae4 8539 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8540
8541 gen_load_fpr32(fp0, fs);
895c2d04 8542 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8543 gen_store_fpr32(fp0, fd);
a7812ae4 8544 tcg_temp_free_i32(fp0);
b6d96bed 8545 }
5a5012ec 8546 opn = "cvt.s.pl";
6ea83fed 8547 break;
bf4120ad 8548 case OPC_PLL_PS:
5e755519 8549 check_cp1_64bitmode(ctx);
b6d96bed 8550 {
a7812ae4
PB
8551 TCGv_i32 fp0 = tcg_temp_new_i32();
8552 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8553
8554 gen_load_fpr32(fp0, fs);
8555 gen_load_fpr32(fp1, ft);
8556 gen_store_fpr32h(fp0, fd);
8557 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8558 tcg_temp_free_i32(fp0);
8559 tcg_temp_free_i32(fp1);
b6d96bed 8560 }
5a5012ec 8561 opn = "pll.ps";
6ea83fed 8562 break;
bf4120ad 8563 case OPC_PLU_PS:
5e755519 8564 check_cp1_64bitmode(ctx);
b6d96bed 8565 {
a7812ae4
PB
8566 TCGv_i32 fp0 = tcg_temp_new_i32();
8567 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8568
8569 gen_load_fpr32(fp0, fs);
8570 gen_load_fpr32h(fp1, ft);
8571 gen_store_fpr32(fp1, fd);
8572 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8573 tcg_temp_free_i32(fp0);
8574 tcg_temp_free_i32(fp1);
b6d96bed 8575 }
5a5012ec
TS
8576 opn = "plu.ps";
8577 break;
bf4120ad 8578 case OPC_PUL_PS:
5e755519 8579 check_cp1_64bitmode(ctx);
b6d96bed 8580 {
a7812ae4
PB
8581 TCGv_i32 fp0 = tcg_temp_new_i32();
8582 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8583
8584 gen_load_fpr32h(fp0, fs);
8585 gen_load_fpr32(fp1, ft);
8586 gen_store_fpr32(fp1, fd);
8587 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8588 tcg_temp_free_i32(fp0);
8589 tcg_temp_free_i32(fp1);
b6d96bed 8590 }
5a5012ec
TS
8591 opn = "pul.ps";
8592 break;
bf4120ad 8593 case OPC_PUU_PS:
5e755519 8594 check_cp1_64bitmode(ctx);
b6d96bed 8595 {
a7812ae4
PB
8596 TCGv_i32 fp0 = tcg_temp_new_i32();
8597 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8598
8599 gen_load_fpr32h(fp0, fs);
8600 gen_load_fpr32h(fp1, ft);
8601 gen_store_fpr32(fp1, fd);
8602 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8603 tcg_temp_free_i32(fp0);
8604 tcg_temp_free_i32(fp1);
b6d96bed 8605 }
5a5012ec
TS
8606 opn = "puu.ps";
8607 break;
bf4120ad
NF
8608 case OPC_CMP_F_PS:
8609 case OPC_CMP_UN_PS:
8610 case OPC_CMP_EQ_PS:
8611 case OPC_CMP_UEQ_PS:
8612 case OPC_CMP_OLT_PS:
8613 case OPC_CMP_ULT_PS:
8614 case OPC_CMP_OLE_PS:
8615 case OPC_CMP_ULE_PS:
8616 case OPC_CMP_SF_PS:
8617 case OPC_CMP_NGLE_PS:
8618 case OPC_CMP_SEQ_PS:
8619 case OPC_CMP_NGL_PS:
8620 case OPC_CMP_LT_PS:
8621 case OPC_CMP_NGE_PS:
8622 case OPC_CMP_LE_PS:
8623 case OPC_CMP_NGT_PS:
8153667c
NF
8624 if (ctx->opcode & (1 << 6)) {
8625 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8626 opn = condnames_abs[func-48];
8627 } else {
8628 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8629 opn = condnames[func-48];
5a1e8ffb 8630 }
6ea83fed 8631 break;
5a5012ec 8632 default:
923617a3 8633 MIPS_INVAL(opn);
e397ee33 8634 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8635 return;
8636 }
2abf314d 8637 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8638 switch (optype) {
8639 case BINOP:
6ea83fed 8640 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8641 break;
8642 case CMPOP:
8643 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8644 break;
8645 default:
6ea83fed 8646 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8647 break;
8648 }
6ea83fed 8649}
6af0bf9c 8650
5a5012ec 8651/* Coprocessor 3 (FPU) */
5e755519
TS
8652static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8653 int fd, int fs, int base, int index)
7a387fff 8654{
923617a3 8655 const char *opn = "extended float load/store";
93b12ccc 8656 int store = 0;
4e2474d6 8657 TCGv t0 = tcg_temp_new();
7a387fff 8658
93b12ccc 8659 if (base == 0) {
6c5c1e20 8660 gen_load_gpr(t0, index);
93b12ccc 8661 } else if (index == 0) {
6c5c1e20 8662 gen_load_gpr(t0, base);
93b12ccc 8663 } else {
05168674 8664 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8665 }
5a5012ec 8666 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8667 memory access. */
5a5012ec
TS
8668 switch (opc) {
8669 case OPC_LWXC1:
8c0ab41f 8670 check_cop1x(ctx);
b6d96bed 8671 {
a7812ae4 8672 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8673
5f68f5ae 8674 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 8675 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8676 gen_store_fpr32(fp0, fd);
a7812ae4 8677 tcg_temp_free_i32(fp0);
b6d96bed 8678 }
5a5012ec
TS
8679 opn = "lwxc1";
8680 break;
8681 case OPC_LDXC1:
8c0ab41f
AJ
8682 check_cop1x(ctx);
8683 check_cp1_registers(ctx, fd);
b6d96bed 8684 {
a7812ae4 8685 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 8686 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 8687 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8688 tcg_temp_free_i64(fp0);
b6d96bed 8689 }
5a5012ec
TS
8690 opn = "ldxc1";
8691 break;
8692 case OPC_LUXC1:
8c0ab41f 8693 check_cp1_64bitmode(ctx);
6c5c1e20 8694 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8695 {
a7812ae4 8696 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8697
5f68f5ae 8698 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 8699 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8700 tcg_temp_free_i64(fp0);
b6d96bed 8701 }
5a5012ec
TS
8702 opn = "luxc1";
8703 break;
8704 case OPC_SWXC1:
8c0ab41f 8705 check_cop1x(ctx);
b6d96bed 8706 {
a7812ae4 8707 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8708 gen_load_fpr32(fp0, fs);
5f68f5ae 8709 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 8710 tcg_temp_free_i32(fp0);
b6d96bed 8711 }
5a5012ec 8712 opn = "swxc1";
93b12ccc 8713 store = 1;
5a5012ec
TS
8714 break;
8715 case OPC_SDXC1:
8c0ab41f
AJ
8716 check_cop1x(ctx);
8717 check_cp1_registers(ctx, fs);
b6d96bed 8718 {
a7812ae4 8719 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8720 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 8721 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 8722 tcg_temp_free_i64(fp0);
b6d96bed 8723 }
5a5012ec 8724 opn = "sdxc1";
93b12ccc 8725 store = 1;
5a5012ec
TS
8726 break;
8727 case OPC_SUXC1:
8c0ab41f 8728 check_cp1_64bitmode(ctx);
6c5c1e20 8729 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8730 {
a7812ae4 8731 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8732 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 8733 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 8734 tcg_temp_free_i64(fp0);
b6d96bed 8735 }
5a5012ec 8736 opn = "suxc1";
93b12ccc 8737 store = 1;
5a5012ec 8738 break;
5a5012ec 8739 }
6c5c1e20 8740 tcg_temp_free(t0);
2abf314d 8741 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8742 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8743 regnames[index], regnames[base]);
5a5012ec
TS
8744}
8745
5e755519
TS
8746static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8747 int fd, int fr, int fs, int ft)
5a5012ec 8748{
923617a3 8749 const char *opn = "flt3_arith";
5a5012ec 8750
5a5012ec
TS
8751 switch (opc) {
8752 case OPC_ALNV_PS:
b8aa4598 8753 check_cp1_64bitmode(ctx);
a16336e4 8754 {
a7812ae4 8755 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8756 TCGv_i32 fp = tcg_temp_new_i32();
8757 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8758 int l1 = gen_new_label();
8759 int l2 = gen_new_label();
8760
6c5c1e20
TS
8761 gen_load_gpr(t0, fr);
8762 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8763
8764 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac
AJ
8765 gen_load_fpr32(fp, fs);
8766 gen_load_fpr32h(fph, fs);
8767 gen_store_fpr32(fp, fd);
8768 gen_store_fpr32h(fph, fd);
a16336e4
TS
8769 tcg_gen_br(l2);
8770 gen_set_label(l1);
6c5c1e20
TS
8771 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8772 tcg_temp_free(t0);
a16336e4 8773#ifdef TARGET_WORDS_BIGENDIAN
c905fdac
AJ
8774 gen_load_fpr32(fp, fs);
8775 gen_load_fpr32h(fph, ft);
8776 gen_store_fpr32h(fp, fd);
8777 gen_store_fpr32(fph, fd);
a16336e4 8778#else
c905fdac
AJ
8779 gen_load_fpr32h(fph, fs);
8780 gen_load_fpr32(fp, ft);
8781 gen_store_fpr32(fph, fd);
8782 gen_store_fpr32h(fp, fd);
a16336e4
TS
8783#endif
8784 gen_set_label(l2);
c905fdac
AJ
8785 tcg_temp_free_i32(fp);
8786 tcg_temp_free_i32(fph);
a16336e4 8787 }
5a5012ec
TS
8788 opn = "alnv.ps";
8789 break;
8790 case OPC_MADD_S:
b8aa4598 8791 check_cop1x(ctx);
b6d96bed 8792 {
a7812ae4
PB
8793 TCGv_i32 fp0 = tcg_temp_new_i32();
8794 TCGv_i32 fp1 = tcg_temp_new_i32();
8795 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8796
8797 gen_load_fpr32(fp0, fs);
8798 gen_load_fpr32(fp1, ft);
8799 gen_load_fpr32(fp2, fr);
b3d6cd44 8800 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8801 tcg_temp_free_i32(fp0);
8802 tcg_temp_free_i32(fp1);
b6d96bed 8803 gen_store_fpr32(fp2, fd);
a7812ae4 8804 tcg_temp_free_i32(fp2);
b6d96bed 8805 }
5a5012ec
TS
8806 opn = "madd.s";
8807 break;
8808 case OPC_MADD_D:
b8aa4598
TS
8809 check_cop1x(ctx);
8810 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8811 {
a7812ae4
PB
8812 TCGv_i64 fp0 = tcg_temp_new_i64();
8813 TCGv_i64 fp1 = tcg_temp_new_i64();
8814 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8815
8816 gen_load_fpr64(ctx, fp0, fs);
8817 gen_load_fpr64(ctx, fp1, ft);
8818 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8819 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8820 tcg_temp_free_i64(fp0);
8821 tcg_temp_free_i64(fp1);
b6d96bed 8822 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8823 tcg_temp_free_i64(fp2);
b6d96bed 8824 }
5a5012ec
TS
8825 opn = "madd.d";
8826 break;
8827 case OPC_MADD_PS:
b8aa4598 8828 check_cp1_64bitmode(ctx);
b6d96bed 8829 {
a7812ae4
PB
8830 TCGv_i64 fp0 = tcg_temp_new_i64();
8831 TCGv_i64 fp1 = tcg_temp_new_i64();
8832 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8833
8834 gen_load_fpr64(ctx, fp0, fs);
8835 gen_load_fpr64(ctx, fp1, ft);
8836 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8837 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8838 tcg_temp_free_i64(fp0);
8839 tcg_temp_free_i64(fp1);
b6d96bed 8840 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8841 tcg_temp_free_i64(fp2);
b6d96bed 8842 }
5a5012ec
TS
8843 opn = "madd.ps";
8844 break;
8845 case OPC_MSUB_S:
b8aa4598 8846 check_cop1x(ctx);
b6d96bed 8847 {
a7812ae4
PB
8848 TCGv_i32 fp0 = tcg_temp_new_i32();
8849 TCGv_i32 fp1 = tcg_temp_new_i32();
8850 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8851
8852 gen_load_fpr32(fp0, fs);
8853 gen_load_fpr32(fp1, ft);
8854 gen_load_fpr32(fp2, fr);
b3d6cd44 8855 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8856 tcg_temp_free_i32(fp0);
8857 tcg_temp_free_i32(fp1);
b6d96bed 8858 gen_store_fpr32(fp2, fd);
a7812ae4 8859 tcg_temp_free_i32(fp2);
b6d96bed 8860 }
5a5012ec
TS
8861 opn = "msub.s";
8862 break;
8863 case OPC_MSUB_D:
b8aa4598
TS
8864 check_cop1x(ctx);
8865 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8866 {
a7812ae4
PB
8867 TCGv_i64 fp0 = tcg_temp_new_i64();
8868 TCGv_i64 fp1 = tcg_temp_new_i64();
8869 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8870
8871 gen_load_fpr64(ctx, fp0, fs);
8872 gen_load_fpr64(ctx, fp1, ft);
8873 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8874 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8875 tcg_temp_free_i64(fp0);
8876 tcg_temp_free_i64(fp1);
b6d96bed 8877 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8878 tcg_temp_free_i64(fp2);
b6d96bed 8879 }
5a5012ec
TS
8880 opn = "msub.d";
8881 break;
8882 case OPC_MSUB_PS:
b8aa4598 8883 check_cp1_64bitmode(ctx);
b6d96bed 8884 {
a7812ae4
PB
8885 TCGv_i64 fp0 = tcg_temp_new_i64();
8886 TCGv_i64 fp1 = tcg_temp_new_i64();
8887 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8888
8889 gen_load_fpr64(ctx, fp0, fs);
8890 gen_load_fpr64(ctx, fp1, ft);
8891 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8892 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8893 tcg_temp_free_i64(fp0);
8894 tcg_temp_free_i64(fp1);
b6d96bed 8895 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8896 tcg_temp_free_i64(fp2);
b6d96bed 8897 }
5a5012ec
TS
8898 opn = "msub.ps";
8899 break;
8900 case OPC_NMADD_S:
b8aa4598 8901 check_cop1x(ctx);
b6d96bed 8902 {
a7812ae4
PB
8903 TCGv_i32 fp0 = tcg_temp_new_i32();
8904 TCGv_i32 fp1 = tcg_temp_new_i32();
8905 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8906
8907 gen_load_fpr32(fp0, fs);
8908 gen_load_fpr32(fp1, ft);
8909 gen_load_fpr32(fp2, fr);
b3d6cd44 8910 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8911 tcg_temp_free_i32(fp0);
8912 tcg_temp_free_i32(fp1);
b6d96bed 8913 gen_store_fpr32(fp2, fd);
a7812ae4 8914 tcg_temp_free_i32(fp2);
b6d96bed 8915 }
5a5012ec
TS
8916 opn = "nmadd.s";
8917 break;
8918 case OPC_NMADD_D:
b8aa4598
TS
8919 check_cop1x(ctx);
8920 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8921 {
a7812ae4
PB
8922 TCGv_i64 fp0 = tcg_temp_new_i64();
8923 TCGv_i64 fp1 = tcg_temp_new_i64();
8924 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8925
8926 gen_load_fpr64(ctx, fp0, fs);
8927 gen_load_fpr64(ctx, fp1, ft);
8928 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8929 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8930 tcg_temp_free_i64(fp0);
8931 tcg_temp_free_i64(fp1);
b6d96bed 8932 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8933 tcg_temp_free_i64(fp2);
b6d96bed 8934 }
5a5012ec
TS
8935 opn = "nmadd.d";
8936 break;
8937 case OPC_NMADD_PS:
b8aa4598 8938 check_cp1_64bitmode(ctx);
b6d96bed 8939 {
a7812ae4
PB
8940 TCGv_i64 fp0 = tcg_temp_new_i64();
8941 TCGv_i64 fp1 = tcg_temp_new_i64();
8942 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8943
8944 gen_load_fpr64(ctx, fp0, fs);
8945 gen_load_fpr64(ctx, fp1, ft);
8946 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8947 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8948 tcg_temp_free_i64(fp0);
8949 tcg_temp_free_i64(fp1);
b6d96bed 8950 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8951 tcg_temp_free_i64(fp2);
b6d96bed 8952 }
5a5012ec
TS
8953 opn = "nmadd.ps";
8954 break;
8955 case OPC_NMSUB_S:
b8aa4598 8956 check_cop1x(ctx);
b6d96bed 8957 {
a7812ae4
PB
8958 TCGv_i32 fp0 = tcg_temp_new_i32();
8959 TCGv_i32 fp1 = tcg_temp_new_i32();
8960 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8961
8962 gen_load_fpr32(fp0, fs);
8963 gen_load_fpr32(fp1, ft);
8964 gen_load_fpr32(fp2, fr);
b3d6cd44 8965 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8966 tcg_temp_free_i32(fp0);
8967 tcg_temp_free_i32(fp1);
b6d96bed 8968 gen_store_fpr32(fp2, fd);
a7812ae4 8969 tcg_temp_free_i32(fp2);
b6d96bed 8970 }
5a5012ec
TS
8971 opn = "nmsub.s";
8972 break;
8973 case OPC_NMSUB_D:
b8aa4598
TS
8974 check_cop1x(ctx);
8975 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8976 {
a7812ae4
PB
8977 TCGv_i64 fp0 = tcg_temp_new_i64();
8978 TCGv_i64 fp1 = tcg_temp_new_i64();
8979 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8980
8981 gen_load_fpr64(ctx, fp0, fs);
8982 gen_load_fpr64(ctx, fp1, ft);
8983 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8984 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8985 tcg_temp_free_i64(fp0);
8986 tcg_temp_free_i64(fp1);
b6d96bed 8987 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8988 tcg_temp_free_i64(fp2);
b6d96bed 8989 }
5a5012ec
TS
8990 opn = "nmsub.d";
8991 break;
8992 case OPC_NMSUB_PS:
b8aa4598 8993 check_cp1_64bitmode(ctx);
b6d96bed 8994 {
a7812ae4
PB
8995 TCGv_i64 fp0 = tcg_temp_new_i64();
8996 TCGv_i64 fp1 = tcg_temp_new_i64();
8997 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8998
8999 gen_load_fpr64(ctx, fp0, fs);
9000 gen_load_fpr64(ctx, fp1, ft);
9001 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9002 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9003 tcg_temp_free_i64(fp0);
9004 tcg_temp_free_i64(fp1);
b6d96bed 9005 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9006 tcg_temp_free_i64(fp2);
b6d96bed 9007 }
5a5012ec
TS
9008 opn = "nmsub.ps";
9009 break;
923617a3
TS
9010 default:
9011 MIPS_INVAL(opn);
5a5012ec
TS
9012 generate_exception (ctx, EXCP_RI);
9013 return;
9014 }
2abf314d 9015 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9016 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9017 fregnames[fs], fregnames[ft]);
7a387fff
TS
9018}
9019
d75c135e 9020static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9021{
9022 TCGv t0;
9023
b3167288
RH
9024#if !defined(CONFIG_USER_ONLY)
9025 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9026 Therefore only check the ISA in system mode. */
d75c135e 9027 check_insn(ctx, ISA_MIPS32R2);
b3167288 9028#endif
26ebe468
NF
9029 t0 = tcg_temp_new();
9030
9031 switch (rd) {
9032 case 0:
9033 save_cpu_state(ctx, 1);
895c2d04 9034 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9035 gen_store_gpr(t0, rt);
9036 break;
9037 case 1:
9038 save_cpu_state(ctx, 1);
895c2d04 9039 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9040 gen_store_gpr(t0, rt);
9041 break;
9042 case 2:
9043 save_cpu_state(ctx, 1);
895c2d04 9044 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9045 gen_store_gpr(t0, rt);
9046 break;
9047 case 3:
9048 save_cpu_state(ctx, 1);
895c2d04 9049 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9050 gen_store_gpr(t0, rt);
9051 break;
9052 case 29:
9053#if defined(CONFIG_USER_ONLY)
7db13fae 9054 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
26ebe468
NF
9055 gen_store_gpr(t0, rt);
9056 break;
9057#else
9058 /* XXX: Some CPUs implement this in hardware.
9059 Not supported yet. */
9060#endif
9061 default: /* Invalid */
9062 MIPS_INVAL("rdhwr");
9063 generate_exception(ctx, EXCP_RI);
9064 break;
9065 }
9066 tcg_temp_free(t0);
9067}
9068
d75c135e 9069static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9070{
9071 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9072 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9073 /* Branches completion */
9074 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9075 ctx->bstate = BS_BRANCH;
9076 save_cpu_state(ctx, 0);
9077 /* FIXME: Need to clear can_do_io. */
364d4831 9078 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9079 case MIPS_HFLAG_B:
9080 /* unconditional branch */
9081 MIPS_DEBUG("unconditional branch");
364d4831
NF
9082 if (proc_hflags & MIPS_HFLAG_BX) {
9083 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9084 }
c9602061
NF
9085 gen_goto_tb(ctx, 0, ctx->btarget);
9086 break;
9087 case MIPS_HFLAG_BL:
9088 /* blikely taken case */
9089 MIPS_DEBUG("blikely branch taken");
9090 gen_goto_tb(ctx, 0, ctx->btarget);
9091 break;
9092 case MIPS_HFLAG_BC:
9093 /* Conditional branch */
9094 MIPS_DEBUG("conditional branch");
9095 {
9096 int l1 = gen_new_label();
9097
9098 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9099 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9100 gen_set_label(l1);
9101 gen_goto_tb(ctx, 0, ctx->btarget);
9102 }
9103 break;
9104 case MIPS_HFLAG_BR:
9105 /* unconditional branch to register */
9106 MIPS_DEBUG("branch to register");
d75c135e 9107 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9108 TCGv t0 = tcg_temp_new();
9109 TCGv_i32 t1 = tcg_temp_new_i32();
9110
9111 tcg_gen_andi_tl(t0, btarget, 0x1);
9112 tcg_gen_trunc_tl_i32(t1, t0);
9113 tcg_temp_free(t0);
9114 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9115 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9116 tcg_gen_or_i32(hflags, hflags, t1);
9117 tcg_temp_free_i32(t1);
9118
9119 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9120 } else {
9121 tcg_gen_mov_tl(cpu_PC, btarget);
9122 }
c9602061
NF
9123 if (ctx->singlestep_enabled) {
9124 save_cpu_state(ctx, 0);
895c2d04 9125 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9126 }
9127 tcg_gen_exit_tb(0);
9128 break;
9129 default:
9130 MIPS_DEBUG("unknown branch");
9131 break;
9132 }
9133 }
9134}
9135
7a387fff 9136/* ISA extensions (ASEs) */
6af0bf9c 9137/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9138
9139/* MIPS16 major opcodes */
9140enum {
9141 M16_OPC_ADDIUSP = 0x00,
9142 M16_OPC_ADDIUPC = 0x01,
9143 M16_OPC_B = 0x02,
9144 M16_OPC_JAL = 0x03,
9145 M16_OPC_BEQZ = 0x04,
9146 M16_OPC_BNEQZ = 0x05,
9147 M16_OPC_SHIFT = 0x06,
9148 M16_OPC_LD = 0x07,
9149 M16_OPC_RRIA = 0x08,
9150 M16_OPC_ADDIU8 = 0x09,
9151 M16_OPC_SLTI = 0x0a,
9152 M16_OPC_SLTIU = 0x0b,
9153 M16_OPC_I8 = 0x0c,
9154 M16_OPC_LI = 0x0d,
9155 M16_OPC_CMPI = 0x0e,
9156 M16_OPC_SD = 0x0f,
9157 M16_OPC_LB = 0x10,
9158 M16_OPC_LH = 0x11,
9159 M16_OPC_LWSP = 0x12,
9160 M16_OPC_LW = 0x13,
9161 M16_OPC_LBU = 0x14,
9162 M16_OPC_LHU = 0x15,
9163 M16_OPC_LWPC = 0x16,
9164 M16_OPC_LWU = 0x17,
9165 M16_OPC_SB = 0x18,
9166 M16_OPC_SH = 0x19,
9167 M16_OPC_SWSP = 0x1a,
9168 M16_OPC_SW = 0x1b,
9169 M16_OPC_RRR = 0x1c,
9170 M16_OPC_RR = 0x1d,
9171 M16_OPC_EXTEND = 0x1e,
9172 M16_OPC_I64 = 0x1f
9173};
9174
9175/* I8 funct field */
9176enum {
9177 I8_BTEQZ = 0x0,
9178 I8_BTNEZ = 0x1,
9179 I8_SWRASP = 0x2,
9180 I8_ADJSP = 0x3,
9181 I8_SVRS = 0x4,
9182 I8_MOV32R = 0x5,
9183 I8_MOVR32 = 0x7
9184};
9185
9186/* RRR f field */
9187enum {
9188 RRR_DADDU = 0x0,
9189 RRR_ADDU = 0x1,
9190 RRR_DSUBU = 0x2,
9191 RRR_SUBU = 0x3
9192};
9193
9194/* RR funct field */
9195enum {
9196 RR_JR = 0x00,
9197 RR_SDBBP = 0x01,
9198 RR_SLT = 0x02,
9199 RR_SLTU = 0x03,
9200 RR_SLLV = 0x04,
9201 RR_BREAK = 0x05,
9202 RR_SRLV = 0x06,
9203 RR_SRAV = 0x07,
9204 RR_DSRL = 0x08,
9205 RR_CMP = 0x0a,
9206 RR_NEG = 0x0b,
9207 RR_AND = 0x0c,
9208 RR_OR = 0x0d,
9209 RR_XOR = 0x0e,
9210 RR_NOT = 0x0f,
9211 RR_MFHI = 0x10,
9212 RR_CNVT = 0x11,
9213 RR_MFLO = 0x12,
9214 RR_DSRA = 0x13,
9215 RR_DSLLV = 0x14,
9216 RR_DSRLV = 0x16,
9217 RR_DSRAV = 0x17,
9218 RR_MULT = 0x18,
9219 RR_MULTU = 0x19,
9220 RR_DIV = 0x1a,
9221 RR_DIVU = 0x1b,
9222 RR_DMULT = 0x1c,
9223 RR_DMULTU = 0x1d,
9224 RR_DDIV = 0x1e,
9225 RR_DDIVU = 0x1f
9226};
9227
9228/* I64 funct field */
9229enum {
9230 I64_LDSP = 0x0,
9231 I64_SDSP = 0x1,
9232 I64_SDRASP = 0x2,
9233 I64_DADJSP = 0x3,
9234 I64_LDPC = 0x4,
364d4831 9235 I64_DADDIU5 = 0x5,
6ea219d0
NF
9236 I64_DADDIUPC = 0x6,
9237 I64_DADDIUSP = 0x7
9238};
9239
9240/* RR ry field for CNVT */
9241enum {
9242 RR_RY_CNVT_ZEB = 0x0,
9243 RR_RY_CNVT_ZEH = 0x1,
9244 RR_RY_CNVT_ZEW = 0x2,
9245 RR_RY_CNVT_SEB = 0x4,
9246 RR_RY_CNVT_SEH = 0x5,
9247 RR_RY_CNVT_SEW = 0x6,
9248};
9249
364d4831
NF
9250static int xlat (int r)
9251{
9252 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9253
9254 return map[r];
9255}
9256
9257static void gen_mips16_save (DisasContext *ctx,
9258 int xsregs, int aregs,
9259 int do_ra, int do_s0, int do_s1,
9260 int framesize)
9261{
9262 TCGv t0 = tcg_temp_new();
9263 TCGv t1 = tcg_temp_new();
9264 int args, astatic;
9265
9266 switch (aregs) {
9267 case 0:
9268 case 1:
9269 case 2:
9270 case 3:
9271 case 11:
9272 args = 0;
9273 break;
9274 case 4:
9275 case 5:
9276 case 6:
9277 case 7:
9278 args = 1;
9279 break;
9280 case 8:
9281 case 9:
9282 case 10:
9283 args = 2;
9284 break;
9285 case 12:
9286 case 13:
9287 args = 3;
9288 break;
9289 case 14:
9290 args = 4;
9291 break;
9292 default:
9293 generate_exception(ctx, EXCP_RI);
9294 return;
9295 }
9296
9297 switch (args) {
9298 case 4:
9299 gen_base_offset_addr(ctx, t0, 29, 12);
9300 gen_load_gpr(t1, 7);
5f68f5ae 9301 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9302 /* Fall through */
9303 case 3:
9304 gen_base_offset_addr(ctx, t0, 29, 8);
9305 gen_load_gpr(t1, 6);
5f68f5ae 9306 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9307 /* Fall through */
9308 case 2:
9309 gen_base_offset_addr(ctx, t0, 29, 4);
9310 gen_load_gpr(t1, 5);
5f68f5ae 9311 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9312 /* Fall through */
9313 case 1:
9314 gen_base_offset_addr(ctx, t0, 29, 0);
9315 gen_load_gpr(t1, 4);
5f68f5ae 9316 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9317 }
9318
9319 gen_load_gpr(t0, 29);
9320
5f68f5ae
AJ
9321#define DECR_AND_STORE(reg) do { \
9322 tcg_gen_subi_tl(t0, t0, 4); \
9323 gen_load_gpr(t1, reg); \
9324 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
9325 } while (0)
9326
9327 if (do_ra) {
9328 DECR_AND_STORE(31);
9329 }
9330
9331 switch (xsregs) {
9332 case 7:
9333 DECR_AND_STORE(30);
9334 /* Fall through */
9335 case 6:
9336 DECR_AND_STORE(23);
9337 /* Fall through */
9338 case 5:
9339 DECR_AND_STORE(22);
9340 /* Fall through */
9341 case 4:
9342 DECR_AND_STORE(21);
9343 /* Fall through */
9344 case 3:
9345 DECR_AND_STORE(20);
9346 /* Fall through */
9347 case 2:
9348 DECR_AND_STORE(19);
9349 /* Fall through */
9350 case 1:
9351 DECR_AND_STORE(18);
9352 }
9353
9354 if (do_s1) {
9355 DECR_AND_STORE(17);
9356 }
9357 if (do_s0) {
9358 DECR_AND_STORE(16);
9359 }
9360
9361 switch (aregs) {
9362 case 0:
9363 case 4:
9364 case 8:
9365 case 12:
9366 case 14:
9367 astatic = 0;
9368 break;
9369 case 1:
9370 case 5:
9371 case 9:
9372 case 13:
9373 astatic = 1;
9374 break;
9375 case 2:
9376 case 6:
9377 case 10:
9378 astatic = 2;
9379 break;
9380 case 3:
9381 case 7:
9382 astatic = 3;
9383 break;
9384 case 11:
9385 astatic = 4;
9386 break;
9387 default:
9388 generate_exception(ctx, EXCP_RI);
9389 return;
9390 }
9391
9392 if (astatic > 0) {
9393 DECR_AND_STORE(7);
9394 if (astatic > 1) {
9395 DECR_AND_STORE(6);
9396 if (astatic > 2) {
9397 DECR_AND_STORE(5);
9398 if (astatic > 3) {
9399 DECR_AND_STORE(4);
9400 }
9401 }
9402 }
9403 }
9404#undef DECR_AND_STORE
9405
9406 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9407 tcg_temp_free(t0);
9408 tcg_temp_free(t1);
9409}
9410
9411static void gen_mips16_restore (DisasContext *ctx,
9412 int xsregs, int aregs,
9413 int do_ra, int do_s0, int do_s1,
9414 int framesize)
9415{
9416 int astatic;
9417 TCGv t0 = tcg_temp_new();
9418 TCGv t1 = tcg_temp_new();
9419
9420 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9421
5f68f5ae
AJ
9422#define DECR_AND_LOAD(reg) do { \
9423 tcg_gen_subi_tl(t0, t0, 4); \
9424 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9425 gen_store_gpr(t1, reg); \
364d4831
NF
9426 } while (0)
9427
9428 if (do_ra) {
9429 DECR_AND_LOAD(31);
9430 }
9431
9432 switch (xsregs) {
9433 case 7:
9434 DECR_AND_LOAD(30);
9435 /* Fall through */
9436 case 6:
9437 DECR_AND_LOAD(23);
9438 /* Fall through */
9439 case 5:
9440 DECR_AND_LOAD(22);
9441 /* Fall through */
9442 case 4:
9443 DECR_AND_LOAD(21);
9444 /* Fall through */
9445 case 3:
9446 DECR_AND_LOAD(20);
9447 /* Fall through */
9448 case 2:
9449 DECR_AND_LOAD(19);
9450 /* Fall through */
9451 case 1:
9452 DECR_AND_LOAD(18);
9453 }
9454
9455 if (do_s1) {
9456 DECR_AND_LOAD(17);
9457 }
9458 if (do_s0) {
9459 DECR_AND_LOAD(16);
9460 }
9461
9462 switch (aregs) {
9463 case 0:
9464 case 4:
9465 case 8:
9466 case 12:
9467 case 14:
9468 astatic = 0;
9469 break;
9470 case 1:
9471 case 5:
9472 case 9:
9473 case 13:
9474 astatic = 1;
9475 break;
9476 case 2:
9477 case 6:
9478 case 10:
9479 astatic = 2;
9480 break;
9481 case 3:
9482 case 7:
9483 astatic = 3;
9484 break;
9485 case 11:
9486 astatic = 4;
9487 break;
9488 default:
9489 generate_exception(ctx, EXCP_RI);
9490 return;
9491 }
9492
9493 if (astatic > 0) {
9494 DECR_AND_LOAD(7);
9495 if (astatic > 1) {
9496 DECR_AND_LOAD(6);
9497 if (astatic > 2) {
9498 DECR_AND_LOAD(5);
9499 if (astatic > 3) {
9500 DECR_AND_LOAD(4);
9501 }
9502 }
9503 }
9504 }
9505#undef DECR_AND_LOAD
9506
9507 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9508 tcg_temp_free(t0);
9509 tcg_temp_free(t1);
9510}
9511
9512static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9513 int is_64_bit, int extended)
9514{
9515 TCGv t0;
9516
9517 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9518 generate_exception(ctx, EXCP_RI);
9519 return;
9520 }
9521
9522 t0 = tcg_temp_new();
9523
9524 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9525 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9526 if (!is_64_bit) {
9527 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9528 }
9529
9530 tcg_temp_free(t0);
9531}
9532
9533#if defined(TARGET_MIPS64)
d75c135e 9534static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9535 int ry, int funct, int16_t offset,
9536 int extended)
9537{
9538 switch (funct) {
9539 case I64_LDSP:
9540 check_mips_64(ctx);
9541 offset = extended ? offset : offset << 3;
d75c135e 9542 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9543 break;
9544 case I64_SDSP:
9545 check_mips_64(ctx);
9546 offset = extended ? offset : offset << 3;
5c13fdfd 9547 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9548 break;
9549 case I64_SDRASP:
9550 check_mips_64(ctx);
9551 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9552 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9553 break;
9554 case I64_DADJSP:
9555 check_mips_64(ctx);
9556 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9557 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9558 break;
9559 case I64_LDPC:
9560 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9561 generate_exception(ctx, EXCP_RI);
9562 } else {
9563 offset = extended ? offset : offset << 3;
d75c135e 9564 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9565 }
9566 break;
9567 case I64_DADDIU5:
9568 check_mips_64(ctx);
9569 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9570 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9571 break;
9572 case I64_DADDIUPC:
9573 check_mips_64(ctx);
9574 offset = extended ? offset : offset << 2;
9575 gen_addiupc(ctx, ry, offset, 1, extended);
9576 break;
9577 case I64_DADDIUSP:
9578 check_mips_64(ctx);
9579 offset = extended ? offset : offset << 2;
d75c135e 9580 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9581 break;
9582 }
9583}
9584#endif
9585
240ce26a 9586static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 9587{
895c2d04 9588 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9589 int op, rx, ry, funct, sa;
9590 int16_t imm, offset;
9591
9592 ctx->opcode = (ctx->opcode << 16) | extend;
9593 op = (ctx->opcode >> 11) & 0x1f;
9594 sa = (ctx->opcode >> 22) & 0x1f;
9595 funct = (ctx->opcode >> 8) & 0x7;
9596 rx = xlat((ctx->opcode >> 8) & 0x7);
9597 ry = xlat((ctx->opcode >> 5) & 0x7);
9598 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9599 | ((ctx->opcode >> 21) & 0x3f) << 5
9600 | (ctx->opcode & 0x1f));
9601
9602 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9603 counterparts. */
9604 switch (op) {
9605 case M16_OPC_ADDIUSP:
d75c135e 9606 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9607 break;
9608 case M16_OPC_ADDIUPC:
9609 gen_addiupc(ctx, rx, imm, 0, 1);
9610 break;
9611 case M16_OPC_B:
9612 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9613 /* No delay slot, so just process as a normal instruction */
9614 break;
9615 case M16_OPC_BEQZ:
9616 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9617 /* No delay slot, so just process as a normal instruction */
9618 break;
9619 case M16_OPC_BNEQZ:
9620 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9621 /* No delay slot, so just process as a normal instruction */
9622 break;
9623 case M16_OPC_SHIFT:
9624 switch (ctx->opcode & 0x3) {
9625 case 0x0:
d75c135e 9626 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9627 break;
9628 case 0x1:
9629#if defined(TARGET_MIPS64)
9630 check_mips_64(ctx);
d75c135e 9631 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9632#else
9633 generate_exception(ctx, EXCP_RI);
9634#endif
9635 break;
9636 case 0x2:
d75c135e 9637 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9638 break;
9639 case 0x3:
d75c135e 9640 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9641 break;
9642 }
9643 break;
9644#if defined(TARGET_MIPS64)
9645 case M16_OPC_LD:
9646 check_mips_64(ctx);
d75c135e 9647 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9648 break;
9649#endif
9650 case M16_OPC_RRIA:
9651 imm = ctx->opcode & 0xf;
9652 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9653 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9654 imm = (int16_t) (imm << 1) >> 1;
9655 if ((ctx->opcode >> 4) & 0x1) {
9656#if defined(TARGET_MIPS64)
9657 check_mips_64(ctx);
d75c135e 9658 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9659#else
9660 generate_exception(ctx, EXCP_RI);
9661#endif
9662 } else {
d75c135e 9663 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9664 }
9665 break;
9666 case M16_OPC_ADDIU8:
d75c135e 9667 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9668 break;
9669 case M16_OPC_SLTI:
d75c135e 9670 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9671 break;
9672 case M16_OPC_SLTIU:
d75c135e 9673 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9674 break;
9675 case M16_OPC_I8:
9676 switch (funct) {
9677 case I8_BTEQZ:
9678 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9679 break;
9680 case I8_BTNEZ:
9681 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9682 break;
9683 case I8_SWRASP:
5c13fdfd 9684 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9685 break;
9686 case I8_ADJSP:
d75c135e 9687 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
9688 break;
9689 case I8_SVRS:
9690 {
9691 int xsregs = (ctx->opcode >> 24) & 0x7;
9692 int aregs = (ctx->opcode >> 16) & 0xf;
9693 int do_ra = (ctx->opcode >> 6) & 0x1;
9694 int do_s0 = (ctx->opcode >> 5) & 0x1;
9695 int do_s1 = (ctx->opcode >> 4) & 0x1;
9696 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9697 | (ctx->opcode & 0xf)) << 3;
9698
9699 if (ctx->opcode & (1 << 7)) {
9700 gen_mips16_save(ctx, xsregs, aregs,
9701 do_ra, do_s0, do_s1,
9702 framesize);
9703 } else {
9704 gen_mips16_restore(ctx, xsregs, aregs,
9705 do_ra, do_s0, do_s1,
9706 framesize);
9707 }
9708 }
9709 break;
9710 default:
9711 generate_exception(ctx, EXCP_RI);
9712 break;
9713 }
9714 break;
9715 case M16_OPC_LI:
9716 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9717 break;
9718 case M16_OPC_CMPI:
9719 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9720 break;
9721#if defined(TARGET_MIPS64)
9722 case M16_OPC_SD:
5c13fdfd 9723 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9724 break;
9725#endif
9726 case M16_OPC_LB:
d75c135e 9727 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9728 break;
9729 case M16_OPC_LH:
d75c135e 9730 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9731 break;
9732 case M16_OPC_LWSP:
d75c135e 9733 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9734 break;
9735 case M16_OPC_LW:
d75c135e 9736 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9737 break;
9738 case M16_OPC_LBU:
d75c135e 9739 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9740 break;
9741 case M16_OPC_LHU:
d75c135e 9742 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9743 break;
9744 case M16_OPC_LWPC:
d75c135e 9745 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9746 break;
9747#if defined(TARGET_MIPS64)
9748 case M16_OPC_LWU:
d75c135e 9749 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9750 break;
9751#endif
9752 case M16_OPC_SB:
5c13fdfd 9753 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9754 break;
9755 case M16_OPC_SH:
5c13fdfd 9756 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9757 break;
9758 case M16_OPC_SWSP:
5c13fdfd 9759 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9760 break;
9761 case M16_OPC_SW:
5c13fdfd 9762 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9763 break;
9764#if defined(TARGET_MIPS64)
9765 case M16_OPC_I64:
d75c135e 9766 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
9767 break;
9768#endif
9769 default:
9770 generate_exception(ctx, EXCP_RI);
9771 break;
9772 }
9773
9774 return 4;
9775}
9776
240ce26a 9777static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
9778{
9779 int rx, ry;
9780 int sa;
9781 int op, cnvt_op, op1, offset;
9782 int funct;
9783 int n_bytes;
9784
9785 op = (ctx->opcode >> 11) & 0x1f;
9786 sa = (ctx->opcode >> 2) & 0x7;
9787 sa = sa == 0 ? 8 : sa;
9788 rx = xlat((ctx->opcode >> 8) & 0x7);
9789 cnvt_op = (ctx->opcode >> 5) & 0x7;
9790 ry = xlat((ctx->opcode >> 5) & 0x7);
9791 op1 = offset = ctx->opcode & 0x1f;
9792
9793 n_bytes = 2;
9794
9795 switch (op) {
9796 case M16_OPC_ADDIUSP:
9797 {
9798 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9799
d75c135e 9800 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9801 }
9802 break;
9803 case M16_OPC_ADDIUPC:
9804 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9805 break;
9806 case M16_OPC_B:
9807 offset = (ctx->opcode & 0x7ff) << 1;
9808 offset = (int16_t)(offset << 4) >> 4;
9809 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9810 /* No delay slot, so just process as a normal instruction */
9811 break;
9812 case M16_OPC_JAL:
895c2d04 9813 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9814 offset = (((ctx->opcode & 0x1f) << 21)
9815 | ((ctx->opcode >> 5) & 0x1f) << 16
9816 | offset) << 2;
620e48f6 9817 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9818 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9819 n_bytes = 4;
364d4831
NF
9820 break;
9821 case M16_OPC_BEQZ:
9822 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9823 /* No delay slot, so just process as a normal instruction */
9824 break;
9825 case M16_OPC_BNEQZ:
9826 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9827 /* No delay slot, so just process as a normal instruction */
9828 break;
9829 case M16_OPC_SHIFT:
9830 switch (ctx->opcode & 0x3) {
9831 case 0x0:
d75c135e 9832 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9833 break;
9834 case 0x1:
9835#if defined(TARGET_MIPS64)
9836 check_mips_64(ctx);
d75c135e 9837 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9838#else
9839 generate_exception(ctx, EXCP_RI);
9840#endif
9841 break;
9842 case 0x2:
d75c135e 9843 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9844 break;
9845 case 0x3:
d75c135e 9846 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9847 break;
9848 }
9849 break;
9850#if defined(TARGET_MIPS64)
9851 case M16_OPC_LD:
9852 check_mips_64(ctx);
d75c135e 9853 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9854 break;
9855#endif
9856 case M16_OPC_RRIA:
9857 {
9858 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9859
9860 if ((ctx->opcode >> 4) & 1) {
9861#if defined(TARGET_MIPS64)
9862 check_mips_64(ctx);
d75c135e 9863 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9864#else
9865 generate_exception(ctx, EXCP_RI);
9866#endif
9867 } else {
d75c135e 9868 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9869 }
9870 }
9871 break;
9872 case M16_OPC_ADDIU8:
9873 {
9874 int16_t imm = (int8_t) ctx->opcode;
9875
d75c135e 9876 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9877 }
9878 break;
9879 case M16_OPC_SLTI:
9880 {
9881 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9882 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9883 }
9884 break;
9885 case M16_OPC_SLTIU:
9886 {
9887 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9888 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9889 }
9890 break;
9891 case M16_OPC_I8:
9892 {
9893 int reg32;
9894
9895 funct = (ctx->opcode >> 8) & 0x7;
9896 switch (funct) {
9897 case I8_BTEQZ:
9898 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9899 ((int8_t)ctx->opcode) << 1);
9900 break;
9901 case I8_BTNEZ:
9902 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9903 ((int8_t)ctx->opcode) << 1);
9904 break;
9905 case I8_SWRASP:
5c13fdfd 9906 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9907 break;
9908 case I8_ADJSP:
d75c135e 9909 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
9910 ((int8_t)ctx->opcode) << 3);
9911 break;
9912 case I8_SVRS:
9913 {
9914 int do_ra = ctx->opcode & (1 << 6);
9915 int do_s0 = ctx->opcode & (1 << 5);
9916 int do_s1 = ctx->opcode & (1 << 4);
9917 int framesize = ctx->opcode & 0xf;
9918
9919 if (framesize == 0) {
9920 framesize = 128;
9921 } else {
9922 framesize = framesize << 3;
9923 }
9924
9925 if (ctx->opcode & (1 << 7)) {
9926 gen_mips16_save(ctx, 0, 0,
9927 do_ra, do_s0, do_s1, framesize);
9928 } else {
9929 gen_mips16_restore(ctx, 0, 0,
9930 do_ra, do_s0, do_s1, framesize);
9931 }
9932 }
9933 break;
9934 case I8_MOV32R:
9935 {
9936 int rz = xlat(ctx->opcode & 0x7);
9937
9938 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9939 ((ctx->opcode >> 5) & 0x7);
d75c135e 9940 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
9941 }
9942 break;
9943 case I8_MOVR32:
9944 reg32 = ctx->opcode & 0x1f;
d75c135e 9945 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
9946 break;
9947 default:
9948 generate_exception(ctx, EXCP_RI);
9949 break;
9950 }
9951 }
9952 break;
9953 case M16_OPC_LI:
9954 {
9955 int16_t imm = (uint8_t) ctx->opcode;
9956
d75c135e 9957 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
9958 }
9959 break;
9960 case M16_OPC_CMPI:
9961 {
9962 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9963 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
9964 }
9965 break;
9966#if defined(TARGET_MIPS64)
9967 case M16_OPC_SD:
9968 check_mips_64(ctx);
5c13fdfd 9969 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
9970 break;
9971#endif
9972 case M16_OPC_LB:
d75c135e 9973 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9974 break;
9975 case M16_OPC_LH:
d75c135e 9976 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
9977 break;
9978 case M16_OPC_LWSP:
d75c135e 9979 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
9980 break;
9981 case M16_OPC_LW:
d75c135e 9982 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
9983 break;
9984 case M16_OPC_LBU:
d75c135e 9985 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9986 break;
9987 case M16_OPC_LHU:
d75c135e 9988 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
9989 break;
9990 case M16_OPC_LWPC:
d75c135e 9991 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
9992 break;
9993#if defined (TARGET_MIPS64)
9994 case M16_OPC_LWU:
9995 check_mips_64(ctx);
d75c135e 9996 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
9997 break;
9998#endif
9999 case M16_OPC_SB:
5c13fdfd 10000 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10001 break;
10002 case M16_OPC_SH:
5c13fdfd 10003 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10004 break;
10005 case M16_OPC_SWSP:
5c13fdfd 10006 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10007 break;
10008 case M16_OPC_SW:
5c13fdfd 10009 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10010 break;
10011 case M16_OPC_RRR:
10012 {
10013 int rz = xlat((ctx->opcode >> 2) & 0x7);
10014 int mips32_op;
10015
10016 switch (ctx->opcode & 0x3) {
10017 case RRR_ADDU:
10018 mips32_op = OPC_ADDU;
10019 break;
10020 case RRR_SUBU:
10021 mips32_op = OPC_SUBU;
10022 break;
10023#if defined(TARGET_MIPS64)
10024 case RRR_DADDU:
10025 mips32_op = OPC_DADDU;
10026 check_mips_64(ctx);
10027 break;
10028 case RRR_DSUBU:
10029 mips32_op = OPC_DSUBU;
10030 check_mips_64(ctx);
10031 break;
10032#endif
10033 default:
10034 generate_exception(ctx, EXCP_RI);
10035 goto done;
10036 }
10037
d75c135e 10038 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10039 done:
10040 ;
10041 }
10042 break;
10043 case M16_OPC_RR:
10044 switch (op1) {
10045 case RR_JR:
10046 {
10047 int nd = (ctx->opcode >> 7) & 0x1;
10048 int link = (ctx->opcode >> 6) & 0x1;
10049 int ra = (ctx->opcode >> 5) & 0x1;
10050
10051 if (link) {
620e48f6 10052 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10053 } else {
10054 op = OPC_JR;
10055 }
10056
10057 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
364d4831
NF
10058 }
10059 break;
10060 case RR_SDBBP:
10061 /* XXX: not clear which exception should be raised
10062 * when in debug mode...
10063 */
d75c135e 10064 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10065 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10066 generate_exception(ctx, EXCP_DBp);
10067 } else {
10068 generate_exception(ctx, EXCP_DBp);
10069 }
10070 break;
10071 case RR_SLT:
d75c135e 10072 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10073 break;
10074 case RR_SLTU:
d75c135e 10075 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10076 break;
10077 case RR_BREAK:
10078 generate_exception(ctx, EXCP_BREAK);
10079 break;
10080 case RR_SLLV:
d75c135e 10081 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10082 break;
10083 case RR_SRLV:
d75c135e 10084 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10085 break;
10086 case RR_SRAV:
d75c135e 10087 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10088 break;
10089#if defined (TARGET_MIPS64)
10090 case RR_DSRL:
10091 check_mips_64(ctx);
d75c135e 10092 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10093 break;
10094#endif
10095 case RR_CMP:
d75c135e 10096 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10097 break;
10098 case RR_NEG:
d75c135e 10099 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10100 break;
10101 case RR_AND:
d75c135e 10102 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10103 break;
10104 case RR_OR:
d75c135e 10105 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10106 break;
10107 case RR_XOR:
d75c135e 10108 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10109 break;
10110 case RR_NOT:
d75c135e 10111 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10112 break;
10113 case RR_MFHI:
26135ead 10114 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
10115 break;
10116 case RR_CNVT:
10117 switch (cnvt_op) {
10118 case RR_RY_CNVT_ZEB:
10119 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10120 break;
10121 case RR_RY_CNVT_ZEH:
10122 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10123 break;
10124 case RR_RY_CNVT_SEB:
10125 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10126 break;
10127 case RR_RY_CNVT_SEH:
10128 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10129 break;
10130#if defined (TARGET_MIPS64)
10131 case RR_RY_CNVT_ZEW:
10132 check_mips_64(ctx);
10133 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10134 break;
10135 case RR_RY_CNVT_SEW:
10136 check_mips_64(ctx);
10137 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10138 break;
10139#endif
10140 default:
10141 generate_exception(ctx, EXCP_RI);
10142 break;
10143 }
10144 break;
10145 case RR_MFLO:
26135ead 10146 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
10147 break;
10148#if defined (TARGET_MIPS64)
10149 case RR_DSRA:
10150 check_mips_64(ctx);
d75c135e 10151 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10152 break;
10153 case RR_DSLLV:
10154 check_mips_64(ctx);
d75c135e 10155 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10156 break;
10157 case RR_DSRLV:
10158 check_mips_64(ctx);
d75c135e 10159 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10160 break;
10161 case RR_DSRAV:
10162 check_mips_64(ctx);
d75c135e 10163 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10164 break;
10165#endif
10166 case RR_MULT:
26135ead 10167 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
10168 break;
10169 case RR_MULTU:
26135ead 10170 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
10171 break;
10172 case RR_DIV:
26135ead 10173 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
10174 break;
10175 case RR_DIVU:
26135ead 10176 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
10177 break;
10178#if defined (TARGET_MIPS64)
10179 case RR_DMULT:
10180 check_mips_64(ctx);
26135ead 10181 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
10182 break;
10183 case RR_DMULTU:
10184 check_mips_64(ctx);
26135ead 10185 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
10186 break;
10187 case RR_DDIV:
10188 check_mips_64(ctx);
26135ead 10189 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
10190 break;
10191 case RR_DDIVU:
10192 check_mips_64(ctx);
26135ead 10193 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
10194 break;
10195#endif
10196 default:
10197 generate_exception(ctx, EXCP_RI);
10198 break;
10199 }
10200 break;
10201 case M16_OPC_EXTEND:
240ce26a 10202 decode_extended_mips16_opc(env, ctx);
364d4831
NF
10203 n_bytes = 4;
10204 break;
10205#if defined(TARGET_MIPS64)
10206 case M16_OPC_I64:
10207 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10208 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10209 break;
10210#endif
10211 default:
10212 generate_exception(ctx, EXCP_RI);
10213 break;
10214 }
10215
10216 return n_bytes;
10217}
10218
211da992 10219/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10220
211da992
CWR
10221/*
10222 * microMIPS32/microMIPS64 major opcodes
10223 *
10224 * 1. MIPS Architecture for Programmers Volume II-B:
10225 * The microMIPS32 Instruction Set (Revision 3.05)
10226 *
10227 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10228 *
10229 * 2. MIPS Architecture For Programmers Volume II-A:
10230 * The MIPS64 Instruction Set (Revision 3.51)
10231 */
6af0bf9c 10232
3c824109
NF
10233enum {
10234 POOL32A = 0x00,
10235 POOL16A = 0x01,
10236 LBU16 = 0x02,
10237 MOVE16 = 0x03,
10238 ADDI32 = 0x04,
10239 LBU32 = 0x05,
10240 SB32 = 0x06,
10241 LB32 = 0x07,
10242
10243 POOL32B = 0x08,
10244 POOL16B = 0x09,
10245 LHU16 = 0x0a,
10246 ANDI16 = 0x0b,
10247 ADDIU32 = 0x0c,
10248 LHU32 = 0x0d,
10249 SH32 = 0x0e,
10250 LH32 = 0x0f,
10251
10252 POOL32I = 0x10,
10253 POOL16C = 0x11,
10254 LWSP16 = 0x12,
10255 POOL16D = 0x13,
10256 ORI32 = 0x14,
10257 POOL32F = 0x15,
211da992
CWR
10258 POOL32S = 0x16, /* MIPS64 */
10259 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10260
211da992 10261 /* 0x1f is reserved */
3c824109
NF
10262 POOL32C = 0x18,
10263 LWGP16 = 0x19,
10264 LW16 = 0x1a,
10265 POOL16E = 0x1b,
10266 XORI32 = 0x1c,
10267 JALS32 = 0x1d,
10268 ADDIUPC = 0x1e,
3c824109
NF
10269
10270 /* 0x20 is reserved */
10271 RES_20 = 0x20,
10272 POOL16F = 0x21,
10273 SB16 = 0x22,
10274 BEQZ16 = 0x23,
10275 SLTI32 = 0x24,
10276 BEQ32 = 0x25,
10277 SWC132 = 0x26,
10278 LWC132 = 0x27,
10279
10280 /* 0x28 and 0x29 are reserved */
10281 RES_28 = 0x28,
10282 RES_29 = 0x29,
10283 SH16 = 0x2a,
10284 BNEZ16 = 0x2b,
10285 SLTIU32 = 0x2c,
10286 BNE32 = 0x2d,
10287 SDC132 = 0x2e,
10288 LDC132 = 0x2f,
10289
10290 /* 0x30 and 0x31 are reserved */
10291 RES_30 = 0x30,
10292 RES_31 = 0x31,
10293 SWSP16 = 0x32,
10294 B16 = 0x33,
10295 ANDI32 = 0x34,
10296 J32 = 0x35,
211da992
CWR
10297 SD32 = 0x36, /* MIPS64 */
10298 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10299
10300 /* 0x38 and 0x39 are reserved */
10301 RES_38 = 0x38,
10302 RES_39 = 0x39,
10303 SW16 = 0x3a,
10304 LI16 = 0x3b,
10305 JALX32 = 0x3c,
10306 JAL32 = 0x3d,
10307 SW32 = 0x3e,
10308 LW32 = 0x3f
10309};
10310
10311/* POOL32A encoding of minor opcode field */
10312
10313enum {
10314 /* These opcodes are distinguished only by bits 9..6; those bits are
10315 * what are recorded below. */
10316 SLL32 = 0x0,
10317 SRL32 = 0x1,
10318 SRA = 0x2,
10319 ROTR = 0x3,
10320
10321 SLLV = 0x0,
10322 SRLV = 0x1,
10323 SRAV = 0x2,
10324 ROTRV = 0x3,
10325 ADD = 0x4,
10326 ADDU32 = 0x5,
10327 SUB = 0x6,
10328 SUBU32 = 0x7,
10329 MUL = 0x8,
10330 AND = 0x9,
10331 OR32 = 0xa,
10332 NOR = 0xb,
10333 XOR32 = 0xc,
10334 SLT = 0xd,
10335 SLTU = 0xe,
10336
10337 MOVN = 0x0,
10338 MOVZ = 0x1,
10339 LWXS = 0x4,
10340
10341 /* The following can be distinguished by their lower 6 bits. */
10342 INS = 0x0c,
10343 EXT = 0x2c,
10344 POOL32AXF = 0x3c
10345};
10346
10347/* POOL32AXF encoding of minor opcode field extension */
10348
d132c79f
CWR
10349/*
10350 * 1. MIPS Architecture for Programmers Volume II-B:
10351 * The microMIPS32 Instruction Set (Revision 3.05)
10352 *
10353 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10354 *
10355 * 2. MIPS Architecture for Programmers VolumeIV-e:
10356 * The MIPS DSP Application-Specific Extension
10357 * to the microMIPS32 Architecture (Revision 2.34)
10358 *
10359 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10360 */
10361
3c824109
NF
10362enum {
10363 /* bits 11..6 */
10364 TEQ = 0x00,
10365 TGE = 0x08,
10366 TGEU = 0x10,
10367 TLT = 0x20,
10368 TLTU = 0x28,
10369 TNE = 0x30,
10370
10371 MFC0 = 0x03,
10372 MTC0 = 0x0b,
10373
d132c79f
CWR
10374 /* begin of microMIPS32 DSP */
10375
3c824109
NF
10376 /* bits 13..12 for 0x01 */
10377 MFHI_ACC = 0x0,
10378 MFLO_ACC = 0x1,
10379 MTHI_ACC = 0x2,
10380 MTLO_ACC = 0x3,
10381
10382 /* bits 13..12 for 0x2a */
10383 MADD_ACC = 0x0,
10384 MADDU_ACC = 0x1,
10385 MSUB_ACC = 0x2,
10386 MSUBU_ACC = 0x3,
10387
10388 /* bits 13..12 for 0x32 */
10389 MULT_ACC = 0x0,
6801038b 10390 MULTU_ACC = 0x1,
3c824109 10391
d132c79f
CWR
10392 /* end of microMIPS32 DSP */
10393
3c824109
NF
10394 /* bits 15..12 for 0x2c */
10395 SEB = 0x2,
10396 SEH = 0x3,
10397 CLO = 0x4,
10398 CLZ = 0x5,
10399 RDHWR = 0x6,
10400 WSBH = 0x7,
10401 MULT = 0x8,
10402 MULTU = 0x9,
10403 DIV = 0xa,
10404 DIVU = 0xb,
10405 MADD = 0xc,
10406 MADDU = 0xd,
10407 MSUB = 0xe,
10408 MSUBU = 0xf,
10409
10410 /* bits 15..12 for 0x34 */
10411 MFC2 = 0x4,
10412 MTC2 = 0x5,
10413 MFHC2 = 0x8,
10414 MTHC2 = 0x9,
10415 CFC2 = 0xc,
10416 CTC2 = 0xd,
10417
10418 /* bits 15..12 for 0x3c */
10419 JALR = 0x0,
10420 JR = 0x0, /* alias */
10421 JALR_HB = 0x1,
10422 JALRS = 0x4,
10423 JALRS_HB = 0x5,
10424
10425 /* bits 15..12 for 0x05 */
10426 RDPGPR = 0xe,
10427 WRPGPR = 0xf,
10428
10429 /* bits 15..12 for 0x0d */
10430 TLBP = 0x0,
10431 TLBR = 0x1,
10432 TLBWI = 0x2,
10433 TLBWR = 0x3,
10434 WAIT = 0x9,
10435 IRET = 0xd,
10436 DERET = 0xe,
10437 ERET = 0xf,
10438
10439 /* bits 15..12 for 0x15 */
10440 DMT = 0x0,
10441 DVPE = 0x1,
10442 EMT = 0x2,
10443 EVPE = 0x3,
10444
10445 /* bits 15..12 for 0x1d */
10446 DI = 0x4,
10447 EI = 0x5,
10448
10449 /* bits 15..12 for 0x2d */
10450 SYNC = 0x6,
10451 SYSCALL = 0x8,
10452 SDBBP = 0xd,
10453
10454 /* bits 15..12 for 0x35 */
10455 MFHI32 = 0x0,
10456 MFLO32 = 0x1,
10457 MTHI32 = 0x2,
10458 MTLO32 = 0x3,
10459};
10460
10461/* POOL32B encoding of minor opcode field (bits 15..12) */
10462
10463enum {
10464 LWC2 = 0x0,
10465 LWP = 0x1,
10466 LDP = 0x4,
10467 LWM32 = 0x5,
10468 CACHE = 0x6,
10469 LDM = 0x7,
10470 SWC2 = 0x8,
10471 SWP = 0x9,
10472 SDP = 0xc,
10473 SWM32 = 0xd,
10474 SDM = 0xf
10475};
10476
10477/* POOL32C encoding of minor opcode field (bits 15..12) */
10478
10479enum {
10480 LWL = 0x0,
10481 SWL = 0x8,
10482 LWR = 0x1,
10483 SWR = 0x9,
10484 PREF = 0x2,
10485 /* 0xa is reserved */
10486 LL = 0x3,
10487 SC = 0xb,
10488 LDL = 0x4,
10489 SDL = 0xc,
10490 LDR = 0x5,
10491 SDR = 0xd,
10492 /* 0x6 is reserved */
10493 LWU = 0xe,
10494 LLD = 0x7,
10495 SCD = 0xf
10496};
10497
10498/* POOL32F encoding of minor opcode field (bits 5..0) */
10499
10500enum {
10501 /* These are the bit 7..6 values */
10502 ADD_FMT = 0x0,
10503 MOVN_FMT = 0x0,
10504
10505 SUB_FMT = 0x1,
10506 MOVZ_FMT = 0x1,
10507
10508 MUL_FMT = 0x2,
10509
10510 DIV_FMT = 0x3,
10511
10512 /* These are the bit 8..6 values */
10513 RSQRT2_FMT = 0x0,
10514 MOVF_FMT = 0x0,
10515
10516 LWXC1 = 0x1,
10517 MOVT_FMT = 0x1,
10518
10519 PLL_PS = 0x2,
10520 SWXC1 = 0x2,
10521
10522 PLU_PS = 0x3,
10523 LDXC1 = 0x3,
10524
10525 PUL_PS = 0x4,
10526 SDXC1 = 0x4,
10527 RECIP2_FMT = 0x4,
10528
10529 PUU_PS = 0x5,
10530 LUXC1 = 0x5,
10531
10532 CVT_PS_S = 0x6,
10533 SUXC1 = 0x6,
10534 ADDR_PS = 0x6,
10535 PREFX = 0x6,
10536
10537 MULR_PS = 0x7,
10538
10539 MADD_S = 0x01,
10540 MADD_D = 0x09,
10541 MADD_PS = 0x11,
10542 ALNV_PS = 0x19,
10543 MSUB_S = 0x21,
10544 MSUB_D = 0x29,
10545 MSUB_PS = 0x31,
10546
10547 NMADD_S = 0x02,
10548 NMADD_D = 0x0a,
10549 NMADD_PS = 0x12,
10550 NMSUB_S = 0x22,
10551 NMSUB_D = 0x2a,
10552 NMSUB_PS = 0x32,
10553
10554 POOL32FXF = 0x3b,
10555
10556 CABS_COND_FMT = 0x1c, /* MIPS3D */
10557 C_COND_FMT = 0x3c
10558};
10559
10560/* POOL32Fxf encoding of minor opcode extension field */
10561
10562enum {
10563 CVT_L = 0x04,
10564 RSQRT_FMT = 0x08,
10565 FLOOR_L = 0x0c,
10566 CVT_PW_PS = 0x1c,
10567 CVT_W = 0x24,
10568 SQRT_FMT = 0x28,
10569 FLOOR_W = 0x2c,
10570 CVT_PS_PW = 0x3c,
10571 CFC1 = 0x40,
10572 RECIP_FMT = 0x48,
10573 CEIL_L = 0x4c,
10574 CTC1 = 0x60,
10575 CEIL_W = 0x6c,
10576 MFC1 = 0x80,
10577 CVT_S_PL = 0x84,
10578 TRUNC_L = 0x8c,
10579 MTC1 = 0xa0,
10580 CVT_S_PU = 0xa4,
10581 TRUNC_W = 0xac,
10582 MFHC1 = 0xc0,
10583 ROUND_L = 0xcc,
10584 MTHC1 = 0xe0,
10585 ROUND_W = 0xec,
10586
10587 MOV_FMT = 0x01,
10588 MOVF = 0x05,
10589 ABS_FMT = 0x0d,
10590 RSQRT1_FMT = 0x1d,
10591 MOVT = 0x25,
10592 NEG_FMT = 0x2d,
10593 CVT_D = 0x4d,
10594 RECIP1_FMT = 0x5d,
10595 CVT_S = 0x6d
10596};
10597
10598/* POOL32I encoding of minor opcode field (bits 25..21) */
10599
10600enum {
10601 BLTZ = 0x00,
10602 BLTZAL = 0x01,
10603 BGEZ = 0x02,
10604 BGEZAL = 0x03,
10605 BLEZ = 0x04,
10606 BNEZC = 0x05,
10607 BGTZ = 0x06,
10608 BEQZC = 0x07,
10609 TLTI = 0x08,
10610 TGEI = 0x09,
10611 TLTIU = 0x0a,
10612 TGEIU = 0x0b,
10613 TNEI = 0x0c,
10614 LUI = 0x0d,
10615 TEQI = 0x0e,
10616 SYNCI = 0x10,
10617 BLTZALS = 0x11,
10618 BGEZALS = 0x13,
10619 BC2F = 0x14,
10620 BC2T = 0x15,
10621 BPOSGE64 = 0x1a,
10622 BPOSGE32 = 0x1b,
10623 /* These overlap and are distinguished by bit16 of the instruction */
10624 BC1F = 0x1c,
10625 BC1T = 0x1d,
10626 BC1ANY2F = 0x1c,
10627 BC1ANY2T = 0x1d,
10628 BC1ANY4F = 0x1e,
10629 BC1ANY4T = 0x1f
10630};
10631
10632/* POOL16A encoding of minor opcode field */
10633
10634enum {
10635 ADDU16 = 0x0,
10636 SUBU16 = 0x1
10637};
10638
10639/* POOL16B encoding of minor opcode field */
10640
10641enum {
10642 SLL16 = 0x0,
10643 SRL16 = 0x1
10644};
10645
10646/* POOL16C encoding of minor opcode field */
10647
10648enum {
10649 NOT16 = 0x00,
10650 XOR16 = 0x04,
10651 AND16 = 0x08,
10652 OR16 = 0x0c,
10653 LWM16 = 0x10,
10654 SWM16 = 0x14,
10655 JR16 = 0x18,
10656 JRC16 = 0x1a,
10657 JALR16 = 0x1c,
10658 JALR16S = 0x1e,
10659 MFHI16 = 0x20,
10660 MFLO16 = 0x24,
10661 BREAK16 = 0x28,
10662 SDBBP16 = 0x2c,
10663 JRADDIUSP = 0x30
10664};
10665
10666/* POOL16D encoding of minor opcode field */
10667
10668enum {
10669 ADDIUS5 = 0x0,
10670 ADDIUSP = 0x1
10671};
10672
10673/* POOL16E encoding of minor opcode field */
10674
10675enum {
10676 ADDIUR2 = 0x0,
10677 ADDIUR1SP = 0x1
10678};
10679
10680static int mmreg (int r)
10681{
10682 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10683
10684 return map[r];
10685}
10686
10687/* Used for 16-bit store instructions. */
10688static int mmreg2 (int r)
10689{
10690 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10691
10692 return map[r];
10693}
10694
10695#define uMIPS_RD(op) ((op >> 7) & 0x7)
10696#define uMIPS_RS(op) ((op >> 4) & 0x7)
10697#define uMIPS_RS2(op) uMIPS_RS(op)
10698#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10699#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10700#define uMIPS_RS5(op) (op & 0x1f)
10701
10702/* Signed immediate */
10703#define SIMM(op, start, width) \
10704 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10705 << (32-width)) \
10706 >> (32-width))
10707/* Zero-extended immediate */
10708#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10709
d75c135e 10710static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
10711{
10712 int rd = mmreg(uMIPS_RD(ctx->opcode));
10713
d75c135e 10714 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
10715}
10716
d75c135e 10717static void gen_addiur2(DisasContext *ctx)
3c824109
NF
10718{
10719 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10720 int rd = mmreg(uMIPS_RD(ctx->opcode));
10721 int rs = mmreg(uMIPS_RS(ctx->opcode));
10722
d75c135e 10723 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
10724}
10725
d75c135e 10726static void gen_addiusp(DisasContext *ctx)
3c824109
NF
10727{
10728 int encoded = ZIMM(ctx->opcode, 1, 9);
10729 int decoded;
10730
10731 if (encoded <= 1) {
10732 decoded = 256 + encoded;
10733 } else if (encoded <= 255) {
10734 decoded = encoded;
10735 } else if (encoded <= 509) {
10736 decoded = encoded - 512;
10737 } else {
10738 decoded = encoded - 768;
10739 }
10740
d75c135e 10741 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
10742}
10743
d75c135e 10744static void gen_addius5(DisasContext *ctx)
3c824109
NF
10745{
10746 int imm = SIMM(ctx->opcode, 1, 4);
10747 int rd = (ctx->opcode >> 5) & 0x1f;
10748
d75c135e 10749 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
10750}
10751
d75c135e 10752static void gen_andi16(DisasContext *ctx)
3c824109
NF
10753{
10754 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10755 31, 32, 63, 64, 255, 32768, 65535 };
10756 int rd = mmreg(uMIPS_RD(ctx->opcode));
10757 int rs = mmreg(uMIPS_RS(ctx->opcode));
10758 int encoded = ZIMM(ctx->opcode, 0, 4);
10759
d75c135e 10760 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10761}
10762
10763static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10764 int base, int16_t offset)
10765{
e1050a76 10766 const char *opn = "ldst_multiple";
3c824109
NF
10767 TCGv t0, t1;
10768 TCGv_i32 t2;
10769
10770 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10771 generate_exception(ctx, EXCP_RI);
10772 return;
10773 }
10774
10775 t0 = tcg_temp_new();
10776
10777 gen_base_offset_addr(ctx, t0, base, offset);
10778
10779 t1 = tcg_const_tl(reglist);
10780 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10781
3c824109
NF
10782 save_cpu_state(ctx, 1);
10783 switch (opc) {
10784 case LWM32:
895c2d04 10785 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10786 opn = "lwm";
3c824109
NF
10787 break;
10788 case SWM32:
895c2d04 10789 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10790 opn = "swm";
3c824109
NF
10791 break;
10792#ifdef TARGET_MIPS64
10793 case LDM:
895c2d04 10794 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10795 opn = "ldm";
3c824109
NF
10796 break;
10797 case SDM:
895c2d04 10798 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10799 opn = "sdm";
3c824109 10800 break;
6af0bf9c 10801#endif
3c824109 10802 }
e1050a76 10803 (void)opn;
3c824109
NF
10804 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10805 tcg_temp_free(t0);
33087598 10806 tcg_temp_free(t1);
3c824109
NF
10807 tcg_temp_free_i32(t2);
10808}
6af0bf9c 10809
3c824109 10810
240ce26a 10811static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 10812{
3c824109
NF
10813 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10814 int rs = mmreg(ctx->opcode & 0x7);
10815 int opc;
6af0bf9c 10816
3c824109
NF
10817 switch (((ctx->opcode) >> 4) & 0x3f) {
10818 case NOT16 + 0:
10819 case NOT16 + 1:
10820 case NOT16 + 2:
10821 case NOT16 + 3:
d75c135e 10822 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10823 break;
10824 case XOR16 + 0:
10825 case XOR16 + 1:
10826 case XOR16 + 2:
10827 case XOR16 + 3:
d75c135e 10828 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10829 break;
10830 case AND16 + 0:
10831 case AND16 + 1:
10832 case AND16 + 2:
10833 case AND16 + 3:
d75c135e 10834 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10835 break;
10836 case OR16 + 0:
10837 case OR16 + 1:
10838 case OR16 + 2:
10839 case OR16 + 3:
d75c135e 10840 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10841 break;
10842 case LWM16 + 0:
10843 case LWM16 + 1:
10844 case LWM16 + 2:
10845 case LWM16 + 3:
10846 {
10847 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10848 int offset = ZIMM(ctx->opcode, 0, 4);
10849
10850 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10851 29, offset << 2);
10852 }
10853 break;
10854 case SWM16 + 0:
10855 case SWM16 + 1:
10856 case SWM16 + 2:
10857 case SWM16 + 3:
10858 {
10859 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10860 int offset = ZIMM(ctx->opcode, 0, 4);
10861
10862 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10863 29, offset << 2);
10864 }
10865 break;
10866 case JR16 + 0:
10867 case JR16 + 1:
10868 {
10869 int reg = ctx->opcode & 0x1f;
10870
10871 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10872 }
3c824109
NF
10873 break;
10874 case JRC16 + 0:
10875 case JRC16 + 1:
10876 {
10877 int reg = ctx->opcode & 0x1f;
10878
10879 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10880 /* Let normal delay slot handling in our caller take us
10881 to the branch target. */
10882 }
10883 break;
10884 case JALR16 + 0:
10885 case JALR16 + 1:
10886 opc = OPC_JALR;
10887 goto do_jalr;
10888 case JALR16S + 0:
10889 case JALR16S + 1:
10890 opc = OPC_JALRS;
10891 do_jalr:
10892 {
10893 int reg = ctx->opcode & 0x1f;
10894
10895 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10896 }
3c824109
NF
10897 break;
10898 case MFHI16 + 0:
10899 case MFHI16 + 1:
26135ead 10900 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
10901 break;
10902 case MFLO16 + 0:
10903 case MFLO16 + 1:
26135ead 10904 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
10905 break;
10906 case BREAK16:
10907 generate_exception(ctx, EXCP_BREAK);
10908 break;
10909 case SDBBP16:
10910 /* XXX: not clear which exception should be raised
10911 * when in debug mode...
10912 */
d75c135e 10913 check_insn(ctx, ISA_MIPS32);
3c824109
NF
10914 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10915 generate_exception(ctx, EXCP_DBp);
10916 } else {
10917 generate_exception(ctx, EXCP_DBp);
10918 }
10919 break;
10920 case JRADDIUSP + 0:
10921 case JRADDIUSP + 1:
10922 {
10923 int imm = ZIMM(ctx->opcode, 0, 5);
10924
10925 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 10926 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
10927 /* Let normal delay slot handling in our caller take us
10928 to the branch target. */
10929 }
10930 break;
10931 default:
10932 generate_exception(ctx, EXCP_RI);
10933 break;
10934 }
10935}
10936
10937static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10938{
10939 TCGv t0 = tcg_temp_new();
10940 TCGv t1 = tcg_temp_new();
10941
10942 gen_load_gpr(t0, base);
10943
10944 if (index != 0) {
10945 gen_load_gpr(t1, index);
10946 tcg_gen_shli_tl(t1, t1, 2);
10947 gen_op_addr_add(ctx, t0, t1, t0);
10948 }
10949
5f68f5ae 10950 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
10951 gen_store_gpr(t1, rd);
10952
10953 tcg_temp_free(t0);
10954 tcg_temp_free(t1);
10955}
10956
10957static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10958 int base, int16_t offset)
10959{
10960 const char *opn = "ldst_pair";
10961 TCGv t0, t1;
10962
36c6711b 10963 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 10964 generate_exception(ctx, EXCP_RI);
d796321b
FB
10965 return;
10966 }
10967
3c824109
NF
10968 t0 = tcg_temp_new();
10969 t1 = tcg_temp_new();
8e9ade68 10970
3c824109
NF
10971 gen_base_offset_addr(ctx, t0, base, offset);
10972
10973 switch (opc) {
10974 case LWP:
36c6711b
EJ
10975 if (rd == base) {
10976 generate_exception(ctx, EXCP_RI);
10977 return;
10978 }
5f68f5ae 10979 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
10980 gen_store_gpr(t1, rd);
10981 tcg_gen_movi_tl(t1, 4);
10982 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 10983 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
10984 gen_store_gpr(t1, rd+1);
10985 opn = "lwp";
10986 break;
10987 case SWP:
3c824109 10988 gen_load_gpr(t1, rd);
5f68f5ae 10989 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
10990 tcg_gen_movi_tl(t1, 4);
10991 gen_op_addr_add(ctx, t0, t0, t1);
10992 gen_load_gpr(t1, rd+1);
5f68f5ae 10993 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
10994 opn = "swp";
10995 break;
10996#ifdef TARGET_MIPS64
10997 case LDP:
36c6711b
EJ
10998 if (rd == base) {
10999 generate_exception(ctx, EXCP_RI);
11000 return;
11001 }
5f68f5ae 11002 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11003 gen_store_gpr(t1, rd);
11004 tcg_gen_movi_tl(t1, 8);
11005 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11006 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11007 gen_store_gpr(t1, rd+1);
11008 opn = "ldp";
11009 break;
11010 case SDP:
3c824109 11011 gen_load_gpr(t1, rd);
5f68f5ae 11012 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11013 tcg_gen_movi_tl(t1, 8);
11014 gen_op_addr_add(ctx, t0, t0, t1);
11015 gen_load_gpr(t1, rd+1);
5f68f5ae 11016 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11017 opn = "sdp";
11018 break;
11019#endif
6af0bf9c 11020 }
2abf314d 11021 (void)opn; /* avoid a compiler warning */
3c824109
NF
11022 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11023 tcg_temp_free(t0);
11024 tcg_temp_free(t1);
11025}
618b0fe9 11026
240ce26a 11027static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
11028{
11029 int extension = (ctx->opcode >> 6) & 0x3f;
11030 int minor = (ctx->opcode >> 12) & 0xf;
11031 uint32_t mips32_op;
11032
11033 switch (extension) {
11034 case TEQ:
11035 mips32_op = OPC_TEQ;
11036 goto do_trap;
11037 case TGE:
11038 mips32_op = OPC_TGE;
11039 goto do_trap;
11040 case TGEU:
11041 mips32_op = OPC_TGEU;
11042 goto do_trap;
11043 case TLT:
11044 mips32_op = OPC_TLT;
11045 goto do_trap;
11046 case TLTU:
11047 mips32_op = OPC_TLTU;
11048 goto do_trap;
11049 case TNE:
11050 mips32_op = OPC_TNE;
11051 do_trap:
11052 gen_trap(ctx, mips32_op, rs, rt, -1);
11053 break;
11054#ifndef CONFIG_USER_ONLY
11055 case MFC0:
11056 case MFC0 + 32:
2e15497c 11057 check_cp0_enabled(ctx);
3c824109
NF
11058 if (rt == 0) {
11059 /* Treat as NOP. */
11060 break;
11061 }
d75c135e 11062 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11063 break;
11064 case MTC0:
11065 case MTC0 + 32:
2e15497c 11066 check_cp0_enabled(ctx);
3c824109
NF
11067 {
11068 TCGv t0 = tcg_temp_new();
618b0fe9 11069
3c824109 11070 gen_load_gpr(t0, rt);
d75c135e 11071 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11072 tcg_temp_free(t0);
11073 }
11074 break;
11075#endif
a1fc6246
LA
11076 case 0x2a:
11077 switch (minor & 3) {
11078 case MADD_ACC:
11079 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11080 break;
11081 case MADDU_ACC:
11082 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11083 break;
11084 case MSUB_ACC:
11085 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11086 break;
11087 case MSUBU_ACC:
11088 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11089 break;
11090 default:
11091 goto pool32axf_invalid;
11092 }
11093 break;
11094 case 0x32:
11095 switch (minor & 3) {
11096 case MULT_ACC:
11097 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11098 break;
11099 case MULTU_ACC:
11100 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11101 break;
11102 default:
11103 goto pool32axf_invalid;
11104 }
11105 break;
3c824109
NF
11106 case 0x2c:
11107 switch (minor) {
11108 case SEB:
11109 gen_bshfl(ctx, OPC_SEB, rs, rt);
11110 break;
11111 case SEH:
11112 gen_bshfl(ctx, OPC_SEH, rs, rt);
11113 break;
11114 case CLO:
11115 mips32_op = OPC_CLO;
11116 goto do_cl;
11117 case CLZ:
11118 mips32_op = OPC_CLZ;
11119 do_cl:
d75c135e 11120 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11121 gen_cl(ctx, mips32_op, rt, rs);
11122 break;
11123 case RDHWR:
d75c135e 11124 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11125 break;
11126 case WSBH:
11127 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11128 break;
11129 case MULT:
11130 mips32_op = OPC_MULT;
26135ead 11131 goto do_mul;
3c824109
NF
11132 case MULTU:
11133 mips32_op = OPC_MULTU;
26135ead 11134 goto do_mul;
3c824109
NF
11135 case DIV:
11136 mips32_op = OPC_DIV;
26135ead 11137 goto do_div;
3c824109
NF
11138 case DIVU:
11139 mips32_op = OPC_DIVU;
26135ead
RS
11140 goto do_div;
11141 do_div:
11142 check_insn(ctx, ISA_MIPS32);
11143 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11144 break;
3c824109
NF
11145 case MADD:
11146 mips32_op = OPC_MADD;
26135ead 11147 goto do_mul;
3c824109
NF
11148 case MADDU:
11149 mips32_op = OPC_MADDU;
26135ead 11150 goto do_mul;
3c824109
NF
11151 case MSUB:
11152 mips32_op = OPC_MSUB;
26135ead 11153 goto do_mul;
3c824109
NF
11154 case MSUBU:
11155 mips32_op = OPC_MSUBU;
26135ead 11156 do_mul:
d75c135e 11157 check_insn(ctx, ISA_MIPS32);
a1fc6246 11158 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
11159 break;
11160 default:
11161 goto pool32axf_invalid;
11162 }
11163 break;
11164 case 0x34:
11165 switch (minor) {
11166 case MFC2:
11167 case MTC2:
11168 case MFHC2:
11169 case MTHC2:
11170 case CFC2:
11171 case CTC2:
11172 generate_exception_err(ctx, EXCP_CpU, 2);
11173 break;
11174 default:
11175 goto pool32axf_invalid;
11176 }
11177 break;
11178 case 0x3c:
11179 switch (minor) {
11180 case JALR:
11181 case JALR_HB:
11182 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
3c824109
NF
11183 break;
11184 case JALRS:
11185 case JALRS_HB:
11186 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
3c824109
NF
11187 break;
11188 default:
11189 goto pool32axf_invalid;
11190 }
11191 break;
11192 case 0x05:
11193 switch (minor) {
11194 case RDPGPR:
2e15497c 11195 check_cp0_enabled(ctx);
d75c135e 11196 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11197 gen_load_srsgpr(rt, rs);
11198 break;
11199 case WRPGPR:
2e15497c 11200 check_cp0_enabled(ctx);
d75c135e 11201 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11202 gen_store_srsgpr(rt, rs);
11203 break;
11204 default:
11205 goto pool32axf_invalid;
11206 }
11207 break;
11208#ifndef CONFIG_USER_ONLY
11209 case 0x0d:
11210 switch (minor) {
11211 case TLBP:
11212 mips32_op = OPC_TLBP;
11213 goto do_cp0;
11214 case TLBR:
11215 mips32_op = OPC_TLBR;
11216 goto do_cp0;
11217 case TLBWI:
11218 mips32_op = OPC_TLBWI;
11219 goto do_cp0;
11220 case TLBWR:
11221 mips32_op = OPC_TLBWR;
11222 goto do_cp0;
11223 case WAIT:
11224 mips32_op = OPC_WAIT;
11225 goto do_cp0;
11226 case DERET:
11227 mips32_op = OPC_DERET;
11228 goto do_cp0;
11229 case ERET:
11230 mips32_op = OPC_ERET;
11231 do_cp0:
11232 gen_cp0(env, ctx, mips32_op, rt, rs);
11233 break;
11234 default:
11235 goto pool32axf_invalid;
11236 }
11237 break;
11238 case 0x1d:
11239 switch (minor) {
11240 case DI:
2e15497c 11241 check_cp0_enabled(ctx);
3c824109
NF
11242 {
11243 TCGv t0 = tcg_temp_new();
11244
11245 save_cpu_state(ctx, 1);
895c2d04 11246 gen_helper_di(t0, cpu_env);
3c824109
NF
11247 gen_store_gpr(t0, rs);
11248 /* Stop translation as we may have switched the execution mode */
11249 ctx->bstate = BS_STOP;
11250 tcg_temp_free(t0);
11251 }
11252 break;
11253 case EI:
2e15497c 11254 check_cp0_enabled(ctx);
3c824109
NF
11255 {
11256 TCGv t0 = tcg_temp_new();
11257
11258 save_cpu_state(ctx, 1);
895c2d04 11259 gen_helper_ei(t0, cpu_env);
3c824109
NF
11260 gen_store_gpr(t0, rs);
11261 /* Stop translation as we may have switched the execution mode */
11262 ctx->bstate = BS_STOP;
11263 tcg_temp_free(t0);
11264 }
11265 break;
11266 default:
11267 goto pool32axf_invalid;
11268 }
11269 break;
11270#endif
11271 case 0x2d:
11272 switch (minor) {
11273 case SYNC:
11274 /* NOP */
11275 break;
11276 case SYSCALL:
11277 generate_exception(ctx, EXCP_SYSCALL);
11278 ctx->bstate = BS_STOP;
11279 break;
11280 case SDBBP:
d75c135e 11281 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11282 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11283 generate_exception(ctx, EXCP_DBp);
11284 } else {
11285 generate_exception(ctx, EXCP_DBp);
11286 }
11287 break;
11288 default:
11289 goto pool32axf_invalid;
11290 }
11291 break;
a1fc6246 11292 case 0x01:
26135ead 11293 switch (minor & 3) {
a1fc6246 11294 case MFHI_ACC:
26135ead 11295 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 11296 break;
a1fc6246 11297 case MFLO_ACC:
26135ead 11298 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 11299 break;
a1fc6246 11300 case MTHI_ACC:
26135ead 11301 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 11302 break;
a1fc6246 11303 case MTLO_ACC:
26135ead 11304 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
11305 break;
11306 default:
11307 goto pool32axf_invalid;
11308 }
11309 break;
a1fc6246
LA
11310 case 0x35:
11311 switch (minor) {
11312 case MFHI32:
11313 gen_HILO(ctx, OPC_MFHI, 0, rs);
11314 break;
11315 case MFLO32:
11316 gen_HILO(ctx, OPC_MFLO, 0, rs);
11317 break;
11318 case MTHI32:
11319 gen_HILO(ctx, OPC_MTHI, 0, rs);
11320 break;
11321 case MTLO32:
11322 gen_HILO(ctx, OPC_MTLO, 0, rs);
11323 break;
11324 default:
11325 goto pool32axf_invalid;
11326 }
11327 break;
3c824109
NF
11328 default:
11329 pool32axf_invalid:
11330 MIPS_INVAL("pool32axf");
11331 generate_exception(ctx, EXCP_RI);
11332 break;
11333 }
11334}
11335
11336/* Values for microMIPS fmt field. Variable-width, depending on which
11337 formats the instruction supports. */
11338
11339enum {
11340 FMT_SD_S = 0,
11341 FMT_SD_D = 1,
11342
11343 FMT_SDPS_S = 0,
11344 FMT_SDPS_D = 1,
11345 FMT_SDPS_PS = 2,
11346
11347 FMT_SWL_S = 0,
11348 FMT_SWL_W = 1,
11349 FMT_SWL_L = 2,
11350
11351 FMT_DWL_D = 0,
11352 FMT_DWL_W = 1,
11353 FMT_DWL_L = 2
11354};
11355
d75c135e 11356static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11357{
11358 int extension = (ctx->opcode >> 6) & 0x3ff;
11359 uint32_t mips32_op;
11360
11361#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11362#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11363#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11364
11365 switch (extension) {
11366 case FLOAT_1BIT_FMT(CFC1, 0):
11367 mips32_op = OPC_CFC1;
11368 goto do_cp1;
11369 case FLOAT_1BIT_FMT(CTC1, 0):
11370 mips32_op = OPC_CTC1;
11371 goto do_cp1;
11372 case FLOAT_1BIT_FMT(MFC1, 0):
11373 mips32_op = OPC_MFC1;
11374 goto do_cp1;
11375 case FLOAT_1BIT_FMT(MTC1, 0):
11376 mips32_op = OPC_MTC1;
11377 goto do_cp1;
11378 case FLOAT_1BIT_FMT(MFHC1, 0):
11379 mips32_op = OPC_MFHC1;
11380 goto do_cp1;
11381 case FLOAT_1BIT_FMT(MTHC1, 0):
11382 mips32_op = OPC_MTHC1;
11383 do_cp1:
11384 gen_cp1(ctx, mips32_op, rt, rs);
11385 break;
11386
11387 /* Reciprocal square root */
11388 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11389 mips32_op = OPC_RSQRT_S;
11390 goto do_unaryfp;
11391 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11392 mips32_op = OPC_RSQRT_D;
11393 goto do_unaryfp;
11394
11395 /* Square root */
11396 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11397 mips32_op = OPC_SQRT_S;
11398 goto do_unaryfp;
11399 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11400 mips32_op = OPC_SQRT_D;
11401 goto do_unaryfp;
11402
11403 /* Reciprocal */
11404 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11405 mips32_op = OPC_RECIP_S;
11406 goto do_unaryfp;
11407 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11408 mips32_op = OPC_RECIP_D;
11409 goto do_unaryfp;
11410
11411 /* Floor */
11412 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11413 mips32_op = OPC_FLOOR_L_S;
11414 goto do_unaryfp;
11415 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11416 mips32_op = OPC_FLOOR_L_D;
11417 goto do_unaryfp;
11418 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11419 mips32_op = OPC_FLOOR_W_S;
11420 goto do_unaryfp;
11421 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11422 mips32_op = OPC_FLOOR_W_D;
11423 goto do_unaryfp;
11424
11425 /* Ceiling */
11426 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11427 mips32_op = OPC_CEIL_L_S;
11428 goto do_unaryfp;
11429 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11430 mips32_op = OPC_CEIL_L_D;
11431 goto do_unaryfp;
11432 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11433 mips32_op = OPC_CEIL_W_S;
11434 goto do_unaryfp;
11435 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11436 mips32_op = OPC_CEIL_W_D;
11437 goto do_unaryfp;
11438
11439 /* Truncation */
11440 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11441 mips32_op = OPC_TRUNC_L_S;
11442 goto do_unaryfp;
11443 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11444 mips32_op = OPC_TRUNC_L_D;
11445 goto do_unaryfp;
11446 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11447 mips32_op = OPC_TRUNC_W_S;
11448 goto do_unaryfp;
11449 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11450 mips32_op = OPC_TRUNC_W_D;
11451 goto do_unaryfp;
11452
11453 /* Round */
11454 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11455 mips32_op = OPC_ROUND_L_S;
11456 goto do_unaryfp;
11457 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11458 mips32_op = OPC_ROUND_L_D;
11459 goto do_unaryfp;
11460 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11461 mips32_op = OPC_ROUND_W_S;
11462 goto do_unaryfp;
11463 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11464 mips32_op = OPC_ROUND_W_D;
11465 goto do_unaryfp;
11466
11467 /* Integer to floating-point conversion */
11468 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11469 mips32_op = OPC_CVT_L_S;
11470 goto do_unaryfp;
11471 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11472 mips32_op = OPC_CVT_L_D;
11473 goto do_unaryfp;
11474 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11475 mips32_op = OPC_CVT_W_S;
11476 goto do_unaryfp;
11477 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11478 mips32_op = OPC_CVT_W_D;
11479 goto do_unaryfp;
11480
11481 /* Paired-foo conversions */
11482 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11483 mips32_op = OPC_CVT_S_PL;
11484 goto do_unaryfp;
11485 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11486 mips32_op = OPC_CVT_S_PU;
11487 goto do_unaryfp;
11488 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11489 mips32_op = OPC_CVT_PW_PS;
11490 goto do_unaryfp;
11491 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11492 mips32_op = OPC_CVT_PS_PW;
11493 goto do_unaryfp;
11494
11495 /* Floating-point moves */
11496 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11497 mips32_op = OPC_MOV_S;
11498 goto do_unaryfp;
11499 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11500 mips32_op = OPC_MOV_D;
11501 goto do_unaryfp;
11502 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11503 mips32_op = OPC_MOV_PS;
11504 goto do_unaryfp;
11505
11506 /* Absolute value */
11507 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11508 mips32_op = OPC_ABS_S;
11509 goto do_unaryfp;
11510 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11511 mips32_op = OPC_ABS_D;
11512 goto do_unaryfp;
11513 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11514 mips32_op = OPC_ABS_PS;
11515 goto do_unaryfp;
11516
11517 /* Negation */
11518 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11519 mips32_op = OPC_NEG_S;
11520 goto do_unaryfp;
11521 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11522 mips32_op = OPC_NEG_D;
11523 goto do_unaryfp;
11524 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11525 mips32_op = OPC_NEG_PS;
11526 goto do_unaryfp;
11527
11528 /* Reciprocal square root step */
11529 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11530 mips32_op = OPC_RSQRT1_S;
11531 goto do_unaryfp;
11532 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11533 mips32_op = OPC_RSQRT1_D;
11534 goto do_unaryfp;
11535 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11536 mips32_op = OPC_RSQRT1_PS;
11537 goto do_unaryfp;
11538
11539 /* Reciprocal step */
11540 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11541 mips32_op = OPC_RECIP1_S;
11542 goto do_unaryfp;
11543 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11544 mips32_op = OPC_RECIP1_S;
11545 goto do_unaryfp;
11546 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11547 mips32_op = OPC_RECIP1_PS;
11548 goto do_unaryfp;
11549
11550 /* Conversions from double */
11551 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11552 mips32_op = OPC_CVT_D_S;
11553 goto do_unaryfp;
11554 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11555 mips32_op = OPC_CVT_D_W;
11556 goto do_unaryfp;
11557 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11558 mips32_op = OPC_CVT_D_L;
11559 goto do_unaryfp;
11560
11561 /* Conversions from single */
11562 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11563 mips32_op = OPC_CVT_S_D;
11564 goto do_unaryfp;
11565 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11566 mips32_op = OPC_CVT_S_W;
11567 goto do_unaryfp;
11568 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11569 mips32_op = OPC_CVT_S_L;
11570 do_unaryfp:
11571 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11572 break;
11573
11574 /* Conditional moves on floating-point codes */
11575 case COND_FLOAT_MOV(MOVT, 0):
11576 case COND_FLOAT_MOV(MOVT, 1):
11577 case COND_FLOAT_MOV(MOVT, 2):
11578 case COND_FLOAT_MOV(MOVT, 3):
11579 case COND_FLOAT_MOV(MOVT, 4):
11580 case COND_FLOAT_MOV(MOVT, 5):
11581 case COND_FLOAT_MOV(MOVT, 6):
11582 case COND_FLOAT_MOV(MOVT, 7):
11583 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11584 break;
11585 case COND_FLOAT_MOV(MOVF, 0):
11586 case COND_FLOAT_MOV(MOVF, 1):
11587 case COND_FLOAT_MOV(MOVF, 2):
11588 case COND_FLOAT_MOV(MOVF, 3):
11589 case COND_FLOAT_MOV(MOVF, 4):
11590 case COND_FLOAT_MOV(MOVF, 5):
11591 case COND_FLOAT_MOV(MOVF, 6):
11592 case COND_FLOAT_MOV(MOVF, 7):
11593 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11594 break;
11595 default:
11596 MIPS_INVAL("pool32fxf");
11597 generate_exception(ctx, EXCP_RI);
11598 break;
11599 }
11600}
11601
7db13fae 11602static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 11603 uint16_t insn_hw1)
3c824109
NF
11604{
11605 int32_t offset;
11606 uint16_t insn;
11607 int rt, rs, rd, rr;
11608 int16_t imm;
11609 uint32_t op, minor, mips32_op;
11610 uint32_t cond, fmt, cc;
11611
895c2d04 11612 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11613 ctx->opcode = (ctx->opcode << 16) | insn;
11614
11615 rt = (ctx->opcode >> 21) & 0x1f;
11616 rs = (ctx->opcode >> 16) & 0x1f;
11617 rd = (ctx->opcode >> 11) & 0x1f;
11618 rr = (ctx->opcode >> 6) & 0x1f;
11619 imm = (int16_t) ctx->opcode;
11620
11621 op = (ctx->opcode >> 26) & 0x3f;
11622 switch (op) {
11623 case POOL32A:
11624 minor = ctx->opcode & 0x3f;
11625 switch (minor) {
11626 case 0x00:
11627 minor = (ctx->opcode >> 6) & 0xf;
11628 switch (minor) {
11629 case SLL32:
11630 mips32_op = OPC_SLL;
11631 goto do_shifti;
11632 case SRA:
11633 mips32_op = OPC_SRA;
11634 goto do_shifti;
11635 case SRL32:
11636 mips32_op = OPC_SRL;
11637 goto do_shifti;
11638 case ROTR:
11639 mips32_op = OPC_ROTR;
11640 do_shifti:
d75c135e 11641 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
11642 break;
11643 default:
11644 goto pool32a_invalid;
11645 }
11646 break;
11647 case 0x10:
11648 minor = (ctx->opcode >> 6) & 0xf;
11649 switch (minor) {
11650 /* Arithmetic */
11651 case ADD:
11652 mips32_op = OPC_ADD;
11653 goto do_arith;
11654 case ADDU32:
11655 mips32_op = OPC_ADDU;
11656 goto do_arith;
11657 case SUB:
11658 mips32_op = OPC_SUB;
11659 goto do_arith;
11660 case SUBU32:
11661 mips32_op = OPC_SUBU;
11662 goto do_arith;
11663 case MUL:
11664 mips32_op = OPC_MUL;
11665 do_arith:
d75c135e 11666 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11667 break;
11668 /* Shifts */
11669 case SLLV:
11670 mips32_op = OPC_SLLV;
11671 goto do_shift;
11672 case SRLV:
11673 mips32_op = OPC_SRLV;
11674 goto do_shift;
11675 case SRAV:
11676 mips32_op = OPC_SRAV;
11677 goto do_shift;
11678 case ROTRV:
11679 mips32_op = OPC_ROTRV;
11680 do_shift:
d75c135e 11681 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11682 break;
11683 /* Logical operations */
11684 case AND:
11685 mips32_op = OPC_AND;
11686 goto do_logic;
11687 case OR32:
11688 mips32_op = OPC_OR;
11689 goto do_logic;
11690 case NOR:
11691 mips32_op = OPC_NOR;
11692 goto do_logic;
11693 case XOR32:
11694 mips32_op = OPC_XOR;
11695 do_logic:
d75c135e 11696 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11697 break;
11698 /* Set less than */
11699 case SLT:
11700 mips32_op = OPC_SLT;
11701 goto do_slt;
11702 case SLTU:
11703 mips32_op = OPC_SLTU;
11704 do_slt:
d75c135e 11705 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11706 break;
11707 default:
11708 goto pool32a_invalid;
11709 }
11710 break;
11711 case 0x18:
11712 minor = (ctx->opcode >> 6) & 0xf;
11713 switch (minor) {
11714 /* Conditional moves */
11715 case MOVN:
11716 mips32_op = OPC_MOVN;
11717 goto do_cmov;
11718 case MOVZ:
11719 mips32_op = OPC_MOVZ;
11720 do_cmov:
d75c135e 11721 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11722 break;
11723 case LWXS:
11724 gen_ldxs(ctx, rs, rt, rd);
11725 break;
11726 default:
11727 goto pool32a_invalid;
11728 }
11729 break;
11730 case INS:
11731 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11732 return;
11733 case EXT:
11734 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11735 return;
11736 case POOL32AXF:
240ce26a 11737 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
11738 break;
11739 case 0x07:
11740 generate_exception(ctx, EXCP_BREAK);
11741 break;
11742 default:
11743 pool32a_invalid:
11744 MIPS_INVAL("pool32a");
11745 generate_exception(ctx, EXCP_RI);
11746 break;
11747 }
11748 break;
11749 case POOL32B:
11750 minor = (ctx->opcode >> 12) & 0xf;
11751 switch (minor) {
11752 case CACHE:
2e15497c 11753 check_cp0_enabled(ctx);
3c824109
NF
11754 /* Treat as no-op. */
11755 break;
11756 case LWC2:
11757 case SWC2:
11758 /* COP2: Not implemented. */
11759 generate_exception_err(ctx, EXCP_CpU, 2);
11760 break;
11761 case LWP:
11762 case SWP:
11763#ifdef TARGET_MIPS64
11764 case LDP:
11765 case SDP:
11766#endif
11767 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11768 break;
11769 case LWM32:
11770 case SWM32:
11771#ifdef TARGET_MIPS64
11772 case LDM:
11773 case SDM:
11774#endif
11775 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11776 break;
11777 default:
11778 MIPS_INVAL("pool32b");
11779 generate_exception(ctx, EXCP_RI);
11780 break;
11781 }
11782 break;
11783 case POOL32F:
11784 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11785 minor = ctx->opcode & 0x3f;
11786 check_cp1_enabled(ctx);
11787 switch (minor) {
11788 case ALNV_PS:
11789 mips32_op = OPC_ALNV_PS;
11790 goto do_madd;
11791 case MADD_S:
11792 mips32_op = OPC_MADD_S;
11793 goto do_madd;
11794 case MADD_D:
11795 mips32_op = OPC_MADD_D;
11796 goto do_madd;
11797 case MADD_PS:
11798 mips32_op = OPC_MADD_PS;
11799 goto do_madd;
11800 case MSUB_S:
11801 mips32_op = OPC_MSUB_S;
11802 goto do_madd;
11803 case MSUB_D:
11804 mips32_op = OPC_MSUB_D;
11805 goto do_madd;
11806 case MSUB_PS:
11807 mips32_op = OPC_MSUB_PS;
11808 goto do_madd;
11809 case NMADD_S:
11810 mips32_op = OPC_NMADD_S;
11811 goto do_madd;
11812 case NMADD_D:
11813 mips32_op = OPC_NMADD_D;
11814 goto do_madd;
11815 case NMADD_PS:
11816 mips32_op = OPC_NMADD_PS;
11817 goto do_madd;
11818 case NMSUB_S:
11819 mips32_op = OPC_NMSUB_S;
11820 goto do_madd;
11821 case NMSUB_D:
11822 mips32_op = OPC_NMSUB_D;
11823 goto do_madd;
11824 case NMSUB_PS:
11825 mips32_op = OPC_NMSUB_PS;
11826 do_madd:
11827 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11828 break;
11829 case CABS_COND_FMT:
11830 cond = (ctx->opcode >> 6) & 0xf;
11831 cc = (ctx->opcode >> 13) & 0x7;
11832 fmt = (ctx->opcode >> 10) & 0x3;
11833 switch (fmt) {
11834 case 0x0:
11835 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11836 break;
11837 case 0x1:
11838 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11839 break;
11840 case 0x2:
11841 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11842 break;
11843 default:
11844 goto pool32f_invalid;
11845 }
11846 break;
11847 case C_COND_FMT:
11848 cond = (ctx->opcode >> 6) & 0xf;
11849 cc = (ctx->opcode >> 13) & 0x7;
11850 fmt = (ctx->opcode >> 10) & 0x3;
11851 switch (fmt) {
11852 case 0x0:
11853 gen_cmp_s(ctx, cond, rt, rs, cc);
11854 break;
11855 case 0x1:
11856 gen_cmp_d(ctx, cond, rt, rs, cc);
11857 break;
11858 case 0x2:
11859 gen_cmp_ps(ctx, cond, rt, rs, cc);
11860 break;
11861 default:
11862 goto pool32f_invalid;
11863 }
11864 break;
11865 case POOL32FXF:
d75c135e 11866 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
11867 break;
11868 case 0x00:
11869 /* PLL foo */
11870 switch ((ctx->opcode >> 6) & 0x7) {
11871 case PLL_PS:
11872 mips32_op = OPC_PLL_PS;
11873 goto do_ps;
11874 case PLU_PS:
11875 mips32_op = OPC_PLU_PS;
11876 goto do_ps;
11877 case PUL_PS:
11878 mips32_op = OPC_PUL_PS;
11879 goto do_ps;
11880 case PUU_PS:
11881 mips32_op = OPC_PUU_PS;
11882 goto do_ps;
11883 case CVT_PS_S:
11884 mips32_op = OPC_CVT_PS_S;
11885 do_ps:
11886 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11887 break;
11888 default:
11889 goto pool32f_invalid;
11890 }
11891 break;
11892 case 0x08:
11893 /* [LS][WDU]XC1 */
11894 switch ((ctx->opcode >> 6) & 0x7) {
11895 case LWXC1:
11896 mips32_op = OPC_LWXC1;
11897 goto do_ldst_cp1;
11898 case SWXC1:
11899 mips32_op = OPC_SWXC1;
11900 goto do_ldst_cp1;
11901 case LDXC1:
11902 mips32_op = OPC_LDXC1;
11903 goto do_ldst_cp1;
11904 case SDXC1:
11905 mips32_op = OPC_SDXC1;
11906 goto do_ldst_cp1;
11907 case LUXC1:
11908 mips32_op = OPC_LUXC1;
11909 goto do_ldst_cp1;
11910 case SUXC1:
11911 mips32_op = OPC_SUXC1;
11912 do_ldst_cp1:
11913 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11914 break;
11915 default:
11916 goto pool32f_invalid;
11917 }
11918 break;
11919 case 0x18:
11920 /* 3D insns */
11921 fmt = (ctx->opcode >> 9) & 0x3;
11922 switch ((ctx->opcode >> 6) & 0x7) {
11923 case RSQRT2_FMT:
11924 switch (fmt) {
11925 case FMT_SDPS_S:
11926 mips32_op = OPC_RSQRT2_S;
11927 goto do_3d;
11928 case FMT_SDPS_D:
11929 mips32_op = OPC_RSQRT2_D;
11930 goto do_3d;
11931 case FMT_SDPS_PS:
11932 mips32_op = OPC_RSQRT2_PS;
11933 goto do_3d;
11934 default:
11935 goto pool32f_invalid;
11936 }
11937 break;
11938 case RECIP2_FMT:
11939 switch (fmt) {
11940 case FMT_SDPS_S:
11941 mips32_op = OPC_RECIP2_S;
11942 goto do_3d;
11943 case FMT_SDPS_D:
11944 mips32_op = OPC_RECIP2_D;
11945 goto do_3d;
11946 case FMT_SDPS_PS:
11947 mips32_op = OPC_RECIP2_PS;
11948 goto do_3d;
11949 default:
11950 goto pool32f_invalid;
11951 }
11952 break;
11953 case ADDR_PS:
11954 mips32_op = OPC_ADDR_PS;
11955 goto do_3d;
11956 case MULR_PS:
11957 mips32_op = OPC_MULR_PS;
11958 do_3d:
11959 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11960 break;
11961 default:
11962 goto pool32f_invalid;
11963 }
11964 break;
11965 case 0x20:
11966 /* MOV[FT].fmt and PREFX */
11967 cc = (ctx->opcode >> 13) & 0x7;
11968 fmt = (ctx->opcode >> 9) & 0x3;
11969 switch ((ctx->opcode >> 6) & 0x7) {
11970 case MOVF_FMT:
11971 switch (fmt) {
11972 case FMT_SDPS_S:
11973 gen_movcf_s(rs, rt, cc, 0);
11974 break;
11975 case FMT_SDPS_D:
11976 gen_movcf_d(ctx, rs, rt, cc, 0);
11977 break;
11978 case FMT_SDPS_PS:
11979 gen_movcf_ps(rs, rt, cc, 0);
11980 break;
11981 default:
11982 goto pool32f_invalid;
11983 }
11984 break;
11985 case MOVT_FMT:
11986 switch (fmt) {
11987 case FMT_SDPS_S:
11988 gen_movcf_s(rs, rt, cc, 1);
11989 break;
11990 case FMT_SDPS_D:
11991 gen_movcf_d(ctx, rs, rt, cc, 1);
11992 break;
11993 case FMT_SDPS_PS:
11994 gen_movcf_ps(rs, rt, cc, 1);
11995 break;
11996 default:
11997 goto pool32f_invalid;
11998 }
11999 break;
12000 case PREFX:
12001 break;
12002 default:
12003 goto pool32f_invalid;
12004 }
12005 break;
12006#define FINSN_3ARG_SDPS(prfx) \
12007 switch ((ctx->opcode >> 8) & 0x3) { \
12008 case FMT_SDPS_S: \
12009 mips32_op = OPC_##prfx##_S; \
12010 goto do_fpop; \
12011 case FMT_SDPS_D: \
12012 mips32_op = OPC_##prfx##_D; \
12013 goto do_fpop; \
12014 case FMT_SDPS_PS: \
12015 mips32_op = OPC_##prfx##_PS; \
12016 goto do_fpop; \
12017 default: \
12018 goto pool32f_invalid; \
12019 }
12020 case 0x30:
12021 /* regular FP ops */
12022 switch ((ctx->opcode >> 6) & 0x3) {
12023 case ADD_FMT:
12024 FINSN_3ARG_SDPS(ADD);
12025 break;
12026 case SUB_FMT:
12027 FINSN_3ARG_SDPS(SUB);
12028 break;
12029 case MUL_FMT:
12030 FINSN_3ARG_SDPS(MUL);
12031 break;
12032 case DIV_FMT:
12033 fmt = (ctx->opcode >> 8) & 0x3;
12034 if (fmt == 1) {
12035 mips32_op = OPC_DIV_D;
12036 } else if (fmt == 0) {
12037 mips32_op = OPC_DIV_S;
12038 } else {
12039 goto pool32f_invalid;
12040 }
12041 goto do_fpop;
12042 default:
12043 goto pool32f_invalid;
12044 }
12045 break;
12046 case 0x38:
12047 /* cmovs */
12048 switch ((ctx->opcode >> 6) & 0x3) {
12049 case MOVN_FMT:
12050 FINSN_3ARG_SDPS(MOVN);
12051 break;
12052 case MOVZ_FMT:
12053 FINSN_3ARG_SDPS(MOVZ);
12054 break;
12055 default:
12056 goto pool32f_invalid;
12057 }
12058 break;
12059 do_fpop:
12060 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12061 break;
12062 default:
12063 pool32f_invalid:
12064 MIPS_INVAL("pool32f");
12065 generate_exception(ctx, EXCP_RI);
12066 break;
12067 }
12068 } else {
12069 generate_exception_err(ctx, EXCP_CpU, 1);
12070 }
12071 break;
12072 case POOL32I:
12073 minor = (ctx->opcode >> 21) & 0x1f;
12074 switch (minor) {
12075 case BLTZ:
12076 mips32_op = OPC_BLTZ;
12077 goto do_branch;
12078 case BLTZAL:
12079 mips32_op = OPC_BLTZAL;
12080 goto do_branch;
12081 case BLTZALS:
12082 mips32_op = OPC_BLTZALS;
12083 goto do_branch;
12084 case BGEZ:
12085 mips32_op = OPC_BGEZ;
12086 goto do_branch;
12087 case BGEZAL:
12088 mips32_op = OPC_BGEZAL;
12089 goto do_branch;
12090 case BGEZALS:
12091 mips32_op = OPC_BGEZALS;
12092 goto do_branch;
12093 case BLEZ:
12094 mips32_op = OPC_BLEZ;
12095 goto do_branch;
12096 case BGTZ:
12097 mips32_op = OPC_BGTZ;
12098 do_branch:
12099 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
3c824109
NF
12100 break;
12101
12102 /* Traps */
12103 case TLTI:
12104 mips32_op = OPC_TLTI;
12105 goto do_trapi;
12106 case TGEI:
12107 mips32_op = OPC_TGEI;
12108 goto do_trapi;
12109 case TLTIU:
12110 mips32_op = OPC_TLTIU;
12111 goto do_trapi;
12112 case TGEIU:
12113 mips32_op = OPC_TGEIU;
12114 goto do_trapi;
12115 case TNEI:
12116 mips32_op = OPC_TNEI;
12117 goto do_trapi;
12118 case TEQI:
12119 mips32_op = OPC_TEQI;
12120 do_trapi:
12121 gen_trap(ctx, mips32_op, rs, -1, imm);
12122 break;
12123
12124 case BNEZC:
12125 case BEQZC:
12126 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12127 4, rs, 0, imm << 1);
12128 /* Compact branches don't have a delay slot, so just let
12129 the normal delay slot handling take us to the branch
12130 target. */
12131 break;
12132 case LUI:
d75c135e 12133 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12134 break;
12135 case SYNCI:
12136 break;
12137 case BC2F:
12138 case BC2T:
12139 /* COP2: Not implemented. */
12140 generate_exception_err(ctx, EXCP_CpU, 2);
12141 break;
12142 case BC1F:
12143 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12144 goto do_cp1branch;
12145 case BC1T:
12146 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12147 goto do_cp1branch;
12148 case BC1ANY4F:
12149 mips32_op = OPC_BC1FANY4;
12150 goto do_cp1mips3d;
12151 case BC1ANY4T:
12152 mips32_op = OPC_BC1TANY4;
12153 do_cp1mips3d:
12154 check_cop1x(ctx);
d75c135e 12155 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12156 /* Fall through */
12157 do_cp1branch:
d75c135e 12158 gen_compute_branch1(ctx, mips32_op,
3c824109 12159 (ctx->opcode >> 18) & 0x7, imm << 1);
3c824109
NF
12160 break;
12161 case BPOSGE64:
12162 case BPOSGE32:
12163 /* MIPS DSP: not implemented */
12164 /* Fall through */
12165 default:
12166 MIPS_INVAL("pool32i");
12167 generate_exception(ctx, EXCP_RI);
12168 break;
12169 }
12170 break;
12171 case POOL32C:
12172 minor = (ctx->opcode >> 12) & 0xf;
12173 switch (minor) {
12174 case LWL:
12175 mips32_op = OPC_LWL;
5c13fdfd 12176 goto do_ld_lr;
3c824109
NF
12177 case SWL:
12178 mips32_op = OPC_SWL;
5c13fdfd 12179 goto do_st_lr;
3c824109
NF
12180 case LWR:
12181 mips32_op = OPC_LWR;
5c13fdfd 12182 goto do_ld_lr;
3c824109
NF
12183 case SWR:
12184 mips32_op = OPC_SWR;
5c13fdfd 12185 goto do_st_lr;
3c824109
NF
12186#if defined(TARGET_MIPS64)
12187 case LDL:
12188 mips32_op = OPC_LDL;
5c13fdfd 12189 goto do_ld_lr;
3c824109
NF
12190 case SDL:
12191 mips32_op = OPC_SDL;
5c13fdfd 12192 goto do_st_lr;
3c824109
NF
12193 case LDR:
12194 mips32_op = OPC_LDR;
5c13fdfd 12195 goto do_ld_lr;
3c824109
NF
12196 case SDR:
12197 mips32_op = OPC_SDR;
5c13fdfd 12198 goto do_st_lr;
3c824109
NF
12199 case LWU:
12200 mips32_op = OPC_LWU;
5c13fdfd 12201 goto do_ld_lr;
3c824109
NF
12202 case LLD:
12203 mips32_op = OPC_LLD;
5c13fdfd 12204 goto do_ld_lr;
3c824109
NF
12205#endif
12206 case LL:
12207 mips32_op = OPC_LL;
5c13fdfd
AJ
12208 goto do_ld_lr;
12209 do_ld_lr:
d75c135e 12210 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12211 break;
12212 do_st_lr:
12213 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12214 break;
12215 case SC:
12216 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12217 break;
12218#if defined(TARGET_MIPS64)
12219 case SCD:
12220 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12221 break;
12222#endif
12223 case PREF:
12224 /* Treat as no-op */
12225 break;
12226 default:
12227 MIPS_INVAL("pool32c");
12228 generate_exception(ctx, EXCP_RI);
12229 break;
12230 }
12231 break;
12232 case ADDI32:
12233 mips32_op = OPC_ADDI;
12234 goto do_addi;
12235 case ADDIU32:
12236 mips32_op = OPC_ADDIU;
12237 do_addi:
d75c135e 12238 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12239 break;
12240
12241 /* Logical operations */
12242 case ORI32:
12243 mips32_op = OPC_ORI;
12244 goto do_logici;
12245 case XORI32:
12246 mips32_op = OPC_XORI;
12247 goto do_logici;
12248 case ANDI32:
12249 mips32_op = OPC_ANDI;
12250 do_logici:
d75c135e 12251 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12252 break;
12253
12254 /* Set less than immediate */
12255 case SLTI32:
12256 mips32_op = OPC_SLTI;
12257 goto do_slti;
12258 case SLTIU32:
12259 mips32_op = OPC_SLTIU;
12260 do_slti:
d75c135e 12261 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12262 break;
12263 case JALX32:
12264 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12265 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
3c824109
NF
12266 break;
12267 case JALS32:
12268 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12269 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
3c824109
NF
12270 break;
12271 case BEQ32:
12272 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
3c824109
NF
12273 break;
12274 case BNE32:
12275 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
3c824109
NF
12276 break;
12277 case J32:
12278 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12279 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12280 break;
12281 case JAL32:
12282 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12283 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12284 break;
12285 /* Floating point (COP1) */
12286 case LWC132:
12287 mips32_op = OPC_LWC1;
12288 goto do_cop1;
12289 case LDC132:
12290 mips32_op = OPC_LDC1;
12291 goto do_cop1;
12292 case SWC132:
12293 mips32_op = OPC_SWC1;
12294 goto do_cop1;
12295 case SDC132:
12296 mips32_op = OPC_SDC1;
12297 do_cop1:
12298 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12299 break;
12300 case ADDIUPC:
12301 {
12302 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12303 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12304
12305 gen_addiupc(ctx, reg, offset, 0, 0);
12306 }
12307 break;
12308 /* Loads and stores */
12309 case LB32:
12310 mips32_op = OPC_LB;
5c13fdfd 12311 goto do_ld;
3c824109
NF
12312 case LBU32:
12313 mips32_op = OPC_LBU;
5c13fdfd 12314 goto do_ld;
3c824109
NF
12315 case LH32:
12316 mips32_op = OPC_LH;
5c13fdfd 12317 goto do_ld;
3c824109
NF
12318 case LHU32:
12319 mips32_op = OPC_LHU;
5c13fdfd 12320 goto do_ld;
3c824109
NF
12321 case LW32:
12322 mips32_op = OPC_LW;
5c13fdfd 12323 goto do_ld;
3c824109
NF
12324#ifdef TARGET_MIPS64
12325 case LD32:
12326 mips32_op = OPC_LD;
5c13fdfd 12327 goto do_ld;
3c824109
NF
12328 case SD32:
12329 mips32_op = OPC_SD;
5c13fdfd 12330 goto do_st;
3c824109
NF
12331#endif
12332 case SB32:
12333 mips32_op = OPC_SB;
5c13fdfd 12334 goto do_st;
3c824109
NF
12335 case SH32:
12336 mips32_op = OPC_SH;
5c13fdfd 12337 goto do_st;
3c824109
NF
12338 case SW32:
12339 mips32_op = OPC_SW;
5c13fdfd
AJ
12340 goto do_st;
12341 do_ld:
d75c135e 12342 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12343 break;
12344 do_st:
12345 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12346 break;
12347 default:
12348 generate_exception(ctx, EXCP_RI);
12349 break;
12350 }
12351}
12352
240ce26a 12353static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
12354{
12355 uint32_t op;
12356
12357 /* make sure instructions are on a halfword boundary */
12358 if (ctx->pc & 0x1) {
12359 env->CP0_BadVAddr = ctx->pc;
12360 generate_exception(ctx, EXCP_AdEL);
12361 ctx->bstate = BS_STOP;
12362 return 2;
12363 }
12364
12365 op = (ctx->opcode >> 10) & 0x3f;
12366 /* Enforce properly-sized instructions in a delay slot */
12367 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12368 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12369
12370 switch (op) {
12371 case POOL32A:
12372 case POOL32B:
12373 case POOL32I:
12374 case POOL32C:
12375 case ADDI32:
12376 case ADDIU32:
12377 case ORI32:
12378 case XORI32:
12379 case SLTI32:
12380 case SLTIU32:
12381 case ANDI32:
12382 case JALX32:
12383 case LBU32:
12384 case LHU32:
12385 case POOL32F:
12386 case JALS32:
12387 case BEQ32:
12388 case BNE32:
12389 case J32:
12390 case JAL32:
12391 case SB32:
12392 case SH32:
12393 case POOL32S:
12394 case ADDIUPC:
12395 case SWC132:
12396 case SDC132:
12397 case SD32:
12398 case SW32:
12399 case LB32:
12400 case LH32:
12401 case DADDIU32:
3c824109
NF
12402 case LWC132:
12403 case LDC132:
12404 case LD32:
12405 case LW32:
12406 if (bits & MIPS_HFLAG_BDS16) {
12407 generate_exception(ctx, EXCP_RI);
12408 /* Just stop translation; the user is confused. */
12409 ctx->bstate = BS_STOP;
12410 return 2;
12411 }
12412 break;
12413 case POOL16A:
12414 case POOL16B:
12415 case POOL16C:
12416 case LWGP16:
12417 case POOL16F:
12418 case LBU16:
12419 case LHU16:
12420 case LWSP16:
12421 case LW16:
12422 case SB16:
12423 case SH16:
12424 case SWSP16:
12425 case SW16:
12426 case MOVE16:
12427 case ANDI16:
12428 case POOL16D:
12429 case POOL16E:
12430 case BEQZ16:
12431 case BNEZ16:
12432 case B16:
12433 case LI16:
12434 if (bits & MIPS_HFLAG_BDS32) {
12435 generate_exception(ctx, EXCP_RI);
12436 /* Just stop translation; the user is confused. */
12437 ctx->bstate = BS_STOP;
12438 return 2;
12439 }
12440 break;
12441 default:
12442 break;
12443 }
12444 }
12445 switch (op) {
12446 case POOL16A:
12447 {
12448 int rd = mmreg(uMIPS_RD(ctx->opcode));
12449 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12450 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12451 uint32_t opc = 0;
12452
12453 switch (ctx->opcode & 0x1) {
12454 case ADDU16:
12455 opc = OPC_ADDU;
12456 break;
12457 case SUBU16:
12458 opc = OPC_SUBU;
12459 break;
12460 }
12461
d75c135e 12462 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12463 }
12464 break;
12465 case POOL16B:
12466 {
12467 int rd = mmreg(uMIPS_RD(ctx->opcode));
12468 int rs = mmreg(uMIPS_RS(ctx->opcode));
12469 int amount = (ctx->opcode >> 1) & 0x7;
12470 uint32_t opc = 0;
12471 amount = amount == 0 ? 8 : amount;
12472
12473 switch (ctx->opcode & 0x1) {
12474 case SLL16:
12475 opc = OPC_SLL;
12476 break;
12477 case SRL16:
12478 opc = OPC_SRL;
12479 break;
12480 }
12481
d75c135e 12482 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12483 }
12484 break;
12485 case POOL16C:
240ce26a 12486 gen_pool16c_insn(ctx);
3c824109
NF
12487 break;
12488 case LWGP16:
12489 {
12490 int rd = mmreg(uMIPS_RD(ctx->opcode));
12491 int rb = 28; /* GP */
12492 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12493
d75c135e 12494 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12495 }
12496 break;
12497 case POOL16F:
12498 if (ctx->opcode & 1) {
12499 generate_exception(ctx, EXCP_RI);
12500 } else {
12501 /* MOVEP */
12502 int enc_dest = uMIPS_RD(ctx->opcode);
12503 int enc_rt = uMIPS_RS2(ctx->opcode);
12504 int enc_rs = uMIPS_RS1(ctx->opcode);
12505 int rd, rs, re, rt;
12506 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12507 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12508 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12509
12510 rd = rd_enc[enc_dest];
12511 re = re_enc[enc_dest];
12512 rs = rs_rt_enc[enc_rs];
12513 rt = rs_rt_enc[enc_rt];
12514
d75c135e
AJ
12515 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12516 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12517 }
12518 break;
12519 case LBU16:
12520 {
12521 int rd = mmreg(uMIPS_RD(ctx->opcode));
12522 int rb = mmreg(uMIPS_RS(ctx->opcode));
12523 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12524 offset = (offset == 0xf ? -1 : offset);
12525
d75c135e 12526 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12527 }
12528 break;
12529 case LHU16:
12530 {
12531 int rd = mmreg(uMIPS_RD(ctx->opcode));
12532 int rb = mmreg(uMIPS_RS(ctx->opcode));
12533 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12534
d75c135e 12535 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12536 }
12537 break;
12538 case LWSP16:
12539 {
12540 int rd = (ctx->opcode >> 5) & 0x1f;
12541 int rb = 29; /* SP */
12542 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12543
d75c135e 12544 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12545 }
12546 break;
12547 case LW16:
12548 {
12549 int rd = mmreg(uMIPS_RD(ctx->opcode));
12550 int rb = mmreg(uMIPS_RS(ctx->opcode));
12551 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12552
d75c135e 12553 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12554 }
12555 break;
12556 case SB16:
12557 {
12558 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12559 int rb = mmreg(uMIPS_RS(ctx->opcode));
12560 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12561
5c13fdfd 12562 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12563 }
12564 break;
12565 case SH16:
12566 {
12567 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12568 int rb = mmreg(uMIPS_RS(ctx->opcode));
12569 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12570
5c13fdfd 12571 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12572 }
12573 break;
12574 case SWSP16:
12575 {
12576 int rd = (ctx->opcode >> 5) & 0x1f;
12577 int rb = 29; /* SP */
12578 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12579
5c13fdfd 12580 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12581 }
12582 break;
12583 case SW16:
12584 {
12585 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12586 int rb = mmreg(uMIPS_RS(ctx->opcode));
12587 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12588
5c13fdfd 12589 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12590 }
12591 break;
12592 case MOVE16:
12593 {
12594 int rd = uMIPS_RD5(ctx->opcode);
12595 int rs = uMIPS_RS5(ctx->opcode);
12596
d75c135e 12597 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12598 }
12599 break;
12600 case ANDI16:
d75c135e 12601 gen_andi16(ctx);
3c824109
NF
12602 break;
12603 case POOL16D:
12604 switch (ctx->opcode & 0x1) {
12605 case ADDIUS5:
d75c135e 12606 gen_addius5(ctx);
3c824109
NF
12607 break;
12608 case ADDIUSP:
d75c135e 12609 gen_addiusp(ctx);
3c824109
NF
12610 break;
12611 }
12612 break;
12613 case POOL16E:
12614 switch (ctx->opcode & 0x1) {
12615 case ADDIUR2:
d75c135e 12616 gen_addiur2(ctx);
3c824109
NF
12617 break;
12618 case ADDIUR1SP:
d75c135e 12619 gen_addiur1sp(ctx);
3c824109
NF
12620 break;
12621 }
12622 break;
12623 case B16:
12624 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12625 SIMM(ctx->opcode, 0, 10) << 1);
3c824109
NF
12626 break;
12627 case BNEZ16:
12628 case BEQZ16:
12629 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12630 mmreg(uMIPS_RD(ctx->opcode)),
12631 0, SIMM(ctx->opcode, 0, 7) << 1);
3c824109
NF
12632 break;
12633 case LI16:
12634 {
12635 int reg = mmreg(uMIPS_RD(ctx->opcode));
12636 int imm = ZIMM(ctx->opcode, 0, 7);
12637
12638 imm = (imm == 0x7f ? -1 : imm);
12639 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12640 }
12641 break;
12642 case RES_20:
12643 case RES_28:
12644 case RES_29:
12645 case RES_30:
12646 case RES_31:
12647 case RES_38:
12648 case RES_39:
12649 generate_exception(ctx, EXCP_RI);
12650 break;
12651 default:
240ce26a 12652 decode_micromips32_opc (env, ctx, op);
3c824109
NF
12653 return 4;
12654 }
12655
12656 return 2;
12657}
12658
12659/* SmartMIPS extension to MIPS32 */
12660
12661#if defined(TARGET_MIPS64)
12662
12663/* MDMX extension to MIPS64 */
12664
12665#endif
12666
9b1a1d68 12667/* MIPSDSP functions. */
d75c135e 12668static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12669 int rd, int base, int offset)
12670{
12671 const char *opn = "ldx";
12672 TCGv t0;
12673
9b1a1d68
JL
12674 check_dsp(ctx);
12675 t0 = tcg_temp_new();
12676
12677 if (base == 0) {
12678 gen_load_gpr(t0, offset);
12679 } else if (offset == 0) {
12680 gen_load_gpr(t0, base);
12681 } else {
12682 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12683 }
12684
9b1a1d68
JL
12685 switch (opc) {
12686 case OPC_LBUX:
5f68f5ae 12687 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
12688 gen_store_gpr(t0, rd);
12689 opn = "lbux";
12690 break;
12691 case OPC_LHX:
5f68f5ae 12692 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
12693 gen_store_gpr(t0, rd);
12694 opn = "lhx";
12695 break;
12696 case OPC_LWX:
5f68f5ae 12697 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
12698 gen_store_gpr(t0, rd);
12699 opn = "lwx";
12700 break;
12701#if defined(TARGET_MIPS64)
12702 case OPC_LDX:
5f68f5ae 12703 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
12704 gen_store_gpr(t0, rd);
12705 opn = "ldx";
12706 break;
12707#endif
12708 }
12709 (void)opn; /* avoid a compiler warning */
12710 MIPS_DEBUG("%s %s, %s(%s)", opn,
12711 regnames[rd], regnames[offset], regnames[base]);
12712 tcg_temp_free(t0);
12713}
12714
461c08df
JL
12715static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12716 int ret, int v1, int v2)
12717{
12718 const char *opn = "mipsdsp arith";
12719 TCGv v1_t;
12720 TCGv v2_t;
12721
12722 if (ret == 0) {
12723 /* Treat as NOP. */
12724 MIPS_DEBUG("NOP");
12725 return;
12726 }
12727
12728 v1_t = tcg_temp_new();
12729 v2_t = tcg_temp_new();
12730
12731 gen_load_gpr(v1_t, v1);
12732 gen_load_gpr(v2_t, v2);
12733
12734 switch (op1) {
12735 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12736 case OPC_MULT_G_2E:
12737 check_dspr2(ctx);
12738 switch (op2) {
12739 case OPC_ADDUH_QB:
12740 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12741 break;
12742 case OPC_ADDUH_R_QB:
12743 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12744 break;
12745 case OPC_ADDQH_PH:
12746 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12747 break;
12748 case OPC_ADDQH_R_PH:
12749 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12750 break;
12751 case OPC_ADDQH_W:
12752 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12753 break;
12754 case OPC_ADDQH_R_W:
12755 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12756 break;
12757 case OPC_SUBUH_QB:
12758 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12759 break;
12760 case OPC_SUBUH_R_QB:
12761 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12762 break;
12763 case OPC_SUBQH_PH:
12764 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12765 break;
12766 case OPC_SUBQH_R_PH:
12767 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12768 break;
12769 case OPC_SUBQH_W:
12770 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12771 break;
12772 case OPC_SUBQH_R_W:
12773 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12774 break;
12775 }
12776 break;
12777 case OPC_ABSQ_S_PH_DSP:
12778 switch (op2) {
12779 case OPC_ABSQ_S_QB:
12780 check_dspr2(ctx);
12781 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12782 break;
12783 case OPC_ABSQ_S_PH:
12784 check_dsp(ctx);
12785 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12786 break;
12787 case OPC_ABSQ_S_W:
12788 check_dsp(ctx);
12789 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12790 break;
12791 case OPC_PRECEQ_W_PHL:
12792 check_dsp(ctx);
12793 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12794 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12795 break;
12796 case OPC_PRECEQ_W_PHR:
12797 check_dsp(ctx);
12798 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12799 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12800 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12801 break;
12802 case OPC_PRECEQU_PH_QBL:
12803 check_dsp(ctx);
12804 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12805 break;
12806 case OPC_PRECEQU_PH_QBR:
12807 check_dsp(ctx);
12808 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12809 break;
12810 case OPC_PRECEQU_PH_QBLA:
12811 check_dsp(ctx);
12812 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12813 break;
12814 case OPC_PRECEQU_PH_QBRA:
12815 check_dsp(ctx);
12816 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12817 break;
12818 case OPC_PRECEU_PH_QBL:
12819 check_dsp(ctx);
12820 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12821 break;
12822 case OPC_PRECEU_PH_QBR:
12823 check_dsp(ctx);
12824 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12825 break;
12826 case OPC_PRECEU_PH_QBLA:
12827 check_dsp(ctx);
12828 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12829 break;
12830 case OPC_PRECEU_PH_QBRA:
12831 check_dsp(ctx);
12832 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12833 break;
12834 }
12835 break;
12836 case OPC_ADDU_QB_DSP:
12837 switch (op2) {
12838 case OPC_ADDQ_PH:
12839 check_dsp(ctx);
12840 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12841 break;
12842 case OPC_ADDQ_S_PH:
12843 check_dsp(ctx);
12844 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12845 break;
12846 case OPC_ADDQ_S_W:
12847 check_dsp(ctx);
12848 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849 break;
12850 case OPC_ADDU_QB:
12851 check_dsp(ctx);
12852 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853 break;
12854 case OPC_ADDU_S_QB:
12855 check_dsp(ctx);
12856 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12857 break;
12858 case OPC_ADDU_PH:
12859 check_dspr2(ctx);
12860 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861 break;
12862 case OPC_ADDU_S_PH:
12863 check_dspr2(ctx);
12864 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865 break;
12866 case OPC_SUBQ_PH:
12867 check_dsp(ctx);
12868 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12869 break;
12870 case OPC_SUBQ_S_PH:
12871 check_dsp(ctx);
12872 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12873 break;
12874 case OPC_SUBQ_S_W:
12875 check_dsp(ctx);
12876 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12877 break;
12878 case OPC_SUBU_QB:
12879 check_dsp(ctx);
12880 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12881 break;
12882 case OPC_SUBU_S_QB:
12883 check_dsp(ctx);
12884 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885 break;
12886 case OPC_SUBU_PH:
12887 check_dspr2(ctx);
12888 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 break;
12890 case OPC_SUBU_S_PH:
12891 check_dspr2(ctx);
12892 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12893 break;
12894 case OPC_ADDSC:
12895 check_dsp(ctx);
12896 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12897 break;
12898 case OPC_ADDWC:
12899 check_dsp(ctx);
12900 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12901 break;
12902 case OPC_MODSUB:
12903 check_dsp(ctx);
12904 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12905 break;
12906 case OPC_RADDU_W_QB:
12907 check_dsp(ctx);
12908 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12909 break;
12910 }
12911 break;
12912 case OPC_CMPU_EQ_QB_DSP:
12913 switch (op2) {
12914 case OPC_PRECR_QB_PH:
12915 check_dspr2(ctx);
12916 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12917 break;
12918 case OPC_PRECRQ_QB_PH:
12919 check_dsp(ctx);
12920 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12921 break;
12922 case OPC_PRECR_SRA_PH_W:
12923 check_dspr2(ctx);
12924 {
12925 TCGv_i32 sa_t = tcg_const_i32(v2);
12926 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12927 cpu_gpr[ret]);
12928 tcg_temp_free_i32(sa_t);
12929 break;
12930 }
12931 case OPC_PRECR_SRA_R_PH_W:
12932 check_dspr2(ctx);
12933 {
12934 TCGv_i32 sa_t = tcg_const_i32(v2);
12935 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12936 cpu_gpr[ret]);
12937 tcg_temp_free_i32(sa_t);
12938 break;
12939 }
12940 case OPC_PRECRQ_PH_W:
12941 check_dsp(ctx);
12942 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12943 break;
12944 case OPC_PRECRQ_RS_PH_W:
12945 check_dsp(ctx);
12946 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12947 break;
12948 case OPC_PRECRQU_S_QB_PH:
12949 check_dsp(ctx);
12950 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12951 break;
12952 }
12953 break;
12954#ifdef TARGET_MIPS64
12955 case OPC_ABSQ_S_QH_DSP:
12956 switch (op2) {
12957 case OPC_PRECEQ_L_PWL:
12958 check_dsp(ctx);
12959 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12960 break;
12961 case OPC_PRECEQ_L_PWR:
12962 check_dsp(ctx);
12963 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12964 break;
12965 case OPC_PRECEQ_PW_QHL:
12966 check_dsp(ctx);
12967 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12968 break;
12969 case OPC_PRECEQ_PW_QHR:
12970 check_dsp(ctx);
12971 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12972 break;
12973 case OPC_PRECEQ_PW_QHLA:
12974 check_dsp(ctx);
12975 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12976 break;
12977 case OPC_PRECEQ_PW_QHRA:
12978 check_dsp(ctx);
12979 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12980 break;
12981 case OPC_PRECEQU_QH_OBL:
12982 check_dsp(ctx);
12983 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12984 break;
12985 case OPC_PRECEQU_QH_OBR:
12986 check_dsp(ctx);
12987 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12988 break;
12989 case OPC_PRECEQU_QH_OBLA:
12990 check_dsp(ctx);
12991 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12992 break;
12993 case OPC_PRECEQU_QH_OBRA:
12994 check_dsp(ctx);
12995 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12996 break;
12997 case OPC_PRECEU_QH_OBL:
12998 check_dsp(ctx);
12999 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13000 break;
13001 case OPC_PRECEU_QH_OBR:
13002 check_dsp(ctx);
13003 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13004 break;
13005 case OPC_PRECEU_QH_OBLA:
13006 check_dsp(ctx);
13007 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13008 break;
13009 case OPC_PRECEU_QH_OBRA:
13010 check_dsp(ctx);
13011 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13012 break;
13013 case OPC_ABSQ_S_OB:
13014 check_dspr2(ctx);
13015 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13016 break;
13017 case OPC_ABSQ_S_PW:
13018 check_dsp(ctx);
13019 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13020 break;
13021 case OPC_ABSQ_S_QH:
13022 check_dsp(ctx);
13023 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13024 break;
13025 }
13026 break;
13027 case OPC_ADDU_OB_DSP:
13028 switch (op2) {
13029 case OPC_RADDU_L_OB:
13030 check_dsp(ctx);
13031 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13032 break;
13033 case OPC_SUBQ_PW:
13034 check_dsp(ctx);
13035 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13036 break;
13037 case OPC_SUBQ_S_PW:
13038 check_dsp(ctx);
13039 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13040 break;
13041 case OPC_SUBQ_QH:
13042 check_dsp(ctx);
13043 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044 break;
13045 case OPC_SUBQ_S_QH:
13046 check_dsp(ctx);
13047 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048 break;
13049 case OPC_SUBU_OB:
13050 check_dsp(ctx);
13051 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052 break;
13053 case OPC_SUBU_S_OB:
13054 check_dsp(ctx);
13055 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13056 break;
13057 case OPC_SUBU_QH:
13058 check_dspr2(ctx);
13059 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13060 break;
13061 case OPC_SUBU_S_QH:
13062 check_dspr2(ctx);
13063 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13064 break;
13065 case OPC_SUBUH_OB:
13066 check_dspr2(ctx);
13067 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13068 break;
13069 case OPC_SUBUH_R_OB:
13070 check_dspr2(ctx);
13071 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13072 break;
13073 case OPC_ADDQ_PW:
13074 check_dsp(ctx);
13075 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13076 break;
13077 case OPC_ADDQ_S_PW:
13078 check_dsp(ctx);
13079 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13080 break;
13081 case OPC_ADDQ_QH:
13082 check_dsp(ctx);
13083 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084 break;
13085 case OPC_ADDQ_S_QH:
13086 check_dsp(ctx);
13087 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13088 break;
13089 case OPC_ADDU_OB:
13090 check_dsp(ctx);
13091 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092 break;
13093 case OPC_ADDU_S_OB:
13094 check_dsp(ctx);
13095 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13096 break;
13097 case OPC_ADDU_QH:
13098 check_dspr2(ctx);
13099 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13100 break;
13101 case OPC_ADDU_S_QH:
13102 check_dspr2(ctx);
13103 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13104 break;
13105 case OPC_ADDUH_OB:
13106 check_dspr2(ctx);
13107 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13108 break;
13109 case OPC_ADDUH_R_OB:
13110 check_dspr2(ctx);
13111 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13112 break;
13113 }
13114 break;
13115 case OPC_CMPU_EQ_OB_DSP:
13116 switch (op2) {
13117 case OPC_PRECR_OB_QH:
13118 check_dspr2(ctx);
13119 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13120 break;
13121 case OPC_PRECR_SRA_QH_PW:
13122 check_dspr2(ctx);
13123 {
13124 TCGv_i32 ret_t = tcg_const_i32(ret);
13125 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13126 tcg_temp_free_i32(ret_t);
13127 break;
13128 }
13129 case OPC_PRECR_SRA_R_QH_PW:
13130 check_dspr2(ctx);
13131 {
13132 TCGv_i32 sa_v = tcg_const_i32(ret);
13133 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13134 tcg_temp_free_i32(sa_v);
13135 break;
13136 }
13137 case OPC_PRECRQ_OB_QH:
13138 check_dsp(ctx);
13139 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13140 break;
13141 case OPC_PRECRQ_PW_L:
13142 check_dsp(ctx);
13143 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13144 break;
13145 case OPC_PRECRQ_QH_PW:
13146 check_dsp(ctx);
13147 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13148 break;
13149 case OPC_PRECRQ_RS_QH_PW:
13150 check_dsp(ctx);
13151 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13152 break;
13153 case OPC_PRECRQU_S_OB_QH:
13154 check_dsp(ctx);
13155 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13156 break;
13157 }
13158 break;
13159#endif
13160 }
13161
13162 tcg_temp_free(v1_t);
13163 tcg_temp_free(v2_t);
13164
13165 (void)opn; /* avoid a compiler warning */
13166 MIPS_DEBUG("%s", opn);
13167}
9b1a1d68 13168
77c5fa8b
JL
13169static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13170 int ret, int v1, int v2)
13171{
13172 uint32_t op2;
13173 const char *opn = "mipsdsp shift";
13174 TCGv t0;
13175 TCGv v1_t;
13176 TCGv v2_t;
13177
13178 if (ret == 0) {
13179 /* Treat as NOP. */
13180 MIPS_DEBUG("NOP");
13181 return;
13182 }
13183
13184 t0 = tcg_temp_new();
13185 v1_t = tcg_temp_new();
13186 v2_t = tcg_temp_new();
13187
13188 tcg_gen_movi_tl(t0, v1);
13189 gen_load_gpr(v1_t, v1);
13190 gen_load_gpr(v2_t, v2);
13191
13192 switch (opc) {
13193 case OPC_SHLL_QB_DSP:
13194 {
13195 op2 = MASK_SHLL_QB(ctx->opcode);
13196 switch (op2) {
13197 case OPC_SHLL_QB:
13198 check_dsp(ctx);
13199 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13200 break;
13201 case OPC_SHLLV_QB:
13202 check_dsp(ctx);
13203 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13204 break;
13205 case OPC_SHLL_PH:
13206 check_dsp(ctx);
13207 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13208 break;
13209 case OPC_SHLLV_PH:
13210 check_dsp(ctx);
13211 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13212 break;
13213 case OPC_SHLL_S_PH:
13214 check_dsp(ctx);
13215 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13216 break;
13217 case OPC_SHLLV_S_PH:
13218 check_dsp(ctx);
13219 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13220 break;
13221 case OPC_SHLL_S_W:
13222 check_dsp(ctx);
13223 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13224 break;
13225 case OPC_SHLLV_S_W:
13226 check_dsp(ctx);
13227 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13228 break;
13229 case OPC_SHRL_QB:
13230 check_dsp(ctx);
13231 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13232 break;
13233 case OPC_SHRLV_QB:
13234 check_dsp(ctx);
13235 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13236 break;
13237 case OPC_SHRL_PH:
13238 check_dspr2(ctx);
13239 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13240 break;
13241 case OPC_SHRLV_PH:
13242 check_dspr2(ctx);
13243 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13244 break;
13245 case OPC_SHRA_QB:
13246 check_dspr2(ctx);
13247 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13248 break;
13249 case OPC_SHRA_R_QB:
13250 check_dspr2(ctx);
13251 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13252 break;
13253 case OPC_SHRAV_QB:
13254 check_dspr2(ctx);
13255 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13256 break;
13257 case OPC_SHRAV_R_QB:
13258 check_dspr2(ctx);
13259 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13260 break;
13261 case OPC_SHRA_PH:
13262 check_dsp(ctx);
13263 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13264 break;
13265 case OPC_SHRA_R_PH:
13266 check_dsp(ctx);
13267 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13268 break;
13269 case OPC_SHRAV_PH:
13270 check_dsp(ctx);
13271 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13272 break;
13273 case OPC_SHRAV_R_PH:
13274 check_dsp(ctx);
13275 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13276 break;
13277 case OPC_SHRA_R_W:
13278 check_dsp(ctx);
13279 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13280 break;
13281 case OPC_SHRAV_R_W:
13282 check_dsp(ctx);
13283 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13284 break;
13285 default: /* Invalid */
13286 MIPS_INVAL("MASK SHLL.QB");
13287 generate_exception(ctx, EXCP_RI);
13288 break;
13289 }
13290 break;
13291 }
13292#ifdef TARGET_MIPS64
13293 case OPC_SHLL_OB_DSP:
13294 op2 = MASK_SHLL_OB(ctx->opcode);
13295 switch (op2) {
13296 case OPC_SHLL_PW:
13297 check_dsp(ctx);
13298 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13299 break;
13300 case OPC_SHLLV_PW:
13301 check_dsp(ctx);
13302 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13303 break;
13304 case OPC_SHLL_S_PW:
13305 check_dsp(ctx);
13306 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13307 break;
13308 case OPC_SHLLV_S_PW:
13309 check_dsp(ctx);
13310 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13311 break;
13312 case OPC_SHLL_OB:
13313 check_dsp(ctx);
13314 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13315 break;
13316 case OPC_SHLLV_OB:
13317 check_dsp(ctx);
13318 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13319 break;
13320 case OPC_SHLL_QH:
13321 check_dsp(ctx);
13322 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13323 break;
13324 case OPC_SHLLV_QH:
13325 check_dsp(ctx);
13326 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13327 break;
13328 case OPC_SHLL_S_QH:
13329 check_dsp(ctx);
13330 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13331 break;
13332 case OPC_SHLLV_S_QH:
13333 check_dsp(ctx);
13334 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13335 break;
13336 case OPC_SHRA_OB:
13337 check_dspr2(ctx);
13338 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13339 break;
13340 case OPC_SHRAV_OB:
13341 check_dspr2(ctx);
13342 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13343 break;
13344 case OPC_SHRA_R_OB:
13345 check_dspr2(ctx);
13346 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13347 break;
13348 case OPC_SHRAV_R_OB:
13349 check_dspr2(ctx);
13350 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13351 break;
13352 case OPC_SHRA_PW:
13353 check_dsp(ctx);
13354 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13355 break;
13356 case OPC_SHRAV_PW:
13357 check_dsp(ctx);
13358 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13359 break;
13360 case OPC_SHRA_R_PW:
13361 check_dsp(ctx);
13362 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13363 break;
13364 case OPC_SHRAV_R_PW:
13365 check_dsp(ctx);
13366 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13367 break;
13368 case OPC_SHRA_QH:
13369 check_dsp(ctx);
13370 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13371 break;
13372 case OPC_SHRAV_QH:
13373 check_dsp(ctx);
13374 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13375 break;
13376 case OPC_SHRA_R_QH:
13377 check_dsp(ctx);
13378 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13379 break;
13380 case OPC_SHRAV_R_QH:
13381 check_dsp(ctx);
13382 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13383 break;
13384 case OPC_SHRL_OB:
13385 check_dsp(ctx);
13386 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13387 break;
13388 case OPC_SHRLV_OB:
13389 check_dsp(ctx);
13390 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13391 break;
13392 case OPC_SHRL_QH:
13393 check_dspr2(ctx);
13394 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13395 break;
13396 case OPC_SHRLV_QH:
13397 check_dspr2(ctx);
13398 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13399 break;
13400 default: /* Invalid */
13401 MIPS_INVAL("MASK SHLL.OB");
13402 generate_exception(ctx, EXCP_RI);
13403 break;
13404 }
13405 break;
13406#endif
13407 }
13408
13409 tcg_temp_free(t0);
13410 tcg_temp_free(v1_t);
13411 tcg_temp_free(v2_t);
13412 (void)opn; /* avoid a compiler warning */
13413 MIPS_DEBUG("%s", opn);
13414}
13415
a22260ae
JL
13416static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13417 int ret, int v1, int v2, int check_ret)
13418{
13419 const char *opn = "mipsdsp multiply";
13420 TCGv_i32 t0;
13421 TCGv v1_t;
13422 TCGv v2_t;
13423
13424 if ((ret == 0) && (check_ret == 1)) {
13425 /* Treat as NOP. */
13426 MIPS_DEBUG("NOP");
13427 return;
13428 }
13429
13430 t0 = tcg_temp_new_i32();
13431 v1_t = tcg_temp_new();
13432 v2_t = tcg_temp_new();
13433
13434 tcg_gen_movi_i32(t0, ret);
13435 gen_load_gpr(v1_t, v1);
13436 gen_load_gpr(v2_t, v2);
13437
13438 switch (op1) {
13439 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13440 * the same mask and op1. */
13441 case OPC_MULT_G_2E:
639eadb9 13442 check_dspr2(ctx);
a22260ae
JL
13443 switch (op2) {
13444 case OPC_MUL_PH:
13445 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13446 break;
13447 case OPC_MUL_S_PH:
13448 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13449 break;
13450 case OPC_MULQ_S_W:
13451 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13452 break;
13453 case OPC_MULQ_RS_W:
13454 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13455 break;
13456 }
13457 break;
13458 case OPC_DPA_W_PH_DSP:
13459 switch (op2) {
13460 case OPC_DPAU_H_QBL:
13461 check_dsp(ctx);
13462 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13463 break;
13464 case OPC_DPAU_H_QBR:
13465 check_dsp(ctx);
13466 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13467 break;
13468 case OPC_DPSU_H_QBL:
13469 check_dsp(ctx);
13470 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13471 break;
13472 case OPC_DPSU_H_QBR:
13473 check_dsp(ctx);
13474 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13475 break;
13476 case OPC_DPA_W_PH:
13477 check_dspr2(ctx);
13478 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13479 break;
13480 case OPC_DPAX_W_PH:
13481 check_dspr2(ctx);
13482 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13483 break;
13484 case OPC_DPAQ_S_W_PH:
13485 check_dsp(ctx);
13486 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13487 break;
13488 case OPC_DPAQX_S_W_PH:
13489 check_dspr2(ctx);
13490 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13491 break;
13492 case OPC_DPAQX_SA_W_PH:
13493 check_dspr2(ctx);
13494 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13495 break;
13496 case OPC_DPS_W_PH:
13497 check_dspr2(ctx);
13498 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13499 break;
13500 case OPC_DPSX_W_PH:
13501 check_dspr2(ctx);
13502 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13503 break;
13504 case OPC_DPSQ_S_W_PH:
13505 check_dsp(ctx);
13506 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13507 break;
13508 case OPC_DPSQX_S_W_PH:
13509 check_dspr2(ctx);
13510 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13511 break;
13512 case OPC_DPSQX_SA_W_PH:
13513 check_dspr2(ctx);
13514 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13515 break;
13516 case OPC_MULSAQ_S_W_PH:
13517 check_dsp(ctx);
13518 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13519 break;
13520 case OPC_DPAQ_SA_L_W:
13521 check_dsp(ctx);
13522 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13523 break;
13524 case OPC_DPSQ_SA_L_W:
13525 check_dsp(ctx);
13526 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13527 break;
13528 case OPC_MAQ_S_W_PHL:
13529 check_dsp(ctx);
13530 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13531 break;
13532 case OPC_MAQ_S_W_PHR:
13533 check_dsp(ctx);
13534 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13535 break;
13536 case OPC_MAQ_SA_W_PHL:
13537 check_dsp(ctx);
13538 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13539 break;
13540 case OPC_MAQ_SA_W_PHR:
13541 check_dsp(ctx);
13542 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13543 break;
13544 case OPC_MULSA_W_PH:
13545 check_dspr2(ctx);
13546 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13547 break;
13548 }
13549 break;
13550#ifdef TARGET_MIPS64
13551 case OPC_DPAQ_W_QH_DSP:
13552 {
13553 int ac = ret & 0x03;
13554 tcg_gen_movi_i32(t0, ac);
13555
13556 switch (op2) {
13557 case OPC_DMADD:
13558 check_dsp(ctx);
13559 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13560 break;
13561 case OPC_DMADDU:
13562 check_dsp(ctx);
13563 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13564 break;
13565 case OPC_DMSUB:
13566 check_dsp(ctx);
13567 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13568 break;
13569 case OPC_DMSUBU:
13570 check_dsp(ctx);
13571 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13572 break;
13573 case OPC_DPA_W_QH:
13574 check_dspr2(ctx);
13575 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13576 break;
13577 case OPC_DPAQ_S_W_QH:
13578 check_dsp(ctx);
13579 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13580 break;
13581 case OPC_DPAQ_SA_L_PW:
13582 check_dsp(ctx);
13583 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13584 break;
13585 case OPC_DPAU_H_OBL:
13586 check_dsp(ctx);
13587 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13588 break;
13589 case OPC_DPAU_H_OBR:
13590 check_dsp(ctx);
13591 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13592 break;
13593 case OPC_DPS_W_QH:
13594 check_dspr2(ctx);
13595 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13596 break;
13597 case OPC_DPSQ_S_W_QH:
13598 check_dsp(ctx);
13599 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13600 break;
13601 case OPC_DPSQ_SA_L_PW:
13602 check_dsp(ctx);
13603 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13604 break;
13605 case OPC_DPSU_H_OBL:
13606 check_dsp(ctx);
13607 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13608 break;
13609 case OPC_DPSU_H_OBR:
13610 check_dsp(ctx);
13611 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13612 break;
13613 case OPC_MAQ_S_L_PWL:
13614 check_dsp(ctx);
13615 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13616 break;
13617 case OPC_MAQ_S_L_PWR:
13618 check_dsp(ctx);
13619 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13620 break;
13621 case OPC_MAQ_S_W_QHLL:
13622 check_dsp(ctx);
13623 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13624 break;
13625 case OPC_MAQ_SA_W_QHLL:
13626 check_dsp(ctx);
13627 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13628 break;
13629 case OPC_MAQ_S_W_QHLR:
13630 check_dsp(ctx);
13631 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13632 break;
13633 case OPC_MAQ_SA_W_QHLR:
13634 check_dsp(ctx);
13635 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13636 break;
13637 case OPC_MAQ_S_W_QHRL:
13638 check_dsp(ctx);
13639 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13640 break;
13641 case OPC_MAQ_SA_W_QHRL:
13642 check_dsp(ctx);
13643 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13644 break;
13645 case OPC_MAQ_S_W_QHRR:
13646 check_dsp(ctx);
13647 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13648 break;
13649 case OPC_MAQ_SA_W_QHRR:
13650 check_dsp(ctx);
13651 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13652 break;
13653 case OPC_MULSAQ_S_L_PW:
13654 check_dsp(ctx);
13655 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13656 break;
13657 case OPC_MULSAQ_S_W_QH:
13658 check_dsp(ctx);
13659 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13660 break;
13661 }
13662 }
13663 break;
13664#endif
13665 case OPC_ADDU_QB_DSP:
13666 switch (op2) {
13667 case OPC_MULEU_S_PH_QBL:
13668 check_dsp(ctx);
13669 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13670 break;
13671 case OPC_MULEU_S_PH_QBR:
13672 check_dsp(ctx);
13673 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13674 break;
13675 case OPC_MULQ_RS_PH:
13676 check_dsp(ctx);
13677 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13678 break;
13679 case OPC_MULEQ_S_W_PHL:
13680 check_dsp(ctx);
13681 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13682 break;
13683 case OPC_MULEQ_S_W_PHR:
13684 check_dsp(ctx);
13685 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13686 break;
13687 case OPC_MULQ_S_PH:
13688 check_dspr2(ctx);
13689 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13690 break;
13691 }
13692 break;
13693#ifdef TARGET_MIPS64
13694 case OPC_ADDU_OB_DSP:
13695 switch (op2) {
13696 case OPC_MULEQ_S_PW_QHL:
13697 check_dsp(ctx);
13698 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13699 break;
13700 case OPC_MULEQ_S_PW_QHR:
13701 check_dsp(ctx);
13702 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13703 break;
13704 case OPC_MULEU_S_QH_OBL:
13705 check_dsp(ctx);
13706 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13707 break;
13708 case OPC_MULEU_S_QH_OBR:
13709 check_dsp(ctx);
13710 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13711 break;
13712 case OPC_MULQ_RS_QH:
13713 check_dsp(ctx);
13714 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13715 break;
13716 }
13717 break;
13718#endif
13719 }
13720
13721 tcg_temp_free_i32(t0);
13722 tcg_temp_free(v1_t);
13723 tcg_temp_free(v2_t);
13724
13725 (void)opn; /* avoid a compiler warning */
13726 MIPS_DEBUG("%s", opn);
13727
13728}
13729
d75c135e 13730static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13731 int ret, int val)
13732{
13733 const char *opn = "mipsdsp Bit/ Manipulation";
13734 int16_t imm;
13735 TCGv t0;
13736 TCGv val_t;
13737
13738 if (ret == 0) {
13739 /* Treat as NOP. */
13740 MIPS_DEBUG("NOP");
13741 return;
13742 }
13743
13744 t0 = tcg_temp_new();
13745 val_t = tcg_temp_new();
13746 gen_load_gpr(val_t, val);
13747
13748 switch (op1) {
13749 case OPC_ABSQ_S_PH_DSP:
13750 switch (op2) {
13751 case OPC_BITREV:
13752 check_dsp(ctx);
13753 gen_helper_bitrev(cpu_gpr[ret], val_t);
13754 break;
13755 case OPC_REPL_QB:
13756 check_dsp(ctx);
13757 {
13758 target_long result;
13759 imm = (ctx->opcode >> 16) & 0xFF;
13760 result = (uint32_t)imm << 24 |
13761 (uint32_t)imm << 16 |
13762 (uint32_t)imm << 8 |
13763 (uint32_t)imm;
13764 result = (int32_t)result;
13765 tcg_gen_movi_tl(cpu_gpr[ret], result);
13766 }
13767 break;
13768 case OPC_REPLV_QB:
13769 check_dsp(ctx);
13770 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13771 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13772 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13773 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13774 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13775 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13776 break;
13777 case OPC_REPL_PH:
13778 check_dsp(ctx);
13779 {
13780 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13781 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13782 tcg_gen_movi_tl(cpu_gpr[ret], \
13783 (target_long)((int32_t)imm << 16 | \
c4aaba92 13784 (uint16_t)imm));
1cb6686c
JL
13785 }
13786 break;
13787 case OPC_REPLV_PH:
13788 check_dsp(ctx);
13789 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13790 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13791 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13792 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13793 break;
13794 }
13795 break;
13796#ifdef TARGET_MIPS64
13797 case OPC_ABSQ_S_QH_DSP:
13798 switch (op2) {
13799 case OPC_REPL_OB:
13800 check_dsp(ctx);
13801 {
13802 target_long temp;
13803
13804 imm = (ctx->opcode >> 16) & 0xFF;
13805 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13806 temp = (temp << 16) | temp;
13807 temp = (temp << 32) | temp;
13808 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13809 break;
13810 }
13811 case OPC_REPL_PW:
13812 check_dsp(ctx);
13813 {
13814 target_long temp;
13815
13816 imm = (ctx->opcode >> 16) & 0x03FF;
13817 imm = (int16_t)(imm << 6) >> 6;
13818 temp = ((target_long)imm << 32) \
13819 | ((target_long)imm & 0xFFFFFFFF);
13820 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13821 break;
13822 }
13823 case OPC_REPL_QH:
13824 check_dsp(ctx);
13825 {
13826 target_long temp;
13827
13828 imm = (ctx->opcode >> 16) & 0x03FF;
13829 imm = (int16_t)(imm << 6) >> 6;
13830
13831 temp = ((uint64_t)(uint16_t)imm << 48) |
13832 ((uint64_t)(uint16_t)imm << 32) |
13833 ((uint64_t)(uint16_t)imm << 16) |
13834 (uint64_t)(uint16_t)imm;
13835 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13836 break;
13837 }
13838 case OPC_REPLV_OB:
13839 check_dsp(ctx);
13840 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13841 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13842 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13843 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13844 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13845 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13846 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13847 break;
13848 case OPC_REPLV_PW:
13849 check_dsp(ctx);
13850 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13851 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13852 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13853 break;
13854 case OPC_REPLV_QH:
13855 check_dsp(ctx);
13856 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13857 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13858 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13859 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13860 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13861 break;
13862 }
13863 break;
13864#endif
13865 }
13866 tcg_temp_free(t0);
13867 tcg_temp_free(val_t);
13868
13869 (void)opn; /* avoid a compiler warning */
13870 MIPS_DEBUG("%s", opn);
13871}
13872
26690560
JL
13873static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13874 uint32_t op1, uint32_t op2,
13875 int ret, int v1, int v2, int check_ret)
13876{
13877 const char *opn = "mipsdsp add compare pick";
26690560
JL
13878 TCGv t1;
13879 TCGv v1_t;
13880 TCGv v2_t;
13881
13882 if ((ret == 0) && (check_ret == 1)) {
13883 /* Treat as NOP. */
13884 MIPS_DEBUG("NOP");
13885 return;
13886 }
13887
26690560
JL
13888 t1 = tcg_temp_new();
13889 v1_t = tcg_temp_new();
13890 v2_t = tcg_temp_new();
13891
13892 gen_load_gpr(v1_t, v1);
13893 gen_load_gpr(v2_t, v2);
13894
13895 switch (op1) {
26690560
JL
13896 case OPC_CMPU_EQ_QB_DSP:
13897 switch (op2) {
13898 case OPC_CMPU_EQ_QB:
13899 check_dsp(ctx);
13900 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13901 break;
13902 case OPC_CMPU_LT_QB:
13903 check_dsp(ctx);
13904 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13905 break;
13906 case OPC_CMPU_LE_QB:
13907 check_dsp(ctx);
13908 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13909 break;
13910 case OPC_CMPGU_EQ_QB:
13911 check_dsp(ctx);
13912 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13913 break;
13914 case OPC_CMPGU_LT_QB:
13915 check_dsp(ctx);
13916 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13917 break;
13918 case OPC_CMPGU_LE_QB:
13919 check_dsp(ctx);
13920 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13921 break;
13922 case OPC_CMPGDU_EQ_QB:
13923 check_dspr2(ctx);
13924 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13925 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13926 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13927 tcg_gen_shli_tl(t1, t1, 24);
13928 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13929 break;
13930 case OPC_CMPGDU_LT_QB:
13931 check_dspr2(ctx);
13932 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13933 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13934 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13935 tcg_gen_shli_tl(t1, t1, 24);
13936 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13937 break;
13938 case OPC_CMPGDU_LE_QB:
13939 check_dspr2(ctx);
13940 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13941 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13942 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13943 tcg_gen_shli_tl(t1, t1, 24);
13944 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13945 break;
13946 case OPC_CMP_EQ_PH:
13947 check_dsp(ctx);
13948 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13949 break;
13950 case OPC_CMP_LT_PH:
13951 check_dsp(ctx);
13952 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13953 break;
13954 case OPC_CMP_LE_PH:
13955 check_dsp(ctx);
13956 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13957 break;
13958 case OPC_PICK_QB:
13959 check_dsp(ctx);
13960 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13961 break;
13962 case OPC_PICK_PH:
13963 check_dsp(ctx);
13964 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13965 break;
13966 case OPC_PACKRL_PH:
13967 check_dsp(ctx);
13968 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13969 break;
13970 }
13971 break;
13972#ifdef TARGET_MIPS64
13973 case OPC_CMPU_EQ_OB_DSP:
13974 switch (op2) {
13975 case OPC_CMP_EQ_PW:
13976 check_dsp(ctx);
13977 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13978 break;
13979 case OPC_CMP_LT_PW:
13980 check_dsp(ctx);
13981 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13982 break;
13983 case OPC_CMP_LE_PW:
13984 check_dsp(ctx);
13985 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13986 break;
13987 case OPC_CMP_EQ_QH:
13988 check_dsp(ctx);
13989 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13990 break;
13991 case OPC_CMP_LT_QH:
13992 check_dsp(ctx);
13993 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13994 break;
13995 case OPC_CMP_LE_QH:
13996 check_dsp(ctx);
13997 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13998 break;
13999 case OPC_CMPGDU_EQ_OB:
14000 check_dspr2(ctx);
14001 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14002 break;
14003 case OPC_CMPGDU_LT_OB:
14004 check_dspr2(ctx);
14005 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14006 break;
14007 case OPC_CMPGDU_LE_OB:
14008 check_dspr2(ctx);
14009 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14010 break;
14011 case OPC_CMPGU_EQ_OB:
14012 check_dsp(ctx);
14013 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14014 break;
14015 case OPC_CMPGU_LT_OB:
14016 check_dsp(ctx);
14017 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14018 break;
14019 case OPC_CMPGU_LE_OB:
14020 check_dsp(ctx);
14021 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14022 break;
14023 case OPC_CMPU_EQ_OB:
14024 check_dsp(ctx);
14025 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14026 break;
14027 case OPC_CMPU_LT_OB:
14028 check_dsp(ctx);
14029 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14030 break;
14031 case OPC_CMPU_LE_OB:
14032 check_dsp(ctx);
14033 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14034 break;
14035 case OPC_PACKRL_PW:
14036 check_dsp(ctx);
14037 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14038 break;
14039 case OPC_PICK_OB:
14040 check_dsp(ctx);
14041 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14042 break;
14043 case OPC_PICK_PW:
14044 check_dsp(ctx);
14045 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14046 break;
14047 case OPC_PICK_QH:
14048 check_dsp(ctx);
14049 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14050 break;
14051 }
14052 break;
df6126a7
AJ
14053#endif
14054 }
14055
14056 tcg_temp_free(t1);
14057 tcg_temp_free(v1_t);
14058 tcg_temp_free(v2_t);
14059
14060 (void)opn; /* avoid a compiler warning */
14061 MIPS_DEBUG("%s", opn);
14062}
14063
14064static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14065 uint32_t op1, int rt, int rs, int sa)
14066{
14067 const char *opn = "mipsdsp append/dappend";
14068 TCGv t0;
14069
14070 check_dspr2(ctx);
14071
14072 if (rt == 0) {
14073 /* Treat as NOP. */
14074 MIPS_DEBUG("NOP");
14075 return;
14076 }
14077
14078 t0 = tcg_temp_new();
14079 gen_load_gpr(t0, rs);
14080
14081 switch (op1) {
14082 case OPC_APPEND_DSP:
14083 switch (MASK_APPEND(ctx->opcode)) {
14084 case OPC_APPEND:
14085 if (sa != 0) {
14086 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14087 }
14088 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14089 break;
14090 case OPC_PREPEND:
14091 if (sa != 0) {
14092 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14093 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14094 tcg_gen_shli_tl(t0, t0, 32 - sa);
14095 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14096 }
14097 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14098 break;
14099 case OPC_BALIGN:
14100 sa &= 3;
14101 if (sa != 0 && sa != 2) {
14102 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14103 tcg_gen_ext32u_tl(t0, t0);
14104 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14105 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14106 }
14107 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14108 break;
14109 default: /* Invalid */
14110 MIPS_INVAL("MASK APPEND");
14111 generate_exception(ctx, EXCP_RI);
14112 break;
14113 }
14114 break;
14115#ifdef TARGET_MIPS64
26690560 14116 case OPC_DAPPEND_DSP:
df6126a7 14117 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 14118 case OPC_DAPPEND:
df6126a7
AJ
14119 if (sa != 0) {
14120 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14121 }
26690560
JL
14122 break;
14123 case OPC_PREPENDD:
df6126a7
AJ
14124 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14125 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14126 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
14127 break;
14128 case OPC_PREPENDW:
df6126a7
AJ
14129 if (sa != 0) {
14130 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14131 tcg_gen_shli_tl(t0, t0, 64 - sa);
14132 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14133 }
26690560
JL
14134 break;
14135 case OPC_DBALIGN:
df6126a7
AJ
14136 sa &= 7;
14137 if (sa != 0 && sa != 2 && sa != 4) {
14138 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14139 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14140 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14141 }
26690560
JL
14142 break;
14143 default: /* Invalid */
14144 MIPS_INVAL("MASK DAPPEND");
14145 generate_exception(ctx, EXCP_RI);
14146 break;
14147 }
14148 break;
14149#endif
14150 }
df6126a7 14151 tcg_temp_free(t0);
26690560
JL
14152 (void)opn; /* avoid a compiler warning */
14153 MIPS_DEBUG("%s", opn);
14154}
14155
b53371ed
JL
14156static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14157 int ret, int v1, int v2, int check_ret)
14158
14159{
14160 const char *opn = "mipsdsp accumulator";
14161 TCGv t0;
14162 TCGv t1;
14163 TCGv v1_t;
14164 TCGv v2_t;
14165 int16_t imm;
14166
14167 if ((ret == 0) && (check_ret == 1)) {
14168 /* Treat as NOP. */
14169 MIPS_DEBUG("NOP");
14170 return;
14171 }
14172
14173 t0 = tcg_temp_new();
14174 t1 = tcg_temp_new();
14175 v1_t = tcg_temp_new();
14176 v2_t = tcg_temp_new();
14177
14178 gen_load_gpr(v1_t, v1);
14179 gen_load_gpr(v2_t, v2);
14180
14181 switch (op1) {
14182 case OPC_EXTR_W_DSP:
14183 check_dsp(ctx);
14184 switch (op2) {
14185 case OPC_EXTR_W:
14186 tcg_gen_movi_tl(t0, v2);
14187 tcg_gen_movi_tl(t1, v1);
14188 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14189 break;
14190 case OPC_EXTR_R_W:
14191 tcg_gen_movi_tl(t0, v2);
14192 tcg_gen_movi_tl(t1, v1);
14193 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14194 break;
14195 case OPC_EXTR_RS_W:
14196 tcg_gen_movi_tl(t0, v2);
14197 tcg_gen_movi_tl(t1, v1);
14198 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14199 break;
14200 case OPC_EXTR_S_H:
14201 tcg_gen_movi_tl(t0, v2);
14202 tcg_gen_movi_tl(t1, v1);
14203 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14204 break;
14205 case OPC_EXTRV_S_H:
14206 tcg_gen_movi_tl(t0, v2);
14207 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14208 break;
14209 case OPC_EXTRV_W:
14210 tcg_gen_movi_tl(t0, v2);
14211 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14212 break;
14213 case OPC_EXTRV_R_W:
14214 tcg_gen_movi_tl(t0, v2);
14215 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14216 break;
14217 case OPC_EXTRV_RS_W:
14218 tcg_gen_movi_tl(t0, v2);
14219 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14220 break;
14221 case OPC_EXTP:
14222 tcg_gen_movi_tl(t0, v2);
14223 tcg_gen_movi_tl(t1, v1);
14224 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14225 break;
14226 case OPC_EXTPV:
14227 tcg_gen_movi_tl(t0, v2);
14228 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14229 break;
14230 case OPC_EXTPDP:
14231 tcg_gen_movi_tl(t0, v2);
14232 tcg_gen_movi_tl(t1, v1);
14233 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14234 break;
14235 case OPC_EXTPDPV:
14236 tcg_gen_movi_tl(t0, v2);
14237 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14238 break;
14239 case OPC_SHILO:
14240 imm = (ctx->opcode >> 20) & 0x3F;
14241 tcg_gen_movi_tl(t0, ret);
14242 tcg_gen_movi_tl(t1, imm);
14243 gen_helper_shilo(t0, t1, cpu_env);
14244 break;
14245 case OPC_SHILOV:
14246 tcg_gen_movi_tl(t0, ret);
14247 gen_helper_shilo(t0, v1_t, cpu_env);
14248 break;
14249 case OPC_MTHLIP:
14250 tcg_gen_movi_tl(t0, ret);
14251 gen_helper_mthlip(t0, v1_t, cpu_env);
14252 break;
14253 case OPC_WRDSP:
14254 imm = (ctx->opcode >> 11) & 0x3FF;
14255 tcg_gen_movi_tl(t0, imm);
14256 gen_helper_wrdsp(v1_t, t0, cpu_env);
14257 break;
14258 case OPC_RDDSP:
14259 imm = (ctx->opcode >> 16) & 0x03FF;
14260 tcg_gen_movi_tl(t0, imm);
14261 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14262 break;
14263 }
14264 break;
14265#ifdef TARGET_MIPS64
14266 case OPC_DEXTR_W_DSP:
14267 check_dsp(ctx);
14268 switch (op2) {
14269 case OPC_DMTHLIP:
14270 tcg_gen_movi_tl(t0, ret);
14271 gen_helper_dmthlip(v1_t, t0, cpu_env);
14272 break;
14273 case OPC_DSHILO:
14274 {
14275 int shift = (ctx->opcode >> 19) & 0x7F;
14276 int ac = (ctx->opcode >> 11) & 0x03;
14277 tcg_gen_movi_tl(t0, shift);
14278 tcg_gen_movi_tl(t1, ac);
14279 gen_helper_dshilo(t0, t1, cpu_env);
14280 break;
14281 }
14282 case OPC_DSHILOV:
14283 {
14284 int ac = (ctx->opcode >> 11) & 0x03;
14285 tcg_gen_movi_tl(t0, ac);
14286 gen_helper_dshilo(v1_t, t0, cpu_env);
14287 break;
14288 }
14289 case OPC_DEXTP:
14290 tcg_gen_movi_tl(t0, v2);
14291 tcg_gen_movi_tl(t1, v1);
14292
14293 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14294 break;
14295 case OPC_DEXTPV:
14296 tcg_gen_movi_tl(t0, v2);
14297 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14298 break;
14299 case OPC_DEXTPDP:
14300 tcg_gen_movi_tl(t0, v2);
14301 tcg_gen_movi_tl(t1, v1);
14302 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14303 break;
14304 case OPC_DEXTPDPV:
14305 tcg_gen_movi_tl(t0, v2);
14306 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14307 break;
14308 case OPC_DEXTR_L:
14309 tcg_gen_movi_tl(t0, v2);
14310 tcg_gen_movi_tl(t1, v1);
14311 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14312 break;
14313 case OPC_DEXTR_R_L:
14314 tcg_gen_movi_tl(t0, v2);
14315 tcg_gen_movi_tl(t1, v1);
14316 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14317 break;
14318 case OPC_DEXTR_RS_L:
14319 tcg_gen_movi_tl(t0, v2);
14320 tcg_gen_movi_tl(t1, v1);
14321 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14322 break;
14323 case OPC_DEXTR_W:
14324 tcg_gen_movi_tl(t0, v2);
14325 tcg_gen_movi_tl(t1, v1);
14326 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14327 break;
14328 case OPC_DEXTR_R_W:
14329 tcg_gen_movi_tl(t0, v2);
14330 tcg_gen_movi_tl(t1, v1);
14331 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14332 break;
14333 case OPC_DEXTR_RS_W:
14334 tcg_gen_movi_tl(t0, v2);
14335 tcg_gen_movi_tl(t1, v1);
14336 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14337 break;
14338 case OPC_DEXTR_S_H:
14339 tcg_gen_movi_tl(t0, v2);
14340 tcg_gen_movi_tl(t1, v1);
14341 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14342 break;
14343 case OPC_DEXTRV_S_H:
14344 tcg_gen_movi_tl(t0, v2);
14345 tcg_gen_movi_tl(t1, v1);
14346 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14347 break;
14348 case OPC_DEXTRV_L:
14349 tcg_gen_movi_tl(t0, v2);
14350 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14351 break;
14352 case OPC_DEXTRV_R_L:
14353 tcg_gen_movi_tl(t0, v2);
14354 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14355 break;
14356 case OPC_DEXTRV_RS_L:
14357 tcg_gen_movi_tl(t0, v2);
14358 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14359 break;
14360 case OPC_DEXTRV_W:
14361 tcg_gen_movi_tl(t0, v2);
14362 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14363 break;
14364 case OPC_DEXTRV_R_W:
14365 tcg_gen_movi_tl(t0, v2);
14366 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14367 break;
14368 case OPC_DEXTRV_RS_W:
14369 tcg_gen_movi_tl(t0, v2);
14370 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14371 break;
14372 }
14373 break;
14374#endif
14375 }
14376
14377 tcg_temp_free(t0);
14378 tcg_temp_free(t1);
14379 tcg_temp_free(v1_t);
14380 tcg_temp_free(v2_t);
14381
14382 (void)opn; /* avoid a compiler warning */
14383 MIPS_DEBUG("%s", opn);
14384}
14385
9b1a1d68
JL
14386/* End MIPSDSP functions. */
14387
240ce26a 14388static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14389{
14390 int32_t offset;
14391 int rs, rt, rd, sa;
14392 uint32_t op, op1, op2;
14393 int16_t imm;
14394
14395 /* make sure instructions are on a word boundary */
14396 if (ctx->pc & 0x3) {
14397 env->CP0_BadVAddr = ctx->pc;
14398 generate_exception(ctx, EXCP_AdEL);
14399 return;
14400 }
14401
14402 /* Handle blikely not taken case */
14403 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14404 int l1 = gen_new_label();
14405
14406 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14407 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14408 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14409 gen_goto_tb(ctx, 1, ctx->pc + 4);
14410 gen_set_label(l1);
14411 }
14412
fdefe51c 14413 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14414 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14415 }
3c824109
NF
14416
14417 op = MASK_OP_MAJOR(ctx->opcode);
14418 rs = (ctx->opcode >> 21) & 0x1f;
14419 rt = (ctx->opcode >> 16) & 0x1f;
14420 rd = (ctx->opcode >> 11) & 0x1f;
14421 sa = (ctx->opcode >> 6) & 0x1f;
14422 imm = (int16_t)ctx->opcode;
14423 switch (op) {
7a387fff
TS
14424 case OPC_SPECIAL:
14425 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14426 switch (op1) {
324d9e32
AJ
14427 case OPC_SLL: /* Shift with immediate */
14428 case OPC_SRA:
d75c135e 14429 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14430 break;
ea63e2c3
NF
14431 case OPC_SRL:
14432 switch ((ctx->opcode >> 21) & 0x1f) {
14433 case 1:
14434 /* rotr is decoded as srl on non-R2 CPUs */
d75c135e 14435 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14436 op1 = OPC_ROTR;
14437 }
14438 /* Fallthrough */
14439 case 0:
d75c135e 14440 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14441 break;
14442 default:
14443 generate_exception(ctx, EXCP_RI);
14444 break;
14445 }
14446 break;
460f00c4
AJ
14447 case OPC_MOVN: /* Conditional move */
14448 case OPC_MOVZ:
d75c135e 14449 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
aa8f4009 14450 INSN_LOONGSON2E | INSN_LOONGSON2F);
d75c135e 14451 gen_cond_move(ctx, op1, rd, rs, rt);
460f00c4
AJ
14452 break;
14453 case OPC_ADD ... OPC_SUBU:
d75c135e 14454 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14455 break;
460f00c4 14456 case OPC_SLLV: /* Shifts */
460f00c4 14457 case OPC_SRAV:
d75c135e 14458 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14459 break;
ea63e2c3
NF
14460 case OPC_SRLV:
14461 switch ((ctx->opcode >> 6) & 0x1f) {
14462 case 1:
14463 /* rotrv is decoded as srlv on non-R2 CPUs */
d75c135e 14464 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14465 op1 = OPC_ROTRV;
14466 }
14467 /* Fallthrough */
14468 case 0:
d75c135e 14469 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14470 break;
14471 default:
14472 generate_exception(ctx, EXCP_RI);
14473 break;
14474 }
14475 break;
460f00c4
AJ
14476 case OPC_SLT: /* Set on less than */
14477 case OPC_SLTU:
d75c135e 14478 gen_slt(ctx, op1, rd, rs, rt);
460f00c4
AJ
14479 break;
14480 case OPC_AND: /* Logic*/
14481 case OPC_OR:
14482 case OPC_NOR:
14483 case OPC_XOR:
d75c135e 14484 gen_logic(ctx, op1, rd, rs, rt);
460f00c4 14485 break;
26135ead
RS
14486 case OPC_MULT:
14487 case OPC_MULTU:
e9c71dd1 14488 if (sa) {
d75c135e 14489 check_insn(ctx, INSN_VR54XX);
e9c71dd1
TS
14490 op1 = MASK_MUL_VR54XX(ctx->opcode);
14491 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
26135ead
RS
14492 } else {
14493 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14494 }
14495 break;
14496 case OPC_DIV:
14497 case OPC_DIVU:
14498 gen_muldiv(ctx, op1, 0, rs, rt);
7a387fff
TS
14499 break;
14500 case OPC_JR ... OPC_JALR:
7dca4ad0 14501 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061 14502 break;
7a387fff
TS
14503 case OPC_TGE ... OPC_TEQ: /* Traps */
14504 case OPC_TNE:
14505 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14506 break;
7a387fff
TS
14507 case OPC_MFHI: /* Move from HI/LO */
14508 case OPC_MFLO:
26135ead 14509 gen_HILO(ctx, op1, rs & 3, rd);
6af0bf9c 14510 break;
7a387fff
TS
14511 case OPC_MTHI:
14512 case OPC_MTLO: /* Move to HI/LO */
26135ead 14513 gen_HILO(ctx, op1, rd & 3, rs);
6af0bf9c 14514 break;
b48cfdff
TS
14515 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14516#ifdef MIPS_STRICT_STANDARD
14517 MIPS_INVAL("PMON / selsl");
14518 generate_exception(ctx, EXCP_RI);
14519#else
895c2d04 14520 gen_helper_0e0i(pmon, sa);
b48cfdff 14521#endif
7a387fff
TS
14522 break;
14523 case OPC_SYSCALL:
6af0bf9c 14524 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14525 ctx->bstate = BS_STOP;
6af0bf9c 14526 break;
7a387fff 14527 case OPC_BREAK:
6af0bf9c
FB
14528 generate_exception(ctx, EXCP_BREAK);
14529 break;
b48cfdff
TS
14530 case OPC_SPIM:
14531#ifdef MIPS_STRICT_STANDARD
14532 MIPS_INVAL("SPIM");
14533 generate_exception(ctx, EXCP_RI);
14534#else
7a387fff
TS
14535 /* Implemented as RI exception for now. */
14536 MIPS_INVAL("spim (unofficial)");
14537 generate_exception(ctx, EXCP_RI);
b48cfdff 14538#endif
6af0bf9c 14539 break;
7a387fff 14540 case OPC_SYNC:
ead9360e 14541 /* Treat as NOP. */
6af0bf9c 14542 break;
4ad40f36 14543
7a387fff 14544 case OPC_MOVCI:
d75c135e 14545 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14546 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14547 check_cp1_enabled(ctx);
36d23958
TS
14548 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14549 (ctx->opcode >> 16) & 1);
14550 } else {
e397ee33 14551 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14552 }
4ad40f36
FB
14553 break;
14554
d26bc211 14555#if defined(TARGET_MIPS64)
7a387fff
TS
14556 /* MIPS64 specific opcodes */
14557 case OPC_DSLL:
324d9e32 14558 case OPC_DSRA:
7a387fff 14559 case OPC_DSLL32:
324d9e32 14560 case OPC_DSRA32:
d75c135e 14561 check_insn(ctx, ISA_MIPS3);
e189e748 14562 check_mips_64(ctx);
d75c135e 14563 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14564 break;
ea63e2c3
NF
14565 case OPC_DSRL:
14566 switch ((ctx->opcode >> 21) & 0x1f) {
14567 case 1:
14568 /* drotr is decoded as dsrl on non-R2 CPUs */
d75c135e 14569 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14570 op1 = OPC_DROTR;
14571 }
14572 /* Fallthrough */
14573 case 0:
d75c135e 14574 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14575 check_mips_64(ctx);
d75c135e 14576 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14577 break;
14578 default:
14579 generate_exception(ctx, EXCP_RI);
14580 break;
14581 }
14582 break;
14583 case OPC_DSRL32:
14584 switch ((ctx->opcode >> 21) & 0x1f) {
14585 case 1:
14586 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
d75c135e 14587 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14588 op1 = OPC_DROTR32;
14589 }
14590 /* Fallthrough */
14591 case 0:
d75c135e 14592 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14593 check_mips_64(ctx);
d75c135e 14594 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14595 break;
14596 default:
14597 generate_exception(ctx, EXCP_RI);
14598 break;
14599 }
14600 break;
7a387fff 14601 case OPC_DADD ... OPC_DSUBU:
d75c135e 14602 check_insn(ctx, ISA_MIPS3);
e189e748 14603 check_mips_64(ctx);
d75c135e 14604 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14605 break;
460f00c4
AJ
14606 case OPC_DSLLV:
14607 case OPC_DSRAV:
d75c135e 14608 check_insn(ctx, ISA_MIPS3);
460f00c4 14609 check_mips_64(ctx);
d75c135e 14610 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14611 break;
ea63e2c3
NF
14612 case OPC_DSRLV:
14613 switch ((ctx->opcode >> 6) & 0x1f) {
14614 case 1:
14615 /* drotrv is decoded as dsrlv on non-R2 CPUs */
d75c135e 14616 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14617 op1 = OPC_DROTRV;
14618 }
14619 /* Fallthrough */
14620 case 0:
d75c135e 14621 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14622 check_mips_64(ctx);
d75c135e 14623 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14624 break;
14625 default:
14626 generate_exception(ctx, EXCP_RI);
14627 break;
14628 }
14629 break;
7a387fff 14630 case OPC_DMULT ... OPC_DDIVU:
d75c135e 14631 check_insn(ctx, ISA_MIPS3);
e189e748 14632 check_mips_64(ctx);
26135ead 14633 gen_muldiv(ctx, op1, 0, rs, rt);
7a387fff 14634 break;
6af0bf9c
FB
14635#endif
14636 default: /* Invalid */
14637 MIPS_INVAL("special");
14638 generate_exception(ctx, EXCP_RI);
14639 break;
14640 }
14641 break;
7a387fff
TS
14642 case OPC_SPECIAL2:
14643 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14644 switch (op1) {
7a387fff
TS
14645 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14646 case OPC_MSUB ... OPC_MSUBU:
d75c135e 14647 check_insn(ctx, ISA_MIPS32);
26135ead 14648 gen_muldiv(ctx, op1, rd & 3, rs, rt);
6af0bf9c 14649 break;
7a387fff 14650 case OPC_MUL:
d75c135e 14651 gen_arith(ctx, op1, rd, rs, rt);
6af0bf9c 14652 break;
20e1fb52
AJ
14653 case OPC_CLO:
14654 case OPC_CLZ:
d75c135e 14655 check_insn(ctx, ISA_MIPS32);
7a387fff 14656 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14657 break;
7a387fff 14658 case OPC_SDBBP:
6af0bf9c
FB
14659 /* XXX: not clear which exception should be raised
14660 * when in debug mode...
14661 */
d75c135e 14662 check_insn(ctx, ISA_MIPS32);
6af0bf9c
FB
14663 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14664 generate_exception(ctx, EXCP_DBp);
14665 } else {
14666 generate_exception(ctx, EXCP_DBp);
14667 }
ead9360e 14668 /* Treat as NOP. */
6af0bf9c 14669 break;
161f85e6
AJ
14670 case OPC_DIV_G_2F:
14671 case OPC_DIVU_G_2F:
14672 case OPC_MULT_G_2F:
14673 case OPC_MULTU_G_2F:
14674 case OPC_MOD_G_2F:
14675 case OPC_MODU_G_2F:
d75c135e 14676 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14677 gen_loongson_integer(ctx, op1, rd, rs, rt);
14678 break;
d26bc211 14679#if defined(TARGET_MIPS64)
20e1fb52
AJ
14680 case OPC_DCLO:
14681 case OPC_DCLZ:
d75c135e 14682 check_insn(ctx, ISA_MIPS64);
e189e748 14683 check_mips_64(ctx);
7a387fff
TS
14684 gen_cl(ctx, op1, rd, rs);
14685 break;
161f85e6
AJ
14686 case OPC_DMULT_G_2F:
14687 case OPC_DMULTU_G_2F:
14688 case OPC_DDIV_G_2F:
14689 case OPC_DDIVU_G_2F:
14690 case OPC_DMOD_G_2F:
14691 case OPC_DMODU_G_2F:
d75c135e 14692 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14693 gen_loongson_integer(ctx, op1, rd, rs, rt);
14694 break;
7a387fff 14695#endif
6af0bf9c
FB
14696 default: /* Invalid */
14697 MIPS_INVAL("special2");
14698 generate_exception(ctx, EXCP_RI);
14699 break;
14700 }
14701 break;
7a387fff 14702 case OPC_SPECIAL3:
2b0233ab
TS
14703 op1 = MASK_SPECIAL3(ctx->opcode);
14704 switch (op1) {
14705 case OPC_EXT:
14706 case OPC_INS:
d75c135e 14707 check_insn(ctx, ISA_MIPS32R2);
2b0233ab
TS
14708 gen_bitops(ctx, op1, rt, rs, sa, rd);
14709 break;
14710 case OPC_BSHFL:
d75c135e 14711 check_insn(ctx, ISA_MIPS32R2);
2b0233ab 14712 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14713 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14714 break;
1579a72e 14715 case OPC_RDHWR:
d75c135e 14716 gen_rdhwr(ctx, rt, rd);
1579a72e 14717 break;
ead9360e 14718 case OPC_FORK:
d75c135e 14719 check_insn(ctx, ASE_MT);
6c5c1e20 14720 {
35fbce2c
AJ
14721 TCGv t0 = tcg_temp_new();
14722 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14723
14724 gen_load_gpr(t0, rt);
14725 gen_load_gpr(t1, rs);
a7812ae4 14726 gen_helper_fork(t0, t1);
6c5c1e20
TS
14727 tcg_temp_free(t0);
14728 tcg_temp_free(t1);
14729 }
ead9360e
TS
14730 break;
14731 case OPC_YIELD:
d75c135e 14732 check_insn(ctx, ASE_MT);
6c5c1e20 14733 {
35fbce2c 14734 TCGv t0 = tcg_temp_new();
6c5c1e20 14735
35fbce2c 14736 save_cpu_state(ctx, 1);
6c5c1e20 14737 gen_load_gpr(t0, rs);
895c2d04 14738 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14739 gen_store_gpr(t0, rd);
14740 tcg_temp_free(t0);
14741 }
ead9360e 14742 break;
161f85e6 14743 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14744 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14745 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14746 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14747 * the same mask and op1. */
d75c135e 14748 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
461c08df
JL
14749 op2 = MASK_ADDUH_QB(ctx->opcode);
14750 switch (op2) {
14751 case OPC_ADDUH_QB:
14752 case OPC_ADDUH_R_QB:
14753 case OPC_ADDQH_PH:
14754 case OPC_ADDQH_R_PH:
14755 case OPC_ADDQH_W:
14756 case OPC_ADDQH_R_W:
14757 case OPC_SUBUH_QB:
14758 case OPC_SUBUH_R_QB:
14759 case OPC_SUBQH_PH:
14760 case OPC_SUBQH_R_PH:
14761 case OPC_SUBQH_W:
14762 case OPC_SUBQH_R_W:
14763 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14764 break;
a22260ae
JL
14765 case OPC_MUL_PH:
14766 case OPC_MUL_S_PH:
14767 case OPC_MULQ_S_W:
14768 case OPC_MULQ_RS_W:
14769 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14770 break;
461c08df
JL
14771 default:
14772 MIPS_INVAL("MASK ADDUH.QB");
14773 generate_exception(ctx, EXCP_RI);
14774 break;
14775 }
d75c135e 14776 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
461c08df
JL
14777 gen_loongson_integer(ctx, op1, rd, rs, rt);
14778 } else {
14779 generate_exception(ctx, EXCP_RI);
14780 }
161f85e6 14781 break;
9b1a1d68
JL
14782 case OPC_LX_DSP:
14783 op2 = MASK_LX(ctx->opcode);
14784 switch (op2) {
14785#if defined(TARGET_MIPS64)
14786 case OPC_LDX:
14787#endif
14788 case OPC_LBUX:
14789 case OPC_LHX:
14790 case OPC_LWX:
d75c135e 14791 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
9b1a1d68
JL
14792 break;
14793 default: /* Invalid */
14794 MIPS_INVAL("MASK LX");
14795 generate_exception(ctx, EXCP_RI);
14796 break;
14797 }
14798 break;
461c08df
JL
14799 case OPC_ABSQ_S_PH_DSP:
14800 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14801 switch (op2) {
14802 case OPC_ABSQ_S_QB:
14803 case OPC_ABSQ_S_PH:
14804 case OPC_ABSQ_S_W:
14805 case OPC_PRECEQ_W_PHL:
14806 case OPC_PRECEQ_W_PHR:
14807 case OPC_PRECEQU_PH_QBL:
14808 case OPC_PRECEQU_PH_QBR:
14809 case OPC_PRECEQU_PH_QBLA:
14810 case OPC_PRECEQU_PH_QBRA:
14811 case OPC_PRECEU_PH_QBL:
14812 case OPC_PRECEU_PH_QBR:
14813 case OPC_PRECEU_PH_QBLA:
14814 case OPC_PRECEU_PH_QBRA:
14815 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14816 break;
1cb6686c
JL
14817 case OPC_BITREV:
14818 case OPC_REPL_QB:
14819 case OPC_REPLV_QB:
14820 case OPC_REPL_PH:
14821 case OPC_REPLV_PH:
d75c135e 14822 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 14823 break;
461c08df
JL
14824 default:
14825 MIPS_INVAL("MASK ABSQ_S.PH");
14826 generate_exception(ctx, EXCP_RI);
14827 break;
14828 }
14829 break;
14830 case OPC_ADDU_QB_DSP:
14831 op2 = MASK_ADDU_QB(ctx->opcode);
14832 switch (op2) {
14833 case OPC_ADDQ_PH:
14834 case OPC_ADDQ_S_PH:
14835 case OPC_ADDQ_S_W:
14836 case OPC_ADDU_QB:
14837 case OPC_ADDU_S_QB:
14838 case OPC_ADDU_PH:
14839 case OPC_ADDU_S_PH:
14840 case OPC_SUBQ_PH:
14841 case OPC_SUBQ_S_PH:
14842 case OPC_SUBQ_S_W:
14843 case OPC_SUBU_QB:
14844 case OPC_SUBU_S_QB:
14845 case OPC_SUBU_PH:
14846 case OPC_SUBU_S_PH:
14847 case OPC_ADDSC:
14848 case OPC_ADDWC:
14849 case OPC_MODSUB:
14850 case OPC_RADDU_W_QB:
14851 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14852 break;
a22260ae
JL
14853 case OPC_MULEU_S_PH_QBL:
14854 case OPC_MULEU_S_PH_QBR:
14855 case OPC_MULQ_RS_PH:
14856 case OPC_MULEQ_S_W_PHL:
14857 case OPC_MULEQ_S_W_PHR:
14858 case OPC_MULQ_S_PH:
14859 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14860 break;
461c08df
JL
14861 default: /* Invalid */
14862 MIPS_INVAL("MASK ADDU.QB");
14863 generate_exception(ctx, EXCP_RI);
14864 break;
14865
14866 }
14867 break;
14868 case OPC_CMPU_EQ_QB_DSP:
14869 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14870 switch (op2) {
14871 case OPC_PRECR_SRA_PH_W:
14872 case OPC_PRECR_SRA_R_PH_W:
14873 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14874 break;
14875 case OPC_PRECR_QB_PH:
14876 case OPC_PRECRQ_QB_PH:
14877 case OPC_PRECRQ_PH_W:
14878 case OPC_PRECRQ_RS_PH_W:
14879 case OPC_PRECRQU_S_QB_PH:
14880 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14881 break;
26690560
JL
14882 case OPC_CMPU_EQ_QB:
14883 case OPC_CMPU_LT_QB:
14884 case OPC_CMPU_LE_QB:
14885 case OPC_CMP_EQ_PH:
14886 case OPC_CMP_LT_PH:
14887 case OPC_CMP_LE_PH:
14888 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14889 break;
14890 case OPC_CMPGU_EQ_QB:
14891 case OPC_CMPGU_LT_QB:
14892 case OPC_CMPGU_LE_QB:
14893 case OPC_CMPGDU_EQ_QB:
14894 case OPC_CMPGDU_LT_QB:
14895 case OPC_CMPGDU_LE_QB:
14896 case OPC_PICK_QB:
14897 case OPC_PICK_PH:
14898 case OPC_PACKRL_PH:
14899 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14900 break;
461c08df
JL
14901 default: /* Invalid */
14902 MIPS_INVAL("MASK CMPU.EQ.QB");
14903 generate_exception(ctx, EXCP_RI);
14904 break;
14905 }
14906 break;
77c5fa8b
JL
14907 case OPC_SHLL_QB_DSP:
14908 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14909 break;
a22260ae
JL
14910 case OPC_DPA_W_PH_DSP:
14911 op2 = MASK_DPA_W_PH(ctx->opcode);
14912 switch (op2) {
14913 case OPC_DPAU_H_QBL:
14914 case OPC_DPAU_H_QBR:
14915 case OPC_DPSU_H_QBL:
14916 case OPC_DPSU_H_QBR:
14917 case OPC_DPA_W_PH:
14918 case OPC_DPAX_W_PH:
14919 case OPC_DPAQ_S_W_PH:
14920 case OPC_DPAQX_S_W_PH:
14921 case OPC_DPAQX_SA_W_PH:
14922 case OPC_DPS_W_PH:
14923 case OPC_DPSX_W_PH:
14924 case OPC_DPSQ_S_W_PH:
14925 case OPC_DPSQX_S_W_PH:
14926 case OPC_DPSQX_SA_W_PH:
14927 case OPC_MULSAQ_S_W_PH:
14928 case OPC_DPAQ_SA_L_W:
14929 case OPC_DPSQ_SA_L_W:
14930 case OPC_MAQ_S_W_PHL:
14931 case OPC_MAQ_S_W_PHR:
14932 case OPC_MAQ_SA_W_PHL:
14933 case OPC_MAQ_SA_W_PHR:
14934 case OPC_MULSA_W_PH:
14935 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14936 break;
14937 default: /* Invalid */
14938 MIPS_INVAL("MASK DPAW.PH");
14939 generate_exception(ctx, EXCP_RI);
14940 break;
14941 }
14942 break;
1cb6686c
JL
14943 case OPC_INSV_DSP:
14944 op2 = MASK_INSV(ctx->opcode);
14945 switch (op2) {
14946 case OPC_INSV:
14947 check_dsp(ctx);
14948 {
14949 TCGv t0, t1;
14950
14951 if (rt == 0) {
14952 MIPS_DEBUG("NOP");
14953 break;
14954 }
14955
14956 t0 = tcg_temp_new();
14957 t1 = tcg_temp_new();
14958
14959 gen_load_gpr(t0, rt);
14960 gen_load_gpr(t1, rs);
14961
14962 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14963
14964 tcg_temp_free(t0);
14965 tcg_temp_free(t1);
14966 break;
14967 }
14968 default: /* Invalid */
14969 MIPS_INVAL("MASK INSV");
14970 generate_exception(ctx, EXCP_RI);
14971 break;
14972 }
14973 break;
26690560 14974 case OPC_APPEND_DSP:
df6126a7 14975 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 14976 break;
b53371ed
JL
14977 case OPC_EXTR_W_DSP:
14978 op2 = MASK_EXTR_W(ctx->opcode);
14979 switch (op2) {
14980 case OPC_EXTR_W:
14981 case OPC_EXTR_R_W:
14982 case OPC_EXTR_RS_W:
14983 case OPC_EXTR_S_H:
14984 case OPC_EXTRV_S_H:
14985 case OPC_EXTRV_W:
14986 case OPC_EXTRV_R_W:
14987 case OPC_EXTRV_RS_W:
14988 case OPC_EXTP:
14989 case OPC_EXTPV:
14990 case OPC_EXTPDP:
14991 case OPC_EXTPDPV:
14992 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14993 break;
14994 case OPC_RDDSP:
14995 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14996 break;
14997 case OPC_SHILO:
14998 case OPC_SHILOV:
14999 case OPC_MTHLIP:
15000 case OPC_WRDSP:
15001 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15002 break;
15003 default: /* Invalid */
15004 MIPS_INVAL("MASK EXTR.W");
15005 generate_exception(ctx, EXCP_RI);
15006 break;
15007 }
15008 break;
d26bc211 15009#if defined(TARGET_MIPS64)
1579a72e
TS
15010 case OPC_DEXTM ... OPC_DEXT:
15011 case OPC_DINSM ... OPC_DINS:
d75c135e 15012 check_insn(ctx, ISA_MIPS64R2);
e189e748 15013 check_mips_64(ctx);
1579a72e 15014 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 15015 break;
1579a72e 15016 case OPC_DBSHFL:
d75c135e 15017 check_insn(ctx, ISA_MIPS64R2);
e189e748 15018 check_mips_64(ctx);
1579a72e 15019 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 15020 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 15021 break;
161f85e6
AJ
15022 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15023 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15024 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
d75c135e 15025 check_insn(ctx, INSN_LOONGSON2E);
161f85e6
AJ
15026 gen_loongson_integer(ctx, op1, rd, rs, rt);
15027 break;
461c08df
JL
15028 case OPC_ABSQ_S_QH_DSP:
15029 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15030 switch (op2) {
15031 case OPC_PRECEQ_L_PWL:
15032 case OPC_PRECEQ_L_PWR:
15033 case OPC_PRECEQ_PW_QHL:
15034 case OPC_PRECEQ_PW_QHR:
15035 case OPC_PRECEQ_PW_QHLA:
15036 case OPC_PRECEQ_PW_QHRA:
15037 case OPC_PRECEQU_QH_OBL:
15038 case OPC_PRECEQU_QH_OBR:
15039 case OPC_PRECEQU_QH_OBLA:
15040 case OPC_PRECEQU_QH_OBRA:
15041 case OPC_PRECEU_QH_OBL:
15042 case OPC_PRECEU_QH_OBR:
15043 case OPC_PRECEU_QH_OBLA:
15044 case OPC_PRECEU_QH_OBRA:
15045 case OPC_ABSQ_S_OB:
15046 case OPC_ABSQ_S_PW:
15047 case OPC_ABSQ_S_QH:
15048 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15049 break;
1cb6686c
JL
15050 case OPC_REPL_OB:
15051 case OPC_REPL_PW:
15052 case OPC_REPL_QH:
15053 case OPC_REPLV_OB:
15054 case OPC_REPLV_PW:
15055 case OPC_REPLV_QH:
d75c135e 15056 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 15057 break;
461c08df
JL
15058 default: /* Invalid */
15059 MIPS_INVAL("MASK ABSQ_S.QH");
15060 generate_exception(ctx, EXCP_RI);
15061 break;
15062 }
15063 break;
15064 case OPC_ADDU_OB_DSP:
15065 op2 = MASK_ADDU_OB(ctx->opcode);
15066 switch (op2) {
15067 case OPC_RADDU_L_OB:
15068 case OPC_SUBQ_PW:
15069 case OPC_SUBQ_S_PW:
15070 case OPC_SUBQ_QH:
15071 case OPC_SUBQ_S_QH:
15072 case OPC_SUBU_OB:
15073 case OPC_SUBU_S_OB:
15074 case OPC_SUBU_QH:
15075 case OPC_SUBU_S_QH:
15076 case OPC_SUBUH_OB:
15077 case OPC_SUBUH_R_OB:
15078 case OPC_ADDQ_PW:
15079 case OPC_ADDQ_S_PW:
15080 case OPC_ADDQ_QH:
15081 case OPC_ADDQ_S_QH:
15082 case OPC_ADDU_OB:
15083 case OPC_ADDU_S_OB:
15084 case OPC_ADDU_QH:
15085 case OPC_ADDU_S_QH:
15086 case OPC_ADDUH_OB:
15087 case OPC_ADDUH_R_OB:
15088 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15089 break;
a22260ae
JL
15090 case OPC_MULEQ_S_PW_QHL:
15091 case OPC_MULEQ_S_PW_QHR:
15092 case OPC_MULEU_S_QH_OBL:
15093 case OPC_MULEU_S_QH_OBR:
15094 case OPC_MULQ_RS_QH:
15095 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15096 break;
461c08df
JL
15097 default: /* Invalid */
15098 MIPS_INVAL("MASK ADDU.OB");
15099 generate_exception(ctx, EXCP_RI);
15100 break;
15101 }
15102 break;
15103 case OPC_CMPU_EQ_OB_DSP:
15104 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15105 switch (op2) {
15106 case OPC_PRECR_SRA_QH_PW:
15107 case OPC_PRECR_SRA_R_QH_PW:
15108 /* Return value is rt. */
15109 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15110 break;
15111 case OPC_PRECR_OB_QH:
15112 case OPC_PRECRQ_OB_QH:
15113 case OPC_PRECRQ_PW_L:
15114 case OPC_PRECRQ_QH_PW:
15115 case OPC_PRECRQ_RS_QH_PW:
15116 case OPC_PRECRQU_S_OB_QH:
15117 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15118 break;
26690560
JL
15119 case OPC_CMPU_EQ_OB:
15120 case OPC_CMPU_LT_OB:
15121 case OPC_CMPU_LE_OB:
15122 case OPC_CMP_EQ_QH:
15123 case OPC_CMP_LT_QH:
15124 case OPC_CMP_LE_QH:
15125 case OPC_CMP_EQ_PW:
15126 case OPC_CMP_LT_PW:
15127 case OPC_CMP_LE_PW:
15128 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15129 break;
15130 case OPC_CMPGDU_EQ_OB:
15131 case OPC_CMPGDU_LT_OB:
15132 case OPC_CMPGDU_LE_OB:
15133 case OPC_CMPGU_EQ_OB:
15134 case OPC_CMPGU_LT_OB:
15135 case OPC_CMPGU_LE_OB:
15136 case OPC_PACKRL_PW:
15137 case OPC_PICK_OB:
15138 case OPC_PICK_PW:
15139 case OPC_PICK_QH:
15140 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15141 break;
461c08df
JL
15142 default: /* Invalid */
15143 MIPS_INVAL("MASK CMPU_EQ.OB");
15144 generate_exception(ctx, EXCP_RI);
15145 break;
15146 }
15147 break;
26690560 15148 case OPC_DAPPEND_DSP:
df6126a7 15149 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 15150 break;
b53371ed
JL
15151 case OPC_DEXTR_W_DSP:
15152 op2 = MASK_DEXTR_W(ctx->opcode);
15153 switch (op2) {
15154 case OPC_DEXTP:
15155 case OPC_DEXTPDP:
15156 case OPC_DEXTPDPV:
15157 case OPC_DEXTPV:
15158 case OPC_DEXTR_L:
15159 case OPC_DEXTR_R_L:
15160 case OPC_DEXTR_RS_L:
15161 case OPC_DEXTR_W:
15162 case OPC_DEXTR_R_W:
15163 case OPC_DEXTR_RS_W:
15164 case OPC_DEXTR_S_H:
15165 case OPC_DEXTRV_L:
15166 case OPC_DEXTRV_R_L:
15167 case OPC_DEXTRV_RS_L:
15168 case OPC_DEXTRV_S_H:
15169 case OPC_DEXTRV_W:
15170 case OPC_DEXTRV_R_W:
15171 case OPC_DEXTRV_RS_W:
15172 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15173 break;
15174 case OPC_DMTHLIP:
15175 case OPC_DSHILO:
15176 case OPC_DSHILOV:
15177 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15178 break;
15179 default: /* Invalid */
15180 MIPS_INVAL("MASK EXTR.W");
15181 generate_exception(ctx, EXCP_RI);
15182 break;
15183 }
15184 break;
a22260ae
JL
15185 case OPC_DPAQ_W_QH_DSP:
15186 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15187 switch (op2) {
15188 case OPC_DPAU_H_OBL:
15189 case OPC_DPAU_H_OBR:
15190 case OPC_DPSU_H_OBL:
15191 case OPC_DPSU_H_OBR:
15192 case OPC_DPA_W_QH:
15193 case OPC_DPAQ_S_W_QH:
15194 case OPC_DPS_W_QH:
15195 case OPC_DPSQ_S_W_QH:
15196 case OPC_MULSAQ_S_W_QH:
15197 case OPC_DPAQ_SA_L_PW:
15198 case OPC_DPSQ_SA_L_PW:
15199 case OPC_MULSAQ_S_L_PW:
15200 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15201 break;
15202 case OPC_MAQ_S_W_QHLL:
15203 case OPC_MAQ_S_W_QHLR:
15204 case OPC_MAQ_S_W_QHRL:
15205 case OPC_MAQ_S_W_QHRR:
15206 case OPC_MAQ_SA_W_QHLL:
15207 case OPC_MAQ_SA_W_QHLR:
15208 case OPC_MAQ_SA_W_QHRL:
15209 case OPC_MAQ_SA_W_QHRR:
15210 case OPC_MAQ_S_L_PWL:
15211 case OPC_MAQ_S_L_PWR:
15212 case OPC_DMADD:
15213 case OPC_DMADDU:
15214 case OPC_DMSUB:
15215 case OPC_DMSUBU:
15216 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15217 break;
15218 default: /* Invalid */
15219 MIPS_INVAL("MASK DPAQ.W.QH");
15220 generate_exception(ctx, EXCP_RI);
15221 break;
15222 }
15223 break;
1cb6686c
JL
15224 case OPC_DINSV_DSP:
15225 op2 = MASK_INSV(ctx->opcode);
15226 switch (op2) {
15227 case OPC_DINSV:
15228 {
15229 TCGv t0, t1;
15230
15231 if (rt == 0) {
15232 MIPS_DEBUG("NOP");
15233 break;
15234 }
15235 check_dsp(ctx);
15236
15237 t0 = tcg_temp_new();
15238 t1 = tcg_temp_new();
15239
15240 gen_load_gpr(t0, rt);
15241 gen_load_gpr(t1, rs);
15242
15243 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15244 break;
15245 }
15246 default: /* Invalid */
15247 MIPS_INVAL("MASK DINSV");
15248 generate_exception(ctx, EXCP_RI);
15249 break;
15250 }
15251 break;
77c5fa8b
JL
15252 case OPC_SHLL_OB_DSP:
15253 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15254 break;
7a387fff
TS
15255#endif
15256 default: /* Invalid */
15257 MIPS_INVAL("special3");
15258 generate_exception(ctx, EXCP_RI);
15259 break;
15260 }
15261 break;
15262 case OPC_REGIMM:
15263 op1 = MASK_REGIMM(ctx->opcode);
15264 switch (op1) {
15265 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15266 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15267 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061 15268 break;
7a387fff
TS
15269 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15270 case OPC_TNEI:
15271 gen_trap(ctx, op1, rs, -1, imm);
15272 break;
15273 case OPC_SYNCI:
d75c135e 15274 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15275 /* Treat as NOP. */
6af0bf9c 15276 break;
e45a93e2
JL
15277 case OPC_BPOSGE32: /* MIPS DSP branch */
15278#if defined(TARGET_MIPS64)
15279 case OPC_BPOSGE64:
15280#endif
15281 check_dsp(ctx);
15282 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
e45a93e2 15283 break;
6af0bf9c 15284 default: /* Invalid */
923617a3 15285 MIPS_INVAL("regimm");
6af0bf9c
FB
15286 generate_exception(ctx, EXCP_RI);
15287 break;
15288 }
15289 break;
7a387fff 15290 case OPC_CP0:
387a8fe5 15291 check_cp0_enabled(ctx);
7a387fff 15292 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15293 switch (op1) {
7a387fff
TS
15294 case OPC_MFC0:
15295 case OPC_MTC0:
ead9360e
TS
15296 case OPC_MFTR:
15297 case OPC_MTTR:
d26bc211 15298#if defined(TARGET_MIPS64)
7a387fff
TS
15299 case OPC_DMFC0:
15300 case OPC_DMTC0:
15301#endif
f1aa6320 15302#ifndef CONFIG_USER_ONLY
932e71cd 15303 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15304#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15305 break;
15306 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15307#ifndef CONFIG_USER_ONLY
932e71cd 15308 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15309#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15310 break;
15311 case OPC_MFMC0:
8706c382 15312#ifndef CONFIG_USER_ONLY
932e71cd 15313 {
35fbce2c 15314 TCGv t0 = tcg_temp_new();
6c5c1e20 15315
0eaef5aa 15316 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15317 switch (op2) {
15318 case OPC_DMT:
d75c135e 15319 check_insn(ctx, ASE_MT);
9ed5726c 15320 gen_helper_dmt(t0);
35fbce2c 15321 gen_store_gpr(t0, rt);
6c5c1e20
TS
15322 break;
15323 case OPC_EMT:
d75c135e 15324 check_insn(ctx, ASE_MT);
9ed5726c 15325 gen_helper_emt(t0);
35fbce2c 15326 gen_store_gpr(t0, rt);
da80682b 15327 break;
6c5c1e20 15328 case OPC_DVPE:
d75c135e 15329 check_insn(ctx, ASE_MT);
895c2d04 15330 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15331 gen_store_gpr(t0, rt);
6c5c1e20
TS
15332 break;
15333 case OPC_EVPE:
d75c135e 15334 check_insn(ctx, ASE_MT);
895c2d04 15335 gen_helper_evpe(t0, cpu_env);
35fbce2c 15336 gen_store_gpr(t0, rt);
6c5c1e20
TS
15337 break;
15338 case OPC_DI:
d75c135e 15339 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15340 save_cpu_state(ctx, 1);
895c2d04 15341 gen_helper_di(t0, cpu_env);
35fbce2c 15342 gen_store_gpr(t0, rt);
6c5c1e20
TS
15343 /* Stop translation as we may have switched the execution mode */
15344 ctx->bstate = BS_STOP;
15345 break;
15346 case OPC_EI:
d75c135e 15347 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15348 save_cpu_state(ctx, 1);
895c2d04 15349 gen_helper_ei(t0, cpu_env);
35fbce2c 15350 gen_store_gpr(t0, rt);
6c5c1e20
TS
15351 /* Stop translation as we may have switched the execution mode */
15352 ctx->bstate = BS_STOP;
15353 break;
15354 default: /* Invalid */
15355 MIPS_INVAL("mfmc0");
15356 generate_exception(ctx, EXCP_RI);
15357 break;
15358 }
6c5c1e20 15359 tcg_temp_free(t0);
7a387fff 15360 }
0eaef5aa 15361#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15362 break;
7a387fff 15363 case OPC_RDPGPR:
d75c135e 15364 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15365 gen_load_srsgpr(rt, rd);
ead9360e 15366 break;
7a387fff 15367 case OPC_WRPGPR:
d75c135e 15368 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15369 gen_store_srsgpr(rt, rd);
38121543 15370 break;
6af0bf9c 15371 default:
923617a3 15372 MIPS_INVAL("cp0");
7a387fff 15373 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15374 break;
15375 }
15376 break;
324d9e32
AJ
15377 case OPC_ADDI: /* Arithmetic with immediate opcode */
15378 case OPC_ADDIU:
d75c135e 15379 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15380 break;
324d9e32
AJ
15381 case OPC_SLTI: /* Set on less than with immediate opcode */
15382 case OPC_SLTIU:
d75c135e 15383 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15384 break;
15385 case OPC_ANDI: /* Arithmetic with immediate opcode */
15386 case OPC_LUI:
15387 case OPC_ORI:
15388 case OPC_XORI:
d75c135e 15389 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15390 break;
7a387fff
TS
15391 case OPC_J ... OPC_JAL: /* Jump */
15392 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15393 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061 15394 break;
7a387fff
TS
15395 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15396 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15397 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061 15398 break;
7a387fff 15399 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15400 case OPC_LL:
d75c135e 15401 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15402 break;
7a387fff
TS
15403 case OPC_SB ... OPC_SW:
15404 case OPC_SWR:
5c13fdfd 15405 gen_st(ctx, op, rt, rs, imm);
7a387fff 15406 break;
d66c7132
AJ
15407 case OPC_SC:
15408 gen_st_cond(ctx, op, rt, rs, imm);
15409 break;
7a387fff 15410 case OPC_CACHE:
2e15497c 15411 check_cp0_enabled(ctx);
d75c135e 15412 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15413 /* Treat as NOP. */
34ae7b51 15414 break;
7a387fff 15415 case OPC_PREF:
d75c135e 15416 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15417 /* Treat as NOP. */
6af0bf9c 15418 break;
4ad40f36 15419
923617a3 15420 /* Floating point (COP1). */
7a387fff
TS
15421 case OPC_LWC1:
15422 case OPC_LDC1:
15423 case OPC_SWC1:
15424 case OPC_SDC1:
26ebe468 15425 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15426 break;
15427
7a387fff 15428 case OPC_CP1:
36d23958 15429 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15430 check_cp1_enabled(ctx);
36d23958
TS
15431 op1 = MASK_CP1(ctx->opcode);
15432 switch (op1) {
3a95e3a7
TS
15433 case OPC_MFHC1:
15434 case OPC_MTHC1:
d75c135e 15435 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
15436 case OPC_MFC1:
15437 case OPC_CFC1:
15438 case OPC_MTC1:
15439 case OPC_CTC1:
e189e748
TS
15440 gen_cp1(ctx, op1, rt, rd);
15441 break;
d26bc211 15442#if defined(TARGET_MIPS64)
36d23958
TS
15443 case OPC_DMFC1:
15444 case OPC_DMTC1:
d75c135e 15445 check_insn(ctx, ISA_MIPS3);
36d23958
TS
15446 gen_cp1(ctx, op1, rt, rd);
15447 break;
e189e748 15448#endif
fbcc6828
TS
15449 case OPC_BC1ANY2:
15450 case OPC_BC1ANY4:
b8aa4598 15451 check_cop1x(ctx);
d75c135e 15452 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
15453 /* fall through */
15454 case OPC_BC1:
d75c135e 15455 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15456 (rt >> 2) & 0x7, imm << 2);
c9602061 15457 break;
36d23958
TS
15458 case OPC_S_FMT:
15459 case OPC_D_FMT:
15460 case OPC_W_FMT:
15461 case OPC_L_FMT:
5a5012ec 15462 case OPC_PS_FMT:
bf4120ad 15463 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15464 (imm >> 8) & 0x7);
36d23958
TS
15465 break;
15466 default:
923617a3 15467 MIPS_INVAL("cp1");
e397ee33 15468 generate_exception (ctx, EXCP_RI);
36d23958
TS
15469 break;
15470 }
15471 } else {
15472 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15473 }
4ad40f36
FB
15474 break;
15475
15476 /* COP2. */
7a387fff
TS
15477 case OPC_LWC2:
15478 case OPC_LDC2:
15479 case OPC_SWC2:
15480 case OPC_SDC2:
7a387fff 15481 /* COP2: Not implemented. */
4ad40f36
FB
15482 generate_exception_err(ctx, EXCP_CpU, 2);
15483 break;
bd277fa1 15484 case OPC_CP2:
d75c135e 15485 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
15486 /* Note that these instructions use different fields. */
15487 gen_loongson_multimedia(ctx, sa, rd, rt);
15488 break;
4ad40f36 15489
7a387fff 15490 case OPC_CP3:
36d23958 15491 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15492 check_cp1_enabled(ctx);
36d23958
TS
15493 op1 = MASK_CP3(ctx->opcode);
15494 switch (op1) {
5a5012ec
TS
15495 case OPC_LWXC1:
15496 case OPC_LDXC1:
15497 case OPC_LUXC1:
15498 case OPC_SWXC1:
15499 case OPC_SDXC1:
15500 case OPC_SUXC1:
93b12ccc 15501 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15502 break;
e0c84da7 15503 case OPC_PREFX:
ead9360e 15504 /* Treat as NOP. */
e0c84da7 15505 break;
5a5012ec
TS
15506 case OPC_ALNV_PS:
15507 case OPC_MADD_S:
15508 case OPC_MADD_D:
15509 case OPC_MADD_PS:
15510 case OPC_MSUB_S:
15511 case OPC_MSUB_D:
15512 case OPC_MSUB_PS:
15513 case OPC_NMADD_S:
15514 case OPC_NMADD_D:
15515 case OPC_NMADD_PS:
15516 case OPC_NMSUB_S:
15517 case OPC_NMSUB_D:
15518 case OPC_NMSUB_PS:
15519 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15520 break;
36d23958 15521 default:
923617a3 15522 MIPS_INVAL("cp3");
e397ee33 15523 generate_exception (ctx, EXCP_RI);
36d23958
TS
15524 break;
15525 }
15526 } else {
e397ee33 15527 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15528 }
4ad40f36
FB
15529 break;
15530
d26bc211 15531#if defined(TARGET_MIPS64)
7a387fff
TS
15532 /* MIPS64 opcodes */
15533 case OPC_LWU:
15534 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15535 case OPC_LLD:
15536 case OPC_LD:
d75c135e 15537 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15538 check_mips_64(ctx);
d75c135e 15539 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
15540 break;
15541 case OPC_SDL ... OPC_SDR:
7a387fff 15542 case OPC_SD:
d75c135e 15543 check_insn(ctx, ISA_MIPS3);
e189e748 15544 check_mips_64(ctx);
5c13fdfd 15545 gen_st(ctx, op, rt, rs, imm);
7a387fff 15546 break;
d66c7132 15547 case OPC_SCD:
d75c135e 15548 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
15549 check_mips_64(ctx);
15550 gen_st_cond(ctx, op, rt, rs, imm);
15551 break;
324d9e32
AJ
15552 case OPC_DADDI:
15553 case OPC_DADDIU:
d75c135e 15554 check_insn(ctx, ISA_MIPS3);
e189e748 15555 check_mips_64(ctx);
d75c135e 15556 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15557 break;
6af0bf9c 15558#endif
7a387fff 15559 case OPC_JALX:
d75c135e 15560 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15561 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15562 gen_compute_branch(ctx, op, 4, rs, rt, offset);
364d4831 15563 break;
7a387fff 15564 case OPC_MDMX:
d75c135e 15565 check_insn(ctx, ASE_MDMX);
7a387fff 15566 /* MDMX: Not implemented. */
6af0bf9c 15567 default: /* Invalid */
923617a3 15568 MIPS_INVAL("major opcode");
6af0bf9c
FB
15569 generate_exception(ctx, EXCP_RI);
15570 break;
15571 }
6af0bf9c
FB
15572}
15573
2cfc5f17 15574static inline void
6429db34
AF
15575gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15576 bool search_pc)
6af0bf9c 15577{
ed2803da 15578 CPUState *cs = CPU(cpu);
6429db34 15579 CPUMIPSState *env = &cpu->env;
278d0702 15580 DisasContext ctx;
6af0bf9c
FB
15581 target_ulong pc_start;
15582 uint16_t *gen_opc_end;
a1d1bb31 15583 CPUBreakpoint *bp;
6af0bf9c 15584 int j, lj = -1;
2e70f6ef
PB
15585 int num_insns;
15586 int max_insns;
c9602061 15587 int insn_bytes;
240ce26a 15588 int is_delay;
6af0bf9c 15589
93fcfe39
AL
15590 if (search_pc)
15591 qemu_log("search pc %d\n", search_pc);
4ad40f36 15592
6af0bf9c 15593 pc_start = tb->pc;
92414b31 15594 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15595 ctx.pc = pc_start;
4ad40f36 15596 ctx.saved_pc = -1;
ed2803da 15597 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 15598 ctx.insn_flags = env->insn_flags;
6af0bf9c
FB
15599 ctx.tb = tb;
15600 ctx.bstate = BS_NONE;
4ad40f36 15601 /* Restore delay slot state from the tb context. */
c068688b 15602 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
fd4a04eb 15603 restore_cpu_state(env, &ctx);
932e71cd 15604#ifdef CONFIG_USER_ONLY
0eaef5aa 15605 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15606#else
0eaef5aa 15607 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15608#endif
2e70f6ef
PB
15609 num_insns = 0;
15610 max_insns = tb->cflags & CF_COUNT_MASK;
15611 if (max_insns == 0)
15612 max_insns = CF_COUNT_MASK;
d12d51d5 15613 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 15614 gen_tb_start();
faf7aaa9 15615 while (ctx.bstate == BS_NONE) {
72cf2d4f
BS
15616 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15617 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 15618 if (bp->pc == ctx.pc) {
278d0702 15619 save_cpu_state(&ctx, 1);
4ad40f36 15620 ctx.bstate = BS_BRANCH;
895c2d04 15621 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15622 /* Include the breakpoint location or the tb won't
15623 * be flushed when it must be. */
15624 ctx.pc += 4;
4ad40f36
FB
15625 goto done_generating;
15626 }
15627 }
15628 }
15629
6af0bf9c 15630 if (search_pc) {
92414b31 15631 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15632 if (lj < j) {
15633 lj++;
15634 while (lj < j)
ab1103de 15635 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 15636 }
25983cad 15637 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 15638 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15639 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 15640 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 15641 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 15642 }
2e70f6ef
PB
15643 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15644 gen_io_start();
c9602061 15645
240ce26a 15646 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 15647 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15648 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 15649 insn_bytes = 4;
240ce26a 15650 decode_opc(env, &ctx);
d75c135e 15651 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 15652 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 15653 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 15654 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 15655 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 15656 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
15657 } else {
15658 generate_exception(&ctx, EXCP_RI);
3c824109 15659 ctx.bstate = BS_STOP;
c9602061
NF
15660 break;
15661 }
240ce26a 15662 if (is_delay) {
d75c135e 15663 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
15664 }
15665 ctx.pc += insn_bytes;
15666
2e70f6ef 15667 num_insns++;
4ad40f36 15668
7b270ef2
NF
15669 /* Execute a branch and its delay slot as a single instruction.
15670 This is what GDB expects and is consistent with what the
15671 hardware does (e.g. if a delay slot instruction faults, the
15672 reported PC is the PC of the branch). */
ed2803da 15673 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 15674 break;
ed2803da 15675 }
4ad40f36 15676
6af0bf9c
FB
15677 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15678 break;
4ad40f36 15679
efd7f486 15680 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 15681 break;
efd7f486 15682 }
faf7aaa9 15683
2e70f6ef
PB
15684 if (num_insns >= max_insns)
15685 break;
1b530a6d
AJ
15686
15687 if (singlestep)
15688 break;
6af0bf9c 15689 }
ed2803da 15690 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 15691 gen_io_end();
ed2803da
AF
15692 }
15693 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15694 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15695 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15696 } else {
6958549d 15697 switch (ctx.bstate) {
16c00cb2 15698 case BS_STOP:
df1561e2
TS
15699 gen_goto_tb(&ctx, 0, ctx.pc);
15700 break;
16c00cb2 15701 case BS_NONE:
278d0702 15702 save_cpu_state(&ctx, 0);
16c00cb2
TS
15703 gen_goto_tb(&ctx, 0, ctx.pc);
15704 break;
5a5012ec 15705 case BS_EXCP:
57fec1fe 15706 tcg_gen_exit_tb(0);
16c00cb2 15707 break;
5a5012ec
TS
15708 case BS_BRANCH:
15709 default:
15710 break;
6958549d 15711 }
6af0bf9c 15712 }
4ad40f36 15713done_generating:
806f352d 15714 gen_tb_end(tb, num_insns);
efd7f486 15715 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 15716 if (search_pc) {
92414b31 15717 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15718 lj++;
15719 while (lj <= j)
ab1103de 15720 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15721 } else {
15722 tb->size = ctx.pc - pc_start;
2e70f6ef 15723 tb->icount = num_insns;
6af0bf9c
FB
15724 }
15725#ifdef DEBUG_DISAS
d12d51d5 15726 LOG_DISAS("\n");
8fec2b8c 15727 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 15728 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 15729 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 15730 qemu_log("\n");
6af0bf9c
FB
15731 }
15732#endif
6af0bf9c
FB
15733}
15734
7db13fae 15735void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15736{
6429db34 15737 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
15738}
15739
7db13fae 15740void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15741{
6429db34 15742 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
15743}
15744
7db13fae 15745static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15746 int flags)
6ea83fed
FB
15747{
15748 int i;
5e755519 15749 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15750
2a5612e6
SW
15751#define printfpr(fp) \
15752 do { \
15753 if (is_fpu64) \
15754 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15755 " fd:%13g fs:%13g psu: %13g\n", \
15756 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15757 (double)(fp)->fd, \
15758 (double)(fp)->fs[FP_ENDIAN_IDX], \
15759 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15760 else { \
15761 fpr_t tmp; \
15762 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15763 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15764 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15765 " fd:%13g fs:%13g psu:%13g\n", \
15766 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15767 (double)tmp.fd, \
15768 (double)tmp.fs[FP_ENDIAN_IDX], \
15769 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15770 } \
6ea83fed
FB
15771 } while(0)
15772
5a5012ec 15773
9a78eead
SW
15774 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15775 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15776 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15777 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15778 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15779 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15780 }
15781
15782#undef printfpr
15783}
15784
d26bc211 15785#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15786/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15787 sign-extended values on 64bit machines. */
c570fd16
TS
15788
15789#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15790
8706c382 15791static void
7db13fae 15792cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15793 fprintf_function cpu_fprintf,
8706c382 15794 int flags)
c570fd16
TS
15795{
15796 int i;
15797
b5dc7732
TS
15798 if (!SIGN_EXT_P(env->active_tc.PC))
15799 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15800 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15801 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15802 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15803 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15804 if (!SIGN_EXT_P(env->btarget))
3594c774 15805 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15806
15807 for (i = 0; i < 32; i++) {
b5dc7732
TS
15808 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15809 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15810 }
15811
15812 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15813 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15814 if (!SIGN_EXT_P(env->lladdr))
15815 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15816}
15817#endif
15818
878096ee
AF
15819void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15820 int flags)
6af0bf9c 15821{
878096ee
AF
15822 MIPSCPU *cpu = MIPS_CPU(cs);
15823 CPUMIPSState *env = &cpu->env;
6af0bf9c 15824 int i;
3b46e624 15825
a7200c9f
SW
15826 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15827 " LO=0x" TARGET_FMT_lx " ds %04x "
15828 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15829 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15830 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15831 for (i = 0; i < 32; i++) {
15832 if ((i & 3) == 0)
15833 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15834 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15835 if ((i & 3) == 3)
15836 cpu_fprintf(f, "\n");
15837 }
568b600d 15838
3594c774 15839 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15840 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15841 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15842 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15843 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15844 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15845#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15846 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15847#endif
6af0bf9c
FB
15848}
15849
78ce64f4 15850void mips_tcg_init(void)
39454628 15851{
f01be154 15852 int i;
39454628
TS
15853 static int inited;
15854
15855 /* Initialize various static tables. */
15856 if (inited)
6958549d 15857 return;
39454628 15858
a7812ae4 15859 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15860 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15861 for (i = 1; i < 32; i++)
a7812ae4 15862 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15863 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15864 regnames[i]);
d73ee8a2
RH
15865
15866 for (i = 0; i < 32; i++) {
15867 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15868 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15869 }
15870
a7812ae4 15871 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15872 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15873 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15874 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15875 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15876 regnames_HI[i]);
a7812ae4 15877 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15878 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15879 regnames_LO[i]);
a7812ae4 15880 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15881 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15882 regnames_ACX[i]);
15883 }
a7812ae4 15884 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15885 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15886 "DSPControl");
1ba74fb8 15887 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15888 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15889 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15890 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15891 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15892 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15893
a7812ae4 15894 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15895 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15896 "fcr0");
15897 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15898 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15899 "fcr31");
39454628
TS
15900
15901 inited = 1;
15902}
15903
aaed909a
FB
15904#include "translate_init.c"
15905
30bf942d 15906MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15907{
0f71a709 15908 MIPSCPU *cpu;
6af0bf9c 15909 CPUMIPSState *env;
c227f099 15910 const mips_def_t *def;
6af0bf9c 15911
aaed909a
FB
15912 def = cpu_mips_find_by_name(cpu_model);
15913 if (!def)
15914 return NULL;
0f71a709
AF
15915 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15916 env = &cpu->env;
aaed909a
FB
15917 env->cpu_model = def;
15918
51cc2e78
BS
15919#ifndef CONFIG_USER_ONLY
15920 mmu_init(env, def);
15921#endif
15922 fpu_init(env, def);
15923 mvp_init(env, def);
c1caf1d9
AF
15924
15925 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15926
30bf942d 15927 return cpu;
6ae81775
TS
15928}
15929
1bba0dc9 15930void cpu_state_reset(CPUMIPSState *env)
6ae81775 15931{
55e5c285
AF
15932#ifndef CONFIG_USER_ONLY
15933 MIPSCPU *cpu = mips_env_get_cpu(env);
15934 CPUState *cs = CPU(cpu);
15935#endif
6ae81775 15936
51cc2e78
BS
15937 /* Reset registers to their default values */
15938 env->CP0_PRid = env->cpu_model->CP0_PRid;
15939 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15940#ifdef TARGET_WORDS_BIGENDIAN
15941 env->CP0_Config0 |= (1 << CP0C0_BE);
15942#endif
15943 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15944 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15945 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
15946 env->CP0_Config4 = env->cpu_model->CP0_Config4;
15947 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
15948 env->CP0_Config5 = env->cpu_model->CP0_Config5;
15949 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
15950 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15951 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
15952 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15953 << env->cpu_model->CP0_LLAddr_shift;
15954 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
15955 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15956 env->CCRes = env->cpu_model->CCRes;
15957 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15958 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15959 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15960 env->current_tc = 0;
15961 env->SEGBITS = env->cpu_model->SEGBITS;
15962 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15963#if defined(TARGET_MIPS64)
15964 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15965 env->SEGMask |= 3ULL << 62;
15966 }
15967#endif
15968 env->PABITS = env->cpu_model->PABITS;
15969 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15970 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15971 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15972 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15973 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15974 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15975 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15976 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15977 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15978 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15979 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 15980 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
15981 env->insn_flags = env->cpu_model->insn_flags;
15982
0eaef5aa 15983#if defined(CONFIG_USER_ONLY)
03e6e501 15984 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
15985# ifdef TARGET_MIPS64
15986 /* Enable 64-bit register mode. */
15987 env->CP0_Status |= (1 << CP0St_PX);
15988# endif
15989# ifdef TARGET_ABI_MIPSN64
15990 /* Enable 64-bit address mode. */
15991 env->CP0_Status |= (1 << CP0St_UX);
15992# endif
94159135
MI
15993 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15994 hardware registers. */
15995 env->CP0_HWREna |= 0x0000000F;
91a75935 15996 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 15997 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 15998 }
6f0af304
PJ
15999 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
16000 env->CP0_Status |= (1 << CP0St_MX);
853c3240 16001 }
4d66261f
PJ
16002# if defined(TARGET_MIPS64)
16003 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16004 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
16005 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
16006 env->CP0_Status |= (1 << CP0St_FR);
16007 }
4d66261f 16008# endif
932e71cd
AJ
16009#else
16010 if (env->hflags & MIPS_HFLAG_BMASK) {
16011 /* If the exception was raised from a delay slot,
16012 come back to the jump. */
16013 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 16014 } else {
932e71cd
AJ
16015 env->CP0_ErrorEPC = env->active_tc.PC;
16016 }
16017 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
16018 env->CP0_Random = env->tlb->nb_tlb - 1;
16019 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 16020 env->CP0_Wired = 0;
55e5c285 16021 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
932e71cd
AJ
16022 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16023 /* vectored interrupts not implemented, timer on int 7,
16024 no performance counters. */
16025 env->CP0_IntCtl = 0xe0000000;
16026 {
16027 int i;
16028
16029 for (i = 0; i < 7; i++) {
16030 env->CP0_WatchLo[i] = 0;
16031 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 16032 }
932e71cd
AJ
16033 env->CP0_WatchLo[7] = 0;
16034 env->CP0_WatchHi[7] = 0;
fd88b6ab 16035 }
932e71cd
AJ
16036 /* Count register increments in debug mode, EJTAG version 1 */
16037 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756
EI
16038
16039 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16040 int i;
16041
16042 /* Only TC0 on VPE 0 starts as active. */
16043 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 16044 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
16045 env->tcs[i].CP0_TCHalt = 1;
16046 }
16047 env->active_tc.CP0_TCHalt = 1;
259186a7 16048 cs->halted = 1;
9e56e756 16049
55e5c285 16050 if (cs->cpu_index == 0) {
9e56e756
EI
16051 /* VPE0 starts up enabled. */
16052 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16053 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16054
16055 /* TC0 starts up unhalted. */
259186a7 16056 cs->halted = 0;
9e56e756
EI
16057 env->active_tc.CP0_TCHalt = 0;
16058 env->tcs[0].CP0_TCHalt = 0;
16059 /* With thread 0 active. */
16060 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16061 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16062 }
16063 }
51cc2e78 16064#endif
03e6e501 16065 compute_hflags(env);
6af0bf9c 16066 env->exception_index = EXCP_NONE;
6af0bf9c 16067}
d2856f1a 16068
7db13fae 16069void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16070{
25983cad 16071 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16072 env->hflags &= ~MIPS_HFLAG_BMASK;
16073 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16074 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16075 case MIPS_HFLAG_BR:
16076 break;
16077 case MIPS_HFLAG_BC:
16078 case MIPS_HFLAG_BL:
16079 case MIPS_HFLAG_B:
16080 env->btarget = gen_opc_btarget[pc_pos];
16081 break;
16082 }
d2856f1a 16083}
This page took 3.472213 seconds and 4 git commands to generate.