]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
trace: [tcg] Include event definitions in "trace.h"
[mirror_qemu.git] / target-mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
6af0bf9c 24#include "cpu.h"
76cad711 25#include "disas/disas.h"
57fec1fe 26#include "tcg-op.h"
f08b6170 27#include "exec/cpu_ldst.h"
6af0bf9c 28
2ef6175a
RH
29#include "exec/helper-proto.h"
30#include "exec/helper-gen.h"
0a2672b7 31#include "sysemu/kvm.h"
a7812ae4 32
fb7729e2 33#define MIPS_DEBUG_DISAS 0
c570fd16 34//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c 35
7a387fff
TS
36/* MIPS major opcodes */
37#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
38
39enum {
40 /* indirect opcode tables */
7a387fff
TS
41 OPC_SPECIAL = (0x00 << 26),
42 OPC_REGIMM = (0x01 << 26),
43 OPC_CP0 = (0x10 << 26),
44 OPC_CP1 = (0x11 << 26),
45 OPC_CP2 = (0x12 << 26),
46 OPC_CP3 = (0x13 << 26),
47 OPC_SPECIAL2 = (0x1C << 26),
48 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 49 /* arithmetic with immediate */
7a387fff
TS
50 OPC_ADDI = (0x08 << 26),
51 OPC_ADDIU = (0x09 << 26),
52 OPC_SLTI = (0x0A << 26),
53 OPC_SLTIU = (0x0B << 26),
324d9e32 54 /* logic with immediate */
7a387fff
TS
55 OPC_ANDI = (0x0C << 26),
56 OPC_ORI = (0x0D << 26),
57 OPC_XORI = (0x0E << 26),
58 OPC_LUI = (0x0F << 26),
324d9e32 59 /* arithmetic with immediate */
7a387fff
TS
60 OPC_DADDI = (0x18 << 26),
61 OPC_DADDIU = (0x19 << 26),
e37e863f 62 /* Jump and branches */
7a387fff
TS
63 OPC_J = (0x02 << 26),
64 OPC_JAL = (0x03 << 26),
620e48f6 65 OPC_JALS = OPC_JAL | 0x5,
7a387fff
TS
66 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
67 OPC_BEQL = (0x14 << 26),
68 OPC_BNE = (0x05 << 26),
69 OPC_BNEL = (0x15 << 26),
70 OPC_BLEZ = (0x06 << 26),
71 OPC_BLEZL = (0x16 << 26),
72 OPC_BGTZ = (0x07 << 26),
73 OPC_BGTZL = (0x17 << 26),
74 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
620e48f6 75 OPC_JALXS = OPC_JALX | 0x5,
e37e863f 76 /* Load and stores */
7a387fff
TS
77 OPC_LDL = (0x1A << 26),
78 OPC_LDR = (0x1B << 26),
79 OPC_LB = (0x20 << 26),
80 OPC_LH = (0x21 << 26),
81 OPC_LWL = (0x22 << 26),
82 OPC_LW = (0x23 << 26),
364d4831 83 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
84 OPC_LBU = (0x24 << 26),
85 OPC_LHU = (0x25 << 26),
86 OPC_LWR = (0x26 << 26),
87 OPC_LWU = (0x27 << 26),
88 OPC_SB = (0x28 << 26),
89 OPC_SH = (0x29 << 26),
90 OPC_SWL = (0x2A << 26),
91 OPC_SW = (0x2B << 26),
92 OPC_SDL = (0x2C << 26),
93 OPC_SDR = (0x2D << 26),
94 OPC_SWR = (0x2E << 26),
95 OPC_LL = (0x30 << 26),
96 OPC_LLD = (0x34 << 26),
97 OPC_LD = (0x37 << 26),
364d4831 98 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
99 OPC_SC = (0x38 << 26),
100 OPC_SCD = (0x3C << 26),
101 OPC_SD = (0x3F << 26),
e37e863f 102 /* Floating point load/store */
7a387fff
TS
103 OPC_LWC1 = (0x31 << 26),
104 OPC_LWC2 = (0x32 << 26),
105 OPC_LDC1 = (0x35 << 26),
106 OPC_LDC2 = (0x36 << 26),
107 OPC_SWC1 = (0x39 << 26),
108 OPC_SWC2 = (0x3A << 26),
109 OPC_SDC1 = (0x3D << 26),
110 OPC_SDC2 = (0x3E << 26),
111 /* MDMX ASE specific */
112 OPC_MDMX = (0x1E << 26),
e37e863f 113 /* Cache and prefetch */
7a387fff
TS
114 OPC_CACHE = (0x2F << 26),
115 OPC_PREF = (0x33 << 26),
116 /* Reserved major opcode */
117 OPC_MAJOR3B_RESERVED = (0x3B << 26),
e37e863f
FB
118};
119
120/* MIPS special opcodes */
7a387fff
TS
121#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
122
e37e863f
FB
123enum {
124 /* Shifts */
7a387fff 125 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
126 /* NOP is SLL r0, r0, 0 */
127 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
128 /* EHB is SLL r0, r0, 3 */
129 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 130 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
131 OPC_SRA = 0x03 | OPC_SPECIAL,
132 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 133 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 134 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
135 OPC_SRAV = 0x07 | OPC_SPECIAL,
136 OPC_DSLLV = 0x14 | OPC_SPECIAL,
137 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 138 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
139 OPC_DSRAV = 0x17 | OPC_SPECIAL,
140 OPC_DSLL = 0x38 | OPC_SPECIAL,
141 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 142 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
143 OPC_DSRA = 0x3B | OPC_SPECIAL,
144 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
145 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 146 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 147 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 148 /* Multiplication / division */
7a387fff
TS
149 OPC_MULT = 0x18 | OPC_SPECIAL,
150 OPC_MULTU = 0x19 | OPC_SPECIAL,
151 OPC_DIV = 0x1A | OPC_SPECIAL,
152 OPC_DIVU = 0x1B | OPC_SPECIAL,
153 OPC_DMULT = 0x1C | OPC_SPECIAL,
154 OPC_DMULTU = 0x1D | OPC_SPECIAL,
155 OPC_DDIV = 0x1E | OPC_SPECIAL,
156 OPC_DDIVU = 0x1F | OPC_SPECIAL,
e37e863f 157 /* 2 registers arithmetic / logic */
7a387fff
TS
158 OPC_ADD = 0x20 | OPC_SPECIAL,
159 OPC_ADDU = 0x21 | OPC_SPECIAL,
160 OPC_SUB = 0x22 | OPC_SPECIAL,
161 OPC_SUBU = 0x23 | OPC_SPECIAL,
162 OPC_AND = 0x24 | OPC_SPECIAL,
163 OPC_OR = 0x25 | OPC_SPECIAL,
164 OPC_XOR = 0x26 | OPC_SPECIAL,
165 OPC_NOR = 0x27 | OPC_SPECIAL,
166 OPC_SLT = 0x2A | OPC_SPECIAL,
167 OPC_SLTU = 0x2B | OPC_SPECIAL,
168 OPC_DADD = 0x2C | OPC_SPECIAL,
169 OPC_DADDU = 0x2D | OPC_SPECIAL,
170 OPC_DSUB = 0x2E | OPC_SPECIAL,
171 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 172 /* Jumps */
7a387fff
TS
173 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
174 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
364d4831 175 OPC_JALRC = OPC_JALR | (0x5 << 6),
620e48f6 176 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
e37e863f 177 /* Traps */
7a387fff
TS
178 OPC_TGE = 0x30 | OPC_SPECIAL,
179 OPC_TGEU = 0x31 | OPC_SPECIAL,
180 OPC_TLT = 0x32 | OPC_SPECIAL,
181 OPC_TLTU = 0x33 | OPC_SPECIAL,
182 OPC_TEQ = 0x34 | OPC_SPECIAL,
183 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 184 /* HI / LO registers load & stores */
7a387fff
TS
185 OPC_MFHI = 0x10 | OPC_SPECIAL,
186 OPC_MTHI = 0x11 | OPC_SPECIAL,
187 OPC_MFLO = 0x12 | OPC_SPECIAL,
188 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 189 /* Conditional moves */
7a387fff
TS
190 OPC_MOVZ = 0x0A | OPC_SPECIAL,
191 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 192
7a387fff 193 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
194
195 /* Special */
a0d700e4 196 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
197 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
198 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 199 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
200 OPC_SYNC = 0x0F | OPC_SPECIAL,
201
202 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
203 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
204 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
205 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
206 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
207 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
208 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
209};
210
e9c71dd1
TS
211/* Multiplication variants of the vr54xx. */
212#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
213
214enum {
215 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
216 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
217 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
218 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
219 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
220 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
221 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
222 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
223 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
224 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
225 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
226 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
227 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
228 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
229};
230
7a387fff
TS
231/* REGIMM (rt field) opcodes */
232#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
233
234enum {
235 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
236 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
237 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
238 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
239 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
3c824109 240 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
7a387fff
TS
241 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
242 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
3c824109 243 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
7a387fff
TS
244 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
245 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
246 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
247 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
248 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
249 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
250 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
251 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
e37e863f
FB
252};
253
7a387fff
TS
254/* Special2 opcodes */
255#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
256
e37e863f 257enum {
7a387fff
TS
258 /* Multiply & xxx operations */
259 OPC_MADD = 0x00 | OPC_SPECIAL2,
260 OPC_MADDU = 0x01 | OPC_SPECIAL2,
261 OPC_MUL = 0x02 | OPC_SPECIAL2,
262 OPC_MSUB = 0x04 | OPC_SPECIAL2,
263 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
264 /* Loongson 2F */
265 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
266 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
267 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
268 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
269 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
270 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
271 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
272 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
273 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
274 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
275 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
276 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 277 /* Misc */
7a387fff
TS
278 OPC_CLZ = 0x20 | OPC_SPECIAL2,
279 OPC_CLO = 0x21 | OPC_SPECIAL2,
280 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
281 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 282 /* Special */
7a387fff
TS
283 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
284};
285
286/* Special3 opcodes */
287#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
288
289enum {
290 OPC_EXT = 0x00 | OPC_SPECIAL3,
291 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
292 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
293 OPC_DEXT = 0x03 | OPC_SPECIAL3,
294 OPC_INS = 0x04 | OPC_SPECIAL3,
295 OPC_DINSM = 0x05 | OPC_SPECIAL3,
296 OPC_DINSU = 0x06 | OPC_SPECIAL3,
297 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
298 OPC_FORK = 0x08 | OPC_SPECIAL3,
299 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
300 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
301 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
302 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
303
304 /* Loongson 2E */
305 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
306 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
307 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
308 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
309 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
310 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
311 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
312 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
313 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
314 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
315 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
316 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
317
318 /* MIPS DSP Load */
319 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
320 /* MIPS DSP Arithmetic */
321 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 322 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 323 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 324 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
325 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
326 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
327 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 328 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
329 /* MIPS DSP GPR-Based Shift Sub-class */
330 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 331 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
332 /* MIPS DSP Multiply Sub-class insns */
333 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
334 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
335 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 336 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
337 /* DSP Bit/Manipulation Sub-class */
338 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 339 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 340 /* MIPS DSP Append Sub-class */
26690560 341 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 342 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
343 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
344 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 345 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
e37e863f
FB
346};
347
7a387fff
TS
348/* BSHFL opcodes */
349#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
350
e37e863f 351enum {
7a387fff
TS
352 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
353 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
354 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
e37e863f
FB
355};
356
7a387fff
TS
357/* DBSHFL opcodes */
358#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
359
e37e863f 360enum {
7a387fff
TS
361 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
362 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
e37e863f
FB
363};
364
e45a93e2
JL
365/* MIPS DSP REGIMM opcodes */
366enum {
367 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 368 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
369};
370
9b1a1d68
JL
371#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
372/* MIPS DSP Load */
373enum {
374 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
375 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
376 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 377 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
378};
379
461c08df
JL
380#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381enum {
382 /* MIPS DSP Arithmetic Sub-class */
383 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
389 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
396 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
398 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
399 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
400 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
401 /* MIPS DSP Multiply Sub-class insns */
402 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
407 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
408};
409
410#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
411#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412enum {
413 /* MIPS DSP Arithmetic Sub-class */
414 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
425 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
426 /* MIPS DSP Multiply Sub-class insns */
427 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
430 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
431};
432
433#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434enum {
435 /* MIPS DSP Arithmetic Sub-class */
436 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
448 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
449 /* DSP Bit/Manipulation Sub-class */
450 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
454 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
455};
456
457#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458enum {
459 /* MIPS DSP Arithmetic Sub-class */
460 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
466 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
467 /* DSP Compare-Pick Sub-class */
468 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
482 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 483};
a22260ae 484
77c5fa8b
JL
485#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486enum {
487 /* MIPS DSP GPR-Based Shift Sub-class */
488 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
509 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
510};
461c08df 511
a22260ae
JL
512#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513enum {
514 /* MIPS DSP Multiply Sub-class insns */
515 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
528 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
529 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
531 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
536 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
537};
538
1cb6686c
JL
539#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540enum {
541 /* DSP Bit/Manipulation Sub-class */
542 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
543};
544
26690560
JL
545#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546enum {
df6126a7 547 /* MIPS DSP Append Sub-class */
26690560
JL
548 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
549 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
550 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
551};
552
b53371ed
JL
553#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554enum {
555 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
556 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
567 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
569 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
570 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
571 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
572 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
573};
574
461c08df
JL
575#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576enum {
577 /* MIPS DSP Arithmetic Sub-class */
578 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
594 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
595 /* DSP Bit/Manipulation Sub-class */
596 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
601 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 602};
461c08df 603
461c08df
JL
604#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605enum {
a22260ae
JL
606 /* MIPS DSP Multiply Sub-class insns */
607 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
611 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
612 /* MIPS DSP Arithmetic Sub-class */
613 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
623 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
633 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
634};
461c08df 635
461c08df
JL
636#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637enum {
26690560
JL
638 /* DSP Compare-Pick Sub-class */
639 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
657 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
658 /* MIPS DSP Arithmetic Sub-class */
659 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
666 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
667};
461c08df 668
26690560
JL
669#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670enum {
df6126a7 671 /* DSP Append Sub-class */
26690560
JL
672 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
674 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
675 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
676};
26690560 677
b53371ed
JL
678#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679enum {
680 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
681 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
682 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
701 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
702};
703
1cb6686c
JL
704#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705enum {
706 /* DSP Bit/Manipulation Sub-class */
707 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
708};
1cb6686c 709
a22260ae
JL
710#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711enum {
712 /* MIPS DSP Multiply Sub-class insns */
713 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
738 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
739};
a22260ae 740
77c5fa8b
JL
741#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742enum {
743 /* MIPS DSP GPR-Based Shift Sub-class */
744 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
769 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
770};
77c5fa8b 771
7a387fff
TS
772/* Coprocessor 0 (rs field) */
773#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
774
6ea83fed 775enum {
7a387fff
TS
776 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
777 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
778 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
779 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 780 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
781 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
782 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 783 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
784 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
785 OPC_C0 = (0x10 << 21) | OPC_CP0,
786 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
787 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 788};
7a387fff
TS
789
790/* MFMC0 opcodes */
b48cfdff 791#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
792
793enum {
ead9360e
TS
794 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
796 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
797 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
798 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
799 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
800};
801
802/* Coprocessor 0 (with rs == C0) */
803#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
804
805enum {
806 OPC_TLBR = 0x01 | OPC_C0,
807 OPC_TLBWI = 0x02 | OPC_C0,
808 OPC_TLBWR = 0x06 | OPC_C0,
809 OPC_TLBP = 0x08 | OPC_C0,
810 OPC_RFE = 0x10 | OPC_C0,
811 OPC_ERET = 0x18 | OPC_C0,
812 OPC_DERET = 0x1F | OPC_C0,
813 OPC_WAIT = 0x20 | OPC_C0,
814};
815
816/* Coprocessor 1 (rs field) */
817#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818
bf4120ad
NF
819/* Values for the fmt field in FP instructions */
820enum {
821 /* 0 - 15 are reserved */
e459440a
AJ
822 FMT_S = 16, /* single fp */
823 FMT_D = 17, /* double fp */
824 FMT_E = 18, /* extended fp */
825 FMT_Q = 19, /* quad fp */
826 FMT_W = 20, /* 32-bit fixed */
827 FMT_L = 21, /* 64-bit fixed */
828 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
829 /* 23 - 31 are reserved */
830};
831
7a387fff
TS
832enum {
833 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
834 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
835 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 836 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
837 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
838 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
839 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 840 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 841 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
842 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
843 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
e459440a
AJ
844 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
845 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
846 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
847 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
848 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
849 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
850 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
7a387fff
TS
851};
852
5a5012ec
TS
853#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
854#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
855
7a387fff
TS
856enum {
857 OPC_BC1F = (0x00 << 16) | OPC_BC1,
858 OPC_BC1T = (0x01 << 16) | OPC_BC1,
859 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
860 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
861};
862
5a5012ec
TS
863enum {
864 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
865 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
866};
867
868enum {
869 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
870 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
871};
7a387fff
TS
872
873#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
874
875enum {
876 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
877 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
878 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
879 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
880 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
881 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
882 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
883 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
884 OPC_BC2 = (0x08 << 21) | OPC_CP2,
885};
886
bd277fa1
RH
887#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
888
889enum {
890 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
897 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898
899 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
906 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907
908 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
911 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
912 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
913 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
914 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
915 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916
917 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
920 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
924 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925
926 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
927 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
928 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
929 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
930 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
931 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932
933 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
938 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939
940 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
941 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
945 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946
947 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
950 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
952 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953
954 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
955 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
956 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
957 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
959 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960
961 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
962 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
963 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
964 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
966 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967
968 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
969 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
970 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
971 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
973 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974
975 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
976 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
977 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
978 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
979 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
980 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
981};
982
983
e0c84da7
TS
984#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
985
986enum {
987 OPC_LWXC1 = 0x00 | OPC_CP3,
988 OPC_LDXC1 = 0x01 | OPC_CP3,
989 OPC_LUXC1 = 0x05 | OPC_CP3,
990 OPC_SWXC1 = 0x08 | OPC_CP3,
991 OPC_SDXC1 = 0x09 | OPC_CP3,
992 OPC_SUXC1 = 0x0D | OPC_CP3,
993 OPC_PREFX = 0x0F | OPC_CP3,
994 OPC_ALNV_PS = 0x1E | OPC_CP3,
995 OPC_MADD_S = 0x20 | OPC_CP3,
996 OPC_MADD_D = 0x21 | OPC_CP3,
997 OPC_MADD_PS = 0x26 | OPC_CP3,
998 OPC_MSUB_S = 0x28 | OPC_CP3,
999 OPC_MSUB_D = 0x29 | OPC_CP3,
1000 OPC_MSUB_PS = 0x2E | OPC_CP3,
1001 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1002 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1003 OPC_NMADD_PS= 0x36 | OPC_CP3,
1004 OPC_NMSUB_S = 0x38 | OPC_CP3,
1005 OPC_NMSUB_D = 0x39 | OPC_CP3,
1006 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1007};
1008
39454628 1009/* global register indices */
a7812ae4
PB
1010static TCGv_ptr cpu_env;
1011static TCGv cpu_gpr[32], cpu_PC;
4b2eb8d2 1012static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
41db4607
AJ
1013static TCGv cpu_dspctrl, btarget, bcond;
1014static TCGv_i32 hflags;
a7812ae4 1015static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1016static TCGv_i64 fpu_f64[32];
aa0bf00b 1017
1a7ff922 1018static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1019static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1020
022c62cb 1021#include "exec/gen-icount.h"
2e70f6ef 1022
895c2d04 1023#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1024 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1025 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1026 tcg_temp_free_i32(helper_tmp); \
1027 } while(0)
be24bb4f 1028
895c2d04 1029#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1030 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1031 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1032 tcg_temp_free_i32(helper_tmp); \
1033 } while(0)
be24bb4f 1034
895c2d04
BS
1035#define gen_helper_1e0i(name, ret, arg1) do { \
1036 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1037 gen_helper_##name(ret, cpu_env, helper_tmp); \
1038 tcg_temp_free_i32(helper_tmp); \
1039 } while(0)
1040
1041#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1042 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1043 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1044 tcg_temp_free_i32(helper_tmp); \
1045 } while(0)
1046
1047#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1048 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1049 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1050 tcg_temp_free_i32(helper_tmp); \
1051 } while(0)
1052
1053#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1054 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1055 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1056 tcg_temp_free_i32(helper_tmp); \
1057 } while(0)
be24bb4f 1058
895c2d04 1059#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1060 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1061 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1062 tcg_temp_free_i32(helper_tmp); \
1063 } while(0)
c239529e 1064
8e9ade68
TS
1065typedef struct DisasContext {
1066 struct TranslationBlock *tb;
1067 target_ulong pc, saved_pc;
1068 uint32_t opcode;
7b270ef2 1069 int singlestep_enabled;
d75c135e 1070 int insn_flags;
5ab5c041 1071 int32_t CP0_Config1;
8e9ade68
TS
1072 /* Routine used to access memory */
1073 int mem_idx;
1074 uint32_t hflags, saved_hflags;
1075 int bstate;
1076 target_ulong btarget;
d279279e 1077 bool ulri;
8e9ade68
TS
1078} DisasContext;
1079
1080enum {
1081 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1082 * exception condition */
8e9ade68
TS
1083 BS_STOP = 1, /* We want to stop translation for any reason */
1084 BS_BRANCH = 2, /* We reached a branch condition */
1085 BS_EXCP = 3, /* We reached an exception condition */
1086};
1087
d73ee8a2
RH
1088static const char * const regnames[] = {
1089 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1090 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1091 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1092 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1093};
6af0bf9c 1094
d73ee8a2
RH
1095static const char * const regnames_HI[] = {
1096 "HI0", "HI1", "HI2", "HI3",
1097};
4b2eb8d2 1098
d73ee8a2
RH
1099static const char * const regnames_LO[] = {
1100 "LO0", "LO1", "LO2", "LO3",
1101};
4b2eb8d2 1102
d73ee8a2
RH
1103static const char * const regnames_ACX[] = {
1104 "ACX0", "ACX1", "ACX2", "ACX3",
1105};
4b2eb8d2 1106
d73ee8a2
RH
1107static const char * const fregnames[] = {
1108 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1109 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1110 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1111 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1112};
958fb4a9 1113
fb7729e2
RH
1114#define MIPS_DEBUG(fmt, ...) \
1115 do { \
1116 if (MIPS_DEBUG_DISAS) { \
1117 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1118 TARGET_FMT_lx ": %08x " fmt "\n", \
1119 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1120 } \
1121 } while (0)
1122
1123#define LOG_DISAS(...) \
1124 do { \
1125 if (MIPS_DEBUG_DISAS) { \
1126 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1127 } \
1128 } while (0)
958fb4a9 1129
8e9ade68 1130#define MIPS_INVAL(op) \
8e9ade68 1131 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1132 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1133
8e9ade68
TS
1134/* General purpose registers moves. */
1135static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1136{
8e9ade68
TS
1137 if (reg == 0)
1138 tcg_gen_movi_tl(t, 0);
1139 else
4b2eb8d2 1140 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1141}
1142
8e9ade68 1143static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1144{
8e9ade68 1145 if (reg != 0)
4b2eb8d2 1146 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1147}
1148
b10fa3c9 1149/* Moves to/from ACX register. */
4b2eb8d2 1150static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1151{
4b2eb8d2 1152 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1153}
1154
4b2eb8d2 1155static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1156{
4b2eb8d2 1157 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1158}
1159
8e9ade68 1160/* Moves to/from shadow registers. */
be24bb4f 1161static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1162{
d9bea114 1163 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1164
1165 if (from == 0)
d9bea114 1166 tcg_gen_movi_tl(t0, 0);
8e9ade68 1167 else {
d9bea114 1168 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1169 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1170
7db13fae 1171 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1172 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1173 tcg_gen_andi_i32(t2, t2, 0xf);
1174 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1175 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1176 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1177
d9bea114 1178 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1179 tcg_temp_free_ptr(addr);
d9bea114 1180 tcg_temp_free_i32(t2);
8e9ade68 1181 }
d9bea114
AJ
1182 gen_store_gpr(t0, to);
1183 tcg_temp_free(t0);
aaa9128a
TS
1184}
1185
be24bb4f 1186static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1187{
be24bb4f 1188 if (to != 0) {
d9bea114
AJ
1189 TCGv t0 = tcg_temp_new();
1190 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1191 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1192
d9bea114 1193 gen_load_gpr(t0, from);
7db13fae 1194 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1195 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1196 tcg_gen_andi_i32(t2, t2, 0xf);
1197 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1198 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1199 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1200
d9bea114 1201 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1202 tcg_temp_free_ptr(addr);
d9bea114
AJ
1203 tcg_temp_free_i32(t2);
1204 tcg_temp_free(t0);
8e9ade68 1205 }
aaa9128a
TS
1206}
1207
aaa9128a 1208/* Floating point register moves. */
d73ee8a2 1209static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1210{
d73ee8a2 1211 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1212}
1213
d73ee8a2 1214static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1215{
d73ee8a2
RH
1216 TCGv_i64 t64 = tcg_temp_new_i64();
1217 tcg_gen_extu_i32_i64(t64, t);
1218 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1219 tcg_temp_free_i64(t64);
6d066274
AJ
1220}
1221
7f6613ce 1222static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1223{
7f6613ce
PJ
1224 if (ctx->hflags & MIPS_HFLAG_F64) {
1225 TCGv_i64 t64 = tcg_temp_new_i64();
1226 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1227 tcg_gen_trunc_i64_i32(t, t64);
1228 tcg_temp_free_i64(t64);
1229 } else {
1230 gen_load_fpr32(t, reg | 1);
1231 }
6d066274
AJ
1232}
1233
7f6613ce 1234static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1235{
7f6613ce
PJ
1236 if (ctx->hflags & MIPS_HFLAG_F64) {
1237 TCGv_i64 t64 = tcg_temp_new_i64();
1238 tcg_gen_extu_i32_i64(t64, t);
1239 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1240 tcg_temp_free_i64(t64);
1241 } else {
1242 gen_store_fpr32(t, reg | 1);
1243 }
aa0bf00b 1244}
6ea83fed 1245
d73ee8a2 1246static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1247{
f364515c 1248 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1249 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1250 } else {
d73ee8a2 1251 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1252 }
1253}
6ea83fed 1254
d73ee8a2 1255static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1256{
f364515c 1257 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1258 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1259 } else {
d73ee8a2
RH
1260 TCGv_i64 t0;
1261 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1262 t0 = tcg_temp_new_i64();
6d066274 1263 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1264 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1265 tcg_temp_free_i64(t0);
aa0bf00b
TS
1266 }
1267}
6ea83fed 1268
d94536f4 1269static inline int get_fp_bit (int cc)
a16336e4 1270{
d94536f4
AJ
1271 if (cc)
1272 return 24 + cc;
1273 else
1274 return 23;
a16336e4
TS
1275}
1276
30898801 1277/* Tests */
8e9ade68
TS
1278static inline void gen_save_pc(target_ulong pc)
1279{
1eb75d4a 1280 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1281}
30898801 1282
356265ae 1283static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1284{
d12d51d5 1285 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1286 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1287 gen_save_pc(ctx->pc);
6af0bf9c
FB
1288 ctx->saved_pc = ctx->pc;
1289 }
1290 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1291 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1292 ctx->saved_hflags = ctx->hflags;
364d4831 1293 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1294 case MIPS_HFLAG_BR:
5a5012ec
TS
1295 break;
1296 case MIPS_HFLAG_BC:
5a5012ec 1297 case MIPS_HFLAG_BL:
5a5012ec 1298 case MIPS_HFLAG_B:
d077b6f7 1299 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1300 break;
6af0bf9c
FB
1301 }
1302 }
1303}
1304
7db13fae 1305static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1306{
fd4a04eb 1307 ctx->saved_hflags = ctx->hflags;
364d4831 1308 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1309 case MIPS_HFLAG_BR:
fd4a04eb
TS
1310 break;
1311 case MIPS_HFLAG_BC:
1312 case MIPS_HFLAG_BL:
39454628 1313 case MIPS_HFLAG_B:
fd4a04eb 1314 ctx->btarget = env->btarget;
fd4a04eb 1315 break;
5a5012ec
TS
1316 }
1317}
1318
356265ae 1319static inline void
48d38ca5 1320generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1321{
a7812ae4
PB
1322 TCGv_i32 texcp = tcg_const_i32(excp);
1323 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1324 save_cpu_state(ctx, 1);
895c2d04 1325 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1326 tcg_temp_free_i32(terr);
1327 tcg_temp_free_i32(texcp);
aaa9128a
TS
1328}
1329
356265ae 1330static inline void
48d38ca5 1331generate_exception (DisasContext *ctx, int excp)
aaa9128a 1332{
6af0bf9c 1333 save_cpu_state(ctx, 1);
895c2d04 1334 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1335}
1336
48d38ca5 1337/* Addresses computation */
941694d0 1338static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1339{
941694d0 1340 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1341
1342#if defined(TARGET_MIPS64)
1343 /* For compatibility with 32-bit code, data reference in user mode
1344 with Status_UX = 0 should be casted to 32-bit and sign extended.
1345 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1346 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1347 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1348 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1349 }
1350#endif
4ad40f36
FB
1351}
1352
356265ae 1353static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1354{
fe253235 1355 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1356 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1357}
1358
356265ae 1359static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1360{
fe253235 1361 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1362 generate_exception_err(ctx, EXCP_CpU, 1);
1363}
1364
b8aa4598
TS
1365/* Verify that the processor is running with COP1X instructions enabled.
1366 This is associated with the nabla symbol in the MIPS32 and MIPS64
1367 opcode tables. */
1368
356265ae 1369static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1370{
1371 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1372 generate_exception(ctx, EXCP_RI);
1373}
1374
1375/* Verify that the processor is running with 64-bit floating-point
1376 operations enabled. */
1377
356265ae 1378static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1379{
b8aa4598 1380 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1381 generate_exception(ctx, EXCP_RI);
1382}
1383
1384/*
1385 * Verify if floating point register is valid; an operation is not defined
1386 * if bit 0 of any register specification is set and the FR bit in the
1387 * Status register equals zero, since the register numbers specify an
1388 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1389 * in the Status register equals one, both even and odd register numbers
1390 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1391 *
1392 * Multiple 64 bit wide registers can be checked by calling
1393 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1394 */
356265ae 1395static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1396{
fe253235 1397 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1398 generate_exception(ctx, EXCP_RI);
1399}
1400
853c3240
JL
1401/* Verify that the processor is running with DSP instructions enabled.
1402 This is enabled by CP0 Status register MX(24) bit.
1403 */
1404
1405static inline void check_dsp(DisasContext *ctx)
1406{
1407 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
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
1416static inline void check_dspr2(DisasContext *ctx)
1417{
1418 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1419 if (ctx->insn_flags & ASE_DSP) {
1420 generate_exception(ctx, EXCP_DSPDIS);
1421 } else {
1422 generate_exception(ctx, EXCP_RI);
1423 }
853c3240
JL
1424 }
1425}
1426
3a95e3a7 1427/* This code generates a "reserved instruction" exception if the
e189e748 1428 CPU does not support the instruction set corresponding to flags. */
d75c135e 1429static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1430{
d75c135e 1431 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1432 generate_exception(ctx, EXCP_RI);
d75c135e 1433 }
3a95e3a7
TS
1434}
1435
e189e748
TS
1436/* This code generates a "reserved instruction" exception if 64-bit
1437 instructions are not enabled. */
356265ae 1438static inline void check_mips_64(DisasContext *ctx)
e189e748 1439{
fe253235 1440 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1441 generate_exception(ctx, EXCP_RI);
1442}
1443
8153667c
NF
1444/* Define small wrappers for gen_load_fpr* so that we have a uniform
1445 calling interface for 32 and 64-bit FPRs. No sense in changing
1446 all callers for gen_load_fpr32 when we need the CTX parameter for
1447 this one use. */
1448#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1449#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1450#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1451static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1452 int ft, int fs, int cc) \
1453{ \
1454 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1455 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1456 switch (ifmt) { \
1457 case FMT_PS: \
1458 check_cp1_64bitmode(ctx); \
1459 break; \
1460 case FMT_D: \
1461 if (abs) { \
1462 check_cop1x(ctx); \
1463 } \
1464 check_cp1_registers(ctx, fs | ft); \
1465 break; \
1466 case FMT_S: \
1467 if (abs) { \
1468 check_cop1x(ctx); \
1469 } \
1470 break; \
1471 } \
1472 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1473 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1474 switch (n) { \
895c2d04
BS
1475 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1476 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1477 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1478 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1479 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1480 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1481 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1482 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1483 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1484 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1485 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1486 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1487 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1488 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1489 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1490 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1491 default: abort(); \
1492 } \
1493 tcg_temp_free_i##bits (fp0); \
1494 tcg_temp_free_i##bits (fp1); \
1495}
1496
1497FOP_CONDS(, 0, d, FMT_D, 64)
1498FOP_CONDS(abs, 1, d, FMT_D, 64)
1499FOP_CONDS(, 0, s, FMT_S, 32)
1500FOP_CONDS(abs, 1, s, FMT_S, 32)
1501FOP_CONDS(, 0, ps, FMT_PS, 64)
1502FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1503#undef FOP_CONDS
1504#undef gen_ldcmp_fpr32
1505#undef gen_ldcmp_fpr64
1506
958fb4a9 1507/* load/store instructions. */
e7139c44 1508#ifdef CONFIG_USER_ONLY
d9bea114 1509#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1510static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1511{ \
1512 TCGv t0 = tcg_temp_new(); \
1513 tcg_gen_mov_tl(t0, arg1); \
1514 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1515 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1516 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1517 tcg_temp_free(t0); \
aaa9128a 1518}
e7139c44
AJ
1519#else
1520#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1521static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1522{ \
895c2d04 1523 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1524}
1525#endif
aaa9128a
TS
1526OP_LD_ATOMIC(ll,ld32s);
1527#if defined(TARGET_MIPS64)
1528OP_LD_ATOMIC(lld,ld64);
1529#endif
1530#undef OP_LD_ATOMIC
1531
590bc601
PB
1532#ifdef CONFIG_USER_ONLY
1533#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1534static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1535{ \
1536 TCGv t0 = tcg_temp_new(); \
1537 int l1 = gen_new_label(); \
1538 int l2 = gen_new_label(); \
1539 \
1540 tcg_gen_andi_tl(t0, arg2, almask); \
1541 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1542 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1543 generate_exception(ctx, EXCP_AdES); \
1544 gen_set_label(l1); \
7db13fae 1545 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1546 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1547 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1548 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1549 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1550 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1551 gen_set_label(l2); \
1552 tcg_gen_movi_tl(t0, 0); \
1553 gen_store_gpr(t0, rt); \
1554 tcg_temp_free(t0); \
1555}
1556#else
1557#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1558static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1559{ \
1560 TCGv t0 = tcg_temp_new(); \
895c2d04 1561 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1562 gen_store_gpr(t0, rt); \
590bc601
PB
1563 tcg_temp_free(t0); \
1564}
1565#endif
590bc601 1566OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1567#if defined(TARGET_MIPS64)
590bc601 1568OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1569#endif
1570#undef OP_ST_ATOMIC
1571
662d7485
NF
1572static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1573 int base, int16_t offset)
1574{
1575 if (base == 0) {
1576 tcg_gen_movi_tl(addr, offset);
1577 } else if (offset == 0) {
1578 gen_load_gpr(addr, base);
1579 } else {
1580 tcg_gen_movi_tl(addr, offset);
1581 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1582 }
1583}
1584
364d4831
NF
1585static target_ulong pc_relative_pc (DisasContext *ctx)
1586{
1587 target_ulong pc = ctx->pc;
1588
1589 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1590 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1591
1592 pc -= branch_bytes;
1593 }
1594
1595 pc &= ~(target_ulong)3;
1596 return pc;
1597}
1598
5c13fdfd 1599/* Load */
d75c135e
AJ
1600static void gen_ld(DisasContext *ctx, uint32_t opc,
1601 int rt, int base, int16_t offset)
6af0bf9c 1602{
5c13fdfd 1603 const char *opn = "ld";
fc40787a 1604 TCGv t0, t1, t2;
afa88c3a 1605
d75c135e 1606 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1607 /* Loongson CPU uses a load to zero register for prefetch.
1608 We emulate it as a NOP. On other CPU we must perform the
1609 actual memory access. */
1610 MIPS_DEBUG("NOP");
1611 return;
1612 }
6af0bf9c 1613
afa88c3a 1614 t0 = tcg_temp_new();
662d7485 1615 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1616
6af0bf9c 1617 switch (opc) {
d26bc211 1618#if defined(TARGET_MIPS64)
6e473128 1619 case OPC_LWU:
5f68f5ae 1620 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 1621 gen_store_gpr(t0, rt);
6e473128
TS
1622 opn = "lwu";
1623 break;
6af0bf9c 1624 case OPC_LD:
5f68f5ae 1625 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 1626 gen_store_gpr(t0, rt);
6af0bf9c
FB
1627 opn = "ld";
1628 break;
7a387fff 1629 case OPC_LLD:
b835e919 1630 save_cpu_state(ctx, 1);
5c13fdfd 1631 op_ld_lld(t0, t0, ctx);
78723684 1632 gen_store_gpr(t0, rt);
7a387fff
TS
1633 opn = "lld";
1634 break;
6af0bf9c 1635 case OPC_LDL:
3cee3050 1636 t1 = tcg_temp_new();
fc40787a
AJ
1637 tcg_gen_andi_tl(t1, t0, 7);
1638#ifndef TARGET_WORDS_BIGENDIAN
1639 tcg_gen_xori_tl(t1, t1, 7);
1640#endif
1641 tcg_gen_shli_tl(t1, t1, 3);
1642 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1643 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1644 tcg_gen_shl_tl(t0, t0, t1);
1645 tcg_gen_xori_tl(t1, t1, 63);
1646 t2 = tcg_const_tl(0x7fffffffffffffffull);
1647 tcg_gen_shr_tl(t2, t2, t1);
78723684 1648 gen_load_gpr(t1, rt);
fc40787a
AJ
1649 tcg_gen_and_tl(t1, t1, t2);
1650 tcg_temp_free(t2);
1651 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1652 tcg_temp_free(t1);
fc40787a 1653 gen_store_gpr(t0, rt);
6af0bf9c
FB
1654 opn = "ldl";
1655 break;
6af0bf9c 1656 case OPC_LDR:
3cee3050 1657 t1 = tcg_temp_new();
fc40787a
AJ
1658 tcg_gen_andi_tl(t1, t0, 7);
1659#ifdef TARGET_WORDS_BIGENDIAN
1660 tcg_gen_xori_tl(t1, t1, 7);
1661#endif
1662 tcg_gen_shli_tl(t1, t1, 3);
1663 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1664 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1665 tcg_gen_shr_tl(t0, t0, t1);
1666 tcg_gen_xori_tl(t1, t1, 63);
1667 t2 = tcg_const_tl(0xfffffffffffffffeull);
1668 tcg_gen_shl_tl(t2, t2, t1);
78723684 1669 gen_load_gpr(t1, rt);
fc40787a
AJ
1670 tcg_gen_and_tl(t1, t1, t2);
1671 tcg_temp_free(t2);
1672 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1673 tcg_temp_free(t1);
fc40787a 1674 gen_store_gpr(t0, rt);
6af0bf9c
FB
1675 opn = "ldr";
1676 break;
364d4831 1677 case OPC_LDPC:
3cee3050 1678 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1679 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1680 tcg_temp_free(t1);
5f68f5ae 1681 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 1682 gen_store_gpr(t0, rt);
5c13fdfd 1683 opn = "ldpc";
364d4831 1684 break;
6af0bf9c 1685#endif
364d4831 1686 case OPC_LWPC:
3cee3050 1687 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1688 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1689 tcg_temp_free(t1);
5f68f5ae 1690 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 1691 gen_store_gpr(t0, rt);
5c13fdfd 1692 opn = "lwpc";
364d4831 1693 break;
6af0bf9c 1694 case OPC_LW:
5f68f5ae 1695 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 1696 gen_store_gpr(t0, rt);
6af0bf9c
FB
1697 opn = "lw";
1698 break;
6af0bf9c 1699 case OPC_LH:
5f68f5ae 1700 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 1701 gen_store_gpr(t0, rt);
6af0bf9c
FB
1702 opn = "lh";
1703 break;
6af0bf9c 1704 case OPC_LHU:
5f68f5ae 1705 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 1706 gen_store_gpr(t0, rt);
6af0bf9c
FB
1707 opn = "lhu";
1708 break;
1709 case OPC_LB:
5f68f5ae 1710 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 1711 gen_store_gpr(t0, rt);
6af0bf9c
FB
1712 opn = "lb";
1713 break;
6af0bf9c 1714 case OPC_LBU:
5f68f5ae 1715 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 1716 gen_store_gpr(t0, rt);
6af0bf9c
FB
1717 opn = "lbu";
1718 break;
1719 case OPC_LWL:
3cee3050 1720 t1 = tcg_temp_new();
fc40787a
AJ
1721 tcg_gen_andi_tl(t1, t0, 3);
1722#ifndef TARGET_WORDS_BIGENDIAN
1723 tcg_gen_xori_tl(t1, t1, 3);
1724#endif
1725 tcg_gen_shli_tl(t1, t1, 3);
1726 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1727 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1728 tcg_gen_shl_tl(t0, t0, t1);
1729 tcg_gen_xori_tl(t1, t1, 31);
1730 t2 = tcg_const_tl(0x7fffffffull);
1731 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1732 gen_load_gpr(t1, rt);
fc40787a
AJ
1733 tcg_gen_and_tl(t1, t1, t2);
1734 tcg_temp_free(t2);
1735 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1736 tcg_temp_free(t1);
fc40787a
AJ
1737 tcg_gen_ext32s_tl(t0, t0);
1738 gen_store_gpr(t0, rt);
6af0bf9c
FB
1739 opn = "lwl";
1740 break;
6af0bf9c 1741 case OPC_LWR:
3cee3050 1742 t1 = tcg_temp_new();
fc40787a
AJ
1743 tcg_gen_andi_tl(t1, t0, 3);
1744#ifdef TARGET_WORDS_BIGENDIAN
1745 tcg_gen_xori_tl(t1, t1, 3);
1746#endif
1747 tcg_gen_shli_tl(t1, t1, 3);
1748 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1749 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1750 tcg_gen_shr_tl(t0, t0, t1);
1751 tcg_gen_xori_tl(t1, t1, 31);
1752 t2 = tcg_const_tl(0xfffffffeull);
1753 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1754 gen_load_gpr(t1, rt);
fc40787a
AJ
1755 tcg_gen_and_tl(t1, t1, t2);
1756 tcg_temp_free(t2);
1757 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1758 tcg_temp_free(t1);
c728154b 1759 tcg_gen_ext32s_tl(t0, t0);
fc40787a 1760 gen_store_gpr(t0, rt);
6af0bf9c
FB
1761 opn = "lwr";
1762 break;
6af0bf9c 1763 case OPC_LL:
e7139c44 1764 save_cpu_state(ctx, 1);
5c13fdfd 1765 op_ld_ll(t0, t0, ctx);
78723684 1766 gen_store_gpr(t0, rt);
6af0bf9c
FB
1767 opn = "ll";
1768 break;
d66c7132 1769 }
2abf314d 1770 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1771 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1772 tcg_temp_free(t0);
d66c7132
AJ
1773}
1774
5c13fdfd
AJ
1775/* Store */
1776static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1777 int base, int16_t offset)
1778{
1779 const char *opn = "st";
1780 TCGv t0 = tcg_temp_new();
1781 TCGv t1 = tcg_temp_new();
1782
1783 gen_base_offset_addr(ctx, t0, base, offset);
1784 gen_load_gpr(t1, rt);
1785 switch (opc) {
1786#if defined(TARGET_MIPS64)
1787 case OPC_SD:
5f68f5ae 1788 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
1789 opn = "sd";
1790 break;
1791 case OPC_SDL:
1792 save_cpu_state(ctx, 1);
895c2d04 1793 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1794 opn = "sdl";
1795 break;
1796 case OPC_SDR:
1797 save_cpu_state(ctx, 1);
895c2d04 1798 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1799 opn = "sdr";
1800 break;
1801#endif
1802 case OPC_SW:
5f68f5ae 1803 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
1804 opn = "sw";
1805 break;
1806 case OPC_SH:
5f68f5ae 1807 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
1808 opn = "sh";
1809 break;
1810 case OPC_SB:
5f68f5ae 1811 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
1812 opn = "sb";
1813 break;
1814 case OPC_SWL:
1815 save_cpu_state(ctx, 1);
895c2d04 1816 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1817 opn = "swl";
1818 break;
1819 case OPC_SWR:
1820 save_cpu_state(ctx, 1);
895c2d04 1821 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1822 opn = "swr";
1823 break;
1824 }
2abf314d 1825 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1826 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1827 tcg_temp_free(t0);
1828 tcg_temp_free(t1);
1829}
1830
1831
d66c7132
AJ
1832/* Store conditional */
1833static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1834 int base, int16_t offset)
1835{
1836 const char *opn = "st_cond";
1837 TCGv t0, t1;
1838
2d2826b9 1839#ifdef CONFIG_USER_ONLY
d66c7132 1840 t0 = tcg_temp_local_new();
d66c7132 1841 t1 = tcg_temp_local_new();
2d2826b9
AJ
1842#else
1843 t0 = tcg_temp_new();
1844 t1 = tcg_temp_new();
1845#endif
1846 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1847 gen_load_gpr(t1, rt);
1848 switch (opc) {
1849#if defined(TARGET_MIPS64)
1850 case OPC_SCD:
b835e919 1851 save_cpu_state(ctx, 1);
5c13fdfd 1852 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1853 opn = "scd";
1854 break;
1855#endif
6af0bf9c 1856 case OPC_SC:
e7139c44 1857 save_cpu_state(ctx, 1);
5c13fdfd 1858 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1859 opn = "sc";
1860 break;
6af0bf9c 1861 }
2abf314d 1862 (void)opn; /* avoid a compiler warning */
6af0bf9c 1863 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1864 tcg_temp_free(t1);
d66c7132 1865 tcg_temp_free(t0);
6af0bf9c
FB
1866}
1867
6ea83fed 1868/* Load and store */
7a387fff 1869static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1870 int base, int16_t offset)
6ea83fed 1871{
923617a3 1872 const char *opn = "flt_ldst";
4e2474d6 1873 TCGv t0 = tcg_temp_new();
6ea83fed 1874
662d7485 1875 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1876 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1877 memory access. */
6ea83fed
FB
1878 switch (opc) {
1879 case OPC_LWC1:
b6d96bed 1880 {
a7812ae4 1881 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 1882 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 1883 gen_store_fpr32(fp0, ft);
a7812ae4 1884 tcg_temp_free_i32(fp0);
b6d96bed 1885 }
6ea83fed
FB
1886 opn = "lwc1";
1887 break;
1888 case OPC_SWC1:
b6d96bed 1889 {
a7812ae4 1890 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1891 gen_load_fpr32(fp0, ft);
5f68f5ae 1892 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 1893 tcg_temp_free_i32(fp0);
b6d96bed 1894 }
6ea83fed
FB
1895 opn = "swc1";
1896 break;
1897 case OPC_LDC1:
b6d96bed 1898 {
a7812ae4 1899 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 1900 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 1901 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1902 tcg_temp_free_i64(fp0);
b6d96bed 1903 }
6ea83fed
FB
1904 opn = "ldc1";
1905 break;
1906 case OPC_SDC1:
b6d96bed 1907 {
a7812ae4 1908 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 1909 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 1910 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 1911 tcg_temp_free_i64(fp0);
b6d96bed 1912 }
6ea83fed
FB
1913 opn = "sdc1";
1914 break;
1915 default:
923617a3 1916 MIPS_INVAL(opn);
e397ee33 1917 generate_exception(ctx, EXCP_RI);
78723684 1918 goto out;
6ea83fed 1919 }
2abf314d 1920 (void)opn; /* avoid a compiler warning */
6ea83fed 1921 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1922 out:
1923 tcg_temp_free(t0);
6ea83fed 1924}
6ea83fed 1925
5ab5c041
AJ
1926static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
1927 int rs, int16_t imm)
26ebe468 1928{
5ab5c041 1929 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468
NF
1930 check_cp1_enabled(ctx);
1931 gen_flt_ldst(ctx, op, rt, rs, imm);
1932 } else {
1933 generate_exception_err(ctx, EXCP_CpU, 1);
1934 }
1935}
1936
6af0bf9c 1937/* Arithmetic with immediate operand */
d75c135e
AJ
1938static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1939 int rt, int rs, int16_t imm)
6af0bf9c 1940{
324d9e32 1941 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1942 const char *opn = "imm arith";
6af0bf9c 1943
7a387fff 1944 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1945 /* If no destination, treat it as a NOP.
1946 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1947 MIPS_DEBUG("NOP");
324d9e32 1948 return;
6af0bf9c
FB
1949 }
1950 switch (opc) {
1951 case OPC_ADDI:
48d38ca5 1952 {
324d9e32
AJ
1953 TCGv t0 = tcg_temp_local_new();
1954 TCGv t1 = tcg_temp_new();
1955 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1956 int l1 = gen_new_label();
1957
324d9e32
AJ
1958 gen_load_gpr(t1, rs);
1959 tcg_gen_addi_tl(t0, t1, uimm);
1960 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1961
324d9e32
AJ
1962 tcg_gen_xori_tl(t1, t1, ~uimm);
1963 tcg_gen_xori_tl(t2, t0, uimm);
1964 tcg_gen_and_tl(t1, t1, t2);
1965 tcg_temp_free(t2);
1966 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1967 tcg_temp_free(t1);
48d38ca5
TS
1968 /* operands of same sign, result different sign */
1969 generate_exception(ctx, EXCP_OVERFLOW);
1970 gen_set_label(l1);
78723684 1971 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1972 gen_store_gpr(t0, rt);
1973 tcg_temp_free(t0);
48d38ca5 1974 }
6af0bf9c
FB
1975 opn = "addi";
1976 break;
1977 case OPC_ADDIU:
324d9e32
AJ
1978 if (rs != 0) {
1979 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1980 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1981 } else {
1982 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1983 }
6af0bf9c
FB
1984 opn = "addiu";
1985 break;
d26bc211 1986#if defined(TARGET_MIPS64)
7a387fff 1987 case OPC_DADDI:
48d38ca5 1988 {
324d9e32
AJ
1989 TCGv t0 = tcg_temp_local_new();
1990 TCGv t1 = tcg_temp_new();
1991 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1992 int l1 = gen_new_label();
1993
324d9e32
AJ
1994 gen_load_gpr(t1, rs);
1995 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1996
324d9e32
AJ
1997 tcg_gen_xori_tl(t1, t1, ~uimm);
1998 tcg_gen_xori_tl(t2, t0, uimm);
1999 tcg_gen_and_tl(t1, t1, t2);
2000 tcg_temp_free(t2);
2001 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2002 tcg_temp_free(t1);
48d38ca5
TS
2003 /* operands of same sign, result different sign */
2004 generate_exception(ctx, EXCP_OVERFLOW);
2005 gen_set_label(l1);
324d9e32
AJ
2006 gen_store_gpr(t0, rt);
2007 tcg_temp_free(t0);
48d38ca5 2008 }
7a387fff
TS
2009 opn = "daddi";
2010 break;
2011 case OPC_DADDIU:
324d9e32
AJ
2012 if (rs != 0) {
2013 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2014 } else {
2015 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2016 }
7a387fff
TS
2017 opn = "daddiu";
2018 break;
2019#endif
324d9e32 2020 }
2abf314d 2021 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2022 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2023}
2024
2025/* Logic with immediate operand */
d75c135e 2026static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2027 int rt, int rs, int16_t imm)
324d9e32
AJ
2028{
2029 target_ulong uimm;
324d9e32
AJ
2030
2031 if (rt == 0) {
2032 /* If no destination, treat it as a NOP. */
2033 MIPS_DEBUG("NOP");
2034 return;
2035 }
2036 uimm = (uint16_t)imm;
2037 switch (opc) {
6af0bf9c 2038 case OPC_ANDI:
324d9e32
AJ
2039 if (likely(rs != 0))
2040 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2041 else
2042 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2043 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2044 regnames[rs], uimm);
6af0bf9c
FB
2045 break;
2046 case OPC_ORI:
324d9e32
AJ
2047 if (rs != 0)
2048 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2049 else
2050 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2051 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2052 regnames[rs], uimm);
6af0bf9c
FB
2053 break;
2054 case OPC_XORI:
324d9e32
AJ
2055 if (likely(rs != 0))
2056 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2057 else
2058 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2059 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2060 regnames[rs], uimm);
6af0bf9c
FB
2061 break;
2062 case OPC_LUI:
324d9e32 2063 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2064 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2065 break;
2066
2067 default:
2068 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2069 break;
324d9e32 2070 }
324d9e32
AJ
2071}
2072
2073/* Set on less than with immediate operand */
d75c135e 2074static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2075 int rt, int rs, int16_t imm)
324d9e32
AJ
2076{
2077 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2078 const char *opn = "imm arith";
2079 TCGv t0;
2080
2081 if (rt == 0) {
2082 /* If no destination, treat it as a NOP. */
2083 MIPS_DEBUG("NOP");
2084 return;
2085 }
2086 t0 = tcg_temp_new();
2087 gen_load_gpr(t0, rs);
2088 switch (opc) {
2089 case OPC_SLTI:
e68dd28f 2090 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2091 opn = "slti";
2092 break;
2093 case OPC_SLTIU:
e68dd28f 2094 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2095 opn = "sltiu";
2096 break;
2097 }
2abf314d 2098 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2099 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2100 tcg_temp_free(t0);
2101}
2102
2103/* Shifts with immediate operand */
d75c135e 2104static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2105 int rt, int rs, int16_t imm)
2106{
2107 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2108 const char *opn = "imm shift";
2109 TCGv t0;
2110
2111 if (rt == 0) {
2112 /* If no destination, treat it as a NOP. */
2113 MIPS_DEBUG("NOP");
2114 return;
2115 }
2116
2117 t0 = tcg_temp_new();
2118 gen_load_gpr(t0, rs);
2119 switch (opc) {
6af0bf9c 2120 case OPC_SLL:
78723684 2121 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2122 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2123 opn = "sll";
2124 break;
2125 case OPC_SRA:
324d9e32 2126 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2127 opn = "sra";
2128 break;
2129 case OPC_SRL:
ea63e2c3
NF
2130 if (uimm != 0) {
2131 tcg_gen_ext32u_tl(t0, t0);
2132 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2133 } else {
2134 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2135 }
ea63e2c3
NF
2136 opn = "srl";
2137 break;
2138 case OPC_ROTR:
2139 if (uimm != 0) {
2140 TCGv_i32 t1 = tcg_temp_new_i32();
2141
2142 tcg_gen_trunc_tl_i32(t1, t0);
2143 tcg_gen_rotri_i32(t1, t1, uimm);
2144 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2145 tcg_temp_free_i32(t1);
3399e30f
NF
2146 } else {
2147 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2148 }
2149 opn = "rotr";
7a387fff 2150 break;
d26bc211 2151#if defined(TARGET_MIPS64)
7a387fff 2152 case OPC_DSLL:
324d9e32 2153 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2154 opn = "dsll";
2155 break;
2156 case OPC_DSRA:
324d9e32 2157 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2158 opn = "dsra";
2159 break;
2160 case OPC_DSRL:
ea63e2c3
NF
2161 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2162 opn = "dsrl";
2163 break;
2164 case OPC_DROTR:
2165 if (uimm != 0) {
2166 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2167 } else {
2168 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2169 }
ea63e2c3 2170 opn = "drotr";
7a387fff
TS
2171 break;
2172 case OPC_DSLL32:
324d9e32 2173 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2174 opn = "dsll32";
2175 break;
2176 case OPC_DSRA32:
324d9e32 2177 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2178 opn = "dsra32";
2179 break;
2180 case OPC_DSRL32:
ea63e2c3
NF
2181 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2182 opn = "dsrl32";
2183 break;
2184 case OPC_DROTR32:
2185 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2186 opn = "drotr32";
6af0bf9c 2187 break;
7a387fff 2188#endif
6af0bf9c 2189 }
2abf314d 2190 (void)opn; /* avoid a compiler warning */
93b12ccc 2191 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2192 tcg_temp_free(t0);
6af0bf9c
FB
2193}
2194
2195/* Arithmetic */
d75c135e
AJ
2196static void gen_arith(DisasContext *ctx, uint32_t opc,
2197 int rd, int rs, int rt)
6af0bf9c 2198{
923617a3 2199 const char *opn = "arith";
6af0bf9c 2200
7a387fff
TS
2201 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2202 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2203 /* If no destination, treat it as a NOP.
2204 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2205 MIPS_DEBUG("NOP");
460f00c4 2206 return;
185f0762 2207 }
460f00c4 2208
6af0bf9c
FB
2209 switch (opc) {
2210 case OPC_ADD:
48d38ca5 2211 {
460f00c4
AJ
2212 TCGv t0 = tcg_temp_local_new();
2213 TCGv t1 = tcg_temp_new();
2214 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2215 int l1 = gen_new_label();
2216
460f00c4
AJ
2217 gen_load_gpr(t1, rs);
2218 gen_load_gpr(t2, rt);
2219 tcg_gen_add_tl(t0, t1, t2);
2220 tcg_gen_ext32s_tl(t0, t0);
2221 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2222 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2223 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2224 tcg_temp_free(t2);
2225 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2226 tcg_temp_free(t1);
48d38ca5
TS
2227 /* operands of same sign, result different sign */
2228 generate_exception(ctx, EXCP_OVERFLOW);
2229 gen_set_label(l1);
460f00c4
AJ
2230 gen_store_gpr(t0, rd);
2231 tcg_temp_free(t0);
48d38ca5 2232 }
6af0bf9c
FB
2233 opn = "add";
2234 break;
2235 case OPC_ADDU:
460f00c4
AJ
2236 if (rs != 0 && rt != 0) {
2237 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2238 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2239 } else if (rs == 0 && rt != 0) {
2240 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2241 } else if (rs != 0 && rt == 0) {
2242 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2243 } else {
2244 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2245 }
6af0bf9c
FB
2246 opn = "addu";
2247 break;
2248 case OPC_SUB:
48d38ca5 2249 {
460f00c4
AJ
2250 TCGv t0 = tcg_temp_local_new();
2251 TCGv t1 = tcg_temp_new();
2252 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2253 int l1 = gen_new_label();
2254
460f00c4
AJ
2255 gen_load_gpr(t1, rs);
2256 gen_load_gpr(t2, rt);
2257 tcg_gen_sub_tl(t0, t1, t2);
2258 tcg_gen_ext32s_tl(t0, t0);
2259 tcg_gen_xor_tl(t2, t1, t2);
2260 tcg_gen_xor_tl(t1, t0, t1);
2261 tcg_gen_and_tl(t1, t1, t2);
2262 tcg_temp_free(t2);
2263 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2264 tcg_temp_free(t1);
31e3104f 2265 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2266 generate_exception(ctx, EXCP_OVERFLOW);
2267 gen_set_label(l1);
460f00c4
AJ
2268 gen_store_gpr(t0, rd);
2269 tcg_temp_free(t0);
48d38ca5 2270 }
6af0bf9c
FB
2271 opn = "sub";
2272 break;
2273 case OPC_SUBU:
460f00c4
AJ
2274 if (rs != 0 && rt != 0) {
2275 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2276 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2277 } else if (rs == 0 && rt != 0) {
2278 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2279 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2280 } else if (rs != 0 && rt == 0) {
2281 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2282 } else {
2283 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2284 }
6af0bf9c
FB
2285 opn = "subu";
2286 break;
d26bc211 2287#if defined(TARGET_MIPS64)
7a387fff 2288 case OPC_DADD:
48d38ca5 2289 {
460f00c4
AJ
2290 TCGv t0 = tcg_temp_local_new();
2291 TCGv t1 = tcg_temp_new();
2292 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2293 int l1 = gen_new_label();
2294
460f00c4
AJ
2295 gen_load_gpr(t1, rs);
2296 gen_load_gpr(t2, rt);
2297 tcg_gen_add_tl(t0, t1, t2);
2298 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2299 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2300 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2301 tcg_temp_free(t2);
2302 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2303 tcg_temp_free(t1);
48d38ca5
TS
2304 /* operands of same sign, result different sign */
2305 generate_exception(ctx, EXCP_OVERFLOW);
2306 gen_set_label(l1);
460f00c4
AJ
2307 gen_store_gpr(t0, rd);
2308 tcg_temp_free(t0);
48d38ca5 2309 }
7a387fff
TS
2310 opn = "dadd";
2311 break;
2312 case OPC_DADDU:
460f00c4
AJ
2313 if (rs != 0 && rt != 0) {
2314 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2315 } else if (rs == 0 && rt != 0) {
2316 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2317 } else if (rs != 0 && rt == 0) {
2318 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2319 } else {
2320 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2321 }
7a387fff
TS
2322 opn = "daddu";
2323 break;
2324 case OPC_DSUB:
48d38ca5 2325 {
460f00c4
AJ
2326 TCGv t0 = tcg_temp_local_new();
2327 TCGv t1 = tcg_temp_new();
2328 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2329 int l1 = gen_new_label();
2330
460f00c4
AJ
2331 gen_load_gpr(t1, rs);
2332 gen_load_gpr(t2, rt);
2333 tcg_gen_sub_tl(t0, t1, t2);
2334 tcg_gen_xor_tl(t2, t1, t2);
2335 tcg_gen_xor_tl(t1, t0, t1);
2336 tcg_gen_and_tl(t1, t1, t2);
2337 tcg_temp_free(t2);
2338 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2339 tcg_temp_free(t1);
31e3104f 2340 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2341 generate_exception(ctx, EXCP_OVERFLOW);
2342 gen_set_label(l1);
460f00c4
AJ
2343 gen_store_gpr(t0, rd);
2344 tcg_temp_free(t0);
48d38ca5 2345 }
7a387fff
TS
2346 opn = "dsub";
2347 break;
2348 case OPC_DSUBU:
460f00c4
AJ
2349 if (rs != 0 && rt != 0) {
2350 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2351 } else if (rs == 0 && rt != 0) {
2352 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2353 } else if (rs != 0 && rt == 0) {
2354 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2355 } else {
2356 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2357 }
7a387fff
TS
2358 opn = "dsubu";
2359 break;
2360#endif
460f00c4
AJ
2361 case OPC_MUL:
2362 if (likely(rs != 0 && rt != 0)) {
2363 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2364 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2365 } else {
2366 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2367 }
2368 opn = "mul";
6af0bf9c 2369 break;
460f00c4 2370 }
2abf314d 2371 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2372 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2373}
2374
2375/* Conditional move */
d75c135e 2376static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2377 int rd, int rs, int rt)
460f00c4
AJ
2378{
2379 const char *opn = "cond move";
acf12465 2380 TCGv t0, t1, t2;
460f00c4
AJ
2381
2382 if (rd == 0) {
acf12465 2383 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2384 MIPS_DEBUG("NOP");
2385 return;
2386 }
2387
acf12465
AJ
2388 t0 = tcg_temp_new();
2389 gen_load_gpr(t0, rt);
2390 t1 = tcg_const_tl(0);
2391 t2 = tcg_temp_new();
2392 gen_load_gpr(t2, rs);
460f00c4
AJ
2393 switch (opc) {
2394 case OPC_MOVN:
acf12465 2395 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2396 opn = "movn";
6af0bf9c 2397 break;
460f00c4 2398 case OPC_MOVZ:
acf12465 2399 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2400 opn = "movz";
2401 break;
2402 }
acf12465
AJ
2403 tcg_temp_free(t2);
2404 tcg_temp_free(t1);
2405 tcg_temp_free(t0);
460f00c4 2406
2abf314d 2407 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2408 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2409}
2410
2411/* Logic */
d75c135e 2412static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2413 int rd, int rs, int rt)
460f00c4
AJ
2414{
2415 const char *opn = "logic";
2416
2417 if (rd == 0) {
2418 /* If no destination, treat it as a NOP. */
2419 MIPS_DEBUG("NOP");
2420 return;
2421 }
2422
2423 switch (opc) {
6af0bf9c 2424 case OPC_AND:
460f00c4
AJ
2425 if (likely(rs != 0 && rt != 0)) {
2426 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2427 } else {
2428 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2429 }
6af0bf9c
FB
2430 opn = "and";
2431 break;
2432 case OPC_NOR:
460f00c4
AJ
2433 if (rs != 0 && rt != 0) {
2434 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2435 } else if (rs == 0 && rt != 0) {
2436 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2437 } else if (rs != 0 && rt == 0) {
2438 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2439 } else {
2440 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2441 }
6af0bf9c
FB
2442 opn = "nor";
2443 break;
2444 case OPC_OR:
460f00c4
AJ
2445 if (likely(rs != 0 && rt != 0)) {
2446 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2447 } else if (rs == 0 && rt != 0) {
2448 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2449 } else if (rs != 0 && rt == 0) {
2450 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2451 } else {
2452 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2453 }
6af0bf9c
FB
2454 opn = "or";
2455 break;
2456 case OPC_XOR:
460f00c4
AJ
2457 if (likely(rs != 0 && rt != 0)) {
2458 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2459 } else if (rs == 0 && rt != 0) {
2460 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2461 } else if (rs != 0 && rt == 0) {
2462 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2463 } else {
2464 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2465 }
6af0bf9c
FB
2466 opn = "xor";
2467 break;
460f00c4 2468 }
2abf314d 2469 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2470 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2471}
2472
2473/* Set on lower than */
d75c135e 2474static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2475 int rd, int rs, int rt)
460f00c4
AJ
2476{
2477 const char *opn = "slt";
2478 TCGv t0, t1;
2479
2480 if (rd == 0) {
2481 /* If no destination, treat it as a NOP. */
2482 MIPS_DEBUG("NOP");
2483 return;
2484 }
2485
2486 t0 = tcg_temp_new();
2487 t1 = tcg_temp_new();
2488 gen_load_gpr(t0, rs);
2489 gen_load_gpr(t1, rt);
2490 switch (opc) {
2491 case OPC_SLT:
e68dd28f 2492 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2493 opn = "slt";
6af0bf9c 2494 break;
460f00c4 2495 case OPC_SLTU:
e68dd28f 2496 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2497 opn = "sltu";
2498 break;
2499 }
2abf314d 2500 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2501 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2502 tcg_temp_free(t0);
2503 tcg_temp_free(t1);
2504}
20c4c97c 2505
460f00c4 2506/* Shifts */
d75c135e
AJ
2507static void gen_shift(DisasContext *ctx, uint32_t opc,
2508 int rd, int rs, int rt)
460f00c4
AJ
2509{
2510 const char *opn = "shifts";
2511 TCGv t0, t1;
20c4c97c 2512
460f00c4
AJ
2513 if (rd == 0) {
2514 /* If no destination, treat it as a NOP.
2515 For add & sub, we must generate the overflow exception when needed. */
2516 MIPS_DEBUG("NOP");
2517 return;
2518 }
2519
2520 t0 = tcg_temp_new();
2521 t1 = tcg_temp_new();
2522 gen_load_gpr(t0, rs);
2523 gen_load_gpr(t1, rt);
2524 switch (opc) {
6af0bf9c 2525 case OPC_SLLV:
78723684
TS
2526 tcg_gen_andi_tl(t0, t0, 0x1f);
2527 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2528 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2529 opn = "sllv";
2530 break;
2531 case OPC_SRAV:
78723684 2532 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2533 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2534 opn = "srav";
2535 break;
2536 case OPC_SRLV:
ea63e2c3
NF
2537 tcg_gen_ext32u_tl(t1, t1);
2538 tcg_gen_andi_tl(t0, t0, 0x1f);
2539 tcg_gen_shr_tl(t0, t1, t0);
2540 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2541 opn = "srlv";
2542 break;
2543 case OPC_ROTRV:
2544 {
2545 TCGv_i32 t2 = tcg_temp_new_i32();
2546 TCGv_i32 t3 = tcg_temp_new_i32();
2547
2548 tcg_gen_trunc_tl_i32(t2, t0);
2549 tcg_gen_trunc_tl_i32(t3, t1);
2550 tcg_gen_andi_i32(t2, t2, 0x1f);
2551 tcg_gen_rotr_i32(t2, t3, t2);
2552 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2553 tcg_temp_free_i32(t2);
2554 tcg_temp_free_i32(t3);
2555 opn = "rotrv";
5a63bcb2 2556 }
7a387fff 2557 break;
d26bc211 2558#if defined(TARGET_MIPS64)
7a387fff 2559 case OPC_DSLLV:
78723684 2560 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2561 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2562 opn = "dsllv";
2563 break;
2564 case OPC_DSRAV:
78723684 2565 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2566 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2567 opn = "dsrav";
2568 break;
2569 case OPC_DSRLV:
ea63e2c3
NF
2570 tcg_gen_andi_tl(t0, t0, 0x3f);
2571 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2572 opn = "dsrlv";
2573 break;
2574 case OPC_DROTRV:
2575 tcg_gen_andi_tl(t0, t0, 0x3f);
2576 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2577 opn = "drotrv";
6af0bf9c 2578 break;
7a387fff 2579#endif
6af0bf9c 2580 }
2abf314d 2581 (void)opn; /* avoid a compiler warning */
6af0bf9c 2582 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2583 tcg_temp_free(t0);
2584 tcg_temp_free(t1);
6af0bf9c
FB
2585}
2586
2587/* Arithmetic on HI/LO registers */
26135ead 2588static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 2589{
923617a3 2590 const char *opn = "hilo";
6af0bf9c
FB
2591
2592 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2593 /* Treat as NOP. */
6af0bf9c 2594 MIPS_DEBUG("NOP");
a1f6684d 2595 return;
6af0bf9c 2596 }
4133498f 2597
4133498f
JL
2598 if (acc != 0) {
2599 check_dsp(ctx);
2600 }
2601
6af0bf9c
FB
2602 switch (opc) {
2603 case OPC_MFHI:
4133498f
JL
2604#if defined(TARGET_MIPS64)
2605 if (acc != 0) {
2606 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2607 } else
2608#endif
2609 {
2610 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2611 }
6af0bf9c
FB
2612 opn = "mfhi";
2613 break;
2614 case OPC_MFLO:
4133498f
JL
2615#if defined(TARGET_MIPS64)
2616 if (acc != 0) {
2617 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2618 } else
2619#endif
2620 {
2621 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2622 }
6af0bf9c
FB
2623 opn = "mflo";
2624 break;
2625 case OPC_MTHI:
4133498f
JL
2626 if (reg != 0) {
2627#if defined(TARGET_MIPS64)
2628 if (acc != 0) {
2629 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2630 } else
2631#endif
2632 {
2633 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2634 }
2635 } else {
2636 tcg_gen_movi_tl(cpu_HI[acc], 0);
2637 }
6af0bf9c
FB
2638 opn = "mthi";
2639 break;
2640 case OPC_MTLO:
4133498f
JL
2641 if (reg != 0) {
2642#if defined(TARGET_MIPS64)
2643 if (acc != 0) {
2644 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2645 } else
2646#endif
2647 {
2648 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2649 }
2650 } else {
2651 tcg_gen_movi_tl(cpu_LO[acc], 0);
2652 }
6af0bf9c
FB
2653 opn = "mtlo";
2654 break;
6af0bf9c 2655 }
2abf314d 2656 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2657 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2658}
2659
26135ead
RS
2660static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2661 int acc, int rs, int rt)
6af0bf9c 2662{
923617a3 2663 const char *opn = "mul/div";
d45f89f4
AJ
2664 TCGv t0, t1;
2665
51127181
AJ
2666 t0 = tcg_temp_new();
2667 t1 = tcg_temp_new();
6af0bf9c 2668
78723684
TS
2669 gen_load_gpr(t0, rs);
2670 gen_load_gpr(t1, rt);
51127181 2671
26135ead
RS
2672 if (acc != 0) {
2673 check_dsp(ctx);
2674 }
2675
6af0bf9c
FB
2676 switch (opc) {
2677 case OPC_DIV:
48d38ca5 2678 {
51127181
AJ
2679 TCGv t2 = tcg_temp_new();
2680 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2681 tcg_gen_ext32s_tl(t0, t0);
2682 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2683 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2684 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2685 tcg_gen_and_tl(t2, t2, t3);
2686 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2687 tcg_gen_or_tl(t2, t2, t3);
2688 tcg_gen_movi_tl(t3, 0);
2689 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2690 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2691 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2692 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2693 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2694 tcg_temp_free(t3);
2695 tcg_temp_free(t2);
48d38ca5 2696 }
6af0bf9c
FB
2697 opn = "div";
2698 break;
2699 case OPC_DIVU:
48d38ca5 2700 {
51127181
AJ
2701 TCGv t2 = tcg_const_tl(0);
2702 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
2703 tcg_gen_ext32u_tl(t0, t0);
2704 tcg_gen_ext32u_tl(t1, t1);
51127181 2705 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2706 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2707 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2708 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2709 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2710 tcg_temp_free(t3);
2711 tcg_temp_free(t2);
48d38ca5 2712 }
6af0bf9c
FB
2713 opn = "divu";
2714 break;
2715 case OPC_MULT:
214c465f 2716 {
ce1dd5d1
RH
2717 TCGv_i32 t2 = tcg_temp_new_i32();
2718 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
2719 tcg_gen_trunc_tl_i32(t2, t0);
2720 tcg_gen_trunc_tl_i32(t3, t1);
2721 tcg_gen_muls2_i32(t2, t3, t2, t3);
2722 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2723 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2724 tcg_temp_free_i32(t2);
2725 tcg_temp_free_i32(t3);
214c465f 2726 }
6af0bf9c
FB
2727 opn = "mult";
2728 break;
2729 case OPC_MULTU:
214c465f 2730 {
ce1dd5d1
RH
2731 TCGv_i32 t2 = tcg_temp_new_i32();
2732 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
2733 tcg_gen_trunc_tl_i32(t2, t0);
2734 tcg_gen_trunc_tl_i32(t3, t1);
2735 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2736 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2737 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2738 tcg_temp_free_i32(t2);
2739 tcg_temp_free_i32(t3);
214c465f 2740 }
6af0bf9c
FB
2741 opn = "multu";
2742 break;
d26bc211 2743#if defined(TARGET_MIPS64)
7a387fff 2744 case OPC_DDIV:
48d38ca5 2745 {
51127181
AJ
2746 TCGv t2 = tcg_temp_new();
2747 TCGv t3 = tcg_temp_new();
2748 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2749 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2750 tcg_gen_and_tl(t2, t2, t3);
2751 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2752 tcg_gen_or_tl(t2, t2, t3);
2753 tcg_gen_movi_tl(t3, 0);
2754 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2755 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2756 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
2757 tcg_temp_free(t3);
2758 tcg_temp_free(t2);
48d38ca5 2759 }
7a387fff
TS
2760 opn = "ddiv";
2761 break;
2762 case OPC_DDIVU:
48d38ca5 2763 {
51127181
AJ
2764 TCGv t2 = tcg_const_tl(0);
2765 TCGv t3 = tcg_const_tl(1);
2766 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
2767 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2768 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
2769 tcg_temp_free(t3);
2770 tcg_temp_free(t2);
48d38ca5 2771 }
7a387fff
TS
2772 opn = "ddivu";
2773 break;
2774 case OPC_DMULT:
26135ead 2775 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
2776 opn = "dmult";
2777 break;
2778 case OPC_DMULTU:
26135ead 2779 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
2780 opn = "dmultu";
2781 break;
2782#endif
6af0bf9c 2783 case OPC_MADD:
214c465f 2784 {
d45f89f4
AJ
2785 TCGv_i64 t2 = tcg_temp_new_i64();
2786 TCGv_i64 t3 = tcg_temp_new_i64();
2787
2788 tcg_gen_ext_tl_i64(t2, t0);
2789 tcg_gen_ext_tl_i64(t3, t1);
2790 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2791 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2792 tcg_gen_add_i64(t2, t2, t3);
2793 tcg_temp_free_i64(t3);
2794 tcg_gen_trunc_i64_tl(t0, t2);
2795 tcg_gen_shri_i64(t2, t2, 32);
2796 tcg_gen_trunc_i64_tl(t1, t2);
2797 tcg_temp_free_i64(t2);
4133498f
JL
2798 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2799 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2800 }
6af0bf9c
FB
2801 opn = "madd";
2802 break;
2803 case OPC_MADDU:
4133498f 2804 {
d45f89f4
AJ
2805 TCGv_i64 t2 = tcg_temp_new_i64();
2806 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 2807
78723684
TS
2808 tcg_gen_ext32u_tl(t0, t0);
2809 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2810 tcg_gen_extu_tl_i64(t2, t0);
2811 tcg_gen_extu_tl_i64(t3, t1);
2812 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2813 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2814 tcg_gen_add_i64(t2, t2, t3);
2815 tcg_temp_free_i64(t3);
2816 tcg_gen_trunc_i64_tl(t0, t2);
2817 tcg_gen_shri_i64(t2, t2, 32);
2818 tcg_gen_trunc_i64_tl(t1, t2);
2819 tcg_temp_free_i64(t2);
4133498f
JL
2820 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2821 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2822 }
6af0bf9c
FB
2823 opn = "maddu";
2824 break;
2825 case OPC_MSUB:
214c465f 2826 {
d45f89f4
AJ
2827 TCGv_i64 t2 = tcg_temp_new_i64();
2828 TCGv_i64 t3 = tcg_temp_new_i64();
2829
2830 tcg_gen_ext_tl_i64(t2, t0);
2831 tcg_gen_ext_tl_i64(t3, t1);
2832 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2833 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2834 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2835 tcg_temp_free_i64(t3);
2836 tcg_gen_trunc_i64_tl(t0, t2);
2837 tcg_gen_shri_i64(t2, t2, 32);
2838 tcg_gen_trunc_i64_tl(t1, t2);
2839 tcg_temp_free_i64(t2);
4133498f
JL
2840 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2841 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2842 }
6af0bf9c
FB
2843 opn = "msub";
2844 break;
2845 case OPC_MSUBU:
214c465f 2846 {
d45f89f4
AJ
2847 TCGv_i64 t2 = tcg_temp_new_i64();
2848 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 2849
78723684
TS
2850 tcg_gen_ext32u_tl(t0, t0);
2851 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2852 tcg_gen_extu_tl_i64(t2, t0);
2853 tcg_gen_extu_tl_i64(t3, t1);
2854 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2855 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2856 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2857 tcg_temp_free_i64(t3);
2858 tcg_gen_trunc_i64_tl(t0, t2);
2859 tcg_gen_shri_i64(t2, t2, 32);
2860 tcg_gen_trunc_i64_tl(t1, t2);
2861 tcg_temp_free_i64(t2);
4133498f
JL
2862 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2863 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2864 }
6af0bf9c
FB
2865 opn = "msubu";
2866 break;
2867 default:
923617a3 2868 MIPS_INVAL(opn);
6af0bf9c 2869 generate_exception(ctx, EXCP_RI);
78723684 2870 goto out;
6af0bf9c 2871 }
2abf314d 2872 (void)opn; /* avoid a compiler warning */
6af0bf9c 2873 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2874 out:
2875 tcg_temp_free(t0);
2876 tcg_temp_free(t1);
6af0bf9c
FB
2877}
2878
e9c71dd1
TS
2879static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2880 int rd, int rs, int rt)
2881{
2882 const char *opn = "mul vr54xx";
f157bfe1
AJ
2883 TCGv t0 = tcg_temp_new();
2884 TCGv t1 = tcg_temp_new();
e9c71dd1 2885
6c5c1e20
TS
2886 gen_load_gpr(t0, rs);
2887 gen_load_gpr(t1, rt);
e9c71dd1
TS
2888
2889 switch (opc) {
2890 case OPC_VR54XX_MULS:
895c2d04 2891 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2892 opn = "muls";
6958549d 2893 break;
e9c71dd1 2894 case OPC_VR54XX_MULSU:
895c2d04 2895 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2896 opn = "mulsu";
6958549d 2897 break;
e9c71dd1 2898 case OPC_VR54XX_MACC:
895c2d04 2899 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2900 opn = "macc";
6958549d 2901 break;
e9c71dd1 2902 case OPC_VR54XX_MACCU:
895c2d04 2903 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2904 opn = "maccu";
6958549d 2905 break;
e9c71dd1 2906 case OPC_VR54XX_MSAC:
895c2d04 2907 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2908 opn = "msac";
6958549d 2909 break;
e9c71dd1 2910 case OPC_VR54XX_MSACU:
895c2d04 2911 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2912 opn = "msacu";
6958549d 2913 break;
e9c71dd1 2914 case OPC_VR54XX_MULHI:
895c2d04 2915 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2916 opn = "mulhi";
6958549d 2917 break;
e9c71dd1 2918 case OPC_VR54XX_MULHIU:
895c2d04 2919 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2920 opn = "mulhiu";
6958549d 2921 break;
e9c71dd1 2922 case OPC_VR54XX_MULSHI:
895c2d04 2923 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2924 opn = "mulshi";
6958549d 2925 break;
e9c71dd1 2926 case OPC_VR54XX_MULSHIU:
895c2d04 2927 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2928 opn = "mulshiu";
6958549d 2929 break;
e9c71dd1 2930 case OPC_VR54XX_MACCHI:
895c2d04 2931 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2932 opn = "macchi";
6958549d 2933 break;
e9c71dd1 2934 case OPC_VR54XX_MACCHIU:
895c2d04 2935 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2936 opn = "macchiu";
6958549d 2937 break;
e9c71dd1 2938 case OPC_VR54XX_MSACHI:
895c2d04 2939 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2940 opn = "msachi";
6958549d 2941 break;
e9c71dd1 2942 case OPC_VR54XX_MSACHIU:
895c2d04 2943 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2944 opn = "msachiu";
6958549d 2945 break;
e9c71dd1
TS
2946 default:
2947 MIPS_INVAL("mul vr54xx");
2948 generate_exception(ctx, EXCP_RI);
6c5c1e20 2949 goto out;
e9c71dd1 2950 }
6c5c1e20 2951 gen_store_gpr(t0, rd);
2abf314d 2952 (void)opn; /* avoid a compiler warning */
e9c71dd1 2953 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2954
2955 out:
2956 tcg_temp_free(t0);
2957 tcg_temp_free(t1);
e9c71dd1
TS
2958}
2959
7a387fff 2960static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2961 int rd, int rs)
2962{
923617a3 2963 const char *opn = "CLx";
20e1fb52 2964 TCGv t0;
6c5c1e20 2965
6af0bf9c 2966 if (rd == 0) {
ead9360e 2967 /* Treat as NOP. */
6af0bf9c 2968 MIPS_DEBUG("NOP");
20e1fb52 2969 return;
6af0bf9c 2970 }
20e1fb52 2971 t0 = tcg_temp_new();
6c5c1e20 2972 gen_load_gpr(t0, rs);
6af0bf9c
FB
2973 switch (opc) {
2974 case OPC_CLO:
20e1fb52 2975 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
2976 opn = "clo";
2977 break;
2978 case OPC_CLZ:
20e1fb52 2979 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
2980 opn = "clz";
2981 break;
d26bc211 2982#if defined(TARGET_MIPS64)
7a387fff 2983 case OPC_DCLO:
20e1fb52 2984 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
2985 opn = "dclo";
2986 break;
2987 case OPC_DCLZ:
20e1fb52 2988 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
2989 opn = "dclz";
2990 break;
2991#endif
6af0bf9c 2992 }
2abf314d 2993 (void)opn; /* avoid a compiler warning */
6af0bf9c 2994 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 2995 tcg_temp_free(t0);
6af0bf9c
FB
2996}
2997
161f85e6 2998/* Godson integer instructions */
bd277fa1
RH
2999static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3000 int rd, int rs, int rt)
161f85e6
AJ
3001{
3002 const char *opn = "loongson";
3003 TCGv t0, t1;
3004
3005 if (rd == 0) {
3006 /* Treat as NOP. */
3007 MIPS_DEBUG("NOP");
3008 return;
3009 }
3010
3011 switch (opc) {
3012 case OPC_MULT_G_2E:
3013 case OPC_MULT_G_2F:
3014 case OPC_MULTU_G_2E:
3015 case OPC_MULTU_G_2F:
3016#if defined(TARGET_MIPS64)
3017 case OPC_DMULT_G_2E:
3018 case OPC_DMULT_G_2F:
3019 case OPC_DMULTU_G_2E:
3020 case OPC_DMULTU_G_2F:
3021#endif
3022 t0 = tcg_temp_new();
3023 t1 = tcg_temp_new();
3024 break;
3025 default:
3026 t0 = tcg_temp_local_new();
3027 t1 = tcg_temp_local_new();
3028 break;
3029 }
3030
3031 gen_load_gpr(t0, rs);
3032 gen_load_gpr(t1, rt);
3033
3034 switch (opc) {
3035 case OPC_MULT_G_2E:
3036 case OPC_MULT_G_2F:
3037 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3038 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3039 opn = "mult.g";
3040 break;
3041 case OPC_MULTU_G_2E:
3042 case OPC_MULTU_G_2F:
3043 tcg_gen_ext32u_tl(t0, t0);
3044 tcg_gen_ext32u_tl(t1, t1);
3045 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3046 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3047 opn = "multu.g";
3048 break;
3049 case OPC_DIV_G_2E:
3050 case OPC_DIV_G_2F:
3051 {
3052 int l1 = gen_new_label();
3053 int l2 = gen_new_label();
3054 int l3 = gen_new_label();
3055 tcg_gen_ext32s_tl(t0, t0);
3056 tcg_gen_ext32s_tl(t1, t1);
3057 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3058 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3059 tcg_gen_br(l3);
3060 gen_set_label(l1);
3061 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3062 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3063 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3064 tcg_gen_br(l3);
3065 gen_set_label(l2);
3066 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3067 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3068 gen_set_label(l3);
3069 }
3070 opn = "div.g";
3071 break;
3072 case OPC_DIVU_G_2E:
3073 case OPC_DIVU_G_2F:
3074 {
3075 int l1 = gen_new_label();
3076 int l2 = gen_new_label();
3077 tcg_gen_ext32u_tl(t0, t0);
3078 tcg_gen_ext32u_tl(t1, t1);
3079 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3080 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3081 tcg_gen_br(l2);
3082 gen_set_label(l1);
3083 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3084 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3085 gen_set_label(l2);
3086 }
3087 opn = "divu.g";
3088 break;
3089 case OPC_MOD_G_2E:
3090 case OPC_MOD_G_2F:
3091 {
3092 int l1 = gen_new_label();
3093 int l2 = gen_new_label();
3094 int l3 = gen_new_label();
3095 tcg_gen_ext32u_tl(t0, t0);
3096 tcg_gen_ext32u_tl(t1, t1);
3097 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3098 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3099 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3100 gen_set_label(l1);
3101 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3102 tcg_gen_br(l3);
3103 gen_set_label(l2);
3104 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3105 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3106 gen_set_label(l3);
3107 }
3108 opn = "mod.g";
3109 break;
3110 case OPC_MODU_G_2E:
3111 case OPC_MODU_G_2F:
3112 {
3113 int l1 = gen_new_label();
3114 int l2 = gen_new_label();
3115 tcg_gen_ext32u_tl(t0, t0);
3116 tcg_gen_ext32u_tl(t1, t1);
3117 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3118 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3119 tcg_gen_br(l2);
3120 gen_set_label(l1);
3121 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3122 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3123 gen_set_label(l2);
3124 }
3125 opn = "modu.g";
3126 break;
3127#if defined(TARGET_MIPS64)
3128 case OPC_DMULT_G_2E:
3129 case OPC_DMULT_G_2F:
3130 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3131 opn = "dmult.g";
3132 break;
3133 case OPC_DMULTU_G_2E:
3134 case OPC_DMULTU_G_2F:
3135 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3136 opn = "dmultu.g";
3137 break;
3138 case OPC_DDIV_G_2E:
3139 case OPC_DDIV_G_2F:
3140 {
3141 int l1 = gen_new_label();
3142 int l2 = gen_new_label();
3143 int l3 = gen_new_label();
3144 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3145 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3146 tcg_gen_br(l3);
3147 gen_set_label(l1);
3148 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3149 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3150 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3151 tcg_gen_br(l3);
3152 gen_set_label(l2);
3153 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3154 gen_set_label(l3);
3155 }
3156 opn = "ddiv.g";
3157 break;
3158 case OPC_DDIVU_G_2E:
3159 case OPC_DDIVU_G_2F:
3160 {
3161 int l1 = gen_new_label();
3162 int l2 = gen_new_label();
3163 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3164 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3165 tcg_gen_br(l2);
3166 gen_set_label(l1);
3167 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3168 gen_set_label(l2);
3169 }
3170 opn = "ddivu.g";
3171 break;
3172 case OPC_DMOD_G_2E:
3173 case OPC_DMOD_G_2F:
3174 {
3175 int l1 = gen_new_label();
3176 int l2 = gen_new_label();
3177 int l3 = gen_new_label();
3178 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3179 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3180 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3181 gen_set_label(l1);
3182 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3183 tcg_gen_br(l3);
3184 gen_set_label(l2);
3185 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3186 gen_set_label(l3);
3187 }
3188 opn = "dmod.g";
3189 break;
3190 case OPC_DMODU_G_2E:
3191 case OPC_DMODU_G_2F:
3192 {
3193 int l1 = gen_new_label();
3194 int l2 = gen_new_label();
3195 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3196 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3197 tcg_gen_br(l2);
3198 gen_set_label(l1);
3199 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3200 gen_set_label(l2);
3201 }
3202 opn = "dmodu.g";
3203 break;
3204#endif
3205 }
3206
2abf314d 3207 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3208 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3209 tcg_temp_free(t0);
3210 tcg_temp_free(t1);
3211}
3212
bd277fa1
RH
3213/* Loongson multimedia instructions */
3214static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3215{
3216 const char *opn = "loongson_cp2";
3217 uint32_t opc, shift_max;
3218 TCGv_i64 t0, t1;
3219
3220 opc = MASK_LMI(ctx->opcode);
3221 switch (opc) {
3222 case OPC_ADD_CP2:
3223 case OPC_SUB_CP2:
3224 case OPC_DADD_CP2:
3225 case OPC_DSUB_CP2:
3226 t0 = tcg_temp_local_new_i64();
3227 t1 = tcg_temp_local_new_i64();
3228 break;
3229 default:
3230 t0 = tcg_temp_new_i64();
3231 t1 = tcg_temp_new_i64();
3232 break;
3233 }
3234
3235 gen_load_fpr64(ctx, t0, rs);
3236 gen_load_fpr64(ctx, t1, rt);
3237
3238#define LMI_HELPER(UP, LO) \
3239 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3240#define LMI_HELPER_1(UP, LO) \
3241 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3242#define LMI_DIRECT(UP, LO, OP) \
3243 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3244
3245 switch (opc) {
3246 LMI_HELPER(PADDSH, paddsh);
3247 LMI_HELPER(PADDUSH, paddush);
3248 LMI_HELPER(PADDH, paddh);
3249 LMI_HELPER(PADDW, paddw);
3250 LMI_HELPER(PADDSB, paddsb);
3251 LMI_HELPER(PADDUSB, paddusb);
3252 LMI_HELPER(PADDB, paddb);
3253
3254 LMI_HELPER(PSUBSH, psubsh);
3255 LMI_HELPER(PSUBUSH, psubush);
3256 LMI_HELPER(PSUBH, psubh);
3257 LMI_HELPER(PSUBW, psubw);
3258 LMI_HELPER(PSUBSB, psubsb);
3259 LMI_HELPER(PSUBUSB, psubusb);
3260 LMI_HELPER(PSUBB, psubb);
3261
3262 LMI_HELPER(PSHUFH, pshufh);
3263 LMI_HELPER(PACKSSWH, packsswh);
3264 LMI_HELPER(PACKSSHB, packsshb);
3265 LMI_HELPER(PACKUSHB, packushb);
3266
3267 LMI_HELPER(PUNPCKLHW, punpcklhw);
3268 LMI_HELPER(PUNPCKHHW, punpckhhw);
3269 LMI_HELPER(PUNPCKLBH, punpcklbh);
3270 LMI_HELPER(PUNPCKHBH, punpckhbh);
3271 LMI_HELPER(PUNPCKLWD, punpcklwd);
3272 LMI_HELPER(PUNPCKHWD, punpckhwd);
3273
3274 LMI_HELPER(PAVGH, pavgh);
3275 LMI_HELPER(PAVGB, pavgb);
3276 LMI_HELPER(PMAXSH, pmaxsh);
3277 LMI_HELPER(PMINSH, pminsh);
3278 LMI_HELPER(PMAXUB, pmaxub);
3279 LMI_HELPER(PMINUB, pminub);
3280
3281 LMI_HELPER(PCMPEQW, pcmpeqw);
3282 LMI_HELPER(PCMPGTW, pcmpgtw);
3283 LMI_HELPER(PCMPEQH, pcmpeqh);
3284 LMI_HELPER(PCMPGTH, pcmpgth);
3285 LMI_HELPER(PCMPEQB, pcmpeqb);
3286 LMI_HELPER(PCMPGTB, pcmpgtb);
3287
3288 LMI_HELPER(PSLLW, psllw);
3289 LMI_HELPER(PSLLH, psllh);
3290 LMI_HELPER(PSRLW, psrlw);
3291 LMI_HELPER(PSRLH, psrlh);
3292 LMI_HELPER(PSRAW, psraw);
3293 LMI_HELPER(PSRAH, psrah);
3294
3295 LMI_HELPER(PMULLH, pmullh);
3296 LMI_HELPER(PMULHH, pmulhh);
3297 LMI_HELPER(PMULHUH, pmulhuh);
3298 LMI_HELPER(PMADDHW, pmaddhw);
3299
3300 LMI_HELPER(PASUBUB, pasubub);
3301 LMI_HELPER_1(BIADD, biadd);
3302 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3303
3304 LMI_DIRECT(PADDD, paddd, add);
3305 LMI_DIRECT(PSUBD, psubd, sub);
3306 LMI_DIRECT(XOR_CP2, xor, xor);
3307 LMI_DIRECT(NOR_CP2, nor, nor);
3308 LMI_DIRECT(AND_CP2, and, and);
3309 LMI_DIRECT(PANDN, pandn, andc);
3310 LMI_DIRECT(OR, or, or);
3311
3312 case OPC_PINSRH_0:
3313 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3314 opn = "pinsrh_0";
3315 break;
3316 case OPC_PINSRH_1:
3317 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3318 opn = "pinsrh_1";
3319 break;
3320 case OPC_PINSRH_2:
3321 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3322 opn = "pinsrh_2";
3323 break;
3324 case OPC_PINSRH_3:
3325 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3326 opn = "pinsrh_3";
3327 break;
3328
3329 case OPC_PEXTRH:
3330 tcg_gen_andi_i64(t1, t1, 3);
3331 tcg_gen_shli_i64(t1, t1, 4);
3332 tcg_gen_shr_i64(t0, t0, t1);
3333 tcg_gen_ext16u_i64(t0, t0);
3334 opn = "pextrh";
3335 break;
3336
3337 case OPC_ADDU_CP2:
3338 tcg_gen_add_i64(t0, t0, t1);
3339 tcg_gen_ext32s_i64(t0, t0);
3340 opn = "addu";
3341 break;
3342 case OPC_SUBU_CP2:
3343 tcg_gen_sub_i64(t0, t0, t1);
3344 tcg_gen_ext32s_i64(t0, t0);
3345 opn = "addu";
3346 break;
3347
3348 case OPC_SLL_CP2:
3349 opn = "sll";
3350 shift_max = 32;
3351 goto do_shift;
3352 case OPC_SRL_CP2:
3353 opn = "srl";
3354 shift_max = 32;
3355 goto do_shift;
3356 case OPC_SRA_CP2:
3357 opn = "sra";
3358 shift_max = 32;
3359 goto do_shift;
3360 case OPC_DSLL_CP2:
3361 opn = "dsll";
3362 shift_max = 64;
3363 goto do_shift;
3364 case OPC_DSRL_CP2:
3365 opn = "dsrl";
3366 shift_max = 64;
3367 goto do_shift;
3368 case OPC_DSRA_CP2:
3369 opn = "dsra";
3370 shift_max = 64;
3371 goto do_shift;
3372 do_shift:
3373 /* Make sure shift count isn't TCG undefined behaviour. */
3374 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3375
3376 switch (opc) {
3377 case OPC_SLL_CP2:
3378 case OPC_DSLL_CP2:
3379 tcg_gen_shl_i64(t0, t0, t1);
3380 break;
3381 case OPC_SRA_CP2:
3382 case OPC_DSRA_CP2:
3383 /* Since SRA is UndefinedResult without sign-extended inputs,
3384 we can treat SRA and DSRA the same. */
3385 tcg_gen_sar_i64(t0, t0, t1);
3386 break;
3387 case OPC_SRL_CP2:
3388 /* We want to shift in zeros for SRL; zero-extend first. */
3389 tcg_gen_ext32u_i64(t0, t0);
3390 /* FALLTHRU */
3391 case OPC_DSRL_CP2:
3392 tcg_gen_shr_i64(t0, t0, t1);
3393 break;
3394 }
3395
3396 if (shift_max == 32) {
3397 tcg_gen_ext32s_i64(t0, t0);
3398 }
3399
3400 /* Shifts larger than MAX produce zero. */
3401 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3402 tcg_gen_neg_i64(t1, t1);
3403 tcg_gen_and_i64(t0, t0, t1);
3404 break;
3405
3406 case OPC_ADD_CP2:
3407 case OPC_DADD_CP2:
3408 {
3409 TCGv_i64 t2 = tcg_temp_new_i64();
3410 int lab = gen_new_label();
3411
3412 tcg_gen_mov_i64(t2, t0);
3413 tcg_gen_add_i64(t0, t1, t2);
3414 if (opc == OPC_ADD_CP2) {
3415 tcg_gen_ext32s_i64(t0, t0);
3416 }
3417 tcg_gen_xor_i64(t1, t1, t2);
3418 tcg_gen_xor_i64(t2, t2, t0);
3419 tcg_gen_andc_i64(t1, t2, t1);
3420 tcg_temp_free_i64(t2);
3421 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3422 generate_exception(ctx, EXCP_OVERFLOW);
3423 gen_set_label(lab);
3424
3425 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3426 break;
3427 }
3428
3429 case OPC_SUB_CP2:
3430 case OPC_DSUB_CP2:
3431 {
3432 TCGv_i64 t2 = tcg_temp_new_i64();
3433 int lab = gen_new_label();
3434
3435 tcg_gen_mov_i64(t2, t0);
3436 tcg_gen_sub_i64(t0, t1, t2);
3437 if (opc == OPC_SUB_CP2) {
3438 tcg_gen_ext32s_i64(t0, t0);
3439 }
3440 tcg_gen_xor_i64(t1, t1, t2);
3441 tcg_gen_xor_i64(t2, t2, t0);
3442 tcg_gen_and_i64(t1, t1, t2);
3443 tcg_temp_free_i64(t2);
3444 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3445 generate_exception(ctx, EXCP_OVERFLOW);
3446 gen_set_label(lab);
3447
3448 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3449 break;
3450 }
3451
3452 case OPC_PMULUW:
3453 tcg_gen_ext32u_i64(t0, t0);
3454 tcg_gen_ext32u_i64(t1, t1);
3455 tcg_gen_mul_i64(t0, t0, t1);
3456 opn = "pmuluw";
3457 break;
3458
3459 case OPC_SEQU_CP2:
3460 case OPC_SEQ_CP2:
3461 case OPC_SLTU_CP2:
3462 case OPC_SLT_CP2:
3463 case OPC_SLEU_CP2:
3464 case OPC_SLE_CP2:
3465 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3466 FD field is the CC field? */
3467 default:
3468 MIPS_INVAL(opn);
3469 generate_exception(ctx, EXCP_RI);
3470 return;
3471 }
3472
3473#undef LMI_HELPER
3474#undef LMI_DIRECT
3475
3476 gen_store_fpr64(ctx, t0, rd);
3477
3478 (void)opn; /* avoid a compiler warning */
3479 MIPS_DEBUG("%s %s, %s, %s", opn,
3480 fregnames[rd], fregnames[rs], fregnames[rt]);
3481 tcg_temp_free_i64(t0);
3482 tcg_temp_free_i64(t1);
3483}
3484
6af0bf9c 3485/* Traps */
7a387fff 3486static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3487 int rs, int rt, int16_t imm)
3488{
3489 int cond;
cdc0faa6 3490 TCGv t0 = tcg_temp_new();
1ba74fb8 3491 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3492
3493 cond = 0;
3494 /* Load needed operands */
3495 switch (opc) {
3496 case OPC_TEQ:
3497 case OPC_TGE:
3498 case OPC_TGEU:
3499 case OPC_TLT:
3500 case OPC_TLTU:
3501 case OPC_TNE:
3502 /* Compare two registers */
3503 if (rs != rt) {
be24bb4f
TS
3504 gen_load_gpr(t0, rs);
3505 gen_load_gpr(t1, rt);
6af0bf9c
FB
3506 cond = 1;
3507 }
179e32bb 3508 break;
6af0bf9c
FB
3509 case OPC_TEQI:
3510 case OPC_TGEI:
3511 case OPC_TGEIU:
3512 case OPC_TLTI:
3513 case OPC_TLTIU:
3514 case OPC_TNEI:
3515 /* Compare register to immediate */
3516 if (rs != 0 || imm != 0) {
be24bb4f
TS
3517 gen_load_gpr(t0, rs);
3518 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3519 cond = 1;
3520 }
3521 break;
3522 }
3523 if (cond == 0) {
3524 switch (opc) {
3525 case OPC_TEQ: /* rs == rs */
3526 case OPC_TEQI: /* r0 == 0 */
3527 case OPC_TGE: /* rs >= rs */
3528 case OPC_TGEI: /* r0 >= 0 */
3529 case OPC_TGEU: /* rs >= rs unsigned */
3530 case OPC_TGEIU: /* r0 >= 0 unsigned */
3531 /* Always trap */
cdc0faa6 3532 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3533 break;
3534 case OPC_TLT: /* rs < rs */
3535 case OPC_TLTI: /* r0 < 0 */
3536 case OPC_TLTU: /* rs < rs unsigned */
3537 case OPC_TLTIU: /* r0 < 0 unsigned */
3538 case OPC_TNE: /* rs != rs */
3539 case OPC_TNEI: /* r0 != 0 */
ead9360e 3540 /* Never trap: treat as NOP. */
cdc0faa6 3541 break;
6af0bf9c
FB
3542 }
3543 } else {
cdc0faa6
AJ
3544 int l1 = gen_new_label();
3545
6af0bf9c
FB
3546 switch (opc) {
3547 case OPC_TEQ:
3548 case OPC_TEQI:
cdc0faa6 3549 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3550 break;
3551 case OPC_TGE:
3552 case OPC_TGEI:
cdc0faa6 3553 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3554 break;
3555 case OPC_TGEU:
3556 case OPC_TGEIU:
cdc0faa6 3557 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3558 break;
3559 case OPC_TLT:
3560 case OPC_TLTI:
cdc0faa6 3561 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3562 break;
3563 case OPC_TLTU:
3564 case OPC_TLTIU:
cdc0faa6 3565 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3566 break;
3567 case OPC_TNE:
3568 case OPC_TNEI:
cdc0faa6 3569 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3570 break;
6af0bf9c 3571 }
cdc0faa6 3572 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3573 gen_set_label(l1);
3574 }
be24bb4f
TS
3575 tcg_temp_free(t0);
3576 tcg_temp_free(t1);
6af0bf9c
FB
3577}
3578
356265ae 3579static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3580{
6e256c93
FB
3581 TranslationBlock *tb;
3582 tb = ctx->tb;
7b270ef2
NF
3583 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3584 likely(!ctx->singlestep_enabled)) {
57fec1fe 3585 tcg_gen_goto_tb(n);
9b9e4393 3586 gen_save_pc(dest);
8cfd0495 3587 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 3588 } else {
9b9e4393 3589 gen_save_pc(dest);
7b270ef2
NF
3590 if (ctx->singlestep_enabled) {
3591 save_cpu_state(ctx, 0);
895c2d04 3592 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3593 }
57fec1fe 3594 tcg_gen_exit_tb(0);
6e256c93 3595 }
c53be334
FB
3596}
3597
6af0bf9c 3598/* Branches (before delay slot) */
7a387fff 3599static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3600 int insn_bytes,
6af0bf9c
FB
3601 int rs, int rt, int32_t offset)
3602{
d077b6f7 3603 target_ulong btgt = -1;
3ad4bb2d 3604 int blink = 0;
2fdbad25 3605 int bcond_compute = 0;
1ba74fb8
AJ
3606 TCGv t0 = tcg_temp_new();
3607 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3608
3609 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3610#ifdef MIPS_DEBUG_DISAS
d12d51d5 3611 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3612#endif
3ad4bb2d 3613 generate_exception(ctx, EXCP_RI);
6c5c1e20 3614 goto out;
3ad4bb2d 3615 }
6af0bf9c 3616
6af0bf9c
FB
3617 /* Load needed operands */
3618 switch (opc) {
3619 case OPC_BEQ:
3620 case OPC_BEQL:
3621 case OPC_BNE:
3622 case OPC_BNEL:
3623 /* Compare two registers */
3624 if (rs != rt) {
6c5c1e20
TS
3625 gen_load_gpr(t0, rs);
3626 gen_load_gpr(t1, rt);
2fdbad25 3627 bcond_compute = 1;
6af0bf9c 3628 }
7dca4ad0 3629 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3630 break;
3631 case OPC_BGEZ:
3632 case OPC_BGEZAL:
3c824109 3633 case OPC_BGEZALS:
6af0bf9c
FB
3634 case OPC_BGEZALL:
3635 case OPC_BGEZL:
3636 case OPC_BGTZ:
3637 case OPC_BGTZL:
3638 case OPC_BLEZ:
3639 case OPC_BLEZL:
3640 case OPC_BLTZ:
3641 case OPC_BLTZAL:
3c824109 3642 case OPC_BLTZALS:
6af0bf9c
FB
3643 case OPC_BLTZALL:
3644 case OPC_BLTZL:
3645 /* Compare to zero */
3646 if (rs != 0) {
6c5c1e20 3647 gen_load_gpr(t0, rs);
2fdbad25 3648 bcond_compute = 1;
6af0bf9c 3649 }
7dca4ad0 3650 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3651 break;
e45a93e2
JL
3652 case OPC_BPOSGE32:
3653#if defined(TARGET_MIPS64)
3654 case OPC_BPOSGE64:
3655 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3656#else
3657 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3658#endif
3659 bcond_compute = 1;
3660 btgt = ctx->pc + insn_bytes + offset;
3661 break;
6af0bf9c
FB
3662 case OPC_J:
3663 case OPC_JAL:
364d4831 3664 case OPC_JALX:
620e48f6
NF
3665 case OPC_JALS:
3666 case OPC_JALXS:
6af0bf9c 3667 /* Jump to immediate */
7dca4ad0 3668 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3669 break;
3670 case OPC_JR:
3671 case OPC_JALR:
364d4831 3672 case OPC_JALRC:
620e48f6 3673 case OPC_JALRS:
6af0bf9c 3674 /* Jump to register */
7a387fff
TS
3675 if (offset != 0 && offset != 16) {
3676 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3677 others are reserved. */
923617a3 3678 MIPS_INVAL("jump hint");
6af0bf9c 3679 generate_exception(ctx, EXCP_RI);
6c5c1e20 3680 goto out;
6af0bf9c 3681 }
d077b6f7 3682 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3683 break;
3684 default:
3685 MIPS_INVAL("branch/jump");
3686 generate_exception(ctx, EXCP_RI);
6c5c1e20 3687 goto out;
6af0bf9c 3688 }
2fdbad25 3689 if (bcond_compute == 0) {
6af0bf9c
FB
3690 /* No condition to be computed */
3691 switch (opc) {
3692 case OPC_BEQ: /* rx == rx */
3693 case OPC_BEQL: /* rx == rx likely */
3694 case OPC_BGEZ: /* 0 >= 0 */
3695 case OPC_BGEZL: /* 0 >= 0 likely */
3696 case OPC_BLEZ: /* 0 <= 0 */
3697 case OPC_BLEZL: /* 0 <= 0 likely */
3698 /* Always take */
4ad40f36 3699 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3700 MIPS_DEBUG("balways");
3701 break;
3c824109 3702 case OPC_BGEZALS:
6af0bf9c
FB
3703 case OPC_BGEZAL: /* 0 >= 0 */
3704 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3705 ctx->hflags |= (opc == OPC_BGEZALS
3706 ? MIPS_HFLAG_BDS16
3707 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3708 /* Always take and link */
3709 blink = 31;
4ad40f36 3710 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3711 MIPS_DEBUG("balways and link");
3712 break;
3713 case OPC_BNE: /* rx != rx */
3714 case OPC_BGTZ: /* 0 > 0 */
3715 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3716 /* Treat as NOP. */
6af0bf9c 3717 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3718 goto out;
3c824109 3719 case OPC_BLTZALS:
eeef26cd 3720 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3721 ctx->hflags |= (opc == OPC_BLTZALS
3722 ? MIPS_HFLAG_BDS16
3723 : MIPS_HFLAG_BDS32);
3724 /* Handle as an unconditional branch to get correct delay
3725 slot checking. */
3726 blink = 31;
3727 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3728 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3729 MIPS_DEBUG("bnever and link");
3c824109 3730 break;
eeef26cd 3731 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3732 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3733 /* Skip the instruction in the delay slot */
3734 MIPS_DEBUG("bnever, link and skip");
3735 ctx->pc += 4;
6c5c1e20 3736 goto out;
6af0bf9c
FB
3737 case OPC_BNEL: /* rx != rx likely */
3738 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3739 case OPC_BLTZL: /* 0 < 0 likely */
3740 /* Skip the instruction in the delay slot */
3741 MIPS_DEBUG("bnever and skip");
9898128f 3742 ctx->pc += 4;
6c5c1e20 3743 goto out;
6af0bf9c 3744 case OPC_J:
4ad40f36 3745 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3746 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3747 break;
620e48f6 3748 case OPC_JALXS:
364d4831
NF
3749 case OPC_JALX:
3750 ctx->hflags |= MIPS_HFLAG_BX;
3751 /* Fallthrough */
620e48f6 3752 case OPC_JALS:
6af0bf9c
FB
3753 case OPC_JAL:
3754 blink = 31;
4ad40f36 3755 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3756 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3757 ? MIPS_HFLAG_BDS16
3758 : MIPS_HFLAG_BDS32);
d077b6f7 3759 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3760 break;
3761 case OPC_JR:
4ad40f36 3762 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3763 if (insn_bytes == 4)
3764 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3765 MIPS_DEBUG("jr %s", regnames[rs]);
3766 break;
620e48f6 3767 case OPC_JALRS:
6af0bf9c 3768 case OPC_JALR:
364d4831 3769 case OPC_JALRC:
6af0bf9c 3770 blink = rt;
4ad40f36 3771 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3772 ctx->hflags |= (opc == OPC_JALRS
3773 ? MIPS_HFLAG_BDS16
3774 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3775 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3776 break;
3777 default:
3778 MIPS_INVAL("branch/jump");
3779 generate_exception(ctx, EXCP_RI);
6c5c1e20 3780 goto out;
6af0bf9c
FB
3781 }
3782 } else {
3783 switch (opc) {
3784 case OPC_BEQ:
e68dd28f 3785 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3786 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3787 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3788 goto not_likely;
3789 case OPC_BEQL:
e68dd28f 3790 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3791 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3792 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3793 goto likely;
3794 case OPC_BNE:
e68dd28f 3795 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3796 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3797 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3798 goto not_likely;
3799 case OPC_BNEL:
e68dd28f 3800 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3801 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3802 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3803 goto likely;
3804 case OPC_BGEZ:
e68dd28f 3805 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3806 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3807 goto not_likely;
3808 case OPC_BGEZL:
e68dd28f 3809 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3810 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3811 goto likely;
3c824109 3812 case OPC_BGEZALS:
6af0bf9c 3813 case OPC_BGEZAL:
3c824109
NF
3814 ctx->hflags |= (opc == OPC_BGEZALS
3815 ? MIPS_HFLAG_BDS16
3816 : MIPS_HFLAG_BDS32);
e68dd28f 3817 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3818 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3819 blink = 31;
3820 goto not_likely;
3821 case OPC_BGEZALL:
e68dd28f 3822 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3823 blink = 31;
d077b6f7 3824 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3825 goto likely;
3826 case OPC_BGTZ:
e68dd28f 3827 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3828 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3829 goto not_likely;
3830 case OPC_BGTZL:
e68dd28f 3831 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3832 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3833 goto likely;
3834 case OPC_BLEZ:
e68dd28f 3835 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3836 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3837 goto not_likely;
3838 case OPC_BLEZL:
e68dd28f 3839 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3840 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3841 goto likely;
3842 case OPC_BLTZ:
e68dd28f 3843 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3844 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3845 goto not_likely;
3846 case OPC_BLTZL:
e68dd28f 3847 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3848 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3849 goto likely;
e45a93e2
JL
3850 case OPC_BPOSGE32:
3851 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3852 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3853 goto not_likely;
3854#if defined(TARGET_MIPS64)
3855 case OPC_BPOSGE64:
3856 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3857 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3858 goto not_likely;
3859#endif
3c824109 3860 case OPC_BLTZALS:
6af0bf9c 3861 case OPC_BLTZAL:
3c824109
NF
3862 ctx->hflags |= (opc == OPC_BLTZALS
3863 ? MIPS_HFLAG_BDS16
3864 : MIPS_HFLAG_BDS32);
e68dd28f 3865 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3866 blink = 31;
d077b6f7 3867 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3868 not_likely:
4ad40f36 3869 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3870 break;
3871 case OPC_BLTZALL:
e68dd28f 3872 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3873 blink = 31;
d077b6f7 3874 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3875 likely:
4ad40f36 3876 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3877 break;
c53f4a62
TS
3878 default:
3879 MIPS_INVAL("conditional branch/jump");
3880 generate_exception(ctx, EXCP_RI);
6c5c1e20 3881 goto out;
6af0bf9c 3882 }
6af0bf9c 3883 }
923617a3 3884 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3885 blink, ctx->hflags, btgt);
9b9e4393 3886
d077b6f7 3887 ctx->btarget = btgt;
6af0bf9c 3888 if (blink > 0) {
364d4831
NF
3889 int post_delay = insn_bytes;
3890 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3891
3892 if (opc != OPC_JALRC)
3893 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3894
3895 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3896 }
6c5c1e20
TS
3897
3898 out:
364d4831
NF
3899 if (insn_bytes == 2)
3900 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3901 tcg_temp_free(t0);
3902 tcg_temp_free(t1);
6af0bf9c
FB
3903}
3904
7a387fff
TS
3905/* special3 bitfield operations */
3906static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3907 int rs, int lsb, int msb)
7a387fff 3908{
a7812ae4
PB
3909 TCGv t0 = tcg_temp_new();
3910 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
3911
3912 gen_load_gpr(t1, rs);
7a387fff
TS
3913 switch (opc) {
3914 case OPC_EXT:
3915 if (lsb + msb > 31)
3916 goto fail;
505ad7c2
AJ
3917 tcg_gen_shri_tl(t0, t1, lsb);
3918 if (msb != 31) {
3919 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3920 } else {
3921 tcg_gen_ext32s_tl(t0, t0);
3922 }
7a387fff 3923 break;
c6d6dd7c 3924#if defined(TARGET_MIPS64)
7a387fff 3925 case OPC_DEXTM:
505ad7c2
AJ
3926 tcg_gen_shri_tl(t0, t1, lsb);
3927 if (msb != 31) {
3928 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3929 }
7a387fff
TS
3930 break;
3931 case OPC_DEXTU:
505ad7c2
AJ
3932 tcg_gen_shri_tl(t0, t1, lsb + 32);
3933 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3934 break;
3935 case OPC_DEXT:
505ad7c2
AJ
3936 tcg_gen_shri_tl(t0, t1, lsb);
3937 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3938 break;
c6d6dd7c 3939#endif
7a387fff
TS
3940 case OPC_INS:
3941 if (lsb > msb)
3942 goto fail;
6c5c1e20 3943 gen_load_gpr(t0, rt);
e0d002f1 3944 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 3945 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3946 break;
c6d6dd7c 3947#if defined(TARGET_MIPS64)
7a387fff 3948 case OPC_DINSM:
6c5c1e20 3949 gen_load_gpr(t0, rt);
e0d002f1 3950 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
3951 break;
3952 case OPC_DINSU:
6c5c1e20 3953 gen_load_gpr(t0, rt);
e0d002f1 3954 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
3955 break;
3956 case OPC_DINS:
6c5c1e20 3957 gen_load_gpr(t0, rt);
e0d002f1 3958 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 3959 break;
c6d6dd7c 3960#endif
7a387fff
TS
3961 default:
3962fail:
3963 MIPS_INVAL("bitops");
3964 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
3965 tcg_temp_free(t0);
3966 tcg_temp_free(t1);
7a387fff
TS
3967 return;
3968 }
6c5c1e20
TS
3969 gen_store_gpr(t0, rt);
3970 tcg_temp_free(t0);
3971 tcg_temp_free(t1);
7a387fff
TS
3972}
3973
49bcf33c
AJ
3974static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3975{
3a55fa47 3976 TCGv t0;
49bcf33c 3977
3a55fa47
AJ
3978 if (rd == 0) {
3979 /* If no destination, treat it as a NOP. */
3980 MIPS_DEBUG("NOP");
3981 return;
3982 }
3983
3984 t0 = tcg_temp_new();
3985 gen_load_gpr(t0, rt);
49bcf33c
AJ
3986 switch (op2) {
3987 case OPC_WSBH:
3a55fa47
AJ
3988 {
3989 TCGv t1 = tcg_temp_new();
3990
3991 tcg_gen_shri_tl(t1, t0, 8);
3992 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3993 tcg_gen_shli_tl(t0, t0, 8);
3994 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3995 tcg_gen_or_tl(t0, t0, t1);
3996 tcg_temp_free(t1);
3997 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3998 }
49bcf33c
AJ
3999 break;
4000 case OPC_SEB:
3a55fa47 4001 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4002 break;
4003 case OPC_SEH:
3a55fa47 4004 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4005 break;
4006#if defined(TARGET_MIPS64)
4007 case OPC_DSBH:
3a55fa47
AJ
4008 {
4009 TCGv t1 = tcg_temp_new();
4010
4011 tcg_gen_shri_tl(t1, t0, 8);
4012 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4013 tcg_gen_shli_tl(t0, t0, 8);
4014 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4015 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4016 tcg_temp_free(t1);
4017 }
49bcf33c
AJ
4018 break;
4019 case OPC_DSHD:
3a55fa47
AJ
4020 {
4021 TCGv t1 = tcg_temp_new();
4022
4023 tcg_gen_shri_tl(t1, t0, 16);
4024 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4025 tcg_gen_shli_tl(t0, t0, 16);
4026 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4027 tcg_gen_or_tl(t0, t0, t1);
4028 tcg_gen_shri_tl(t1, t0, 32);
4029 tcg_gen_shli_tl(t0, t0, 32);
4030 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4031 tcg_temp_free(t1);
4032 }
49bcf33c
AJ
4033 break;
4034#endif
4035 default:
4036 MIPS_INVAL("bsfhl");
4037 generate_exception(ctx, EXCP_RI);
4038 tcg_temp_free(t0);
49bcf33c
AJ
4039 return;
4040 }
49bcf33c 4041 tcg_temp_free(t0);
49bcf33c
AJ
4042}
4043
f1aa6320 4044#ifndef CONFIG_USER_ONLY
0eaef5aa 4045/* CP0 (MMU and control) */
d9bea114 4046static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4047{
d9bea114 4048 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4049
d9bea114
AJ
4050 tcg_gen_ld_i32(t0, cpu_env, off);
4051 tcg_gen_ext_i32_tl(arg, t0);
4052 tcg_temp_free_i32(t0);
4f57689a
TS
4053}
4054
d9bea114 4055static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4056{
d9bea114
AJ
4057 tcg_gen_ld_tl(arg, cpu_env, off);
4058 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4059}
4060
d9bea114 4061static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4062{
d9bea114 4063 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4064
d9bea114
AJ
4065 tcg_gen_trunc_tl_i32(t0, arg);
4066 tcg_gen_st_i32(t0, cpu_env, off);
4067 tcg_temp_free_i32(t0);
f1aa6320
TS
4068}
4069
d9bea114 4070static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4071{
d9bea114
AJ
4072 tcg_gen_ext32s_tl(arg, arg);
4073 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4074}
4075
d75c135e 4076static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4077{
7a387fff 4078 const char *rn = "invalid";
873eb012 4079
e189e748 4080 if (sel != 0)
d75c135e 4081 check_insn(ctx, ISA_MIPS32);
e189e748 4082
873eb012
TS
4083 switch (reg) {
4084 case 0:
7a387fff
TS
4085 switch (sel) {
4086 case 0:
7db13fae 4087 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4088 rn = "Index";
4089 break;
4090 case 1:
d75c135e 4091 check_insn(ctx, ASE_MT);
895c2d04 4092 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4093 rn = "MVPControl";
ead9360e 4094 break;
7a387fff 4095 case 2:
d75c135e 4096 check_insn(ctx, ASE_MT);
895c2d04 4097 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4098 rn = "MVPConf0";
ead9360e 4099 break;
7a387fff 4100 case 3:
d75c135e 4101 check_insn(ctx, ASE_MT);
895c2d04 4102 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4103 rn = "MVPConf1";
ead9360e 4104 break;
7a387fff
TS
4105 default:
4106 goto die;
4107 }
873eb012
TS
4108 break;
4109 case 1:
7a387fff
TS
4110 switch (sel) {
4111 case 0:
895c2d04 4112 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4113 rn = "Random";
2423f660 4114 break;
7a387fff 4115 case 1:
d75c135e 4116 check_insn(ctx, ASE_MT);
7db13fae 4117 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4118 rn = "VPEControl";
ead9360e 4119 break;
7a387fff 4120 case 2:
d75c135e 4121 check_insn(ctx, ASE_MT);
7db13fae 4122 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4123 rn = "VPEConf0";
ead9360e 4124 break;
7a387fff 4125 case 3:
d75c135e 4126 check_insn(ctx, ASE_MT);
7db13fae 4127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4128 rn = "VPEConf1";
ead9360e 4129 break;
7a387fff 4130 case 4:
d75c135e 4131 check_insn(ctx, ASE_MT);
7db13fae 4132 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4133 rn = "YQMask";
ead9360e 4134 break;
7a387fff 4135 case 5:
d75c135e 4136 check_insn(ctx, ASE_MT);
7db13fae 4137 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4138 rn = "VPESchedule";
ead9360e 4139 break;
7a387fff 4140 case 6:
d75c135e 4141 check_insn(ctx, ASE_MT);
7db13fae 4142 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4143 rn = "VPEScheFBack";
ead9360e 4144 break;
7a387fff 4145 case 7:
d75c135e 4146 check_insn(ctx, ASE_MT);
7db13fae 4147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4148 rn = "VPEOpt";
ead9360e 4149 break;
7a387fff
TS
4150 default:
4151 goto die;
4152 }
873eb012
TS
4153 break;
4154 case 2:
7a387fff
TS
4155 switch (sel) {
4156 case 0:
7db13fae 4157 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4158 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4159 rn = "EntryLo0";
4160 break;
7a387fff 4161 case 1:
d75c135e 4162 check_insn(ctx, ASE_MT);
895c2d04 4163 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4164 rn = "TCStatus";
ead9360e 4165 break;
7a387fff 4166 case 2:
d75c135e 4167 check_insn(ctx, ASE_MT);
895c2d04 4168 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4169 rn = "TCBind";
ead9360e 4170 break;
7a387fff 4171 case 3:
d75c135e 4172 check_insn(ctx, ASE_MT);
895c2d04 4173 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4174 rn = "TCRestart";
ead9360e 4175 break;
7a387fff 4176 case 4:
d75c135e 4177 check_insn(ctx, ASE_MT);
895c2d04 4178 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4179 rn = "TCHalt";
ead9360e 4180 break;
7a387fff 4181 case 5:
d75c135e 4182 check_insn(ctx, ASE_MT);
895c2d04 4183 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4184 rn = "TCContext";
ead9360e 4185 break;
7a387fff 4186 case 6:
d75c135e 4187 check_insn(ctx, ASE_MT);
895c2d04 4188 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4189 rn = "TCSchedule";
ead9360e 4190 break;
7a387fff 4191 case 7:
d75c135e 4192 check_insn(ctx, ASE_MT);
895c2d04 4193 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4194 rn = "TCScheFBack";
ead9360e 4195 break;
7a387fff
TS
4196 default:
4197 goto die;
4198 }
873eb012
TS
4199 break;
4200 case 3:
7a387fff
TS
4201 switch (sel) {
4202 case 0:
7db13fae 4203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4204 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4205 rn = "EntryLo1";
4206 break;
7a387fff
TS
4207 default:
4208 goto die;
1579a72e 4209 }
873eb012
TS
4210 break;
4211 case 4:
7a387fff
TS
4212 switch (sel) {
4213 case 0:
7db13fae 4214 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4215 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4216 rn = "Context";
4217 break;
7a387fff 4218 case 1:
d9bea114 4219// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 4220 rn = "ContextConfig";
d279279e 4221 goto die;
2423f660 4222// break;
d279279e
PJ
4223 case 2:
4224 if (ctx->ulri) {
4225 tcg_gen_ld32s_tl(arg, cpu_env,
4226 offsetof(CPUMIPSState,
4227 active_tc.CP0_UserLocal));
4228 rn = "UserLocal";
4229 } else {
4230 tcg_gen_movi_tl(arg, 0);
4231 }
4232 break;
7a387fff
TS
4233 default:
4234 goto die;
1579a72e 4235 }
873eb012
TS
4236 break;
4237 case 5:
7a387fff
TS
4238 switch (sel) {
4239 case 0:
7db13fae 4240 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4241 rn = "PageMask";
4242 break;
7a387fff 4243 case 1:
d75c135e 4244 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4245 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4246 rn = "PageGrain";
4247 break;
7a387fff
TS
4248 default:
4249 goto die;
1579a72e 4250 }
873eb012
TS
4251 break;
4252 case 6:
7a387fff
TS
4253 switch (sel) {
4254 case 0:
7db13fae 4255 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4256 rn = "Wired";
4257 break;
7a387fff 4258 case 1:
d75c135e 4259 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4261 rn = "SRSConf0";
ead9360e 4262 break;
7a387fff 4263 case 2:
d75c135e 4264 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4265 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4266 rn = "SRSConf1";
ead9360e 4267 break;
7a387fff 4268 case 3:
d75c135e 4269 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4271 rn = "SRSConf2";
ead9360e 4272 break;
7a387fff 4273 case 4:
d75c135e 4274 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4275 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4276 rn = "SRSConf3";
ead9360e 4277 break;
7a387fff 4278 case 5:
d75c135e 4279 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4280 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4281 rn = "SRSConf4";
ead9360e 4282 break;
7a387fff
TS
4283 default:
4284 goto die;
1579a72e 4285 }
873eb012 4286 break;
8c0fdd85 4287 case 7:
7a387fff
TS
4288 switch (sel) {
4289 case 0:
d75c135e 4290 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4292 rn = "HWREna";
4293 break;
7a387fff
TS
4294 default:
4295 goto die;
1579a72e 4296 }
8c0fdd85 4297 break;
873eb012 4298 case 8:
7a387fff
TS
4299 switch (sel) {
4300 case 0:
7db13fae 4301 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4302 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4303 rn = "BadVAddr";
2423f660 4304 break;
7a387fff
TS
4305 default:
4306 goto die;
4307 }
873eb012
TS
4308 break;
4309 case 9:
7a387fff
TS
4310 switch (sel) {
4311 case 0:
2e70f6ef
PB
4312 /* Mark as an IO operation because we read the time. */
4313 if (use_icount)
4314 gen_io_start();
895c2d04 4315 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4316 if (use_icount) {
4317 gen_io_end();
2e70f6ef 4318 }
55807224
EI
4319 /* Break the TB to be able to take timer interrupts immediately
4320 after reading count. */
4321 ctx->bstate = BS_STOP;
2423f660
TS
4322 rn = "Count";
4323 break;
4324 /* 6,7 are implementation dependent */
7a387fff
TS
4325 default:
4326 goto die;
2423f660 4327 }
873eb012
TS
4328 break;
4329 case 10:
7a387fff
TS
4330 switch (sel) {
4331 case 0:
7db13fae 4332 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4333 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4334 rn = "EntryHi";
4335 break;
7a387fff
TS
4336 default:
4337 goto die;
1579a72e 4338 }
873eb012
TS
4339 break;
4340 case 11:
7a387fff
TS
4341 switch (sel) {
4342 case 0:
7db13fae 4343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4344 rn = "Compare";
4345 break;
4346 /* 6,7 are implementation dependent */
7a387fff
TS
4347 default:
4348 goto die;
2423f660 4349 }
873eb012
TS
4350 break;
4351 case 12:
7a387fff
TS
4352 switch (sel) {
4353 case 0:
7db13fae 4354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4355 rn = "Status";
4356 break;
7a387fff 4357 case 1:
d75c135e 4358 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4360 rn = "IntCtl";
4361 break;
7a387fff 4362 case 2:
d75c135e 4363 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4365 rn = "SRSCtl";
4366 break;
7a387fff 4367 case 3:
d75c135e 4368 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4370 rn = "SRSMap";
fd88b6ab 4371 break;
7a387fff
TS
4372 default:
4373 goto die;
4374 }
873eb012
TS
4375 break;
4376 case 13:
7a387fff
TS
4377 switch (sel) {
4378 case 0:
7db13fae 4379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4380 rn = "Cause";
4381 break;
7a387fff
TS
4382 default:
4383 goto die;
4384 }
873eb012
TS
4385 break;
4386 case 14:
7a387fff
TS
4387 switch (sel) {
4388 case 0:
7db13fae 4389 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4390 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4391 rn = "EPC";
4392 break;
7a387fff
TS
4393 default:
4394 goto die;
1579a72e 4395 }
873eb012
TS
4396 break;
4397 case 15:
7a387fff
TS
4398 switch (sel) {
4399 case 0:
7db13fae 4400 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4401 rn = "PRid";
4402 break;
7a387fff 4403 case 1:
d75c135e 4404 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4406 rn = "EBase";
4407 break;
7a387fff
TS
4408 default:
4409 goto die;
4410 }
873eb012
TS
4411 break;
4412 case 16:
4413 switch (sel) {
4414 case 0:
7db13fae 4415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4416 rn = "Config";
4417 break;
4418 case 1:
7db13fae 4419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4420 rn = "Config1";
4421 break;
7a387fff 4422 case 2:
7db13fae 4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4424 rn = "Config2";
4425 break;
4426 case 3:
7db13fae 4427 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4428 rn = "Config3";
4429 break;
b4160af1
PJ
4430 case 4:
4431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4432 rn = "Config4";
4433 break;
b4dd99a3
PJ
4434 case 5:
4435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4436 rn = "Config5";
4437 break;
e397ee33
TS
4438 /* 6,7 are implementation dependent */
4439 case 6:
7db13fae 4440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4441 rn = "Config6";
4442 break;
4443 case 7:
7db13fae 4444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4445 rn = "Config7";
4446 break;
873eb012 4447 default:
873eb012
TS
4448 goto die;
4449 }
4450 break;
4451 case 17:
7a387fff
TS
4452 switch (sel) {
4453 case 0:
895c2d04 4454 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4455 rn = "LLAddr";
4456 break;
7a387fff
TS
4457 default:
4458 goto die;
4459 }
873eb012
TS
4460 break;
4461 case 18:
7a387fff 4462 switch (sel) {
fd88b6ab 4463 case 0 ... 7:
895c2d04 4464 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4465 rn = "WatchLo";
4466 break;
7a387fff
TS
4467 default:
4468 goto die;
4469 }
873eb012
TS
4470 break;
4471 case 19:
7a387fff 4472 switch (sel) {
fd88b6ab 4473 case 0 ...7:
895c2d04 4474 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4475 rn = "WatchHi";
4476 break;
7a387fff
TS
4477 default:
4478 goto die;
4479 }
873eb012 4480 break;
8c0fdd85 4481 case 20:
7a387fff
TS
4482 switch (sel) {
4483 case 0:
d26bc211 4484#if defined(TARGET_MIPS64)
d75c135e 4485 check_insn(ctx, ISA_MIPS3);
7db13fae 4486 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4487 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4488 rn = "XContext";
4489 break;
703eaf37 4490#endif
7a387fff
TS
4491 default:
4492 goto die;
4493 }
8c0fdd85
TS
4494 break;
4495 case 21:
7a387fff
TS
4496 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4497 switch (sel) {
4498 case 0:
7db13fae 4499 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4500 rn = "Framemask";
4501 break;
7a387fff
TS
4502 default:
4503 goto die;
4504 }
8c0fdd85
TS
4505 break;
4506 case 22:
d9bea114 4507 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4508 rn = "'Diagnostic"; /* implementation dependent */
4509 break;
873eb012 4510 case 23:
7a387fff
TS
4511 switch (sel) {
4512 case 0:
895c2d04 4513 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4514 rn = "Debug";
4515 break;
7a387fff 4516 case 1:
d9bea114 4517// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4518 rn = "TraceControl";
4519// break;
7a387fff 4520 case 2:
d9bea114 4521// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4522 rn = "TraceControl2";
4523// break;
7a387fff 4524 case 3:
d9bea114 4525// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4526 rn = "UserTraceData";
4527// break;
7a387fff 4528 case 4:
d9bea114 4529// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4530 rn = "TraceBPC";
4531// break;
7a387fff
TS
4532 default:
4533 goto die;
4534 }
873eb012
TS
4535 break;
4536 case 24:
7a387fff
TS
4537 switch (sel) {
4538 case 0:
f0b3f3ae 4539 /* EJTAG support */
7db13fae 4540 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4541 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4542 rn = "DEPC";
4543 break;
7a387fff
TS
4544 default:
4545 goto die;
4546 }
873eb012 4547 break;
8c0fdd85 4548 case 25:
7a387fff
TS
4549 switch (sel) {
4550 case 0:
7db13fae 4551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4552 rn = "Performance0";
7a387fff
TS
4553 break;
4554 case 1:
d9bea114 4555// gen_helper_mfc0_performance1(arg);
2423f660
TS
4556 rn = "Performance1";
4557// break;
7a387fff 4558 case 2:
d9bea114 4559// gen_helper_mfc0_performance2(arg);
2423f660
TS
4560 rn = "Performance2";
4561// break;
7a387fff 4562 case 3:
d9bea114 4563// gen_helper_mfc0_performance3(arg);
2423f660
TS
4564 rn = "Performance3";
4565// break;
7a387fff 4566 case 4:
d9bea114 4567// gen_helper_mfc0_performance4(arg);
2423f660
TS
4568 rn = "Performance4";
4569// break;
7a387fff 4570 case 5:
d9bea114 4571// gen_helper_mfc0_performance5(arg);
2423f660
TS
4572 rn = "Performance5";
4573// break;
7a387fff 4574 case 6:
d9bea114 4575// gen_helper_mfc0_performance6(arg);
2423f660
TS
4576 rn = "Performance6";
4577// break;
7a387fff 4578 case 7:
d9bea114 4579// gen_helper_mfc0_performance7(arg);
2423f660
TS
4580 rn = "Performance7";
4581// break;
7a387fff
TS
4582 default:
4583 goto die;
4584 }
8c0fdd85
TS
4585 break;
4586 case 26:
d9bea114 4587 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4588 rn = "ECC";
4589 break;
8c0fdd85 4590 case 27:
7a387fff 4591 switch (sel) {
7a387fff 4592 case 0 ... 3:
d9bea114 4593 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4594 rn = "CacheErr";
4595 break;
7a387fff
TS
4596 default:
4597 goto die;
4598 }
8c0fdd85 4599 break;
873eb012
TS
4600 case 28:
4601 switch (sel) {
4602 case 0:
7a387fff
TS
4603 case 2:
4604 case 4:
4605 case 6:
7db13fae 4606 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4607 rn = "TagLo";
4608 break;
4609 case 1:
7a387fff
TS
4610 case 3:
4611 case 5:
4612 case 7:
7db13fae 4613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4614 rn = "DataLo";
4615 break;
4616 default:
873eb012
TS
4617 goto die;
4618 }
4619 break;
8c0fdd85 4620 case 29:
7a387fff
TS
4621 switch (sel) {
4622 case 0:
4623 case 2:
4624 case 4:
4625 case 6:
7db13fae 4626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4627 rn = "TagHi";
4628 break;
4629 case 1:
4630 case 3:
4631 case 5:
4632 case 7:
7db13fae 4633 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4634 rn = "DataHi";
4635 break;
4636 default:
4637 goto die;
4638 }
8c0fdd85 4639 break;
873eb012 4640 case 30:
7a387fff
TS
4641 switch (sel) {
4642 case 0:
7db13fae 4643 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4644 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4645 rn = "ErrorEPC";
4646 break;
7a387fff
TS
4647 default:
4648 goto die;
4649 }
873eb012
TS
4650 break;
4651 case 31:
7a387fff
TS
4652 switch (sel) {
4653 case 0:
f0b3f3ae 4654 /* EJTAG support */
7db13fae 4655 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4656 rn = "DESAVE";
4657 break;
7a387fff
TS
4658 default:
4659 goto die;
4660 }
873eb012
TS
4661 break;
4662 default:
873eb012
TS
4663 goto die;
4664 }
2abf314d 4665 (void)rn; /* avoid a compiler warning */
d12d51d5 4666 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4667 return;
4668
4669die:
d12d51d5 4670 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4671 generate_exception(ctx, EXCP_RI);
4672}
4673
d75c135e 4674static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4675{
7a387fff
TS
4676 const char *rn = "invalid";
4677
e189e748 4678 if (sel != 0)
d75c135e 4679 check_insn(ctx, ISA_MIPS32);
e189e748 4680
2e70f6ef
PB
4681 if (use_icount)
4682 gen_io_start();
4683
8c0fdd85
TS
4684 switch (reg) {
4685 case 0:
7a387fff
TS
4686 switch (sel) {
4687 case 0:
895c2d04 4688 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4689 rn = "Index";
4690 break;
4691 case 1:
d75c135e 4692 check_insn(ctx, ASE_MT);
895c2d04 4693 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4694 rn = "MVPControl";
ead9360e 4695 break;
7a387fff 4696 case 2:
d75c135e 4697 check_insn(ctx, ASE_MT);
ead9360e 4698 /* ignored */
7a387fff 4699 rn = "MVPConf0";
ead9360e 4700 break;
7a387fff 4701 case 3:
d75c135e 4702 check_insn(ctx, ASE_MT);
ead9360e 4703 /* ignored */
7a387fff 4704 rn = "MVPConf1";
ead9360e 4705 break;
7a387fff
TS
4706 default:
4707 goto die;
4708 }
8c0fdd85
TS
4709 break;
4710 case 1:
7a387fff
TS
4711 switch (sel) {
4712 case 0:
2423f660 4713 /* ignored */
7a387fff 4714 rn = "Random";
2423f660 4715 break;
7a387fff 4716 case 1:
d75c135e 4717 check_insn(ctx, ASE_MT);
895c2d04 4718 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4719 rn = "VPEControl";
ead9360e 4720 break;
7a387fff 4721 case 2:
d75c135e 4722 check_insn(ctx, ASE_MT);
895c2d04 4723 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4724 rn = "VPEConf0";
ead9360e 4725 break;
7a387fff 4726 case 3:
d75c135e 4727 check_insn(ctx, ASE_MT);
895c2d04 4728 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4729 rn = "VPEConf1";
ead9360e 4730 break;
7a387fff 4731 case 4:
d75c135e 4732 check_insn(ctx, ASE_MT);
895c2d04 4733 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4734 rn = "YQMask";
ead9360e 4735 break;
7a387fff 4736 case 5:
d75c135e 4737 check_insn(ctx, ASE_MT);
7db13fae 4738 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4739 rn = "VPESchedule";
ead9360e 4740 break;
7a387fff 4741 case 6:
d75c135e 4742 check_insn(ctx, ASE_MT);
7db13fae 4743 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4744 rn = "VPEScheFBack";
ead9360e 4745 break;
7a387fff 4746 case 7:
d75c135e 4747 check_insn(ctx, ASE_MT);
895c2d04 4748 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4749 rn = "VPEOpt";
ead9360e 4750 break;
7a387fff
TS
4751 default:
4752 goto die;
4753 }
8c0fdd85
TS
4754 break;
4755 case 2:
7a387fff
TS
4756 switch (sel) {
4757 case 0:
895c2d04 4758 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4759 rn = "EntryLo0";
4760 break;
7a387fff 4761 case 1:
d75c135e 4762 check_insn(ctx, ASE_MT);
895c2d04 4763 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4764 rn = "TCStatus";
ead9360e 4765 break;
7a387fff 4766 case 2:
d75c135e 4767 check_insn(ctx, ASE_MT);
895c2d04 4768 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4769 rn = "TCBind";
ead9360e 4770 break;
7a387fff 4771 case 3:
d75c135e 4772 check_insn(ctx, ASE_MT);
895c2d04 4773 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4774 rn = "TCRestart";
ead9360e 4775 break;
7a387fff 4776 case 4:
d75c135e 4777 check_insn(ctx, ASE_MT);
895c2d04 4778 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4779 rn = "TCHalt";
ead9360e 4780 break;
7a387fff 4781 case 5:
d75c135e 4782 check_insn(ctx, ASE_MT);
895c2d04 4783 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4784 rn = "TCContext";
ead9360e 4785 break;
7a387fff 4786 case 6:
d75c135e 4787 check_insn(ctx, ASE_MT);
895c2d04 4788 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4789 rn = "TCSchedule";
ead9360e 4790 break;
7a387fff 4791 case 7:
d75c135e 4792 check_insn(ctx, ASE_MT);
895c2d04 4793 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4794 rn = "TCScheFBack";
ead9360e 4795 break;
7a387fff
TS
4796 default:
4797 goto die;
4798 }
8c0fdd85
TS
4799 break;
4800 case 3:
7a387fff
TS
4801 switch (sel) {
4802 case 0:
895c2d04 4803 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4804 rn = "EntryLo1";
4805 break;
7a387fff
TS
4806 default:
4807 goto die;
876d4b07 4808 }
8c0fdd85
TS
4809 break;
4810 case 4:
7a387fff
TS
4811 switch (sel) {
4812 case 0:
895c2d04 4813 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4814 rn = "Context";
4815 break;
7a387fff 4816 case 1:
895c2d04 4817// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 4818 rn = "ContextConfig";
d279279e 4819 goto die;
2423f660 4820// break;
d279279e
PJ
4821 case 2:
4822 if (ctx->ulri) {
4823 tcg_gen_st_tl(arg, cpu_env,
4824 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
4825 rn = "UserLocal";
4826 }
4827 break;
7a387fff
TS
4828 default:
4829 goto die;
876d4b07 4830 }
8c0fdd85
TS
4831 break;
4832 case 5:
7a387fff
TS
4833 switch (sel) {
4834 case 0:
895c2d04 4835 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4836 rn = "PageMask";
4837 break;
7a387fff 4838 case 1:
d75c135e 4839 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4840 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4841 rn = "PageGrain";
4842 break;
7a387fff
TS
4843 default:
4844 goto die;
876d4b07 4845 }
8c0fdd85
TS
4846 break;
4847 case 6:
7a387fff
TS
4848 switch (sel) {
4849 case 0:
895c2d04 4850 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4851 rn = "Wired";
4852 break;
7a387fff 4853 case 1:
d75c135e 4854 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4855 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4856 rn = "SRSConf0";
ead9360e 4857 break;
7a387fff 4858 case 2:
d75c135e 4859 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4860 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4861 rn = "SRSConf1";
ead9360e 4862 break;
7a387fff 4863 case 3:
d75c135e 4864 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4865 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4866 rn = "SRSConf2";
ead9360e 4867 break;
7a387fff 4868 case 4:
d75c135e 4869 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4870 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4871 rn = "SRSConf3";
ead9360e 4872 break;
7a387fff 4873 case 5:
d75c135e 4874 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4875 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4876 rn = "SRSConf4";
ead9360e 4877 break;
7a387fff
TS
4878 default:
4879 goto die;
876d4b07 4880 }
8c0fdd85
TS
4881 break;
4882 case 7:
7a387fff
TS
4883 switch (sel) {
4884 case 0:
d75c135e 4885 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4886 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 4887 ctx->bstate = BS_STOP;
2423f660
TS
4888 rn = "HWREna";
4889 break;
7a387fff
TS
4890 default:
4891 goto die;
876d4b07 4892 }
8c0fdd85
TS
4893 break;
4894 case 8:
7a387fff 4895 /* ignored */
f0b3f3ae 4896 rn = "BadVAddr";
8c0fdd85
TS
4897 break;
4898 case 9:
7a387fff
TS
4899 switch (sel) {
4900 case 0:
895c2d04 4901 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4902 rn = "Count";
4903 break;
876d4b07 4904 /* 6,7 are implementation dependent */
7a387fff
TS
4905 default:
4906 goto die;
876d4b07 4907 }
8c0fdd85
TS
4908 break;
4909 case 10:
7a387fff
TS
4910 switch (sel) {
4911 case 0:
895c2d04 4912 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4913 rn = "EntryHi";
4914 break;
7a387fff
TS
4915 default:
4916 goto die;
876d4b07 4917 }
8c0fdd85
TS
4918 break;
4919 case 11:
7a387fff
TS
4920 switch (sel) {
4921 case 0:
895c2d04 4922 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4923 rn = "Compare";
4924 break;
4925 /* 6,7 are implementation dependent */
7a387fff
TS
4926 default:
4927 goto die;
876d4b07 4928 }
8c0fdd85
TS
4929 break;
4930 case 12:
7a387fff
TS
4931 switch (sel) {
4932 case 0:
867abc7e 4933 save_cpu_state(ctx, 1);
895c2d04 4934 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4935 /* BS_STOP isn't good enough here, hflags may have changed. */
4936 gen_save_pc(ctx->pc + 4);
4937 ctx->bstate = BS_EXCP;
2423f660
TS
4938 rn = "Status";
4939 break;
7a387fff 4940 case 1:
d75c135e 4941 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4942 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4943 /* Stop translation as we may have switched the execution mode */
4944 ctx->bstate = BS_STOP;
2423f660
TS
4945 rn = "IntCtl";
4946 break;
7a387fff 4947 case 2:
d75c135e 4948 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4949 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4950 /* Stop translation as we may have switched the execution mode */
4951 ctx->bstate = BS_STOP;
2423f660
TS
4952 rn = "SRSCtl";
4953 break;
7a387fff 4954 case 3:
d75c135e 4955 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4956 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4957 /* Stop translation as we may have switched the execution mode */
4958 ctx->bstate = BS_STOP;
2423f660 4959 rn = "SRSMap";
fd88b6ab 4960 break;
7a387fff
TS
4961 default:
4962 goto die;
876d4b07 4963 }
8c0fdd85
TS
4964 break;
4965 case 13:
7a387fff
TS
4966 switch (sel) {
4967 case 0:
867abc7e 4968 save_cpu_state(ctx, 1);
895c2d04 4969 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4970 rn = "Cause";
4971 break;
7a387fff
TS
4972 default:
4973 goto die;
876d4b07 4974 }
8c0fdd85
TS
4975 break;
4976 case 14:
7a387fff
TS
4977 switch (sel) {
4978 case 0:
7db13fae 4979 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4980 rn = "EPC";
4981 break;
7a387fff
TS
4982 default:
4983 goto die;
876d4b07 4984 }
8c0fdd85
TS
4985 break;
4986 case 15:
7a387fff
TS
4987 switch (sel) {
4988 case 0:
2423f660
TS
4989 /* ignored */
4990 rn = "PRid";
4991 break;
7a387fff 4992 case 1:
d75c135e 4993 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4994 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
4995 rn = "EBase";
4996 break;
7a387fff
TS
4997 default:
4998 goto die;
1579a72e 4999 }
8c0fdd85
TS
5000 break;
5001 case 16:
5002 switch (sel) {
5003 case 0:
895c2d04 5004 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5005 rn = "Config";
2423f660
TS
5006 /* Stop translation as we may have switched the execution mode */
5007 ctx->bstate = BS_STOP;
7a387fff
TS
5008 break;
5009 case 1:
e397ee33 5010 /* ignored, read only */
7a387fff
TS
5011 rn = "Config1";
5012 break;
5013 case 2:
895c2d04 5014 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5015 rn = "Config2";
2423f660
TS
5016 /* Stop translation as we may have switched the execution mode */
5017 ctx->bstate = BS_STOP;
8c0fdd85 5018 break;
7a387fff 5019 case 3:
e397ee33 5020 /* ignored, read only */
7a387fff
TS
5021 rn = "Config3";
5022 break;
b4160af1
PJ
5023 case 4:
5024 gen_helper_mtc0_config4(cpu_env, arg);
5025 rn = "Config4";
5026 ctx->bstate = BS_STOP;
5027 break;
b4dd99a3
PJ
5028 case 5:
5029 gen_helper_mtc0_config5(cpu_env, arg);
5030 rn = "Config5";
5031 /* Stop translation as we may have switched the execution mode */
5032 ctx->bstate = BS_STOP;
5033 break;
e397ee33
TS
5034 /* 6,7 are implementation dependent */
5035 case 6:
5036 /* ignored */
5037 rn = "Config6";
5038 break;
5039 case 7:
5040 /* ignored */
5041 rn = "Config7";
5042 break;
8c0fdd85
TS
5043 default:
5044 rn = "Invalid config selector";
5045 goto die;
5046 }
5047 break;
5048 case 17:
7a387fff
TS
5049 switch (sel) {
5050 case 0:
895c2d04 5051 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5052 rn = "LLAddr";
5053 break;
7a387fff
TS
5054 default:
5055 goto die;
5056 }
8c0fdd85
TS
5057 break;
5058 case 18:
7a387fff 5059 switch (sel) {
fd88b6ab 5060 case 0 ... 7:
895c2d04 5061 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5062 rn = "WatchLo";
5063 break;
7a387fff
TS
5064 default:
5065 goto die;
5066 }
8c0fdd85
TS
5067 break;
5068 case 19:
7a387fff 5069 switch (sel) {
fd88b6ab 5070 case 0 ... 7:
895c2d04 5071 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5072 rn = "WatchHi";
5073 break;
7a387fff
TS
5074 default:
5075 goto die;
5076 }
8c0fdd85
TS
5077 break;
5078 case 20:
7a387fff
TS
5079 switch (sel) {
5080 case 0:
d26bc211 5081#if defined(TARGET_MIPS64)
d75c135e 5082 check_insn(ctx, ISA_MIPS3);
895c2d04 5083 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5084 rn = "XContext";
5085 break;
703eaf37 5086#endif
7a387fff
TS
5087 default:
5088 goto die;
5089 }
8c0fdd85
TS
5090 break;
5091 case 21:
7a387fff
TS
5092 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5093 switch (sel) {
5094 case 0:
895c2d04 5095 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5096 rn = "Framemask";
5097 break;
7a387fff
TS
5098 default:
5099 goto die;
5100 }
5101 break;
8c0fdd85 5102 case 22:
7a387fff
TS
5103 /* ignored */
5104 rn = "Diagnostic"; /* implementation dependent */
2423f660 5105 break;
8c0fdd85 5106 case 23:
7a387fff
TS
5107 switch (sel) {
5108 case 0:
895c2d04 5109 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5110 /* BS_STOP isn't good enough here, hflags may have changed. */
5111 gen_save_pc(ctx->pc + 4);
5112 ctx->bstate = BS_EXCP;
2423f660
TS
5113 rn = "Debug";
5114 break;
7a387fff 5115 case 1:
895c2d04 5116// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5117 rn = "TraceControl";
8487327a
TS
5118 /* Stop translation as we may have switched the execution mode */
5119 ctx->bstate = BS_STOP;
2423f660 5120// break;
7a387fff 5121 case 2:
895c2d04 5122// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5123 rn = "TraceControl2";
8487327a
TS
5124 /* Stop translation as we may have switched the execution mode */
5125 ctx->bstate = BS_STOP;
2423f660 5126// break;
7a387fff 5127 case 3:
8487327a
TS
5128 /* Stop translation as we may have switched the execution mode */
5129 ctx->bstate = BS_STOP;
895c2d04 5130// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5131 rn = "UserTraceData";
8487327a
TS
5132 /* Stop translation as we may have switched the execution mode */
5133 ctx->bstate = BS_STOP;
2423f660 5134// break;
7a387fff 5135 case 4:
895c2d04 5136// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5137 /* Stop translation as we may have switched the execution mode */
5138 ctx->bstate = BS_STOP;
2423f660
TS
5139 rn = "TraceBPC";
5140// break;
7a387fff
TS
5141 default:
5142 goto die;
5143 }
8c0fdd85
TS
5144 break;
5145 case 24:
7a387fff
TS
5146 switch (sel) {
5147 case 0:
f1aa6320 5148 /* EJTAG support */
7db13fae 5149 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5150 rn = "DEPC";
5151 break;
7a387fff
TS
5152 default:
5153 goto die;
5154 }
8c0fdd85
TS
5155 break;
5156 case 25:
7a387fff
TS
5157 switch (sel) {
5158 case 0:
895c2d04 5159 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5160 rn = "Performance0";
5161 break;
7a387fff 5162 case 1:
d9bea114 5163// gen_helper_mtc0_performance1(arg);
2423f660
TS
5164 rn = "Performance1";
5165// break;
7a387fff 5166 case 2:
d9bea114 5167// gen_helper_mtc0_performance2(arg);
2423f660
TS
5168 rn = "Performance2";
5169// break;
7a387fff 5170 case 3:
d9bea114 5171// gen_helper_mtc0_performance3(arg);
2423f660
TS
5172 rn = "Performance3";
5173// break;
7a387fff 5174 case 4:
d9bea114 5175// gen_helper_mtc0_performance4(arg);
2423f660
TS
5176 rn = "Performance4";
5177// break;
7a387fff 5178 case 5:
d9bea114 5179// gen_helper_mtc0_performance5(arg);
2423f660
TS
5180 rn = "Performance5";
5181// break;
7a387fff 5182 case 6:
d9bea114 5183// gen_helper_mtc0_performance6(arg);
2423f660
TS
5184 rn = "Performance6";
5185// break;
7a387fff 5186 case 7:
d9bea114 5187// gen_helper_mtc0_performance7(arg);
2423f660
TS
5188 rn = "Performance7";
5189// break;
7a387fff
TS
5190 default:
5191 goto die;
5192 }
8c0fdd85
TS
5193 break;
5194 case 26:
2423f660 5195 /* ignored */
8c0fdd85 5196 rn = "ECC";
2423f660 5197 break;
8c0fdd85 5198 case 27:
7a387fff
TS
5199 switch (sel) {
5200 case 0 ... 3:
2423f660
TS
5201 /* ignored */
5202 rn = "CacheErr";
5203 break;
7a387fff
TS
5204 default:
5205 goto die;
5206 }
8c0fdd85
TS
5207 break;
5208 case 28:
5209 switch (sel) {
5210 case 0:
7a387fff
TS
5211 case 2:
5212 case 4:
5213 case 6:
895c2d04 5214 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5215 rn = "TagLo";
5216 break;
7a387fff
TS
5217 case 1:
5218 case 3:
5219 case 5:
5220 case 7:
895c2d04 5221 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5222 rn = "DataLo";
5223 break;
8c0fdd85 5224 default:
8c0fdd85
TS
5225 goto die;
5226 }
5227 break;
5228 case 29:
7a387fff
TS
5229 switch (sel) {
5230 case 0:
5231 case 2:
5232 case 4:
5233 case 6:
895c2d04 5234 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5235 rn = "TagHi";
5236 break;
5237 case 1:
5238 case 3:
5239 case 5:
5240 case 7:
895c2d04 5241 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5242 rn = "DataHi";
5243 break;
5244 default:
5245 rn = "invalid sel";
5246 goto die;
5247 }
8c0fdd85
TS
5248 break;
5249 case 30:
7a387fff
TS
5250 switch (sel) {
5251 case 0:
7db13fae 5252 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5253 rn = "ErrorEPC";
5254 break;
7a387fff
TS
5255 default:
5256 goto die;
5257 }
8c0fdd85
TS
5258 break;
5259 case 31:
7a387fff
TS
5260 switch (sel) {
5261 case 0:
f1aa6320 5262 /* EJTAG support */
7db13fae 5263 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5264 rn = "DESAVE";
5265 break;
7a387fff
TS
5266 default:
5267 goto die;
5268 }
2423f660
TS
5269 /* Stop translation as we may have switched the execution mode */
5270 ctx->bstate = BS_STOP;
8c0fdd85
TS
5271 break;
5272 default:
8c0fdd85
TS
5273 goto die;
5274 }
2abf314d 5275 (void)rn; /* avoid a compiler warning */
d12d51d5 5276 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5277 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5278 if (use_icount) {
5279 gen_io_end();
5280 ctx->bstate = BS_STOP;
5281 }
8c0fdd85
TS
5282 return;
5283
5284die:
d12d51d5 5285 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5286 generate_exception(ctx, EXCP_RI);
5287}
5288
d26bc211 5289#if defined(TARGET_MIPS64)
d75c135e 5290static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5291{
5292 const char *rn = "invalid";
5293
e189e748 5294 if (sel != 0)
d75c135e 5295 check_insn(ctx, ISA_MIPS64);
e189e748 5296
9c2149c8
TS
5297 switch (reg) {
5298 case 0:
5299 switch (sel) {
5300 case 0:
7db13fae 5301 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5302 rn = "Index";
5303 break;
5304 case 1:
d75c135e 5305 check_insn(ctx, ASE_MT);
895c2d04 5306 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5307 rn = "MVPControl";
ead9360e 5308 break;
9c2149c8 5309 case 2:
d75c135e 5310 check_insn(ctx, ASE_MT);
895c2d04 5311 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5312 rn = "MVPConf0";
ead9360e 5313 break;
9c2149c8 5314 case 3:
d75c135e 5315 check_insn(ctx, ASE_MT);
895c2d04 5316 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5317 rn = "MVPConf1";
ead9360e 5318 break;
9c2149c8
TS
5319 default:
5320 goto die;
5321 }
5322 break;
5323 case 1:
5324 switch (sel) {
5325 case 0:
895c2d04 5326 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5327 rn = "Random";
2423f660 5328 break;
9c2149c8 5329 case 1:
d75c135e 5330 check_insn(ctx, ASE_MT);
7db13fae 5331 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5332 rn = "VPEControl";
ead9360e 5333 break;
9c2149c8 5334 case 2:
d75c135e 5335 check_insn(ctx, ASE_MT);
7db13fae 5336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5337 rn = "VPEConf0";
ead9360e 5338 break;
9c2149c8 5339 case 3:
d75c135e 5340 check_insn(ctx, ASE_MT);
7db13fae 5341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5342 rn = "VPEConf1";
ead9360e 5343 break;
9c2149c8 5344 case 4:
d75c135e 5345 check_insn(ctx, ASE_MT);
7db13fae 5346 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5347 rn = "YQMask";
ead9360e 5348 break;
9c2149c8 5349 case 5:
d75c135e 5350 check_insn(ctx, ASE_MT);
7db13fae 5351 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5352 rn = "VPESchedule";
ead9360e 5353 break;
9c2149c8 5354 case 6:
d75c135e 5355 check_insn(ctx, ASE_MT);
7db13fae 5356 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5357 rn = "VPEScheFBack";
ead9360e 5358 break;
9c2149c8 5359 case 7:
d75c135e 5360 check_insn(ctx, ASE_MT);
7db13fae 5361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5362 rn = "VPEOpt";
ead9360e 5363 break;
9c2149c8
TS
5364 default:
5365 goto die;
5366 }
5367 break;
5368 case 2:
5369 switch (sel) {
5370 case 0:
7db13fae 5371 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5372 rn = "EntryLo0";
5373 break;
9c2149c8 5374 case 1:
d75c135e 5375 check_insn(ctx, ASE_MT);
895c2d04 5376 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5377 rn = "TCStatus";
ead9360e 5378 break;
9c2149c8 5379 case 2:
d75c135e 5380 check_insn(ctx, ASE_MT);
895c2d04 5381 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5382 rn = "TCBind";
ead9360e 5383 break;
9c2149c8 5384 case 3:
d75c135e 5385 check_insn(ctx, ASE_MT);
895c2d04 5386 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5387 rn = "TCRestart";
ead9360e 5388 break;
9c2149c8 5389 case 4:
d75c135e 5390 check_insn(ctx, ASE_MT);
895c2d04 5391 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5392 rn = "TCHalt";
ead9360e 5393 break;
9c2149c8 5394 case 5:
d75c135e 5395 check_insn(ctx, ASE_MT);
895c2d04 5396 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5397 rn = "TCContext";
ead9360e 5398 break;
9c2149c8 5399 case 6:
d75c135e 5400 check_insn(ctx, ASE_MT);
895c2d04 5401 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5402 rn = "TCSchedule";
ead9360e 5403 break;
9c2149c8 5404 case 7:
d75c135e 5405 check_insn(ctx, ASE_MT);
895c2d04 5406 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5407 rn = "TCScheFBack";
ead9360e 5408 break;
9c2149c8
TS
5409 default:
5410 goto die;
5411 }
5412 break;
5413 case 3:
5414 switch (sel) {
5415 case 0:
7db13fae 5416 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5417 rn = "EntryLo1";
5418 break;
9c2149c8
TS
5419 default:
5420 goto die;
1579a72e 5421 }
9c2149c8
TS
5422 break;
5423 case 4:
5424 switch (sel) {
5425 case 0:
7db13fae 5426 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5427 rn = "Context";
5428 break;
9c2149c8 5429 case 1:
d9bea114 5430// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5431 rn = "ContextConfig";
d279279e 5432 goto die;
2423f660 5433// break;
d279279e
PJ
5434 case 2:
5435 if (ctx->ulri) {
5436 tcg_gen_ld_tl(arg, cpu_env,
5437 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5438 rn = "UserLocal";
5439 } else {
5440 tcg_gen_movi_tl(arg, 0);
5441 }
5442 break;
9c2149c8
TS
5443 default:
5444 goto die;
876d4b07 5445 }
9c2149c8
TS
5446 break;
5447 case 5:
5448 switch (sel) {
5449 case 0:
7db13fae 5450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5451 rn = "PageMask";
5452 break;
9c2149c8 5453 case 1:
d75c135e 5454 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5455 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5456 rn = "PageGrain";
5457 break;
9c2149c8
TS
5458 default:
5459 goto die;
876d4b07 5460 }
9c2149c8
TS
5461 break;
5462 case 6:
5463 switch (sel) {
5464 case 0:
7db13fae 5465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5466 rn = "Wired";
5467 break;
9c2149c8 5468 case 1:
d75c135e 5469 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5471 rn = "SRSConf0";
ead9360e 5472 break;
9c2149c8 5473 case 2:
d75c135e 5474 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5475 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5476 rn = "SRSConf1";
ead9360e 5477 break;
9c2149c8 5478 case 3:
d75c135e 5479 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5481 rn = "SRSConf2";
ead9360e 5482 break;
9c2149c8 5483 case 4:
d75c135e 5484 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5486 rn = "SRSConf3";
ead9360e 5487 break;
9c2149c8 5488 case 5:
d75c135e 5489 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5490 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5491 rn = "SRSConf4";
ead9360e 5492 break;
9c2149c8
TS
5493 default:
5494 goto die;
876d4b07 5495 }
9c2149c8
TS
5496 break;
5497 case 7:
5498 switch (sel) {
5499 case 0:
d75c135e 5500 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5502 rn = "HWREna";
5503 break;
9c2149c8
TS
5504 default:
5505 goto die;
876d4b07 5506 }
9c2149c8
TS
5507 break;
5508 case 8:
5509 switch (sel) {
5510 case 0:
7db13fae 5511 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5512 rn = "BadVAddr";
2423f660 5513 break;
9c2149c8
TS
5514 default:
5515 goto die;
876d4b07 5516 }
9c2149c8
TS
5517 break;
5518 case 9:
5519 switch (sel) {
5520 case 0:
2e70f6ef
PB
5521 /* Mark as an IO operation because we read the time. */
5522 if (use_icount)
5523 gen_io_start();
895c2d04 5524 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5525 if (use_icount) {
5526 gen_io_end();
2e70f6ef 5527 }
55807224
EI
5528 /* Break the TB to be able to take timer interrupts immediately
5529 after reading count. */
5530 ctx->bstate = BS_STOP;
2423f660
TS
5531 rn = "Count";
5532 break;
5533 /* 6,7 are implementation dependent */
9c2149c8
TS
5534 default:
5535 goto die;
876d4b07 5536 }
9c2149c8
TS
5537 break;
5538 case 10:
5539 switch (sel) {
5540 case 0:
7db13fae 5541 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5542 rn = "EntryHi";
5543 break;
9c2149c8
TS
5544 default:
5545 goto die;
876d4b07 5546 }
9c2149c8
TS
5547 break;
5548 case 11:
5549 switch (sel) {
5550 case 0:
7db13fae 5551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5552 rn = "Compare";
5553 break;
876d4b07 5554 /* 6,7 are implementation dependent */
9c2149c8
TS
5555 default:
5556 goto die;
876d4b07 5557 }
9c2149c8
TS
5558 break;
5559 case 12:
5560 switch (sel) {
5561 case 0:
7db13fae 5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5563 rn = "Status";
5564 break;
9c2149c8 5565 case 1:
d75c135e 5566 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5568 rn = "IntCtl";
5569 break;
9c2149c8 5570 case 2:
d75c135e 5571 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5573 rn = "SRSCtl";
5574 break;
9c2149c8 5575 case 3:
d75c135e 5576 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5577 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5578 rn = "SRSMap";
5579 break;
9c2149c8
TS
5580 default:
5581 goto die;
876d4b07 5582 }
9c2149c8
TS
5583 break;
5584 case 13:
5585 switch (sel) {
5586 case 0:
7db13fae 5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5588 rn = "Cause";
5589 break;
9c2149c8
TS
5590 default:
5591 goto die;
876d4b07 5592 }
9c2149c8
TS
5593 break;
5594 case 14:
5595 switch (sel) {
5596 case 0:
7db13fae 5597 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5598 rn = "EPC";
5599 break;
9c2149c8
TS
5600 default:
5601 goto die;
876d4b07 5602 }
9c2149c8
TS
5603 break;
5604 case 15:
5605 switch (sel) {
5606 case 0:
7db13fae 5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5608 rn = "PRid";
5609 break;
9c2149c8 5610 case 1:
d75c135e 5611 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5613 rn = "EBase";
5614 break;
9c2149c8
TS
5615 default:
5616 goto die;
876d4b07 5617 }
9c2149c8
TS
5618 break;
5619 case 16:
5620 switch (sel) {
5621 case 0:
7db13fae 5622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5623 rn = "Config";
5624 break;
5625 case 1:
7db13fae 5626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5627 rn = "Config1";
5628 break;
5629 case 2:
7db13fae 5630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5631 rn = "Config2";
5632 break;
5633 case 3:
7db13fae 5634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5635 rn = "Config3";
5636 break;
5637 /* 6,7 are implementation dependent */
f0b3f3ae 5638 case 6:
7db13fae 5639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5640 rn = "Config6";
5641 break;
5642 case 7:
7db13fae 5643 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5644 rn = "Config7";
5645 break;
9c2149c8
TS
5646 default:
5647 goto die;
5648 }
5649 break;
5650 case 17:
5651 switch (sel) {
5652 case 0:
895c2d04 5653 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5654 rn = "LLAddr";
5655 break;
9c2149c8
TS
5656 default:
5657 goto die;
5658 }
5659 break;
5660 case 18:
5661 switch (sel) {
fd88b6ab 5662 case 0 ... 7:
895c2d04 5663 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5664 rn = "WatchLo";
5665 break;
9c2149c8
TS
5666 default:
5667 goto die;
5668 }
5669 break;
5670 case 19:
5671 switch (sel) {
fd88b6ab 5672 case 0 ... 7:
895c2d04 5673 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5674 rn = "WatchHi";
5675 break;
9c2149c8
TS
5676 default:
5677 goto die;
5678 }
5679 break;
5680 case 20:
5681 switch (sel) {
5682 case 0:
d75c135e 5683 check_insn(ctx, ISA_MIPS3);
7db13fae 5684 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5685 rn = "XContext";
5686 break;
9c2149c8
TS
5687 default:
5688 goto die;
5689 }
5690 break;
5691 case 21:
5692 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5693 switch (sel) {
5694 case 0:
7db13fae 5695 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5696 rn = "Framemask";
5697 break;
9c2149c8
TS
5698 default:
5699 goto die;
5700 }
5701 break;
5702 case 22:
d9bea114 5703 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5704 rn = "'Diagnostic"; /* implementation dependent */
5705 break;
9c2149c8
TS
5706 case 23:
5707 switch (sel) {
5708 case 0:
895c2d04 5709 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5710 rn = "Debug";
5711 break;
9c2149c8 5712 case 1:
895c2d04 5713// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5714 rn = "TraceControl";
5715// break;
9c2149c8 5716 case 2:
895c2d04 5717// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5718 rn = "TraceControl2";
5719// break;
9c2149c8 5720 case 3:
895c2d04 5721// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5722 rn = "UserTraceData";
5723// break;
9c2149c8 5724 case 4:
895c2d04 5725// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5726 rn = "TraceBPC";
5727// break;
9c2149c8
TS
5728 default:
5729 goto die;
5730 }
5731 break;
5732 case 24:
5733 switch (sel) {
5734 case 0:
f0b3f3ae 5735 /* EJTAG support */
7db13fae 5736 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5737 rn = "DEPC";
5738 break;
9c2149c8
TS
5739 default:
5740 goto die;
5741 }
5742 break;
5743 case 25:
5744 switch (sel) {
5745 case 0:
7db13fae 5746 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5747 rn = "Performance0";
9c2149c8
TS
5748 break;
5749 case 1:
d9bea114 5750// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5751 rn = "Performance1";
5752// break;
9c2149c8 5753 case 2:
d9bea114 5754// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5755 rn = "Performance2";
5756// break;
9c2149c8 5757 case 3:
d9bea114 5758// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5759 rn = "Performance3";
5760// break;
9c2149c8 5761 case 4:
d9bea114 5762// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5763 rn = "Performance4";
5764// break;
9c2149c8 5765 case 5:
d9bea114 5766// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5767 rn = "Performance5";
5768// break;
9c2149c8 5769 case 6:
d9bea114 5770// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5771 rn = "Performance6";
5772// break;
9c2149c8 5773 case 7:
d9bea114 5774// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5775 rn = "Performance7";
5776// break;
9c2149c8
TS
5777 default:
5778 goto die;
5779 }
5780 break;
5781 case 26:
d9bea114 5782 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5783 rn = "ECC";
5784 break;
9c2149c8
TS
5785 case 27:
5786 switch (sel) {
5787 /* ignored */
5788 case 0 ... 3:
d9bea114 5789 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5790 rn = "CacheErr";
5791 break;
9c2149c8
TS
5792 default:
5793 goto die;
5794 }
5795 break;
5796 case 28:
5797 switch (sel) {
5798 case 0:
5799 case 2:
5800 case 4:
5801 case 6:
7db13fae 5802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5803 rn = "TagLo";
5804 break;
5805 case 1:
5806 case 3:
5807 case 5:
5808 case 7:
7db13fae 5809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5810 rn = "DataLo";
5811 break;
5812 default:
5813 goto die;
5814 }
5815 break;
5816 case 29:
5817 switch (sel) {
5818 case 0:
5819 case 2:
5820 case 4:
5821 case 6:
7db13fae 5822 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5823 rn = "TagHi";
5824 break;
5825 case 1:
5826 case 3:
5827 case 5:
5828 case 7:
7db13fae 5829 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5830 rn = "DataHi";
5831 break;
5832 default:
5833 goto die;
5834 }
5835 break;
5836 case 30:
5837 switch (sel) {
5838 case 0:
7db13fae 5839 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5840 rn = "ErrorEPC";
5841 break;
9c2149c8
TS
5842 default:
5843 goto die;
5844 }
5845 break;
5846 case 31:
5847 switch (sel) {
5848 case 0:
f0b3f3ae 5849 /* EJTAG support */
7db13fae 5850 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5851 rn = "DESAVE";
5852 break;
9c2149c8
TS
5853 default:
5854 goto die;
5855 }
5856 break;
5857 default:
876d4b07 5858 goto die;
9c2149c8 5859 }
2abf314d 5860 (void)rn; /* avoid a compiler warning */
d12d51d5 5861 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5862 return;
5863
5864die:
d12d51d5 5865 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5866 generate_exception(ctx, EXCP_RI);
5867}
5868
d75c135e 5869static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5870{
5871 const char *rn = "invalid";
5872
e189e748 5873 if (sel != 0)
d75c135e 5874 check_insn(ctx, ISA_MIPS64);
e189e748 5875
2e70f6ef
PB
5876 if (use_icount)
5877 gen_io_start();
5878
9c2149c8
TS
5879 switch (reg) {
5880 case 0:
5881 switch (sel) {
5882 case 0:
895c2d04 5883 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5884 rn = "Index";
5885 break;
5886 case 1:
d75c135e 5887 check_insn(ctx, ASE_MT);
895c2d04 5888 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5889 rn = "MVPControl";
ead9360e 5890 break;
9c2149c8 5891 case 2:
d75c135e 5892 check_insn(ctx, ASE_MT);
ead9360e 5893 /* ignored */
9c2149c8 5894 rn = "MVPConf0";
ead9360e 5895 break;
9c2149c8 5896 case 3:
d75c135e 5897 check_insn(ctx, ASE_MT);
ead9360e 5898 /* ignored */
9c2149c8 5899 rn = "MVPConf1";
ead9360e 5900 break;
9c2149c8
TS
5901 default:
5902 goto die;
5903 }
5904 break;
5905 case 1:
5906 switch (sel) {
5907 case 0:
2423f660 5908 /* ignored */
9c2149c8 5909 rn = "Random";
2423f660 5910 break;
9c2149c8 5911 case 1:
d75c135e 5912 check_insn(ctx, ASE_MT);
895c2d04 5913 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5914 rn = "VPEControl";
ead9360e 5915 break;
9c2149c8 5916 case 2:
d75c135e 5917 check_insn(ctx, ASE_MT);
895c2d04 5918 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5919 rn = "VPEConf0";
ead9360e 5920 break;
9c2149c8 5921 case 3:
d75c135e 5922 check_insn(ctx, ASE_MT);
895c2d04 5923 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5924 rn = "VPEConf1";
ead9360e 5925 break;
9c2149c8 5926 case 4:
d75c135e 5927 check_insn(ctx, ASE_MT);
895c2d04 5928 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5929 rn = "YQMask";
ead9360e 5930 break;
9c2149c8 5931 case 5:
d75c135e 5932 check_insn(ctx, ASE_MT);
7db13fae 5933 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5934 rn = "VPESchedule";
ead9360e 5935 break;
9c2149c8 5936 case 6:
d75c135e 5937 check_insn(ctx, ASE_MT);
7db13fae 5938 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5939 rn = "VPEScheFBack";
ead9360e 5940 break;
9c2149c8 5941 case 7:
d75c135e 5942 check_insn(ctx, ASE_MT);
895c2d04 5943 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5944 rn = "VPEOpt";
ead9360e 5945 break;
9c2149c8
TS
5946 default:
5947 goto die;
5948 }
5949 break;
5950 case 2:
5951 switch (sel) {
5952 case 0:
895c2d04 5953 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5954 rn = "EntryLo0";
5955 break;
9c2149c8 5956 case 1:
d75c135e 5957 check_insn(ctx, ASE_MT);
895c2d04 5958 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5959 rn = "TCStatus";
ead9360e 5960 break;
9c2149c8 5961 case 2:
d75c135e 5962 check_insn(ctx, ASE_MT);
895c2d04 5963 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5964 rn = "TCBind";
ead9360e 5965 break;
9c2149c8 5966 case 3:
d75c135e 5967 check_insn(ctx, ASE_MT);
895c2d04 5968 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5969 rn = "TCRestart";
ead9360e 5970 break;
9c2149c8 5971 case 4:
d75c135e 5972 check_insn(ctx, ASE_MT);
895c2d04 5973 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5974 rn = "TCHalt";
ead9360e 5975 break;
9c2149c8 5976 case 5:
d75c135e 5977 check_insn(ctx, ASE_MT);
895c2d04 5978 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5979 rn = "TCContext";
ead9360e 5980 break;
9c2149c8 5981 case 6:
d75c135e 5982 check_insn(ctx, ASE_MT);
895c2d04 5983 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5984 rn = "TCSchedule";
ead9360e 5985 break;
9c2149c8 5986 case 7:
d75c135e 5987 check_insn(ctx, ASE_MT);
895c2d04 5988 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5989 rn = "TCScheFBack";
ead9360e 5990 break;
9c2149c8
TS
5991 default:
5992 goto die;
5993 }
5994 break;
5995 case 3:
5996 switch (sel) {
5997 case 0:
895c2d04 5998 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5999 rn = "EntryLo1";
6000 break;
9c2149c8
TS
6001 default:
6002 goto die;
876d4b07 6003 }
9c2149c8
TS
6004 break;
6005 case 4:
6006 switch (sel) {
6007 case 0:
895c2d04 6008 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6009 rn = "Context";
6010 break;
9c2149c8 6011 case 1:
895c2d04 6012// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6013 rn = "ContextConfig";
d279279e 6014 goto die;
2423f660 6015// break;
d279279e
PJ
6016 case 2:
6017 if (ctx->ulri) {
6018 tcg_gen_st_tl(arg, cpu_env,
6019 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6020 rn = "UserLocal";
6021 }
6022 break;
9c2149c8
TS
6023 default:
6024 goto die;
876d4b07 6025 }
9c2149c8
TS
6026 break;
6027 case 5:
6028 switch (sel) {
6029 case 0:
895c2d04 6030 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6031 rn = "PageMask";
6032 break;
9c2149c8 6033 case 1:
d75c135e 6034 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6035 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6036 rn = "PageGrain";
6037 break;
9c2149c8
TS
6038 default:
6039 goto die;
876d4b07 6040 }
9c2149c8
TS
6041 break;
6042 case 6:
6043 switch (sel) {
6044 case 0:
895c2d04 6045 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6046 rn = "Wired";
6047 break;
9c2149c8 6048 case 1:
d75c135e 6049 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6050 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6051 rn = "SRSConf0";
ead9360e 6052 break;
9c2149c8 6053 case 2:
d75c135e 6054 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6055 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6056 rn = "SRSConf1";
ead9360e 6057 break;
9c2149c8 6058 case 3:
d75c135e 6059 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6060 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6061 rn = "SRSConf2";
ead9360e 6062 break;
9c2149c8 6063 case 4:
d75c135e 6064 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6065 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6066 rn = "SRSConf3";
ead9360e 6067 break;
9c2149c8 6068 case 5:
d75c135e 6069 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6070 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6071 rn = "SRSConf4";
ead9360e 6072 break;
9c2149c8
TS
6073 default:
6074 goto die;
876d4b07 6075 }
9c2149c8
TS
6076 break;
6077 case 7:
6078 switch (sel) {
6079 case 0:
d75c135e 6080 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6081 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6082 ctx->bstate = BS_STOP;
2423f660
TS
6083 rn = "HWREna";
6084 break;
9c2149c8
TS
6085 default:
6086 goto die;
876d4b07 6087 }
9c2149c8
TS
6088 break;
6089 case 8:
6090 /* ignored */
f0b3f3ae 6091 rn = "BadVAddr";
9c2149c8
TS
6092 break;
6093 case 9:
6094 switch (sel) {
6095 case 0:
895c2d04 6096 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6097 rn = "Count";
6098 break;
876d4b07 6099 /* 6,7 are implementation dependent */
9c2149c8
TS
6100 default:
6101 goto die;
876d4b07
TS
6102 }
6103 /* Stop translation as we may have switched the execution mode */
6104 ctx->bstate = BS_STOP;
9c2149c8
TS
6105 break;
6106 case 10:
6107 switch (sel) {
6108 case 0:
895c2d04 6109 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6110 rn = "EntryHi";
6111 break;
9c2149c8
TS
6112 default:
6113 goto die;
876d4b07 6114 }
9c2149c8
TS
6115 break;
6116 case 11:
6117 switch (sel) {
6118 case 0:
895c2d04 6119 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6120 rn = "Compare";
6121 break;
876d4b07 6122 /* 6,7 are implementation dependent */
9c2149c8
TS
6123 default:
6124 goto die;
876d4b07 6125 }
de9a95f0
AJ
6126 /* Stop translation as we may have switched the execution mode */
6127 ctx->bstate = BS_STOP;
9c2149c8
TS
6128 break;
6129 case 12:
6130 switch (sel) {
6131 case 0:
867abc7e 6132 save_cpu_state(ctx, 1);
895c2d04 6133 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6134 /* BS_STOP isn't good enough here, hflags may have changed. */
6135 gen_save_pc(ctx->pc + 4);
6136 ctx->bstate = BS_EXCP;
2423f660
TS
6137 rn = "Status";
6138 break;
9c2149c8 6139 case 1:
d75c135e 6140 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6141 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6142 /* Stop translation as we may have switched the execution mode */
6143 ctx->bstate = BS_STOP;
2423f660
TS
6144 rn = "IntCtl";
6145 break;
9c2149c8 6146 case 2:
d75c135e 6147 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6148 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6149 /* Stop translation as we may have switched the execution mode */
6150 ctx->bstate = BS_STOP;
2423f660
TS
6151 rn = "SRSCtl";
6152 break;
9c2149c8 6153 case 3:
d75c135e 6154 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6155 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6156 /* Stop translation as we may have switched the execution mode */
6157 ctx->bstate = BS_STOP;
2423f660
TS
6158 rn = "SRSMap";
6159 break;
6160 default:
9c2149c8 6161 goto die;
876d4b07 6162 }
9c2149c8
TS
6163 break;
6164 case 13:
6165 switch (sel) {
6166 case 0:
867abc7e 6167 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6168 /* Mark as an IO operation because we may trigger a software
6169 interrupt. */
6170 if (use_icount) {
6171 gen_io_start();
6172 }
895c2d04 6173 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6174 if (use_icount) {
6175 gen_io_end();
6176 }
6177 /* Stop translation as we may have triggered an intetrupt */
6178 ctx->bstate = BS_STOP;
2423f660
TS
6179 rn = "Cause";
6180 break;
9c2149c8
TS
6181 default:
6182 goto die;
876d4b07 6183 }
9c2149c8
TS
6184 break;
6185 case 14:
6186 switch (sel) {
6187 case 0:
7db13fae 6188 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6189 rn = "EPC";
6190 break;
9c2149c8
TS
6191 default:
6192 goto die;
876d4b07 6193 }
9c2149c8
TS
6194 break;
6195 case 15:
6196 switch (sel) {
6197 case 0:
2423f660
TS
6198 /* ignored */
6199 rn = "PRid";
6200 break;
9c2149c8 6201 case 1:
d75c135e 6202 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6203 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6204 rn = "EBase";
6205 break;
9c2149c8
TS
6206 default:
6207 goto die;
876d4b07 6208 }
9c2149c8
TS
6209 break;
6210 case 16:
6211 switch (sel) {
6212 case 0:
895c2d04 6213 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6214 rn = "Config";
2423f660
TS
6215 /* Stop translation as we may have switched the execution mode */
6216 ctx->bstate = BS_STOP;
9c2149c8
TS
6217 break;
6218 case 1:
1fc7bf6e 6219 /* ignored, read only */
9c2149c8
TS
6220 rn = "Config1";
6221 break;
6222 case 2:
895c2d04 6223 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6224 rn = "Config2";
2423f660
TS
6225 /* Stop translation as we may have switched the execution mode */
6226 ctx->bstate = BS_STOP;
9c2149c8
TS
6227 break;
6228 case 3:
2423f660 6229 /* ignored */
9c2149c8
TS
6230 rn = "Config3";
6231 break;
6232 /* 6,7 are implementation dependent */
6233 default:
6234 rn = "Invalid config selector";
6235 goto die;
6236 }
9c2149c8
TS
6237 break;
6238 case 17:
6239 switch (sel) {
6240 case 0:
895c2d04 6241 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6242 rn = "LLAddr";
6243 break;
9c2149c8
TS
6244 default:
6245 goto die;
6246 }
6247 break;
6248 case 18:
6249 switch (sel) {
fd88b6ab 6250 case 0 ... 7:
895c2d04 6251 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6252 rn = "WatchLo";
6253 break;
9c2149c8
TS
6254 default:
6255 goto die;
6256 }
6257 break;
6258 case 19:
6259 switch (sel) {
fd88b6ab 6260 case 0 ... 7:
895c2d04 6261 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6262 rn = "WatchHi";
6263 break;
9c2149c8
TS
6264 default:
6265 goto die;
6266 }
6267 break;
6268 case 20:
6269 switch (sel) {
6270 case 0:
d75c135e 6271 check_insn(ctx, ISA_MIPS3);
895c2d04 6272 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6273 rn = "XContext";
6274 break;
9c2149c8
TS
6275 default:
6276 goto die;
6277 }
6278 break;
6279 case 21:
6280 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6281 switch (sel) {
6282 case 0:
895c2d04 6283 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6284 rn = "Framemask";
6285 break;
9c2149c8
TS
6286 default:
6287 goto die;
6288 }
6289 break;
6290 case 22:
6291 /* ignored */
6292 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6293 break;
9c2149c8
TS
6294 case 23:
6295 switch (sel) {
6296 case 0:
895c2d04 6297 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6298 /* BS_STOP isn't good enough here, hflags may have changed. */
6299 gen_save_pc(ctx->pc + 4);
6300 ctx->bstate = BS_EXCP;
2423f660
TS
6301 rn = "Debug";
6302 break;
9c2149c8 6303 case 1:
895c2d04 6304// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6305 /* Stop translation as we may have switched the execution mode */
6306 ctx->bstate = BS_STOP;
2423f660
TS
6307 rn = "TraceControl";
6308// break;
9c2149c8 6309 case 2:
895c2d04 6310// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6311 /* Stop translation as we may have switched the execution mode */
6312 ctx->bstate = BS_STOP;
2423f660
TS
6313 rn = "TraceControl2";
6314// break;
9c2149c8 6315 case 3:
895c2d04 6316// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6317 /* Stop translation as we may have switched the execution mode */
6318 ctx->bstate = BS_STOP;
2423f660
TS
6319 rn = "UserTraceData";
6320// break;
9c2149c8 6321 case 4:
895c2d04 6322// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6323 /* Stop translation as we may have switched the execution mode */
6324 ctx->bstate = BS_STOP;
2423f660
TS
6325 rn = "TraceBPC";
6326// break;
9c2149c8
TS
6327 default:
6328 goto die;
6329 }
9c2149c8
TS
6330 break;
6331 case 24:
6332 switch (sel) {
6333 case 0:
f1aa6320 6334 /* EJTAG support */
7db13fae 6335 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6336 rn = "DEPC";
6337 break;
9c2149c8
TS
6338 default:
6339 goto die;
6340 }
6341 break;
6342 case 25:
6343 switch (sel) {
6344 case 0:
895c2d04 6345 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6346 rn = "Performance0";
6347 break;
9c2149c8 6348 case 1:
895c2d04 6349// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6350 rn = "Performance1";
6351// break;
9c2149c8 6352 case 2:
895c2d04 6353// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6354 rn = "Performance2";
6355// break;
9c2149c8 6356 case 3:
895c2d04 6357// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6358 rn = "Performance3";
6359// break;
9c2149c8 6360 case 4:
895c2d04 6361// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6362 rn = "Performance4";
6363// break;
9c2149c8 6364 case 5:
895c2d04 6365// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6366 rn = "Performance5";
6367// break;
9c2149c8 6368 case 6:
895c2d04 6369// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6370 rn = "Performance6";
6371// break;
9c2149c8 6372 case 7:
895c2d04 6373// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6374 rn = "Performance7";
6375// break;
9c2149c8
TS
6376 default:
6377 goto die;
6378 }
876d4b07 6379 break;
9c2149c8 6380 case 26:
876d4b07 6381 /* ignored */
9c2149c8 6382 rn = "ECC";
876d4b07 6383 break;
9c2149c8
TS
6384 case 27:
6385 switch (sel) {
6386 case 0 ... 3:
2423f660
TS
6387 /* ignored */
6388 rn = "CacheErr";
6389 break;
9c2149c8
TS
6390 default:
6391 goto die;
6392 }
876d4b07 6393 break;
9c2149c8
TS
6394 case 28:
6395 switch (sel) {
6396 case 0:
6397 case 2:
6398 case 4:
6399 case 6:
895c2d04 6400 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6401 rn = "TagLo";
6402 break;
6403 case 1:
6404 case 3:
6405 case 5:
6406 case 7:
895c2d04 6407 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6408 rn = "DataLo";
6409 break;
6410 default:
6411 goto die;
6412 }
6413 break;
6414 case 29:
6415 switch (sel) {
6416 case 0:
6417 case 2:
6418 case 4:
6419 case 6:
895c2d04 6420 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6421 rn = "TagHi";
6422 break;
6423 case 1:
6424 case 3:
6425 case 5:
6426 case 7:
895c2d04 6427 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6428 rn = "DataHi";
6429 break;
6430 default:
6431 rn = "invalid sel";
6432 goto die;
6433 }
876d4b07 6434 break;
9c2149c8
TS
6435 case 30:
6436 switch (sel) {
6437 case 0:
7db13fae 6438 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6439 rn = "ErrorEPC";
6440 break;
9c2149c8
TS
6441 default:
6442 goto die;
6443 }
6444 break;
6445 case 31:
6446 switch (sel) {
6447 case 0:
f1aa6320 6448 /* EJTAG support */
7db13fae 6449 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6450 rn = "DESAVE";
6451 break;
9c2149c8
TS
6452 default:
6453 goto die;
6454 }
876d4b07
TS
6455 /* Stop translation as we may have switched the execution mode */
6456 ctx->bstate = BS_STOP;
9c2149c8
TS
6457 break;
6458 default:
876d4b07 6459 goto die;
9c2149c8 6460 }
2abf314d 6461 (void)rn; /* avoid a compiler warning */
d12d51d5 6462 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6463 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6464 if (use_icount) {
6465 gen_io_end();
6466 ctx->bstate = BS_STOP;
6467 }
9c2149c8
TS
6468 return;
6469
6470die:
d12d51d5 6471 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6472 generate_exception(ctx, EXCP_RI);
6473}
d26bc211 6474#endif /* TARGET_MIPS64 */
9c2149c8 6475
7db13fae 6476static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6477 int u, int sel, int h)
6478{
6479 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6480 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6481
6482 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6483 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6484 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6485 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6486 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6487 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6488 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6489 else if (u == 0) {
6490 switch (rt) {
5a25ce94
EI
6491 case 1:
6492 switch (sel) {
6493 case 1:
895c2d04 6494 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6495 break;
6496 case 2:
895c2d04 6497 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6498 break;
6499 default:
6500 goto die;
6501 break;
6502 }
6503 break;
ead9360e
TS
6504 case 2:
6505 switch (sel) {
6506 case 1:
895c2d04 6507 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6508 break;
6509 case 2:
895c2d04 6510 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6511 break;
6512 case 3:
895c2d04 6513 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6514 break;
6515 case 4:
895c2d04 6516 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6517 break;
6518 case 5:
895c2d04 6519 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6520 break;
6521 case 6:
895c2d04 6522 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6523 break;
6524 case 7:
895c2d04 6525 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6526 break;
6527 default:
d75c135e 6528 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6529 break;
6530 }
6531 break;
6532 case 10:
6533 switch (sel) {
6534 case 0:
895c2d04 6535 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6536 break;
6537 default:
d75c135e 6538 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6539 break;
6540 }
6541 case 12:
6542 switch (sel) {
6543 case 0:
895c2d04 6544 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6545 break;
6546 default:
d75c135e 6547 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6548 break;
6549 }
5a25ce94
EI
6550 case 13:
6551 switch (sel) {
6552 case 0:
895c2d04 6553 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6554 break;
6555 default:
6556 goto die;
6557 break;
6558 }
6559 break;
6560 case 14:
6561 switch (sel) {
6562 case 0:
895c2d04 6563 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6564 break;
6565 default:
6566 goto die;
6567 break;
6568 }
6569 break;
6570 case 15:
6571 switch (sel) {
6572 case 1:
895c2d04 6573 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6574 break;
6575 default:
6576 goto die;
6577 break;
6578 }
6579 break;
6580 case 16:
6581 switch (sel) {
6582 case 0 ... 7:
895c2d04 6583 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6584 break;
6585 default:
6586 goto die;
6587 break;
6588 }
6589 break;
ead9360e
TS
6590 case 23:
6591 switch (sel) {
6592 case 0:
895c2d04 6593 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6594 break;
6595 default:
d75c135e 6596 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6597 break;
6598 }
6599 break;
6600 default:
d75c135e 6601 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6602 }
6603 } else switch (sel) {
6604 /* GPR registers. */
6605 case 0:
895c2d04 6606 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6607 break;
6608 /* Auxiliary CPU registers */
6609 case 1:
6610 switch (rt) {
6611 case 0:
895c2d04 6612 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6613 break;
6614 case 1:
895c2d04 6615 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6616 break;
6617 case 2:
895c2d04 6618 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6619 break;
6620 case 4:
895c2d04 6621 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6622 break;
6623 case 5:
895c2d04 6624 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6625 break;
6626 case 6:
895c2d04 6627 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6628 break;
6629 case 8:
895c2d04 6630 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6631 break;
6632 case 9:
895c2d04 6633 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6634 break;
6635 case 10:
895c2d04 6636 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6637 break;
6638 case 12:
895c2d04 6639 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6640 break;
6641 case 13:
895c2d04 6642 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6643 break;
6644 case 14:
895c2d04 6645 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6646 break;
6647 case 16:
895c2d04 6648 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6649 break;
6650 default:
6651 goto die;
6652 }
6653 break;
6654 /* Floating point (COP1). */
6655 case 2:
6656 /* XXX: For now we support only a single FPU context. */
6657 if (h == 0) {
a7812ae4 6658 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6659
6660 gen_load_fpr32(fp0, rt);
6661 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6662 tcg_temp_free_i32(fp0);
ead9360e 6663 } else {
a7812ae4 6664 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 6665
7f6613ce 6666 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 6667 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6668 tcg_temp_free_i32(fp0);
ead9360e
TS
6669 }
6670 break;
6671 case 3:
6672 /* XXX: For now we support only a single FPU context. */
895c2d04 6673 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6674 break;
6675 /* COP2: Not implemented. */
6676 case 4:
6677 case 5:
6678 /* fall through */
6679 default:
6680 goto die;
6681 }
d12d51d5 6682 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6683 gen_store_gpr(t0, rd);
6684 tcg_temp_free(t0);
ead9360e
TS
6685 return;
6686
6687die:
1a3fd9c3 6688 tcg_temp_free(t0);
d12d51d5 6689 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6690 generate_exception(ctx, EXCP_RI);
6691}
6692
7db13fae 6693static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6694 int u, int sel, int h)
6695{
6696 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6697 TCGv t0 = tcg_temp_local_new();
ead9360e 6698
1a3fd9c3 6699 gen_load_gpr(t0, rt);
ead9360e 6700 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6701 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6702 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6703 /* NOP */ ;
6704 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6705 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6706 /* NOP */ ;
6707 else if (u == 0) {
6708 switch (rd) {
5a25ce94
EI
6709 case 1:
6710 switch (sel) {
6711 case 1:
895c2d04 6712 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6713 break;
6714 case 2:
895c2d04 6715 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6716 break;
6717 default:
6718 goto die;
6719 break;
6720 }
6721 break;
ead9360e
TS
6722 case 2:
6723 switch (sel) {
6724 case 1:
895c2d04 6725 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6726 break;
6727 case 2:
895c2d04 6728 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6729 break;
6730 case 3:
895c2d04 6731 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6732 break;
6733 case 4:
895c2d04 6734 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6735 break;
6736 case 5:
895c2d04 6737 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6738 break;
6739 case 6:
895c2d04 6740 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6741 break;
6742 case 7:
895c2d04 6743 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6744 break;
6745 default:
d75c135e 6746 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6747 break;
6748 }
6749 break;
6750 case 10:
6751 switch (sel) {
6752 case 0:
895c2d04 6753 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6754 break;
6755 default:
d75c135e 6756 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6757 break;
6758 }
6759 case 12:
6760 switch (sel) {
6761 case 0:
895c2d04 6762 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6763 break;
6764 default:
d75c135e 6765 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6766 break;
6767 }
5a25ce94
EI
6768 case 13:
6769 switch (sel) {
6770 case 0:
895c2d04 6771 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6772 break;
6773 default:
6774 goto die;
6775 break;
6776 }
6777 break;
6778 case 15:
6779 switch (sel) {
6780 case 1:
895c2d04 6781 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6782 break;
6783 default:
6784 goto die;
6785 break;
6786 }
6787 break;
ead9360e
TS
6788 case 23:
6789 switch (sel) {
6790 case 0:
895c2d04 6791 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6792 break;
6793 default:
d75c135e 6794 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6795 break;
6796 }
6797 break;
6798 default:
d75c135e 6799 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6800 }
6801 } else switch (sel) {
6802 /* GPR registers. */
6803 case 0:
895c2d04 6804 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6805 break;
6806 /* Auxiliary CPU registers */
6807 case 1:
6808 switch (rd) {
6809 case 0:
895c2d04 6810 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6811 break;
6812 case 1:
895c2d04 6813 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6814 break;
6815 case 2:
895c2d04 6816 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6817 break;
6818 case 4:
895c2d04 6819 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6820 break;
6821 case 5:
895c2d04 6822 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6823 break;
6824 case 6:
895c2d04 6825 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6826 break;
6827 case 8:
895c2d04 6828 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6829 break;
6830 case 9:
895c2d04 6831 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6832 break;
6833 case 10:
895c2d04 6834 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6835 break;
6836 case 12:
895c2d04 6837 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6838 break;
6839 case 13:
895c2d04 6840 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6841 break;
6842 case 14:
895c2d04 6843 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6844 break;
6845 case 16:
895c2d04 6846 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6847 break;
6848 default:
6849 goto die;
6850 }
6851 break;
6852 /* Floating point (COP1). */
6853 case 2:
6854 /* XXX: For now we support only a single FPU context. */
6855 if (h == 0) {
a7812ae4 6856 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6857
6858 tcg_gen_trunc_tl_i32(fp0, t0);
6859 gen_store_fpr32(fp0, rd);
a7812ae4 6860 tcg_temp_free_i32(fp0);
ead9360e 6861 } else {
a7812ae4 6862 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6863
6864 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 6865 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 6866 tcg_temp_free_i32(fp0);
ead9360e
TS
6867 }
6868 break;
6869 case 3:
6870 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
6871 {
6872 TCGv_i32 fs_tmp = tcg_const_i32(rd);
6873
6874 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
6875 tcg_temp_free_i32(fs_tmp);
6876 }
ead9360e
TS
6877 break;
6878 /* COP2: Not implemented. */
6879 case 4:
6880 case 5:
6881 /* fall through */
6882 default:
6883 goto die;
6884 }
d12d51d5 6885 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6886 tcg_temp_free(t0);
ead9360e
TS
6887 return;
6888
6889die:
1a3fd9c3 6890 tcg_temp_free(t0);
d12d51d5 6891 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6892 generate_exception(ctx, EXCP_RI);
6893}
6894
7db13fae 6895static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6896{
287c4b84 6897 const char *opn = "ldst";
6af0bf9c 6898
2e15497c 6899 check_cp0_enabled(ctx);
6af0bf9c
FB
6900 switch (opc) {
6901 case OPC_MFC0:
6902 if (rt == 0) {
ead9360e 6903 /* Treat as NOP. */
6af0bf9c
FB
6904 return;
6905 }
d75c135e 6906 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6907 opn = "mfc0";
6908 break;
6909 case OPC_MTC0:
1a3fd9c3 6910 {
1fc7bf6e 6911 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6912
6913 gen_load_gpr(t0, rt);
d75c135e 6914 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6915 tcg_temp_free(t0);
6916 }
6af0bf9c
FB
6917 opn = "mtc0";
6918 break;
d26bc211 6919#if defined(TARGET_MIPS64)
9c2149c8 6920 case OPC_DMFC0:
d75c135e 6921 check_insn(ctx, ISA_MIPS3);
9c2149c8 6922 if (rt == 0) {
ead9360e 6923 /* Treat as NOP. */
9c2149c8
TS
6924 return;
6925 }
d75c135e 6926 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6927 opn = "dmfc0";
6928 break;
6929 case OPC_DMTC0:
d75c135e 6930 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 6931 {
1fc7bf6e 6932 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6933
6934 gen_load_gpr(t0, rt);
d75c135e 6935 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6936 tcg_temp_free(t0);
6937 }
9c2149c8
TS
6938 opn = "dmtc0";
6939 break;
534ce69f 6940#endif
ead9360e 6941 case OPC_MFTR:
d75c135e 6942 check_insn(ctx, ASE_MT);
ead9360e
TS
6943 if (rd == 0) {
6944 /* Treat as NOP. */
6945 return;
6946 }
6c5c1e20 6947 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6948 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6949 opn = "mftr";
6950 break;
6951 case OPC_MTTR:
d75c135e 6952 check_insn(ctx, ASE_MT);
6c5c1e20 6953 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6954 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6955 opn = "mttr";
6956 break;
6af0bf9c 6957 case OPC_TLBWI:
6af0bf9c 6958 opn = "tlbwi";
c01fccd2 6959 if (!env->tlb->helper_tlbwi)
29929e34 6960 goto die;
895c2d04 6961 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6962 break;
6963 case OPC_TLBWR:
6af0bf9c 6964 opn = "tlbwr";
c01fccd2 6965 if (!env->tlb->helper_tlbwr)
29929e34 6966 goto die;
895c2d04 6967 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6968 break;
6969 case OPC_TLBP:
6af0bf9c 6970 opn = "tlbp";
c01fccd2 6971 if (!env->tlb->helper_tlbp)
29929e34 6972 goto die;
895c2d04 6973 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6974 break;
6975 case OPC_TLBR:
6af0bf9c 6976 opn = "tlbr";
c01fccd2 6977 if (!env->tlb->helper_tlbr)
29929e34 6978 goto die;
895c2d04 6979 gen_helper_tlbr(cpu_env);
6af0bf9c 6980 break;
6af0bf9c
FB
6981 case OPC_ERET:
6982 opn = "eret";
d75c135e 6983 check_insn(ctx, ISA_MIPS2);
895c2d04 6984 gen_helper_eret(cpu_env);
6af0bf9c
FB
6985 ctx->bstate = BS_EXCP;
6986 break;
6987 case OPC_DERET:
6988 opn = "deret";
d75c135e 6989 check_insn(ctx, ISA_MIPS32);
6af0bf9c 6990 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6991 MIPS_INVAL(opn);
6af0bf9c
FB
6992 generate_exception(ctx, EXCP_RI);
6993 } else {
895c2d04 6994 gen_helper_deret(cpu_env);
6af0bf9c
FB
6995 ctx->bstate = BS_EXCP;
6996 }
6997 break;
4ad40f36
FB
6998 case OPC_WAIT:
6999 opn = "wait";
d75c135e 7000 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
7001 /* If we get an exception, we want to restart at next instruction */
7002 ctx->pc += 4;
7003 save_cpu_state(ctx, 1);
7004 ctx->pc -= 4;
895c2d04 7005 gen_helper_wait(cpu_env);
4ad40f36
FB
7006 ctx->bstate = BS_EXCP;
7007 break;
6af0bf9c 7008 default:
29929e34 7009 die:
923617a3 7010 MIPS_INVAL(opn);
6af0bf9c
FB
7011 generate_exception(ctx, EXCP_RI);
7012 return;
7013 }
2abf314d 7014 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7015 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7016}
f1aa6320 7017#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7018
6ea83fed 7019/* CP1 Branches (before delay slot) */
d75c135e
AJ
7020static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7021 int32_t cc, int32_t offset)
6ea83fed
FB
7022{
7023 target_ulong btarget;
923617a3 7024 const char *opn = "cp1 cond branch";
a7812ae4 7025 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7026
e189e748 7027 if (cc != 0)
d75c135e 7028 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7029
6ea83fed
FB
7030 btarget = ctx->pc + 4 + offset;
7031
7a387fff
TS
7032 switch (op) {
7033 case OPC_BC1F:
d94536f4
AJ
7034 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7035 tcg_gen_not_i32(t0, t0);
7036 tcg_gen_andi_i32(t0, t0, 1);
7037 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7038 opn = "bc1f";
6ea83fed 7039 goto not_likely;
7a387fff 7040 case OPC_BC1FL:
d94536f4
AJ
7041 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7042 tcg_gen_not_i32(t0, t0);
7043 tcg_gen_andi_i32(t0, t0, 1);
7044 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7045 opn = "bc1fl";
6ea83fed 7046 goto likely;
7a387fff 7047 case OPC_BC1T:
d94536f4
AJ
7048 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7049 tcg_gen_andi_i32(t0, t0, 1);
7050 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7051 opn = "bc1t";
5a5012ec 7052 goto not_likely;
7a387fff 7053 case OPC_BC1TL:
d94536f4
AJ
7054 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7055 tcg_gen_andi_i32(t0, t0, 1);
7056 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7057 opn = "bc1tl";
6ea83fed
FB
7058 likely:
7059 ctx->hflags |= MIPS_HFLAG_BL;
7060 break;
5a5012ec 7061 case OPC_BC1FANY2:
a16336e4 7062 {
d94536f4
AJ
7063 TCGv_i32 t1 = tcg_temp_new_i32();
7064 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7065 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7066 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7067 tcg_temp_free_i32(t1);
d94536f4
AJ
7068 tcg_gen_andi_i32(t0, t0, 1);
7069 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7070 }
fd4a04eb 7071 opn = "bc1any2f";
5a5012ec
TS
7072 goto not_likely;
7073 case OPC_BC1TANY2:
a16336e4 7074 {
d94536f4
AJ
7075 TCGv_i32 t1 = tcg_temp_new_i32();
7076 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7077 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7078 tcg_gen_or_i32(t0, t0, t1);
7079 tcg_temp_free_i32(t1);
7080 tcg_gen_andi_i32(t0, t0, 1);
7081 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7082 }
fd4a04eb 7083 opn = "bc1any2t";
5a5012ec
TS
7084 goto not_likely;
7085 case OPC_BC1FANY4:
a16336e4 7086 {
d94536f4
AJ
7087 TCGv_i32 t1 = tcg_temp_new_i32();
7088 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7089 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7090 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7091 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7092 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7093 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7094 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7095 tcg_temp_free_i32(t1);
d94536f4
AJ
7096 tcg_gen_andi_i32(t0, t0, 1);
7097 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7098 }
fd4a04eb 7099 opn = "bc1any4f";
5a5012ec
TS
7100 goto not_likely;
7101 case OPC_BC1TANY4:
a16336e4 7102 {
d94536f4
AJ
7103 TCGv_i32 t1 = tcg_temp_new_i32();
7104 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7105 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7106 tcg_gen_or_i32(t0, t0, t1);
7107 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7108 tcg_gen_or_i32(t0, t0, t1);
7109 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7110 tcg_gen_or_i32(t0, t0, t1);
7111 tcg_temp_free_i32(t1);
7112 tcg_gen_andi_i32(t0, t0, 1);
7113 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7114 }
fd4a04eb 7115 opn = "bc1any4t";
5a5012ec
TS
7116 not_likely:
7117 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7118 break;
7119 default:
923617a3 7120 MIPS_INVAL(opn);
e397ee33 7121 generate_exception (ctx, EXCP_RI);
6c5c1e20 7122 goto out;
6ea83fed 7123 }
2abf314d 7124 (void)opn; /* avoid a compiler warning */
923617a3 7125 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7126 ctx->hflags, btarget);
7127 ctx->btarget = btarget;
6c5c1e20
TS
7128
7129 out:
a7812ae4 7130 tcg_temp_free_i32(t0);
6ea83fed
FB
7131}
7132
6af0bf9c 7133/* Coprocessor 1 (FPU) */
5a5012ec 7134
5a5012ec
TS
7135#define FOP(func, fmt) (((fmt) << 21) | (func))
7136
bf4120ad
NF
7137enum fopcode {
7138 OPC_ADD_S = FOP(0, FMT_S),
7139 OPC_SUB_S = FOP(1, FMT_S),
7140 OPC_MUL_S = FOP(2, FMT_S),
7141 OPC_DIV_S = FOP(3, FMT_S),
7142 OPC_SQRT_S = FOP(4, FMT_S),
7143 OPC_ABS_S = FOP(5, FMT_S),
7144 OPC_MOV_S = FOP(6, FMT_S),
7145 OPC_NEG_S = FOP(7, FMT_S),
7146 OPC_ROUND_L_S = FOP(8, FMT_S),
7147 OPC_TRUNC_L_S = FOP(9, FMT_S),
7148 OPC_CEIL_L_S = FOP(10, FMT_S),
7149 OPC_FLOOR_L_S = FOP(11, FMT_S),
7150 OPC_ROUND_W_S = FOP(12, FMT_S),
7151 OPC_TRUNC_W_S = FOP(13, FMT_S),
7152 OPC_CEIL_W_S = FOP(14, FMT_S),
7153 OPC_FLOOR_W_S = FOP(15, FMT_S),
7154 OPC_MOVCF_S = FOP(17, FMT_S),
7155 OPC_MOVZ_S = FOP(18, FMT_S),
7156 OPC_MOVN_S = FOP(19, FMT_S),
7157 OPC_RECIP_S = FOP(21, FMT_S),
7158 OPC_RSQRT_S = FOP(22, FMT_S),
7159 OPC_RECIP2_S = FOP(28, FMT_S),
7160 OPC_RECIP1_S = FOP(29, FMT_S),
7161 OPC_RSQRT1_S = FOP(30, FMT_S),
7162 OPC_RSQRT2_S = FOP(31, FMT_S),
7163 OPC_CVT_D_S = FOP(33, FMT_S),
7164 OPC_CVT_W_S = FOP(36, FMT_S),
7165 OPC_CVT_L_S = FOP(37, FMT_S),
7166 OPC_CVT_PS_S = FOP(38, FMT_S),
7167 OPC_CMP_F_S = FOP (48, FMT_S),
7168 OPC_CMP_UN_S = FOP (49, FMT_S),
7169 OPC_CMP_EQ_S = FOP (50, FMT_S),
7170 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7171 OPC_CMP_OLT_S = FOP (52, FMT_S),
7172 OPC_CMP_ULT_S = FOP (53, FMT_S),
7173 OPC_CMP_OLE_S = FOP (54, FMT_S),
7174 OPC_CMP_ULE_S = FOP (55, FMT_S),
7175 OPC_CMP_SF_S = FOP (56, FMT_S),
7176 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7177 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7178 OPC_CMP_NGL_S = FOP (59, FMT_S),
7179 OPC_CMP_LT_S = FOP (60, FMT_S),
7180 OPC_CMP_NGE_S = FOP (61, FMT_S),
7181 OPC_CMP_LE_S = FOP (62, FMT_S),
7182 OPC_CMP_NGT_S = FOP (63, FMT_S),
7183
7184 OPC_ADD_D = FOP(0, FMT_D),
7185 OPC_SUB_D = FOP(1, FMT_D),
7186 OPC_MUL_D = FOP(2, FMT_D),
7187 OPC_DIV_D = FOP(3, FMT_D),
7188 OPC_SQRT_D = FOP(4, FMT_D),
7189 OPC_ABS_D = FOP(5, FMT_D),
7190 OPC_MOV_D = FOP(6, FMT_D),
7191 OPC_NEG_D = FOP(7, FMT_D),
7192 OPC_ROUND_L_D = FOP(8, FMT_D),
7193 OPC_TRUNC_L_D = FOP(9, FMT_D),
7194 OPC_CEIL_L_D = FOP(10, FMT_D),
7195 OPC_FLOOR_L_D = FOP(11, FMT_D),
7196 OPC_ROUND_W_D = FOP(12, FMT_D),
7197 OPC_TRUNC_W_D = FOP(13, FMT_D),
7198 OPC_CEIL_W_D = FOP(14, FMT_D),
7199 OPC_FLOOR_W_D = FOP(15, FMT_D),
7200 OPC_MOVCF_D = FOP(17, FMT_D),
7201 OPC_MOVZ_D = FOP(18, FMT_D),
7202 OPC_MOVN_D = FOP(19, FMT_D),
7203 OPC_RECIP_D = FOP(21, FMT_D),
7204 OPC_RSQRT_D = FOP(22, FMT_D),
7205 OPC_RECIP2_D = FOP(28, FMT_D),
7206 OPC_RECIP1_D = FOP(29, FMT_D),
7207 OPC_RSQRT1_D = FOP(30, FMT_D),
7208 OPC_RSQRT2_D = FOP(31, FMT_D),
7209 OPC_CVT_S_D = FOP(32, FMT_D),
7210 OPC_CVT_W_D = FOP(36, FMT_D),
7211 OPC_CVT_L_D = FOP(37, FMT_D),
7212 OPC_CMP_F_D = FOP (48, FMT_D),
7213 OPC_CMP_UN_D = FOP (49, FMT_D),
7214 OPC_CMP_EQ_D = FOP (50, FMT_D),
7215 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7216 OPC_CMP_OLT_D = FOP (52, FMT_D),
7217 OPC_CMP_ULT_D = FOP (53, FMT_D),
7218 OPC_CMP_OLE_D = FOP (54, FMT_D),
7219 OPC_CMP_ULE_D = FOP (55, FMT_D),
7220 OPC_CMP_SF_D = FOP (56, FMT_D),
7221 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7222 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7223 OPC_CMP_NGL_D = FOP (59, FMT_D),
7224 OPC_CMP_LT_D = FOP (60, FMT_D),
7225 OPC_CMP_NGE_D = FOP (61, FMT_D),
7226 OPC_CMP_LE_D = FOP (62, FMT_D),
7227 OPC_CMP_NGT_D = FOP (63, FMT_D),
7228
7229 OPC_CVT_S_W = FOP(32, FMT_W),
7230 OPC_CVT_D_W = FOP(33, FMT_W),
7231 OPC_CVT_S_L = FOP(32, FMT_L),
7232 OPC_CVT_D_L = FOP(33, FMT_L),
7233 OPC_CVT_PS_PW = FOP(38, FMT_W),
7234
7235 OPC_ADD_PS = FOP(0, FMT_PS),
7236 OPC_SUB_PS = FOP(1, FMT_PS),
7237 OPC_MUL_PS = FOP(2, FMT_PS),
7238 OPC_DIV_PS = FOP(3, FMT_PS),
7239 OPC_ABS_PS = FOP(5, FMT_PS),
7240 OPC_MOV_PS = FOP(6, FMT_PS),
7241 OPC_NEG_PS = FOP(7, FMT_PS),
7242 OPC_MOVCF_PS = FOP(17, FMT_PS),
7243 OPC_MOVZ_PS = FOP(18, FMT_PS),
7244 OPC_MOVN_PS = FOP(19, FMT_PS),
7245 OPC_ADDR_PS = FOP(24, FMT_PS),
7246 OPC_MULR_PS = FOP(26, FMT_PS),
7247 OPC_RECIP2_PS = FOP(28, FMT_PS),
7248 OPC_RECIP1_PS = FOP(29, FMT_PS),
7249 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7250 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7251
7252 OPC_CVT_S_PU = FOP(32, FMT_PS),
7253 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7254 OPC_CVT_S_PL = FOP(40, FMT_PS),
7255 OPC_PLL_PS = FOP(44, FMT_PS),
7256 OPC_PLU_PS = FOP(45, FMT_PS),
7257 OPC_PUL_PS = FOP(46, FMT_PS),
7258 OPC_PUU_PS = FOP(47, FMT_PS),
7259 OPC_CMP_F_PS = FOP (48, FMT_PS),
7260 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7261 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7262 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7263 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7264 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7265 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7266 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7267 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7268 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7269 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7270 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7271 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7272 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7273 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7274 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7275};
7276
7a387fff 7277static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7278{
923617a3 7279 const char *opn = "cp1 move";
72c3a3ee 7280 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7281
7282 switch (opc) {
7283 case OPC_MFC1:
b6d96bed 7284 {
a7812ae4 7285 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7286
7287 gen_load_fpr32(fp0, fs);
7288 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7289 tcg_temp_free_i32(fp0);
6958549d 7290 }
6c5c1e20 7291 gen_store_gpr(t0, rt);
6ea83fed
FB
7292 opn = "mfc1";
7293 break;
7294 case OPC_MTC1:
6c5c1e20 7295 gen_load_gpr(t0, rt);
b6d96bed 7296 {
a7812ae4 7297 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7298
7299 tcg_gen_trunc_tl_i32(fp0, t0);
7300 gen_store_fpr32(fp0, fs);
a7812ae4 7301 tcg_temp_free_i32(fp0);
6958549d 7302 }
6ea83fed
FB
7303 opn = "mtc1";
7304 break;
7305 case OPC_CFC1:
895c2d04 7306 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7307 gen_store_gpr(t0, rt);
6ea83fed
FB
7308 opn = "cfc1";
7309 break;
7310 case OPC_CTC1:
6c5c1e20 7311 gen_load_gpr(t0, rt);
736d120a
PJ
7312 {
7313 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7314
7315 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7316 tcg_temp_free_i32(fs_tmp);
7317 }
6ea83fed
FB
7318 opn = "ctc1";
7319 break;
72c3a3ee 7320#if defined(TARGET_MIPS64)
9c2149c8 7321 case OPC_DMFC1:
72c3a3ee 7322 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7323 gen_store_gpr(t0, rt);
5a5012ec
TS
7324 opn = "dmfc1";
7325 break;
9c2149c8 7326 case OPC_DMTC1:
6c5c1e20 7327 gen_load_gpr(t0, rt);
72c3a3ee 7328 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7329 opn = "dmtc1";
7330 break;
72c3a3ee 7331#endif
5a5012ec 7332 case OPC_MFHC1:
b6d96bed 7333 {
a7812ae4 7334 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7335
7f6613ce 7336 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 7337 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7338 tcg_temp_free_i32(fp0);
6958549d 7339 }
6c5c1e20 7340 gen_store_gpr(t0, rt);
5a5012ec
TS
7341 opn = "mfhc1";
7342 break;
7343 case OPC_MTHC1:
6c5c1e20 7344 gen_load_gpr(t0, rt);
b6d96bed 7345 {
a7812ae4 7346 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7347
7348 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7349 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 7350 tcg_temp_free_i32(fp0);
6958549d 7351 }
5a5012ec
TS
7352 opn = "mthc1";
7353 break;
6ea83fed 7354 default:
923617a3 7355 MIPS_INVAL(opn);
e397ee33 7356 generate_exception (ctx, EXCP_RI);
6c5c1e20 7357 goto out;
6ea83fed 7358 }
2abf314d 7359 (void)opn; /* avoid a compiler warning */
6ea83fed 7360 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7361
7362 out:
7363 tcg_temp_free(t0);
6ea83fed
FB
7364}
7365
5a5012ec
TS
7366static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7367{
af58f9ca 7368 int l1;
e214b9bb 7369 TCGCond cond;
af58f9ca
AJ
7370 TCGv_i32 t0;
7371
7372 if (rd == 0) {
7373 /* Treat as NOP. */
7374 return;
7375 }
6ea83fed 7376
e214b9bb 7377 if (tf)
e214b9bb 7378 cond = TCG_COND_EQ;
27848470
TS
7379 else
7380 cond = TCG_COND_NE;
7381
af58f9ca
AJ
7382 l1 = gen_new_label();
7383 t0 = tcg_temp_new_i32();
fa31af0e 7384 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7385 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7386 tcg_temp_free_i32(t0);
af58f9ca
AJ
7387 if (rs == 0) {
7388 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7389 } else {
7390 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7391 }
e214b9bb 7392 gen_set_label(l1);
5a5012ec
TS
7393}
7394
b6d96bed 7395static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7396{
a16336e4 7397 int cond;
cbc37b28 7398 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7399 int l1 = gen_new_label();
7400
a16336e4
TS
7401 if (tf)
7402 cond = TCG_COND_EQ;
7403 else
7404 cond = TCG_COND_NE;
7405
fa31af0e 7406 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7407 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7408 gen_load_fpr32(t0, fs);
7409 gen_store_fpr32(t0, fd);
a16336e4 7410 gen_set_label(l1);
cbc37b28 7411 tcg_temp_free_i32(t0);
5a5012ec 7412}
a16336e4 7413
b6d96bed 7414static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7415{
a16336e4 7416 int cond;
cbc37b28
AJ
7417 TCGv_i32 t0 = tcg_temp_new_i32();
7418 TCGv_i64 fp0;
a16336e4
TS
7419 int l1 = gen_new_label();
7420
a16336e4
TS
7421 if (tf)
7422 cond = TCG_COND_EQ;
7423 else
7424 cond = TCG_COND_NE;
7425
fa31af0e 7426 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7427 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7428 tcg_temp_free_i32(t0);
11f94258 7429 fp0 = tcg_temp_new_i64();
9bf3eb2c 7430 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7431 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7432 tcg_temp_free_i64(fp0);
cbc37b28 7433 gen_set_label(l1);
a16336e4
TS
7434}
7435
7f6613ce
PJ
7436static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
7437 int cc, int tf)
a16336e4
TS
7438{
7439 int cond;
cbc37b28 7440 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7441 int l1 = gen_new_label();
7442 int l2 = gen_new_label();
7443
7444 if (tf)
7445 cond = TCG_COND_EQ;
7446 else
7447 cond = TCG_COND_NE;
7448
fa31af0e 7449 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7450 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7451 gen_load_fpr32(t0, fs);
7452 gen_store_fpr32(t0, fd);
a16336e4 7453 gen_set_label(l1);
9bf3eb2c 7454
fa31af0e 7455 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 7456 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
7457 gen_load_fpr32h(ctx, t0, fs);
7458 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 7459 tcg_temp_free_i32(t0);
a16336e4 7460 gen_set_label(l2);
a16336e4
TS
7461}
7462
6ea83fed 7463
bf4120ad 7464static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7465 int ft, int fs, int fd, int cc)
6ea83fed 7466{
923617a3 7467 const char *opn = "farith";
6ea83fed
FB
7468 const char *condnames[] = {
7469 "c.f",
7470 "c.un",
7471 "c.eq",
7472 "c.ueq",
7473 "c.olt",
7474 "c.ult",
7475 "c.ole",
7476 "c.ule",
7477 "c.sf",
7478 "c.ngle",
7479 "c.seq",
7480 "c.ngl",
7481 "c.lt",
7482 "c.nge",
7483 "c.le",
7484 "c.ngt",
7485 };
5a1e8ffb
TS
7486 const char *condnames_abs[] = {
7487 "cabs.f",
7488 "cabs.un",
7489 "cabs.eq",
7490 "cabs.ueq",
7491 "cabs.olt",
7492 "cabs.ult",
7493 "cabs.ole",
7494 "cabs.ule",
7495 "cabs.sf",
7496 "cabs.ngle",
7497 "cabs.seq",
7498 "cabs.ngl",
7499 "cabs.lt",
7500 "cabs.nge",
7501 "cabs.le",
7502 "cabs.ngt",
7503 };
7504 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7505 uint32_t func = ctx->opcode & 0x3f;
7506
bf4120ad
NF
7507 switch (op1) {
7508 case OPC_ADD_S:
b6d96bed 7509 {
a7812ae4
PB
7510 TCGv_i32 fp0 = tcg_temp_new_i32();
7511 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7512
7513 gen_load_fpr32(fp0, fs);
7514 gen_load_fpr32(fp1, ft);
895c2d04 7515 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7516 tcg_temp_free_i32(fp1);
b6d96bed 7517 gen_store_fpr32(fp0, fd);
a7812ae4 7518 tcg_temp_free_i32(fp0);
b6d96bed 7519 }
5a5012ec 7520 opn = "add.s";
5a1e8ffb 7521 optype = BINOP;
5a5012ec 7522 break;
bf4120ad 7523 case OPC_SUB_S:
b6d96bed 7524 {
a7812ae4
PB
7525 TCGv_i32 fp0 = tcg_temp_new_i32();
7526 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7527
7528 gen_load_fpr32(fp0, fs);
7529 gen_load_fpr32(fp1, ft);
895c2d04 7530 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7531 tcg_temp_free_i32(fp1);
b6d96bed 7532 gen_store_fpr32(fp0, fd);
a7812ae4 7533 tcg_temp_free_i32(fp0);
b6d96bed 7534 }
5a5012ec 7535 opn = "sub.s";
5a1e8ffb 7536 optype = BINOP;
5a5012ec 7537 break;
bf4120ad 7538 case OPC_MUL_S:
b6d96bed 7539 {
a7812ae4
PB
7540 TCGv_i32 fp0 = tcg_temp_new_i32();
7541 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7542
7543 gen_load_fpr32(fp0, fs);
7544 gen_load_fpr32(fp1, ft);
895c2d04 7545 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7546 tcg_temp_free_i32(fp1);
b6d96bed 7547 gen_store_fpr32(fp0, fd);
a7812ae4 7548 tcg_temp_free_i32(fp0);
b6d96bed 7549 }
5a5012ec 7550 opn = "mul.s";
5a1e8ffb 7551 optype = BINOP;
5a5012ec 7552 break;
bf4120ad 7553 case OPC_DIV_S:
b6d96bed 7554 {
a7812ae4
PB
7555 TCGv_i32 fp0 = tcg_temp_new_i32();
7556 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7557
7558 gen_load_fpr32(fp0, fs);
7559 gen_load_fpr32(fp1, ft);
895c2d04 7560 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7561 tcg_temp_free_i32(fp1);
b6d96bed 7562 gen_store_fpr32(fp0, fd);
a7812ae4 7563 tcg_temp_free_i32(fp0);
b6d96bed 7564 }
5a5012ec 7565 opn = "div.s";
5a1e8ffb 7566 optype = BINOP;
5a5012ec 7567 break;
bf4120ad 7568 case OPC_SQRT_S:
b6d96bed 7569 {
a7812ae4 7570 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7571
7572 gen_load_fpr32(fp0, fs);
895c2d04 7573 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7574 gen_store_fpr32(fp0, fd);
a7812ae4 7575 tcg_temp_free_i32(fp0);
b6d96bed 7576 }
5a5012ec
TS
7577 opn = "sqrt.s";
7578 break;
bf4120ad 7579 case OPC_ABS_S:
b6d96bed 7580 {
a7812ae4 7581 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7582
7583 gen_load_fpr32(fp0, fs);
a7812ae4 7584 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7585 gen_store_fpr32(fp0, fd);
a7812ae4 7586 tcg_temp_free_i32(fp0);
b6d96bed 7587 }
5a5012ec
TS
7588 opn = "abs.s";
7589 break;
bf4120ad 7590 case OPC_MOV_S:
b6d96bed 7591 {
a7812ae4 7592 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7593
7594 gen_load_fpr32(fp0, fs);
7595 gen_store_fpr32(fp0, fd);
a7812ae4 7596 tcg_temp_free_i32(fp0);
b6d96bed 7597 }
5a5012ec
TS
7598 opn = "mov.s";
7599 break;
bf4120ad 7600 case OPC_NEG_S:
b6d96bed 7601 {
a7812ae4 7602 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7603
7604 gen_load_fpr32(fp0, fs);
a7812ae4 7605 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7606 gen_store_fpr32(fp0, fd);
a7812ae4 7607 tcg_temp_free_i32(fp0);
b6d96bed 7608 }
5a5012ec
TS
7609 opn = "neg.s";
7610 break;
bf4120ad 7611 case OPC_ROUND_L_S:
5e755519 7612 check_cp1_64bitmode(ctx);
b6d96bed 7613 {
a7812ae4
PB
7614 TCGv_i32 fp32 = tcg_temp_new_i32();
7615 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7616
7617 gen_load_fpr32(fp32, fs);
895c2d04 7618 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7619 tcg_temp_free_i32(fp32);
b6d96bed 7620 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7621 tcg_temp_free_i64(fp64);
b6d96bed 7622 }
5a5012ec
TS
7623 opn = "round.l.s";
7624 break;
bf4120ad 7625 case OPC_TRUNC_L_S:
5e755519 7626 check_cp1_64bitmode(ctx);
b6d96bed 7627 {
a7812ae4
PB
7628 TCGv_i32 fp32 = tcg_temp_new_i32();
7629 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7630
7631 gen_load_fpr32(fp32, fs);
895c2d04 7632 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7633 tcg_temp_free_i32(fp32);
b6d96bed 7634 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7635 tcg_temp_free_i64(fp64);
b6d96bed 7636 }
5a5012ec
TS
7637 opn = "trunc.l.s";
7638 break;
bf4120ad 7639 case OPC_CEIL_L_S:
5e755519 7640 check_cp1_64bitmode(ctx);
b6d96bed 7641 {
a7812ae4
PB
7642 TCGv_i32 fp32 = tcg_temp_new_i32();
7643 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7644
7645 gen_load_fpr32(fp32, fs);
895c2d04 7646 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7647 tcg_temp_free_i32(fp32);
b6d96bed 7648 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7649 tcg_temp_free_i64(fp64);
b6d96bed 7650 }
5a5012ec
TS
7651 opn = "ceil.l.s";
7652 break;
bf4120ad 7653 case OPC_FLOOR_L_S:
5e755519 7654 check_cp1_64bitmode(ctx);
b6d96bed 7655 {
a7812ae4
PB
7656 TCGv_i32 fp32 = tcg_temp_new_i32();
7657 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7658
7659 gen_load_fpr32(fp32, fs);
895c2d04 7660 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7661 tcg_temp_free_i32(fp32);
b6d96bed 7662 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7663 tcg_temp_free_i64(fp64);
b6d96bed 7664 }
5a5012ec
TS
7665 opn = "floor.l.s";
7666 break;
bf4120ad 7667 case OPC_ROUND_W_S:
b6d96bed 7668 {
a7812ae4 7669 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7670
7671 gen_load_fpr32(fp0, fs);
895c2d04 7672 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7673 gen_store_fpr32(fp0, fd);
a7812ae4 7674 tcg_temp_free_i32(fp0);
b6d96bed 7675 }
5a5012ec
TS
7676 opn = "round.w.s";
7677 break;
bf4120ad 7678 case OPC_TRUNC_W_S:
b6d96bed 7679 {
a7812ae4 7680 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7681
7682 gen_load_fpr32(fp0, fs);
895c2d04 7683 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7684 gen_store_fpr32(fp0, fd);
a7812ae4 7685 tcg_temp_free_i32(fp0);
b6d96bed 7686 }
5a5012ec
TS
7687 opn = "trunc.w.s";
7688 break;
bf4120ad 7689 case OPC_CEIL_W_S:
b6d96bed 7690 {
a7812ae4 7691 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7692
7693 gen_load_fpr32(fp0, fs);
895c2d04 7694 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7695 gen_store_fpr32(fp0, fd);
a7812ae4 7696 tcg_temp_free_i32(fp0);
b6d96bed 7697 }
5a5012ec
TS
7698 opn = "ceil.w.s";
7699 break;
bf4120ad 7700 case OPC_FLOOR_W_S:
b6d96bed 7701 {
a7812ae4 7702 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7703
7704 gen_load_fpr32(fp0, fs);
895c2d04 7705 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7706 gen_store_fpr32(fp0, fd);
a7812ae4 7707 tcg_temp_free_i32(fp0);
b6d96bed 7708 }
5a5012ec
TS
7709 opn = "floor.w.s";
7710 break;
bf4120ad 7711 case OPC_MOVCF_S:
b6d96bed 7712 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7713 opn = "movcf.s";
7714 break;
bf4120ad 7715 case OPC_MOVZ_S:
a16336e4
TS
7716 {
7717 int l1 = gen_new_label();
c9297f4d 7718 TCGv_i32 fp0;
a16336e4 7719
c9297f4d
AJ
7720 if (ft != 0) {
7721 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7722 }
7723 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7724 gen_load_fpr32(fp0, fs);
7725 gen_store_fpr32(fp0, fd);
a7812ae4 7726 tcg_temp_free_i32(fp0);
a16336e4
TS
7727 gen_set_label(l1);
7728 }
5a5012ec
TS
7729 opn = "movz.s";
7730 break;
bf4120ad 7731 case OPC_MOVN_S:
a16336e4
TS
7732 {
7733 int l1 = gen_new_label();
c9297f4d
AJ
7734 TCGv_i32 fp0;
7735
7736 if (ft != 0) {
7737 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7738 fp0 = tcg_temp_new_i32();
7739 gen_load_fpr32(fp0, fs);
7740 gen_store_fpr32(fp0, fd);
7741 tcg_temp_free_i32(fp0);
7742 gen_set_label(l1);
7743 }
a16336e4 7744 }
5a5012ec
TS
7745 opn = "movn.s";
7746 break;
bf4120ad 7747 case OPC_RECIP_S:
b8aa4598 7748 check_cop1x(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_recip_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 = "recip.s";
7758 break;
bf4120ad 7759 case OPC_RSQRT_S:
b8aa4598 7760 check_cop1x(ctx);
b6d96bed 7761 {
a7812ae4 7762 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7763
7764 gen_load_fpr32(fp0, fs);
895c2d04 7765 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7766 gen_store_fpr32(fp0, fd);
a7812ae4 7767 tcg_temp_free_i32(fp0);
b6d96bed 7768 }
57fa1fb3
TS
7769 opn = "rsqrt.s";
7770 break;
bf4120ad 7771 case OPC_RECIP2_S:
5e755519 7772 check_cp1_64bitmode(ctx);
b6d96bed 7773 {
a7812ae4
PB
7774 TCGv_i32 fp0 = tcg_temp_new_i32();
7775 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7776
7777 gen_load_fpr32(fp0, fs);
d22d7289 7778 gen_load_fpr32(fp1, ft);
895c2d04 7779 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7780 tcg_temp_free_i32(fp1);
b6d96bed 7781 gen_store_fpr32(fp0, fd);
a7812ae4 7782 tcg_temp_free_i32(fp0);
b6d96bed 7783 }
57fa1fb3
TS
7784 opn = "recip2.s";
7785 break;
bf4120ad 7786 case OPC_RECIP1_S:
5e755519 7787 check_cp1_64bitmode(ctx);
b6d96bed 7788 {
a7812ae4 7789 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7790
7791 gen_load_fpr32(fp0, fs);
895c2d04 7792 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7793 gen_store_fpr32(fp0, fd);
a7812ae4 7794 tcg_temp_free_i32(fp0);
b6d96bed 7795 }
57fa1fb3
TS
7796 opn = "recip1.s";
7797 break;
bf4120ad 7798 case OPC_RSQRT1_S:
5e755519 7799 check_cp1_64bitmode(ctx);
b6d96bed 7800 {
a7812ae4 7801 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7802
7803 gen_load_fpr32(fp0, fs);
895c2d04 7804 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7805 gen_store_fpr32(fp0, fd);
a7812ae4 7806 tcg_temp_free_i32(fp0);
b6d96bed 7807 }
57fa1fb3
TS
7808 opn = "rsqrt1.s";
7809 break;
bf4120ad 7810 case OPC_RSQRT2_S:
5e755519 7811 check_cp1_64bitmode(ctx);
b6d96bed 7812 {
a7812ae4
PB
7813 TCGv_i32 fp0 = tcg_temp_new_i32();
7814 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7815
7816 gen_load_fpr32(fp0, fs);
7817 gen_load_fpr32(fp1, ft);
895c2d04 7818 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7819 tcg_temp_free_i32(fp1);
b6d96bed 7820 gen_store_fpr32(fp0, fd);
a7812ae4 7821 tcg_temp_free_i32(fp0);
b6d96bed 7822 }
57fa1fb3
TS
7823 opn = "rsqrt2.s";
7824 break;
bf4120ad 7825 case OPC_CVT_D_S:
5e755519 7826 check_cp1_registers(ctx, fd);
b6d96bed 7827 {
a7812ae4
PB
7828 TCGv_i32 fp32 = tcg_temp_new_i32();
7829 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7830
7831 gen_load_fpr32(fp32, fs);
895c2d04 7832 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7833 tcg_temp_free_i32(fp32);
b6d96bed 7834 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7835 tcg_temp_free_i64(fp64);
b6d96bed 7836 }
5a5012ec
TS
7837 opn = "cvt.d.s";
7838 break;
bf4120ad 7839 case OPC_CVT_W_S:
b6d96bed 7840 {
a7812ae4 7841 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7842
7843 gen_load_fpr32(fp0, fs);
895c2d04 7844 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7845 gen_store_fpr32(fp0, fd);
a7812ae4 7846 tcg_temp_free_i32(fp0);
b6d96bed 7847 }
5a5012ec
TS
7848 opn = "cvt.w.s";
7849 break;
bf4120ad 7850 case OPC_CVT_L_S:
5e755519 7851 check_cp1_64bitmode(ctx);
b6d96bed 7852 {
a7812ae4
PB
7853 TCGv_i32 fp32 = tcg_temp_new_i32();
7854 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7855
7856 gen_load_fpr32(fp32, fs);
895c2d04 7857 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7858 tcg_temp_free_i32(fp32);
b6d96bed 7859 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7860 tcg_temp_free_i64(fp64);
b6d96bed 7861 }
5a5012ec
TS
7862 opn = "cvt.l.s";
7863 break;
bf4120ad 7864 case OPC_CVT_PS_S:
5e755519 7865 check_cp1_64bitmode(ctx);
b6d96bed 7866 {
a7812ae4
PB
7867 TCGv_i64 fp64 = tcg_temp_new_i64();
7868 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7869 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7870
7871 gen_load_fpr32(fp32_0, fs);
7872 gen_load_fpr32(fp32_1, ft);
13d24f49 7873 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7874 tcg_temp_free_i32(fp32_1);
7875 tcg_temp_free_i32(fp32_0);
36aa55dc 7876 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7877 tcg_temp_free_i64(fp64);
b6d96bed 7878 }
5a5012ec
TS
7879 opn = "cvt.ps.s";
7880 break;
bf4120ad
NF
7881 case OPC_CMP_F_S:
7882 case OPC_CMP_UN_S:
7883 case OPC_CMP_EQ_S:
7884 case OPC_CMP_UEQ_S:
7885 case OPC_CMP_OLT_S:
7886 case OPC_CMP_ULT_S:
7887 case OPC_CMP_OLE_S:
7888 case OPC_CMP_ULE_S:
7889 case OPC_CMP_SF_S:
7890 case OPC_CMP_NGLE_S:
7891 case OPC_CMP_SEQ_S:
7892 case OPC_CMP_NGL_S:
7893 case OPC_CMP_LT_S:
7894 case OPC_CMP_NGE_S:
7895 case OPC_CMP_LE_S:
7896 case OPC_CMP_NGT_S:
8153667c
NF
7897 if (ctx->opcode & (1 << 6)) {
7898 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7899 opn = condnames_abs[func-48];
7900 } else {
7901 gen_cmp_s(ctx, func-48, ft, fs, cc);
7902 opn = condnames[func-48];
5a1e8ffb 7903 }
5a5012ec 7904 break;
bf4120ad 7905 case OPC_ADD_D:
5e755519 7906 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7907 {
a7812ae4
PB
7908 TCGv_i64 fp0 = tcg_temp_new_i64();
7909 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7910
7911 gen_load_fpr64(ctx, fp0, fs);
7912 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7913 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7914 tcg_temp_free_i64(fp1);
b6d96bed 7915 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7916 tcg_temp_free_i64(fp0);
b6d96bed 7917 }
6ea83fed 7918 opn = "add.d";
5a1e8ffb 7919 optype = BINOP;
6ea83fed 7920 break;
bf4120ad 7921 case OPC_SUB_D:
5e755519 7922 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7923 {
a7812ae4
PB
7924 TCGv_i64 fp0 = tcg_temp_new_i64();
7925 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7926
7927 gen_load_fpr64(ctx, fp0, fs);
7928 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7929 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7930 tcg_temp_free_i64(fp1);
b6d96bed 7931 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7932 tcg_temp_free_i64(fp0);
b6d96bed 7933 }
6ea83fed 7934 opn = "sub.d";
5a1e8ffb 7935 optype = BINOP;
6ea83fed 7936 break;
bf4120ad 7937 case OPC_MUL_D:
5e755519 7938 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7939 {
a7812ae4
PB
7940 TCGv_i64 fp0 = tcg_temp_new_i64();
7941 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7942
7943 gen_load_fpr64(ctx, fp0, fs);
7944 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7945 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7946 tcg_temp_free_i64(fp1);
b6d96bed 7947 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7948 tcg_temp_free_i64(fp0);
b6d96bed 7949 }
6ea83fed 7950 opn = "mul.d";
5a1e8ffb 7951 optype = BINOP;
6ea83fed 7952 break;
bf4120ad 7953 case OPC_DIV_D:
5e755519 7954 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7955 {
a7812ae4
PB
7956 TCGv_i64 fp0 = tcg_temp_new_i64();
7957 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7958
7959 gen_load_fpr64(ctx, fp0, fs);
7960 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7961 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7962 tcg_temp_free_i64(fp1);
b6d96bed 7963 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7964 tcg_temp_free_i64(fp0);
b6d96bed 7965 }
6ea83fed 7966 opn = "div.d";
5a1e8ffb 7967 optype = BINOP;
6ea83fed 7968 break;
bf4120ad 7969 case OPC_SQRT_D:
5e755519 7970 check_cp1_registers(ctx, fs | fd);
b6d96bed 7971 {
a7812ae4 7972 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7973
7974 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7975 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7976 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7977 tcg_temp_free_i64(fp0);
b6d96bed 7978 }
6ea83fed
FB
7979 opn = "sqrt.d";
7980 break;
bf4120ad 7981 case OPC_ABS_D:
5e755519 7982 check_cp1_registers(ctx, fs | fd);
b6d96bed 7983 {
a7812ae4 7984 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7985
7986 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7987 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7988 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7989 tcg_temp_free_i64(fp0);
b6d96bed 7990 }
6ea83fed
FB
7991 opn = "abs.d";
7992 break;
bf4120ad 7993 case OPC_MOV_D:
5e755519 7994 check_cp1_registers(ctx, fs | fd);
b6d96bed 7995 {
a7812ae4 7996 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7997
7998 gen_load_fpr64(ctx, fp0, fs);
7999 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8000 tcg_temp_free_i64(fp0);
b6d96bed 8001 }
6ea83fed
FB
8002 opn = "mov.d";
8003 break;
bf4120ad 8004 case OPC_NEG_D:
5e755519 8005 check_cp1_registers(ctx, fs | fd);
b6d96bed 8006 {
a7812ae4 8007 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8008
8009 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8010 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 8011 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8012 tcg_temp_free_i64(fp0);
b6d96bed 8013 }
6ea83fed
FB
8014 opn = "neg.d";
8015 break;
bf4120ad 8016 case OPC_ROUND_L_D:
5e755519 8017 check_cp1_64bitmode(ctx);
b6d96bed 8018 {
a7812ae4 8019 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8020
8021 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8022 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 8023 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8024 tcg_temp_free_i64(fp0);
b6d96bed 8025 }
5a5012ec
TS
8026 opn = "round.l.d";
8027 break;
bf4120ad 8028 case OPC_TRUNC_L_D:
5e755519 8029 check_cp1_64bitmode(ctx);
b6d96bed 8030 {
a7812ae4 8031 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8032
8033 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8034 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 8035 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8036 tcg_temp_free_i64(fp0);
b6d96bed 8037 }
5a5012ec
TS
8038 opn = "trunc.l.d";
8039 break;
bf4120ad 8040 case OPC_CEIL_L_D:
5e755519 8041 check_cp1_64bitmode(ctx);
b6d96bed 8042 {
a7812ae4 8043 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8044
8045 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8046 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8047 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8048 tcg_temp_free_i64(fp0);
b6d96bed 8049 }
5a5012ec
TS
8050 opn = "ceil.l.d";
8051 break;
bf4120ad 8052 case OPC_FLOOR_L_D:
5e755519 8053 check_cp1_64bitmode(ctx);
b6d96bed 8054 {
a7812ae4 8055 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8056
8057 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8058 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8059 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8060 tcg_temp_free_i64(fp0);
b6d96bed 8061 }
5a5012ec
TS
8062 opn = "floor.l.d";
8063 break;
bf4120ad 8064 case OPC_ROUND_W_D:
5e755519 8065 check_cp1_registers(ctx, fs);
b6d96bed 8066 {
a7812ae4
PB
8067 TCGv_i32 fp32 = tcg_temp_new_i32();
8068 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8069
8070 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8071 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8072 tcg_temp_free_i64(fp64);
b6d96bed 8073 gen_store_fpr32(fp32, fd);
a7812ae4 8074 tcg_temp_free_i32(fp32);
b6d96bed 8075 }
6ea83fed
FB
8076 opn = "round.w.d";
8077 break;
bf4120ad 8078 case OPC_TRUNC_W_D:
5e755519 8079 check_cp1_registers(ctx, fs);
b6d96bed 8080 {
a7812ae4
PB
8081 TCGv_i32 fp32 = tcg_temp_new_i32();
8082 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8083
8084 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8085 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8086 tcg_temp_free_i64(fp64);
b6d96bed 8087 gen_store_fpr32(fp32, fd);
a7812ae4 8088 tcg_temp_free_i32(fp32);
b6d96bed 8089 }
6ea83fed
FB
8090 opn = "trunc.w.d";
8091 break;
bf4120ad 8092 case OPC_CEIL_W_D:
5e755519 8093 check_cp1_registers(ctx, fs);
b6d96bed 8094 {
a7812ae4
PB
8095 TCGv_i32 fp32 = tcg_temp_new_i32();
8096 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8097
8098 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8099 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8100 tcg_temp_free_i64(fp64);
b6d96bed 8101 gen_store_fpr32(fp32, fd);
a7812ae4 8102 tcg_temp_free_i32(fp32);
b6d96bed 8103 }
6ea83fed
FB
8104 opn = "ceil.w.d";
8105 break;
bf4120ad 8106 case OPC_FLOOR_W_D:
5e755519 8107 check_cp1_registers(ctx, fs);
b6d96bed 8108 {
a7812ae4
PB
8109 TCGv_i32 fp32 = tcg_temp_new_i32();
8110 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8111
8112 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8113 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8114 tcg_temp_free_i64(fp64);
b6d96bed 8115 gen_store_fpr32(fp32, fd);
a7812ae4 8116 tcg_temp_free_i32(fp32);
b6d96bed 8117 }
7a387fff 8118 opn = "floor.w.d";
6ea83fed 8119 break;
bf4120ad 8120 case OPC_MOVCF_D:
b6d96bed 8121 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8122 opn = "movcf.d";
dd016883 8123 break;
bf4120ad 8124 case OPC_MOVZ_D:
a16336e4
TS
8125 {
8126 int l1 = gen_new_label();
c9297f4d 8127 TCGv_i64 fp0;
a16336e4 8128
c9297f4d
AJ
8129 if (ft != 0) {
8130 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8131 }
8132 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8133 gen_load_fpr64(ctx, fp0, fs);
8134 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8135 tcg_temp_free_i64(fp0);
a16336e4
TS
8136 gen_set_label(l1);
8137 }
5a5012ec
TS
8138 opn = "movz.d";
8139 break;
bf4120ad 8140 case OPC_MOVN_D:
a16336e4
TS
8141 {
8142 int l1 = gen_new_label();
c9297f4d
AJ
8143 TCGv_i64 fp0;
8144
8145 if (ft != 0) {
8146 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8147 fp0 = tcg_temp_new_i64();
8148 gen_load_fpr64(ctx, fp0, fs);
8149 gen_store_fpr64(ctx, fp0, fd);
8150 tcg_temp_free_i64(fp0);
8151 gen_set_label(l1);
8152 }
a16336e4 8153 }
5a5012ec 8154 opn = "movn.d";
6ea83fed 8155 break;
bf4120ad 8156 case OPC_RECIP_D:
b8aa4598 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_recip_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 = "recip.d";
8167 break;
bf4120ad 8168 case OPC_RSQRT_D:
b8aa4598 8169 check_cp1_64bitmode(ctx);
b6d96bed 8170 {
a7812ae4 8171 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8172
8173 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8174 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8175 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8176 tcg_temp_free_i64(fp0);
b6d96bed 8177 }
57fa1fb3
TS
8178 opn = "rsqrt.d";
8179 break;
bf4120ad 8180 case OPC_RECIP2_D:
5e755519 8181 check_cp1_64bitmode(ctx);
b6d96bed 8182 {
a7812ae4
PB
8183 TCGv_i64 fp0 = tcg_temp_new_i64();
8184 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8185
8186 gen_load_fpr64(ctx, fp0, fs);
8187 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8188 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8189 tcg_temp_free_i64(fp1);
b6d96bed 8190 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8191 tcg_temp_free_i64(fp0);
b6d96bed 8192 }
57fa1fb3
TS
8193 opn = "recip2.d";
8194 break;
bf4120ad 8195 case OPC_RECIP1_D:
5e755519 8196 check_cp1_64bitmode(ctx);
b6d96bed 8197 {
a7812ae4 8198 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8199
8200 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8201 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8202 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8203 tcg_temp_free_i64(fp0);
b6d96bed 8204 }
57fa1fb3
TS
8205 opn = "recip1.d";
8206 break;
bf4120ad 8207 case OPC_RSQRT1_D:
5e755519 8208 check_cp1_64bitmode(ctx);
b6d96bed 8209 {
a7812ae4 8210 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8211
8212 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8213 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8214 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8215 tcg_temp_free_i64(fp0);
b6d96bed 8216 }
57fa1fb3
TS
8217 opn = "rsqrt1.d";
8218 break;
bf4120ad 8219 case OPC_RSQRT2_D:
5e755519 8220 check_cp1_64bitmode(ctx);
b6d96bed 8221 {
a7812ae4
PB
8222 TCGv_i64 fp0 = tcg_temp_new_i64();
8223 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8224
8225 gen_load_fpr64(ctx, fp0, fs);
8226 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8227 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8228 tcg_temp_free_i64(fp1);
b6d96bed 8229 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8230 tcg_temp_free_i64(fp0);
b6d96bed 8231 }
57fa1fb3
TS
8232 opn = "rsqrt2.d";
8233 break;
bf4120ad
NF
8234 case OPC_CMP_F_D:
8235 case OPC_CMP_UN_D:
8236 case OPC_CMP_EQ_D:
8237 case OPC_CMP_UEQ_D:
8238 case OPC_CMP_OLT_D:
8239 case OPC_CMP_ULT_D:
8240 case OPC_CMP_OLE_D:
8241 case OPC_CMP_ULE_D:
8242 case OPC_CMP_SF_D:
8243 case OPC_CMP_NGLE_D:
8244 case OPC_CMP_SEQ_D:
8245 case OPC_CMP_NGL_D:
8246 case OPC_CMP_LT_D:
8247 case OPC_CMP_NGE_D:
8248 case OPC_CMP_LE_D:
8249 case OPC_CMP_NGT_D:
8153667c
NF
8250 if (ctx->opcode & (1 << 6)) {
8251 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8252 opn = condnames_abs[func-48];
8253 } else {
8254 gen_cmp_d(ctx, func-48, ft, fs, cc);
8255 opn = condnames[func-48];
5a1e8ffb 8256 }
6ea83fed 8257 break;
bf4120ad 8258 case OPC_CVT_S_D:
5e755519 8259 check_cp1_registers(ctx, fs);
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_fpr64(ctx, fp64, fs);
895c2d04 8265 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8266 tcg_temp_free_i64(fp64);
b6d96bed 8267 gen_store_fpr32(fp32, fd);
a7812ae4 8268 tcg_temp_free_i32(fp32);
b6d96bed 8269 }
5a5012ec
TS
8270 opn = "cvt.s.d";
8271 break;
bf4120ad 8272 case OPC_CVT_W_D:
5e755519 8273 check_cp1_registers(ctx, fs);
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_cvtw_d(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.w.d";
8285 break;
bf4120ad 8286 case OPC_CVT_L_D:
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_cvtl_d(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.l.d";
8297 break;
bf4120ad 8298 case OPC_CVT_S_W:
b6d96bed 8299 {
a7812ae4 8300 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8301
8302 gen_load_fpr32(fp0, fs);
895c2d04 8303 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8304 gen_store_fpr32(fp0, fd);
a7812ae4 8305 tcg_temp_free_i32(fp0);
b6d96bed 8306 }
5a5012ec 8307 opn = "cvt.s.w";
6ea83fed 8308 break;
bf4120ad 8309 case OPC_CVT_D_W:
5e755519 8310 check_cp1_registers(ctx, fd);
b6d96bed 8311 {
a7812ae4
PB
8312 TCGv_i32 fp32 = tcg_temp_new_i32();
8313 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8314
8315 gen_load_fpr32(fp32, fs);
895c2d04 8316 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8317 tcg_temp_free_i32(fp32);
b6d96bed 8318 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8319 tcg_temp_free_i64(fp64);
b6d96bed 8320 }
5a5012ec
TS
8321 opn = "cvt.d.w";
8322 break;
bf4120ad 8323 case OPC_CVT_S_L:
5e755519 8324 check_cp1_64bitmode(ctx);
b6d96bed 8325 {
a7812ae4
PB
8326 TCGv_i32 fp32 = tcg_temp_new_i32();
8327 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8328
8329 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8330 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8331 tcg_temp_free_i64(fp64);
b6d96bed 8332 gen_store_fpr32(fp32, fd);
a7812ae4 8333 tcg_temp_free_i32(fp32);
b6d96bed 8334 }
5a5012ec
TS
8335 opn = "cvt.s.l";
8336 break;
bf4120ad 8337 case OPC_CVT_D_L:
5e755519 8338 check_cp1_64bitmode(ctx);
b6d96bed 8339 {
a7812ae4 8340 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8341
8342 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8343 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8344 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8345 tcg_temp_free_i64(fp0);
b6d96bed 8346 }
5a5012ec
TS
8347 opn = "cvt.d.l";
8348 break;
bf4120ad 8349 case OPC_CVT_PS_PW:
5e755519 8350 check_cp1_64bitmode(ctx);
b6d96bed 8351 {
a7812ae4 8352 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8353
8354 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8355 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8356 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8357 tcg_temp_free_i64(fp0);
b6d96bed 8358 }
5a5012ec
TS
8359 opn = "cvt.ps.pw";
8360 break;
bf4120ad 8361 case OPC_ADD_PS:
5e755519 8362 check_cp1_64bitmode(ctx);
b6d96bed 8363 {
a7812ae4
PB
8364 TCGv_i64 fp0 = tcg_temp_new_i64();
8365 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8366
8367 gen_load_fpr64(ctx, fp0, fs);
8368 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8369 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8370 tcg_temp_free_i64(fp1);
b6d96bed 8371 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8372 tcg_temp_free_i64(fp0);
b6d96bed 8373 }
5a5012ec 8374 opn = "add.ps";
6ea83fed 8375 break;
bf4120ad 8376 case OPC_SUB_PS:
5e755519 8377 check_cp1_64bitmode(ctx);
b6d96bed 8378 {
a7812ae4
PB
8379 TCGv_i64 fp0 = tcg_temp_new_i64();
8380 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8381
8382 gen_load_fpr64(ctx, fp0, fs);
8383 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8384 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8385 tcg_temp_free_i64(fp1);
b6d96bed 8386 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8387 tcg_temp_free_i64(fp0);
b6d96bed 8388 }
5a5012ec 8389 opn = "sub.ps";
6ea83fed 8390 break;
bf4120ad 8391 case OPC_MUL_PS:
5e755519 8392 check_cp1_64bitmode(ctx);
b6d96bed 8393 {
a7812ae4
PB
8394 TCGv_i64 fp0 = tcg_temp_new_i64();
8395 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8396
8397 gen_load_fpr64(ctx, fp0, fs);
8398 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8399 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8400 tcg_temp_free_i64(fp1);
b6d96bed 8401 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8402 tcg_temp_free_i64(fp0);
b6d96bed 8403 }
5a5012ec 8404 opn = "mul.ps";
6ea83fed 8405 break;
bf4120ad 8406 case OPC_ABS_PS:
5e755519 8407 check_cp1_64bitmode(ctx);
b6d96bed 8408 {
a7812ae4 8409 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8410
8411 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8412 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8413 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8414 tcg_temp_free_i64(fp0);
b6d96bed 8415 }
5a5012ec 8416 opn = "abs.ps";
6ea83fed 8417 break;
bf4120ad 8418 case OPC_MOV_PS:
5e755519 8419 check_cp1_64bitmode(ctx);
b6d96bed 8420 {
a7812ae4 8421 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8422
8423 gen_load_fpr64(ctx, fp0, fs);
8424 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8425 tcg_temp_free_i64(fp0);
b6d96bed 8426 }
5a5012ec 8427 opn = "mov.ps";
6ea83fed 8428 break;
bf4120ad 8429 case OPC_NEG_PS:
5e755519 8430 check_cp1_64bitmode(ctx);
b6d96bed 8431 {
a7812ae4 8432 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8433
8434 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8435 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8436 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8437 tcg_temp_free_i64(fp0);
b6d96bed 8438 }
5a5012ec 8439 opn = "neg.ps";
6ea83fed 8440 break;
bf4120ad 8441 case OPC_MOVCF_PS:
5e755519 8442 check_cp1_64bitmode(ctx);
7f6613ce 8443 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8444 opn = "movcf.ps";
6ea83fed 8445 break;
bf4120ad 8446 case OPC_MOVZ_PS:
5e755519 8447 check_cp1_64bitmode(ctx);
a16336e4
TS
8448 {
8449 int l1 = gen_new_label();
30a3848b 8450 TCGv_i64 fp0;
a16336e4 8451
c9297f4d
AJ
8452 if (ft != 0)
8453 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8454 fp0 = tcg_temp_new_i64();
8455 gen_load_fpr64(ctx, fp0, fs);
8456 gen_store_fpr64(ctx, fp0, fd);
8457 tcg_temp_free_i64(fp0);
a16336e4
TS
8458 gen_set_label(l1);
8459 }
5a5012ec 8460 opn = "movz.ps";
6ea83fed 8461 break;
bf4120ad 8462 case OPC_MOVN_PS:
5e755519 8463 check_cp1_64bitmode(ctx);
a16336e4
TS
8464 {
8465 int l1 = gen_new_label();
30a3848b 8466 TCGv_i64 fp0;
c9297f4d
AJ
8467
8468 if (ft != 0) {
8469 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8470 fp0 = tcg_temp_new_i64();
8471 gen_load_fpr64(ctx, fp0, fs);
8472 gen_store_fpr64(ctx, fp0, fd);
8473 tcg_temp_free_i64(fp0);
8474 gen_set_label(l1);
8475 }
a16336e4 8476 }
5a5012ec 8477 opn = "movn.ps";
6ea83fed 8478 break;
bf4120ad 8479 case OPC_ADDR_PS:
5e755519 8480 check_cp1_64bitmode(ctx);
b6d96bed 8481 {
a7812ae4
PB
8482 TCGv_i64 fp0 = tcg_temp_new_i64();
8483 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8484
8485 gen_load_fpr64(ctx, fp0, ft);
8486 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8487 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8488 tcg_temp_free_i64(fp1);
b6d96bed 8489 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8490 tcg_temp_free_i64(fp0);
b6d96bed 8491 }
fbcc6828
TS
8492 opn = "addr.ps";
8493 break;
bf4120ad 8494 case OPC_MULR_PS:
5e755519 8495 check_cp1_64bitmode(ctx);
b6d96bed 8496 {
a7812ae4
PB
8497 TCGv_i64 fp0 = tcg_temp_new_i64();
8498 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8499
8500 gen_load_fpr64(ctx, fp0, ft);
8501 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8502 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8503 tcg_temp_free_i64(fp1);
b6d96bed 8504 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8505 tcg_temp_free_i64(fp0);
b6d96bed 8506 }
57fa1fb3
TS
8507 opn = "mulr.ps";
8508 break;
bf4120ad 8509 case OPC_RECIP2_PS:
5e755519 8510 check_cp1_64bitmode(ctx);
b6d96bed 8511 {
a7812ae4
PB
8512 TCGv_i64 fp0 = tcg_temp_new_i64();
8513 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8514
8515 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8516 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8517 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8518 tcg_temp_free_i64(fp1);
b6d96bed 8519 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8520 tcg_temp_free_i64(fp0);
b6d96bed 8521 }
57fa1fb3
TS
8522 opn = "recip2.ps";
8523 break;
bf4120ad 8524 case OPC_RECIP1_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_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8531 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8532 tcg_temp_free_i64(fp0);
b6d96bed 8533 }
57fa1fb3
TS
8534 opn = "recip1.ps";
8535 break;
bf4120ad 8536 case OPC_RSQRT1_PS:
5e755519 8537 check_cp1_64bitmode(ctx);
b6d96bed 8538 {
a7812ae4 8539 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8540
8541 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8542 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8543 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8544 tcg_temp_free_i64(fp0);
b6d96bed 8545 }
57fa1fb3
TS
8546 opn = "rsqrt1.ps";
8547 break;
bf4120ad 8548 case OPC_RSQRT2_PS:
5e755519 8549 check_cp1_64bitmode(ctx);
b6d96bed 8550 {
a7812ae4
PB
8551 TCGv_i64 fp0 = tcg_temp_new_i64();
8552 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8553
8554 gen_load_fpr64(ctx, fp0, fs);
8555 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8556 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8557 tcg_temp_free_i64(fp1);
b6d96bed 8558 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8559 tcg_temp_free_i64(fp0);
b6d96bed 8560 }
57fa1fb3
TS
8561 opn = "rsqrt2.ps";
8562 break;
bf4120ad 8563 case OPC_CVT_S_PU:
5e755519 8564 check_cp1_64bitmode(ctx);
b6d96bed 8565 {
a7812ae4 8566 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8567
7f6613ce 8568 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 8569 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8570 gen_store_fpr32(fp0, fd);
a7812ae4 8571 tcg_temp_free_i32(fp0);
b6d96bed 8572 }
5a5012ec 8573 opn = "cvt.s.pu";
dd016883 8574 break;
bf4120ad 8575 case OPC_CVT_PW_PS:
5e755519 8576 check_cp1_64bitmode(ctx);
b6d96bed 8577 {
a7812ae4 8578 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8579
8580 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8581 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8582 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8583 tcg_temp_free_i64(fp0);
b6d96bed 8584 }
5a5012ec 8585 opn = "cvt.pw.ps";
6ea83fed 8586 break;
bf4120ad 8587 case OPC_CVT_S_PL:
5e755519 8588 check_cp1_64bitmode(ctx);
b6d96bed 8589 {
a7812ae4 8590 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8591
8592 gen_load_fpr32(fp0, fs);
895c2d04 8593 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8594 gen_store_fpr32(fp0, fd);
a7812ae4 8595 tcg_temp_free_i32(fp0);
b6d96bed 8596 }
5a5012ec 8597 opn = "cvt.s.pl";
6ea83fed 8598 break;
bf4120ad 8599 case OPC_PLL_PS:
5e755519 8600 check_cp1_64bitmode(ctx);
b6d96bed 8601 {
a7812ae4
PB
8602 TCGv_i32 fp0 = tcg_temp_new_i32();
8603 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8604
8605 gen_load_fpr32(fp0, fs);
8606 gen_load_fpr32(fp1, ft);
7f6613ce 8607 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 8608 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8609 tcg_temp_free_i32(fp0);
8610 tcg_temp_free_i32(fp1);
b6d96bed 8611 }
5a5012ec 8612 opn = "pll.ps";
6ea83fed 8613 break;
bf4120ad 8614 case OPC_PLU_PS:
5e755519 8615 check_cp1_64bitmode(ctx);
b6d96bed 8616 {
a7812ae4
PB
8617 TCGv_i32 fp0 = tcg_temp_new_i32();
8618 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8619
8620 gen_load_fpr32(fp0, fs);
7f6613ce 8621 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 8622 gen_store_fpr32(fp1, fd);
7f6613ce 8623 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8624 tcg_temp_free_i32(fp0);
8625 tcg_temp_free_i32(fp1);
b6d96bed 8626 }
5a5012ec
TS
8627 opn = "plu.ps";
8628 break;
bf4120ad 8629 case OPC_PUL_PS:
5e755519 8630 check_cp1_64bitmode(ctx);
b6d96bed 8631 {
a7812ae4
PB
8632 TCGv_i32 fp0 = tcg_temp_new_i32();
8633 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8634
7f6613ce 8635 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
8636 gen_load_fpr32(fp1, ft);
8637 gen_store_fpr32(fp1, fd);
7f6613ce 8638 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8639 tcg_temp_free_i32(fp0);
8640 tcg_temp_free_i32(fp1);
b6d96bed 8641 }
5a5012ec
TS
8642 opn = "pul.ps";
8643 break;
bf4120ad 8644 case OPC_PUU_PS:
5e755519 8645 check_cp1_64bitmode(ctx);
b6d96bed 8646 {
a7812ae4
PB
8647 TCGv_i32 fp0 = tcg_temp_new_i32();
8648 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8649
7f6613ce
PJ
8650 gen_load_fpr32h(ctx, fp0, fs);
8651 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 8652 gen_store_fpr32(fp1, fd);
7f6613ce 8653 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8654 tcg_temp_free_i32(fp0);
8655 tcg_temp_free_i32(fp1);
b6d96bed 8656 }
5a5012ec
TS
8657 opn = "puu.ps";
8658 break;
bf4120ad
NF
8659 case OPC_CMP_F_PS:
8660 case OPC_CMP_UN_PS:
8661 case OPC_CMP_EQ_PS:
8662 case OPC_CMP_UEQ_PS:
8663 case OPC_CMP_OLT_PS:
8664 case OPC_CMP_ULT_PS:
8665 case OPC_CMP_OLE_PS:
8666 case OPC_CMP_ULE_PS:
8667 case OPC_CMP_SF_PS:
8668 case OPC_CMP_NGLE_PS:
8669 case OPC_CMP_SEQ_PS:
8670 case OPC_CMP_NGL_PS:
8671 case OPC_CMP_LT_PS:
8672 case OPC_CMP_NGE_PS:
8673 case OPC_CMP_LE_PS:
8674 case OPC_CMP_NGT_PS:
8153667c
NF
8675 if (ctx->opcode & (1 << 6)) {
8676 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8677 opn = condnames_abs[func-48];
8678 } else {
8679 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8680 opn = condnames[func-48];
5a1e8ffb 8681 }
6ea83fed 8682 break;
5a5012ec 8683 default:
923617a3 8684 MIPS_INVAL(opn);
e397ee33 8685 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8686 return;
8687 }
2abf314d 8688 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8689 switch (optype) {
8690 case BINOP:
6ea83fed 8691 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8692 break;
8693 case CMPOP:
8694 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8695 break;
8696 default:
6ea83fed 8697 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8698 break;
8699 }
6ea83fed 8700}
6af0bf9c 8701
5a5012ec 8702/* Coprocessor 3 (FPU) */
5e755519
TS
8703static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8704 int fd, int fs, int base, int index)
7a387fff 8705{
923617a3 8706 const char *opn = "extended float load/store";
93b12ccc 8707 int store = 0;
4e2474d6 8708 TCGv t0 = tcg_temp_new();
7a387fff 8709
93b12ccc 8710 if (base == 0) {
6c5c1e20 8711 gen_load_gpr(t0, index);
93b12ccc 8712 } else if (index == 0) {
6c5c1e20 8713 gen_load_gpr(t0, base);
93b12ccc 8714 } else {
05168674 8715 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8716 }
5a5012ec 8717 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8718 memory access. */
5a5012ec
TS
8719 switch (opc) {
8720 case OPC_LWXC1:
8c0ab41f 8721 check_cop1x(ctx);
b6d96bed 8722 {
a7812ae4 8723 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8724
5f68f5ae 8725 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 8726 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8727 gen_store_fpr32(fp0, fd);
a7812ae4 8728 tcg_temp_free_i32(fp0);
b6d96bed 8729 }
5a5012ec
TS
8730 opn = "lwxc1";
8731 break;
8732 case OPC_LDXC1:
8c0ab41f
AJ
8733 check_cop1x(ctx);
8734 check_cp1_registers(ctx, fd);
b6d96bed 8735 {
a7812ae4 8736 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 8737 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 8738 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8739 tcg_temp_free_i64(fp0);
b6d96bed 8740 }
5a5012ec
TS
8741 opn = "ldxc1";
8742 break;
8743 case OPC_LUXC1:
8c0ab41f 8744 check_cp1_64bitmode(ctx);
6c5c1e20 8745 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8746 {
a7812ae4 8747 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8748
5f68f5ae 8749 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 8750 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8751 tcg_temp_free_i64(fp0);
b6d96bed 8752 }
5a5012ec
TS
8753 opn = "luxc1";
8754 break;
8755 case OPC_SWXC1:
8c0ab41f 8756 check_cop1x(ctx);
b6d96bed 8757 {
a7812ae4 8758 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8759 gen_load_fpr32(fp0, fs);
5f68f5ae 8760 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 8761 tcg_temp_free_i32(fp0);
b6d96bed 8762 }
5a5012ec 8763 opn = "swxc1";
93b12ccc 8764 store = 1;
5a5012ec
TS
8765 break;
8766 case OPC_SDXC1:
8c0ab41f
AJ
8767 check_cop1x(ctx);
8768 check_cp1_registers(ctx, fs);
b6d96bed 8769 {
a7812ae4 8770 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8771 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 8772 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 8773 tcg_temp_free_i64(fp0);
b6d96bed 8774 }
5a5012ec 8775 opn = "sdxc1";
93b12ccc 8776 store = 1;
5a5012ec
TS
8777 break;
8778 case OPC_SUXC1:
8c0ab41f 8779 check_cp1_64bitmode(ctx);
6c5c1e20 8780 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8781 {
a7812ae4 8782 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 8783 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 8784 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 8785 tcg_temp_free_i64(fp0);
b6d96bed 8786 }
5a5012ec 8787 opn = "suxc1";
93b12ccc 8788 store = 1;
5a5012ec 8789 break;
5a5012ec 8790 }
6c5c1e20 8791 tcg_temp_free(t0);
2abf314d 8792 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8793 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8794 regnames[index], regnames[base]);
5a5012ec
TS
8795}
8796
5e755519
TS
8797static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8798 int fd, int fr, int fs, int ft)
5a5012ec 8799{
923617a3 8800 const char *opn = "flt3_arith";
5a5012ec 8801
5a5012ec
TS
8802 switch (opc) {
8803 case OPC_ALNV_PS:
b8aa4598 8804 check_cp1_64bitmode(ctx);
a16336e4 8805 {
a7812ae4 8806 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8807 TCGv_i32 fp = tcg_temp_new_i32();
8808 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8809 int l1 = gen_new_label();
8810 int l2 = gen_new_label();
8811
6c5c1e20
TS
8812 gen_load_gpr(t0, fr);
8813 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8814
8815 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 8816 gen_load_fpr32(fp, fs);
7f6613ce 8817 gen_load_fpr32h(ctx, fph, fs);
c905fdac 8818 gen_store_fpr32(fp, fd);
7f6613ce 8819 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
8820 tcg_gen_br(l2);
8821 gen_set_label(l1);
6c5c1e20
TS
8822 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8823 tcg_temp_free(t0);
a16336e4 8824#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 8825 gen_load_fpr32(fp, fs);
7f6613ce
PJ
8826 gen_load_fpr32h(ctx, fph, ft);
8827 gen_store_fpr32h(ctx, fp, fd);
c905fdac 8828 gen_store_fpr32(fph, fd);
a16336e4 8829#else
7f6613ce 8830 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
8831 gen_load_fpr32(fp, ft);
8832 gen_store_fpr32(fph, fd);
7f6613ce 8833 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
8834#endif
8835 gen_set_label(l2);
c905fdac
AJ
8836 tcg_temp_free_i32(fp);
8837 tcg_temp_free_i32(fph);
a16336e4 8838 }
5a5012ec
TS
8839 opn = "alnv.ps";
8840 break;
8841 case OPC_MADD_S:
b8aa4598 8842 check_cop1x(ctx);
b6d96bed 8843 {
a7812ae4
PB
8844 TCGv_i32 fp0 = tcg_temp_new_i32();
8845 TCGv_i32 fp1 = tcg_temp_new_i32();
8846 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8847
8848 gen_load_fpr32(fp0, fs);
8849 gen_load_fpr32(fp1, ft);
8850 gen_load_fpr32(fp2, fr);
b3d6cd44 8851 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8852 tcg_temp_free_i32(fp0);
8853 tcg_temp_free_i32(fp1);
b6d96bed 8854 gen_store_fpr32(fp2, fd);
a7812ae4 8855 tcg_temp_free_i32(fp2);
b6d96bed 8856 }
5a5012ec
TS
8857 opn = "madd.s";
8858 break;
8859 case OPC_MADD_D:
b8aa4598
TS
8860 check_cop1x(ctx);
8861 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8862 {
a7812ae4
PB
8863 TCGv_i64 fp0 = tcg_temp_new_i64();
8864 TCGv_i64 fp1 = tcg_temp_new_i64();
8865 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8866
8867 gen_load_fpr64(ctx, fp0, fs);
8868 gen_load_fpr64(ctx, fp1, ft);
8869 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8870 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8871 tcg_temp_free_i64(fp0);
8872 tcg_temp_free_i64(fp1);
b6d96bed 8873 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8874 tcg_temp_free_i64(fp2);
b6d96bed 8875 }
5a5012ec
TS
8876 opn = "madd.d";
8877 break;
8878 case OPC_MADD_PS:
b8aa4598 8879 check_cp1_64bitmode(ctx);
b6d96bed 8880 {
a7812ae4
PB
8881 TCGv_i64 fp0 = tcg_temp_new_i64();
8882 TCGv_i64 fp1 = tcg_temp_new_i64();
8883 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8884
8885 gen_load_fpr64(ctx, fp0, fs);
8886 gen_load_fpr64(ctx, fp1, ft);
8887 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8888 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8889 tcg_temp_free_i64(fp0);
8890 tcg_temp_free_i64(fp1);
b6d96bed 8891 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8892 tcg_temp_free_i64(fp2);
b6d96bed 8893 }
5a5012ec
TS
8894 opn = "madd.ps";
8895 break;
8896 case OPC_MSUB_S:
b8aa4598 8897 check_cop1x(ctx);
b6d96bed 8898 {
a7812ae4
PB
8899 TCGv_i32 fp0 = tcg_temp_new_i32();
8900 TCGv_i32 fp1 = tcg_temp_new_i32();
8901 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8902
8903 gen_load_fpr32(fp0, fs);
8904 gen_load_fpr32(fp1, ft);
8905 gen_load_fpr32(fp2, fr);
b3d6cd44 8906 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8907 tcg_temp_free_i32(fp0);
8908 tcg_temp_free_i32(fp1);
b6d96bed 8909 gen_store_fpr32(fp2, fd);
a7812ae4 8910 tcg_temp_free_i32(fp2);
b6d96bed 8911 }
5a5012ec
TS
8912 opn = "msub.s";
8913 break;
8914 case OPC_MSUB_D:
b8aa4598
TS
8915 check_cop1x(ctx);
8916 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8917 {
a7812ae4
PB
8918 TCGv_i64 fp0 = tcg_temp_new_i64();
8919 TCGv_i64 fp1 = tcg_temp_new_i64();
8920 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8921
8922 gen_load_fpr64(ctx, fp0, fs);
8923 gen_load_fpr64(ctx, fp1, ft);
8924 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8925 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8926 tcg_temp_free_i64(fp0);
8927 tcg_temp_free_i64(fp1);
b6d96bed 8928 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8929 tcg_temp_free_i64(fp2);
b6d96bed 8930 }
5a5012ec
TS
8931 opn = "msub.d";
8932 break;
8933 case OPC_MSUB_PS:
b8aa4598 8934 check_cp1_64bitmode(ctx);
b6d96bed 8935 {
a7812ae4
PB
8936 TCGv_i64 fp0 = tcg_temp_new_i64();
8937 TCGv_i64 fp1 = tcg_temp_new_i64();
8938 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8939
8940 gen_load_fpr64(ctx, fp0, fs);
8941 gen_load_fpr64(ctx, fp1, ft);
8942 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8943 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8944 tcg_temp_free_i64(fp0);
8945 tcg_temp_free_i64(fp1);
b6d96bed 8946 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8947 tcg_temp_free_i64(fp2);
b6d96bed 8948 }
5a5012ec
TS
8949 opn = "msub.ps";
8950 break;
8951 case OPC_NMADD_S:
b8aa4598 8952 check_cop1x(ctx);
b6d96bed 8953 {
a7812ae4
PB
8954 TCGv_i32 fp0 = tcg_temp_new_i32();
8955 TCGv_i32 fp1 = tcg_temp_new_i32();
8956 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8957
8958 gen_load_fpr32(fp0, fs);
8959 gen_load_fpr32(fp1, ft);
8960 gen_load_fpr32(fp2, fr);
b3d6cd44 8961 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8962 tcg_temp_free_i32(fp0);
8963 tcg_temp_free_i32(fp1);
b6d96bed 8964 gen_store_fpr32(fp2, fd);
a7812ae4 8965 tcg_temp_free_i32(fp2);
b6d96bed 8966 }
5a5012ec
TS
8967 opn = "nmadd.s";
8968 break;
8969 case OPC_NMADD_D:
b8aa4598
TS
8970 check_cop1x(ctx);
8971 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8972 {
a7812ae4
PB
8973 TCGv_i64 fp0 = tcg_temp_new_i64();
8974 TCGv_i64 fp1 = tcg_temp_new_i64();
8975 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8976
8977 gen_load_fpr64(ctx, fp0, fs);
8978 gen_load_fpr64(ctx, fp1, ft);
8979 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8980 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8981 tcg_temp_free_i64(fp0);
8982 tcg_temp_free_i64(fp1);
b6d96bed 8983 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8984 tcg_temp_free_i64(fp2);
b6d96bed 8985 }
5a5012ec
TS
8986 opn = "nmadd.d";
8987 break;
8988 case OPC_NMADD_PS:
b8aa4598 8989 check_cp1_64bitmode(ctx);
b6d96bed 8990 {
a7812ae4
PB
8991 TCGv_i64 fp0 = tcg_temp_new_i64();
8992 TCGv_i64 fp1 = tcg_temp_new_i64();
8993 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8994
8995 gen_load_fpr64(ctx, fp0, fs);
8996 gen_load_fpr64(ctx, fp1, ft);
8997 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8998 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8999 tcg_temp_free_i64(fp0);
9000 tcg_temp_free_i64(fp1);
b6d96bed 9001 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9002 tcg_temp_free_i64(fp2);
b6d96bed 9003 }
5a5012ec
TS
9004 opn = "nmadd.ps";
9005 break;
9006 case OPC_NMSUB_S:
b8aa4598 9007 check_cop1x(ctx);
b6d96bed 9008 {
a7812ae4
PB
9009 TCGv_i32 fp0 = tcg_temp_new_i32();
9010 TCGv_i32 fp1 = tcg_temp_new_i32();
9011 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9012
9013 gen_load_fpr32(fp0, fs);
9014 gen_load_fpr32(fp1, ft);
9015 gen_load_fpr32(fp2, fr);
b3d6cd44 9016 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9017 tcg_temp_free_i32(fp0);
9018 tcg_temp_free_i32(fp1);
b6d96bed 9019 gen_store_fpr32(fp2, fd);
a7812ae4 9020 tcg_temp_free_i32(fp2);
b6d96bed 9021 }
5a5012ec
TS
9022 opn = "nmsub.s";
9023 break;
9024 case OPC_NMSUB_D:
b8aa4598
TS
9025 check_cop1x(ctx);
9026 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9027 {
a7812ae4
PB
9028 TCGv_i64 fp0 = tcg_temp_new_i64();
9029 TCGv_i64 fp1 = tcg_temp_new_i64();
9030 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9031
9032 gen_load_fpr64(ctx, fp0, fs);
9033 gen_load_fpr64(ctx, fp1, ft);
9034 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9035 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9036 tcg_temp_free_i64(fp0);
9037 tcg_temp_free_i64(fp1);
b6d96bed 9038 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9039 tcg_temp_free_i64(fp2);
b6d96bed 9040 }
5a5012ec
TS
9041 opn = "nmsub.d";
9042 break;
9043 case OPC_NMSUB_PS:
b8aa4598 9044 check_cp1_64bitmode(ctx);
b6d96bed 9045 {
a7812ae4
PB
9046 TCGv_i64 fp0 = tcg_temp_new_i64();
9047 TCGv_i64 fp1 = tcg_temp_new_i64();
9048 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9049
9050 gen_load_fpr64(ctx, fp0, fs);
9051 gen_load_fpr64(ctx, fp1, ft);
9052 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9053 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9054 tcg_temp_free_i64(fp0);
9055 tcg_temp_free_i64(fp1);
b6d96bed 9056 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9057 tcg_temp_free_i64(fp2);
b6d96bed 9058 }
5a5012ec
TS
9059 opn = "nmsub.ps";
9060 break;
923617a3
TS
9061 default:
9062 MIPS_INVAL(opn);
5a5012ec
TS
9063 generate_exception (ctx, EXCP_RI);
9064 return;
9065 }
2abf314d 9066 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9067 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9068 fregnames[fs], fregnames[ft]);
7a387fff
TS
9069}
9070
d75c135e 9071static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9072{
9073 TCGv t0;
9074
b3167288
RH
9075#if !defined(CONFIG_USER_ONLY)
9076 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9077 Therefore only check the ISA in system mode. */
d75c135e 9078 check_insn(ctx, ISA_MIPS32R2);
b3167288 9079#endif
26ebe468
NF
9080 t0 = tcg_temp_new();
9081
9082 switch (rd) {
9083 case 0:
9084 save_cpu_state(ctx, 1);
895c2d04 9085 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9086 gen_store_gpr(t0, rt);
9087 break;
9088 case 1:
9089 save_cpu_state(ctx, 1);
895c2d04 9090 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9091 gen_store_gpr(t0, rt);
9092 break;
9093 case 2:
9094 save_cpu_state(ctx, 1);
895c2d04 9095 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9096 gen_store_gpr(t0, rt);
9097 break;
9098 case 3:
9099 save_cpu_state(ctx, 1);
895c2d04 9100 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9101 gen_store_gpr(t0, rt);
9102 break;
9103 case 29:
9104#if defined(CONFIG_USER_ONLY)
d279279e
PJ
9105 tcg_gen_ld_tl(t0, cpu_env,
9106 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
9107 gen_store_gpr(t0, rt);
9108 break;
9109#else
d279279e
PJ
9110 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
9111 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
9112 tcg_gen_ld_tl(t0, cpu_env,
9113 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9114 gen_store_gpr(t0, rt);
9115 } else {
9116 generate_exception(ctx, EXCP_RI);
9117 }
9118 break;
26ebe468
NF
9119#endif
9120 default: /* Invalid */
9121 MIPS_INVAL("rdhwr");
9122 generate_exception(ctx, EXCP_RI);
9123 break;
9124 }
9125 tcg_temp_free(t0);
9126}
9127
d75c135e 9128static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9129{
9130 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9131 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9132 /* Branches completion */
9133 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9134 ctx->bstate = BS_BRANCH;
9135 save_cpu_state(ctx, 0);
9136 /* FIXME: Need to clear can_do_io. */
364d4831 9137 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9138 case MIPS_HFLAG_B:
9139 /* unconditional branch */
9140 MIPS_DEBUG("unconditional branch");
364d4831
NF
9141 if (proc_hflags & MIPS_HFLAG_BX) {
9142 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9143 }
c9602061
NF
9144 gen_goto_tb(ctx, 0, ctx->btarget);
9145 break;
9146 case MIPS_HFLAG_BL:
9147 /* blikely taken case */
9148 MIPS_DEBUG("blikely branch taken");
9149 gen_goto_tb(ctx, 0, ctx->btarget);
9150 break;
9151 case MIPS_HFLAG_BC:
9152 /* Conditional branch */
9153 MIPS_DEBUG("conditional branch");
9154 {
9155 int l1 = gen_new_label();
9156
9157 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9158 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9159 gen_set_label(l1);
9160 gen_goto_tb(ctx, 0, ctx->btarget);
9161 }
9162 break;
9163 case MIPS_HFLAG_BR:
9164 /* unconditional branch to register */
9165 MIPS_DEBUG("branch to register");
d75c135e 9166 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9167 TCGv t0 = tcg_temp_new();
9168 TCGv_i32 t1 = tcg_temp_new_i32();
9169
9170 tcg_gen_andi_tl(t0, btarget, 0x1);
9171 tcg_gen_trunc_tl_i32(t1, t0);
9172 tcg_temp_free(t0);
9173 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9174 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9175 tcg_gen_or_i32(hflags, hflags, t1);
9176 tcg_temp_free_i32(t1);
9177
9178 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9179 } else {
9180 tcg_gen_mov_tl(cpu_PC, btarget);
9181 }
c9602061
NF
9182 if (ctx->singlestep_enabled) {
9183 save_cpu_state(ctx, 0);
895c2d04 9184 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9185 }
9186 tcg_gen_exit_tb(0);
9187 break;
9188 default:
9189 MIPS_DEBUG("unknown branch");
9190 break;
9191 }
9192 }
9193}
9194
7a387fff 9195/* ISA extensions (ASEs) */
6af0bf9c 9196/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9197
9198/* MIPS16 major opcodes */
9199enum {
9200 M16_OPC_ADDIUSP = 0x00,
9201 M16_OPC_ADDIUPC = 0x01,
9202 M16_OPC_B = 0x02,
9203 M16_OPC_JAL = 0x03,
9204 M16_OPC_BEQZ = 0x04,
9205 M16_OPC_BNEQZ = 0x05,
9206 M16_OPC_SHIFT = 0x06,
9207 M16_OPC_LD = 0x07,
9208 M16_OPC_RRIA = 0x08,
9209 M16_OPC_ADDIU8 = 0x09,
9210 M16_OPC_SLTI = 0x0a,
9211 M16_OPC_SLTIU = 0x0b,
9212 M16_OPC_I8 = 0x0c,
9213 M16_OPC_LI = 0x0d,
9214 M16_OPC_CMPI = 0x0e,
9215 M16_OPC_SD = 0x0f,
9216 M16_OPC_LB = 0x10,
9217 M16_OPC_LH = 0x11,
9218 M16_OPC_LWSP = 0x12,
9219 M16_OPC_LW = 0x13,
9220 M16_OPC_LBU = 0x14,
9221 M16_OPC_LHU = 0x15,
9222 M16_OPC_LWPC = 0x16,
9223 M16_OPC_LWU = 0x17,
9224 M16_OPC_SB = 0x18,
9225 M16_OPC_SH = 0x19,
9226 M16_OPC_SWSP = 0x1a,
9227 M16_OPC_SW = 0x1b,
9228 M16_OPC_RRR = 0x1c,
9229 M16_OPC_RR = 0x1d,
9230 M16_OPC_EXTEND = 0x1e,
9231 M16_OPC_I64 = 0x1f
9232};
9233
9234/* I8 funct field */
9235enum {
9236 I8_BTEQZ = 0x0,
9237 I8_BTNEZ = 0x1,
9238 I8_SWRASP = 0x2,
9239 I8_ADJSP = 0x3,
9240 I8_SVRS = 0x4,
9241 I8_MOV32R = 0x5,
9242 I8_MOVR32 = 0x7
9243};
9244
9245/* RRR f field */
9246enum {
9247 RRR_DADDU = 0x0,
9248 RRR_ADDU = 0x1,
9249 RRR_DSUBU = 0x2,
9250 RRR_SUBU = 0x3
9251};
9252
9253/* RR funct field */
9254enum {
9255 RR_JR = 0x00,
9256 RR_SDBBP = 0x01,
9257 RR_SLT = 0x02,
9258 RR_SLTU = 0x03,
9259 RR_SLLV = 0x04,
9260 RR_BREAK = 0x05,
9261 RR_SRLV = 0x06,
9262 RR_SRAV = 0x07,
9263 RR_DSRL = 0x08,
9264 RR_CMP = 0x0a,
9265 RR_NEG = 0x0b,
9266 RR_AND = 0x0c,
9267 RR_OR = 0x0d,
9268 RR_XOR = 0x0e,
9269 RR_NOT = 0x0f,
9270 RR_MFHI = 0x10,
9271 RR_CNVT = 0x11,
9272 RR_MFLO = 0x12,
9273 RR_DSRA = 0x13,
9274 RR_DSLLV = 0x14,
9275 RR_DSRLV = 0x16,
9276 RR_DSRAV = 0x17,
9277 RR_MULT = 0x18,
9278 RR_MULTU = 0x19,
9279 RR_DIV = 0x1a,
9280 RR_DIVU = 0x1b,
9281 RR_DMULT = 0x1c,
9282 RR_DMULTU = 0x1d,
9283 RR_DDIV = 0x1e,
9284 RR_DDIVU = 0x1f
9285};
9286
9287/* I64 funct field */
9288enum {
9289 I64_LDSP = 0x0,
9290 I64_SDSP = 0x1,
9291 I64_SDRASP = 0x2,
9292 I64_DADJSP = 0x3,
9293 I64_LDPC = 0x4,
364d4831 9294 I64_DADDIU5 = 0x5,
6ea219d0
NF
9295 I64_DADDIUPC = 0x6,
9296 I64_DADDIUSP = 0x7
9297};
9298
9299/* RR ry field for CNVT */
9300enum {
9301 RR_RY_CNVT_ZEB = 0x0,
9302 RR_RY_CNVT_ZEH = 0x1,
9303 RR_RY_CNVT_ZEW = 0x2,
9304 RR_RY_CNVT_SEB = 0x4,
9305 RR_RY_CNVT_SEH = 0x5,
9306 RR_RY_CNVT_SEW = 0x6,
9307};
9308
364d4831
NF
9309static int xlat (int r)
9310{
9311 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9312
9313 return map[r];
9314}
9315
9316static void gen_mips16_save (DisasContext *ctx,
9317 int xsregs, int aregs,
9318 int do_ra, int do_s0, int do_s1,
9319 int framesize)
9320{
9321 TCGv t0 = tcg_temp_new();
9322 TCGv t1 = tcg_temp_new();
9323 int args, astatic;
9324
9325 switch (aregs) {
9326 case 0:
9327 case 1:
9328 case 2:
9329 case 3:
9330 case 11:
9331 args = 0;
9332 break;
9333 case 4:
9334 case 5:
9335 case 6:
9336 case 7:
9337 args = 1;
9338 break;
9339 case 8:
9340 case 9:
9341 case 10:
9342 args = 2;
9343 break;
9344 case 12:
9345 case 13:
9346 args = 3;
9347 break;
9348 case 14:
9349 args = 4;
9350 break;
9351 default:
9352 generate_exception(ctx, EXCP_RI);
9353 return;
9354 }
9355
9356 switch (args) {
9357 case 4:
9358 gen_base_offset_addr(ctx, t0, 29, 12);
9359 gen_load_gpr(t1, 7);
5f68f5ae 9360 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9361 /* Fall through */
9362 case 3:
9363 gen_base_offset_addr(ctx, t0, 29, 8);
9364 gen_load_gpr(t1, 6);
5f68f5ae 9365 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9366 /* Fall through */
9367 case 2:
9368 gen_base_offset_addr(ctx, t0, 29, 4);
9369 gen_load_gpr(t1, 5);
5f68f5ae 9370 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9371 /* Fall through */
9372 case 1:
9373 gen_base_offset_addr(ctx, t0, 29, 0);
9374 gen_load_gpr(t1, 4);
5f68f5ae 9375 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9376 }
9377
9378 gen_load_gpr(t0, 29);
9379
5f68f5ae
AJ
9380#define DECR_AND_STORE(reg) do { \
9381 tcg_gen_subi_tl(t0, t0, 4); \
9382 gen_load_gpr(t1, reg); \
9383 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
9384 } while (0)
9385
9386 if (do_ra) {
9387 DECR_AND_STORE(31);
9388 }
9389
9390 switch (xsregs) {
9391 case 7:
9392 DECR_AND_STORE(30);
9393 /* Fall through */
9394 case 6:
9395 DECR_AND_STORE(23);
9396 /* Fall through */
9397 case 5:
9398 DECR_AND_STORE(22);
9399 /* Fall through */
9400 case 4:
9401 DECR_AND_STORE(21);
9402 /* Fall through */
9403 case 3:
9404 DECR_AND_STORE(20);
9405 /* Fall through */
9406 case 2:
9407 DECR_AND_STORE(19);
9408 /* Fall through */
9409 case 1:
9410 DECR_AND_STORE(18);
9411 }
9412
9413 if (do_s1) {
9414 DECR_AND_STORE(17);
9415 }
9416 if (do_s0) {
9417 DECR_AND_STORE(16);
9418 }
9419
9420 switch (aregs) {
9421 case 0:
9422 case 4:
9423 case 8:
9424 case 12:
9425 case 14:
9426 astatic = 0;
9427 break;
9428 case 1:
9429 case 5:
9430 case 9:
9431 case 13:
9432 astatic = 1;
9433 break;
9434 case 2:
9435 case 6:
9436 case 10:
9437 astatic = 2;
9438 break;
9439 case 3:
9440 case 7:
9441 astatic = 3;
9442 break;
9443 case 11:
9444 astatic = 4;
9445 break;
9446 default:
9447 generate_exception(ctx, EXCP_RI);
9448 return;
9449 }
9450
9451 if (astatic > 0) {
9452 DECR_AND_STORE(7);
9453 if (astatic > 1) {
9454 DECR_AND_STORE(6);
9455 if (astatic > 2) {
9456 DECR_AND_STORE(5);
9457 if (astatic > 3) {
9458 DECR_AND_STORE(4);
9459 }
9460 }
9461 }
9462 }
9463#undef DECR_AND_STORE
9464
9465 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9466 tcg_temp_free(t0);
9467 tcg_temp_free(t1);
9468}
9469
9470static void gen_mips16_restore (DisasContext *ctx,
9471 int xsregs, int aregs,
9472 int do_ra, int do_s0, int do_s1,
9473 int framesize)
9474{
9475 int astatic;
9476 TCGv t0 = tcg_temp_new();
9477 TCGv t1 = tcg_temp_new();
9478
9479 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9480
5f68f5ae
AJ
9481#define DECR_AND_LOAD(reg) do { \
9482 tcg_gen_subi_tl(t0, t0, 4); \
9483 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9484 gen_store_gpr(t1, reg); \
364d4831
NF
9485 } while (0)
9486
9487 if (do_ra) {
9488 DECR_AND_LOAD(31);
9489 }
9490
9491 switch (xsregs) {
9492 case 7:
9493 DECR_AND_LOAD(30);
9494 /* Fall through */
9495 case 6:
9496 DECR_AND_LOAD(23);
9497 /* Fall through */
9498 case 5:
9499 DECR_AND_LOAD(22);
9500 /* Fall through */
9501 case 4:
9502 DECR_AND_LOAD(21);
9503 /* Fall through */
9504 case 3:
9505 DECR_AND_LOAD(20);
9506 /* Fall through */
9507 case 2:
9508 DECR_AND_LOAD(19);
9509 /* Fall through */
9510 case 1:
9511 DECR_AND_LOAD(18);
9512 }
9513
9514 if (do_s1) {
9515 DECR_AND_LOAD(17);
9516 }
9517 if (do_s0) {
9518 DECR_AND_LOAD(16);
9519 }
9520
9521 switch (aregs) {
9522 case 0:
9523 case 4:
9524 case 8:
9525 case 12:
9526 case 14:
9527 astatic = 0;
9528 break;
9529 case 1:
9530 case 5:
9531 case 9:
9532 case 13:
9533 astatic = 1;
9534 break;
9535 case 2:
9536 case 6:
9537 case 10:
9538 astatic = 2;
9539 break;
9540 case 3:
9541 case 7:
9542 astatic = 3;
9543 break;
9544 case 11:
9545 astatic = 4;
9546 break;
9547 default:
9548 generate_exception(ctx, EXCP_RI);
9549 return;
9550 }
9551
9552 if (astatic > 0) {
9553 DECR_AND_LOAD(7);
9554 if (astatic > 1) {
9555 DECR_AND_LOAD(6);
9556 if (astatic > 2) {
9557 DECR_AND_LOAD(5);
9558 if (astatic > 3) {
9559 DECR_AND_LOAD(4);
9560 }
9561 }
9562 }
9563 }
9564#undef DECR_AND_LOAD
9565
9566 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9567 tcg_temp_free(t0);
9568 tcg_temp_free(t1);
9569}
9570
9571static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9572 int is_64_bit, int extended)
9573{
9574 TCGv t0;
9575
9576 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9577 generate_exception(ctx, EXCP_RI);
9578 return;
9579 }
9580
9581 t0 = tcg_temp_new();
9582
9583 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9584 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9585 if (!is_64_bit) {
9586 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9587 }
9588
9589 tcg_temp_free(t0);
9590}
9591
9592#if defined(TARGET_MIPS64)
d75c135e 9593static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9594 int ry, int funct, int16_t offset,
9595 int extended)
9596{
9597 switch (funct) {
9598 case I64_LDSP:
9599 check_mips_64(ctx);
9600 offset = extended ? offset : offset << 3;
d75c135e 9601 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9602 break;
9603 case I64_SDSP:
9604 check_mips_64(ctx);
9605 offset = extended ? offset : offset << 3;
5c13fdfd 9606 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9607 break;
9608 case I64_SDRASP:
9609 check_mips_64(ctx);
9610 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9611 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9612 break;
9613 case I64_DADJSP:
9614 check_mips_64(ctx);
9615 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9616 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9617 break;
9618 case I64_LDPC:
9619 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9620 generate_exception(ctx, EXCP_RI);
9621 } else {
9622 offset = extended ? offset : offset << 3;
d75c135e 9623 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9624 }
9625 break;
9626 case I64_DADDIU5:
9627 check_mips_64(ctx);
9628 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9629 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9630 break;
9631 case I64_DADDIUPC:
9632 check_mips_64(ctx);
9633 offset = extended ? offset : offset << 2;
9634 gen_addiupc(ctx, ry, offset, 1, extended);
9635 break;
9636 case I64_DADDIUSP:
9637 check_mips_64(ctx);
9638 offset = extended ? offset : offset << 2;
d75c135e 9639 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9640 break;
9641 }
9642}
9643#endif
9644
240ce26a 9645static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 9646{
895c2d04 9647 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9648 int op, rx, ry, funct, sa;
9649 int16_t imm, offset;
9650
9651 ctx->opcode = (ctx->opcode << 16) | extend;
9652 op = (ctx->opcode >> 11) & 0x1f;
9653 sa = (ctx->opcode >> 22) & 0x1f;
9654 funct = (ctx->opcode >> 8) & 0x7;
9655 rx = xlat((ctx->opcode >> 8) & 0x7);
9656 ry = xlat((ctx->opcode >> 5) & 0x7);
9657 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9658 | ((ctx->opcode >> 21) & 0x3f) << 5
9659 | (ctx->opcode & 0x1f));
9660
9661 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9662 counterparts. */
9663 switch (op) {
9664 case M16_OPC_ADDIUSP:
d75c135e 9665 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9666 break;
9667 case M16_OPC_ADDIUPC:
9668 gen_addiupc(ctx, rx, imm, 0, 1);
9669 break;
9670 case M16_OPC_B:
9671 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9672 /* No delay slot, so just process as a normal instruction */
9673 break;
9674 case M16_OPC_BEQZ:
9675 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9676 /* No delay slot, so just process as a normal instruction */
9677 break;
9678 case M16_OPC_BNEQZ:
9679 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9680 /* No delay slot, so just process as a normal instruction */
9681 break;
9682 case M16_OPC_SHIFT:
9683 switch (ctx->opcode & 0x3) {
9684 case 0x0:
d75c135e 9685 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9686 break;
9687 case 0x1:
9688#if defined(TARGET_MIPS64)
9689 check_mips_64(ctx);
d75c135e 9690 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9691#else
9692 generate_exception(ctx, EXCP_RI);
9693#endif
9694 break;
9695 case 0x2:
d75c135e 9696 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9697 break;
9698 case 0x3:
d75c135e 9699 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9700 break;
9701 }
9702 break;
9703#if defined(TARGET_MIPS64)
9704 case M16_OPC_LD:
9705 check_mips_64(ctx);
d75c135e 9706 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9707 break;
9708#endif
9709 case M16_OPC_RRIA:
9710 imm = ctx->opcode & 0xf;
9711 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9712 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9713 imm = (int16_t) (imm << 1) >> 1;
9714 if ((ctx->opcode >> 4) & 0x1) {
9715#if defined(TARGET_MIPS64)
9716 check_mips_64(ctx);
d75c135e 9717 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9718#else
9719 generate_exception(ctx, EXCP_RI);
9720#endif
9721 } else {
d75c135e 9722 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9723 }
9724 break;
9725 case M16_OPC_ADDIU8:
d75c135e 9726 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9727 break;
9728 case M16_OPC_SLTI:
d75c135e 9729 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9730 break;
9731 case M16_OPC_SLTIU:
d75c135e 9732 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9733 break;
9734 case M16_OPC_I8:
9735 switch (funct) {
9736 case I8_BTEQZ:
9737 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9738 break;
9739 case I8_BTNEZ:
9740 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9741 break;
9742 case I8_SWRASP:
5c13fdfd 9743 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9744 break;
9745 case I8_ADJSP:
d75c135e 9746 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
9747 break;
9748 case I8_SVRS:
9749 {
9750 int xsregs = (ctx->opcode >> 24) & 0x7;
9751 int aregs = (ctx->opcode >> 16) & 0xf;
9752 int do_ra = (ctx->opcode >> 6) & 0x1;
9753 int do_s0 = (ctx->opcode >> 5) & 0x1;
9754 int do_s1 = (ctx->opcode >> 4) & 0x1;
9755 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9756 | (ctx->opcode & 0xf)) << 3;
9757
9758 if (ctx->opcode & (1 << 7)) {
9759 gen_mips16_save(ctx, xsregs, aregs,
9760 do_ra, do_s0, do_s1,
9761 framesize);
9762 } else {
9763 gen_mips16_restore(ctx, xsregs, aregs,
9764 do_ra, do_s0, do_s1,
9765 framesize);
9766 }
9767 }
9768 break;
9769 default:
9770 generate_exception(ctx, EXCP_RI);
9771 break;
9772 }
9773 break;
9774 case M16_OPC_LI:
9775 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9776 break;
9777 case M16_OPC_CMPI:
9778 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9779 break;
9780#if defined(TARGET_MIPS64)
9781 case M16_OPC_SD:
5c13fdfd 9782 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9783 break;
9784#endif
9785 case M16_OPC_LB:
d75c135e 9786 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9787 break;
9788 case M16_OPC_LH:
d75c135e 9789 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9790 break;
9791 case M16_OPC_LWSP:
d75c135e 9792 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9793 break;
9794 case M16_OPC_LW:
d75c135e 9795 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9796 break;
9797 case M16_OPC_LBU:
d75c135e 9798 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9799 break;
9800 case M16_OPC_LHU:
d75c135e 9801 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9802 break;
9803 case M16_OPC_LWPC:
d75c135e 9804 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9805 break;
9806#if defined(TARGET_MIPS64)
9807 case M16_OPC_LWU:
d75c135e 9808 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9809 break;
9810#endif
9811 case M16_OPC_SB:
5c13fdfd 9812 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9813 break;
9814 case M16_OPC_SH:
5c13fdfd 9815 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9816 break;
9817 case M16_OPC_SWSP:
5c13fdfd 9818 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9819 break;
9820 case M16_OPC_SW:
5c13fdfd 9821 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9822 break;
9823#if defined(TARGET_MIPS64)
9824 case M16_OPC_I64:
d75c135e 9825 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
9826 break;
9827#endif
9828 default:
9829 generate_exception(ctx, EXCP_RI);
9830 break;
9831 }
9832
9833 return 4;
9834}
9835
240ce26a 9836static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
9837{
9838 int rx, ry;
9839 int sa;
9840 int op, cnvt_op, op1, offset;
9841 int funct;
9842 int n_bytes;
9843
9844 op = (ctx->opcode >> 11) & 0x1f;
9845 sa = (ctx->opcode >> 2) & 0x7;
9846 sa = sa == 0 ? 8 : sa;
9847 rx = xlat((ctx->opcode >> 8) & 0x7);
9848 cnvt_op = (ctx->opcode >> 5) & 0x7;
9849 ry = xlat((ctx->opcode >> 5) & 0x7);
9850 op1 = offset = ctx->opcode & 0x1f;
9851
9852 n_bytes = 2;
9853
9854 switch (op) {
9855 case M16_OPC_ADDIUSP:
9856 {
9857 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9858
d75c135e 9859 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9860 }
9861 break;
9862 case M16_OPC_ADDIUPC:
9863 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9864 break;
9865 case M16_OPC_B:
9866 offset = (ctx->opcode & 0x7ff) << 1;
9867 offset = (int16_t)(offset << 4) >> 4;
9868 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9869 /* No delay slot, so just process as a normal instruction */
9870 break;
9871 case M16_OPC_JAL:
895c2d04 9872 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9873 offset = (((ctx->opcode & 0x1f) << 21)
9874 | ((ctx->opcode >> 5) & 0x1f) << 16
9875 | offset) << 2;
620e48f6 9876 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9877 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9878 n_bytes = 4;
364d4831
NF
9879 break;
9880 case M16_OPC_BEQZ:
9881 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9882 /* No delay slot, so just process as a normal instruction */
9883 break;
9884 case M16_OPC_BNEQZ:
9885 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9886 /* No delay slot, so just process as a normal instruction */
9887 break;
9888 case M16_OPC_SHIFT:
9889 switch (ctx->opcode & 0x3) {
9890 case 0x0:
d75c135e 9891 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9892 break;
9893 case 0x1:
9894#if defined(TARGET_MIPS64)
9895 check_mips_64(ctx);
d75c135e 9896 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9897#else
9898 generate_exception(ctx, EXCP_RI);
9899#endif
9900 break;
9901 case 0x2:
d75c135e 9902 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9903 break;
9904 case 0x3:
d75c135e 9905 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9906 break;
9907 }
9908 break;
9909#if defined(TARGET_MIPS64)
9910 case M16_OPC_LD:
9911 check_mips_64(ctx);
d75c135e 9912 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9913 break;
9914#endif
9915 case M16_OPC_RRIA:
9916 {
9917 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9918
9919 if ((ctx->opcode >> 4) & 1) {
9920#if defined(TARGET_MIPS64)
9921 check_mips_64(ctx);
d75c135e 9922 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9923#else
9924 generate_exception(ctx, EXCP_RI);
9925#endif
9926 } else {
d75c135e 9927 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9928 }
9929 }
9930 break;
9931 case M16_OPC_ADDIU8:
9932 {
9933 int16_t imm = (int8_t) ctx->opcode;
9934
d75c135e 9935 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9936 }
9937 break;
9938 case M16_OPC_SLTI:
9939 {
9940 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9941 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9942 }
9943 break;
9944 case M16_OPC_SLTIU:
9945 {
9946 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9947 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9948 }
9949 break;
9950 case M16_OPC_I8:
9951 {
9952 int reg32;
9953
9954 funct = (ctx->opcode >> 8) & 0x7;
9955 switch (funct) {
9956 case I8_BTEQZ:
9957 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9958 ((int8_t)ctx->opcode) << 1);
9959 break;
9960 case I8_BTNEZ:
9961 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9962 ((int8_t)ctx->opcode) << 1);
9963 break;
9964 case I8_SWRASP:
5c13fdfd 9965 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9966 break;
9967 case I8_ADJSP:
d75c135e 9968 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
9969 ((int8_t)ctx->opcode) << 3);
9970 break;
9971 case I8_SVRS:
9972 {
9973 int do_ra = ctx->opcode & (1 << 6);
9974 int do_s0 = ctx->opcode & (1 << 5);
9975 int do_s1 = ctx->opcode & (1 << 4);
9976 int framesize = ctx->opcode & 0xf;
9977
9978 if (framesize == 0) {
9979 framesize = 128;
9980 } else {
9981 framesize = framesize << 3;
9982 }
9983
9984 if (ctx->opcode & (1 << 7)) {
9985 gen_mips16_save(ctx, 0, 0,
9986 do_ra, do_s0, do_s1, framesize);
9987 } else {
9988 gen_mips16_restore(ctx, 0, 0,
9989 do_ra, do_s0, do_s1, framesize);
9990 }
9991 }
9992 break;
9993 case I8_MOV32R:
9994 {
9995 int rz = xlat(ctx->opcode & 0x7);
9996
9997 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9998 ((ctx->opcode >> 5) & 0x7);
d75c135e 9999 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
10000 }
10001 break;
10002 case I8_MOVR32:
10003 reg32 = ctx->opcode & 0x1f;
d75c135e 10004 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
10005 break;
10006 default:
10007 generate_exception(ctx, EXCP_RI);
10008 break;
10009 }
10010 }
10011 break;
10012 case M16_OPC_LI:
10013 {
10014 int16_t imm = (uint8_t) ctx->opcode;
10015
d75c135e 10016 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
10017 }
10018 break;
10019 case M16_OPC_CMPI:
10020 {
10021 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10022 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
10023 }
10024 break;
10025#if defined(TARGET_MIPS64)
10026 case M16_OPC_SD:
10027 check_mips_64(ctx);
5c13fdfd 10028 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
10029 break;
10030#endif
10031 case M16_OPC_LB:
d75c135e 10032 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10033 break;
10034 case M16_OPC_LH:
d75c135e 10035 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
10036 break;
10037 case M16_OPC_LWSP:
d75c135e 10038 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10039 break;
10040 case M16_OPC_LW:
d75c135e 10041 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10042 break;
10043 case M16_OPC_LBU:
d75c135e 10044 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10045 break;
10046 case M16_OPC_LHU:
d75c135e 10047 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10048 break;
10049 case M16_OPC_LWPC:
d75c135e 10050 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10051 break;
10052#if defined (TARGET_MIPS64)
10053 case M16_OPC_LWU:
10054 check_mips_64(ctx);
d75c135e 10055 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10056 break;
10057#endif
10058 case M16_OPC_SB:
5c13fdfd 10059 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10060 break;
10061 case M16_OPC_SH:
5c13fdfd 10062 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10063 break;
10064 case M16_OPC_SWSP:
5c13fdfd 10065 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10066 break;
10067 case M16_OPC_SW:
5c13fdfd 10068 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10069 break;
10070 case M16_OPC_RRR:
10071 {
10072 int rz = xlat((ctx->opcode >> 2) & 0x7);
10073 int mips32_op;
10074
10075 switch (ctx->opcode & 0x3) {
10076 case RRR_ADDU:
10077 mips32_op = OPC_ADDU;
10078 break;
10079 case RRR_SUBU:
10080 mips32_op = OPC_SUBU;
10081 break;
10082#if defined(TARGET_MIPS64)
10083 case RRR_DADDU:
10084 mips32_op = OPC_DADDU;
10085 check_mips_64(ctx);
10086 break;
10087 case RRR_DSUBU:
10088 mips32_op = OPC_DSUBU;
10089 check_mips_64(ctx);
10090 break;
10091#endif
10092 default:
10093 generate_exception(ctx, EXCP_RI);
10094 goto done;
10095 }
10096
d75c135e 10097 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10098 done:
10099 ;
10100 }
10101 break;
10102 case M16_OPC_RR:
10103 switch (op1) {
10104 case RR_JR:
10105 {
10106 int nd = (ctx->opcode >> 7) & 0x1;
10107 int link = (ctx->opcode >> 6) & 0x1;
10108 int ra = (ctx->opcode >> 5) & 0x1;
10109
10110 if (link) {
620e48f6 10111 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10112 } else {
10113 op = OPC_JR;
10114 }
10115
10116 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
364d4831
NF
10117 }
10118 break;
10119 case RR_SDBBP:
10120 /* XXX: not clear which exception should be raised
10121 * when in debug mode...
10122 */
d75c135e 10123 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10124 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10125 generate_exception(ctx, EXCP_DBp);
10126 } else {
10127 generate_exception(ctx, EXCP_DBp);
10128 }
10129 break;
10130 case RR_SLT:
d75c135e 10131 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10132 break;
10133 case RR_SLTU:
d75c135e 10134 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10135 break;
10136 case RR_BREAK:
10137 generate_exception(ctx, EXCP_BREAK);
10138 break;
10139 case RR_SLLV:
d75c135e 10140 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10141 break;
10142 case RR_SRLV:
d75c135e 10143 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10144 break;
10145 case RR_SRAV:
d75c135e 10146 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10147 break;
10148#if defined (TARGET_MIPS64)
10149 case RR_DSRL:
10150 check_mips_64(ctx);
d75c135e 10151 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10152 break;
10153#endif
10154 case RR_CMP:
d75c135e 10155 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10156 break;
10157 case RR_NEG:
d75c135e 10158 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10159 break;
10160 case RR_AND:
d75c135e 10161 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10162 break;
10163 case RR_OR:
d75c135e 10164 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10165 break;
10166 case RR_XOR:
d75c135e 10167 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10168 break;
10169 case RR_NOT:
d75c135e 10170 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10171 break;
10172 case RR_MFHI:
26135ead 10173 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
10174 break;
10175 case RR_CNVT:
10176 switch (cnvt_op) {
10177 case RR_RY_CNVT_ZEB:
10178 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10179 break;
10180 case RR_RY_CNVT_ZEH:
10181 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10182 break;
10183 case RR_RY_CNVT_SEB:
10184 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10185 break;
10186 case RR_RY_CNVT_SEH:
10187 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10188 break;
10189#if defined (TARGET_MIPS64)
10190 case RR_RY_CNVT_ZEW:
10191 check_mips_64(ctx);
10192 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10193 break;
10194 case RR_RY_CNVT_SEW:
10195 check_mips_64(ctx);
10196 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10197 break;
10198#endif
10199 default:
10200 generate_exception(ctx, EXCP_RI);
10201 break;
10202 }
10203 break;
10204 case RR_MFLO:
26135ead 10205 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
10206 break;
10207#if defined (TARGET_MIPS64)
10208 case RR_DSRA:
10209 check_mips_64(ctx);
d75c135e 10210 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10211 break;
10212 case RR_DSLLV:
10213 check_mips_64(ctx);
d75c135e 10214 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10215 break;
10216 case RR_DSRLV:
10217 check_mips_64(ctx);
d75c135e 10218 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10219 break;
10220 case RR_DSRAV:
10221 check_mips_64(ctx);
d75c135e 10222 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10223 break;
10224#endif
10225 case RR_MULT:
26135ead 10226 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
10227 break;
10228 case RR_MULTU:
26135ead 10229 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
10230 break;
10231 case RR_DIV:
26135ead 10232 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
10233 break;
10234 case RR_DIVU:
26135ead 10235 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
10236 break;
10237#if defined (TARGET_MIPS64)
10238 case RR_DMULT:
10239 check_mips_64(ctx);
26135ead 10240 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
10241 break;
10242 case RR_DMULTU:
10243 check_mips_64(ctx);
26135ead 10244 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
10245 break;
10246 case RR_DDIV:
10247 check_mips_64(ctx);
26135ead 10248 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
10249 break;
10250 case RR_DDIVU:
10251 check_mips_64(ctx);
26135ead 10252 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
10253 break;
10254#endif
10255 default:
10256 generate_exception(ctx, EXCP_RI);
10257 break;
10258 }
10259 break;
10260 case M16_OPC_EXTEND:
240ce26a 10261 decode_extended_mips16_opc(env, ctx);
364d4831
NF
10262 n_bytes = 4;
10263 break;
10264#if defined(TARGET_MIPS64)
10265 case M16_OPC_I64:
10266 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10267 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10268 break;
10269#endif
10270 default:
10271 generate_exception(ctx, EXCP_RI);
10272 break;
10273 }
10274
10275 return n_bytes;
10276}
10277
211da992 10278/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10279
211da992
CWR
10280/*
10281 * microMIPS32/microMIPS64 major opcodes
10282 *
10283 * 1. MIPS Architecture for Programmers Volume II-B:
10284 * The microMIPS32 Instruction Set (Revision 3.05)
10285 *
10286 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10287 *
10288 * 2. MIPS Architecture For Programmers Volume II-A:
10289 * The MIPS64 Instruction Set (Revision 3.51)
10290 */
6af0bf9c 10291
3c824109
NF
10292enum {
10293 POOL32A = 0x00,
10294 POOL16A = 0x01,
10295 LBU16 = 0x02,
10296 MOVE16 = 0x03,
10297 ADDI32 = 0x04,
10298 LBU32 = 0x05,
10299 SB32 = 0x06,
10300 LB32 = 0x07,
10301
10302 POOL32B = 0x08,
10303 POOL16B = 0x09,
10304 LHU16 = 0x0a,
10305 ANDI16 = 0x0b,
10306 ADDIU32 = 0x0c,
10307 LHU32 = 0x0d,
10308 SH32 = 0x0e,
10309 LH32 = 0x0f,
10310
10311 POOL32I = 0x10,
10312 POOL16C = 0x11,
10313 LWSP16 = 0x12,
10314 POOL16D = 0x13,
10315 ORI32 = 0x14,
10316 POOL32F = 0x15,
211da992
CWR
10317 POOL32S = 0x16, /* MIPS64 */
10318 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10319
211da992 10320 /* 0x1f is reserved */
3c824109
NF
10321 POOL32C = 0x18,
10322 LWGP16 = 0x19,
10323 LW16 = 0x1a,
10324 POOL16E = 0x1b,
10325 XORI32 = 0x1c,
10326 JALS32 = 0x1d,
10327 ADDIUPC = 0x1e,
3c824109
NF
10328
10329 /* 0x20 is reserved */
10330 RES_20 = 0x20,
10331 POOL16F = 0x21,
10332 SB16 = 0x22,
10333 BEQZ16 = 0x23,
10334 SLTI32 = 0x24,
10335 BEQ32 = 0x25,
10336 SWC132 = 0x26,
10337 LWC132 = 0x27,
10338
10339 /* 0x28 and 0x29 are reserved */
10340 RES_28 = 0x28,
10341 RES_29 = 0x29,
10342 SH16 = 0x2a,
10343 BNEZ16 = 0x2b,
10344 SLTIU32 = 0x2c,
10345 BNE32 = 0x2d,
10346 SDC132 = 0x2e,
10347 LDC132 = 0x2f,
10348
10349 /* 0x30 and 0x31 are reserved */
10350 RES_30 = 0x30,
10351 RES_31 = 0x31,
10352 SWSP16 = 0x32,
10353 B16 = 0x33,
10354 ANDI32 = 0x34,
10355 J32 = 0x35,
211da992
CWR
10356 SD32 = 0x36, /* MIPS64 */
10357 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10358
10359 /* 0x38 and 0x39 are reserved */
10360 RES_38 = 0x38,
10361 RES_39 = 0x39,
10362 SW16 = 0x3a,
10363 LI16 = 0x3b,
10364 JALX32 = 0x3c,
10365 JAL32 = 0x3d,
10366 SW32 = 0x3e,
10367 LW32 = 0x3f
10368};
10369
10370/* POOL32A encoding of minor opcode field */
10371
10372enum {
10373 /* These opcodes are distinguished only by bits 9..6; those bits are
10374 * what are recorded below. */
10375 SLL32 = 0x0,
10376 SRL32 = 0x1,
10377 SRA = 0x2,
10378 ROTR = 0x3,
10379
10380 SLLV = 0x0,
10381 SRLV = 0x1,
10382 SRAV = 0x2,
10383 ROTRV = 0x3,
10384 ADD = 0x4,
10385 ADDU32 = 0x5,
10386 SUB = 0x6,
10387 SUBU32 = 0x7,
10388 MUL = 0x8,
10389 AND = 0x9,
10390 OR32 = 0xa,
10391 NOR = 0xb,
10392 XOR32 = 0xc,
10393 SLT = 0xd,
10394 SLTU = 0xe,
10395
10396 MOVN = 0x0,
10397 MOVZ = 0x1,
10398 LWXS = 0x4,
10399
10400 /* The following can be distinguished by their lower 6 bits. */
10401 INS = 0x0c,
10402 EXT = 0x2c,
10403 POOL32AXF = 0x3c
10404};
10405
10406/* POOL32AXF encoding of minor opcode field extension */
10407
d132c79f
CWR
10408/*
10409 * 1. MIPS Architecture for Programmers Volume II-B:
10410 * The microMIPS32 Instruction Set (Revision 3.05)
10411 *
10412 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10413 *
10414 * 2. MIPS Architecture for Programmers VolumeIV-e:
10415 * The MIPS DSP Application-Specific Extension
10416 * to the microMIPS32 Architecture (Revision 2.34)
10417 *
10418 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10419 */
10420
3c824109
NF
10421enum {
10422 /* bits 11..6 */
10423 TEQ = 0x00,
10424 TGE = 0x08,
10425 TGEU = 0x10,
10426 TLT = 0x20,
10427 TLTU = 0x28,
10428 TNE = 0x30,
10429
10430 MFC0 = 0x03,
10431 MTC0 = 0x0b,
10432
d132c79f
CWR
10433 /* begin of microMIPS32 DSP */
10434
3c824109
NF
10435 /* bits 13..12 for 0x01 */
10436 MFHI_ACC = 0x0,
10437 MFLO_ACC = 0x1,
10438 MTHI_ACC = 0x2,
10439 MTLO_ACC = 0x3,
10440
10441 /* bits 13..12 for 0x2a */
10442 MADD_ACC = 0x0,
10443 MADDU_ACC = 0x1,
10444 MSUB_ACC = 0x2,
10445 MSUBU_ACC = 0x3,
10446
10447 /* bits 13..12 for 0x32 */
10448 MULT_ACC = 0x0,
6801038b 10449 MULTU_ACC = 0x1,
3c824109 10450
d132c79f
CWR
10451 /* end of microMIPS32 DSP */
10452
3c824109
NF
10453 /* bits 15..12 for 0x2c */
10454 SEB = 0x2,
10455 SEH = 0x3,
10456 CLO = 0x4,
10457 CLZ = 0x5,
10458 RDHWR = 0x6,
10459 WSBH = 0x7,
10460 MULT = 0x8,
10461 MULTU = 0x9,
10462 DIV = 0xa,
10463 DIVU = 0xb,
10464 MADD = 0xc,
10465 MADDU = 0xd,
10466 MSUB = 0xe,
10467 MSUBU = 0xf,
10468
10469 /* bits 15..12 for 0x34 */
10470 MFC2 = 0x4,
10471 MTC2 = 0x5,
10472 MFHC2 = 0x8,
10473 MTHC2 = 0x9,
10474 CFC2 = 0xc,
10475 CTC2 = 0xd,
10476
10477 /* bits 15..12 for 0x3c */
10478 JALR = 0x0,
10479 JR = 0x0, /* alias */
10480 JALR_HB = 0x1,
10481 JALRS = 0x4,
10482 JALRS_HB = 0x5,
10483
10484 /* bits 15..12 for 0x05 */
10485 RDPGPR = 0xe,
10486 WRPGPR = 0xf,
10487
10488 /* bits 15..12 for 0x0d */
10489 TLBP = 0x0,
10490 TLBR = 0x1,
10491 TLBWI = 0x2,
10492 TLBWR = 0x3,
10493 WAIT = 0x9,
10494 IRET = 0xd,
10495 DERET = 0xe,
10496 ERET = 0xf,
10497
10498 /* bits 15..12 for 0x15 */
10499 DMT = 0x0,
10500 DVPE = 0x1,
10501 EMT = 0x2,
10502 EVPE = 0x3,
10503
10504 /* bits 15..12 for 0x1d */
10505 DI = 0x4,
10506 EI = 0x5,
10507
10508 /* bits 15..12 for 0x2d */
10509 SYNC = 0x6,
10510 SYSCALL = 0x8,
10511 SDBBP = 0xd,
10512
10513 /* bits 15..12 for 0x35 */
10514 MFHI32 = 0x0,
10515 MFLO32 = 0x1,
10516 MTHI32 = 0x2,
10517 MTLO32 = 0x3,
10518};
10519
10520/* POOL32B encoding of minor opcode field (bits 15..12) */
10521
10522enum {
10523 LWC2 = 0x0,
10524 LWP = 0x1,
10525 LDP = 0x4,
10526 LWM32 = 0x5,
10527 CACHE = 0x6,
10528 LDM = 0x7,
10529 SWC2 = 0x8,
10530 SWP = 0x9,
10531 SDP = 0xc,
10532 SWM32 = 0xd,
10533 SDM = 0xf
10534};
10535
10536/* POOL32C encoding of minor opcode field (bits 15..12) */
10537
10538enum {
10539 LWL = 0x0,
10540 SWL = 0x8,
10541 LWR = 0x1,
10542 SWR = 0x9,
10543 PREF = 0x2,
10544 /* 0xa is reserved */
10545 LL = 0x3,
10546 SC = 0xb,
10547 LDL = 0x4,
10548 SDL = 0xc,
10549 LDR = 0x5,
10550 SDR = 0xd,
10551 /* 0x6 is reserved */
10552 LWU = 0xe,
10553 LLD = 0x7,
10554 SCD = 0xf
10555};
10556
10557/* POOL32F encoding of minor opcode field (bits 5..0) */
10558
10559enum {
10560 /* These are the bit 7..6 values */
10561 ADD_FMT = 0x0,
10562 MOVN_FMT = 0x0,
10563
10564 SUB_FMT = 0x1,
10565 MOVZ_FMT = 0x1,
10566
10567 MUL_FMT = 0x2,
10568
10569 DIV_FMT = 0x3,
10570
10571 /* These are the bit 8..6 values */
10572 RSQRT2_FMT = 0x0,
10573 MOVF_FMT = 0x0,
10574
10575 LWXC1 = 0x1,
10576 MOVT_FMT = 0x1,
10577
10578 PLL_PS = 0x2,
10579 SWXC1 = 0x2,
10580
10581 PLU_PS = 0x3,
10582 LDXC1 = 0x3,
10583
10584 PUL_PS = 0x4,
10585 SDXC1 = 0x4,
10586 RECIP2_FMT = 0x4,
10587
10588 PUU_PS = 0x5,
10589 LUXC1 = 0x5,
10590
10591 CVT_PS_S = 0x6,
10592 SUXC1 = 0x6,
10593 ADDR_PS = 0x6,
10594 PREFX = 0x6,
10595
10596 MULR_PS = 0x7,
10597
10598 MADD_S = 0x01,
10599 MADD_D = 0x09,
10600 MADD_PS = 0x11,
10601 ALNV_PS = 0x19,
10602 MSUB_S = 0x21,
10603 MSUB_D = 0x29,
10604 MSUB_PS = 0x31,
10605
10606 NMADD_S = 0x02,
10607 NMADD_D = 0x0a,
10608 NMADD_PS = 0x12,
10609 NMSUB_S = 0x22,
10610 NMSUB_D = 0x2a,
10611 NMSUB_PS = 0x32,
10612
10613 POOL32FXF = 0x3b,
10614
10615 CABS_COND_FMT = 0x1c, /* MIPS3D */
10616 C_COND_FMT = 0x3c
10617};
10618
10619/* POOL32Fxf encoding of minor opcode extension field */
10620
10621enum {
10622 CVT_L = 0x04,
10623 RSQRT_FMT = 0x08,
10624 FLOOR_L = 0x0c,
10625 CVT_PW_PS = 0x1c,
10626 CVT_W = 0x24,
10627 SQRT_FMT = 0x28,
10628 FLOOR_W = 0x2c,
10629 CVT_PS_PW = 0x3c,
10630 CFC1 = 0x40,
10631 RECIP_FMT = 0x48,
10632 CEIL_L = 0x4c,
10633 CTC1 = 0x60,
10634 CEIL_W = 0x6c,
10635 MFC1 = 0x80,
10636 CVT_S_PL = 0x84,
10637 TRUNC_L = 0x8c,
10638 MTC1 = 0xa0,
10639 CVT_S_PU = 0xa4,
10640 TRUNC_W = 0xac,
10641 MFHC1 = 0xc0,
10642 ROUND_L = 0xcc,
10643 MTHC1 = 0xe0,
10644 ROUND_W = 0xec,
10645
10646 MOV_FMT = 0x01,
10647 MOVF = 0x05,
10648 ABS_FMT = 0x0d,
10649 RSQRT1_FMT = 0x1d,
10650 MOVT = 0x25,
10651 NEG_FMT = 0x2d,
10652 CVT_D = 0x4d,
10653 RECIP1_FMT = 0x5d,
10654 CVT_S = 0x6d
10655};
10656
10657/* POOL32I encoding of minor opcode field (bits 25..21) */
10658
10659enum {
10660 BLTZ = 0x00,
10661 BLTZAL = 0x01,
10662 BGEZ = 0x02,
10663 BGEZAL = 0x03,
10664 BLEZ = 0x04,
10665 BNEZC = 0x05,
10666 BGTZ = 0x06,
10667 BEQZC = 0x07,
10668 TLTI = 0x08,
10669 TGEI = 0x09,
10670 TLTIU = 0x0a,
10671 TGEIU = 0x0b,
10672 TNEI = 0x0c,
10673 LUI = 0x0d,
10674 TEQI = 0x0e,
10675 SYNCI = 0x10,
10676 BLTZALS = 0x11,
10677 BGEZALS = 0x13,
10678 BC2F = 0x14,
10679 BC2T = 0x15,
10680 BPOSGE64 = 0x1a,
10681 BPOSGE32 = 0x1b,
10682 /* These overlap and are distinguished by bit16 of the instruction */
10683 BC1F = 0x1c,
10684 BC1T = 0x1d,
10685 BC1ANY2F = 0x1c,
10686 BC1ANY2T = 0x1d,
10687 BC1ANY4F = 0x1e,
10688 BC1ANY4T = 0x1f
10689};
10690
10691/* POOL16A encoding of minor opcode field */
10692
10693enum {
10694 ADDU16 = 0x0,
10695 SUBU16 = 0x1
10696};
10697
10698/* POOL16B encoding of minor opcode field */
10699
10700enum {
10701 SLL16 = 0x0,
10702 SRL16 = 0x1
10703};
10704
10705/* POOL16C encoding of minor opcode field */
10706
10707enum {
10708 NOT16 = 0x00,
10709 XOR16 = 0x04,
10710 AND16 = 0x08,
10711 OR16 = 0x0c,
10712 LWM16 = 0x10,
10713 SWM16 = 0x14,
10714 JR16 = 0x18,
10715 JRC16 = 0x1a,
10716 JALR16 = 0x1c,
10717 JALR16S = 0x1e,
10718 MFHI16 = 0x20,
10719 MFLO16 = 0x24,
10720 BREAK16 = 0x28,
10721 SDBBP16 = 0x2c,
10722 JRADDIUSP = 0x30
10723};
10724
10725/* POOL16D encoding of minor opcode field */
10726
10727enum {
10728 ADDIUS5 = 0x0,
10729 ADDIUSP = 0x1
10730};
10731
10732/* POOL16E encoding of minor opcode field */
10733
10734enum {
10735 ADDIUR2 = 0x0,
10736 ADDIUR1SP = 0x1
10737};
10738
10739static int mmreg (int r)
10740{
10741 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10742
10743 return map[r];
10744}
10745
10746/* Used for 16-bit store instructions. */
10747static int mmreg2 (int r)
10748{
10749 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10750
10751 return map[r];
10752}
10753
10754#define uMIPS_RD(op) ((op >> 7) & 0x7)
10755#define uMIPS_RS(op) ((op >> 4) & 0x7)
10756#define uMIPS_RS2(op) uMIPS_RS(op)
10757#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10758#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10759#define uMIPS_RS5(op) (op & 0x1f)
10760
10761/* Signed immediate */
10762#define SIMM(op, start, width) \
10763 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10764 << (32-width)) \
10765 >> (32-width))
10766/* Zero-extended immediate */
10767#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10768
d75c135e 10769static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
10770{
10771 int rd = mmreg(uMIPS_RD(ctx->opcode));
10772
d75c135e 10773 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
10774}
10775
d75c135e 10776static void gen_addiur2(DisasContext *ctx)
3c824109
NF
10777{
10778 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10779 int rd = mmreg(uMIPS_RD(ctx->opcode));
10780 int rs = mmreg(uMIPS_RS(ctx->opcode));
10781
d75c135e 10782 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
10783}
10784
d75c135e 10785static void gen_addiusp(DisasContext *ctx)
3c824109
NF
10786{
10787 int encoded = ZIMM(ctx->opcode, 1, 9);
10788 int decoded;
10789
10790 if (encoded <= 1) {
10791 decoded = 256 + encoded;
10792 } else if (encoded <= 255) {
10793 decoded = encoded;
10794 } else if (encoded <= 509) {
10795 decoded = encoded - 512;
10796 } else {
10797 decoded = encoded - 768;
10798 }
10799
d75c135e 10800 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
10801}
10802
d75c135e 10803static void gen_addius5(DisasContext *ctx)
3c824109
NF
10804{
10805 int imm = SIMM(ctx->opcode, 1, 4);
10806 int rd = (ctx->opcode >> 5) & 0x1f;
10807
d75c135e 10808 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
10809}
10810
d75c135e 10811static void gen_andi16(DisasContext *ctx)
3c824109
NF
10812{
10813 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10814 31, 32, 63, 64, 255, 32768, 65535 };
10815 int rd = mmreg(uMIPS_RD(ctx->opcode));
10816 int rs = mmreg(uMIPS_RS(ctx->opcode));
10817 int encoded = ZIMM(ctx->opcode, 0, 4);
10818
d75c135e 10819 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10820}
10821
10822static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10823 int base, int16_t offset)
10824{
e1050a76 10825 const char *opn = "ldst_multiple";
3c824109
NF
10826 TCGv t0, t1;
10827 TCGv_i32 t2;
10828
10829 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10830 generate_exception(ctx, EXCP_RI);
10831 return;
10832 }
10833
10834 t0 = tcg_temp_new();
10835
10836 gen_base_offset_addr(ctx, t0, base, offset);
10837
10838 t1 = tcg_const_tl(reglist);
10839 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10840
3c824109
NF
10841 save_cpu_state(ctx, 1);
10842 switch (opc) {
10843 case LWM32:
895c2d04 10844 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10845 opn = "lwm";
3c824109
NF
10846 break;
10847 case SWM32:
895c2d04 10848 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10849 opn = "swm";
3c824109
NF
10850 break;
10851#ifdef TARGET_MIPS64
10852 case LDM:
895c2d04 10853 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10854 opn = "ldm";
3c824109
NF
10855 break;
10856 case SDM:
895c2d04 10857 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10858 opn = "sdm";
3c824109 10859 break;
6af0bf9c 10860#endif
3c824109 10861 }
e1050a76 10862 (void)opn;
3c824109
NF
10863 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10864 tcg_temp_free(t0);
33087598 10865 tcg_temp_free(t1);
3c824109
NF
10866 tcg_temp_free_i32(t2);
10867}
6af0bf9c 10868
3c824109 10869
240ce26a 10870static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 10871{
3c824109
NF
10872 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10873 int rs = mmreg(ctx->opcode & 0x7);
10874 int opc;
6af0bf9c 10875
3c824109
NF
10876 switch (((ctx->opcode) >> 4) & 0x3f) {
10877 case NOT16 + 0:
10878 case NOT16 + 1:
10879 case NOT16 + 2:
10880 case NOT16 + 3:
d75c135e 10881 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10882 break;
10883 case XOR16 + 0:
10884 case XOR16 + 1:
10885 case XOR16 + 2:
10886 case XOR16 + 3:
d75c135e 10887 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10888 break;
10889 case AND16 + 0:
10890 case AND16 + 1:
10891 case AND16 + 2:
10892 case AND16 + 3:
d75c135e 10893 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10894 break;
10895 case OR16 + 0:
10896 case OR16 + 1:
10897 case OR16 + 2:
10898 case OR16 + 3:
d75c135e 10899 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10900 break;
10901 case LWM16 + 0:
10902 case LWM16 + 1:
10903 case LWM16 + 2:
10904 case LWM16 + 3:
10905 {
10906 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10907 int offset = ZIMM(ctx->opcode, 0, 4);
10908
10909 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10910 29, offset << 2);
10911 }
10912 break;
10913 case SWM16 + 0:
10914 case SWM16 + 1:
10915 case SWM16 + 2:
10916 case SWM16 + 3:
10917 {
10918 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10919 int offset = ZIMM(ctx->opcode, 0, 4);
10920
10921 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10922 29, offset << 2);
10923 }
10924 break;
10925 case JR16 + 0:
10926 case JR16 + 1:
10927 {
10928 int reg = ctx->opcode & 0x1f;
10929
10930 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10931 }
3c824109
NF
10932 break;
10933 case JRC16 + 0:
10934 case JRC16 + 1:
10935 {
10936 int reg = ctx->opcode & 0x1f;
10937
10938 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10939 /* Let normal delay slot handling in our caller take us
10940 to the branch target. */
10941 }
10942 break;
10943 case JALR16 + 0:
10944 case JALR16 + 1:
10945 opc = OPC_JALR;
10946 goto do_jalr;
10947 case JALR16S + 0:
10948 case JALR16S + 1:
10949 opc = OPC_JALRS;
10950 do_jalr:
10951 {
10952 int reg = ctx->opcode & 0x1f;
10953
10954 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10955 }
3c824109
NF
10956 break;
10957 case MFHI16 + 0:
10958 case MFHI16 + 1:
26135ead 10959 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
10960 break;
10961 case MFLO16 + 0:
10962 case MFLO16 + 1:
26135ead 10963 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
10964 break;
10965 case BREAK16:
10966 generate_exception(ctx, EXCP_BREAK);
10967 break;
10968 case SDBBP16:
10969 /* XXX: not clear which exception should be raised
10970 * when in debug mode...
10971 */
d75c135e 10972 check_insn(ctx, ISA_MIPS32);
3c824109
NF
10973 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10974 generate_exception(ctx, EXCP_DBp);
10975 } else {
10976 generate_exception(ctx, EXCP_DBp);
10977 }
10978 break;
10979 case JRADDIUSP + 0:
10980 case JRADDIUSP + 1:
10981 {
10982 int imm = ZIMM(ctx->opcode, 0, 5);
10983
10984 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 10985 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
10986 /* Let normal delay slot handling in our caller take us
10987 to the branch target. */
10988 }
10989 break;
10990 default:
10991 generate_exception(ctx, EXCP_RI);
10992 break;
10993 }
10994}
10995
10996static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10997{
10998 TCGv t0 = tcg_temp_new();
10999 TCGv t1 = tcg_temp_new();
11000
11001 gen_load_gpr(t0, base);
11002
11003 if (index != 0) {
11004 gen_load_gpr(t1, index);
11005 tcg_gen_shli_tl(t1, t1, 2);
11006 gen_op_addr_add(ctx, t0, t1, t0);
11007 }
11008
5f68f5ae 11009 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11010 gen_store_gpr(t1, rd);
11011
11012 tcg_temp_free(t0);
11013 tcg_temp_free(t1);
11014}
11015
11016static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
11017 int base, int16_t offset)
11018{
11019 const char *opn = "ldst_pair";
11020 TCGv t0, t1;
11021
36c6711b 11022 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 11023 generate_exception(ctx, EXCP_RI);
d796321b
FB
11024 return;
11025 }
11026
3c824109
NF
11027 t0 = tcg_temp_new();
11028 t1 = tcg_temp_new();
8e9ade68 11029
3c824109
NF
11030 gen_base_offset_addr(ctx, t0, base, offset);
11031
11032 switch (opc) {
11033 case LWP:
36c6711b
EJ
11034 if (rd == base) {
11035 generate_exception(ctx, EXCP_RI);
11036 return;
11037 }
5f68f5ae 11038 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11039 gen_store_gpr(t1, rd);
11040 tcg_gen_movi_tl(t1, 4);
11041 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11042 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11043 gen_store_gpr(t1, rd+1);
11044 opn = "lwp";
11045 break;
11046 case SWP:
3c824109 11047 gen_load_gpr(t1, rd);
5f68f5ae 11048 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
11049 tcg_gen_movi_tl(t1, 4);
11050 gen_op_addr_add(ctx, t0, t0, t1);
11051 gen_load_gpr(t1, rd+1);
5f68f5ae 11052 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
11053 opn = "swp";
11054 break;
11055#ifdef TARGET_MIPS64
11056 case LDP:
36c6711b
EJ
11057 if (rd == base) {
11058 generate_exception(ctx, EXCP_RI);
11059 return;
11060 }
5f68f5ae 11061 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11062 gen_store_gpr(t1, rd);
11063 tcg_gen_movi_tl(t1, 8);
11064 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11065 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11066 gen_store_gpr(t1, rd+1);
11067 opn = "ldp";
11068 break;
11069 case SDP:
3c824109 11070 gen_load_gpr(t1, rd);
5f68f5ae 11071 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11072 tcg_gen_movi_tl(t1, 8);
11073 gen_op_addr_add(ctx, t0, t0, t1);
11074 gen_load_gpr(t1, rd+1);
5f68f5ae 11075 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11076 opn = "sdp";
11077 break;
11078#endif
6af0bf9c 11079 }
2abf314d 11080 (void)opn; /* avoid a compiler warning */
3c824109
NF
11081 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11082 tcg_temp_free(t0);
11083 tcg_temp_free(t1);
11084}
618b0fe9 11085
240ce26a 11086static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
11087{
11088 int extension = (ctx->opcode >> 6) & 0x3f;
11089 int minor = (ctx->opcode >> 12) & 0xf;
11090 uint32_t mips32_op;
11091
11092 switch (extension) {
11093 case TEQ:
11094 mips32_op = OPC_TEQ;
11095 goto do_trap;
11096 case TGE:
11097 mips32_op = OPC_TGE;
11098 goto do_trap;
11099 case TGEU:
11100 mips32_op = OPC_TGEU;
11101 goto do_trap;
11102 case TLT:
11103 mips32_op = OPC_TLT;
11104 goto do_trap;
11105 case TLTU:
11106 mips32_op = OPC_TLTU;
11107 goto do_trap;
11108 case TNE:
11109 mips32_op = OPC_TNE;
11110 do_trap:
11111 gen_trap(ctx, mips32_op, rs, rt, -1);
11112 break;
11113#ifndef CONFIG_USER_ONLY
11114 case MFC0:
11115 case MFC0 + 32:
2e15497c 11116 check_cp0_enabled(ctx);
3c824109
NF
11117 if (rt == 0) {
11118 /* Treat as NOP. */
11119 break;
11120 }
d75c135e 11121 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11122 break;
11123 case MTC0:
11124 case MTC0 + 32:
2e15497c 11125 check_cp0_enabled(ctx);
3c824109
NF
11126 {
11127 TCGv t0 = tcg_temp_new();
618b0fe9 11128
3c824109 11129 gen_load_gpr(t0, rt);
d75c135e 11130 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11131 tcg_temp_free(t0);
11132 }
11133 break;
11134#endif
a1fc6246
LA
11135 case 0x2a:
11136 switch (minor & 3) {
11137 case MADD_ACC:
11138 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11139 break;
11140 case MADDU_ACC:
11141 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11142 break;
11143 case MSUB_ACC:
11144 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11145 break;
11146 case MSUBU_ACC:
11147 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11148 break;
11149 default:
11150 goto pool32axf_invalid;
11151 }
11152 break;
11153 case 0x32:
11154 switch (minor & 3) {
11155 case MULT_ACC:
11156 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11157 break;
11158 case MULTU_ACC:
11159 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11160 break;
11161 default:
11162 goto pool32axf_invalid;
11163 }
11164 break;
3c824109
NF
11165 case 0x2c:
11166 switch (minor) {
11167 case SEB:
11168 gen_bshfl(ctx, OPC_SEB, rs, rt);
11169 break;
11170 case SEH:
11171 gen_bshfl(ctx, OPC_SEH, rs, rt);
11172 break;
11173 case CLO:
11174 mips32_op = OPC_CLO;
11175 goto do_cl;
11176 case CLZ:
11177 mips32_op = OPC_CLZ;
11178 do_cl:
d75c135e 11179 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11180 gen_cl(ctx, mips32_op, rt, rs);
11181 break;
11182 case RDHWR:
d75c135e 11183 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11184 break;
11185 case WSBH:
11186 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11187 break;
11188 case MULT:
11189 mips32_op = OPC_MULT;
26135ead 11190 goto do_mul;
3c824109
NF
11191 case MULTU:
11192 mips32_op = OPC_MULTU;
26135ead 11193 goto do_mul;
3c824109
NF
11194 case DIV:
11195 mips32_op = OPC_DIV;
26135ead 11196 goto do_div;
3c824109
NF
11197 case DIVU:
11198 mips32_op = OPC_DIVU;
26135ead
RS
11199 goto do_div;
11200 do_div:
11201 check_insn(ctx, ISA_MIPS32);
11202 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11203 break;
3c824109
NF
11204 case MADD:
11205 mips32_op = OPC_MADD;
26135ead 11206 goto do_mul;
3c824109
NF
11207 case MADDU:
11208 mips32_op = OPC_MADDU;
26135ead 11209 goto do_mul;
3c824109
NF
11210 case MSUB:
11211 mips32_op = OPC_MSUB;
26135ead 11212 goto do_mul;
3c824109
NF
11213 case MSUBU:
11214 mips32_op = OPC_MSUBU;
26135ead 11215 do_mul:
d75c135e 11216 check_insn(ctx, ISA_MIPS32);
a1fc6246 11217 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
11218 break;
11219 default:
11220 goto pool32axf_invalid;
11221 }
11222 break;
11223 case 0x34:
11224 switch (minor) {
11225 case MFC2:
11226 case MTC2:
11227 case MFHC2:
11228 case MTHC2:
11229 case CFC2:
11230 case CTC2:
11231 generate_exception_err(ctx, EXCP_CpU, 2);
11232 break;
11233 default:
11234 goto pool32axf_invalid;
11235 }
11236 break;
11237 case 0x3c:
11238 switch (minor) {
11239 case JALR:
11240 case JALR_HB:
11241 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
3c824109
NF
11242 break;
11243 case JALRS:
11244 case JALRS_HB:
11245 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
3c824109
NF
11246 break;
11247 default:
11248 goto pool32axf_invalid;
11249 }
11250 break;
11251 case 0x05:
11252 switch (minor) {
11253 case RDPGPR:
2e15497c 11254 check_cp0_enabled(ctx);
d75c135e 11255 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11256 gen_load_srsgpr(rt, rs);
11257 break;
11258 case WRPGPR:
2e15497c 11259 check_cp0_enabled(ctx);
d75c135e 11260 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11261 gen_store_srsgpr(rt, rs);
11262 break;
11263 default:
11264 goto pool32axf_invalid;
11265 }
11266 break;
11267#ifndef CONFIG_USER_ONLY
11268 case 0x0d:
11269 switch (minor) {
11270 case TLBP:
11271 mips32_op = OPC_TLBP;
11272 goto do_cp0;
11273 case TLBR:
11274 mips32_op = OPC_TLBR;
11275 goto do_cp0;
11276 case TLBWI:
11277 mips32_op = OPC_TLBWI;
11278 goto do_cp0;
11279 case TLBWR:
11280 mips32_op = OPC_TLBWR;
11281 goto do_cp0;
11282 case WAIT:
11283 mips32_op = OPC_WAIT;
11284 goto do_cp0;
11285 case DERET:
11286 mips32_op = OPC_DERET;
11287 goto do_cp0;
11288 case ERET:
11289 mips32_op = OPC_ERET;
11290 do_cp0:
11291 gen_cp0(env, ctx, mips32_op, rt, rs);
11292 break;
11293 default:
11294 goto pool32axf_invalid;
11295 }
11296 break;
11297 case 0x1d:
11298 switch (minor) {
11299 case DI:
2e15497c 11300 check_cp0_enabled(ctx);
3c824109
NF
11301 {
11302 TCGv t0 = tcg_temp_new();
11303
11304 save_cpu_state(ctx, 1);
895c2d04 11305 gen_helper_di(t0, cpu_env);
3c824109
NF
11306 gen_store_gpr(t0, rs);
11307 /* Stop translation as we may have switched the execution mode */
11308 ctx->bstate = BS_STOP;
11309 tcg_temp_free(t0);
11310 }
11311 break;
11312 case EI:
2e15497c 11313 check_cp0_enabled(ctx);
3c824109
NF
11314 {
11315 TCGv t0 = tcg_temp_new();
11316
11317 save_cpu_state(ctx, 1);
895c2d04 11318 gen_helper_ei(t0, cpu_env);
3c824109
NF
11319 gen_store_gpr(t0, rs);
11320 /* Stop translation as we may have switched the execution mode */
11321 ctx->bstate = BS_STOP;
11322 tcg_temp_free(t0);
11323 }
11324 break;
11325 default:
11326 goto pool32axf_invalid;
11327 }
11328 break;
11329#endif
11330 case 0x2d:
11331 switch (minor) {
11332 case SYNC:
11333 /* NOP */
11334 break;
11335 case SYSCALL:
11336 generate_exception(ctx, EXCP_SYSCALL);
11337 ctx->bstate = BS_STOP;
11338 break;
11339 case SDBBP:
d75c135e 11340 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11341 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11342 generate_exception(ctx, EXCP_DBp);
11343 } else {
11344 generate_exception(ctx, EXCP_DBp);
11345 }
11346 break;
11347 default:
11348 goto pool32axf_invalid;
11349 }
11350 break;
a1fc6246 11351 case 0x01:
26135ead 11352 switch (minor & 3) {
a1fc6246 11353 case MFHI_ACC:
26135ead 11354 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 11355 break;
a1fc6246 11356 case MFLO_ACC:
26135ead 11357 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 11358 break;
a1fc6246 11359 case MTHI_ACC:
26135ead 11360 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 11361 break;
a1fc6246 11362 case MTLO_ACC:
26135ead 11363 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
11364 break;
11365 default:
11366 goto pool32axf_invalid;
11367 }
11368 break;
a1fc6246
LA
11369 case 0x35:
11370 switch (minor) {
11371 case MFHI32:
11372 gen_HILO(ctx, OPC_MFHI, 0, rs);
11373 break;
11374 case MFLO32:
11375 gen_HILO(ctx, OPC_MFLO, 0, rs);
11376 break;
11377 case MTHI32:
11378 gen_HILO(ctx, OPC_MTHI, 0, rs);
11379 break;
11380 case MTLO32:
11381 gen_HILO(ctx, OPC_MTLO, 0, rs);
11382 break;
11383 default:
11384 goto pool32axf_invalid;
11385 }
11386 break;
3c824109
NF
11387 default:
11388 pool32axf_invalid:
11389 MIPS_INVAL("pool32axf");
11390 generate_exception(ctx, EXCP_RI);
11391 break;
11392 }
11393}
11394
11395/* Values for microMIPS fmt field. Variable-width, depending on which
11396 formats the instruction supports. */
11397
11398enum {
11399 FMT_SD_S = 0,
11400 FMT_SD_D = 1,
11401
11402 FMT_SDPS_S = 0,
11403 FMT_SDPS_D = 1,
11404 FMT_SDPS_PS = 2,
11405
11406 FMT_SWL_S = 0,
11407 FMT_SWL_W = 1,
11408 FMT_SWL_L = 2,
11409
11410 FMT_DWL_D = 0,
11411 FMT_DWL_W = 1,
11412 FMT_DWL_L = 2
11413};
11414
d75c135e 11415static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11416{
11417 int extension = (ctx->opcode >> 6) & 0x3ff;
11418 uint32_t mips32_op;
11419
11420#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11421#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11422#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11423
11424 switch (extension) {
11425 case FLOAT_1BIT_FMT(CFC1, 0):
11426 mips32_op = OPC_CFC1;
11427 goto do_cp1;
11428 case FLOAT_1BIT_FMT(CTC1, 0):
11429 mips32_op = OPC_CTC1;
11430 goto do_cp1;
11431 case FLOAT_1BIT_FMT(MFC1, 0):
11432 mips32_op = OPC_MFC1;
11433 goto do_cp1;
11434 case FLOAT_1BIT_FMT(MTC1, 0):
11435 mips32_op = OPC_MTC1;
11436 goto do_cp1;
11437 case FLOAT_1BIT_FMT(MFHC1, 0):
11438 mips32_op = OPC_MFHC1;
11439 goto do_cp1;
11440 case FLOAT_1BIT_FMT(MTHC1, 0):
11441 mips32_op = OPC_MTHC1;
11442 do_cp1:
11443 gen_cp1(ctx, mips32_op, rt, rs);
11444 break;
11445
11446 /* Reciprocal square root */
11447 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11448 mips32_op = OPC_RSQRT_S;
11449 goto do_unaryfp;
11450 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11451 mips32_op = OPC_RSQRT_D;
11452 goto do_unaryfp;
11453
11454 /* Square root */
11455 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11456 mips32_op = OPC_SQRT_S;
11457 goto do_unaryfp;
11458 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11459 mips32_op = OPC_SQRT_D;
11460 goto do_unaryfp;
11461
11462 /* Reciprocal */
11463 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11464 mips32_op = OPC_RECIP_S;
11465 goto do_unaryfp;
11466 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11467 mips32_op = OPC_RECIP_D;
11468 goto do_unaryfp;
11469
11470 /* Floor */
11471 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11472 mips32_op = OPC_FLOOR_L_S;
11473 goto do_unaryfp;
11474 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11475 mips32_op = OPC_FLOOR_L_D;
11476 goto do_unaryfp;
11477 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11478 mips32_op = OPC_FLOOR_W_S;
11479 goto do_unaryfp;
11480 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11481 mips32_op = OPC_FLOOR_W_D;
11482 goto do_unaryfp;
11483
11484 /* Ceiling */
11485 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11486 mips32_op = OPC_CEIL_L_S;
11487 goto do_unaryfp;
11488 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11489 mips32_op = OPC_CEIL_L_D;
11490 goto do_unaryfp;
11491 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11492 mips32_op = OPC_CEIL_W_S;
11493 goto do_unaryfp;
11494 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11495 mips32_op = OPC_CEIL_W_D;
11496 goto do_unaryfp;
11497
11498 /* Truncation */
11499 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11500 mips32_op = OPC_TRUNC_L_S;
11501 goto do_unaryfp;
11502 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11503 mips32_op = OPC_TRUNC_L_D;
11504 goto do_unaryfp;
11505 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11506 mips32_op = OPC_TRUNC_W_S;
11507 goto do_unaryfp;
11508 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11509 mips32_op = OPC_TRUNC_W_D;
11510 goto do_unaryfp;
11511
11512 /* Round */
11513 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11514 mips32_op = OPC_ROUND_L_S;
11515 goto do_unaryfp;
11516 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11517 mips32_op = OPC_ROUND_L_D;
11518 goto do_unaryfp;
11519 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11520 mips32_op = OPC_ROUND_W_S;
11521 goto do_unaryfp;
11522 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11523 mips32_op = OPC_ROUND_W_D;
11524 goto do_unaryfp;
11525
11526 /* Integer to floating-point conversion */
11527 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11528 mips32_op = OPC_CVT_L_S;
11529 goto do_unaryfp;
11530 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11531 mips32_op = OPC_CVT_L_D;
11532 goto do_unaryfp;
11533 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11534 mips32_op = OPC_CVT_W_S;
11535 goto do_unaryfp;
11536 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11537 mips32_op = OPC_CVT_W_D;
11538 goto do_unaryfp;
11539
11540 /* Paired-foo conversions */
11541 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11542 mips32_op = OPC_CVT_S_PL;
11543 goto do_unaryfp;
11544 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11545 mips32_op = OPC_CVT_S_PU;
11546 goto do_unaryfp;
11547 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11548 mips32_op = OPC_CVT_PW_PS;
11549 goto do_unaryfp;
11550 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11551 mips32_op = OPC_CVT_PS_PW;
11552 goto do_unaryfp;
11553
11554 /* Floating-point moves */
11555 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11556 mips32_op = OPC_MOV_S;
11557 goto do_unaryfp;
11558 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11559 mips32_op = OPC_MOV_D;
11560 goto do_unaryfp;
11561 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11562 mips32_op = OPC_MOV_PS;
11563 goto do_unaryfp;
11564
11565 /* Absolute value */
11566 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11567 mips32_op = OPC_ABS_S;
11568 goto do_unaryfp;
11569 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11570 mips32_op = OPC_ABS_D;
11571 goto do_unaryfp;
11572 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11573 mips32_op = OPC_ABS_PS;
11574 goto do_unaryfp;
11575
11576 /* Negation */
11577 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11578 mips32_op = OPC_NEG_S;
11579 goto do_unaryfp;
11580 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11581 mips32_op = OPC_NEG_D;
11582 goto do_unaryfp;
11583 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11584 mips32_op = OPC_NEG_PS;
11585 goto do_unaryfp;
11586
11587 /* Reciprocal square root step */
11588 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11589 mips32_op = OPC_RSQRT1_S;
11590 goto do_unaryfp;
11591 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11592 mips32_op = OPC_RSQRT1_D;
11593 goto do_unaryfp;
11594 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11595 mips32_op = OPC_RSQRT1_PS;
11596 goto do_unaryfp;
11597
11598 /* Reciprocal step */
11599 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11600 mips32_op = OPC_RECIP1_S;
11601 goto do_unaryfp;
11602 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11603 mips32_op = OPC_RECIP1_S;
11604 goto do_unaryfp;
11605 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11606 mips32_op = OPC_RECIP1_PS;
11607 goto do_unaryfp;
11608
11609 /* Conversions from double */
11610 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11611 mips32_op = OPC_CVT_D_S;
11612 goto do_unaryfp;
11613 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11614 mips32_op = OPC_CVT_D_W;
11615 goto do_unaryfp;
11616 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11617 mips32_op = OPC_CVT_D_L;
11618 goto do_unaryfp;
11619
11620 /* Conversions from single */
11621 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11622 mips32_op = OPC_CVT_S_D;
11623 goto do_unaryfp;
11624 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11625 mips32_op = OPC_CVT_S_W;
11626 goto do_unaryfp;
11627 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11628 mips32_op = OPC_CVT_S_L;
11629 do_unaryfp:
11630 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11631 break;
11632
11633 /* Conditional moves on floating-point codes */
11634 case COND_FLOAT_MOV(MOVT, 0):
11635 case COND_FLOAT_MOV(MOVT, 1):
11636 case COND_FLOAT_MOV(MOVT, 2):
11637 case COND_FLOAT_MOV(MOVT, 3):
11638 case COND_FLOAT_MOV(MOVT, 4):
11639 case COND_FLOAT_MOV(MOVT, 5):
11640 case COND_FLOAT_MOV(MOVT, 6):
11641 case COND_FLOAT_MOV(MOVT, 7):
11642 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11643 break;
11644 case COND_FLOAT_MOV(MOVF, 0):
11645 case COND_FLOAT_MOV(MOVF, 1):
11646 case COND_FLOAT_MOV(MOVF, 2):
11647 case COND_FLOAT_MOV(MOVF, 3):
11648 case COND_FLOAT_MOV(MOVF, 4):
11649 case COND_FLOAT_MOV(MOVF, 5):
11650 case COND_FLOAT_MOV(MOVF, 6):
11651 case COND_FLOAT_MOV(MOVF, 7):
11652 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11653 break;
11654 default:
11655 MIPS_INVAL("pool32fxf");
11656 generate_exception(ctx, EXCP_RI);
11657 break;
11658 }
11659}
11660
7db13fae 11661static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 11662 uint16_t insn_hw1)
3c824109
NF
11663{
11664 int32_t offset;
11665 uint16_t insn;
11666 int rt, rs, rd, rr;
11667 int16_t imm;
11668 uint32_t op, minor, mips32_op;
11669 uint32_t cond, fmt, cc;
11670
895c2d04 11671 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11672 ctx->opcode = (ctx->opcode << 16) | insn;
11673
11674 rt = (ctx->opcode >> 21) & 0x1f;
11675 rs = (ctx->opcode >> 16) & 0x1f;
11676 rd = (ctx->opcode >> 11) & 0x1f;
11677 rr = (ctx->opcode >> 6) & 0x1f;
11678 imm = (int16_t) ctx->opcode;
11679
11680 op = (ctx->opcode >> 26) & 0x3f;
11681 switch (op) {
11682 case POOL32A:
11683 minor = ctx->opcode & 0x3f;
11684 switch (minor) {
11685 case 0x00:
11686 minor = (ctx->opcode >> 6) & 0xf;
11687 switch (minor) {
11688 case SLL32:
11689 mips32_op = OPC_SLL;
11690 goto do_shifti;
11691 case SRA:
11692 mips32_op = OPC_SRA;
11693 goto do_shifti;
11694 case SRL32:
11695 mips32_op = OPC_SRL;
11696 goto do_shifti;
11697 case ROTR:
11698 mips32_op = OPC_ROTR;
11699 do_shifti:
d75c135e 11700 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
11701 break;
11702 default:
11703 goto pool32a_invalid;
11704 }
11705 break;
11706 case 0x10:
11707 minor = (ctx->opcode >> 6) & 0xf;
11708 switch (minor) {
11709 /* Arithmetic */
11710 case ADD:
11711 mips32_op = OPC_ADD;
11712 goto do_arith;
11713 case ADDU32:
11714 mips32_op = OPC_ADDU;
11715 goto do_arith;
11716 case SUB:
11717 mips32_op = OPC_SUB;
11718 goto do_arith;
11719 case SUBU32:
11720 mips32_op = OPC_SUBU;
11721 goto do_arith;
11722 case MUL:
11723 mips32_op = OPC_MUL;
11724 do_arith:
d75c135e 11725 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11726 break;
11727 /* Shifts */
11728 case SLLV:
11729 mips32_op = OPC_SLLV;
11730 goto do_shift;
11731 case SRLV:
11732 mips32_op = OPC_SRLV;
11733 goto do_shift;
11734 case SRAV:
11735 mips32_op = OPC_SRAV;
11736 goto do_shift;
11737 case ROTRV:
11738 mips32_op = OPC_ROTRV;
11739 do_shift:
d75c135e 11740 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11741 break;
11742 /* Logical operations */
11743 case AND:
11744 mips32_op = OPC_AND;
11745 goto do_logic;
11746 case OR32:
11747 mips32_op = OPC_OR;
11748 goto do_logic;
11749 case NOR:
11750 mips32_op = OPC_NOR;
11751 goto do_logic;
11752 case XOR32:
11753 mips32_op = OPC_XOR;
11754 do_logic:
d75c135e 11755 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11756 break;
11757 /* Set less than */
11758 case SLT:
11759 mips32_op = OPC_SLT;
11760 goto do_slt;
11761 case SLTU:
11762 mips32_op = OPC_SLTU;
11763 do_slt:
d75c135e 11764 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11765 break;
11766 default:
11767 goto pool32a_invalid;
11768 }
11769 break;
11770 case 0x18:
11771 minor = (ctx->opcode >> 6) & 0xf;
11772 switch (minor) {
11773 /* Conditional moves */
11774 case MOVN:
11775 mips32_op = OPC_MOVN;
11776 goto do_cmov;
11777 case MOVZ:
11778 mips32_op = OPC_MOVZ;
11779 do_cmov:
d75c135e 11780 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11781 break;
11782 case LWXS:
11783 gen_ldxs(ctx, rs, rt, rd);
11784 break;
11785 default:
11786 goto pool32a_invalid;
11787 }
11788 break;
11789 case INS:
11790 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11791 return;
11792 case EXT:
11793 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11794 return;
11795 case POOL32AXF:
240ce26a 11796 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
11797 break;
11798 case 0x07:
11799 generate_exception(ctx, EXCP_BREAK);
11800 break;
11801 default:
11802 pool32a_invalid:
11803 MIPS_INVAL("pool32a");
11804 generate_exception(ctx, EXCP_RI);
11805 break;
11806 }
11807 break;
11808 case POOL32B:
11809 minor = (ctx->opcode >> 12) & 0xf;
11810 switch (minor) {
11811 case CACHE:
2e15497c 11812 check_cp0_enabled(ctx);
3c824109
NF
11813 /* Treat as no-op. */
11814 break;
11815 case LWC2:
11816 case SWC2:
11817 /* COP2: Not implemented. */
11818 generate_exception_err(ctx, EXCP_CpU, 2);
11819 break;
11820 case LWP:
11821 case SWP:
11822#ifdef TARGET_MIPS64
11823 case LDP:
11824 case SDP:
11825#endif
11826 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11827 break;
11828 case LWM32:
11829 case SWM32:
11830#ifdef TARGET_MIPS64
11831 case LDM:
11832 case SDM:
11833#endif
11834 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11835 break;
11836 default:
11837 MIPS_INVAL("pool32b");
11838 generate_exception(ctx, EXCP_RI);
11839 break;
11840 }
11841 break;
11842 case POOL32F:
5ab5c041 11843 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
11844 minor = ctx->opcode & 0x3f;
11845 check_cp1_enabled(ctx);
11846 switch (minor) {
11847 case ALNV_PS:
11848 mips32_op = OPC_ALNV_PS;
11849 goto do_madd;
11850 case MADD_S:
11851 mips32_op = OPC_MADD_S;
11852 goto do_madd;
11853 case MADD_D:
11854 mips32_op = OPC_MADD_D;
11855 goto do_madd;
11856 case MADD_PS:
11857 mips32_op = OPC_MADD_PS;
11858 goto do_madd;
11859 case MSUB_S:
11860 mips32_op = OPC_MSUB_S;
11861 goto do_madd;
11862 case MSUB_D:
11863 mips32_op = OPC_MSUB_D;
11864 goto do_madd;
11865 case MSUB_PS:
11866 mips32_op = OPC_MSUB_PS;
11867 goto do_madd;
11868 case NMADD_S:
11869 mips32_op = OPC_NMADD_S;
11870 goto do_madd;
11871 case NMADD_D:
11872 mips32_op = OPC_NMADD_D;
11873 goto do_madd;
11874 case NMADD_PS:
11875 mips32_op = OPC_NMADD_PS;
11876 goto do_madd;
11877 case NMSUB_S:
11878 mips32_op = OPC_NMSUB_S;
11879 goto do_madd;
11880 case NMSUB_D:
11881 mips32_op = OPC_NMSUB_D;
11882 goto do_madd;
11883 case NMSUB_PS:
11884 mips32_op = OPC_NMSUB_PS;
11885 do_madd:
11886 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11887 break;
11888 case CABS_COND_FMT:
11889 cond = (ctx->opcode >> 6) & 0xf;
11890 cc = (ctx->opcode >> 13) & 0x7;
11891 fmt = (ctx->opcode >> 10) & 0x3;
11892 switch (fmt) {
11893 case 0x0:
11894 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11895 break;
11896 case 0x1:
11897 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11898 break;
11899 case 0x2:
11900 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11901 break;
11902 default:
11903 goto pool32f_invalid;
11904 }
11905 break;
11906 case C_COND_FMT:
11907 cond = (ctx->opcode >> 6) & 0xf;
11908 cc = (ctx->opcode >> 13) & 0x7;
11909 fmt = (ctx->opcode >> 10) & 0x3;
11910 switch (fmt) {
11911 case 0x0:
11912 gen_cmp_s(ctx, cond, rt, rs, cc);
11913 break;
11914 case 0x1:
11915 gen_cmp_d(ctx, cond, rt, rs, cc);
11916 break;
11917 case 0x2:
11918 gen_cmp_ps(ctx, cond, rt, rs, cc);
11919 break;
11920 default:
11921 goto pool32f_invalid;
11922 }
11923 break;
11924 case POOL32FXF:
d75c135e 11925 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
11926 break;
11927 case 0x00:
11928 /* PLL foo */
11929 switch ((ctx->opcode >> 6) & 0x7) {
11930 case PLL_PS:
11931 mips32_op = OPC_PLL_PS;
11932 goto do_ps;
11933 case PLU_PS:
11934 mips32_op = OPC_PLU_PS;
11935 goto do_ps;
11936 case PUL_PS:
11937 mips32_op = OPC_PUL_PS;
11938 goto do_ps;
11939 case PUU_PS:
11940 mips32_op = OPC_PUU_PS;
11941 goto do_ps;
11942 case CVT_PS_S:
11943 mips32_op = OPC_CVT_PS_S;
11944 do_ps:
11945 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11946 break;
11947 default:
11948 goto pool32f_invalid;
11949 }
11950 break;
11951 case 0x08:
11952 /* [LS][WDU]XC1 */
11953 switch ((ctx->opcode >> 6) & 0x7) {
11954 case LWXC1:
11955 mips32_op = OPC_LWXC1;
11956 goto do_ldst_cp1;
11957 case SWXC1:
11958 mips32_op = OPC_SWXC1;
11959 goto do_ldst_cp1;
11960 case LDXC1:
11961 mips32_op = OPC_LDXC1;
11962 goto do_ldst_cp1;
11963 case SDXC1:
11964 mips32_op = OPC_SDXC1;
11965 goto do_ldst_cp1;
11966 case LUXC1:
11967 mips32_op = OPC_LUXC1;
11968 goto do_ldst_cp1;
11969 case SUXC1:
11970 mips32_op = OPC_SUXC1;
11971 do_ldst_cp1:
11972 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11973 break;
11974 default:
11975 goto pool32f_invalid;
11976 }
11977 break;
11978 case 0x18:
11979 /* 3D insns */
11980 fmt = (ctx->opcode >> 9) & 0x3;
11981 switch ((ctx->opcode >> 6) & 0x7) {
11982 case RSQRT2_FMT:
11983 switch (fmt) {
11984 case FMT_SDPS_S:
11985 mips32_op = OPC_RSQRT2_S;
11986 goto do_3d;
11987 case FMT_SDPS_D:
11988 mips32_op = OPC_RSQRT2_D;
11989 goto do_3d;
11990 case FMT_SDPS_PS:
11991 mips32_op = OPC_RSQRT2_PS;
11992 goto do_3d;
11993 default:
11994 goto pool32f_invalid;
11995 }
11996 break;
11997 case RECIP2_FMT:
11998 switch (fmt) {
11999 case FMT_SDPS_S:
12000 mips32_op = OPC_RECIP2_S;
12001 goto do_3d;
12002 case FMT_SDPS_D:
12003 mips32_op = OPC_RECIP2_D;
12004 goto do_3d;
12005 case FMT_SDPS_PS:
12006 mips32_op = OPC_RECIP2_PS;
12007 goto do_3d;
12008 default:
12009 goto pool32f_invalid;
12010 }
12011 break;
12012 case ADDR_PS:
12013 mips32_op = OPC_ADDR_PS;
12014 goto do_3d;
12015 case MULR_PS:
12016 mips32_op = OPC_MULR_PS;
12017 do_3d:
12018 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12019 break;
12020 default:
12021 goto pool32f_invalid;
12022 }
12023 break;
12024 case 0x20:
12025 /* MOV[FT].fmt and PREFX */
12026 cc = (ctx->opcode >> 13) & 0x7;
12027 fmt = (ctx->opcode >> 9) & 0x3;
12028 switch ((ctx->opcode >> 6) & 0x7) {
12029 case MOVF_FMT:
12030 switch (fmt) {
12031 case FMT_SDPS_S:
12032 gen_movcf_s(rs, rt, cc, 0);
12033 break;
12034 case FMT_SDPS_D:
12035 gen_movcf_d(ctx, rs, rt, cc, 0);
12036 break;
12037 case FMT_SDPS_PS:
7f6613ce 12038 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
12039 break;
12040 default:
12041 goto pool32f_invalid;
12042 }
12043 break;
12044 case MOVT_FMT:
12045 switch (fmt) {
12046 case FMT_SDPS_S:
12047 gen_movcf_s(rs, rt, cc, 1);
12048 break;
12049 case FMT_SDPS_D:
12050 gen_movcf_d(ctx, rs, rt, cc, 1);
12051 break;
12052 case FMT_SDPS_PS:
7f6613ce 12053 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
12054 break;
12055 default:
12056 goto pool32f_invalid;
12057 }
12058 break;
12059 case PREFX:
12060 break;
12061 default:
12062 goto pool32f_invalid;
12063 }
12064 break;
12065#define FINSN_3ARG_SDPS(prfx) \
12066 switch ((ctx->opcode >> 8) & 0x3) { \
12067 case FMT_SDPS_S: \
12068 mips32_op = OPC_##prfx##_S; \
12069 goto do_fpop; \
12070 case FMT_SDPS_D: \
12071 mips32_op = OPC_##prfx##_D; \
12072 goto do_fpop; \
12073 case FMT_SDPS_PS: \
12074 mips32_op = OPC_##prfx##_PS; \
12075 goto do_fpop; \
12076 default: \
12077 goto pool32f_invalid; \
12078 }
12079 case 0x30:
12080 /* regular FP ops */
12081 switch ((ctx->opcode >> 6) & 0x3) {
12082 case ADD_FMT:
12083 FINSN_3ARG_SDPS(ADD);
12084 break;
12085 case SUB_FMT:
12086 FINSN_3ARG_SDPS(SUB);
12087 break;
12088 case MUL_FMT:
12089 FINSN_3ARG_SDPS(MUL);
12090 break;
12091 case DIV_FMT:
12092 fmt = (ctx->opcode >> 8) & 0x3;
12093 if (fmt == 1) {
12094 mips32_op = OPC_DIV_D;
12095 } else if (fmt == 0) {
12096 mips32_op = OPC_DIV_S;
12097 } else {
12098 goto pool32f_invalid;
12099 }
12100 goto do_fpop;
12101 default:
12102 goto pool32f_invalid;
12103 }
12104 break;
12105 case 0x38:
12106 /* cmovs */
12107 switch ((ctx->opcode >> 6) & 0x3) {
12108 case MOVN_FMT:
12109 FINSN_3ARG_SDPS(MOVN);
12110 break;
12111 case MOVZ_FMT:
12112 FINSN_3ARG_SDPS(MOVZ);
12113 break;
12114 default:
12115 goto pool32f_invalid;
12116 }
12117 break;
12118 do_fpop:
12119 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12120 break;
12121 default:
12122 pool32f_invalid:
12123 MIPS_INVAL("pool32f");
12124 generate_exception(ctx, EXCP_RI);
12125 break;
12126 }
12127 } else {
12128 generate_exception_err(ctx, EXCP_CpU, 1);
12129 }
12130 break;
12131 case POOL32I:
12132 minor = (ctx->opcode >> 21) & 0x1f;
12133 switch (minor) {
12134 case BLTZ:
12135 mips32_op = OPC_BLTZ;
12136 goto do_branch;
12137 case BLTZAL:
12138 mips32_op = OPC_BLTZAL;
12139 goto do_branch;
12140 case BLTZALS:
12141 mips32_op = OPC_BLTZALS;
12142 goto do_branch;
12143 case BGEZ:
12144 mips32_op = OPC_BGEZ;
12145 goto do_branch;
12146 case BGEZAL:
12147 mips32_op = OPC_BGEZAL;
12148 goto do_branch;
12149 case BGEZALS:
12150 mips32_op = OPC_BGEZALS;
12151 goto do_branch;
12152 case BLEZ:
12153 mips32_op = OPC_BLEZ;
12154 goto do_branch;
12155 case BGTZ:
12156 mips32_op = OPC_BGTZ;
12157 do_branch:
12158 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
3c824109
NF
12159 break;
12160
12161 /* Traps */
12162 case TLTI:
12163 mips32_op = OPC_TLTI;
12164 goto do_trapi;
12165 case TGEI:
12166 mips32_op = OPC_TGEI;
12167 goto do_trapi;
12168 case TLTIU:
12169 mips32_op = OPC_TLTIU;
12170 goto do_trapi;
12171 case TGEIU:
12172 mips32_op = OPC_TGEIU;
12173 goto do_trapi;
12174 case TNEI:
12175 mips32_op = OPC_TNEI;
12176 goto do_trapi;
12177 case TEQI:
12178 mips32_op = OPC_TEQI;
12179 do_trapi:
12180 gen_trap(ctx, mips32_op, rs, -1, imm);
12181 break;
12182
12183 case BNEZC:
12184 case BEQZC:
12185 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12186 4, rs, 0, imm << 1);
12187 /* Compact branches don't have a delay slot, so just let
12188 the normal delay slot handling take us to the branch
12189 target. */
12190 break;
12191 case LUI:
d75c135e 12192 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12193 break;
12194 case SYNCI:
12195 break;
12196 case BC2F:
12197 case BC2T:
12198 /* COP2: Not implemented. */
12199 generate_exception_err(ctx, EXCP_CpU, 2);
12200 break;
12201 case BC1F:
12202 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12203 goto do_cp1branch;
12204 case BC1T:
12205 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12206 goto do_cp1branch;
12207 case BC1ANY4F:
12208 mips32_op = OPC_BC1FANY4;
12209 goto do_cp1mips3d;
12210 case BC1ANY4T:
12211 mips32_op = OPC_BC1TANY4;
12212 do_cp1mips3d:
12213 check_cop1x(ctx);
d75c135e 12214 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12215 /* Fall through */
12216 do_cp1branch:
d75c135e 12217 gen_compute_branch1(ctx, mips32_op,
3c824109 12218 (ctx->opcode >> 18) & 0x7, imm << 1);
3c824109
NF
12219 break;
12220 case BPOSGE64:
12221 case BPOSGE32:
12222 /* MIPS DSP: not implemented */
12223 /* Fall through */
12224 default:
12225 MIPS_INVAL("pool32i");
12226 generate_exception(ctx, EXCP_RI);
12227 break;
12228 }
12229 break;
12230 case POOL32C:
12231 minor = (ctx->opcode >> 12) & 0xf;
12232 switch (minor) {
12233 case LWL:
12234 mips32_op = OPC_LWL;
5c13fdfd 12235 goto do_ld_lr;
3c824109
NF
12236 case SWL:
12237 mips32_op = OPC_SWL;
5c13fdfd 12238 goto do_st_lr;
3c824109
NF
12239 case LWR:
12240 mips32_op = OPC_LWR;
5c13fdfd 12241 goto do_ld_lr;
3c824109
NF
12242 case SWR:
12243 mips32_op = OPC_SWR;
5c13fdfd 12244 goto do_st_lr;
3c824109
NF
12245#if defined(TARGET_MIPS64)
12246 case LDL:
12247 mips32_op = OPC_LDL;
5c13fdfd 12248 goto do_ld_lr;
3c824109
NF
12249 case SDL:
12250 mips32_op = OPC_SDL;
5c13fdfd 12251 goto do_st_lr;
3c824109
NF
12252 case LDR:
12253 mips32_op = OPC_LDR;
5c13fdfd 12254 goto do_ld_lr;
3c824109
NF
12255 case SDR:
12256 mips32_op = OPC_SDR;
5c13fdfd 12257 goto do_st_lr;
3c824109
NF
12258 case LWU:
12259 mips32_op = OPC_LWU;
5c13fdfd 12260 goto do_ld_lr;
3c824109
NF
12261 case LLD:
12262 mips32_op = OPC_LLD;
5c13fdfd 12263 goto do_ld_lr;
3c824109
NF
12264#endif
12265 case LL:
12266 mips32_op = OPC_LL;
5c13fdfd
AJ
12267 goto do_ld_lr;
12268 do_ld_lr:
d75c135e 12269 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12270 break;
12271 do_st_lr:
12272 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12273 break;
12274 case SC:
12275 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12276 break;
12277#if defined(TARGET_MIPS64)
12278 case SCD:
12279 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12280 break;
12281#endif
12282 case PREF:
12283 /* Treat as no-op */
12284 break;
12285 default:
12286 MIPS_INVAL("pool32c");
12287 generate_exception(ctx, EXCP_RI);
12288 break;
12289 }
12290 break;
12291 case ADDI32:
12292 mips32_op = OPC_ADDI;
12293 goto do_addi;
12294 case ADDIU32:
12295 mips32_op = OPC_ADDIU;
12296 do_addi:
d75c135e 12297 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12298 break;
12299
12300 /* Logical operations */
12301 case ORI32:
12302 mips32_op = OPC_ORI;
12303 goto do_logici;
12304 case XORI32:
12305 mips32_op = OPC_XORI;
12306 goto do_logici;
12307 case ANDI32:
12308 mips32_op = OPC_ANDI;
12309 do_logici:
d75c135e 12310 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12311 break;
12312
12313 /* Set less than immediate */
12314 case SLTI32:
12315 mips32_op = OPC_SLTI;
12316 goto do_slti;
12317 case SLTIU32:
12318 mips32_op = OPC_SLTIU;
12319 do_slti:
d75c135e 12320 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12321 break;
12322 case JALX32:
12323 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12324 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
3c824109
NF
12325 break;
12326 case JALS32:
12327 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12328 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
3c824109
NF
12329 break;
12330 case BEQ32:
12331 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
3c824109
NF
12332 break;
12333 case BNE32:
12334 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
3c824109
NF
12335 break;
12336 case J32:
12337 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12338 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12339 break;
12340 case JAL32:
12341 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12342 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12343 break;
12344 /* Floating point (COP1) */
12345 case LWC132:
12346 mips32_op = OPC_LWC1;
12347 goto do_cop1;
12348 case LDC132:
12349 mips32_op = OPC_LDC1;
12350 goto do_cop1;
12351 case SWC132:
12352 mips32_op = OPC_SWC1;
12353 goto do_cop1;
12354 case SDC132:
12355 mips32_op = OPC_SDC1;
12356 do_cop1:
5ab5c041 12357 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12358 break;
12359 case ADDIUPC:
12360 {
12361 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12362 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12363
12364 gen_addiupc(ctx, reg, offset, 0, 0);
12365 }
12366 break;
12367 /* Loads and stores */
12368 case LB32:
12369 mips32_op = OPC_LB;
5c13fdfd 12370 goto do_ld;
3c824109
NF
12371 case LBU32:
12372 mips32_op = OPC_LBU;
5c13fdfd 12373 goto do_ld;
3c824109
NF
12374 case LH32:
12375 mips32_op = OPC_LH;
5c13fdfd 12376 goto do_ld;
3c824109
NF
12377 case LHU32:
12378 mips32_op = OPC_LHU;
5c13fdfd 12379 goto do_ld;
3c824109
NF
12380 case LW32:
12381 mips32_op = OPC_LW;
5c13fdfd 12382 goto do_ld;
3c824109
NF
12383#ifdef TARGET_MIPS64
12384 case LD32:
12385 mips32_op = OPC_LD;
5c13fdfd 12386 goto do_ld;
3c824109
NF
12387 case SD32:
12388 mips32_op = OPC_SD;
5c13fdfd 12389 goto do_st;
3c824109
NF
12390#endif
12391 case SB32:
12392 mips32_op = OPC_SB;
5c13fdfd 12393 goto do_st;
3c824109
NF
12394 case SH32:
12395 mips32_op = OPC_SH;
5c13fdfd 12396 goto do_st;
3c824109
NF
12397 case SW32:
12398 mips32_op = OPC_SW;
5c13fdfd
AJ
12399 goto do_st;
12400 do_ld:
d75c135e 12401 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12402 break;
12403 do_st:
12404 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12405 break;
12406 default:
12407 generate_exception(ctx, EXCP_RI);
12408 break;
12409 }
12410}
12411
240ce26a 12412static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
12413{
12414 uint32_t op;
12415
12416 /* make sure instructions are on a halfword boundary */
12417 if (ctx->pc & 0x1) {
12418 env->CP0_BadVAddr = ctx->pc;
12419 generate_exception(ctx, EXCP_AdEL);
12420 ctx->bstate = BS_STOP;
12421 return 2;
12422 }
12423
12424 op = (ctx->opcode >> 10) & 0x3f;
12425 /* Enforce properly-sized instructions in a delay slot */
12426 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12427 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12428
12429 switch (op) {
12430 case POOL32A:
12431 case POOL32B:
12432 case POOL32I:
12433 case POOL32C:
12434 case ADDI32:
12435 case ADDIU32:
12436 case ORI32:
12437 case XORI32:
12438 case SLTI32:
12439 case SLTIU32:
12440 case ANDI32:
12441 case JALX32:
12442 case LBU32:
12443 case LHU32:
12444 case POOL32F:
12445 case JALS32:
12446 case BEQ32:
12447 case BNE32:
12448 case J32:
12449 case JAL32:
12450 case SB32:
12451 case SH32:
12452 case POOL32S:
12453 case ADDIUPC:
12454 case SWC132:
12455 case SDC132:
12456 case SD32:
12457 case SW32:
12458 case LB32:
12459 case LH32:
12460 case DADDIU32:
3c824109
NF
12461 case LWC132:
12462 case LDC132:
12463 case LD32:
12464 case LW32:
12465 if (bits & MIPS_HFLAG_BDS16) {
12466 generate_exception(ctx, EXCP_RI);
12467 /* Just stop translation; the user is confused. */
12468 ctx->bstate = BS_STOP;
12469 return 2;
12470 }
12471 break;
12472 case POOL16A:
12473 case POOL16B:
12474 case POOL16C:
12475 case LWGP16:
12476 case POOL16F:
12477 case LBU16:
12478 case LHU16:
12479 case LWSP16:
12480 case LW16:
12481 case SB16:
12482 case SH16:
12483 case SWSP16:
12484 case SW16:
12485 case MOVE16:
12486 case ANDI16:
12487 case POOL16D:
12488 case POOL16E:
12489 case BEQZ16:
12490 case BNEZ16:
12491 case B16:
12492 case LI16:
12493 if (bits & MIPS_HFLAG_BDS32) {
12494 generate_exception(ctx, EXCP_RI);
12495 /* Just stop translation; the user is confused. */
12496 ctx->bstate = BS_STOP;
12497 return 2;
12498 }
12499 break;
12500 default:
12501 break;
12502 }
12503 }
12504 switch (op) {
12505 case POOL16A:
12506 {
12507 int rd = mmreg(uMIPS_RD(ctx->opcode));
12508 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12509 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12510 uint32_t opc = 0;
12511
12512 switch (ctx->opcode & 0x1) {
12513 case ADDU16:
12514 opc = OPC_ADDU;
12515 break;
12516 case SUBU16:
12517 opc = OPC_SUBU;
12518 break;
12519 }
12520
d75c135e 12521 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12522 }
12523 break;
12524 case POOL16B:
12525 {
12526 int rd = mmreg(uMIPS_RD(ctx->opcode));
12527 int rs = mmreg(uMIPS_RS(ctx->opcode));
12528 int amount = (ctx->opcode >> 1) & 0x7;
12529 uint32_t opc = 0;
12530 amount = amount == 0 ? 8 : amount;
12531
12532 switch (ctx->opcode & 0x1) {
12533 case SLL16:
12534 opc = OPC_SLL;
12535 break;
12536 case SRL16:
12537 opc = OPC_SRL;
12538 break;
12539 }
12540
d75c135e 12541 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12542 }
12543 break;
12544 case POOL16C:
240ce26a 12545 gen_pool16c_insn(ctx);
3c824109
NF
12546 break;
12547 case LWGP16:
12548 {
12549 int rd = mmreg(uMIPS_RD(ctx->opcode));
12550 int rb = 28; /* GP */
12551 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12552
d75c135e 12553 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12554 }
12555 break;
12556 case POOL16F:
12557 if (ctx->opcode & 1) {
12558 generate_exception(ctx, EXCP_RI);
12559 } else {
12560 /* MOVEP */
12561 int enc_dest = uMIPS_RD(ctx->opcode);
12562 int enc_rt = uMIPS_RS2(ctx->opcode);
12563 int enc_rs = uMIPS_RS1(ctx->opcode);
12564 int rd, rs, re, rt;
12565 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12566 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12567 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12568
12569 rd = rd_enc[enc_dest];
12570 re = re_enc[enc_dest];
12571 rs = rs_rt_enc[enc_rs];
12572 rt = rs_rt_enc[enc_rt];
12573
d75c135e
AJ
12574 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12575 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12576 }
12577 break;
12578 case LBU16:
12579 {
12580 int rd = mmreg(uMIPS_RD(ctx->opcode));
12581 int rb = mmreg(uMIPS_RS(ctx->opcode));
12582 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12583 offset = (offset == 0xf ? -1 : offset);
12584
d75c135e 12585 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12586 }
12587 break;
12588 case LHU16:
12589 {
12590 int rd = mmreg(uMIPS_RD(ctx->opcode));
12591 int rb = mmreg(uMIPS_RS(ctx->opcode));
12592 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12593
d75c135e 12594 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12595 }
12596 break;
12597 case LWSP16:
12598 {
12599 int rd = (ctx->opcode >> 5) & 0x1f;
12600 int rb = 29; /* SP */
12601 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12602
d75c135e 12603 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12604 }
12605 break;
12606 case LW16:
12607 {
12608 int rd = mmreg(uMIPS_RD(ctx->opcode));
12609 int rb = mmreg(uMIPS_RS(ctx->opcode));
12610 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12611
d75c135e 12612 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12613 }
12614 break;
12615 case SB16:
12616 {
12617 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12618 int rb = mmreg(uMIPS_RS(ctx->opcode));
12619 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12620
5c13fdfd 12621 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12622 }
12623 break;
12624 case SH16:
12625 {
12626 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12627 int rb = mmreg(uMIPS_RS(ctx->opcode));
12628 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12629
5c13fdfd 12630 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12631 }
12632 break;
12633 case SWSP16:
12634 {
12635 int rd = (ctx->opcode >> 5) & 0x1f;
12636 int rb = 29; /* SP */
12637 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12638
5c13fdfd 12639 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12640 }
12641 break;
12642 case SW16:
12643 {
12644 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12645 int rb = mmreg(uMIPS_RS(ctx->opcode));
12646 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12647
5c13fdfd 12648 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12649 }
12650 break;
12651 case MOVE16:
12652 {
12653 int rd = uMIPS_RD5(ctx->opcode);
12654 int rs = uMIPS_RS5(ctx->opcode);
12655
d75c135e 12656 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12657 }
12658 break;
12659 case ANDI16:
d75c135e 12660 gen_andi16(ctx);
3c824109
NF
12661 break;
12662 case POOL16D:
12663 switch (ctx->opcode & 0x1) {
12664 case ADDIUS5:
d75c135e 12665 gen_addius5(ctx);
3c824109
NF
12666 break;
12667 case ADDIUSP:
d75c135e 12668 gen_addiusp(ctx);
3c824109
NF
12669 break;
12670 }
12671 break;
12672 case POOL16E:
12673 switch (ctx->opcode & 0x1) {
12674 case ADDIUR2:
d75c135e 12675 gen_addiur2(ctx);
3c824109
NF
12676 break;
12677 case ADDIUR1SP:
d75c135e 12678 gen_addiur1sp(ctx);
3c824109
NF
12679 break;
12680 }
12681 break;
12682 case B16:
12683 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12684 SIMM(ctx->opcode, 0, 10) << 1);
3c824109
NF
12685 break;
12686 case BNEZ16:
12687 case BEQZ16:
12688 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12689 mmreg(uMIPS_RD(ctx->opcode)),
12690 0, SIMM(ctx->opcode, 0, 7) << 1);
3c824109
NF
12691 break;
12692 case LI16:
12693 {
12694 int reg = mmreg(uMIPS_RD(ctx->opcode));
12695 int imm = ZIMM(ctx->opcode, 0, 7);
12696
12697 imm = (imm == 0x7f ? -1 : imm);
12698 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12699 }
12700 break;
12701 case RES_20:
12702 case RES_28:
12703 case RES_29:
12704 case RES_30:
12705 case RES_31:
12706 case RES_38:
12707 case RES_39:
12708 generate_exception(ctx, EXCP_RI);
12709 break;
12710 default:
240ce26a 12711 decode_micromips32_opc (env, ctx, op);
3c824109
NF
12712 return 4;
12713 }
12714
12715 return 2;
12716}
12717
12718/* SmartMIPS extension to MIPS32 */
12719
12720#if defined(TARGET_MIPS64)
12721
12722/* MDMX extension to MIPS64 */
12723
12724#endif
12725
9b1a1d68 12726/* MIPSDSP functions. */
d75c135e 12727static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12728 int rd, int base, int offset)
12729{
12730 const char *opn = "ldx";
12731 TCGv t0;
12732
9b1a1d68
JL
12733 check_dsp(ctx);
12734 t0 = tcg_temp_new();
12735
12736 if (base == 0) {
12737 gen_load_gpr(t0, offset);
12738 } else if (offset == 0) {
12739 gen_load_gpr(t0, base);
12740 } else {
12741 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12742 }
12743
9b1a1d68
JL
12744 switch (opc) {
12745 case OPC_LBUX:
5f68f5ae 12746 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
12747 gen_store_gpr(t0, rd);
12748 opn = "lbux";
12749 break;
12750 case OPC_LHX:
5f68f5ae 12751 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
12752 gen_store_gpr(t0, rd);
12753 opn = "lhx";
12754 break;
12755 case OPC_LWX:
5f68f5ae 12756 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
12757 gen_store_gpr(t0, rd);
12758 opn = "lwx";
12759 break;
12760#if defined(TARGET_MIPS64)
12761 case OPC_LDX:
5f68f5ae 12762 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
12763 gen_store_gpr(t0, rd);
12764 opn = "ldx";
12765 break;
12766#endif
12767 }
12768 (void)opn; /* avoid a compiler warning */
12769 MIPS_DEBUG("%s %s, %s(%s)", opn,
12770 regnames[rd], regnames[offset], regnames[base]);
12771 tcg_temp_free(t0);
12772}
12773
461c08df
JL
12774static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12775 int ret, int v1, int v2)
12776{
12777 const char *opn = "mipsdsp arith";
12778 TCGv v1_t;
12779 TCGv v2_t;
12780
12781 if (ret == 0) {
12782 /* Treat as NOP. */
12783 MIPS_DEBUG("NOP");
12784 return;
12785 }
12786
12787 v1_t = tcg_temp_new();
12788 v2_t = tcg_temp_new();
12789
12790 gen_load_gpr(v1_t, v1);
12791 gen_load_gpr(v2_t, v2);
12792
12793 switch (op1) {
12794 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12795 case OPC_MULT_G_2E:
12796 check_dspr2(ctx);
12797 switch (op2) {
12798 case OPC_ADDUH_QB:
12799 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12800 break;
12801 case OPC_ADDUH_R_QB:
12802 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12803 break;
12804 case OPC_ADDQH_PH:
12805 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12806 break;
12807 case OPC_ADDQH_R_PH:
12808 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12809 break;
12810 case OPC_ADDQH_W:
12811 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12812 break;
12813 case OPC_ADDQH_R_W:
12814 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12815 break;
12816 case OPC_SUBUH_QB:
12817 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12818 break;
12819 case OPC_SUBUH_R_QB:
12820 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12821 break;
12822 case OPC_SUBQH_PH:
12823 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12824 break;
12825 case OPC_SUBQH_R_PH:
12826 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12827 break;
12828 case OPC_SUBQH_W:
12829 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12830 break;
12831 case OPC_SUBQH_R_W:
12832 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12833 break;
12834 }
12835 break;
12836 case OPC_ABSQ_S_PH_DSP:
12837 switch (op2) {
12838 case OPC_ABSQ_S_QB:
12839 check_dspr2(ctx);
12840 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12841 break;
12842 case OPC_ABSQ_S_PH:
12843 check_dsp(ctx);
12844 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12845 break;
12846 case OPC_ABSQ_S_W:
12847 check_dsp(ctx);
12848 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12849 break;
12850 case OPC_PRECEQ_W_PHL:
12851 check_dsp(ctx);
12852 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12853 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12854 break;
12855 case OPC_PRECEQ_W_PHR:
12856 check_dsp(ctx);
12857 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12858 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12859 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12860 break;
12861 case OPC_PRECEQU_PH_QBL:
12862 check_dsp(ctx);
12863 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12864 break;
12865 case OPC_PRECEQU_PH_QBR:
12866 check_dsp(ctx);
12867 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12868 break;
12869 case OPC_PRECEQU_PH_QBLA:
12870 check_dsp(ctx);
12871 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12872 break;
12873 case OPC_PRECEQU_PH_QBRA:
12874 check_dsp(ctx);
12875 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12876 break;
12877 case OPC_PRECEU_PH_QBL:
12878 check_dsp(ctx);
12879 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12880 break;
12881 case OPC_PRECEU_PH_QBR:
12882 check_dsp(ctx);
12883 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12884 break;
12885 case OPC_PRECEU_PH_QBLA:
12886 check_dsp(ctx);
12887 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12888 break;
12889 case OPC_PRECEU_PH_QBRA:
12890 check_dsp(ctx);
12891 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12892 break;
12893 }
12894 break;
12895 case OPC_ADDU_QB_DSP:
12896 switch (op2) {
12897 case OPC_ADDQ_PH:
12898 check_dsp(ctx);
12899 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12900 break;
12901 case OPC_ADDQ_S_PH:
12902 check_dsp(ctx);
12903 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12904 break;
12905 case OPC_ADDQ_S_W:
12906 check_dsp(ctx);
12907 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12908 break;
12909 case OPC_ADDU_QB:
12910 check_dsp(ctx);
12911 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12912 break;
12913 case OPC_ADDU_S_QB:
12914 check_dsp(ctx);
12915 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12916 break;
12917 case OPC_ADDU_PH:
12918 check_dspr2(ctx);
12919 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12920 break;
12921 case OPC_ADDU_S_PH:
12922 check_dspr2(ctx);
12923 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12924 break;
12925 case OPC_SUBQ_PH:
12926 check_dsp(ctx);
12927 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12928 break;
12929 case OPC_SUBQ_S_PH:
12930 check_dsp(ctx);
12931 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12932 break;
12933 case OPC_SUBQ_S_W:
12934 check_dsp(ctx);
12935 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12936 break;
12937 case OPC_SUBU_QB:
12938 check_dsp(ctx);
12939 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12940 break;
12941 case OPC_SUBU_S_QB:
12942 check_dsp(ctx);
12943 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12944 break;
12945 case OPC_SUBU_PH:
12946 check_dspr2(ctx);
12947 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12948 break;
12949 case OPC_SUBU_S_PH:
12950 check_dspr2(ctx);
12951 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12952 break;
12953 case OPC_ADDSC:
12954 check_dsp(ctx);
12955 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12956 break;
12957 case OPC_ADDWC:
12958 check_dsp(ctx);
12959 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12960 break;
12961 case OPC_MODSUB:
12962 check_dsp(ctx);
12963 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12964 break;
12965 case OPC_RADDU_W_QB:
12966 check_dsp(ctx);
12967 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12968 break;
12969 }
12970 break;
12971 case OPC_CMPU_EQ_QB_DSP:
12972 switch (op2) {
12973 case OPC_PRECR_QB_PH:
12974 check_dspr2(ctx);
12975 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12976 break;
12977 case OPC_PRECRQ_QB_PH:
12978 check_dsp(ctx);
12979 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12980 break;
12981 case OPC_PRECR_SRA_PH_W:
12982 check_dspr2(ctx);
12983 {
12984 TCGv_i32 sa_t = tcg_const_i32(v2);
12985 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12986 cpu_gpr[ret]);
12987 tcg_temp_free_i32(sa_t);
12988 break;
12989 }
12990 case OPC_PRECR_SRA_R_PH_W:
12991 check_dspr2(ctx);
12992 {
12993 TCGv_i32 sa_t = tcg_const_i32(v2);
12994 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12995 cpu_gpr[ret]);
12996 tcg_temp_free_i32(sa_t);
12997 break;
12998 }
12999 case OPC_PRECRQ_PH_W:
13000 check_dsp(ctx);
13001 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
13002 break;
13003 case OPC_PRECRQ_RS_PH_W:
13004 check_dsp(ctx);
13005 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13006 break;
13007 case OPC_PRECRQU_S_QB_PH:
13008 check_dsp(ctx);
13009 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13010 break;
13011 }
13012 break;
13013#ifdef TARGET_MIPS64
13014 case OPC_ABSQ_S_QH_DSP:
13015 switch (op2) {
13016 case OPC_PRECEQ_L_PWL:
13017 check_dsp(ctx);
13018 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
13019 break;
13020 case OPC_PRECEQ_L_PWR:
13021 check_dsp(ctx);
13022 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
13023 break;
13024 case OPC_PRECEQ_PW_QHL:
13025 check_dsp(ctx);
13026 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
13027 break;
13028 case OPC_PRECEQ_PW_QHR:
13029 check_dsp(ctx);
13030 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
13031 break;
13032 case OPC_PRECEQ_PW_QHLA:
13033 check_dsp(ctx);
13034 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
13035 break;
13036 case OPC_PRECEQ_PW_QHRA:
13037 check_dsp(ctx);
13038 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
13039 break;
13040 case OPC_PRECEQU_QH_OBL:
13041 check_dsp(ctx);
13042 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
13043 break;
13044 case OPC_PRECEQU_QH_OBR:
13045 check_dsp(ctx);
13046 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
13047 break;
13048 case OPC_PRECEQU_QH_OBLA:
13049 check_dsp(ctx);
13050 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13051 break;
13052 case OPC_PRECEQU_QH_OBRA:
13053 check_dsp(ctx);
13054 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13055 break;
13056 case OPC_PRECEU_QH_OBL:
13057 check_dsp(ctx);
13058 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13059 break;
13060 case OPC_PRECEU_QH_OBR:
13061 check_dsp(ctx);
13062 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13063 break;
13064 case OPC_PRECEU_QH_OBLA:
13065 check_dsp(ctx);
13066 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13067 break;
13068 case OPC_PRECEU_QH_OBRA:
13069 check_dsp(ctx);
13070 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13071 break;
13072 case OPC_ABSQ_S_OB:
13073 check_dspr2(ctx);
13074 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13075 break;
13076 case OPC_ABSQ_S_PW:
13077 check_dsp(ctx);
13078 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13079 break;
13080 case OPC_ABSQ_S_QH:
13081 check_dsp(ctx);
13082 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13083 break;
13084 }
13085 break;
13086 case OPC_ADDU_OB_DSP:
13087 switch (op2) {
13088 case OPC_RADDU_L_OB:
13089 check_dsp(ctx);
13090 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13091 break;
13092 case OPC_SUBQ_PW:
13093 check_dsp(ctx);
13094 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13095 break;
13096 case OPC_SUBQ_S_PW:
13097 check_dsp(ctx);
13098 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13099 break;
13100 case OPC_SUBQ_QH:
13101 check_dsp(ctx);
13102 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13103 break;
13104 case OPC_SUBQ_S_QH:
13105 check_dsp(ctx);
13106 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13107 break;
13108 case OPC_SUBU_OB:
13109 check_dsp(ctx);
13110 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13111 break;
13112 case OPC_SUBU_S_OB:
13113 check_dsp(ctx);
13114 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13115 break;
13116 case OPC_SUBU_QH:
13117 check_dspr2(ctx);
13118 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13119 break;
13120 case OPC_SUBU_S_QH:
13121 check_dspr2(ctx);
13122 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13123 break;
13124 case OPC_SUBUH_OB:
13125 check_dspr2(ctx);
13126 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13127 break;
13128 case OPC_SUBUH_R_OB:
13129 check_dspr2(ctx);
13130 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13131 break;
13132 case OPC_ADDQ_PW:
13133 check_dsp(ctx);
13134 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13135 break;
13136 case OPC_ADDQ_S_PW:
13137 check_dsp(ctx);
13138 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13139 break;
13140 case OPC_ADDQ_QH:
13141 check_dsp(ctx);
13142 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13143 break;
13144 case OPC_ADDQ_S_QH:
13145 check_dsp(ctx);
13146 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13147 break;
13148 case OPC_ADDU_OB:
13149 check_dsp(ctx);
13150 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13151 break;
13152 case OPC_ADDU_S_OB:
13153 check_dsp(ctx);
13154 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13155 break;
13156 case OPC_ADDU_QH:
13157 check_dspr2(ctx);
13158 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13159 break;
13160 case OPC_ADDU_S_QH:
13161 check_dspr2(ctx);
13162 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13163 break;
13164 case OPC_ADDUH_OB:
13165 check_dspr2(ctx);
13166 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13167 break;
13168 case OPC_ADDUH_R_OB:
13169 check_dspr2(ctx);
13170 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13171 break;
13172 }
13173 break;
13174 case OPC_CMPU_EQ_OB_DSP:
13175 switch (op2) {
13176 case OPC_PRECR_OB_QH:
13177 check_dspr2(ctx);
13178 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13179 break;
13180 case OPC_PRECR_SRA_QH_PW:
13181 check_dspr2(ctx);
13182 {
13183 TCGv_i32 ret_t = tcg_const_i32(ret);
13184 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13185 tcg_temp_free_i32(ret_t);
13186 break;
13187 }
13188 case OPC_PRECR_SRA_R_QH_PW:
13189 check_dspr2(ctx);
13190 {
13191 TCGv_i32 sa_v = tcg_const_i32(ret);
13192 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13193 tcg_temp_free_i32(sa_v);
13194 break;
13195 }
13196 case OPC_PRECRQ_OB_QH:
13197 check_dsp(ctx);
13198 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13199 break;
13200 case OPC_PRECRQ_PW_L:
13201 check_dsp(ctx);
13202 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13203 break;
13204 case OPC_PRECRQ_QH_PW:
13205 check_dsp(ctx);
13206 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13207 break;
13208 case OPC_PRECRQ_RS_QH_PW:
13209 check_dsp(ctx);
13210 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13211 break;
13212 case OPC_PRECRQU_S_OB_QH:
13213 check_dsp(ctx);
13214 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13215 break;
13216 }
13217 break;
13218#endif
13219 }
13220
13221 tcg_temp_free(v1_t);
13222 tcg_temp_free(v2_t);
13223
13224 (void)opn; /* avoid a compiler warning */
13225 MIPS_DEBUG("%s", opn);
13226}
9b1a1d68 13227
77c5fa8b
JL
13228static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13229 int ret, int v1, int v2)
13230{
13231 uint32_t op2;
13232 const char *opn = "mipsdsp shift";
13233 TCGv t0;
13234 TCGv v1_t;
13235 TCGv v2_t;
13236
13237 if (ret == 0) {
13238 /* Treat as NOP. */
13239 MIPS_DEBUG("NOP");
13240 return;
13241 }
13242
13243 t0 = tcg_temp_new();
13244 v1_t = tcg_temp_new();
13245 v2_t = tcg_temp_new();
13246
13247 tcg_gen_movi_tl(t0, v1);
13248 gen_load_gpr(v1_t, v1);
13249 gen_load_gpr(v2_t, v2);
13250
13251 switch (opc) {
13252 case OPC_SHLL_QB_DSP:
13253 {
13254 op2 = MASK_SHLL_QB(ctx->opcode);
13255 switch (op2) {
13256 case OPC_SHLL_QB:
13257 check_dsp(ctx);
13258 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13259 break;
13260 case OPC_SHLLV_QB:
13261 check_dsp(ctx);
13262 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13263 break;
13264 case OPC_SHLL_PH:
13265 check_dsp(ctx);
13266 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13267 break;
13268 case OPC_SHLLV_PH:
13269 check_dsp(ctx);
13270 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13271 break;
13272 case OPC_SHLL_S_PH:
13273 check_dsp(ctx);
13274 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13275 break;
13276 case OPC_SHLLV_S_PH:
13277 check_dsp(ctx);
13278 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13279 break;
13280 case OPC_SHLL_S_W:
13281 check_dsp(ctx);
13282 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13283 break;
13284 case OPC_SHLLV_S_W:
13285 check_dsp(ctx);
13286 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13287 break;
13288 case OPC_SHRL_QB:
13289 check_dsp(ctx);
13290 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13291 break;
13292 case OPC_SHRLV_QB:
13293 check_dsp(ctx);
13294 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13295 break;
13296 case OPC_SHRL_PH:
13297 check_dspr2(ctx);
13298 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13299 break;
13300 case OPC_SHRLV_PH:
13301 check_dspr2(ctx);
13302 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13303 break;
13304 case OPC_SHRA_QB:
13305 check_dspr2(ctx);
13306 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13307 break;
13308 case OPC_SHRA_R_QB:
13309 check_dspr2(ctx);
13310 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13311 break;
13312 case OPC_SHRAV_QB:
13313 check_dspr2(ctx);
13314 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13315 break;
13316 case OPC_SHRAV_R_QB:
13317 check_dspr2(ctx);
13318 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13319 break;
13320 case OPC_SHRA_PH:
13321 check_dsp(ctx);
13322 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13323 break;
13324 case OPC_SHRA_R_PH:
13325 check_dsp(ctx);
13326 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13327 break;
13328 case OPC_SHRAV_PH:
13329 check_dsp(ctx);
13330 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13331 break;
13332 case OPC_SHRAV_R_PH:
13333 check_dsp(ctx);
13334 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13335 break;
13336 case OPC_SHRA_R_W:
13337 check_dsp(ctx);
13338 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13339 break;
13340 case OPC_SHRAV_R_W:
13341 check_dsp(ctx);
13342 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13343 break;
13344 default: /* Invalid */
13345 MIPS_INVAL("MASK SHLL.QB");
13346 generate_exception(ctx, EXCP_RI);
13347 break;
13348 }
13349 break;
13350 }
13351#ifdef TARGET_MIPS64
13352 case OPC_SHLL_OB_DSP:
13353 op2 = MASK_SHLL_OB(ctx->opcode);
13354 switch (op2) {
13355 case OPC_SHLL_PW:
13356 check_dsp(ctx);
13357 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13358 break;
13359 case OPC_SHLLV_PW:
13360 check_dsp(ctx);
13361 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13362 break;
13363 case OPC_SHLL_S_PW:
13364 check_dsp(ctx);
13365 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13366 break;
13367 case OPC_SHLLV_S_PW:
13368 check_dsp(ctx);
13369 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13370 break;
13371 case OPC_SHLL_OB:
13372 check_dsp(ctx);
13373 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13374 break;
13375 case OPC_SHLLV_OB:
13376 check_dsp(ctx);
13377 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13378 break;
13379 case OPC_SHLL_QH:
13380 check_dsp(ctx);
13381 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13382 break;
13383 case OPC_SHLLV_QH:
13384 check_dsp(ctx);
13385 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13386 break;
13387 case OPC_SHLL_S_QH:
13388 check_dsp(ctx);
13389 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13390 break;
13391 case OPC_SHLLV_S_QH:
13392 check_dsp(ctx);
13393 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13394 break;
13395 case OPC_SHRA_OB:
13396 check_dspr2(ctx);
13397 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13398 break;
13399 case OPC_SHRAV_OB:
13400 check_dspr2(ctx);
13401 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13402 break;
13403 case OPC_SHRA_R_OB:
13404 check_dspr2(ctx);
13405 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13406 break;
13407 case OPC_SHRAV_R_OB:
13408 check_dspr2(ctx);
13409 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13410 break;
13411 case OPC_SHRA_PW:
13412 check_dsp(ctx);
13413 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13414 break;
13415 case OPC_SHRAV_PW:
13416 check_dsp(ctx);
13417 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13418 break;
13419 case OPC_SHRA_R_PW:
13420 check_dsp(ctx);
13421 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13422 break;
13423 case OPC_SHRAV_R_PW:
13424 check_dsp(ctx);
13425 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13426 break;
13427 case OPC_SHRA_QH:
13428 check_dsp(ctx);
13429 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13430 break;
13431 case OPC_SHRAV_QH:
13432 check_dsp(ctx);
13433 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13434 break;
13435 case OPC_SHRA_R_QH:
13436 check_dsp(ctx);
13437 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13438 break;
13439 case OPC_SHRAV_R_QH:
13440 check_dsp(ctx);
13441 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13442 break;
13443 case OPC_SHRL_OB:
13444 check_dsp(ctx);
13445 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13446 break;
13447 case OPC_SHRLV_OB:
13448 check_dsp(ctx);
13449 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13450 break;
13451 case OPC_SHRL_QH:
13452 check_dspr2(ctx);
13453 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13454 break;
13455 case OPC_SHRLV_QH:
13456 check_dspr2(ctx);
13457 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13458 break;
13459 default: /* Invalid */
13460 MIPS_INVAL("MASK SHLL.OB");
13461 generate_exception(ctx, EXCP_RI);
13462 break;
13463 }
13464 break;
13465#endif
13466 }
13467
13468 tcg_temp_free(t0);
13469 tcg_temp_free(v1_t);
13470 tcg_temp_free(v2_t);
13471 (void)opn; /* avoid a compiler warning */
13472 MIPS_DEBUG("%s", opn);
13473}
13474
a22260ae
JL
13475static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13476 int ret, int v1, int v2, int check_ret)
13477{
13478 const char *opn = "mipsdsp multiply";
13479 TCGv_i32 t0;
13480 TCGv v1_t;
13481 TCGv v2_t;
13482
13483 if ((ret == 0) && (check_ret == 1)) {
13484 /* Treat as NOP. */
13485 MIPS_DEBUG("NOP");
13486 return;
13487 }
13488
13489 t0 = tcg_temp_new_i32();
13490 v1_t = tcg_temp_new();
13491 v2_t = tcg_temp_new();
13492
13493 tcg_gen_movi_i32(t0, ret);
13494 gen_load_gpr(v1_t, v1);
13495 gen_load_gpr(v2_t, v2);
13496
13497 switch (op1) {
13498 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13499 * the same mask and op1. */
13500 case OPC_MULT_G_2E:
639eadb9 13501 check_dspr2(ctx);
a22260ae
JL
13502 switch (op2) {
13503 case OPC_MUL_PH:
13504 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13505 break;
13506 case OPC_MUL_S_PH:
13507 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13508 break;
13509 case OPC_MULQ_S_W:
13510 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13511 break;
13512 case OPC_MULQ_RS_W:
13513 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13514 break;
13515 }
13516 break;
13517 case OPC_DPA_W_PH_DSP:
13518 switch (op2) {
13519 case OPC_DPAU_H_QBL:
13520 check_dsp(ctx);
13521 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13522 break;
13523 case OPC_DPAU_H_QBR:
13524 check_dsp(ctx);
13525 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13526 break;
13527 case OPC_DPSU_H_QBL:
13528 check_dsp(ctx);
13529 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13530 break;
13531 case OPC_DPSU_H_QBR:
13532 check_dsp(ctx);
13533 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13534 break;
13535 case OPC_DPA_W_PH:
13536 check_dspr2(ctx);
13537 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13538 break;
13539 case OPC_DPAX_W_PH:
13540 check_dspr2(ctx);
13541 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13542 break;
13543 case OPC_DPAQ_S_W_PH:
13544 check_dsp(ctx);
13545 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13546 break;
13547 case OPC_DPAQX_S_W_PH:
13548 check_dspr2(ctx);
13549 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13550 break;
13551 case OPC_DPAQX_SA_W_PH:
13552 check_dspr2(ctx);
13553 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13554 break;
13555 case OPC_DPS_W_PH:
13556 check_dspr2(ctx);
13557 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13558 break;
13559 case OPC_DPSX_W_PH:
13560 check_dspr2(ctx);
13561 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13562 break;
13563 case OPC_DPSQ_S_W_PH:
13564 check_dsp(ctx);
13565 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13566 break;
13567 case OPC_DPSQX_S_W_PH:
13568 check_dspr2(ctx);
13569 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13570 break;
13571 case OPC_DPSQX_SA_W_PH:
13572 check_dspr2(ctx);
13573 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13574 break;
13575 case OPC_MULSAQ_S_W_PH:
13576 check_dsp(ctx);
13577 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13578 break;
13579 case OPC_DPAQ_SA_L_W:
13580 check_dsp(ctx);
13581 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13582 break;
13583 case OPC_DPSQ_SA_L_W:
13584 check_dsp(ctx);
13585 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13586 break;
13587 case OPC_MAQ_S_W_PHL:
13588 check_dsp(ctx);
13589 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13590 break;
13591 case OPC_MAQ_S_W_PHR:
13592 check_dsp(ctx);
13593 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13594 break;
13595 case OPC_MAQ_SA_W_PHL:
13596 check_dsp(ctx);
13597 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13598 break;
13599 case OPC_MAQ_SA_W_PHR:
13600 check_dsp(ctx);
13601 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13602 break;
13603 case OPC_MULSA_W_PH:
13604 check_dspr2(ctx);
13605 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13606 break;
13607 }
13608 break;
13609#ifdef TARGET_MIPS64
13610 case OPC_DPAQ_W_QH_DSP:
13611 {
13612 int ac = ret & 0x03;
13613 tcg_gen_movi_i32(t0, ac);
13614
13615 switch (op2) {
13616 case OPC_DMADD:
13617 check_dsp(ctx);
13618 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13619 break;
13620 case OPC_DMADDU:
13621 check_dsp(ctx);
13622 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13623 break;
13624 case OPC_DMSUB:
13625 check_dsp(ctx);
13626 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13627 break;
13628 case OPC_DMSUBU:
13629 check_dsp(ctx);
13630 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13631 break;
13632 case OPC_DPA_W_QH:
13633 check_dspr2(ctx);
13634 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13635 break;
13636 case OPC_DPAQ_S_W_QH:
13637 check_dsp(ctx);
13638 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13639 break;
13640 case OPC_DPAQ_SA_L_PW:
13641 check_dsp(ctx);
13642 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13643 break;
13644 case OPC_DPAU_H_OBL:
13645 check_dsp(ctx);
13646 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13647 break;
13648 case OPC_DPAU_H_OBR:
13649 check_dsp(ctx);
13650 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13651 break;
13652 case OPC_DPS_W_QH:
13653 check_dspr2(ctx);
13654 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13655 break;
13656 case OPC_DPSQ_S_W_QH:
13657 check_dsp(ctx);
13658 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13659 break;
13660 case OPC_DPSQ_SA_L_PW:
13661 check_dsp(ctx);
13662 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13663 break;
13664 case OPC_DPSU_H_OBL:
13665 check_dsp(ctx);
13666 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13667 break;
13668 case OPC_DPSU_H_OBR:
13669 check_dsp(ctx);
13670 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13671 break;
13672 case OPC_MAQ_S_L_PWL:
13673 check_dsp(ctx);
13674 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13675 break;
13676 case OPC_MAQ_S_L_PWR:
13677 check_dsp(ctx);
13678 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13679 break;
13680 case OPC_MAQ_S_W_QHLL:
13681 check_dsp(ctx);
13682 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13683 break;
13684 case OPC_MAQ_SA_W_QHLL:
13685 check_dsp(ctx);
13686 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13687 break;
13688 case OPC_MAQ_S_W_QHLR:
13689 check_dsp(ctx);
13690 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13691 break;
13692 case OPC_MAQ_SA_W_QHLR:
13693 check_dsp(ctx);
13694 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13695 break;
13696 case OPC_MAQ_S_W_QHRL:
13697 check_dsp(ctx);
13698 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13699 break;
13700 case OPC_MAQ_SA_W_QHRL:
13701 check_dsp(ctx);
13702 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13703 break;
13704 case OPC_MAQ_S_W_QHRR:
13705 check_dsp(ctx);
13706 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13707 break;
13708 case OPC_MAQ_SA_W_QHRR:
13709 check_dsp(ctx);
13710 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13711 break;
13712 case OPC_MULSAQ_S_L_PW:
13713 check_dsp(ctx);
13714 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13715 break;
13716 case OPC_MULSAQ_S_W_QH:
13717 check_dsp(ctx);
13718 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13719 break;
13720 }
13721 }
13722 break;
13723#endif
13724 case OPC_ADDU_QB_DSP:
13725 switch (op2) {
13726 case OPC_MULEU_S_PH_QBL:
13727 check_dsp(ctx);
13728 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13729 break;
13730 case OPC_MULEU_S_PH_QBR:
13731 check_dsp(ctx);
13732 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13733 break;
13734 case OPC_MULQ_RS_PH:
13735 check_dsp(ctx);
13736 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13737 break;
13738 case OPC_MULEQ_S_W_PHL:
13739 check_dsp(ctx);
13740 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13741 break;
13742 case OPC_MULEQ_S_W_PHR:
13743 check_dsp(ctx);
13744 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13745 break;
13746 case OPC_MULQ_S_PH:
13747 check_dspr2(ctx);
13748 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13749 break;
13750 }
13751 break;
13752#ifdef TARGET_MIPS64
13753 case OPC_ADDU_OB_DSP:
13754 switch (op2) {
13755 case OPC_MULEQ_S_PW_QHL:
13756 check_dsp(ctx);
13757 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13758 break;
13759 case OPC_MULEQ_S_PW_QHR:
13760 check_dsp(ctx);
13761 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13762 break;
13763 case OPC_MULEU_S_QH_OBL:
13764 check_dsp(ctx);
13765 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13766 break;
13767 case OPC_MULEU_S_QH_OBR:
13768 check_dsp(ctx);
13769 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13770 break;
13771 case OPC_MULQ_RS_QH:
13772 check_dsp(ctx);
13773 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13774 break;
13775 }
13776 break;
13777#endif
13778 }
13779
13780 tcg_temp_free_i32(t0);
13781 tcg_temp_free(v1_t);
13782 tcg_temp_free(v2_t);
13783
13784 (void)opn; /* avoid a compiler warning */
13785 MIPS_DEBUG("%s", opn);
13786
13787}
13788
d75c135e 13789static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13790 int ret, int val)
13791{
13792 const char *opn = "mipsdsp Bit/ Manipulation";
13793 int16_t imm;
13794 TCGv t0;
13795 TCGv val_t;
13796
13797 if (ret == 0) {
13798 /* Treat as NOP. */
13799 MIPS_DEBUG("NOP");
13800 return;
13801 }
13802
13803 t0 = tcg_temp_new();
13804 val_t = tcg_temp_new();
13805 gen_load_gpr(val_t, val);
13806
13807 switch (op1) {
13808 case OPC_ABSQ_S_PH_DSP:
13809 switch (op2) {
13810 case OPC_BITREV:
13811 check_dsp(ctx);
13812 gen_helper_bitrev(cpu_gpr[ret], val_t);
13813 break;
13814 case OPC_REPL_QB:
13815 check_dsp(ctx);
13816 {
13817 target_long result;
13818 imm = (ctx->opcode >> 16) & 0xFF;
13819 result = (uint32_t)imm << 24 |
13820 (uint32_t)imm << 16 |
13821 (uint32_t)imm << 8 |
13822 (uint32_t)imm;
13823 result = (int32_t)result;
13824 tcg_gen_movi_tl(cpu_gpr[ret], result);
13825 }
13826 break;
13827 case OPC_REPLV_QB:
13828 check_dsp(ctx);
13829 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13830 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13831 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13832 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13833 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13834 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13835 break;
13836 case OPC_REPL_PH:
13837 check_dsp(ctx);
13838 {
13839 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13840 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13841 tcg_gen_movi_tl(cpu_gpr[ret], \
13842 (target_long)((int32_t)imm << 16 | \
c4aaba92 13843 (uint16_t)imm));
1cb6686c
JL
13844 }
13845 break;
13846 case OPC_REPLV_PH:
13847 check_dsp(ctx);
13848 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13849 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13850 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13851 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13852 break;
13853 }
13854 break;
13855#ifdef TARGET_MIPS64
13856 case OPC_ABSQ_S_QH_DSP:
13857 switch (op2) {
13858 case OPC_REPL_OB:
13859 check_dsp(ctx);
13860 {
13861 target_long temp;
13862
13863 imm = (ctx->opcode >> 16) & 0xFF;
13864 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13865 temp = (temp << 16) | temp;
13866 temp = (temp << 32) | temp;
13867 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13868 break;
13869 }
13870 case OPC_REPL_PW:
13871 check_dsp(ctx);
13872 {
13873 target_long temp;
13874
13875 imm = (ctx->opcode >> 16) & 0x03FF;
13876 imm = (int16_t)(imm << 6) >> 6;
13877 temp = ((target_long)imm << 32) \
13878 | ((target_long)imm & 0xFFFFFFFF);
13879 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13880 break;
13881 }
13882 case OPC_REPL_QH:
13883 check_dsp(ctx);
13884 {
13885 target_long temp;
13886
13887 imm = (ctx->opcode >> 16) & 0x03FF;
13888 imm = (int16_t)(imm << 6) >> 6;
13889
13890 temp = ((uint64_t)(uint16_t)imm << 48) |
13891 ((uint64_t)(uint16_t)imm << 32) |
13892 ((uint64_t)(uint16_t)imm << 16) |
13893 (uint64_t)(uint16_t)imm;
13894 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13895 break;
13896 }
13897 case OPC_REPLV_OB:
13898 check_dsp(ctx);
13899 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13900 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13901 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13902 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13903 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13904 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13905 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13906 break;
13907 case OPC_REPLV_PW:
13908 check_dsp(ctx);
13909 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13910 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13911 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13912 break;
13913 case OPC_REPLV_QH:
13914 check_dsp(ctx);
13915 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13916 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13917 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13918 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13919 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13920 break;
13921 }
13922 break;
13923#endif
13924 }
13925 tcg_temp_free(t0);
13926 tcg_temp_free(val_t);
13927
13928 (void)opn; /* avoid a compiler warning */
13929 MIPS_DEBUG("%s", opn);
13930}
13931
26690560
JL
13932static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13933 uint32_t op1, uint32_t op2,
13934 int ret, int v1, int v2, int check_ret)
13935{
13936 const char *opn = "mipsdsp add compare pick";
26690560
JL
13937 TCGv t1;
13938 TCGv v1_t;
13939 TCGv v2_t;
13940
13941 if ((ret == 0) && (check_ret == 1)) {
13942 /* Treat as NOP. */
13943 MIPS_DEBUG("NOP");
13944 return;
13945 }
13946
26690560
JL
13947 t1 = tcg_temp_new();
13948 v1_t = tcg_temp_new();
13949 v2_t = tcg_temp_new();
13950
13951 gen_load_gpr(v1_t, v1);
13952 gen_load_gpr(v2_t, v2);
13953
13954 switch (op1) {
26690560
JL
13955 case OPC_CMPU_EQ_QB_DSP:
13956 switch (op2) {
13957 case OPC_CMPU_EQ_QB:
13958 check_dsp(ctx);
13959 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13960 break;
13961 case OPC_CMPU_LT_QB:
13962 check_dsp(ctx);
13963 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13964 break;
13965 case OPC_CMPU_LE_QB:
13966 check_dsp(ctx);
13967 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13968 break;
13969 case OPC_CMPGU_EQ_QB:
13970 check_dsp(ctx);
13971 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13972 break;
13973 case OPC_CMPGU_LT_QB:
13974 check_dsp(ctx);
13975 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13976 break;
13977 case OPC_CMPGU_LE_QB:
13978 check_dsp(ctx);
13979 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13980 break;
13981 case OPC_CMPGDU_EQ_QB:
13982 check_dspr2(ctx);
13983 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13984 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13985 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13986 tcg_gen_shli_tl(t1, t1, 24);
13987 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13988 break;
13989 case OPC_CMPGDU_LT_QB:
13990 check_dspr2(ctx);
13991 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13992 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13993 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13994 tcg_gen_shli_tl(t1, t1, 24);
13995 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13996 break;
13997 case OPC_CMPGDU_LE_QB:
13998 check_dspr2(ctx);
13999 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
14000 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14001 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14002 tcg_gen_shli_tl(t1, t1, 24);
14003 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14004 break;
14005 case OPC_CMP_EQ_PH:
14006 check_dsp(ctx);
14007 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
14008 break;
14009 case OPC_CMP_LT_PH:
14010 check_dsp(ctx);
14011 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
14012 break;
14013 case OPC_CMP_LE_PH:
14014 check_dsp(ctx);
14015 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
14016 break;
14017 case OPC_PICK_QB:
14018 check_dsp(ctx);
14019 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14020 break;
14021 case OPC_PICK_PH:
14022 check_dsp(ctx);
14023 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14024 break;
14025 case OPC_PACKRL_PH:
14026 check_dsp(ctx);
14027 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
14028 break;
14029 }
14030 break;
14031#ifdef TARGET_MIPS64
14032 case OPC_CMPU_EQ_OB_DSP:
14033 switch (op2) {
14034 case OPC_CMP_EQ_PW:
14035 check_dsp(ctx);
14036 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
14037 break;
14038 case OPC_CMP_LT_PW:
14039 check_dsp(ctx);
14040 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14041 break;
14042 case OPC_CMP_LE_PW:
14043 check_dsp(ctx);
14044 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14045 break;
14046 case OPC_CMP_EQ_QH:
14047 check_dsp(ctx);
14048 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14049 break;
14050 case OPC_CMP_LT_QH:
14051 check_dsp(ctx);
14052 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14053 break;
14054 case OPC_CMP_LE_QH:
14055 check_dsp(ctx);
14056 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14057 break;
14058 case OPC_CMPGDU_EQ_OB:
14059 check_dspr2(ctx);
14060 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14061 break;
14062 case OPC_CMPGDU_LT_OB:
14063 check_dspr2(ctx);
14064 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14065 break;
14066 case OPC_CMPGDU_LE_OB:
14067 check_dspr2(ctx);
14068 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14069 break;
14070 case OPC_CMPGU_EQ_OB:
14071 check_dsp(ctx);
14072 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14073 break;
14074 case OPC_CMPGU_LT_OB:
14075 check_dsp(ctx);
14076 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14077 break;
14078 case OPC_CMPGU_LE_OB:
14079 check_dsp(ctx);
14080 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14081 break;
14082 case OPC_CMPU_EQ_OB:
14083 check_dsp(ctx);
14084 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14085 break;
14086 case OPC_CMPU_LT_OB:
14087 check_dsp(ctx);
14088 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14089 break;
14090 case OPC_CMPU_LE_OB:
14091 check_dsp(ctx);
14092 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14093 break;
14094 case OPC_PACKRL_PW:
14095 check_dsp(ctx);
14096 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14097 break;
14098 case OPC_PICK_OB:
14099 check_dsp(ctx);
14100 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14101 break;
14102 case OPC_PICK_PW:
14103 check_dsp(ctx);
14104 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14105 break;
14106 case OPC_PICK_QH:
14107 check_dsp(ctx);
14108 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14109 break;
14110 }
14111 break;
df6126a7
AJ
14112#endif
14113 }
14114
14115 tcg_temp_free(t1);
14116 tcg_temp_free(v1_t);
14117 tcg_temp_free(v2_t);
14118
14119 (void)opn; /* avoid a compiler warning */
14120 MIPS_DEBUG("%s", opn);
14121}
14122
14123static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14124 uint32_t op1, int rt, int rs, int sa)
14125{
14126 const char *opn = "mipsdsp append/dappend";
14127 TCGv t0;
14128
14129 check_dspr2(ctx);
14130
14131 if (rt == 0) {
14132 /* Treat as NOP. */
14133 MIPS_DEBUG("NOP");
14134 return;
14135 }
14136
14137 t0 = tcg_temp_new();
14138 gen_load_gpr(t0, rs);
14139
14140 switch (op1) {
14141 case OPC_APPEND_DSP:
14142 switch (MASK_APPEND(ctx->opcode)) {
14143 case OPC_APPEND:
14144 if (sa != 0) {
14145 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14146 }
14147 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14148 break;
14149 case OPC_PREPEND:
14150 if (sa != 0) {
14151 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14152 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14153 tcg_gen_shli_tl(t0, t0, 32 - sa);
14154 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14155 }
14156 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14157 break;
14158 case OPC_BALIGN:
14159 sa &= 3;
14160 if (sa != 0 && sa != 2) {
14161 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14162 tcg_gen_ext32u_tl(t0, t0);
14163 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14164 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14165 }
14166 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14167 break;
14168 default: /* Invalid */
14169 MIPS_INVAL("MASK APPEND");
14170 generate_exception(ctx, EXCP_RI);
14171 break;
14172 }
14173 break;
14174#ifdef TARGET_MIPS64
26690560 14175 case OPC_DAPPEND_DSP:
df6126a7 14176 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 14177 case OPC_DAPPEND:
df6126a7
AJ
14178 if (sa != 0) {
14179 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14180 }
26690560
JL
14181 break;
14182 case OPC_PREPENDD:
df6126a7
AJ
14183 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14184 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14185 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
14186 break;
14187 case OPC_PREPENDW:
df6126a7
AJ
14188 if (sa != 0) {
14189 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14190 tcg_gen_shli_tl(t0, t0, 64 - sa);
14191 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14192 }
26690560
JL
14193 break;
14194 case OPC_DBALIGN:
df6126a7
AJ
14195 sa &= 7;
14196 if (sa != 0 && sa != 2 && sa != 4) {
14197 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14198 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14199 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14200 }
26690560
JL
14201 break;
14202 default: /* Invalid */
14203 MIPS_INVAL("MASK DAPPEND");
14204 generate_exception(ctx, EXCP_RI);
14205 break;
14206 }
14207 break;
14208#endif
14209 }
df6126a7 14210 tcg_temp_free(t0);
26690560
JL
14211 (void)opn; /* avoid a compiler warning */
14212 MIPS_DEBUG("%s", opn);
14213}
14214
b53371ed
JL
14215static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14216 int ret, int v1, int v2, int check_ret)
14217
14218{
14219 const char *opn = "mipsdsp accumulator";
14220 TCGv t0;
14221 TCGv t1;
14222 TCGv v1_t;
14223 TCGv v2_t;
14224 int16_t imm;
14225
14226 if ((ret == 0) && (check_ret == 1)) {
14227 /* Treat as NOP. */
14228 MIPS_DEBUG("NOP");
14229 return;
14230 }
14231
14232 t0 = tcg_temp_new();
14233 t1 = tcg_temp_new();
14234 v1_t = tcg_temp_new();
14235 v2_t = tcg_temp_new();
14236
14237 gen_load_gpr(v1_t, v1);
14238 gen_load_gpr(v2_t, v2);
14239
14240 switch (op1) {
14241 case OPC_EXTR_W_DSP:
14242 check_dsp(ctx);
14243 switch (op2) {
14244 case OPC_EXTR_W:
14245 tcg_gen_movi_tl(t0, v2);
14246 tcg_gen_movi_tl(t1, v1);
14247 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14248 break;
14249 case OPC_EXTR_R_W:
14250 tcg_gen_movi_tl(t0, v2);
14251 tcg_gen_movi_tl(t1, v1);
14252 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14253 break;
14254 case OPC_EXTR_RS_W:
14255 tcg_gen_movi_tl(t0, v2);
14256 tcg_gen_movi_tl(t1, v1);
14257 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14258 break;
14259 case OPC_EXTR_S_H:
14260 tcg_gen_movi_tl(t0, v2);
14261 tcg_gen_movi_tl(t1, v1);
14262 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14263 break;
14264 case OPC_EXTRV_S_H:
14265 tcg_gen_movi_tl(t0, v2);
14266 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14267 break;
14268 case OPC_EXTRV_W:
14269 tcg_gen_movi_tl(t0, v2);
14270 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14271 break;
14272 case OPC_EXTRV_R_W:
14273 tcg_gen_movi_tl(t0, v2);
14274 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14275 break;
14276 case OPC_EXTRV_RS_W:
14277 tcg_gen_movi_tl(t0, v2);
14278 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14279 break;
14280 case OPC_EXTP:
14281 tcg_gen_movi_tl(t0, v2);
14282 tcg_gen_movi_tl(t1, v1);
14283 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14284 break;
14285 case OPC_EXTPV:
14286 tcg_gen_movi_tl(t0, v2);
14287 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14288 break;
14289 case OPC_EXTPDP:
14290 tcg_gen_movi_tl(t0, v2);
14291 tcg_gen_movi_tl(t1, v1);
14292 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14293 break;
14294 case OPC_EXTPDPV:
14295 tcg_gen_movi_tl(t0, v2);
14296 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14297 break;
14298 case OPC_SHILO:
14299 imm = (ctx->opcode >> 20) & 0x3F;
14300 tcg_gen_movi_tl(t0, ret);
14301 tcg_gen_movi_tl(t1, imm);
14302 gen_helper_shilo(t0, t1, cpu_env);
14303 break;
14304 case OPC_SHILOV:
14305 tcg_gen_movi_tl(t0, ret);
14306 gen_helper_shilo(t0, v1_t, cpu_env);
14307 break;
14308 case OPC_MTHLIP:
14309 tcg_gen_movi_tl(t0, ret);
14310 gen_helper_mthlip(t0, v1_t, cpu_env);
14311 break;
14312 case OPC_WRDSP:
14313 imm = (ctx->opcode >> 11) & 0x3FF;
14314 tcg_gen_movi_tl(t0, imm);
14315 gen_helper_wrdsp(v1_t, t0, cpu_env);
14316 break;
14317 case OPC_RDDSP:
14318 imm = (ctx->opcode >> 16) & 0x03FF;
14319 tcg_gen_movi_tl(t0, imm);
14320 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14321 break;
14322 }
14323 break;
14324#ifdef TARGET_MIPS64
14325 case OPC_DEXTR_W_DSP:
14326 check_dsp(ctx);
14327 switch (op2) {
14328 case OPC_DMTHLIP:
14329 tcg_gen_movi_tl(t0, ret);
14330 gen_helper_dmthlip(v1_t, t0, cpu_env);
14331 break;
14332 case OPC_DSHILO:
14333 {
14334 int shift = (ctx->opcode >> 19) & 0x7F;
14335 int ac = (ctx->opcode >> 11) & 0x03;
14336 tcg_gen_movi_tl(t0, shift);
14337 tcg_gen_movi_tl(t1, ac);
14338 gen_helper_dshilo(t0, t1, cpu_env);
14339 break;
14340 }
14341 case OPC_DSHILOV:
14342 {
14343 int ac = (ctx->opcode >> 11) & 0x03;
14344 tcg_gen_movi_tl(t0, ac);
14345 gen_helper_dshilo(v1_t, t0, cpu_env);
14346 break;
14347 }
14348 case OPC_DEXTP:
14349 tcg_gen_movi_tl(t0, v2);
14350 tcg_gen_movi_tl(t1, v1);
14351
14352 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14353 break;
14354 case OPC_DEXTPV:
14355 tcg_gen_movi_tl(t0, v2);
14356 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14357 break;
14358 case OPC_DEXTPDP:
14359 tcg_gen_movi_tl(t0, v2);
14360 tcg_gen_movi_tl(t1, v1);
14361 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14362 break;
14363 case OPC_DEXTPDPV:
14364 tcg_gen_movi_tl(t0, v2);
14365 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14366 break;
14367 case OPC_DEXTR_L:
14368 tcg_gen_movi_tl(t0, v2);
14369 tcg_gen_movi_tl(t1, v1);
14370 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14371 break;
14372 case OPC_DEXTR_R_L:
14373 tcg_gen_movi_tl(t0, v2);
14374 tcg_gen_movi_tl(t1, v1);
14375 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14376 break;
14377 case OPC_DEXTR_RS_L:
14378 tcg_gen_movi_tl(t0, v2);
14379 tcg_gen_movi_tl(t1, v1);
14380 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14381 break;
14382 case OPC_DEXTR_W:
14383 tcg_gen_movi_tl(t0, v2);
14384 tcg_gen_movi_tl(t1, v1);
14385 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14386 break;
14387 case OPC_DEXTR_R_W:
14388 tcg_gen_movi_tl(t0, v2);
14389 tcg_gen_movi_tl(t1, v1);
14390 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14391 break;
14392 case OPC_DEXTR_RS_W:
14393 tcg_gen_movi_tl(t0, v2);
14394 tcg_gen_movi_tl(t1, v1);
14395 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14396 break;
14397 case OPC_DEXTR_S_H:
14398 tcg_gen_movi_tl(t0, v2);
14399 tcg_gen_movi_tl(t1, v1);
14400 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14401 break;
14402 case OPC_DEXTRV_S_H:
14403 tcg_gen_movi_tl(t0, v2);
14404 tcg_gen_movi_tl(t1, v1);
14405 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14406 break;
14407 case OPC_DEXTRV_L:
14408 tcg_gen_movi_tl(t0, v2);
14409 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14410 break;
14411 case OPC_DEXTRV_R_L:
14412 tcg_gen_movi_tl(t0, v2);
14413 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14414 break;
14415 case OPC_DEXTRV_RS_L:
14416 tcg_gen_movi_tl(t0, v2);
14417 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14418 break;
14419 case OPC_DEXTRV_W:
14420 tcg_gen_movi_tl(t0, v2);
14421 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14422 break;
14423 case OPC_DEXTRV_R_W:
14424 tcg_gen_movi_tl(t0, v2);
14425 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14426 break;
14427 case OPC_DEXTRV_RS_W:
14428 tcg_gen_movi_tl(t0, v2);
14429 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14430 break;
14431 }
14432 break;
14433#endif
14434 }
14435
14436 tcg_temp_free(t0);
14437 tcg_temp_free(t1);
14438 tcg_temp_free(v1_t);
14439 tcg_temp_free(v2_t);
14440
14441 (void)opn; /* avoid a compiler warning */
14442 MIPS_DEBUG("%s", opn);
14443}
14444
9b1a1d68
JL
14445/* End MIPSDSP functions. */
14446
240ce26a 14447static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14448{
14449 int32_t offset;
14450 int rs, rt, rd, sa;
14451 uint32_t op, op1, op2;
14452 int16_t imm;
14453
14454 /* make sure instructions are on a word boundary */
14455 if (ctx->pc & 0x3) {
14456 env->CP0_BadVAddr = ctx->pc;
14457 generate_exception(ctx, EXCP_AdEL);
14458 return;
14459 }
14460
14461 /* Handle blikely not taken case */
14462 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14463 int l1 = gen_new_label();
14464
14465 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14466 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14467 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14468 gen_goto_tb(ctx, 1, ctx->pc + 4);
14469 gen_set_label(l1);
14470 }
14471
fdefe51c 14472 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14473 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14474 }
3c824109
NF
14475
14476 op = MASK_OP_MAJOR(ctx->opcode);
14477 rs = (ctx->opcode >> 21) & 0x1f;
14478 rt = (ctx->opcode >> 16) & 0x1f;
14479 rd = (ctx->opcode >> 11) & 0x1f;
14480 sa = (ctx->opcode >> 6) & 0x1f;
14481 imm = (int16_t)ctx->opcode;
14482 switch (op) {
7a387fff
TS
14483 case OPC_SPECIAL:
14484 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14485 switch (op1) {
324d9e32
AJ
14486 case OPC_SLL: /* Shift with immediate */
14487 case OPC_SRA:
d75c135e 14488 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14489 break;
ea63e2c3
NF
14490 case OPC_SRL:
14491 switch ((ctx->opcode >> 21) & 0x1f) {
14492 case 1:
14493 /* rotr is decoded as srl on non-R2 CPUs */
d75c135e 14494 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14495 op1 = OPC_ROTR;
14496 }
14497 /* Fallthrough */
14498 case 0:
d75c135e 14499 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14500 break;
14501 default:
14502 generate_exception(ctx, EXCP_RI);
14503 break;
14504 }
14505 break;
460f00c4
AJ
14506 case OPC_MOVN: /* Conditional move */
14507 case OPC_MOVZ:
d75c135e 14508 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
aa8f4009 14509 INSN_LOONGSON2E | INSN_LOONGSON2F);
d75c135e 14510 gen_cond_move(ctx, op1, rd, rs, rt);
460f00c4
AJ
14511 break;
14512 case OPC_ADD ... OPC_SUBU:
d75c135e 14513 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14514 break;
460f00c4 14515 case OPC_SLLV: /* Shifts */
460f00c4 14516 case OPC_SRAV:
d75c135e 14517 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14518 break;
ea63e2c3
NF
14519 case OPC_SRLV:
14520 switch ((ctx->opcode >> 6) & 0x1f) {
14521 case 1:
14522 /* rotrv is decoded as srlv on non-R2 CPUs */
d75c135e 14523 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14524 op1 = OPC_ROTRV;
14525 }
14526 /* Fallthrough */
14527 case 0:
d75c135e 14528 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14529 break;
14530 default:
14531 generate_exception(ctx, EXCP_RI);
14532 break;
14533 }
14534 break;
460f00c4
AJ
14535 case OPC_SLT: /* Set on less than */
14536 case OPC_SLTU:
d75c135e 14537 gen_slt(ctx, op1, rd, rs, rt);
460f00c4
AJ
14538 break;
14539 case OPC_AND: /* Logic*/
14540 case OPC_OR:
14541 case OPC_NOR:
14542 case OPC_XOR:
d75c135e 14543 gen_logic(ctx, op1, rd, rs, rt);
460f00c4 14544 break;
26135ead
RS
14545 case OPC_MULT:
14546 case OPC_MULTU:
e9c71dd1 14547 if (sa) {
d75c135e 14548 check_insn(ctx, INSN_VR54XX);
e9c71dd1
TS
14549 op1 = MASK_MUL_VR54XX(ctx->opcode);
14550 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
26135ead
RS
14551 } else {
14552 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14553 }
14554 break;
14555 case OPC_DIV:
14556 case OPC_DIVU:
14557 gen_muldiv(ctx, op1, 0, rs, rt);
7a387fff
TS
14558 break;
14559 case OPC_JR ... OPC_JALR:
7dca4ad0 14560 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061 14561 break;
7a387fff
TS
14562 case OPC_TGE ... OPC_TEQ: /* Traps */
14563 case OPC_TNE:
14564 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14565 break;
7a387fff
TS
14566 case OPC_MFHI: /* Move from HI/LO */
14567 case OPC_MFLO:
26135ead 14568 gen_HILO(ctx, op1, rs & 3, rd);
6af0bf9c 14569 break;
7a387fff
TS
14570 case OPC_MTHI:
14571 case OPC_MTLO: /* Move to HI/LO */
26135ead 14572 gen_HILO(ctx, op1, rd & 3, rs);
6af0bf9c 14573 break;
b48cfdff
TS
14574 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14575#ifdef MIPS_STRICT_STANDARD
14576 MIPS_INVAL("PMON / selsl");
14577 generate_exception(ctx, EXCP_RI);
14578#else
895c2d04 14579 gen_helper_0e0i(pmon, sa);
b48cfdff 14580#endif
7a387fff
TS
14581 break;
14582 case OPC_SYSCALL:
6af0bf9c 14583 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14584 ctx->bstate = BS_STOP;
6af0bf9c 14585 break;
7a387fff 14586 case OPC_BREAK:
6af0bf9c
FB
14587 generate_exception(ctx, EXCP_BREAK);
14588 break;
b48cfdff
TS
14589 case OPC_SPIM:
14590#ifdef MIPS_STRICT_STANDARD
14591 MIPS_INVAL("SPIM");
14592 generate_exception(ctx, EXCP_RI);
14593#else
7a387fff
TS
14594 /* Implemented as RI exception for now. */
14595 MIPS_INVAL("spim (unofficial)");
14596 generate_exception(ctx, EXCP_RI);
b48cfdff 14597#endif
6af0bf9c 14598 break;
7a387fff 14599 case OPC_SYNC:
ead9360e 14600 /* Treat as NOP. */
6af0bf9c 14601 break;
4ad40f36 14602
7a387fff 14603 case OPC_MOVCI:
d75c135e 14604 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
5ab5c041 14605 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14606 check_cp1_enabled(ctx);
36d23958
TS
14607 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14608 (ctx->opcode >> 16) & 1);
14609 } else {
e397ee33 14610 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14611 }
4ad40f36
FB
14612 break;
14613
d26bc211 14614#if defined(TARGET_MIPS64)
7a387fff
TS
14615 /* MIPS64 specific opcodes */
14616 case OPC_DSLL:
324d9e32 14617 case OPC_DSRA:
7a387fff 14618 case OPC_DSLL32:
324d9e32 14619 case OPC_DSRA32:
d75c135e 14620 check_insn(ctx, ISA_MIPS3);
e189e748 14621 check_mips_64(ctx);
d75c135e 14622 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14623 break;
ea63e2c3
NF
14624 case OPC_DSRL:
14625 switch ((ctx->opcode >> 21) & 0x1f) {
14626 case 1:
14627 /* drotr is decoded as dsrl on non-R2 CPUs */
d75c135e 14628 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14629 op1 = OPC_DROTR;
14630 }
14631 /* Fallthrough */
14632 case 0:
d75c135e 14633 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14634 check_mips_64(ctx);
d75c135e 14635 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14636 break;
14637 default:
14638 generate_exception(ctx, EXCP_RI);
14639 break;
14640 }
14641 break;
14642 case OPC_DSRL32:
14643 switch ((ctx->opcode >> 21) & 0x1f) {
14644 case 1:
14645 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
d75c135e 14646 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14647 op1 = OPC_DROTR32;
14648 }
14649 /* Fallthrough */
14650 case 0:
d75c135e 14651 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14652 check_mips_64(ctx);
d75c135e 14653 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14654 break;
14655 default:
14656 generate_exception(ctx, EXCP_RI);
14657 break;
14658 }
14659 break;
7a387fff 14660 case OPC_DADD ... OPC_DSUBU:
d75c135e 14661 check_insn(ctx, ISA_MIPS3);
e189e748 14662 check_mips_64(ctx);
d75c135e 14663 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14664 break;
460f00c4
AJ
14665 case OPC_DSLLV:
14666 case OPC_DSRAV:
d75c135e 14667 check_insn(ctx, ISA_MIPS3);
460f00c4 14668 check_mips_64(ctx);
d75c135e 14669 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14670 break;
ea63e2c3
NF
14671 case OPC_DSRLV:
14672 switch ((ctx->opcode >> 6) & 0x1f) {
14673 case 1:
14674 /* drotrv is decoded as dsrlv on non-R2 CPUs */
d75c135e 14675 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14676 op1 = OPC_DROTRV;
14677 }
14678 /* Fallthrough */
14679 case 0:
d75c135e 14680 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14681 check_mips_64(ctx);
d75c135e 14682 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14683 break;
14684 default:
14685 generate_exception(ctx, EXCP_RI);
14686 break;
14687 }
14688 break;
7a387fff 14689 case OPC_DMULT ... OPC_DDIVU:
d75c135e 14690 check_insn(ctx, ISA_MIPS3);
e189e748 14691 check_mips_64(ctx);
26135ead 14692 gen_muldiv(ctx, op1, 0, rs, rt);
7a387fff 14693 break;
6af0bf9c
FB
14694#endif
14695 default: /* Invalid */
14696 MIPS_INVAL("special");
14697 generate_exception(ctx, EXCP_RI);
14698 break;
14699 }
14700 break;
7a387fff
TS
14701 case OPC_SPECIAL2:
14702 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14703 switch (op1) {
7a387fff
TS
14704 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14705 case OPC_MSUB ... OPC_MSUBU:
d75c135e 14706 check_insn(ctx, ISA_MIPS32);
26135ead 14707 gen_muldiv(ctx, op1, rd & 3, rs, rt);
6af0bf9c 14708 break;
7a387fff 14709 case OPC_MUL:
d75c135e 14710 gen_arith(ctx, op1, rd, rs, rt);
6af0bf9c 14711 break;
20e1fb52
AJ
14712 case OPC_CLO:
14713 case OPC_CLZ:
d75c135e 14714 check_insn(ctx, ISA_MIPS32);
7a387fff 14715 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14716 break;
7a387fff 14717 case OPC_SDBBP:
6af0bf9c
FB
14718 /* XXX: not clear which exception should be raised
14719 * when in debug mode...
14720 */
d75c135e 14721 check_insn(ctx, ISA_MIPS32);
6af0bf9c
FB
14722 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14723 generate_exception(ctx, EXCP_DBp);
14724 } else {
14725 generate_exception(ctx, EXCP_DBp);
14726 }
ead9360e 14727 /* Treat as NOP. */
6af0bf9c 14728 break;
161f85e6
AJ
14729 case OPC_DIV_G_2F:
14730 case OPC_DIVU_G_2F:
14731 case OPC_MULT_G_2F:
14732 case OPC_MULTU_G_2F:
14733 case OPC_MOD_G_2F:
14734 case OPC_MODU_G_2F:
d75c135e 14735 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14736 gen_loongson_integer(ctx, op1, rd, rs, rt);
14737 break;
d26bc211 14738#if defined(TARGET_MIPS64)
20e1fb52
AJ
14739 case OPC_DCLO:
14740 case OPC_DCLZ:
d75c135e 14741 check_insn(ctx, ISA_MIPS64);
e189e748 14742 check_mips_64(ctx);
7a387fff
TS
14743 gen_cl(ctx, op1, rd, rs);
14744 break;
161f85e6
AJ
14745 case OPC_DMULT_G_2F:
14746 case OPC_DMULTU_G_2F:
14747 case OPC_DDIV_G_2F:
14748 case OPC_DDIVU_G_2F:
14749 case OPC_DMOD_G_2F:
14750 case OPC_DMODU_G_2F:
d75c135e 14751 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14752 gen_loongson_integer(ctx, op1, rd, rs, rt);
14753 break;
7a387fff 14754#endif
6af0bf9c
FB
14755 default: /* Invalid */
14756 MIPS_INVAL("special2");
14757 generate_exception(ctx, EXCP_RI);
14758 break;
14759 }
14760 break;
7a387fff 14761 case OPC_SPECIAL3:
2b0233ab
TS
14762 op1 = MASK_SPECIAL3(ctx->opcode);
14763 switch (op1) {
14764 case OPC_EXT:
14765 case OPC_INS:
d75c135e 14766 check_insn(ctx, ISA_MIPS32R2);
2b0233ab
TS
14767 gen_bitops(ctx, op1, rt, rs, sa, rd);
14768 break;
14769 case OPC_BSHFL:
d75c135e 14770 check_insn(ctx, ISA_MIPS32R2);
2b0233ab 14771 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14772 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14773 break;
1579a72e 14774 case OPC_RDHWR:
d75c135e 14775 gen_rdhwr(ctx, rt, rd);
1579a72e 14776 break;
ead9360e 14777 case OPC_FORK:
d75c135e 14778 check_insn(ctx, ASE_MT);
6c5c1e20 14779 {
35fbce2c
AJ
14780 TCGv t0 = tcg_temp_new();
14781 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14782
14783 gen_load_gpr(t0, rt);
14784 gen_load_gpr(t1, rs);
a7812ae4 14785 gen_helper_fork(t0, t1);
6c5c1e20
TS
14786 tcg_temp_free(t0);
14787 tcg_temp_free(t1);
14788 }
ead9360e
TS
14789 break;
14790 case OPC_YIELD:
d75c135e 14791 check_insn(ctx, ASE_MT);
6c5c1e20 14792 {
35fbce2c 14793 TCGv t0 = tcg_temp_new();
6c5c1e20 14794
35fbce2c 14795 save_cpu_state(ctx, 1);
6c5c1e20 14796 gen_load_gpr(t0, rs);
895c2d04 14797 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14798 gen_store_gpr(t0, rd);
14799 tcg_temp_free(t0);
14800 }
ead9360e 14801 break;
161f85e6 14802 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14803 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14804 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14805 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14806 * the same mask and op1. */
d75c135e 14807 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
461c08df
JL
14808 op2 = MASK_ADDUH_QB(ctx->opcode);
14809 switch (op2) {
14810 case OPC_ADDUH_QB:
14811 case OPC_ADDUH_R_QB:
14812 case OPC_ADDQH_PH:
14813 case OPC_ADDQH_R_PH:
14814 case OPC_ADDQH_W:
14815 case OPC_ADDQH_R_W:
14816 case OPC_SUBUH_QB:
14817 case OPC_SUBUH_R_QB:
14818 case OPC_SUBQH_PH:
14819 case OPC_SUBQH_R_PH:
14820 case OPC_SUBQH_W:
14821 case OPC_SUBQH_R_W:
14822 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14823 break;
a22260ae
JL
14824 case OPC_MUL_PH:
14825 case OPC_MUL_S_PH:
14826 case OPC_MULQ_S_W:
14827 case OPC_MULQ_RS_W:
14828 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14829 break;
461c08df
JL
14830 default:
14831 MIPS_INVAL("MASK ADDUH.QB");
14832 generate_exception(ctx, EXCP_RI);
14833 break;
14834 }
d75c135e 14835 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
461c08df
JL
14836 gen_loongson_integer(ctx, op1, rd, rs, rt);
14837 } else {
14838 generate_exception(ctx, EXCP_RI);
14839 }
161f85e6 14840 break;
9b1a1d68
JL
14841 case OPC_LX_DSP:
14842 op2 = MASK_LX(ctx->opcode);
14843 switch (op2) {
14844#if defined(TARGET_MIPS64)
14845 case OPC_LDX:
14846#endif
14847 case OPC_LBUX:
14848 case OPC_LHX:
14849 case OPC_LWX:
d75c135e 14850 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
9b1a1d68
JL
14851 break;
14852 default: /* Invalid */
14853 MIPS_INVAL("MASK LX");
14854 generate_exception(ctx, EXCP_RI);
14855 break;
14856 }
14857 break;
461c08df
JL
14858 case OPC_ABSQ_S_PH_DSP:
14859 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14860 switch (op2) {
14861 case OPC_ABSQ_S_QB:
14862 case OPC_ABSQ_S_PH:
14863 case OPC_ABSQ_S_W:
14864 case OPC_PRECEQ_W_PHL:
14865 case OPC_PRECEQ_W_PHR:
14866 case OPC_PRECEQU_PH_QBL:
14867 case OPC_PRECEQU_PH_QBR:
14868 case OPC_PRECEQU_PH_QBLA:
14869 case OPC_PRECEQU_PH_QBRA:
14870 case OPC_PRECEU_PH_QBL:
14871 case OPC_PRECEU_PH_QBR:
14872 case OPC_PRECEU_PH_QBLA:
14873 case OPC_PRECEU_PH_QBRA:
14874 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14875 break;
1cb6686c
JL
14876 case OPC_BITREV:
14877 case OPC_REPL_QB:
14878 case OPC_REPLV_QB:
14879 case OPC_REPL_PH:
14880 case OPC_REPLV_PH:
d75c135e 14881 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 14882 break;
461c08df
JL
14883 default:
14884 MIPS_INVAL("MASK ABSQ_S.PH");
14885 generate_exception(ctx, EXCP_RI);
14886 break;
14887 }
14888 break;
14889 case OPC_ADDU_QB_DSP:
14890 op2 = MASK_ADDU_QB(ctx->opcode);
14891 switch (op2) {
14892 case OPC_ADDQ_PH:
14893 case OPC_ADDQ_S_PH:
14894 case OPC_ADDQ_S_W:
14895 case OPC_ADDU_QB:
14896 case OPC_ADDU_S_QB:
14897 case OPC_ADDU_PH:
14898 case OPC_ADDU_S_PH:
14899 case OPC_SUBQ_PH:
14900 case OPC_SUBQ_S_PH:
14901 case OPC_SUBQ_S_W:
14902 case OPC_SUBU_QB:
14903 case OPC_SUBU_S_QB:
14904 case OPC_SUBU_PH:
14905 case OPC_SUBU_S_PH:
14906 case OPC_ADDSC:
14907 case OPC_ADDWC:
14908 case OPC_MODSUB:
14909 case OPC_RADDU_W_QB:
14910 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14911 break;
a22260ae
JL
14912 case OPC_MULEU_S_PH_QBL:
14913 case OPC_MULEU_S_PH_QBR:
14914 case OPC_MULQ_RS_PH:
14915 case OPC_MULEQ_S_W_PHL:
14916 case OPC_MULEQ_S_W_PHR:
14917 case OPC_MULQ_S_PH:
14918 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14919 break;
461c08df
JL
14920 default: /* Invalid */
14921 MIPS_INVAL("MASK ADDU.QB");
14922 generate_exception(ctx, EXCP_RI);
14923 break;
14924
14925 }
14926 break;
14927 case OPC_CMPU_EQ_QB_DSP:
14928 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14929 switch (op2) {
14930 case OPC_PRECR_SRA_PH_W:
14931 case OPC_PRECR_SRA_R_PH_W:
14932 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14933 break;
14934 case OPC_PRECR_QB_PH:
14935 case OPC_PRECRQ_QB_PH:
14936 case OPC_PRECRQ_PH_W:
14937 case OPC_PRECRQ_RS_PH_W:
14938 case OPC_PRECRQU_S_QB_PH:
14939 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14940 break;
26690560
JL
14941 case OPC_CMPU_EQ_QB:
14942 case OPC_CMPU_LT_QB:
14943 case OPC_CMPU_LE_QB:
14944 case OPC_CMP_EQ_PH:
14945 case OPC_CMP_LT_PH:
14946 case OPC_CMP_LE_PH:
14947 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14948 break;
14949 case OPC_CMPGU_EQ_QB:
14950 case OPC_CMPGU_LT_QB:
14951 case OPC_CMPGU_LE_QB:
14952 case OPC_CMPGDU_EQ_QB:
14953 case OPC_CMPGDU_LT_QB:
14954 case OPC_CMPGDU_LE_QB:
14955 case OPC_PICK_QB:
14956 case OPC_PICK_PH:
14957 case OPC_PACKRL_PH:
14958 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14959 break;
461c08df
JL
14960 default: /* Invalid */
14961 MIPS_INVAL("MASK CMPU.EQ.QB");
14962 generate_exception(ctx, EXCP_RI);
14963 break;
14964 }
14965 break;
77c5fa8b
JL
14966 case OPC_SHLL_QB_DSP:
14967 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14968 break;
a22260ae
JL
14969 case OPC_DPA_W_PH_DSP:
14970 op2 = MASK_DPA_W_PH(ctx->opcode);
14971 switch (op2) {
14972 case OPC_DPAU_H_QBL:
14973 case OPC_DPAU_H_QBR:
14974 case OPC_DPSU_H_QBL:
14975 case OPC_DPSU_H_QBR:
14976 case OPC_DPA_W_PH:
14977 case OPC_DPAX_W_PH:
14978 case OPC_DPAQ_S_W_PH:
14979 case OPC_DPAQX_S_W_PH:
14980 case OPC_DPAQX_SA_W_PH:
14981 case OPC_DPS_W_PH:
14982 case OPC_DPSX_W_PH:
14983 case OPC_DPSQ_S_W_PH:
14984 case OPC_DPSQX_S_W_PH:
14985 case OPC_DPSQX_SA_W_PH:
14986 case OPC_MULSAQ_S_W_PH:
14987 case OPC_DPAQ_SA_L_W:
14988 case OPC_DPSQ_SA_L_W:
14989 case OPC_MAQ_S_W_PHL:
14990 case OPC_MAQ_S_W_PHR:
14991 case OPC_MAQ_SA_W_PHL:
14992 case OPC_MAQ_SA_W_PHR:
14993 case OPC_MULSA_W_PH:
14994 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14995 break;
14996 default: /* Invalid */
14997 MIPS_INVAL("MASK DPAW.PH");
14998 generate_exception(ctx, EXCP_RI);
14999 break;
15000 }
15001 break;
1cb6686c
JL
15002 case OPC_INSV_DSP:
15003 op2 = MASK_INSV(ctx->opcode);
15004 switch (op2) {
15005 case OPC_INSV:
15006 check_dsp(ctx);
15007 {
15008 TCGv t0, t1;
15009
15010 if (rt == 0) {
15011 MIPS_DEBUG("NOP");
15012 break;
15013 }
15014
15015 t0 = tcg_temp_new();
15016 t1 = tcg_temp_new();
15017
15018 gen_load_gpr(t0, rt);
15019 gen_load_gpr(t1, rs);
15020
15021 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
15022
15023 tcg_temp_free(t0);
15024 tcg_temp_free(t1);
15025 break;
15026 }
15027 default: /* Invalid */
15028 MIPS_INVAL("MASK INSV");
15029 generate_exception(ctx, EXCP_RI);
15030 break;
15031 }
15032 break;
26690560 15033 case OPC_APPEND_DSP:
df6126a7 15034 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 15035 break;
b53371ed
JL
15036 case OPC_EXTR_W_DSP:
15037 op2 = MASK_EXTR_W(ctx->opcode);
15038 switch (op2) {
15039 case OPC_EXTR_W:
15040 case OPC_EXTR_R_W:
15041 case OPC_EXTR_RS_W:
15042 case OPC_EXTR_S_H:
15043 case OPC_EXTRV_S_H:
15044 case OPC_EXTRV_W:
15045 case OPC_EXTRV_R_W:
15046 case OPC_EXTRV_RS_W:
15047 case OPC_EXTP:
15048 case OPC_EXTPV:
15049 case OPC_EXTPDP:
15050 case OPC_EXTPDPV:
15051 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15052 break;
15053 case OPC_RDDSP:
15054 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
15055 break;
15056 case OPC_SHILO:
15057 case OPC_SHILOV:
15058 case OPC_MTHLIP:
15059 case OPC_WRDSP:
15060 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15061 break;
15062 default: /* Invalid */
15063 MIPS_INVAL("MASK EXTR.W");
15064 generate_exception(ctx, EXCP_RI);
15065 break;
15066 }
15067 break;
d26bc211 15068#if defined(TARGET_MIPS64)
1579a72e
TS
15069 case OPC_DEXTM ... OPC_DEXT:
15070 case OPC_DINSM ... OPC_DINS:
d75c135e 15071 check_insn(ctx, ISA_MIPS64R2);
e189e748 15072 check_mips_64(ctx);
1579a72e 15073 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 15074 break;
1579a72e 15075 case OPC_DBSHFL:
d75c135e 15076 check_insn(ctx, ISA_MIPS64R2);
e189e748 15077 check_mips_64(ctx);
1579a72e 15078 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 15079 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 15080 break;
161f85e6
AJ
15081 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15082 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15083 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
d75c135e 15084 check_insn(ctx, INSN_LOONGSON2E);
161f85e6
AJ
15085 gen_loongson_integer(ctx, op1, rd, rs, rt);
15086 break;
461c08df
JL
15087 case OPC_ABSQ_S_QH_DSP:
15088 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15089 switch (op2) {
15090 case OPC_PRECEQ_L_PWL:
15091 case OPC_PRECEQ_L_PWR:
15092 case OPC_PRECEQ_PW_QHL:
15093 case OPC_PRECEQ_PW_QHR:
15094 case OPC_PRECEQ_PW_QHLA:
15095 case OPC_PRECEQ_PW_QHRA:
15096 case OPC_PRECEQU_QH_OBL:
15097 case OPC_PRECEQU_QH_OBR:
15098 case OPC_PRECEQU_QH_OBLA:
15099 case OPC_PRECEQU_QH_OBRA:
15100 case OPC_PRECEU_QH_OBL:
15101 case OPC_PRECEU_QH_OBR:
15102 case OPC_PRECEU_QH_OBLA:
15103 case OPC_PRECEU_QH_OBRA:
15104 case OPC_ABSQ_S_OB:
15105 case OPC_ABSQ_S_PW:
15106 case OPC_ABSQ_S_QH:
15107 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15108 break;
1cb6686c
JL
15109 case OPC_REPL_OB:
15110 case OPC_REPL_PW:
15111 case OPC_REPL_QH:
15112 case OPC_REPLV_OB:
15113 case OPC_REPLV_PW:
15114 case OPC_REPLV_QH:
d75c135e 15115 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 15116 break;
461c08df
JL
15117 default: /* Invalid */
15118 MIPS_INVAL("MASK ABSQ_S.QH");
15119 generate_exception(ctx, EXCP_RI);
15120 break;
15121 }
15122 break;
15123 case OPC_ADDU_OB_DSP:
15124 op2 = MASK_ADDU_OB(ctx->opcode);
15125 switch (op2) {
15126 case OPC_RADDU_L_OB:
15127 case OPC_SUBQ_PW:
15128 case OPC_SUBQ_S_PW:
15129 case OPC_SUBQ_QH:
15130 case OPC_SUBQ_S_QH:
15131 case OPC_SUBU_OB:
15132 case OPC_SUBU_S_OB:
15133 case OPC_SUBU_QH:
15134 case OPC_SUBU_S_QH:
15135 case OPC_SUBUH_OB:
15136 case OPC_SUBUH_R_OB:
15137 case OPC_ADDQ_PW:
15138 case OPC_ADDQ_S_PW:
15139 case OPC_ADDQ_QH:
15140 case OPC_ADDQ_S_QH:
15141 case OPC_ADDU_OB:
15142 case OPC_ADDU_S_OB:
15143 case OPC_ADDU_QH:
15144 case OPC_ADDU_S_QH:
15145 case OPC_ADDUH_OB:
15146 case OPC_ADDUH_R_OB:
15147 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15148 break;
a22260ae
JL
15149 case OPC_MULEQ_S_PW_QHL:
15150 case OPC_MULEQ_S_PW_QHR:
15151 case OPC_MULEU_S_QH_OBL:
15152 case OPC_MULEU_S_QH_OBR:
15153 case OPC_MULQ_RS_QH:
15154 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15155 break;
461c08df
JL
15156 default: /* Invalid */
15157 MIPS_INVAL("MASK ADDU.OB");
15158 generate_exception(ctx, EXCP_RI);
15159 break;
15160 }
15161 break;
15162 case OPC_CMPU_EQ_OB_DSP:
15163 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15164 switch (op2) {
15165 case OPC_PRECR_SRA_QH_PW:
15166 case OPC_PRECR_SRA_R_QH_PW:
15167 /* Return value is rt. */
15168 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15169 break;
15170 case OPC_PRECR_OB_QH:
15171 case OPC_PRECRQ_OB_QH:
15172 case OPC_PRECRQ_PW_L:
15173 case OPC_PRECRQ_QH_PW:
15174 case OPC_PRECRQ_RS_QH_PW:
15175 case OPC_PRECRQU_S_OB_QH:
15176 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15177 break;
26690560
JL
15178 case OPC_CMPU_EQ_OB:
15179 case OPC_CMPU_LT_OB:
15180 case OPC_CMPU_LE_OB:
15181 case OPC_CMP_EQ_QH:
15182 case OPC_CMP_LT_QH:
15183 case OPC_CMP_LE_QH:
15184 case OPC_CMP_EQ_PW:
15185 case OPC_CMP_LT_PW:
15186 case OPC_CMP_LE_PW:
15187 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15188 break;
15189 case OPC_CMPGDU_EQ_OB:
15190 case OPC_CMPGDU_LT_OB:
15191 case OPC_CMPGDU_LE_OB:
15192 case OPC_CMPGU_EQ_OB:
15193 case OPC_CMPGU_LT_OB:
15194 case OPC_CMPGU_LE_OB:
15195 case OPC_PACKRL_PW:
15196 case OPC_PICK_OB:
15197 case OPC_PICK_PW:
15198 case OPC_PICK_QH:
15199 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15200 break;
461c08df
JL
15201 default: /* Invalid */
15202 MIPS_INVAL("MASK CMPU_EQ.OB");
15203 generate_exception(ctx, EXCP_RI);
15204 break;
15205 }
15206 break;
26690560 15207 case OPC_DAPPEND_DSP:
df6126a7 15208 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 15209 break;
b53371ed
JL
15210 case OPC_DEXTR_W_DSP:
15211 op2 = MASK_DEXTR_W(ctx->opcode);
15212 switch (op2) {
15213 case OPC_DEXTP:
15214 case OPC_DEXTPDP:
15215 case OPC_DEXTPDPV:
15216 case OPC_DEXTPV:
15217 case OPC_DEXTR_L:
15218 case OPC_DEXTR_R_L:
15219 case OPC_DEXTR_RS_L:
15220 case OPC_DEXTR_W:
15221 case OPC_DEXTR_R_W:
15222 case OPC_DEXTR_RS_W:
15223 case OPC_DEXTR_S_H:
15224 case OPC_DEXTRV_L:
15225 case OPC_DEXTRV_R_L:
15226 case OPC_DEXTRV_RS_L:
15227 case OPC_DEXTRV_S_H:
15228 case OPC_DEXTRV_W:
15229 case OPC_DEXTRV_R_W:
15230 case OPC_DEXTRV_RS_W:
15231 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15232 break;
15233 case OPC_DMTHLIP:
15234 case OPC_DSHILO:
15235 case OPC_DSHILOV:
15236 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15237 break;
15238 default: /* Invalid */
15239 MIPS_INVAL("MASK EXTR.W");
15240 generate_exception(ctx, EXCP_RI);
15241 break;
15242 }
15243 break;
a22260ae
JL
15244 case OPC_DPAQ_W_QH_DSP:
15245 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15246 switch (op2) {
15247 case OPC_DPAU_H_OBL:
15248 case OPC_DPAU_H_OBR:
15249 case OPC_DPSU_H_OBL:
15250 case OPC_DPSU_H_OBR:
15251 case OPC_DPA_W_QH:
15252 case OPC_DPAQ_S_W_QH:
15253 case OPC_DPS_W_QH:
15254 case OPC_DPSQ_S_W_QH:
15255 case OPC_MULSAQ_S_W_QH:
15256 case OPC_DPAQ_SA_L_PW:
15257 case OPC_DPSQ_SA_L_PW:
15258 case OPC_MULSAQ_S_L_PW:
15259 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15260 break;
15261 case OPC_MAQ_S_W_QHLL:
15262 case OPC_MAQ_S_W_QHLR:
15263 case OPC_MAQ_S_W_QHRL:
15264 case OPC_MAQ_S_W_QHRR:
15265 case OPC_MAQ_SA_W_QHLL:
15266 case OPC_MAQ_SA_W_QHLR:
15267 case OPC_MAQ_SA_W_QHRL:
15268 case OPC_MAQ_SA_W_QHRR:
15269 case OPC_MAQ_S_L_PWL:
15270 case OPC_MAQ_S_L_PWR:
15271 case OPC_DMADD:
15272 case OPC_DMADDU:
15273 case OPC_DMSUB:
15274 case OPC_DMSUBU:
15275 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15276 break;
15277 default: /* Invalid */
15278 MIPS_INVAL("MASK DPAQ.W.QH");
15279 generate_exception(ctx, EXCP_RI);
15280 break;
15281 }
15282 break;
1cb6686c
JL
15283 case OPC_DINSV_DSP:
15284 op2 = MASK_INSV(ctx->opcode);
15285 switch (op2) {
15286 case OPC_DINSV:
15287 {
15288 TCGv t0, t1;
15289
15290 if (rt == 0) {
15291 MIPS_DEBUG("NOP");
15292 break;
15293 }
15294 check_dsp(ctx);
15295
15296 t0 = tcg_temp_new();
15297 t1 = tcg_temp_new();
15298
15299 gen_load_gpr(t0, rt);
15300 gen_load_gpr(t1, rs);
15301
15302 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a
DZ
15303
15304 tcg_temp_free(t0);
15305 tcg_temp_free(t1);
1cb6686c
JL
15306 break;
15307 }
15308 default: /* Invalid */
15309 MIPS_INVAL("MASK DINSV");
15310 generate_exception(ctx, EXCP_RI);
15311 break;
15312 }
15313 break;
77c5fa8b
JL
15314 case OPC_SHLL_OB_DSP:
15315 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15316 break;
7a387fff
TS
15317#endif
15318 default: /* Invalid */
15319 MIPS_INVAL("special3");
15320 generate_exception(ctx, EXCP_RI);
15321 break;
15322 }
15323 break;
15324 case OPC_REGIMM:
15325 op1 = MASK_REGIMM(ctx->opcode);
15326 switch (op1) {
15327 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15328 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15329 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061 15330 break;
7a387fff
TS
15331 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15332 case OPC_TNEI:
15333 gen_trap(ctx, op1, rs, -1, imm);
15334 break;
15335 case OPC_SYNCI:
d75c135e 15336 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15337 /* Treat as NOP. */
6af0bf9c 15338 break;
e45a93e2
JL
15339 case OPC_BPOSGE32: /* MIPS DSP branch */
15340#if defined(TARGET_MIPS64)
15341 case OPC_BPOSGE64:
15342#endif
15343 check_dsp(ctx);
15344 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
e45a93e2 15345 break;
6af0bf9c 15346 default: /* Invalid */
923617a3 15347 MIPS_INVAL("regimm");
6af0bf9c
FB
15348 generate_exception(ctx, EXCP_RI);
15349 break;
15350 }
15351 break;
7a387fff 15352 case OPC_CP0:
387a8fe5 15353 check_cp0_enabled(ctx);
7a387fff 15354 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15355 switch (op1) {
7a387fff
TS
15356 case OPC_MFC0:
15357 case OPC_MTC0:
ead9360e
TS
15358 case OPC_MFTR:
15359 case OPC_MTTR:
d26bc211 15360#if defined(TARGET_MIPS64)
7a387fff
TS
15361 case OPC_DMFC0:
15362 case OPC_DMTC0:
15363#endif
f1aa6320 15364#ifndef CONFIG_USER_ONLY
932e71cd 15365 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15366#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15367 break;
15368 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15369#ifndef CONFIG_USER_ONLY
932e71cd 15370 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15371#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15372 break;
15373 case OPC_MFMC0:
8706c382 15374#ifndef CONFIG_USER_ONLY
932e71cd 15375 {
35fbce2c 15376 TCGv t0 = tcg_temp_new();
6c5c1e20 15377
0eaef5aa 15378 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15379 switch (op2) {
15380 case OPC_DMT:
d75c135e 15381 check_insn(ctx, ASE_MT);
9ed5726c 15382 gen_helper_dmt(t0);
35fbce2c 15383 gen_store_gpr(t0, rt);
6c5c1e20
TS
15384 break;
15385 case OPC_EMT:
d75c135e 15386 check_insn(ctx, ASE_MT);
9ed5726c 15387 gen_helper_emt(t0);
35fbce2c 15388 gen_store_gpr(t0, rt);
da80682b 15389 break;
6c5c1e20 15390 case OPC_DVPE:
d75c135e 15391 check_insn(ctx, ASE_MT);
895c2d04 15392 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15393 gen_store_gpr(t0, rt);
6c5c1e20
TS
15394 break;
15395 case OPC_EVPE:
d75c135e 15396 check_insn(ctx, ASE_MT);
895c2d04 15397 gen_helper_evpe(t0, cpu_env);
35fbce2c 15398 gen_store_gpr(t0, rt);
6c5c1e20
TS
15399 break;
15400 case OPC_DI:
d75c135e 15401 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15402 save_cpu_state(ctx, 1);
895c2d04 15403 gen_helper_di(t0, cpu_env);
35fbce2c 15404 gen_store_gpr(t0, rt);
6c5c1e20
TS
15405 /* Stop translation as we may have switched the execution mode */
15406 ctx->bstate = BS_STOP;
15407 break;
15408 case OPC_EI:
d75c135e 15409 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15410 save_cpu_state(ctx, 1);
895c2d04 15411 gen_helper_ei(t0, cpu_env);
35fbce2c 15412 gen_store_gpr(t0, rt);
6c5c1e20
TS
15413 /* Stop translation as we may have switched the execution mode */
15414 ctx->bstate = BS_STOP;
15415 break;
15416 default: /* Invalid */
15417 MIPS_INVAL("mfmc0");
15418 generate_exception(ctx, EXCP_RI);
15419 break;
15420 }
6c5c1e20 15421 tcg_temp_free(t0);
7a387fff 15422 }
0eaef5aa 15423#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15424 break;
7a387fff 15425 case OPC_RDPGPR:
d75c135e 15426 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15427 gen_load_srsgpr(rt, rd);
ead9360e 15428 break;
7a387fff 15429 case OPC_WRPGPR:
d75c135e 15430 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15431 gen_store_srsgpr(rt, rd);
38121543 15432 break;
6af0bf9c 15433 default:
923617a3 15434 MIPS_INVAL("cp0");
7a387fff 15435 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15436 break;
15437 }
15438 break;
324d9e32
AJ
15439 case OPC_ADDI: /* Arithmetic with immediate opcode */
15440 case OPC_ADDIU:
d75c135e 15441 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15442 break;
324d9e32
AJ
15443 case OPC_SLTI: /* Set on less than with immediate opcode */
15444 case OPC_SLTIU:
d75c135e 15445 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15446 break;
15447 case OPC_ANDI: /* Arithmetic with immediate opcode */
15448 case OPC_LUI:
15449 case OPC_ORI:
15450 case OPC_XORI:
d75c135e 15451 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15452 break;
7a387fff
TS
15453 case OPC_J ... OPC_JAL: /* Jump */
15454 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15455 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061 15456 break;
7a387fff
TS
15457 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15458 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15459 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061 15460 break;
7a387fff 15461 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15462 case OPC_LL:
d75c135e 15463 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15464 break;
7a387fff
TS
15465 case OPC_SB ... OPC_SW:
15466 case OPC_SWR:
5c13fdfd 15467 gen_st(ctx, op, rt, rs, imm);
7a387fff 15468 break;
d66c7132
AJ
15469 case OPC_SC:
15470 gen_st_cond(ctx, op, rt, rs, imm);
15471 break;
7a387fff 15472 case OPC_CACHE:
2e15497c 15473 check_cp0_enabled(ctx);
d75c135e 15474 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15475 /* Treat as NOP. */
34ae7b51 15476 break;
7a387fff 15477 case OPC_PREF:
d75c135e 15478 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15479 /* Treat as NOP. */
6af0bf9c 15480 break;
4ad40f36 15481
923617a3 15482 /* Floating point (COP1). */
7a387fff
TS
15483 case OPC_LWC1:
15484 case OPC_LDC1:
15485 case OPC_SWC1:
15486 case OPC_SDC1:
5ab5c041 15487 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
15488 break;
15489
7a387fff 15490 case OPC_CP1:
5ab5c041 15491 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15492 check_cp1_enabled(ctx);
36d23958
TS
15493 op1 = MASK_CP1(ctx->opcode);
15494 switch (op1) {
3a95e3a7
TS
15495 case OPC_MFHC1:
15496 case OPC_MTHC1:
d75c135e 15497 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
15498 case OPC_MFC1:
15499 case OPC_CFC1:
15500 case OPC_MTC1:
15501 case OPC_CTC1:
e189e748
TS
15502 gen_cp1(ctx, op1, rt, rd);
15503 break;
d26bc211 15504#if defined(TARGET_MIPS64)
36d23958
TS
15505 case OPC_DMFC1:
15506 case OPC_DMTC1:
d75c135e 15507 check_insn(ctx, ISA_MIPS3);
36d23958
TS
15508 gen_cp1(ctx, op1, rt, rd);
15509 break;
e189e748 15510#endif
fbcc6828
TS
15511 case OPC_BC1ANY2:
15512 case OPC_BC1ANY4:
b8aa4598 15513 check_cop1x(ctx);
d75c135e 15514 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
15515 /* fall through */
15516 case OPC_BC1:
d75c135e 15517 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15518 (rt >> 2) & 0x7, imm << 2);
c9602061 15519 break;
36d23958
TS
15520 case OPC_S_FMT:
15521 case OPC_D_FMT:
15522 case OPC_W_FMT:
15523 case OPC_L_FMT:
5a5012ec 15524 case OPC_PS_FMT:
bf4120ad 15525 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15526 (imm >> 8) & 0x7);
36d23958
TS
15527 break;
15528 default:
923617a3 15529 MIPS_INVAL("cp1");
e397ee33 15530 generate_exception (ctx, EXCP_RI);
36d23958
TS
15531 break;
15532 }
15533 } else {
15534 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15535 }
4ad40f36
FB
15536 break;
15537
15538 /* COP2. */
7a387fff
TS
15539 case OPC_LWC2:
15540 case OPC_LDC2:
15541 case OPC_SWC2:
15542 case OPC_SDC2:
7a387fff 15543 /* COP2: Not implemented. */
4ad40f36
FB
15544 generate_exception_err(ctx, EXCP_CpU, 2);
15545 break;
bd277fa1 15546 case OPC_CP2:
d75c135e 15547 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
15548 /* Note that these instructions use different fields. */
15549 gen_loongson_multimedia(ctx, sa, rd, rt);
15550 break;
4ad40f36 15551
7a387fff 15552 case OPC_CP3:
5ab5c041 15553 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15554 check_cp1_enabled(ctx);
36d23958
TS
15555 op1 = MASK_CP3(ctx->opcode);
15556 switch (op1) {
5a5012ec
TS
15557 case OPC_LWXC1:
15558 case OPC_LDXC1:
15559 case OPC_LUXC1:
15560 case OPC_SWXC1:
15561 case OPC_SDXC1:
15562 case OPC_SUXC1:
93b12ccc 15563 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15564 break;
e0c84da7 15565 case OPC_PREFX:
ead9360e 15566 /* Treat as NOP. */
e0c84da7 15567 break;
5a5012ec
TS
15568 case OPC_ALNV_PS:
15569 case OPC_MADD_S:
15570 case OPC_MADD_D:
15571 case OPC_MADD_PS:
15572 case OPC_MSUB_S:
15573 case OPC_MSUB_D:
15574 case OPC_MSUB_PS:
15575 case OPC_NMADD_S:
15576 case OPC_NMADD_D:
15577 case OPC_NMADD_PS:
15578 case OPC_NMSUB_S:
15579 case OPC_NMSUB_D:
15580 case OPC_NMSUB_PS:
15581 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15582 break;
36d23958 15583 default:
923617a3 15584 MIPS_INVAL("cp3");
e397ee33 15585 generate_exception (ctx, EXCP_RI);
36d23958
TS
15586 break;
15587 }
15588 } else {
e397ee33 15589 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15590 }
4ad40f36
FB
15591 break;
15592
d26bc211 15593#if defined(TARGET_MIPS64)
7a387fff
TS
15594 /* MIPS64 opcodes */
15595 case OPC_LWU:
15596 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15597 case OPC_LLD:
15598 case OPC_LD:
d75c135e 15599 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15600 check_mips_64(ctx);
d75c135e 15601 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
15602 break;
15603 case OPC_SDL ... OPC_SDR:
7a387fff 15604 case OPC_SD:
d75c135e 15605 check_insn(ctx, ISA_MIPS3);
e189e748 15606 check_mips_64(ctx);
5c13fdfd 15607 gen_st(ctx, op, rt, rs, imm);
7a387fff 15608 break;
d66c7132 15609 case OPC_SCD:
d75c135e 15610 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
15611 check_mips_64(ctx);
15612 gen_st_cond(ctx, op, rt, rs, imm);
15613 break;
324d9e32
AJ
15614 case OPC_DADDI:
15615 case OPC_DADDIU:
d75c135e 15616 check_insn(ctx, ISA_MIPS3);
e189e748 15617 check_mips_64(ctx);
d75c135e 15618 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15619 break;
6af0bf9c 15620#endif
7a387fff 15621 case OPC_JALX:
d75c135e 15622 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15623 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15624 gen_compute_branch(ctx, op, 4, rs, rt, offset);
364d4831 15625 break;
7a387fff 15626 case OPC_MDMX:
d75c135e 15627 check_insn(ctx, ASE_MDMX);
7a387fff 15628 /* MDMX: Not implemented. */
6af0bf9c 15629 default: /* Invalid */
923617a3 15630 MIPS_INVAL("major opcode");
6af0bf9c
FB
15631 generate_exception(ctx, EXCP_RI);
15632 break;
15633 }
6af0bf9c
FB
15634}
15635
2cfc5f17 15636static inline void
6429db34
AF
15637gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15638 bool search_pc)
6af0bf9c 15639{
ed2803da 15640 CPUState *cs = CPU(cpu);
6429db34 15641 CPUMIPSState *env = &cpu->env;
278d0702 15642 DisasContext ctx;
6af0bf9c
FB
15643 target_ulong pc_start;
15644 uint16_t *gen_opc_end;
a1d1bb31 15645 CPUBreakpoint *bp;
6af0bf9c 15646 int j, lj = -1;
2e70f6ef
PB
15647 int num_insns;
15648 int max_insns;
c9602061 15649 int insn_bytes;
240ce26a 15650 int is_delay;
6af0bf9c 15651
93fcfe39
AL
15652 if (search_pc)
15653 qemu_log("search pc %d\n", search_pc);
4ad40f36 15654
6af0bf9c 15655 pc_start = tb->pc;
92414b31 15656 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15657 ctx.pc = pc_start;
4ad40f36 15658 ctx.saved_pc = -1;
ed2803da 15659 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 15660 ctx.insn_flags = env->insn_flags;
5ab5c041 15661 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
15662 ctx.tb = tb;
15663 ctx.bstate = BS_NONE;
4ad40f36 15664 /* Restore delay slot state from the tb context. */
c068688b 15665 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
d279279e 15666 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
fd4a04eb 15667 restore_cpu_state(env, &ctx);
932e71cd 15668#ifdef CONFIG_USER_ONLY
0eaef5aa 15669 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15670#else
0eaef5aa 15671 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15672#endif
2e70f6ef
PB
15673 num_insns = 0;
15674 max_insns = tb->cflags & CF_COUNT_MASK;
15675 if (max_insns == 0)
15676 max_insns = CF_COUNT_MASK;
d12d51d5 15677 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 15678 gen_tb_start();
faf7aaa9 15679 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
15680 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
15681 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 15682 if (bp->pc == ctx.pc) {
278d0702 15683 save_cpu_state(&ctx, 1);
4ad40f36 15684 ctx.bstate = BS_BRANCH;
895c2d04 15685 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15686 /* Include the breakpoint location or the tb won't
15687 * be flushed when it must be. */
15688 ctx.pc += 4;
4ad40f36
FB
15689 goto done_generating;
15690 }
15691 }
15692 }
15693
6af0bf9c 15694 if (search_pc) {
92414b31 15695 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15696 if (lj < j) {
15697 lj++;
15698 while (lj < j)
ab1103de 15699 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 15700 }
25983cad 15701 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 15702 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15703 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 15704 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 15705 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 15706 }
2e70f6ef
PB
15707 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15708 gen_io_start();
c9602061 15709
240ce26a 15710 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 15711 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15712 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 15713 insn_bytes = 4;
240ce26a 15714 decode_opc(env, &ctx);
d75c135e 15715 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 15716 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 15717 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 15718 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 15719 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 15720 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
15721 } else {
15722 generate_exception(&ctx, EXCP_RI);
3c824109 15723 ctx.bstate = BS_STOP;
c9602061
NF
15724 break;
15725 }
240ce26a 15726 if (is_delay) {
d75c135e 15727 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
15728 }
15729 ctx.pc += insn_bytes;
15730
2e70f6ef 15731 num_insns++;
4ad40f36 15732
7b270ef2
NF
15733 /* Execute a branch and its delay slot as a single instruction.
15734 This is what GDB expects and is consistent with what the
15735 hardware does (e.g. if a delay slot instruction faults, the
15736 reported PC is the PC of the branch). */
ed2803da 15737 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 15738 break;
ed2803da 15739 }
4ad40f36 15740
6af0bf9c
FB
15741 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15742 break;
4ad40f36 15743
efd7f486 15744 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 15745 break;
efd7f486 15746 }
faf7aaa9 15747
2e70f6ef
PB
15748 if (num_insns >= max_insns)
15749 break;
1b530a6d
AJ
15750
15751 if (singlestep)
15752 break;
6af0bf9c 15753 }
ed2803da 15754 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 15755 gen_io_end();
ed2803da
AF
15756 }
15757 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15758 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15759 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15760 } else {
6958549d 15761 switch (ctx.bstate) {
16c00cb2 15762 case BS_STOP:
df1561e2
TS
15763 gen_goto_tb(&ctx, 0, ctx.pc);
15764 break;
16c00cb2 15765 case BS_NONE:
278d0702 15766 save_cpu_state(&ctx, 0);
16c00cb2
TS
15767 gen_goto_tb(&ctx, 0, ctx.pc);
15768 break;
5a5012ec 15769 case BS_EXCP:
57fec1fe 15770 tcg_gen_exit_tb(0);
16c00cb2 15771 break;
5a5012ec
TS
15772 case BS_BRANCH:
15773 default:
15774 break;
6958549d 15775 }
6af0bf9c 15776 }
4ad40f36 15777done_generating:
806f352d 15778 gen_tb_end(tb, num_insns);
efd7f486 15779 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 15780 if (search_pc) {
92414b31 15781 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15782 lj++;
15783 while (lj <= j)
ab1103de 15784 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15785 } else {
15786 tb->size = ctx.pc - pc_start;
2e70f6ef 15787 tb->icount = num_insns;
6af0bf9c
FB
15788 }
15789#ifdef DEBUG_DISAS
d12d51d5 15790 LOG_DISAS("\n");
8fec2b8c 15791 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 15792 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 15793 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 15794 qemu_log("\n");
6af0bf9c
FB
15795 }
15796#endif
6af0bf9c
FB
15797}
15798
7db13fae 15799void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15800{
6429db34 15801 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
15802}
15803
7db13fae 15804void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15805{
6429db34 15806 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
15807}
15808
7db13fae 15809static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15810 int flags)
6ea83fed
FB
15811{
15812 int i;
5e755519 15813 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15814
2a5612e6
SW
15815#define printfpr(fp) \
15816 do { \
15817 if (is_fpu64) \
15818 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15819 " fd:%13g fs:%13g psu: %13g\n", \
15820 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15821 (double)(fp)->fd, \
15822 (double)(fp)->fs[FP_ENDIAN_IDX], \
15823 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15824 else { \
15825 fpr_t tmp; \
15826 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15827 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15828 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15829 " fd:%13g fs:%13g psu:%13g\n", \
15830 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15831 (double)tmp.fd, \
15832 (double)tmp.fs[FP_ENDIAN_IDX], \
15833 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15834 } \
6ea83fed
FB
15835 } while(0)
15836
5a5012ec 15837
9a78eead
SW
15838 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15839 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15840 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15841 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15842 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15843 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15844 }
15845
15846#undef printfpr
15847}
15848
d26bc211 15849#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15850/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15851 sign-extended values on 64bit machines. */
c570fd16
TS
15852
15853#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15854
8706c382 15855static void
7db13fae 15856cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15857 fprintf_function cpu_fprintf,
8706c382 15858 int flags)
c570fd16
TS
15859{
15860 int i;
15861
b5dc7732
TS
15862 if (!SIGN_EXT_P(env->active_tc.PC))
15863 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15864 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15865 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15866 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15867 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15868 if (!SIGN_EXT_P(env->btarget))
3594c774 15869 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15870
15871 for (i = 0; i < 32; i++) {
b5dc7732
TS
15872 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15873 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15874 }
15875
15876 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15877 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15878 if (!SIGN_EXT_P(env->lladdr))
15879 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15880}
15881#endif
15882
878096ee
AF
15883void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15884 int flags)
6af0bf9c 15885{
878096ee
AF
15886 MIPSCPU *cpu = MIPS_CPU(cs);
15887 CPUMIPSState *env = &cpu->env;
6af0bf9c 15888 int i;
3b46e624 15889
a7200c9f
SW
15890 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15891 " LO=0x" TARGET_FMT_lx " ds %04x "
15892 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15893 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15894 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15895 for (i = 0; i < 32; i++) {
15896 if ((i & 3) == 0)
15897 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15898 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15899 if ((i & 3) == 3)
15900 cpu_fprintf(f, "\n");
15901 }
568b600d 15902
3594c774 15903 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15904 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15905 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15906 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15907 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15908 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15909#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15910 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15911#endif
6af0bf9c
FB
15912}
15913
78ce64f4 15914void mips_tcg_init(void)
39454628 15915{
f01be154 15916 int i;
39454628
TS
15917 static int inited;
15918
15919 /* Initialize various static tables. */
15920 if (inited)
6958549d 15921 return;
39454628 15922
a7812ae4 15923 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15924 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15925 for (i = 1; i < 32; i++)
a7812ae4 15926 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15927 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15928 regnames[i]);
d73ee8a2
RH
15929
15930 for (i = 0; i < 32; i++) {
15931 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15932 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15933 }
15934
a7812ae4 15935 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15936 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15937 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15938 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15939 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15940 regnames_HI[i]);
a7812ae4 15941 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15942 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15943 regnames_LO[i]);
a7812ae4 15944 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15945 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15946 regnames_ACX[i]);
15947 }
a7812ae4 15948 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15949 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15950 "DSPControl");
1ba74fb8 15951 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15952 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15953 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15954 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15955 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15956 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15957
a7812ae4 15958 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15959 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15960 "fcr0");
15961 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15962 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15963 "fcr31");
39454628
TS
15964
15965 inited = 1;
15966}
15967
aaed909a
FB
15968#include "translate_init.c"
15969
30bf942d 15970MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15971{
0f71a709 15972 MIPSCPU *cpu;
6af0bf9c 15973 CPUMIPSState *env;
c227f099 15974 const mips_def_t *def;
6af0bf9c 15975
aaed909a
FB
15976 def = cpu_mips_find_by_name(cpu_model);
15977 if (!def)
15978 return NULL;
0f71a709
AF
15979 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15980 env = &cpu->env;
aaed909a
FB
15981 env->cpu_model = def;
15982
51cc2e78
BS
15983#ifndef CONFIG_USER_ONLY
15984 mmu_init(env, def);
15985#endif
15986 fpu_init(env, def);
15987 mvp_init(env, def);
c1caf1d9
AF
15988
15989 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15990
30bf942d 15991 return cpu;
6ae81775
TS
15992}
15993
1bba0dc9 15994void cpu_state_reset(CPUMIPSState *env)
6ae81775 15995{
55e5c285
AF
15996 MIPSCPU *cpu = mips_env_get_cpu(env);
15997 CPUState *cs = CPU(cpu);
6ae81775 15998
51cc2e78
BS
15999 /* Reset registers to their default values */
16000 env->CP0_PRid = env->cpu_model->CP0_PRid;
16001 env->CP0_Config0 = env->cpu_model->CP0_Config0;
16002#ifdef TARGET_WORDS_BIGENDIAN
16003 env->CP0_Config0 |= (1 << CP0C0_BE);
16004#endif
16005 env->CP0_Config1 = env->cpu_model->CP0_Config1;
16006 env->CP0_Config2 = env->cpu_model->CP0_Config2;
16007 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
16008 env->CP0_Config4 = env->cpu_model->CP0_Config4;
16009 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
16010 env->CP0_Config5 = env->cpu_model->CP0_Config5;
16011 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
16012 env->CP0_Config6 = env->cpu_model->CP0_Config6;
16013 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
16014 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
16015 << env->cpu_model->CP0_LLAddr_shift;
16016 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
16017 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
16018 env->CCRes = env->cpu_model->CCRes;
16019 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
16020 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
16021 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
16022 env->current_tc = 0;
16023 env->SEGBITS = env->cpu_model->SEGBITS;
16024 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
16025#if defined(TARGET_MIPS64)
16026 if (env->cpu_model->insn_flags & ISA_MIPS3) {
16027 env->SEGMask |= 3ULL << 62;
16028 }
16029#endif
16030 env->PABITS = env->cpu_model->PABITS;
16031 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
16032 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
16033 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
16034 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
16035 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
16036 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
16037 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
16038 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
16039 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
16040 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
16041 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 16042 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
16043 env->insn_flags = env->cpu_model->insn_flags;
16044
0eaef5aa 16045#if defined(CONFIG_USER_ONLY)
03e6e501 16046 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
16047# ifdef TARGET_MIPS64
16048 /* Enable 64-bit register mode. */
16049 env->CP0_Status |= (1 << CP0St_PX);
16050# endif
16051# ifdef TARGET_ABI_MIPSN64
16052 /* Enable 64-bit address mode. */
16053 env->CP0_Status |= (1 << CP0St_UX);
16054# endif
94159135
MI
16055 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16056 hardware registers. */
16057 env->CP0_HWREna |= 0x0000000F;
91a75935 16058 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 16059 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 16060 }
6f0af304
PJ
16061 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
16062 env->CP0_Status |= (1 << CP0St_MX);
853c3240 16063 }
4d66261f
PJ
16064# if defined(TARGET_MIPS64)
16065 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16066 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
16067 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
16068 env->CP0_Status |= (1 << CP0St_FR);
16069 }
4d66261f 16070# endif
932e71cd
AJ
16071#else
16072 if (env->hflags & MIPS_HFLAG_BMASK) {
16073 /* If the exception was raised from a delay slot,
16074 come back to the jump. */
16075 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 16076 } else {
932e71cd
AJ
16077 env->CP0_ErrorEPC = env->active_tc.PC;
16078 }
16079 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
16080 env->CP0_Random = env->tlb->nb_tlb - 1;
16081 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 16082 env->CP0_Wired = 0;
0a2672b7
JH
16083 env->CP0_EBase = (cs->cpu_index & 0x3FF);
16084 if (kvm_enabled()) {
16085 env->CP0_EBase |= 0x40000000;
16086 } else {
16087 env->CP0_EBase |= 0x80000000;
16088 }
932e71cd
AJ
16089 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16090 /* vectored interrupts not implemented, timer on int 7,
16091 no performance counters. */
16092 env->CP0_IntCtl = 0xe0000000;
16093 {
16094 int i;
16095
16096 for (i = 0; i < 7; i++) {
16097 env->CP0_WatchLo[i] = 0;
16098 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 16099 }
932e71cd
AJ
16100 env->CP0_WatchLo[7] = 0;
16101 env->CP0_WatchHi[7] = 0;
fd88b6ab 16102 }
932e71cd
AJ
16103 /* Count register increments in debug mode, EJTAG version 1 */
16104 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 16105
4b69c7e2
JH
16106 cpu_mips_store_count(env, 1);
16107
9e56e756
EI
16108 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16109 int i;
16110
16111 /* Only TC0 on VPE 0 starts as active. */
16112 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 16113 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
16114 env->tcs[i].CP0_TCHalt = 1;
16115 }
16116 env->active_tc.CP0_TCHalt = 1;
259186a7 16117 cs->halted = 1;
9e56e756 16118
55e5c285 16119 if (cs->cpu_index == 0) {
9e56e756
EI
16120 /* VPE0 starts up enabled. */
16121 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16122 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16123
16124 /* TC0 starts up unhalted. */
259186a7 16125 cs->halted = 0;
9e56e756
EI
16126 env->active_tc.CP0_TCHalt = 0;
16127 env->tcs[0].CP0_TCHalt = 0;
16128 /* With thread 0 active. */
16129 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16130 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16131 }
16132 }
51cc2e78 16133#endif
03e6e501 16134 compute_hflags(env);
27103424 16135 cs->exception_index = EXCP_NONE;
6af0bf9c 16136}
d2856f1a 16137
7db13fae 16138void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16139{
25983cad 16140 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16141 env->hflags &= ~MIPS_HFLAG_BMASK;
16142 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16143 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16144 case MIPS_HFLAG_BR:
16145 break;
16146 case MIPS_HFLAG_BC:
16147 case MIPS_HFLAG_BL:
16148 case MIPS_HFLAG_B:
16149 env->btarget = gen_opc_btarget[pc_pos];
16150 break;
16151 }
d2856f1a 16152}