]> git.proxmox.com Git - qemu.git/blame - target-mips/translate.c
Merge branch 'target-arm.next' of git://git.linaro.org/people/pmaydell/qemu-arm
[qemu.git] / target-mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
6af0bf9c 24#include "cpu.h"
76cad711 25#include "disas/disas.h"
57fec1fe 26#include "tcg-op.h"
6af0bf9c 27
a7812ae4
PB
28#include "helper.h"
29#define GEN_HELPER 1
30#include "helper.h"
31
fb7729e2 32#define MIPS_DEBUG_DISAS 0
c570fd16 33//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c 34
7a387fff
TS
35/* MIPS major opcodes */
36#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
37
38enum {
39 /* indirect opcode tables */
7a387fff
TS
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 48 /* arithmetic with immediate */
7a387fff
TS
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
324d9e32 53 /* logic with immediate */
7a387fff
TS
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
324d9e32 58 /* arithmetic with immediate */
7a387fff
TS
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
e37e863f 61 /* Jump and branches */
7a387fff
TS
62 OPC_J = (0x02 << 26),
63 OPC_JAL = (0x03 << 26),
620e48f6 64 OPC_JALS = OPC_JAL | 0x5,
7a387fff
TS
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
620e48f6 74 OPC_JALXS = OPC_JALX | 0x5,
e37e863f 75 /* Load and stores */
7a387fff
TS
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
364d4831 82 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
364d4831 97 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
e37e863f 101 /* Floating point load/store */
7a387fff
TS
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
e37e863f 112 /* Cache and prefetch */
7a387fff
TS
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
e37e863f
FB
117};
118
119/* MIPS special opcodes */
7a387fff
TS
120#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
121
e37e863f
FB
122enum {
123 /* Shifts */
7a387fff 124 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 129 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 133 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 141 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 147 /* Multiplication / division */
7a387fff
TS
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
e37e863f 156 /* 2 registers arithmetic / logic */
7a387fff
TS
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 171 /* Jumps */
7a387fff
TS
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
364d4831 174 OPC_JALRC = OPC_JALR | (0x5 << 6),
620e48f6 175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
e37e863f 176 /* Traps */
7a387fff
TS
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 183 /* HI / LO registers load & stores */
7a387fff
TS
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 188 /* Conditional moves */
7a387fff
TS
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 191
7a387fff 192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
193
194 /* Special */
a0d700e4 195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
200
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
208};
209
e9c71dd1
TS
210/* Multiplication variants of the vr54xx. */
211#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
212
213enum {
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
228};
229
7a387fff
TS
230/* REGIMM (rt field) opcodes */
231#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
232
233enum {
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
3c824109 239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
7a387fff
TS
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
3c824109 242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
7a387fff
TS
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
e37e863f
FB
251};
252
7a387fff
TS
253/* Special2 opcodes */
254#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
255
e37e863f 256enum {
7a387fff
TS
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
263 /* Loongson 2F */
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 276 /* Misc */
7a387fff
TS
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 281 /* Special */
7a387fff
TS
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
283};
284
285/* Special3 opcodes */
286#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
287
288enum {
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
302
303 /* Loongson 2E */
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
316
317 /* MIPS DSP Load */
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 339 /* MIPS DSP Append Sub-class */
26690560 340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
e37e863f
FB
345};
346
7a387fff
TS
347/* BSHFL opcodes */
348#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
349
e37e863f 350enum {
7a387fff
TS
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
e37e863f
FB
354};
355
7a387fff
TS
356/* DBSHFL opcodes */
357#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
358
e37e863f 359enum {
7a387fff
TS
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
e37e863f
FB
362};
363
e45a93e2
JL
364/* MIPS DSP REGIMM opcodes */
365enum {
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
368};
369
9b1a1d68
JL
370#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
371/* MIPS DSP Load */
372enum {
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
377};
378
461c08df
JL
379#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
380enum {
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
407};
408
409#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
411enum {
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
430};
431
432#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
433enum {
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
454};
455
456#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457enum {
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 482};
a22260ae 483
77c5fa8b
JL
484#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485enum {
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
509};
461c08df 510
a22260ae
JL
511#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
512enum {
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
536};
537
1cb6686c
JL
538#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539enum {
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
542};
543
26690560
JL
544#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545enum {
df6126a7 546 /* MIPS DSP Append Sub-class */
26690560
JL
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
550};
551
b53371ed
JL
552#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553enum {
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
572};
573
461c08df
JL
574#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 601};
461c08df 602
461c08df
JL
603#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604enum {
a22260ae
JL
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
633};
461c08df 634
461c08df
JL
635#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636enum {
26690560
JL
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
666};
461c08df 667
26690560
JL
668#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669enum {
df6126a7 670 /* DSP Append Sub-class */
26690560
JL
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
675};
26690560 676
b53371ed
JL
677#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678enum {
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
701};
702
1cb6686c
JL
703#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704enum {
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
707};
1cb6686c 708
a22260ae
JL
709#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710enum {
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
738};
a22260ae 739
77c5fa8b
JL
740#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741enum {
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
769};
77c5fa8b 770
7a387fff
TS
771/* Coprocessor 0 (rs field) */
772#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
773
6ea83fed 774enum {
7a387fff
TS
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 787};
7a387fff
TS
788
789/* MFMC0 opcodes */
b48cfdff 790#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
791
792enum {
ead9360e
TS
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
799};
800
801/* Coprocessor 0 (with rs == C0) */
802#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
803
804enum {
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
813};
814
815/* Coprocessor 1 (rs field) */
816#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
817
bf4120ad
NF
818/* Values for the fmt field in FP instructions */
819enum {
820 /* 0 - 15 are reserved */
e459440a
AJ
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
828 /* 23 - 31 are reserved */
829};
830
7a387fff
TS
831enum {
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
e459440a
AJ
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
7a387fff
TS
850};
851
5a5012ec
TS
852#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
854
7a387fff
TS
855enum {
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
860};
861
5a5012ec
TS
862enum {
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
865};
866
867enum {
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
870};
7a387fff
TS
871
872#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
873
874enum {
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
884};
885
bd277fa1
RH
886#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
887
888enum {
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
897
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
906
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
915
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
924
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
931
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
938
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
945
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
952
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
959
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
966
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
973
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
980};
981
982
e0c84da7
TS
983#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
984
985enum {
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1001 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1006};
1007
39454628 1008/* global register indices */
a7812ae4
PB
1009static TCGv_ptr cpu_env;
1010static TCGv cpu_gpr[32], cpu_PC;
4b2eb8d2 1011static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
41db4607
AJ
1012static TCGv cpu_dspctrl, btarget, bcond;
1013static TCGv_i32 hflags;
a7812ae4 1014static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1015static TCGv_i64 fpu_f64[32];
aa0bf00b 1016
1a7ff922 1017static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1018static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1019
022c62cb 1020#include "exec/gen-icount.h"
2e70f6ef 1021
895c2d04 1022#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1024 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1025 tcg_temp_free_i32(helper_tmp); \
1026 } while(0)
be24bb4f 1027
895c2d04 1028#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1031 tcg_temp_free_i32(helper_tmp); \
1032 } while(0)
be24bb4f 1033
895c2d04
BS
1034#define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1038 } while(0)
1039
1040#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1044 } while(0)
1045
1046#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1050 } while(0)
1051
1052#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1055 tcg_temp_free_i32(helper_tmp); \
1056 } while(0)
be24bb4f 1057
895c2d04 1058#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1061 tcg_temp_free_i32(helper_tmp); \
1062 } while(0)
c239529e 1063
8e9ade68
TS
1064typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1067 uint32_t opcode;
7b270ef2 1068 int singlestep_enabled;
d75c135e 1069 int insn_flags;
8e9ade68
TS
1070 /* Routine used to access memory */
1071 int mem_idx;
1072 uint32_t hflags, saved_hflags;
1073 int bstate;
1074 target_ulong btarget;
1075} DisasContext;
1076
1077enum {
1078 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1079 * exception condition */
8e9ade68
TS
1080 BS_STOP = 1, /* We want to stop translation for any reason */
1081 BS_BRANCH = 2, /* We reached a branch condition */
1082 BS_EXCP = 3, /* We reached an exception condition */
1083};
1084
d73ee8a2
RH
1085static const char * const regnames[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1090};
6af0bf9c 1091
d73ee8a2
RH
1092static const char * const regnames_HI[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1094};
4b2eb8d2 1095
d73ee8a2
RH
1096static const char * const regnames_LO[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1098};
4b2eb8d2 1099
d73ee8a2
RH
1100static const char * const regnames_ACX[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1102};
4b2eb8d2 1103
d73ee8a2
RH
1104static const char * const fregnames[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1109};
958fb4a9 1110
fb7729e2
RH
1111#define MIPS_DEBUG(fmt, ...) \
1112 do { \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1117 } \
1118 } while (0)
1119
1120#define LOG_DISAS(...) \
1121 do { \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1124 } \
1125 } while (0)
958fb4a9 1126
8e9ade68 1127#define MIPS_INVAL(op) \
8e9ade68 1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1130
8e9ade68
TS
1131/* General purpose registers moves. */
1132static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1133{
8e9ade68
TS
1134 if (reg == 0)
1135 tcg_gen_movi_tl(t, 0);
1136 else
4b2eb8d2 1137 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1138}
1139
8e9ade68 1140static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1141{
8e9ade68 1142 if (reg != 0)
4b2eb8d2 1143 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1144}
1145
b10fa3c9 1146/* Moves to/from ACX register. */
4b2eb8d2 1147static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1148{
4b2eb8d2 1149 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1150}
1151
4b2eb8d2 1152static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1153{
4b2eb8d2 1154 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1155}
1156
8e9ade68 1157/* Moves to/from shadow registers. */
be24bb4f 1158static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1159{
d9bea114 1160 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1161
1162 if (from == 0)
d9bea114 1163 tcg_gen_movi_tl(t0, 0);
8e9ade68 1164 else {
d9bea114 1165 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1166 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1167
7db13fae 1168 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1169 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1170 tcg_gen_andi_i32(t2, t2, 0xf);
1171 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1172 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1173 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1174
d9bea114 1175 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1176 tcg_temp_free_ptr(addr);
d9bea114 1177 tcg_temp_free_i32(t2);
8e9ade68 1178 }
d9bea114
AJ
1179 gen_store_gpr(t0, to);
1180 tcg_temp_free(t0);
aaa9128a
TS
1181}
1182
be24bb4f 1183static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1184{
be24bb4f 1185 if (to != 0) {
d9bea114
AJ
1186 TCGv t0 = tcg_temp_new();
1187 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1188 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1189
d9bea114 1190 gen_load_gpr(t0, from);
7db13fae 1191 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1192 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1193 tcg_gen_andi_i32(t2, t2, 0xf);
1194 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1195 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1196 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1197
d9bea114 1198 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1199 tcg_temp_free_ptr(addr);
d9bea114
AJ
1200 tcg_temp_free_i32(t2);
1201 tcg_temp_free(t0);
8e9ade68 1202 }
aaa9128a
TS
1203}
1204
aaa9128a 1205/* Floating point register moves. */
d73ee8a2 1206static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1207{
d73ee8a2 1208 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1209}
1210
d73ee8a2 1211static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1212{
d73ee8a2
RH
1213 TCGv_i64 t64 = tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64, t);
1215 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1216 tcg_temp_free_i64(t64);
6d066274
AJ
1217}
1218
d73ee8a2 1219static void gen_load_fpr32h(TCGv_i32 t, int reg)
6d066274 1220{
d73ee8a2
RH
1221 TCGv_i64 t64 = tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1223 tcg_gen_trunc_i64_i32(t, t64);
1224 tcg_temp_free_i64(t64);
6d066274
AJ
1225}
1226
d73ee8a2 1227static void gen_store_fpr32h(TCGv_i32 t, int reg)
6d066274 1228{
d73ee8a2
RH
1229 TCGv_i64 t64 = tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64, t);
1231 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1232 tcg_temp_free_i64(t64);
aa0bf00b 1233}
6ea83fed 1234
d73ee8a2 1235static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1236{
f364515c 1237 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1238 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1239 } else {
d73ee8a2 1240 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1241 }
1242}
6ea83fed 1243
d73ee8a2 1244static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1245{
f364515c 1246 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1247 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1248 } else {
d73ee8a2
RH
1249 TCGv_i64 t0;
1250 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1251 t0 = tcg_temp_new_i64();
6d066274 1252 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1253 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1254 tcg_temp_free_i64(t0);
aa0bf00b
TS
1255 }
1256}
6ea83fed 1257
d94536f4 1258static inline int get_fp_bit (int cc)
a16336e4 1259{
d94536f4
AJ
1260 if (cc)
1261 return 24 + cc;
1262 else
1263 return 23;
a16336e4
TS
1264}
1265
30898801 1266/* Tests */
8e9ade68
TS
1267static inline void gen_save_pc(target_ulong pc)
1268{
1eb75d4a 1269 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1270}
30898801 1271
356265ae 1272static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1273{
d12d51d5 1274 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1275 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1276 gen_save_pc(ctx->pc);
6af0bf9c
FB
1277 ctx->saved_pc = ctx->pc;
1278 }
1279 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1280 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1281 ctx->saved_hflags = ctx->hflags;
364d4831 1282 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1283 case MIPS_HFLAG_BR:
5a5012ec
TS
1284 break;
1285 case MIPS_HFLAG_BC:
5a5012ec 1286 case MIPS_HFLAG_BL:
5a5012ec 1287 case MIPS_HFLAG_B:
d077b6f7 1288 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1289 break;
6af0bf9c
FB
1290 }
1291 }
1292}
1293
7db13fae 1294static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1295{
fd4a04eb 1296 ctx->saved_hflags = ctx->hflags;
364d4831 1297 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1298 case MIPS_HFLAG_BR:
fd4a04eb
TS
1299 break;
1300 case MIPS_HFLAG_BC:
1301 case MIPS_HFLAG_BL:
39454628 1302 case MIPS_HFLAG_B:
fd4a04eb 1303 ctx->btarget = env->btarget;
fd4a04eb 1304 break;
5a5012ec
TS
1305 }
1306}
1307
356265ae 1308static inline void
48d38ca5 1309generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1310{
a7812ae4
PB
1311 TCGv_i32 texcp = tcg_const_i32(excp);
1312 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1313 save_cpu_state(ctx, 1);
895c2d04 1314 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1315 tcg_temp_free_i32(terr);
1316 tcg_temp_free_i32(texcp);
aaa9128a
TS
1317}
1318
356265ae 1319static inline void
48d38ca5 1320generate_exception (DisasContext *ctx, int excp)
aaa9128a 1321{
6af0bf9c 1322 save_cpu_state(ctx, 1);
895c2d04 1323 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1324}
1325
48d38ca5 1326/* Addresses computation */
941694d0 1327static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1328{
941694d0 1329 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1330
1331#if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1335 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1336 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1337 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1338 }
1339#endif
4ad40f36
FB
1340}
1341
356265ae 1342static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1343{
fe253235 1344 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1345 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1346}
1347
356265ae 1348static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1349{
fe253235 1350 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1351 generate_exception_err(ctx, EXCP_CpU, 1);
1352}
1353
b8aa4598
TS
1354/* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1356 opcode tables. */
1357
356265ae 1358static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1359{
1360 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1361 generate_exception(ctx, EXCP_RI);
1362}
1363
1364/* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1366
356265ae 1367static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1368{
b8aa4598 1369 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1370 generate_exception(ctx, EXCP_RI);
1371}
1372
1373/*
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 *
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 */
356265ae 1384static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1385{
fe253235 1386 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1387 generate_exception(ctx, EXCP_RI);
1388}
1389
853c3240
JL
1390/* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1392 */
1393
1394static inline void check_dsp(DisasContext *ctx)
1395{
1396 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1397 if (ctx->insn_flags & ASE_DSP) {
1398 generate_exception(ctx, EXCP_DSPDIS);
1399 } else {
1400 generate_exception(ctx, EXCP_RI);
1401 }
853c3240
JL
1402 }
1403}
1404
1405static inline void check_dspr2(DisasContext *ctx)
1406{
1407 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1408 if (ctx->insn_flags & ASE_DSP) {
1409 generate_exception(ctx, EXCP_DSPDIS);
1410 } else {
1411 generate_exception(ctx, EXCP_RI);
1412 }
853c3240
JL
1413 }
1414}
1415
3a95e3a7 1416/* This code generates a "reserved instruction" exception if the
e189e748 1417 CPU does not support the instruction set corresponding to flags. */
d75c135e 1418static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1419{
d75c135e 1420 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1421 generate_exception(ctx, EXCP_RI);
d75c135e 1422 }
3a95e3a7
TS
1423}
1424
e189e748
TS
1425/* This code generates a "reserved instruction" exception if 64-bit
1426 instructions are not enabled. */
356265ae 1427static inline void check_mips_64(DisasContext *ctx)
e189e748 1428{
fe253235 1429 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1430 generate_exception(ctx, EXCP_RI);
1431}
1432
8153667c
NF
1433/* Define small wrappers for gen_load_fpr* so that we have a uniform
1434 calling interface for 32 and 64-bit FPRs. No sense in changing
1435 all callers for gen_load_fpr32 when we need the CTX parameter for
1436 this one use. */
1437#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1440static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1441 int ft, int fs, int cc) \
1442{ \
1443 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1444 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1445 switch (ifmt) { \
1446 case FMT_PS: \
1447 check_cp1_64bitmode(ctx); \
1448 break; \
1449 case FMT_D: \
1450 if (abs) { \
1451 check_cop1x(ctx); \
1452 } \
1453 check_cp1_registers(ctx, fs | ft); \
1454 break; \
1455 case FMT_S: \
1456 if (abs) { \
1457 check_cop1x(ctx); \
1458 } \
1459 break; \
1460 } \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1463 switch (n) { \
895c2d04
BS
1464 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1465 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1466 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1467 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1468 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1469 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1470 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1471 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1472 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1473 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1475 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1476 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1477 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1478 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1479 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1480 default: abort(); \
1481 } \
1482 tcg_temp_free_i##bits (fp0); \
1483 tcg_temp_free_i##bits (fp1); \
1484}
1485
1486FOP_CONDS(, 0, d, FMT_D, 64)
1487FOP_CONDS(abs, 1, d, FMT_D, 64)
1488FOP_CONDS(, 0, s, FMT_S, 32)
1489FOP_CONDS(abs, 1, s, FMT_S, 32)
1490FOP_CONDS(, 0, ps, FMT_PS, 64)
1491FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1492#undef FOP_CONDS
1493#undef gen_ldcmp_fpr32
1494#undef gen_ldcmp_fpr64
1495
958fb4a9 1496/* load/store instructions. */
e7139c44 1497#ifdef CONFIG_USER_ONLY
d9bea114 1498#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1499static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1500{ \
1501 TCGv t0 = tcg_temp_new(); \
1502 tcg_gen_mov_tl(t0, arg1); \
1503 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1504 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1505 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1506 tcg_temp_free(t0); \
aaa9128a 1507}
e7139c44
AJ
1508#else
1509#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1510static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1511{ \
895c2d04 1512 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1513}
1514#endif
aaa9128a
TS
1515OP_LD_ATOMIC(ll,ld32s);
1516#if defined(TARGET_MIPS64)
1517OP_LD_ATOMIC(lld,ld64);
1518#endif
1519#undef OP_LD_ATOMIC
1520
590bc601
PB
1521#ifdef CONFIG_USER_ONLY
1522#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1523static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1524{ \
1525 TCGv t0 = tcg_temp_new(); \
1526 int l1 = gen_new_label(); \
1527 int l2 = gen_new_label(); \
1528 \
1529 tcg_gen_andi_tl(t0, arg2, almask); \
1530 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1531 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1532 generate_exception(ctx, EXCP_AdES); \
1533 gen_set_label(l1); \
7db13fae 1534 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1535 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1536 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1537 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1538 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1539 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1540 gen_set_label(l2); \
1541 tcg_gen_movi_tl(t0, 0); \
1542 gen_store_gpr(t0, rt); \
1543 tcg_temp_free(t0); \
1544}
1545#else
1546#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1547static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1548{ \
1549 TCGv t0 = tcg_temp_new(); \
895c2d04 1550 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1551 gen_store_gpr(t0, rt); \
590bc601
PB
1552 tcg_temp_free(t0); \
1553}
1554#endif
590bc601 1555OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1556#if defined(TARGET_MIPS64)
590bc601 1557OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1558#endif
1559#undef OP_ST_ATOMIC
1560
662d7485
NF
1561static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1562 int base, int16_t offset)
1563{
1564 if (base == 0) {
1565 tcg_gen_movi_tl(addr, offset);
1566 } else if (offset == 0) {
1567 gen_load_gpr(addr, base);
1568 } else {
1569 tcg_gen_movi_tl(addr, offset);
1570 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1571 }
1572}
1573
364d4831
NF
1574static target_ulong pc_relative_pc (DisasContext *ctx)
1575{
1576 target_ulong pc = ctx->pc;
1577
1578 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1579 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1580
1581 pc -= branch_bytes;
1582 }
1583
1584 pc &= ~(target_ulong)3;
1585 return pc;
1586}
1587
5c13fdfd 1588/* Load */
d75c135e
AJ
1589static void gen_ld(DisasContext *ctx, uint32_t opc,
1590 int rt, int base, int16_t offset)
6af0bf9c 1591{
5c13fdfd 1592 const char *opn = "ld";
fc40787a 1593 TCGv t0, t1, t2;
afa88c3a 1594
d75c135e 1595 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1596 /* Loongson CPU uses a load to zero register for prefetch.
1597 We emulate it as a NOP. On other CPU we must perform the
1598 actual memory access. */
1599 MIPS_DEBUG("NOP");
1600 return;
1601 }
6af0bf9c 1602
afa88c3a 1603 t0 = tcg_temp_new();
662d7485 1604 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1605
6af0bf9c 1606 switch (opc) {
d26bc211 1607#if defined(TARGET_MIPS64)
6e473128 1608 case OPC_LWU:
2910c6cb 1609 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
78723684 1610 gen_store_gpr(t0, rt);
6e473128
TS
1611 opn = "lwu";
1612 break;
6af0bf9c 1613 case OPC_LD:
2910c6cb 1614 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
78723684 1615 gen_store_gpr(t0, rt);
6af0bf9c
FB
1616 opn = "ld";
1617 break;
7a387fff 1618 case OPC_LLD:
b835e919 1619 save_cpu_state(ctx, 1);
5c13fdfd 1620 op_ld_lld(t0, t0, ctx);
78723684 1621 gen_store_gpr(t0, rt);
7a387fff
TS
1622 opn = "lld";
1623 break;
6af0bf9c 1624 case OPC_LDL:
3cee3050 1625 t1 = tcg_temp_new();
fc40787a
AJ
1626 tcg_gen_andi_tl(t1, t0, 7);
1627#ifndef TARGET_WORDS_BIGENDIAN
1628 tcg_gen_xori_tl(t1, t1, 7);
1629#endif
1630 tcg_gen_shli_tl(t1, t1, 3);
1631 tcg_gen_andi_tl(t0, t0, ~7);
1632 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1633 tcg_gen_shl_tl(t0, t0, t1);
1634 tcg_gen_xori_tl(t1, t1, 63);
1635 t2 = tcg_const_tl(0x7fffffffffffffffull);
1636 tcg_gen_shr_tl(t2, t2, t1);
78723684 1637 gen_load_gpr(t1, rt);
fc40787a
AJ
1638 tcg_gen_and_tl(t1, t1, t2);
1639 tcg_temp_free(t2);
1640 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1641 tcg_temp_free(t1);
fc40787a 1642 gen_store_gpr(t0, rt);
6af0bf9c
FB
1643 opn = "ldl";
1644 break;
6af0bf9c 1645 case OPC_LDR:
3cee3050 1646 t1 = tcg_temp_new();
fc40787a
AJ
1647 tcg_gen_andi_tl(t1, t0, 7);
1648#ifdef TARGET_WORDS_BIGENDIAN
1649 tcg_gen_xori_tl(t1, t1, 7);
1650#endif
1651 tcg_gen_shli_tl(t1, t1, 3);
1652 tcg_gen_andi_tl(t0, t0, ~7);
1653 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1654 tcg_gen_shr_tl(t0, t0, t1);
1655 tcg_gen_xori_tl(t1, t1, 63);
1656 t2 = tcg_const_tl(0xfffffffffffffffeull);
1657 tcg_gen_shl_tl(t2, t2, t1);
78723684 1658 gen_load_gpr(t1, rt);
fc40787a
AJ
1659 tcg_gen_and_tl(t1, t1, t2);
1660 tcg_temp_free(t2);
1661 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1662 tcg_temp_free(t1);
fc40787a 1663 gen_store_gpr(t0, rt);
6af0bf9c
FB
1664 opn = "ldr";
1665 break;
364d4831 1666 case OPC_LDPC:
3cee3050 1667 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1668 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1669 tcg_temp_free(t1);
2910c6cb 1670 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
364d4831 1671 gen_store_gpr(t0, rt);
5c13fdfd 1672 opn = "ldpc";
364d4831 1673 break;
6af0bf9c 1674#endif
364d4831 1675 case OPC_LWPC:
3cee3050 1676 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1677 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1678 tcg_temp_free(t1);
2910c6cb 1679 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
364d4831 1680 gen_store_gpr(t0, rt);
5c13fdfd 1681 opn = "lwpc";
364d4831 1682 break;
6af0bf9c 1683 case OPC_LW:
2910c6cb 1684 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
78723684 1685 gen_store_gpr(t0, rt);
6af0bf9c
FB
1686 opn = "lw";
1687 break;
6af0bf9c 1688 case OPC_LH:
2910c6cb 1689 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
78723684 1690 gen_store_gpr(t0, rt);
6af0bf9c
FB
1691 opn = "lh";
1692 break;
6af0bf9c 1693 case OPC_LHU:
2910c6cb 1694 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
78723684 1695 gen_store_gpr(t0, rt);
6af0bf9c
FB
1696 opn = "lhu";
1697 break;
1698 case OPC_LB:
2910c6cb 1699 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
78723684 1700 gen_store_gpr(t0, rt);
6af0bf9c
FB
1701 opn = "lb";
1702 break;
6af0bf9c 1703 case OPC_LBU:
2910c6cb 1704 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
78723684 1705 gen_store_gpr(t0, rt);
6af0bf9c
FB
1706 opn = "lbu";
1707 break;
1708 case OPC_LWL:
3cee3050 1709 t1 = tcg_temp_new();
fc40787a
AJ
1710 tcg_gen_andi_tl(t1, t0, 3);
1711#ifndef TARGET_WORDS_BIGENDIAN
1712 tcg_gen_xori_tl(t1, t1, 3);
1713#endif
1714 tcg_gen_shli_tl(t1, t1, 3);
1715 tcg_gen_andi_tl(t0, t0, ~3);
1716 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1717 tcg_gen_shl_tl(t0, t0, t1);
1718 tcg_gen_xori_tl(t1, t1, 31);
1719 t2 = tcg_const_tl(0x7fffffffull);
1720 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1721 gen_load_gpr(t1, rt);
fc40787a
AJ
1722 tcg_gen_and_tl(t1, t1, t2);
1723 tcg_temp_free(t2);
1724 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1725 tcg_temp_free(t1);
fc40787a
AJ
1726 tcg_gen_ext32s_tl(t0, t0);
1727 gen_store_gpr(t0, rt);
6af0bf9c
FB
1728 opn = "lwl";
1729 break;
6af0bf9c 1730 case OPC_LWR:
3cee3050 1731 t1 = tcg_temp_new();
fc40787a
AJ
1732 tcg_gen_andi_tl(t1, t0, 3);
1733#ifdef TARGET_WORDS_BIGENDIAN
1734 tcg_gen_xori_tl(t1, t1, 3);
1735#endif
1736 tcg_gen_shli_tl(t1, t1, 3);
1737 tcg_gen_andi_tl(t0, t0, ~3);
1738 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1739 tcg_gen_shr_tl(t0, t0, t1);
1740 tcg_gen_xori_tl(t1, t1, 31);
1741 t2 = tcg_const_tl(0xfffffffeull);
1742 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1743 gen_load_gpr(t1, rt);
fc40787a
AJ
1744 tcg_gen_and_tl(t1, t1, t2);
1745 tcg_temp_free(t2);
1746 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1747 tcg_temp_free(t1);
fc40787a 1748 gen_store_gpr(t0, rt);
6af0bf9c
FB
1749 opn = "lwr";
1750 break;
6af0bf9c 1751 case OPC_LL:
e7139c44 1752 save_cpu_state(ctx, 1);
5c13fdfd 1753 op_ld_ll(t0, t0, ctx);
78723684 1754 gen_store_gpr(t0, rt);
6af0bf9c
FB
1755 opn = "ll";
1756 break;
d66c7132 1757 }
2abf314d 1758 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1759 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1760 tcg_temp_free(t0);
d66c7132
AJ
1761}
1762
5c13fdfd
AJ
1763/* Store */
1764static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1765 int base, int16_t offset)
1766{
1767 const char *opn = "st";
1768 TCGv t0 = tcg_temp_new();
1769 TCGv t1 = tcg_temp_new();
1770
1771 gen_base_offset_addr(ctx, t0, base, offset);
1772 gen_load_gpr(t1, rt);
1773 switch (opc) {
1774#if defined(TARGET_MIPS64)
1775 case OPC_SD:
2910c6cb 1776 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1777 opn = "sd";
1778 break;
1779 case OPC_SDL:
1780 save_cpu_state(ctx, 1);
895c2d04 1781 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1782 opn = "sdl";
1783 break;
1784 case OPC_SDR:
1785 save_cpu_state(ctx, 1);
895c2d04 1786 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1787 opn = "sdr";
1788 break;
1789#endif
1790 case OPC_SW:
2910c6cb 1791 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1792 opn = "sw";
1793 break;
1794 case OPC_SH:
2910c6cb 1795 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1796 opn = "sh";
1797 break;
1798 case OPC_SB:
2910c6cb 1799 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1800 opn = "sb";
1801 break;
1802 case OPC_SWL:
1803 save_cpu_state(ctx, 1);
895c2d04 1804 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1805 opn = "swl";
1806 break;
1807 case OPC_SWR:
1808 save_cpu_state(ctx, 1);
895c2d04 1809 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1810 opn = "swr";
1811 break;
1812 }
2abf314d 1813 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1814 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1815 tcg_temp_free(t0);
1816 tcg_temp_free(t1);
1817}
1818
1819
d66c7132
AJ
1820/* Store conditional */
1821static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1822 int base, int16_t offset)
1823{
1824 const char *opn = "st_cond";
1825 TCGv t0, t1;
1826
2d2826b9 1827#ifdef CONFIG_USER_ONLY
d66c7132 1828 t0 = tcg_temp_local_new();
d66c7132 1829 t1 = tcg_temp_local_new();
2d2826b9
AJ
1830#else
1831 t0 = tcg_temp_new();
1832 t1 = tcg_temp_new();
1833#endif
1834 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1835 gen_load_gpr(t1, rt);
1836 switch (opc) {
1837#if defined(TARGET_MIPS64)
1838 case OPC_SCD:
b835e919 1839 save_cpu_state(ctx, 1);
5c13fdfd 1840 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1841 opn = "scd";
1842 break;
1843#endif
6af0bf9c 1844 case OPC_SC:
e7139c44 1845 save_cpu_state(ctx, 1);
5c13fdfd 1846 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1847 opn = "sc";
1848 break;
6af0bf9c 1849 }
2abf314d 1850 (void)opn; /* avoid a compiler warning */
6af0bf9c 1851 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1852 tcg_temp_free(t1);
d66c7132 1853 tcg_temp_free(t0);
6af0bf9c
FB
1854}
1855
6ea83fed 1856/* Load and store */
7a387fff 1857static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1858 int base, int16_t offset)
6ea83fed 1859{
923617a3 1860 const char *opn = "flt_ldst";
4e2474d6 1861 TCGv t0 = tcg_temp_new();
6ea83fed 1862
662d7485 1863 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1864 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1865 memory access. */
6ea83fed
FB
1866 switch (opc) {
1867 case OPC_LWC1:
b6d96bed 1868 {
a7812ae4 1869 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1870
c407df81
AJ
1871 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1872 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 1873 gen_store_fpr32(fp0, ft);
a7812ae4 1874 tcg_temp_free_i32(fp0);
b6d96bed 1875 }
6ea83fed
FB
1876 opn = "lwc1";
1877 break;
1878 case OPC_SWC1:
b6d96bed 1879 {
a7812ae4
PB
1880 TCGv_i32 fp0 = tcg_temp_new_i32();
1881 TCGv t1 = tcg_temp_new();
b6d96bed
TS
1882
1883 gen_load_fpr32(fp0, ft);
a7812ae4
PB
1884 tcg_gen_extu_i32_tl(t1, fp0);
1885 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1886 tcg_temp_free(t1);
1887 tcg_temp_free_i32(fp0);
b6d96bed 1888 }
6ea83fed
FB
1889 opn = "swc1";
1890 break;
1891 case OPC_LDC1:
b6d96bed 1892 {
a7812ae4 1893 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1894
1895 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1896 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1897 tcg_temp_free_i64(fp0);
b6d96bed 1898 }
6ea83fed
FB
1899 opn = "ldc1";
1900 break;
1901 case OPC_SDC1:
b6d96bed 1902 {
a7812ae4 1903 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1904
1905 gen_load_fpr64(ctx, fp0, ft);
1906 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 1907 tcg_temp_free_i64(fp0);
b6d96bed 1908 }
6ea83fed
FB
1909 opn = "sdc1";
1910 break;
1911 default:
923617a3 1912 MIPS_INVAL(opn);
e397ee33 1913 generate_exception(ctx, EXCP_RI);
78723684 1914 goto out;
6ea83fed 1915 }
2abf314d 1916 (void)opn; /* avoid a compiler warning */
6ea83fed 1917 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1918 out:
1919 tcg_temp_free(t0);
6ea83fed 1920}
6ea83fed 1921
7db13fae 1922static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
26ebe468
NF
1923 uint32_t op, int rt, int rs, int16_t imm)
1924{
1925 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1926 check_cp1_enabled(ctx);
1927 gen_flt_ldst(ctx, op, rt, rs, imm);
1928 } else {
1929 generate_exception_err(ctx, EXCP_CpU, 1);
1930 }
1931}
1932
6af0bf9c 1933/* Arithmetic with immediate operand */
d75c135e
AJ
1934static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1935 int rt, int rs, int16_t imm)
6af0bf9c 1936{
324d9e32 1937 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1938 const char *opn = "imm arith";
6af0bf9c 1939
7a387fff 1940 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1941 /* If no destination, treat it as a NOP.
1942 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1943 MIPS_DEBUG("NOP");
324d9e32 1944 return;
6af0bf9c
FB
1945 }
1946 switch (opc) {
1947 case OPC_ADDI:
48d38ca5 1948 {
324d9e32
AJ
1949 TCGv t0 = tcg_temp_local_new();
1950 TCGv t1 = tcg_temp_new();
1951 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1952 int l1 = gen_new_label();
1953
324d9e32
AJ
1954 gen_load_gpr(t1, rs);
1955 tcg_gen_addi_tl(t0, t1, uimm);
1956 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1957
324d9e32
AJ
1958 tcg_gen_xori_tl(t1, t1, ~uimm);
1959 tcg_gen_xori_tl(t2, t0, uimm);
1960 tcg_gen_and_tl(t1, t1, t2);
1961 tcg_temp_free(t2);
1962 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1963 tcg_temp_free(t1);
48d38ca5
TS
1964 /* operands of same sign, result different sign */
1965 generate_exception(ctx, EXCP_OVERFLOW);
1966 gen_set_label(l1);
78723684 1967 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1968 gen_store_gpr(t0, rt);
1969 tcg_temp_free(t0);
48d38ca5 1970 }
6af0bf9c
FB
1971 opn = "addi";
1972 break;
1973 case OPC_ADDIU:
324d9e32
AJ
1974 if (rs != 0) {
1975 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1976 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1977 } else {
1978 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1979 }
6af0bf9c
FB
1980 opn = "addiu";
1981 break;
d26bc211 1982#if defined(TARGET_MIPS64)
7a387fff 1983 case OPC_DADDI:
48d38ca5 1984 {
324d9e32
AJ
1985 TCGv t0 = tcg_temp_local_new();
1986 TCGv t1 = tcg_temp_new();
1987 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1988 int l1 = gen_new_label();
1989
324d9e32
AJ
1990 gen_load_gpr(t1, rs);
1991 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1992
324d9e32
AJ
1993 tcg_gen_xori_tl(t1, t1, ~uimm);
1994 tcg_gen_xori_tl(t2, t0, uimm);
1995 tcg_gen_and_tl(t1, t1, t2);
1996 tcg_temp_free(t2);
1997 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1998 tcg_temp_free(t1);
48d38ca5
TS
1999 /* operands of same sign, result different sign */
2000 generate_exception(ctx, EXCP_OVERFLOW);
2001 gen_set_label(l1);
324d9e32
AJ
2002 gen_store_gpr(t0, rt);
2003 tcg_temp_free(t0);
48d38ca5 2004 }
7a387fff
TS
2005 opn = "daddi";
2006 break;
2007 case OPC_DADDIU:
324d9e32
AJ
2008 if (rs != 0) {
2009 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2010 } else {
2011 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2012 }
7a387fff
TS
2013 opn = "daddiu";
2014 break;
2015#endif
324d9e32 2016 }
2abf314d 2017 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2018 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2019}
2020
2021/* Logic with immediate operand */
d75c135e 2022static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2023 int rt, int rs, int16_t imm)
324d9e32
AJ
2024{
2025 target_ulong uimm;
324d9e32
AJ
2026
2027 if (rt == 0) {
2028 /* If no destination, treat it as a NOP. */
2029 MIPS_DEBUG("NOP");
2030 return;
2031 }
2032 uimm = (uint16_t)imm;
2033 switch (opc) {
6af0bf9c 2034 case OPC_ANDI:
324d9e32
AJ
2035 if (likely(rs != 0))
2036 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2037 else
2038 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2039 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2040 regnames[rs], uimm);
6af0bf9c
FB
2041 break;
2042 case OPC_ORI:
324d9e32
AJ
2043 if (rs != 0)
2044 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2045 else
2046 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2047 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2048 regnames[rs], uimm);
6af0bf9c
FB
2049 break;
2050 case OPC_XORI:
324d9e32
AJ
2051 if (likely(rs != 0))
2052 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2053 else
2054 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2055 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2056 regnames[rs], uimm);
6af0bf9c
FB
2057 break;
2058 case OPC_LUI:
324d9e32 2059 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2060 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2061 break;
2062
2063 default:
2064 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2065 break;
324d9e32 2066 }
324d9e32
AJ
2067}
2068
2069/* Set on less than with immediate operand */
d75c135e 2070static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2071 int rt, int rs, int16_t imm)
324d9e32
AJ
2072{
2073 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2074 const char *opn = "imm arith";
2075 TCGv t0;
2076
2077 if (rt == 0) {
2078 /* If no destination, treat it as a NOP. */
2079 MIPS_DEBUG("NOP");
2080 return;
2081 }
2082 t0 = tcg_temp_new();
2083 gen_load_gpr(t0, rs);
2084 switch (opc) {
2085 case OPC_SLTI:
e68dd28f 2086 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2087 opn = "slti";
2088 break;
2089 case OPC_SLTIU:
e68dd28f 2090 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2091 opn = "sltiu";
2092 break;
2093 }
2abf314d 2094 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2095 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2096 tcg_temp_free(t0);
2097}
2098
2099/* Shifts with immediate operand */
d75c135e 2100static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2101 int rt, int rs, int16_t imm)
2102{
2103 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2104 const char *opn = "imm shift";
2105 TCGv t0;
2106
2107 if (rt == 0) {
2108 /* If no destination, treat it as a NOP. */
2109 MIPS_DEBUG("NOP");
2110 return;
2111 }
2112
2113 t0 = tcg_temp_new();
2114 gen_load_gpr(t0, rs);
2115 switch (opc) {
6af0bf9c 2116 case OPC_SLL:
78723684 2117 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2118 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2119 opn = "sll";
2120 break;
2121 case OPC_SRA:
324d9e32 2122 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2123 opn = "sra";
2124 break;
2125 case OPC_SRL:
ea63e2c3
NF
2126 if (uimm != 0) {
2127 tcg_gen_ext32u_tl(t0, t0);
2128 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2129 } else {
2130 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2131 }
ea63e2c3
NF
2132 opn = "srl";
2133 break;
2134 case OPC_ROTR:
2135 if (uimm != 0) {
2136 TCGv_i32 t1 = tcg_temp_new_i32();
2137
2138 tcg_gen_trunc_tl_i32(t1, t0);
2139 tcg_gen_rotri_i32(t1, t1, uimm);
2140 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2141 tcg_temp_free_i32(t1);
3399e30f
NF
2142 } else {
2143 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2144 }
2145 opn = "rotr";
7a387fff 2146 break;
d26bc211 2147#if defined(TARGET_MIPS64)
7a387fff 2148 case OPC_DSLL:
324d9e32 2149 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2150 opn = "dsll";
2151 break;
2152 case OPC_DSRA:
324d9e32 2153 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2154 opn = "dsra";
2155 break;
2156 case OPC_DSRL:
ea63e2c3
NF
2157 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2158 opn = "dsrl";
2159 break;
2160 case OPC_DROTR:
2161 if (uimm != 0) {
2162 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2163 } else {
2164 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2165 }
ea63e2c3 2166 opn = "drotr";
7a387fff
TS
2167 break;
2168 case OPC_DSLL32:
324d9e32 2169 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2170 opn = "dsll32";
2171 break;
2172 case OPC_DSRA32:
324d9e32 2173 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2174 opn = "dsra32";
2175 break;
2176 case OPC_DSRL32:
ea63e2c3
NF
2177 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2178 opn = "dsrl32";
2179 break;
2180 case OPC_DROTR32:
2181 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2182 opn = "drotr32";
6af0bf9c 2183 break;
7a387fff 2184#endif
6af0bf9c 2185 }
2abf314d 2186 (void)opn; /* avoid a compiler warning */
93b12ccc 2187 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2188 tcg_temp_free(t0);
6af0bf9c
FB
2189}
2190
2191/* Arithmetic */
d75c135e
AJ
2192static void gen_arith(DisasContext *ctx, uint32_t opc,
2193 int rd, int rs, int rt)
6af0bf9c 2194{
923617a3 2195 const char *opn = "arith";
6af0bf9c 2196
7a387fff
TS
2197 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2198 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2199 /* If no destination, treat it as a NOP.
2200 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2201 MIPS_DEBUG("NOP");
460f00c4 2202 return;
185f0762 2203 }
460f00c4 2204
6af0bf9c
FB
2205 switch (opc) {
2206 case OPC_ADD:
48d38ca5 2207 {
460f00c4
AJ
2208 TCGv t0 = tcg_temp_local_new();
2209 TCGv t1 = tcg_temp_new();
2210 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2211 int l1 = gen_new_label();
2212
460f00c4
AJ
2213 gen_load_gpr(t1, rs);
2214 gen_load_gpr(t2, rt);
2215 tcg_gen_add_tl(t0, t1, t2);
2216 tcg_gen_ext32s_tl(t0, t0);
2217 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2218 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2219 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2220 tcg_temp_free(t2);
2221 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2222 tcg_temp_free(t1);
48d38ca5
TS
2223 /* operands of same sign, result different sign */
2224 generate_exception(ctx, EXCP_OVERFLOW);
2225 gen_set_label(l1);
460f00c4
AJ
2226 gen_store_gpr(t0, rd);
2227 tcg_temp_free(t0);
48d38ca5 2228 }
6af0bf9c
FB
2229 opn = "add";
2230 break;
2231 case OPC_ADDU:
460f00c4
AJ
2232 if (rs != 0 && rt != 0) {
2233 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2234 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2235 } else if (rs == 0 && rt != 0) {
2236 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2237 } else if (rs != 0 && rt == 0) {
2238 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2239 } else {
2240 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2241 }
6af0bf9c
FB
2242 opn = "addu";
2243 break;
2244 case OPC_SUB:
48d38ca5 2245 {
460f00c4
AJ
2246 TCGv t0 = tcg_temp_local_new();
2247 TCGv t1 = tcg_temp_new();
2248 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2249 int l1 = gen_new_label();
2250
460f00c4
AJ
2251 gen_load_gpr(t1, rs);
2252 gen_load_gpr(t2, rt);
2253 tcg_gen_sub_tl(t0, t1, t2);
2254 tcg_gen_ext32s_tl(t0, t0);
2255 tcg_gen_xor_tl(t2, t1, t2);
2256 tcg_gen_xor_tl(t1, t0, t1);
2257 tcg_gen_and_tl(t1, t1, t2);
2258 tcg_temp_free(t2);
2259 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2260 tcg_temp_free(t1);
31e3104f 2261 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2262 generate_exception(ctx, EXCP_OVERFLOW);
2263 gen_set_label(l1);
460f00c4
AJ
2264 gen_store_gpr(t0, rd);
2265 tcg_temp_free(t0);
48d38ca5 2266 }
6af0bf9c
FB
2267 opn = "sub";
2268 break;
2269 case OPC_SUBU:
460f00c4
AJ
2270 if (rs != 0 && rt != 0) {
2271 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2272 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2273 } else if (rs == 0 && rt != 0) {
2274 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2275 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2276 } else if (rs != 0 && rt == 0) {
2277 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2278 } else {
2279 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2280 }
6af0bf9c
FB
2281 opn = "subu";
2282 break;
d26bc211 2283#if defined(TARGET_MIPS64)
7a387fff 2284 case OPC_DADD:
48d38ca5 2285 {
460f00c4
AJ
2286 TCGv t0 = tcg_temp_local_new();
2287 TCGv t1 = tcg_temp_new();
2288 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2289 int l1 = gen_new_label();
2290
460f00c4
AJ
2291 gen_load_gpr(t1, rs);
2292 gen_load_gpr(t2, rt);
2293 tcg_gen_add_tl(t0, t1, t2);
2294 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2295 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2296 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2297 tcg_temp_free(t2);
2298 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2299 tcg_temp_free(t1);
48d38ca5
TS
2300 /* operands of same sign, result different sign */
2301 generate_exception(ctx, EXCP_OVERFLOW);
2302 gen_set_label(l1);
460f00c4
AJ
2303 gen_store_gpr(t0, rd);
2304 tcg_temp_free(t0);
48d38ca5 2305 }
7a387fff
TS
2306 opn = "dadd";
2307 break;
2308 case OPC_DADDU:
460f00c4
AJ
2309 if (rs != 0 && rt != 0) {
2310 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2311 } else if (rs == 0 && rt != 0) {
2312 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2313 } else if (rs != 0 && rt == 0) {
2314 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2315 } else {
2316 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2317 }
7a387fff
TS
2318 opn = "daddu";
2319 break;
2320 case OPC_DSUB:
48d38ca5 2321 {
460f00c4
AJ
2322 TCGv t0 = tcg_temp_local_new();
2323 TCGv t1 = tcg_temp_new();
2324 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2325 int l1 = gen_new_label();
2326
460f00c4
AJ
2327 gen_load_gpr(t1, rs);
2328 gen_load_gpr(t2, rt);
2329 tcg_gen_sub_tl(t0, t1, t2);
2330 tcg_gen_xor_tl(t2, t1, t2);
2331 tcg_gen_xor_tl(t1, t0, t1);
2332 tcg_gen_and_tl(t1, t1, t2);
2333 tcg_temp_free(t2);
2334 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2335 tcg_temp_free(t1);
31e3104f 2336 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2337 generate_exception(ctx, EXCP_OVERFLOW);
2338 gen_set_label(l1);
460f00c4
AJ
2339 gen_store_gpr(t0, rd);
2340 tcg_temp_free(t0);
48d38ca5 2341 }
7a387fff
TS
2342 opn = "dsub";
2343 break;
2344 case OPC_DSUBU:
460f00c4
AJ
2345 if (rs != 0 && rt != 0) {
2346 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2347 } else if (rs == 0 && rt != 0) {
2348 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2349 } else if (rs != 0 && rt == 0) {
2350 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2351 } else {
2352 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2353 }
7a387fff
TS
2354 opn = "dsubu";
2355 break;
2356#endif
460f00c4
AJ
2357 case OPC_MUL:
2358 if (likely(rs != 0 && rt != 0)) {
2359 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2360 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2361 } else {
2362 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2363 }
2364 opn = "mul";
6af0bf9c 2365 break;
460f00c4 2366 }
2abf314d 2367 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2368 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2369}
2370
2371/* Conditional move */
d75c135e 2372static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2373 int rd, int rs, int rt)
460f00c4
AJ
2374{
2375 const char *opn = "cond move";
acf12465 2376 TCGv t0, t1, t2;
460f00c4
AJ
2377
2378 if (rd == 0) {
acf12465 2379 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2380 MIPS_DEBUG("NOP");
2381 return;
2382 }
2383
acf12465
AJ
2384 t0 = tcg_temp_new();
2385 gen_load_gpr(t0, rt);
2386 t1 = tcg_const_tl(0);
2387 t2 = tcg_temp_new();
2388 gen_load_gpr(t2, rs);
460f00c4
AJ
2389 switch (opc) {
2390 case OPC_MOVN:
acf12465 2391 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2392 opn = "movn";
6af0bf9c 2393 break;
460f00c4 2394 case OPC_MOVZ:
acf12465 2395 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2396 opn = "movz";
2397 break;
2398 }
acf12465
AJ
2399 tcg_temp_free(t2);
2400 tcg_temp_free(t1);
2401 tcg_temp_free(t0);
460f00c4 2402
2abf314d 2403 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2404 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2405}
2406
2407/* Logic */
d75c135e 2408static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2409 int rd, int rs, int rt)
460f00c4
AJ
2410{
2411 const char *opn = "logic";
2412
2413 if (rd == 0) {
2414 /* If no destination, treat it as a NOP. */
2415 MIPS_DEBUG("NOP");
2416 return;
2417 }
2418
2419 switch (opc) {
6af0bf9c 2420 case OPC_AND:
460f00c4
AJ
2421 if (likely(rs != 0 && rt != 0)) {
2422 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2423 } else {
2424 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2425 }
6af0bf9c
FB
2426 opn = "and";
2427 break;
2428 case OPC_NOR:
460f00c4
AJ
2429 if (rs != 0 && rt != 0) {
2430 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2431 } else if (rs == 0 && rt != 0) {
2432 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2433 } else if (rs != 0 && rt == 0) {
2434 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2435 } else {
2436 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2437 }
6af0bf9c
FB
2438 opn = "nor";
2439 break;
2440 case OPC_OR:
460f00c4
AJ
2441 if (likely(rs != 0 && rt != 0)) {
2442 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2443 } else if (rs == 0 && rt != 0) {
2444 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2445 } else if (rs != 0 && rt == 0) {
2446 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2447 } else {
2448 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2449 }
6af0bf9c
FB
2450 opn = "or";
2451 break;
2452 case OPC_XOR:
460f00c4
AJ
2453 if (likely(rs != 0 && rt != 0)) {
2454 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2455 } else if (rs == 0 && rt != 0) {
2456 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2457 } else if (rs != 0 && rt == 0) {
2458 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2459 } else {
2460 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2461 }
6af0bf9c
FB
2462 opn = "xor";
2463 break;
460f00c4 2464 }
2abf314d 2465 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2466 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2467}
2468
2469/* Set on lower than */
d75c135e 2470static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2471 int rd, int rs, int rt)
460f00c4
AJ
2472{
2473 const char *opn = "slt";
2474 TCGv t0, t1;
2475
2476 if (rd == 0) {
2477 /* If no destination, treat it as a NOP. */
2478 MIPS_DEBUG("NOP");
2479 return;
2480 }
2481
2482 t0 = tcg_temp_new();
2483 t1 = tcg_temp_new();
2484 gen_load_gpr(t0, rs);
2485 gen_load_gpr(t1, rt);
2486 switch (opc) {
2487 case OPC_SLT:
e68dd28f 2488 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2489 opn = "slt";
6af0bf9c 2490 break;
460f00c4 2491 case OPC_SLTU:
e68dd28f 2492 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2493 opn = "sltu";
2494 break;
2495 }
2abf314d 2496 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2497 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2498 tcg_temp_free(t0);
2499 tcg_temp_free(t1);
2500}
20c4c97c 2501
460f00c4 2502/* Shifts */
d75c135e
AJ
2503static void gen_shift(DisasContext *ctx, uint32_t opc,
2504 int rd, int rs, int rt)
460f00c4
AJ
2505{
2506 const char *opn = "shifts";
2507 TCGv t0, t1;
20c4c97c 2508
460f00c4
AJ
2509 if (rd == 0) {
2510 /* If no destination, treat it as a NOP.
2511 For add & sub, we must generate the overflow exception when needed. */
2512 MIPS_DEBUG("NOP");
2513 return;
2514 }
2515
2516 t0 = tcg_temp_new();
2517 t1 = tcg_temp_new();
2518 gen_load_gpr(t0, rs);
2519 gen_load_gpr(t1, rt);
2520 switch (opc) {
6af0bf9c 2521 case OPC_SLLV:
78723684
TS
2522 tcg_gen_andi_tl(t0, t0, 0x1f);
2523 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2524 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2525 opn = "sllv";
2526 break;
2527 case OPC_SRAV:
78723684 2528 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2529 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2530 opn = "srav";
2531 break;
2532 case OPC_SRLV:
ea63e2c3
NF
2533 tcg_gen_ext32u_tl(t1, t1);
2534 tcg_gen_andi_tl(t0, t0, 0x1f);
2535 tcg_gen_shr_tl(t0, t1, t0);
2536 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2537 opn = "srlv";
2538 break;
2539 case OPC_ROTRV:
2540 {
2541 TCGv_i32 t2 = tcg_temp_new_i32();
2542 TCGv_i32 t3 = tcg_temp_new_i32();
2543
2544 tcg_gen_trunc_tl_i32(t2, t0);
2545 tcg_gen_trunc_tl_i32(t3, t1);
2546 tcg_gen_andi_i32(t2, t2, 0x1f);
2547 tcg_gen_rotr_i32(t2, t3, t2);
2548 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2549 tcg_temp_free_i32(t2);
2550 tcg_temp_free_i32(t3);
2551 opn = "rotrv";
5a63bcb2 2552 }
7a387fff 2553 break;
d26bc211 2554#if defined(TARGET_MIPS64)
7a387fff 2555 case OPC_DSLLV:
78723684 2556 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2557 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2558 opn = "dsllv";
2559 break;
2560 case OPC_DSRAV:
78723684 2561 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2562 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2563 opn = "dsrav";
2564 break;
2565 case OPC_DSRLV:
ea63e2c3
NF
2566 tcg_gen_andi_tl(t0, t0, 0x3f);
2567 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2568 opn = "dsrlv";
2569 break;
2570 case OPC_DROTRV:
2571 tcg_gen_andi_tl(t0, t0, 0x3f);
2572 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2573 opn = "drotrv";
6af0bf9c 2574 break;
7a387fff 2575#endif
6af0bf9c 2576 }
2abf314d 2577 (void)opn; /* avoid a compiler warning */
6af0bf9c 2578 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2579 tcg_temp_free(t0);
2580 tcg_temp_free(t1);
6af0bf9c
FB
2581}
2582
2583/* Arithmetic on HI/LO registers */
7a387fff 2584static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
6af0bf9c 2585{
923617a3 2586 const char *opn = "hilo";
4133498f 2587 unsigned int acc;
6af0bf9c
FB
2588
2589 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2590 /* Treat as NOP. */
6af0bf9c 2591 MIPS_DEBUG("NOP");
a1f6684d 2592 return;
6af0bf9c 2593 }
4133498f
JL
2594
2595 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2596 acc = ((ctx->opcode) >> 21) & 0x03;
2597 } else {
2598 acc = ((ctx->opcode) >> 11) & 0x03;
2599 }
2600
2601 if (acc != 0) {
2602 check_dsp(ctx);
2603 }
2604
6af0bf9c
FB
2605 switch (opc) {
2606 case OPC_MFHI:
4133498f
JL
2607#if defined(TARGET_MIPS64)
2608 if (acc != 0) {
2609 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2610 } else
2611#endif
2612 {
2613 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2614 }
6af0bf9c
FB
2615 opn = "mfhi";
2616 break;
2617 case OPC_MFLO:
4133498f
JL
2618#if defined(TARGET_MIPS64)
2619 if (acc != 0) {
2620 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2621 } else
2622#endif
2623 {
2624 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2625 }
6af0bf9c
FB
2626 opn = "mflo";
2627 break;
2628 case OPC_MTHI:
4133498f
JL
2629 if (reg != 0) {
2630#if defined(TARGET_MIPS64)
2631 if (acc != 0) {
2632 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2633 } else
2634#endif
2635 {
2636 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2637 }
2638 } else {
2639 tcg_gen_movi_tl(cpu_HI[acc], 0);
2640 }
6af0bf9c
FB
2641 opn = "mthi";
2642 break;
2643 case OPC_MTLO:
4133498f
JL
2644 if (reg != 0) {
2645#if defined(TARGET_MIPS64)
2646 if (acc != 0) {
2647 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2648 } else
2649#endif
2650 {
2651 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2652 }
2653 } else {
2654 tcg_gen_movi_tl(cpu_LO[acc], 0);
2655 }
6af0bf9c
FB
2656 opn = "mtlo";
2657 break;
6af0bf9c 2658 }
2abf314d 2659 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2660 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2661}
2662
7a387fff 2663static void gen_muldiv (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2664 int rs, int rt)
2665{
923617a3 2666 const char *opn = "mul/div";
d45f89f4 2667 TCGv t0, t1;
4133498f 2668 unsigned int acc;
d45f89f4 2669
51127181
AJ
2670 t0 = tcg_temp_new();
2671 t1 = tcg_temp_new();
6af0bf9c 2672
78723684
TS
2673 gen_load_gpr(t0, rs);
2674 gen_load_gpr(t1, rt);
51127181 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);
d45f89f4
AJ
2690 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2691 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2692 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2693 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
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);
d45f89f4
AJ
2706 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2707 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2708 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2709 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
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 {
d45f89f4
AJ
2717 TCGv_i64 t2 = tcg_temp_new_i64();
2718 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2719 acc = ((ctx->opcode) >> 11) & 0x03;
2720 if (acc != 0) {
2721 check_dsp(ctx);
2722 }
d45f89f4
AJ
2723
2724 tcg_gen_ext_tl_i64(t2, t0);
2725 tcg_gen_ext_tl_i64(t3, t1);
2726 tcg_gen_mul_i64(t2, t2, t3);
2727 tcg_temp_free_i64(t3);
2728 tcg_gen_trunc_i64_tl(t0, t2);
2729 tcg_gen_shri_i64(t2, t2, 32);
2730 tcg_gen_trunc_i64_tl(t1, t2);
2731 tcg_temp_free_i64(t2);
4133498f
JL
2732 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2733 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2734 }
6af0bf9c
FB
2735 opn = "mult";
2736 break;
2737 case OPC_MULTU:
214c465f 2738 {
d45f89f4
AJ
2739 TCGv_i64 t2 = tcg_temp_new_i64();
2740 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2741 acc = ((ctx->opcode) >> 11) & 0x03;
2742 if (acc != 0) {
2743 check_dsp(ctx);
2744 }
214c465f 2745
78723684
TS
2746 tcg_gen_ext32u_tl(t0, t0);
2747 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2748 tcg_gen_extu_tl_i64(t2, t0);
2749 tcg_gen_extu_tl_i64(t3, t1);
2750 tcg_gen_mul_i64(t2, t2, t3);
2751 tcg_temp_free_i64(t3);
2752 tcg_gen_trunc_i64_tl(t0, t2);
2753 tcg_gen_shri_i64(t2, t2, 32);
2754 tcg_gen_trunc_i64_tl(t1, t2);
2755 tcg_temp_free_i64(t2);
4133498f
JL
2756 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2757 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2758 }
6af0bf9c
FB
2759 opn = "multu";
2760 break;
d26bc211 2761#if defined(TARGET_MIPS64)
7a387fff 2762 case OPC_DDIV:
48d38ca5 2763 {
51127181
AJ
2764 TCGv t2 = tcg_temp_new();
2765 TCGv t3 = tcg_temp_new();
2766 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2767 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2768 tcg_gen_and_tl(t2, t2, t3);
2769 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2770 tcg_gen_or_tl(t2, t2, t3);
2771 tcg_gen_movi_tl(t3, 0);
2772 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2773 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2774 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2775 tcg_temp_free(t3);
2776 tcg_temp_free(t2);
48d38ca5 2777 }
7a387fff
TS
2778 opn = "ddiv";
2779 break;
2780 case OPC_DDIVU:
48d38ca5 2781 {
51127181
AJ
2782 TCGv t2 = tcg_const_tl(0);
2783 TCGv t3 = tcg_const_tl(1);
2784 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
b10fa3c9
AJ
2785 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2786 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
51127181
AJ
2787 tcg_temp_free(t3);
2788 tcg_temp_free(t2);
48d38ca5 2789 }
7a387fff
TS
2790 opn = "ddivu";
2791 break;
2792 case OPC_DMULT:
895c2d04 2793 gen_helper_dmult(cpu_env, t0, t1);
7a387fff
TS
2794 opn = "dmult";
2795 break;
2796 case OPC_DMULTU:
895c2d04 2797 gen_helper_dmultu(cpu_env, t0, t1);
7a387fff
TS
2798 opn = "dmultu";
2799 break;
2800#endif
6af0bf9c 2801 case OPC_MADD:
214c465f 2802 {
d45f89f4
AJ
2803 TCGv_i64 t2 = tcg_temp_new_i64();
2804 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2805 acc = ((ctx->opcode) >> 11) & 0x03;
2806 if (acc != 0) {
2807 check_dsp(ctx);
2808 }
d45f89f4
AJ
2809
2810 tcg_gen_ext_tl_i64(t2, t0);
2811 tcg_gen_ext_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 = "madd";
2824 break;
2825 case OPC_MADDU:
4133498f 2826 {
d45f89f4
AJ
2827 TCGv_i64 t2 = tcg_temp_new_i64();
2828 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2829 acc = ((ctx->opcode) >> 11) & 0x03;
2830 if (acc != 0) {
2831 check_dsp(ctx);
2832 }
214c465f 2833
78723684
TS
2834 tcg_gen_ext32u_tl(t0, t0);
2835 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2836 tcg_gen_extu_tl_i64(t2, t0);
2837 tcg_gen_extu_tl_i64(t3, t1);
2838 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2839 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2840 tcg_gen_add_i64(t2, t2, t3);
2841 tcg_temp_free_i64(t3);
2842 tcg_gen_trunc_i64_tl(t0, t2);
2843 tcg_gen_shri_i64(t2, t2, 32);
2844 tcg_gen_trunc_i64_tl(t1, t2);
2845 tcg_temp_free_i64(t2);
4133498f
JL
2846 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2847 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2848 }
6af0bf9c
FB
2849 opn = "maddu";
2850 break;
2851 case OPC_MSUB:
214c465f 2852 {
d45f89f4
AJ
2853 TCGv_i64 t2 = tcg_temp_new_i64();
2854 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2855 acc = ((ctx->opcode) >> 11) & 0x03;
2856 if (acc != 0) {
2857 check_dsp(ctx);
2858 }
d45f89f4
AJ
2859
2860 tcg_gen_ext_tl_i64(t2, t0);
2861 tcg_gen_ext_tl_i64(t3, t1);
2862 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2863 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2864 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2865 tcg_temp_free_i64(t3);
2866 tcg_gen_trunc_i64_tl(t0, t2);
2867 tcg_gen_shri_i64(t2, t2, 32);
2868 tcg_gen_trunc_i64_tl(t1, t2);
2869 tcg_temp_free_i64(t2);
4133498f
JL
2870 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2871 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2872 }
6af0bf9c
FB
2873 opn = "msub";
2874 break;
2875 case OPC_MSUBU:
214c465f 2876 {
d45f89f4
AJ
2877 TCGv_i64 t2 = tcg_temp_new_i64();
2878 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2879 acc = ((ctx->opcode) >> 11) & 0x03;
2880 if (acc != 0) {
2881 check_dsp(ctx);
2882 }
214c465f 2883
78723684
TS
2884 tcg_gen_ext32u_tl(t0, t0);
2885 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2886 tcg_gen_extu_tl_i64(t2, t0);
2887 tcg_gen_extu_tl_i64(t3, t1);
2888 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2889 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2890 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2891 tcg_temp_free_i64(t3);
2892 tcg_gen_trunc_i64_tl(t0, t2);
2893 tcg_gen_shri_i64(t2, t2, 32);
2894 tcg_gen_trunc_i64_tl(t1, t2);
2895 tcg_temp_free_i64(t2);
4133498f
JL
2896 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2897 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2898 }
6af0bf9c
FB
2899 opn = "msubu";
2900 break;
2901 default:
923617a3 2902 MIPS_INVAL(opn);
6af0bf9c 2903 generate_exception(ctx, EXCP_RI);
78723684 2904 goto out;
6af0bf9c 2905 }
2abf314d 2906 (void)opn; /* avoid a compiler warning */
6af0bf9c 2907 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2908 out:
2909 tcg_temp_free(t0);
2910 tcg_temp_free(t1);
6af0bf9c
FB
2911}
2912
e9c71dd1
TS
2913static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2914 int rd, int rs, int rt)
2915{
2916 const char *opn = "mul vr54xx";
f157bfe1
AJ
2917 TCGv t0 = tcg_temp_new();
2918 TCGv t1 = tcg_temp_new();
e9c71dd1 2919
6c5c1e20
TS
2920 gen_load_gpr(t0, rs);
2921 gen_load_gpr(t1, rt);
e9c71dd1
TS
2922
2923 switch (opc) {
2924 case OPC_VR54XX_MULS:
895c2d04 2925 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2926 opn = "muls";
6958549d 2927 break;
e9c71dd1 2928 case OPC_VR54XX_MULSU:
895c2d04 2929 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2930 opn = "mulsu";
6958549d 2931 break;
e9c71dd1 2932 case OPC_VR54XX_MACC:
895c2d04 2933 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2934 opn = "macc";
6958549d 2935 break;
e9c71dd1 2936 case OPC_VR54XX_MACCU:
895c2d04 2937 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2938 opn = "maccu";
6958549d 2939 break;
e9c71dd1 2940 case OPC_VR54XX_MSAC:
895c2d04 2941 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2942 opn = "msac";
6958549d 2943 break;
e9c71dd1 2944 case OPC_VR54XX_MSACU:
895c2d04 2945 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2946 opn = "msacu";
6958549d 2947 break;
e9c71dd1 2948 case OPC_VR54XX_MULHI:
895c2d04 2949 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2950 opn = "mulhi";
6958549d 2951 break;
e9c71dd1 2952 case OPC_VR54XX_MULHIU:
895c2d04 2953 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2954 opn = "mulhiu";
6958549d 2955 break;
e9c71dd1 2956 case OPC_VR54XX_MULSHI:
895c2d04 2957 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2958 opn = "mulshi";
6958549d 2959 break;
e9c71dd1 2960 case OPC_VR54XX_MULSHIU:
895c2d04 2961 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2962 opn = "mulshiu";
6958549d 2963 break;
e9c71dd1 2964 case OPC_VR54XX_MACCHI:
895c2d04 2965 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2966 opn = "macchi";
6958549d 2967 break;
e9c71dd1 2968 case OPC_VR54XX_MACCHIU:
895c2d04 2969 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2970 opn = "macchiu";
6958549d 2971 break;
e9c71dd1 2972 case OPC_VR54XX_MSACHI:
895c2d04 2973 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2974 opn = "msachi";
6958549d 2975 break;
e9c71dd1 2976 case OPC_VR54XX_MSACHIU:
895c2d04 2977 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2978 opn = "msachiu";
6958549d 2979 break;
e9c71dd1
TS
2980 default:
2981 MIPS_INVAL("mul vr54xx");
2982 generate_exception(ctx, EXCP_RI);
6c5c1e20 2983 goto out;
e9c71dd1 2984 }
6c5c1e20 2985 gen_store_gpr(t0, rd);
2abf314d 2986 (void)opn; /* avoid a compiler warning */
e9c71dd1 2987 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2988
2989 out:
2990 tcg_temp_free(t0);
2991 tcg_temp_free(t1);
e9c71dd1
TS
2992}
2993
7a387fff 2994static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2995 int rd, int rs)
2996{
923617a3 2997 const char *opn = "CLx";
20e1fb52 2998 TCGv t0;
6c5c1e20 2999
6af0bf9c 3000 if (rd == 0) {
ead9360e 3001 /* Treat as NOP. */
6af0bf9c 3002 MIPS_DEBUG("NOP");
20e1fb52 3003 return;
6af0bf9c 3004 }
20e1fb52 3005 t0 = tcg_temp_new();
6c5c1e20 3006 gen_load_gpr(t0, rs);
6af0bf9c
FB
3007 switch (opc) {
3008 case OPC_CLO:
20e1fb52 3009 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3010 opn = "clo";
3011 break;
3012 case OPC_CLZ:
20e1fb52 3013 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3014 opn = "clz";
3015 break;
d26bc211 3016#if defined(TARGET_MIPS64)
7a387fff 3017 case OPC_DCLO:
20e1fb52 3018 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3019 opn = "dclo";
3020 break;
3021 case OPC_DCLZ:
20e1fb52 3022 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3023 opn = "dclz";
3024 break;
3025#endif
6af0bf9c 3026 }
2abf314d 3027 (void)opn; /* avoid a compiler warning */
6af0bf9c 3028 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3029 tcg_temp_free(t0);
6af0bf9c
FB
3030}
3031
161f85e6 3032/* Godson integer instructions */
bd277fa1
RH
3033static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3034 int rd, int rs, int rt)
161f85e6
AJ
3035{
3036 const char *opn = "loongson";
3037 TCGv t0, t1;
3038
3039 if (rd == 0) {
3040 /* Treat as NOP. */
3041 MIPS_DEBUG("NOP");
3042 return;
3043 }
3044
3045 switch (opc) {
3046 case OPC_MULT_G_2E:
3047 case OPC_MULT_G_2F:
3048 case OPC_MULTU_G_2E:
3049 case OPC_MULTU_G_2F:
3050#if defined(TARGET_MIPS64)
3051 case OPC_DMULT_G_2E:
3052 case OPC_DMULT_G_2F:
3053 case OPC_DMULTU_G_2E:
3054 case OPC_DMULTU_G_2F:
3055#endif
3056 t0 = tcg_temp_new();
3057 t1 = tcg_temp_new();
3058 break;
3059 default:
3060 t0 = tcg_temp_local_new();
3061 t1 = tcg_temp_local_new();
3062 break;
3063 }
3064
3065 gen_load_gpr(t0, rs);
3066 gen_load_gpr(t1, rt);
3067
3068 switch (opc) {
3069 case OPC_MULT_G_2E:
3070 case OPC_MULT_G_2F:
3071 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3072 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3073 opn = "mult.g";
3074 break;
3075 case OPC_MULTU_G_2E:
3076 case OPC_MULTU_G_2F:
3077 tcg_gen_ext32u_tl(t0, t0);
3078 tcg_gen_ext32u_tl(t1, t1);
3079 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3080 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3081 opn = "multu.g";
3082 break;
3083 case OPC_DIV_G_2E:
3084 case OPC_DIV_G_2F:
3085 {
3086 int l1 = gen_new_label();
3087 int l2 = gen_new_label();
3088 int l3 = gen_new_label();
3089 tcg_gen_ext32s_tl(t0, t0);
3090 tcg_gen_ext32s_tl(t1, t1);
3091 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3092 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3093 tcg_gen_br(l3);
3094 gen_set_label(l1);
3095 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3097 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3098 tcg_gen_br(l3);
3099 gen_set_label(l2);
3100 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3101 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3102 gen_set_label(l3);
3103 }
3104 opn = "div.g";
3105 break;
3106 case OPC_DIVU_G_2E:
3107 case OPC_DIVU_G_2F:
3108 {
3109 int l1 = gen_new_label();
3110 int l2 = gen_new_label();
3111 tcg_gen_ext32u_tl(t0, t0);
3112 tcg_gen_ext32u_tl(t1, t1);
3113 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3114 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3115 tcg_gen_br(l2);
3116 gen_set_label(l1);
3117 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3118 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3119 gen_set_label(l2);
3120 }
3121 opn = "divu.g";
3122 break;
3123 case OPC_MOD_G_2E:
3124 case OPC_MOD_G_2F:
3125 {
3126 int l1 = gen_new_label();
3127 int l2 = gen_new_label();
3128 int l3 = gen_new_label();
3129 tcg_gen_ext32u_tl(t0, t0);
3130 tcg_gen_ext32u_tl(t1, t1);
3131 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3132 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3133 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3134 gen_set_label(l1);
3135 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3136 tcg_gen_br(l3);
3137 gen_set_label(l2);
3138 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3139 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3140 gen_set_label(l3);
3141 }
3142 opn = "mod.g";
3143 break;
3144 case OPC_MODU_G_2E:
3145 case OPC_MODU_G_2F:
3146 {
3147 int l1 = gen_new_label();
3148 int l2 = gen_new_label();
3149 tcg_gen_ext32u_tl(t0, t0);
3150 tcg_gen_ext32u_tl(t1, t1);
3151 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3152 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3153 tcg_gen_br(l2);
3154 gen_set_label(l1);
3155 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3156 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3157 gen_set_label(l2);
3158 }
3159 opn = "modu.g";
3160 break;
3161#if defined(TARGET_MIPS64)
3162 case OPC_DMULT_G_2E:
3163 case OPC_DMULT_G_2F:
3164 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3165 opn = "dmult.g";
3166 break;
3167 case OPC_DMULTU_G_2E:
3168 case OPC_DMULTU_G_2F:
3169 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3170 opn = "dmultu.g";
3171 break;
3172 case OPC_DDIV_G_2E:
3173 case OPC_DDIV_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_NE, t1, 0, l1);
3179 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3180 tcg_gen_br(l3);
3181 gen_set_label(l1);
3182 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3183 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3184 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3185 tcg_gen_br(l3);
3186 gen_set_label(l2);
3187 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3188 gen_set_label(l3);
3189 }
3190 opn = "ddiv.g";
3191 break;
3192 case OPC_DDIVU_G_2E:
3193 case OPC_DDIVU_G_2F:
3194 {
3195 int l1 = gen_new_label();
3196 int l2 = gen_new_label();
3197 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3198 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3199 tcg_gen_br(l2);
3200 gen_set_label(l1);
3201 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3202 gen_set_label(l2);
3203 }
3204 opn = "ddivu.g";
3205 break;
3206 case OPC_DMOD_G_2E:
3207 case OPC_DMOD_G_2F:
3208 {
3209 int l1 = gen_new_label();
3210 int l2 = gen_new_label();
3211 int l3 = gen_new_label();
3212 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3213 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3214 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3215 gen_set_label(l1);
3216 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3217 tcg_gen_br(l3);
3218 gen_set_label(l2);
3219 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3220 gen_set_label(l3);
3221 }
3222 opn = "dmod.g";
3223 break;
3224 case OPC_DMODU_G_2E:
3225 case OPC_DMODU_G_2F:
3226 {
3227 int l1 = gen_new_label();
3228 int l2 = gen_new_label();
3229 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3230 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3231 tcg_gen_br(l2);
3232 gen_set_label(l1);
3233 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3234 gen_set_label(l2);
3235 }
3236 opn = "dmodu.g";
3237 break;
3238#endif
3239 }
3240
2abf314d 3241 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3242 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3243 tcg_temp_free(t0);
3244 tcg_temp_free(t1);
3245}
3246
bd277fa1
RH
3247/* Loongson multimedia instructions */
3248static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3249{
3250 const char *opn = "loongson_cp2";
3251 uint32_t opc, shift_max;
3252 TCGv_i64 t0, t1;
3253
3254 opc = MASK_LMI(ctx->opcode);
3255 switch (opc) {
3256 case OPC_ADD_CP2:
3257 case OPC_SUB_CP2:
3258 case OPC_DADD_CP2:
3259 case OPC_DSUB_CP2:
3260 t0 = tcg_temp_local_new_i64();
3261 t1 = tcg_temp_local_new_i64();
3262 break;
3263 default:
3264 t0 = tcg_temp_new_i64();
3265 t1 = tcg_temp_new_i64();
3266 break;
3267 }
3268
3269 gen_load_fpr64(ctx, t0, rs);
3270 gen_load_fpr64(ctx, t1, rt);
3271
3272#define LMI_HELPER(UP, LO) \
3273 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3274#define LMI_HELPER_1(UP, LO) \
3275 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3276#define LMI_DIRECT(UP, LO, OP) \
3277 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3278
3279 switch (opc) {
3280 LMI_HELPER(PADDSH, paddsh);
3281 LMI_HELPER(PADDUSH, paddush);
3282 LMI_HELPER(PADDH, paddh);
3283 LMI_HELPER(PADDW, paddw);
3284 LMI_HELPER(PADDSB, paddsb);
3285 LMI_HELPER(PADDUSB, paddusb);
3286 LMI_HELPER(PADDB, paddb);
3287
3288 LMI_HELPER(PSUBSH, psubsh);
3289 LMI_HELPER(PSUBUSH, psubush);
3290 LMI_HELPER(PSUBH, psubh);
3291 LMI_HELPER(PSUBW, psubw);
3292 LMI_HELPER(PSUBSB, psubsb);
3293 LMI_HELPER(PSUBUSB, psubusb);
3294 LMI_HELPER(PSUBB, psubb);
3295
3296 LMI_HELPER(PSHUFH, pshufh);
3297 LMI_HELPER(PACKSSWH, packsswh);
3298 LMI_HELPER(PACKSSHB, packsshb);
3299 LMI_HELPER(PACKUSHB, packushb);
3300
3301 LMI_HELPER(PUNPCKLHW, punpcklhw);
3302 LMI_HELPER(PUNPCKHHW, punpckhhw);
3303 LMI_HELPER(PUNPCKLBH, punpcklbh);
3304 LMI_HELPER(PUNPCKHBH, punpckhbh);
3305 LMI_HELPER(PUNPCKLWD, punpcklwd);
3306 LMI_HELPER(PUNPCKHWD, punpckhwd);
3307
3308 LMI_HELPER(PAVGH, pavgh);
3309 LMI_HELPER(PAVGB, pavgb);
3310 LMI_HELPER(PMAXSH, pmaxsh);
3311 LMI_HELPER(PMINSH, pminsh);
3312 LMI_HELPER(PMAXUB, pmaxub);
3313 LMI_HELPER(PMINUB, pminub);
3314
3315 LMI_HELPER(PCMPEQW, pcmpeqw);
3316 LMI_HELPER(PCMPGTW, pcmpgtw);
3317 LMI_HELPER(PCMPEQH, pcmpeqh);
3318 LMI_HELPER(PCMPGTH, pcmpgth);
3319 LMI_HELPER(PCMPEQB, pcmpeqb);
3320 LMI_HELPER(PCMPGTB, pcmpgtb);
3321
3322 LMI_HELPER(PSLLW, psllw);
3323 LMI_HELPER(PSLLH, psllh);
3324 LMI_HELPER(PSRLW, psrlw);
3325 LMI_HELPER(PSRLH, psrlh);
3326 LMI_HELPER(PSRAW, psraw);
3327 LMI_HELPER(PSRAH, psrah);
3328
3329 LMI_HELPER(PMULLH, pmullh);
3330 LMI_HELPER(PMULHH, pmulhh);
3331 LMI_HELPER(PMULHUH, pmulhuh);
3332 LMI_HELPER(PMADDHW, pmaddhw);
3333
3334 LMI_HELPER(PASUBUB, pasubub);
3335 LMI_HELPER_1(BIADD, biadd);
3336 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3337
3338 LMI_DIRECT(PADDD, paddd, add);
3339 LMI_DIRECT(PSUBD, psubd, sub);
3340 LMI_DIRECT(XOR_CP2, xor, xor);
3341 LMI_DIRECT(NOR_CP2, nor, nor);
3342 LMI_DIRECT(AND_CP2, and, and);
3343 LMI_DIRECT(PANDN, pandn, andc);
3344 LMI_DIRECT(OR, or, or);
3345
3346 case OPC_PINSRH_0:
3347 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3348 opn = "pinsrh_0";
3349 break;
3350 case OPC_PINSRH_1:
3351 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3352 opn = "pinsrh_1";
3353 break;
3354 case OPC_PINSRH_2:
3355 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3356 opn = "pinsrh_2";
3357 break;
3358 case OPC_PINSRH_3:
3359 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3360 opn = "pinsrh_3";
3361 break;
3362
3363 case OPC_PEXTRH:
3364 tcg_gen_andi_i64(t1, t1, 3);
3365 tcg_gen_shli_i64(t1, t1, 4);
3366 tcg_gen_shr_i64(t0, t0, t1);
3367 tcg_gen_ext16u_i64(t0, t0);
3368 opn = "pextrh";
3369 break;
3370
3371 case OPC_ADDU_CP2:
3372 tcg_gen_add_i64(t0, t0, t1);
3373 tcg_gen_ext32s_i64(t0, t0);
3374 opn = "addu";
3375 break;
3376 case OPC_SUBU_CP2:
3377 tcg_gen_sub_i64(t0, t0, t1);
3378 tcg_gen_ext32s_i64(t0, t0);
3379 opn = "addu";
3380 break;
3381
3382 case OPC_SLL_CP2:
3383 opn = "sll";
3384 shift_max = 32;
3385 goto do_shift;
3386 case OPC_SRL_CP2:
3387 opn = "srl";
3388 shift_max = 32;
3389 goto do_shift;
3390 case OPC_SRA_CP2:
3391 opn = "sra";
3392 shift_max = 32;
3393 goto do_shift;
3394 case OPC_DSLL_CP2:
3395 opn = "dsll";
3396 shift_max = 64;
3397 goto do_shift;
3398 case OPC_DSRL_CP2:
3399 opn = "dsrl";
3400 shift_max = 64;
3401 goto do_shift;
3402 case OPC_DSRA_CP2:
3403 opn = "dsra";
3404 shift_max = 64;
3405 goto do_shift;
3406 do_shift:
3407 /* Make sure shift count isn't TCG undefined behaviour. */
3408 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3409
3410 switch (opc) {
3411 case OPC_SLL_CP2:
3412 case OPC_DSLL_CP2:
3413 tcg_gen_shl_i64(t0, t0, t1);
3414 break;
3415 case OPC_SRA_CP2:
3416 case OPC_DSRA_CP2:
3417 /* Since SRA is UndefinedResult without sign-extended inputs,
3418 we can treat SRA and DSRA the same. */
3419 tcg_gen_sar_i64(t0, t0, t1);
3420 break;
3421 case OPC_SRL_CP2:
3422 /* We want to shift in zeros for SRL; zero-extend first. */
3423 tcg_gen_ext32u_i64(t0, t0);
3424 /* FALLTHRU */
3425 case OPC_DSRL_CP2:
3426 tcg_gen_shr_i64(t0, t0, t1);
3427 break;
3428 }
3429
3430 if (shift_max == 32) {
3431 tcg_gen_ext32s_i64(t0, t0);
3432 }
3433
3434 /* Shifts larger than MAX produce zero. */
3435 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3436 tcg_gen_neg_i64(t1, t1);
3437 tcg_gen_and_i64(t0, t0, t1);
3438 break;
3439
3440 case OPC_ADD_CP2:
3441 case OPC_DADD_CP2:
3442 {
3443 TCGv_i64 t2 = tcg_temp_new_i64();
3444 int lab = gen_new_label();
3445
3446 tcg_gen_mov_i64(t2, t0);
3447 tcg_gen_add_i64(t0, t1, t2);
3448 if (opc == OPC_ADD_CP2) {
3449 tcg_gen_ext32s_i64(t0, t0);
3450 }
3451 tcg_gen_xor_i64(t1, t1, t2);
3452 tcg_gen_xor_i64(t2, t2, t0);
3453 tcg_gen_andc_i64(t1, t2, t1);
3454 tcg_temp_free_i64(t2);
3455 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3456 generate_exception(ctx, EXCP_OVERFLOW);
3457 gen_set_label(lab);
3458
3459 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3460 break;
3461 }
3462
3463 case OPC_SUB_CP2:
3464 case OPC_DSUB_CP2:
3465 {
3466 TCGv_i64 t2 = tcg_temp_new_i64();
3467 int lab = gen_new_label();
3468
3469 tcg_gen_mov_i64(t2, t0);
3470 tcg_gen_sub_i64(t0, t1, t2);
3471 if (opc == OPC_SUB_CP2) {
3472 tcg_gen_ext32s_i64(t0, t0);
3473 }
3474 tcg_gen_xor_i64(t1, t1, t2);
3475 tcg_gen_xor_i64(t2, t2, t0);
3476 tcg_gen_and_i64(t1, t1, t2);
3477 tcg_temp_free_i64(t2);
3478 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3479 generate_exception(ctx, EXCP_OVERFLOW);
3480 gen_set_label(lab);
3481
3482 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3483 break;
3484 }
3485
3486 case OPC_PMULUW:
3487 tcg_gen_ext32u_i64(t0, t0);
3488 tcg_gen_ext32u_i64(t1, t1);
3489 tcg_gen_mul_i64(t0, t0, t1);
3490 opn = "pmuluw";
3491 break;
3492
3493 case OPC_SEQU_CP2:
3494 case OPC_SEQ_CP2:
3495 case OPC_SLTU_CP2:
3496 case OPC_SLT_CP2:
3497 case OPC_SLEU_CP2:
3498 case OPC_SLE_CP2:
3499 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3500 FD field is the CC field? */
3501 default:
3502 MIPS_INVAL(opn);
3503 generate_exception(ctx, EXCP_RI);
3504 return;
3505 }
3506
3507#undef LMI_HELPER
3508#undef LMI_DIRECT
3509
3510 gen_store_fpr64(ctx, t0, rd);
3511
3512 (void)opn; /* avoid a compiler warning */
3513 MIPS_DEBUG("%s %s, %s, %s", opn,
3514 fregnames[rd], fregnames[rs], fregnames[rt]);
3515 tcg_temp_free_i64(t0);
3516 tcg_temp_free_i64(t1);
3517}
3518
6af0bf9c 3519/* Traps */
7a387fff 3520static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3521 int rs, int rt, int16_t imm)
3522{
3523 int cond;
cdc0faa6 3524 TCGv t0 = tcg_temp_new();
1ba74fb8 3525 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3526
3527 cond = 0;
3528 /* Load needed operands */
3529 switch (opc) {
3530 case OPC_TEQ:
3531 case OPC_TGE:
3532 case OPC_TGEU:
3533 case OPC_TLT:
3534 case OPC_TLTU:
3535 case OPC_TNE:
3536 /* Compare two registers */
3537 if (rs != rt) {
be24bb4f
TS
3538 gen_load_gpr(t0, rs);
3539 gen_load_gpr(t1, rt);
6af0bf9c
FB
3540 cond = 1;
3541 }
179e32bb 3542 break;
6af0bf9c
FB
3543 case OPC_TEQI:
3544 case OPC_TGEI:
3545 case OPC_TGEIU:
3546 case OPC_TLTI:
3547 case OPC_TLTIU:
3548 case OPC_TNEI:
3549 /* Compare register to immediate */
3550 if (rs != 0 || imm != 0) {
be24bb4f
TS
3551 gen_load_gpr(t0, rs);
3552 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3553 cond = 1;
3554 }
3555 break;
3556 }
3557 if (cond == 0) {
3558 switch (opc) {
3559 case OPC_TEQ: /* rs == rs */
3560 case OPC_TEQI: /* r0 == 0 */
3561 case OPC_TGE: /* rs >= rs */
3562 case OPC_TGEI: /* r0 >= 0 */
3563 case OPC_TGEU: /* rs >= rs unsigned */
3564 case OPC_TGEIU: /* r0 >= 0 unsigned */
3565 /* Always trap */
cdc0faa6 3566 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3567 break;
3568 case OPC_TLT: /* rs < rs */
3569 case OPC_TLTI: /* r0 < 0 */
3570 case OPC_TLTU: /* rs < rs unsigned */
3571 case OPC_TLTIU: /* r0 < 0 unsigned */
3572 case OPC_TNE: /* rs != rs */
3573 case OPC_TNEI: /* r0 != 0 */
ead9360e 3574 /* Never trap: treat as NOP. */
cdc0faa6 3575 break;
6af0bf9c
FB
3576 }
3577 } else {
cdc0faa6
AJ
3578 int l1 = gen_new_label();
3579
6af0bf9c
FB
3580 switch (opc) {
3581 case OPC_TEQ:
3582 case OPC_TEQI:
cdc0faa6 3583 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3584 break;
3585 case OPC_TGE:
3586 case OPC_TGEI:
cdc0faa6 3587 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3588 break;
3589 case OPC_TGEU:
3590 case OPC_TGEIU:
cdc0faa6 3591 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3592 break;
3593 case OPC_TLT:
3594 case OPC_TLTI:
cdc0faa6 3595 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3596 break;
3597 case OPC_TLTU:
3598 case OPC_TLTIU:
cdc0faa6 3599 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3600 break;
3601 case OPC_TNE:
3602 case OPC_TNEI:
cdc0faa6 3603 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3604 break;
6af0bf9c 3605 }
cdc0faa6 3606 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3607 gen_set_label(l1);
3608 }
be24bb4f
TS
3609 tcg_temp_free(t0);
3610 tcg_temp_free(t1);
6af0bf9c
FB
3611}
3612
356265ae 3613static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3614{
6e256c93
FB
3615 TranslationBlock *tb;
3616 tb = ctx->tb;
7b270ef2
NF
3617 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3618 likely(!ctx->singlestep_enabled)) {
57fec1fe 3619 tcg_gen_goto_tb(n);
9b9e4393 3620 gen_save_pc(dest);
4b4a72e5 3621 tcg_gen_exit_tb((tcg_target_long)tb + n);
6e256c93 3622 } else {
9b9e4393 3623 gen_save_pc(dest);
7b270ef2
NF
3624 if (ctx->singlestep_enabled) {
3625 save_cpu_state(ctx, 0);
895c2d04 3626 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3627 }
57fec1fe 3628 tcg_gen_exit_tb(0);
6e256c93 3629 }
c53be334
FB
3630}
3631
6af0bf9c 3632/* Branches (before delay slot) */
7a387fff 3633static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3634 int insn_bytes,
6af0bf9c
FB
3635 int rs, int rt, int32_t offset)
3636{
d077b6f7 3637 target_ulong btgt = -1;
3ad4bb2d 3638 int blink = 0;
2fdbad25 3639 int bcond_compute = 0;
1ba74fb8
AJ
3640 TCGv t0 = tcg_temp_new();
3641 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3642
3643 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3644#ifdef MIPS_DEBUG_DISAS
d12d51d5 3645 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3646#endif
3ad4bb2d 3647 generate_exception(ctx, EXCP_RI);
6c5c1e20 3648 goto out;
3ad4bb2d 3649 }
6af0bf9c 3650
6af0bf9c
FB
3651 /* Load needed operands */
3652 switch (opc) {
3653 case OPC_BEQ:
3654 case OPC_BEQL:
3655 case OPC_BNE:
3656 case OPC_BNEL:
3657 /* Compare two registers */
3658 if (rs != rt) {
6c5c1e20
TS
3659 gen_load_gpr(t0, rs);
3660 gen_load_gpr(t1, rt);
2fdbad25 3661 bcond_compute = 1;
6af0bf9c 3662 }
7dca4ad0 3663 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3664 break;
3665 case OPC_BGEZ:
3666 case OPC_BGEZAL:
3c824109 3667 case OPC_BGEZALS:
6af0bf9c
FB
3668 case OPC_BGEZALL:
3669 case OPC_BGEZL:
3670 case OPC_BGTZ:
3671 case OPC_BGTZL:
3672 case OPC_BLEZ:
3673 case OPC_BLEZL:
3674 case OPC_BLTZ:
3675 case OPC_BLTZAL:
3c824109 3676 case OPC_BLTZALS:
6af0bf9c
FB
3677 case OPC_BLTZALL:
3678 case OPC_BLTZL:
3679 /* Compare to zero */
3680 if (rs != 0) {
6c5c1e20 3681 gen_load_gpr(t0, rs);
2fdbad25 3682 bcond_compute = 1;
6af0bf9c 3683 }
7dca4ad0 3684 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3685 break;
e45a93e2
JL
3686 case OPC_BPOSGE32:
3687#if defined(TARGET_MIPS64)
3688 case OPC_BPOSGE64:
3689 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3690#else
3691 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3692#endif
3693 bcond_compute = 1;
3694 btgt = ctx->pc + insn_bytes + offset;
3695 break;
6af0bf9c
FB
3696 case OPC_J:
3697 case OPC_JAL:
364d4831 3698 case OPC_JALX:
620e48f6
NF
3699 case OPC_JALS:
3700 case OPC_JALXS:
6af0bf9c 3701 /* Jump to immediate */
7dca4ad0 3702 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3703 break;
3704 case OPC_JR:
3705 case OPC_JALR:
364d4831 3706 case OPC_JALRC:
620e48f6 3707 case OPC_JALRS:
6af0bf9c 3708 /* Jump to register */
7a387fff
TS
3709 if (offset != 0 && offset != 16) {
3710 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3711 others are reserved. */
923617a3 3712 MIPS_INVAL("jump hint");
6af0bf9c 3713 generate_exception(ctx, EXCP_RI);
6c5c1e20 3714 goto out;
6af0bf9c 3715 }
d077b6f7 3716 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3717 break;
3718 default:
3719 MIPS_INVAL("branch/jump");
3720 generate_exception(ctx, EXCP_RI);
6c5c1e20 3721 goto out;
6af0bf9c 3722 }
2fdbad25 3723 if (bcond_compute == 0) {
6af0bf9c
FB
3724 /* No condition to be computed */
3725 switch (opc) {
3726 case OPC_BEQ: /* rx == rx */
3727 case OPC_BEQL: /* rx == rx likely */
3728 case OPC_BGEZ: /* 0 >= 0 */
3729 case OPC_BGEZL: /* 0 >= 0 likely */
3730 case OPC_BLEZ: /* 0 <= 0 */
3731 case OPC_BLEZL: /* 0 <= 0 likely */
3732 /* Always take */
4ad40f36 3733 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3734 MIPS_DEBUG("balways");
3735 break;
3c824109 3736 case OPC_BGEZALS:
6af0bf9c
FB
3737 case OPC_BGEZAL: /* 0 >= 0 */
3738 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3739 ctx->hflags |= (opc == OPC_BGEZALS
3740 ? MIPS_HFLAG_BDS16
3741 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3742 /* Always take and link */
3743 blink = 31;
4ad40f36 3744 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3745 MIPS_DEBUG("balways and link");
3746 break;
3747 case OPC_BNE: /* rx != rx */
3748 case OPC_BGTZ: /* 0 > 0 */
3749 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3750 /* Treat as NOP. */
6af0bf9c 3751 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3752 goto out;
3c824109 3753 case OPC_BLTZALS:
eeef26cd 3754 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3755 ctx->hflags |= (opc == OPC_BLTZALS
3756 ? MIPS_HFLAG_BDS16
3757 : MIPS_HFLAG_BDS32);
3758 /* Handle as an unconditional branch to get correct delay
3759 slot checking. */
3760 blink = 31;
3761 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3762 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3763 MIPS_DEBUG("bnever and link");
3c824109 3764 break;
eeef26cd 3765 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3766 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3767 /* Skip the instruction in the delay slot */
3768 MIPS_DEBUG("bnever, link and skip");
3769 ctx->pc += 4;
6c5c1e20 3770 goto out;
6af0bf9c
FB
3771 case OPC_BNEL: /* rx != rx likely */
3772 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3773 case OPC_BLTZL: /* 0 < 0 likely */
3774 /* Skip the instruction in the delay slot */
3775 MIPS_DEBUG("bnever and skip");
9898128f 3776 ctx->pc += 4;
6c5c1e20 3777 goto out;
6af0bf9c 3778 case OPC_J:
4ad40f36 3779 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3780 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3781 break;
620e48f6 3782 case OPC_JALXS:
364d4831
NF
3783 case OPC_JALX:
3784 ctx->hflags |= MIPS_HFLAG_BX;
3785 /* Fallthrough */
620e48f6 3786 case OPC_JALS:
6af0bf9c
FB
3787 case OPC_JAL:
3788 blink = 31;
4ad40f36 3789 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3790 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3791 ? MIPS_HFLAG_BDS16
3792 : MIPS_HFLAG_BDS32);
d077b6f7 3793 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3794 break;
3795 case OPC_JR:
4ad40f36 3796 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3797 if (insn_bytes == 4)
3798 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3799 MIPS_DEBUG("jr %s", regnames[rs]);
3800 break;
620e48f6 3801 case OPC_JALRS:
6af0bf9c 3802 case OPC_JALR:
364d4831 3803 case OPC_JALRC:
6af0bf9c 3804 blink = rt;
4ad40f36 3805 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3806 ctx->hflags |= (opc == OPC_JALRS
3807 ? MIPS_HFLAG_BDS16
3808 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3809 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3810 break;
3811 default:
3812 MIPS_INVAL("branch/jump");
3813 generate_exception(ctx, EXCP_RI);
6c5c1e20 3814 goto out;
6af0bf9c
FB
3815 }
3816 } else {
3817 switch (opc) {
3818 case OPC_BEQ:
e68dd28f 3819 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3820 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3821 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3822 goto not_likely;
3823 case OPC_BEQL:
e68dd28f 3824 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3825 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3826 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3827 goto likely;
3828 case OPC_BNE:
e68dd28f 3829 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3830 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3831 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3832 goto not_likely;
3833 case OPC_BNEL:
e68dd28f 3834 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3835 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3836 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3837 goto likely;
3838 case OPC_BGEZ:
e68dd28f 3839 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3840 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3841 goto not_likely;
3842 case OPC_BGEZL:
e68dd28f 3843 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3844 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3845 goto likely;
3c824109 3846 case OPC_BGEZALS:
6af0bf9c 3847 case OPC_BGEZAL:
3c824109
NF
3848 ctx->hflags |= (opc == OPC_BGEZALS
3849 ? MIPS_HFLAG_BDS16
3850 : MIPS_HFLAG_BDS32);
e68dd28f 3851 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3852 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3853 blink = 31;
3854 goto not_likely;
3855 case OPC_BGEZALL:
e68dd28f 3856 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3857 blink = 31;
d077b6f7 3858 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3859 goto likely;
3860 case OPC_BGTZ:
e68dd28f 3861 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3862 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3863 goto not_likely;
3864 case OPC_BGTZL:
e68dd28f 3865 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3866 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3867 goto likely;
3868 case OPC_BLEZ:
e68dd28f 3869 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3870 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3871 goto not_likely;
3872 case OPC_BLEZL:
e68dd28f 3873 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3874 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3875 goto likely;
3876 case OPC_BLTZ:
e68dd28f 3877 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3878 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3879 goto not_likely;
3880 case OPC_BLTZL:
e68dd28f 3881 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3882 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3883 goto likely;
e45a93e2
JL
3884 case OPC_BPOSGE32:
3885 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3886 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3887 goto not_likely;
3888#if defined(TARGET_MIPS64)
3889 case OPC_BPOSGE64:
3890 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3891 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3892 goto not_likely;
3893#endif
3c824109 3894 case OPC_BLTZALS:
6af0bf9c 3895 case OPC_BLTZAL:
3c824109
NF
3896 ctx->hflags |= (opc == OPC_BLTZALS
3897 ? MIPS_HFLAG_BDS16
3898 : MIPS_HFLAG_BDS32);
e68dd28f 3899 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3900 blink = 31;
d077b6f7 3901 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3902 not_likely:
4ad40f36 3903 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3904 break;
3905 case OPC_BLTZALL:
e68dd28f 3906 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3907 blink = 31;
d077b6f7 3908 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3909 likely:
4ad40f36 3910 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3911 break;
c53f4a62
TS
3912 default:
3913 MIPS_INVAL("conditional branch/jump");
3914 generate_exception(ctx, EXCP_RI);
6c5c1e20 3915 goto out;
6af0bf9c 3916 }
6af0bf9c 3917 }
923617a3 3918 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3919 blink, ctx->hflags, btgt);
9b9e4393 3920
d077b6f7 3921 ctx->btarget = btgt;
6af0bf9c 3922 if (blink > 0) {
364d4831
NF
3923 int post_delay = insn_bytes;
3924 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3925
3926 if (opc != OPC_JALRC)
3927 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3928
3929 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3930 }
6c5c1e20
TS
3931
3932 out:
364d4831
NF
3933 if (insn_bytes == 2)
3934 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3935 tcg_temp_free(t0);
3936 tcg_temp_free(t1);
6af0bf9c
FB
3937}
3938
7a387fff
TS
3939/* special3 bitfield operations */
3940static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3941 int rs, int lsb, int msb)
7a387fff 3942{
a7812ae4
PB
3943 TCGv t0 = tcg_temp_new();
3944 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
3945
3946 gen_load_gpr(t1, rs);
7a387fff
TS
3947 switch (opc) {
3948 case OPC_EXT:
3949 if (lsb + msb > 31)
3950 goto fail;
505ad7c2
AJ
3951 tcg_gen_shri_tl(t0, t1, lsb);
3952 if (msb != 31) {
3953 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3954 } else {
3955 tcg_gen_ext32s_tl(t0, t0);
3956 }
7a387fff 3957 break;
c6d6dd7c 3958#if defined(TARGET_MIPS64)
7a387fff 3959 case OPC_DEXTM:
505ad7c2
AJ
3960 tcg_gen_shri_tl(t0, t1, lsb);
3961 if (msb != 31) {
3962 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3963 }
7a387fff
TS
3964 break;
3965 case OPC_DEXTU:
505ad7c2
AJ
3966 tcg_gen_shri_tl(t0, t1, lsb + 32);
3967 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3968 break;
3969 case OPC_DEXT:
505ad7c2
AJ
3970 tcg_gen_shri_tl(t0, t1, lsb);
3971 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3972 break;
c6d6dd7c 3973#endif
7a387fff
TS
3974 case OPC_INS:
3975 if (lsb > msb)
3976 goto fail;
6c5c1e20 3977 gen_load_gpr(t0, rt);
e0d002f1 3978 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 3979 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3980 break;
c6d6dd7c 3981#if defined(TARGET_MIPS64)
7a387fff 3982 case OPC_DINSM:
6c5c1e20 3983 gen_load_gpr(t0, rt);
e0d002f1 3984 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
3985 break;
3986 case OPC_DINSU:
6c5c1e20 3987 gen_load_gpr(t0, rt);
e0d002f1 3988 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
3989 break;
3990 case OPC_DINS:
6c5c1e20 3991 gen_load_gpr(t0, rt);
e0d002f1 3992 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 3993 break;
c6d6dd7c 3994#endif
7a387fff
TS
3995 default:
3996fail:
3997 MIPS_INVAL("bitops");
3998 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
3999 tcg_temp_free(t0);
4000 tcg_temp_free(t1);
7a387fff
TS
4001 return;
4002 }
6c5c1e20
TS
4003 gen_store_gpr(t0, rt);
4004 tcg_temp_free(t0);
4005 tcg_temp_free(t1);
7a387fff
TS
4006}
4007
49bcf33c
AJ
4008static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4009{
3a55fa47 4010 TCGv t0;
49bcf33c 4011
3a55fa47
AJ
4012 if (rd == 0) {
4013 /* If no destination, treat it as a NOP. */
4014 MIPS_DEBUG("NOP");
4015 return;
4016 }
4017
4018 t0 = tcg_temp_new();
4019 gen_load_gpr(t0, rt);
49bcf33c
AJ
4020 switch (op2) {
4021 case OPC_WSBH:
3a55fa47
AJ
4022 {
4023 TCGv t1 = tcg_temp_new();
4024
4025 tcg_gen_shri_tl(t1, t0, 8);
4026 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4027 tcg_gen_shli_tl(t0, t0, 8);
4028 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4029 tcg_gen_or_tl(t0, t0, t1);
4030 tcg_temp_free(t1);
4031 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4032 }
49bcf33c
AJ
4033 break;
4034 case OPC_SEB:
3a55fa47 4035 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4036 break;
4037 case OPC_SEH:
3a55fa47 4038 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4039 break;
4040#if defined(TARGET_MIPS64)
4041 case OPC_DSBH:
3a55fa47
AJ
4042 {
4043 TCGv t1 = tcg_temp_new();
4044
4045 tcg_gen_shri_tl(t1, t0, 8);
4046 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4047 tcg_gen_shli_tl(t0, t0, 8);
4048 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4049 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4050 tcg_temp_free(t1);
4051 }
49bcf33c
AJ
4052 break;
4053 case OPC_DSHD:
3a55fa47
AJ
4054 {
4055 TCGv t1 = tcg_temp_new();
4056
4057 tcg_gen_shri_tl(t1, t0, 16);
4058 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4059 tcg_gen_shli_tl(t0, t0, 16);
4060 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4061 tcg_gen_or_tl(t0, t0, t1);
4062 tcg_gen_shri_tl(t1, t0, 32);
4063 tcg_gen_shli_tl(t0, t0, 32);
4064 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4065 tcg_temp_free(t1);
4066 }
49bcf33c
AJ
4067 break;
4068#endif
4069 default:
4070 MIPS_INVAL("bsfhl");
4071 generate_exception(ctx, EXCP_RI);
4072 tcg_temp_free(t0);
49bcf33c
AJ
4073 return;
4074 }
49bcf33c 4075 tcg_temp_free(t0);
49bcf33c
AJ
4076}
4077
f1aa6320 4078#ifndef CONFIG_USER_ONLY
0eaef5aa 4079/* CP0 (MMU and control) */
d9bea114 4080static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4081{
d9bea114 4082 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4083
d9bea114
AJ
4084 tcg_gen_ld_i32(t0, cpu_env, off);
4085 tcg_gen_ext_i32_tl(arg, t0);
4086 tcg_temp_free_i32(t0);
4f57689a
TS
4087}
4088
d9bea114 4089static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4090{
d9bea114
AJ
4091 tcg_gen_ld_tl(arg, cpu_env, off);
4092 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4093}
4094
d9bea114 4095static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4096{
d9bea114 4097 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4098
d9bea114
AJ
4099 tcg_gen_trunc_tl_i32(t0, arg);
4100 tcg_gen_st_i32(t0, cpu_env, off);
4101 tcg_temp_free_i32(t0);
f1aa6320
TS
4102}
4103
d9bea114 4104static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4105{
d9bea114
AJ
4106 tcg_gen_ext32s_tl(arg, arg);
4107 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4108}
4109
d75c135e 4110static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4111{
7a387fff 4112 const char *rn = "invalid";
873eb012 4113
e189e748 4114 if (sel != 0)
d75c135e 4115 check_insn(ctx, ISA_MIPS32);
e189e748 4116
873eb012
TS
4117 switch (reg) {
4118 case 0:
7a387fff
TS
4119 switch (sel) {
4120 case 0:
7db13fae 4121 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4122 rn = "Index";
4123 break;
4124 case 1:
d75c135e 4125 check_insn(ctx, ASE_MT);
895c2d04 4126 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4127 rn = "MVPControl";
ead9360e 4128 break;
7a387fff 4129 case 2:
d75c135e 4130 check_insn(ctx, ASE_MT);
895c2d04 4131 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4132 rn = "MVPConf0";
ead9360e 4133 break;
7a387fff 4134 case 3:
d75c135e 4135 check_insn(ctx, ASE_MT);
895c2d04 4136 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4137 rn = "MVPConf1";
ead9360e 4138 break;
7a387fff
TS
4139 default:
4140 goto die;
4141 }
873eb012
TS
4142 break;
4143 case 1:
7a387fff
TS
4144 switch (sel) {
4145 case 0:
895c2d04 4146 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4147 rn = "Random";
2423f660 4148 break;
7a387fff 4149 case 1:
d75c135e 4150 check_insn(ctx, ASE_MT);
7db13fae 4151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4152 rn = "VPEControl";
ead9360e 4153 break;
7a387fff 4154 case 2:
d75c135e 4155 check_insn(ctx, ASE_MT);
7db13fae 4156 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4157 rn = "VPEConf0";
ead9360e 4158 break;
7a387fff 4159 case 3:
d75c135e 4160 check_insn(ctx, ASE_MT);
7db13fae 4161 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4162 rn = "VPEConf1";
ead9360e 4163 break;
7a387fff 4164 case 4:
d75c135e 4165 check_insn(ctx, ASE_MT);
7db13fae 4166 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4167 rn = "YQMask";
ead9360e 4168 break;
7a387fff 4169 case 5:
d75c135e 4170 check_insn(ctx, ASE_MT);
7db13fae 4171 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4172 rn = "VPESchedule";
ead9360e 4173 break;
7a387fff 4174 case 6:
d75c135e 4175 check_insn(ctx, ASE_MT);
7db13fae 4176 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4177 rn = "VPEScheFBack";
ead9360e 4178 break;
7a387fff 4179 case 7:
d75c135e 4180 check_insn(ctx, ASE_MT);
7db13fae 4181 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4182 rn = "VPEOpt";
ead9360e 4183 break;
7a387fff
TS
4184 default:
4185 goto die;
4186 }
873eb012
TS
4187 break;
4188 case 2:
7a387fff
TS
4189 switch (sel) {
4190 case 0:
7db13fae 4191 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4192 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4193 rn = "EntryLo0";
4194 break;
7a387fff 4195 case 1:
d75c135e 4196 check_insn(ctx, ASE_MT);
895c2d04 4197 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4198 rn = "TCStatus";
ead9360e 4199 break;
7a387fff 4200 case 2:
d75c135e 4201 check_insn(ctx, ASE_MT);
895c2d04 4202 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4203 rn = "TCBind";
ead9360e 4204 break;
7a387fff 4205 case 3:
d75c135e 4206 check_insn(ctx, ASE_MT);
895c2d04 4207 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4208 rn = "TCRestart";
ead9360e 4209 break;
7a387fff 4210 case 4:
d75c135e 4211 check_insn(ctx, ASE_MT);
895c2d04 4212 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4213 rn = "TCHalt";
ead9360e 4214 break;
7a387fff 4215 case 5:
d75c135e 4216 check_insn(ctx, ASE_MT);
895c2d04 4217 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4218 rn = "TCContext";
ead9360e 4219 break;
7a387fff 4220 case 6:
d75c135e 4221 check_insn(ctx, ASE_MT);
895c2d04 4222 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4223 rn = "TCSchedule";
ead9360e 4224 break;
7a387fff 4225 case 7:
d75c135e 4226 check_insn(ctx, ASE_MT);
895c2d04 4227 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4228 rn = "TCScheFBack";
ead9360e 4229 break;
7a387fff
TS
4230 default:
4231 goto die;
4232 }
873eb012
TS
4233 break;
4234 case 3:
7a387fff
TS
4235 switch (sel) {
4236 case 0:
7db13fae 4237 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4238 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4239 rn = "EntryLo1";
4240 break;
7a387fff
TS
4241 default:
4242 goto die;
1579a72e 4243 }
873eb012
TS
4244 break;
4245 case 4:
7a387fff
TS
4246 switch (sel) {
4247 case 0:
7db13fae 4248 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4249 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4250 rn = "Context";
4251 break;
7a387fff 4252 case 1:
d9bea114 4253// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
4254 rn = "ContextConfig";
4255// break;
7a387fff
TS
4256 default:
4257 goto die;
1579a72e 4258 }
873eb012
TS
4259 break;
4260 case 5:
7a387fff
TS
4261 switch (sel) {
4262 case 0:
7db13fae 4263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4264 rn = "PageMask";
4265 break;
7a387fff 4266 case 1:
d75c135e 4267 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4269 rn = "PageGrain";
4270 break;
7a387fff
TS
4271 default:
4272 goto die;
1579a72e 4273 }
873eb012
TS
4274 break;
4275 case 6:
7a387fff
TS
4276 switch (sel) {
4277 case 0:
7db13fae 4278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4279 rn = "Wired";
4280 break;
7a387fff 4281 case 1:
d75c135e 4282 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4284 rn = "SRSConf0";
ead9360e 4285 break;
7a387fff 4286 case 2:
d75c135e 4287 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4289 rn = "SRSConf1";
ead9360e 4290 break;
7a387fff 4291 case 3:
d75c135e 4292 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4294 rn = "SRSConf2";
ead9360e 4295 break;
7a387fff 4296 case 4:
d75c135e 4297 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4299 rn = "SRSConf3";
ead9360e 4300 break;
7a387fff 4301 case 5:
d75c135e 4302 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4303 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4304 rn = "SRSConf4";
ead9360e 4305 break;
7a387fff
TS
4306 default:
4307 goto die;
1579a72e 4308 }
873eb012 4309 break;
8c0fdd85 4310 case 7:
7a387fff
TS
4311 switch (sel) {
4312 case 0:
d75c135e 4313 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4315 rn = "HWREna";
4316 break;
7a387fff
TS
4317 default:
4318 goto die;
1579a72e 4319 }
8c0fdd85 4320 break;
873eb012 4321 case 8:
7a387fff
TS
4322 switch (sel) {
4323 case 0:
7db13fae 4324 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4325 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4326 rn = "BadVAddr";
2423f660 4327 break;
7a387fff
TS
4328 default:
4329 goto die;
4330 }
873eb012
TS
4331 break;
4332 case 9:
7a387fff
TS
4333 switch (sel) {
4334 case 0:
2e70f6ef
PB
4335 /* Mark as an IO operation because we read the time. */
4336 if (use_icount)
4337 gen_io_start();
895c2d04 4338 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4339 if (use_icount) {
4340 gen_io_end();
2e70f6ef 4341 }
55807224
EI
4342 /* Break the TB to be able to take timer interrupts immediately
4343 after reading count. */
4344 ctx->bstate = BS_STOP;
2423f660
TS
4345 rn = "Count";
4346 break;
4347 /* 6,7 are implementation dependent */
7a387fff
TS
4348 default:
4349 goto die;
2423f660 4350 }
873eb012
TS
4351 break;
4352 case 10:
7a387fff
TS
4353 switch (sel) {
4354 case 0:
7db13fae 4355 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4356 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4357 rn = "EntryHi";
4358 break;
7a387fff
TS
4359 default:
4360 goto die;
1579a72e 4361 }
873eb012
TS
4362 break;
4363 case 11:
7a387fff
TS
4364 switch (sel) {
4365 case 0:
7db13fae 4366 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4367 rn = "Compare";
4368 break;
4369 /* 6,7 are implementation dependent */
7a387fff
TS
4370 default:
4371 goto die;
2423f660 4372 }
873eb012
TS
4373 break;
4374 case 12:
7a387fff
TS
4375 switch (sel) {
4376 case 0:
7db13fae 4377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4378 rn = "Status";
4379 break;
7a387fff 4380 case 1:
d75c135e 4381 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4383 rn = "IntCtl";
4384 break;
7a387fff 4385 case 2:
d75c135e 4386 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4388 rn = "SRSCtl";
4389 break;
7a387fff 4390 case 3:
d75c135e 4391 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4393 rn = "SRSMap";
fd88b6ab 4394 break;
7a387fff
TS
4395 default:
4396 goto die;
4397 }
873eb012
TS
4398 break;
4399 case 13:
7a387fff
TS
4400 switch (sel) {
4401 case 0:
7db13fae 4402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4403 rn = "Cause";
4404 break;
7a387fff
TS
4405 default:
4406 goto die;
4407 }
873eb012
TS
4408 break;
4409 case 14:
7a387fff
TS
4410 switch (sel) {
4411 case 0:
7db13fae 4412 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4413 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4414 rn = "EPC";
4415 break;
7a387fff
TS
4416 default:
4417 goto die;
1579a72e 4418 }
873eb012
TS
4419 break;
4420 case 15:
7a387fff
TS
4421 switch (sel) {
4422 case 0:
7db13fae 4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4424 rn = "PRid";
4425 break;
7a387fff 4426 case 1:
d75c135e 4427 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4429 rn = "EBase";
4430 break;
7a387fff
TS
4431 default:
4432 goto die;
4433 }
873eb012
TS
4434 break;
4435 case 16:
4436 switch (sel) {
4437 case 0:
7db13fae 4438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4439 rn = "Config";
4440 break;
4441 case 1:
7db13fae 4442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4443 rn = "Config1";
4444 break;
7a387fff 4445 case 2:
7db13fae 4446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4447 rn = "Config2";
4448 break;
4449 case 3:
7db13fae 4450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4451 rn = "Config3";
4452 break;
e397ee33
TS
4453 /* 4,5 are reserved */
4454 /* 6,7 are implementation dependent */
4455 case 6:
7db13fae 4456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4457 rn = "Config6";
4458 break;
4459 case 7:
7db13fae 4460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4461 rn = "Config7";
4462 break;
873eb012 4463 default:
873eb012
TS
4464 goto die;
4465 }
4466 break;
4467 case 17:
7a387fff
TS
4468 switch (sel) {
4469 case 0:
895c2d04 4470 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4471 rn = "LLAddr";
4472 break;
7a387fff
TS
4473 default:
4474 goto die;
4475 }
873eb012
TS
4476 break;
4477 case 18:
7a387fff 4478 switch (sel) {
fd88b6ab 4479 case 0 ... 7:
895c2d04 4480 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4481 rn = "WatchLo";
4482 break;
7a387fff
TS
4483 default:
4484 goto die;
4485 }
873eb012
TS
4486 break;
4487 case 19:
7a387fff 4488 switch (sel) {
fd88b6ab 4489 case 0 ...7:
895c2d04 4490 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4491 rn = "WatchHi";
4492 break;
7a387fff
TS
4493 default:
4494 goto die;
4495 }
873eb012 4496 break;
8c0fdd85 4497 case 20:
7a387fff
TS
4498 switch (sel) {
4499 case 0:
d26bc211 4500#if defined(TARGET_MIPS64)
d75c135e 4501 check_insn(ctx, ISA_MIPS3);
7db13fae 4502 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4503 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4504 rn = "XContext";
4505 break;
703eaf37 4506#endif
7a387fff
TS
4507 default:
4508 goto die;
4509 }
8c0fdd85
TS
4510 break;
4511 case 21:
7a387fff
TS
4512 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4513 switch (sel) {
4514 case 0:
7db13fae 4515 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4516 rn = "Framemask";
4517 break;
7a387fff
TS
4518 default:
4519 goto die;
4520 }
8c0fdd85
TS
4521 break;
4522 case 22:
d9bea114 4523 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4524 rn = "'Diagnostic"; /* implementation dependent */
4525 break;
873eb012 4526 case 23:
7a387fff
TS
4527 switch (sel) {
4528 case 0:
895c2d04 4529 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4530 rn = "Debug";
4531 break;
7a387fff 4532 case 1:
d9bea114 4533// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4534 rn = "TraceControl";
4535// break;
7a387fff 4536 case 2:
d9bea114 4537// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4538 rn = "TraceControl2";
4539// break;
7a387fff 4540 case 3:
d9bea114 4541// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4542 rn = "UserTraceData";
4543// break;
7a387fff 4544 case 4:
d9bea114 4545// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4546 rn = "TraceBPC";
4547// break;
7a387fff
TS
4548 default:
4549 goto die;
4550 }
873eb012
TS
4551 break;
4552 case 24:
7a387fff
TS
4553 switch (sel) {
4554 case 0:
f0b3f3ae 4555 /* EJTAG support */
7db13fae 4556 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4557 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4558 rn = "DEPC";
4559 break;
7a387fff
TS
4560 default:
4561 goto die;
4562 }
873eb012 4563 break;
8c0fdd85 4564 case 25:
7a387fff
TS
4565 switch (sel) {
4566 case 0:
7db13fae 4567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4568 rn = "Performance0";
7a387fff
TS
4569 break;
4570 case 1:
d9bea114 4571// gen_helper_mfc0_performance1(arg);
2423f660
TS
4572 rn = "Performance1";
4573// break;
7a387fff 4574 case 2:
d9bea114 4575// gen_helper_mfc0_performance2(arg);
2423f660
TS
4576 rn = "Performance2";
4577// break;
7a387fff 4578 case 3:
d9bea114 4579// gen_helper_mfc0_performance3(arg);
2423f660
TS
4580 rn = "Performance3";
4581// break;
7a387fff 4582 case 4:
d9bea114 4583// gen_helper_mfc0_performance4(arg);
2423f660
TS
4584 rn = "Performance4";
4585// break;
7a387fff 4586 case 5:
d9bea114 4587// gen_helper_mfc0_performance5(arg);
2423f660
TS
4588 rn = "Performance5";
4589// break;
7a387fff 4590 case 6:
d9bea114 4591// gen_helper_mfc0_performance6(arg);
2423f660
TS
4592 rn = "Performance6";
4593// break;
7a387fff 4594 case 7:
d9bea114 4595// gen_helper_mfc0_performance7(arg);
2423f660
TS
4596 rn = "Performance7";
4597// break;
7a387fff
TS
4598 default:
4599 goto die;
4600 }
8c0fdd85
TS
4601 break;
4602 case 26:
d9bea114 4603 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4604 rn = "ECC";
4605 break;
8c0fdd85 4606 case 27:
7a387fff 4607 switch (sel) {
7a387fff 4608 case 0 ... 3:
d9bea114 4609 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4610 rn = "CacheErr";
4611 break;
7a387fff
TS
4612 default:
4613 goto die;
4614 }
8c0fdd85 4615 break;
873eb012
TS
4616 case 28:
4617 switch (sel) {
4618 case 0:
7a387fff
TS
4619 case 2:
4620 case 4:
4621 case 6:
7db13fae 4622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4623 rn = "TagLo";
4624 break;
4625 case 1:
7a387fff
TS
4626 case 3:
4627 case 5:
4628 case 7:
7db13fae 4629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4630 rn = "DataLo";
4631 break;
4632 default:
873eb012
TS
4633 goto die;
4634 }
4635 break;
8c0fdd85 4636 case 29:
7a387fff
TS
4637 switch (sel) {
4638 case 0:
4639 case 2:
4640 case 4:
4641 case 6:
7db13fae 4642 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4643 rn = "TagHi";
4644 break;
4645 case 1:
4646 case 3:
4647 case 5:
4648 case 7:
7db13fae 4649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4650 rn = "DataHi";
4651 break;
4652 default:
4653 goto die;
4654 }
8c0fdd85 4655 break;
873eb012 4656 case 30:
7a387fff
TS
4657 switch (sel) {
4658 case 0:
7db13fae 4659 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4660 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4661 rn = "ErrorEPC";
4662 break;
7a387fff
TS
4663 default:
4664 goto die;
4665 }
873eb012
TS
4666 break;
4667 case 31:
7a387fff
TS
4668 switch (sel) {
4669 case 0:
f0b3f3ae 4670 /* EJTAG support */
7db13fae 4671 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4672 rn = "DESAVE";
4673 break;
7a387fff
TS
4674 default:
4675 goto die;
4676 }
873eb012
TS
4677 break;
4678 default:
873eb012
TS
4679 goto die;
4680 }
2abf314d 4681 (void)rn; /* avoid a compiler warning */
d12d51d5 4682 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4683 return;
4684
4685die:
d12d51d5 4686 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4687 generate_exception(ctx, EXCP_RI);
4688}
4689
d75c135e 4690static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4691{
7a387fff
TS
4692 const char *rn = "invalid";
4693
e189e748 4694 if (sel != 0)
d75c135e 4695 check_insn(ctx, ISA_MIPS32);
e189e748 4696
2e70f6ef
PB
4697 if (use_icount)
4698 gen_io_start();
4699
8c0fdd85
TS
4700 switch (reg) {
4701 case 0:
7a387fff
TS
4702 switch (sel) {
4703 case 0:
895c2d04 4704 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4705 rn = "Index";
4706 break;
4707 case 1:
d75c135e 4708 check_insn(ctx, ASE_MT);
895c2d04 4709 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4710 rn = "MVPControl";
ead9360e 4711 break;
7a387fff 4712 case 2:
d75c135e 4713 check_insn(ctx, ASE_MT);
ead9360e 4714 /* ignored */
7a387fff 4715 rn = "MVPConf0";
ead9360e 4716 break;
7a387fff 4717 case 3:
d75c135e 4718 check_insn(ctx, ASE_MT);
ead9360e 4719 /* ignored */
7a387fff 4720 rn = "MVPConf1";
ead9360e 4721 break;
7a387fff
TS
4722 default:
4723 goto die;
4724 }
8c0fdd85
TS
4725 break;
4726 case 1:
7a387fff
TS
4727 switch (sel) {
4728 case 0:
2423f660 4729 /* ignored */
7a387fff 4730 rn = "Random";
2423f660 4731 break;
7a387fff 4732 case 1:
d75c135e 4733 check_insn(ctx, ASE_MT);
895c2d04 4734 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4735 rn = "VPEControl";
ead9360e 4736 break;
7a387fff 4737 case 2:
d75c135e 4738 check_insn(ctx, ASE_MT);
895c2d04 4739 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4740 rn = "VPEConf0";
ead9360e 4741 break;
7a387fff 4742 case 3:
d75c135e 4743 check_insn(ctx, ASE_MT);
895c2d04 4744 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4745 rn = "VPEConf1";
ead9360e 4746 break;
7a387fff 4747 case 4:
d75c135e 4748 check_insn(ctx, ASE_MT);
895c2d04 4749 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4750 rn = "YQMask";
ead9360e 4751 break;
7a387fff 4752 case 5:
d75c135e 4753 check_insn(ctx, ASE_MT);
7db13fae 4754 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4755 rn = "VPESchedule";
ead9360e 4756 break;
7a387fff 4757 case 6:
d75c135e 4758 check_insn(ctx, ASE_MT);
7db13fae 4759 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4760 rn = "VPEScheFBack";
ead9360e 4761 break;
7a387fff 4762 case 7:
d75c135e 4763 check_insn(ctx, ASE_MT);
895c2d04 4764 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4765 rn = "VPEOpt";
ead9360e 4766 break;
7a387fff
TS
4767 default:
4768 goto die;
4769 }
8c0fdd85
TS
4770 break;
4771 case 2:
7a387fff
TS
4772 switch (sel) {
4773 case 0:
895c2d04 4774 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4775 rn = "EntryLo0";
4776 break;
7a387fff 4777 case 1:
d75c135e 4778 check_insn(ctx, ASE_MT);
895c2d04 4779 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4780 rn = "TCStatus";
ead9360e 4781 break;
7a387fff 4782 case 2:
d75c135e 4783 check_insn(ctx, ASE_MT);
895c2d04 4784 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4785 rn = "TCBind";
ead9360e 4786 break;
7a387fff 4787 case 3:
d75c135e 4788 check_insn(ctx, ASE_MT);
895c2d04 4789 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4790 rn = "TCRestart";
ead9360e 4791 break;
7a387fff 4792 case 4:
d75c135e 4793 check_insn(ctx, ASE_MT);
895c2d04 4794 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4795 rn = "TCHalt";
ead9360e 4796 break;
7a387fff 4797 case 5:
d75c135e 4798 check_insn(ctx, ASE_MT);
895c2d04 4799 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4800 rn = "TCContext";
ead9360e 4801 break;
7a387fff 4802 case 6:
d75c135e 4803 check_insn(ctx, ASE_MT);
895c2d04 4804 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4805 rn = "TCSchedule";
ead9360e 4806 break;
7a387fff 4807 case 7:
d75c135e 4808 check_insn(ctx, ASE_MT);
895c2d04 4809 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4810 rn = "TCScheFBack";
ead9360e 4811 break;
7a387fff
TS
4812 default:
4813 goto die;
4814 }
8c0fdd85
TS
4815 break;
4816 case 3:
7a387fff
TS
4817 switch (sel) {
4818 case 0:
895c2d04 4819 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4820 rn = "EntryLo1";
4821 break;
7a387fff
TS
4822 default:
4823 goto die;
876d4b07 4824 }
8c0fdd85
TS
4825 break;
4826 case 4:
7a387fff
TS
4827 switch (sel) {
4828 case 0:
895c2d04 4829 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4830 rn = "Context";
4831 break;
7a387fff 4832 case 1:
895c2d04 4833// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
4834 rn = "ContextConfig";
4835// break;
7a387fff
TS
4836 default:
4837 goto die;
876d4b07 4838 }
8c0fdd85
TS
4839 break;
4840 case 5:
7a387fff
TS
4841 switch (sel) {
4842 case 0:
895c2d04 4843 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4844 rn = "PageMask";
4845 break;
7a387fff 4846 case 1:
d75c135e 4847 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4848 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4849 rn = "PageGrain";
4850 break;
7a387fff
TS
4851 default:
4852 goto die;
876d4b07 4853 }
8c0fdd85
TS
4854 break;
4855 case 6:
7a387fff
TS
4856 switch (sel) {
4857 case 0:
895c2d04 4858 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4859 rn = "Wired";
4860 break;
7a387fff 4861 case 1:
d75c135e 4862 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4863 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4864 rn = "SRSConf0";
ead9360e 4865 break;
7a387fff 4866 case 2:
d75c135e 4867 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4868 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4869 rn = "SRSConf1";
ead9360e 4870 break;
7a387fff 4871 case 3:
d75c135e 4872 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4873 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4874 rn = "SRSConf2";
ead9360e 4875 break;
7a387fff 4876 case 4:
d75c135e 4877 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4878 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4879 rn = "SRSConf3";
ead9360e 4880 break;
7a387fff 4881 case 5:
d75c135e 4882 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4883 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4884 rn = "SRSConf4";
ead9360e 4885 break;
7a387fff
TS
4886 default:
4887 goto die;
876d4b07 4888 }
8c0fdd85
TS
4889 break;
4890 case 7:
7a387fff
TS
4891 switch (sel) {
4892 case 0:
d75c135e 4893 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4894 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
4895 rn = "HWREna";
4896 break;
7a387fff
TS
4897 default:
4898 goto die;
876d4b07 4899 }
8c0fdd85
TS
4900 break;
4901 case 8:
7a387fff 4902 /* ignored */
f0b3f3ae 4903 rn = "BadVAddr";
8c0fdd85
TS
4904 break;
4905 case 9:
7a387fff
TS
4906 switch (sel) {
4907 case 0:
895c2d04 4908 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4909 rn = "Count";
4910 break;
876d4b07 4911 /* 6,7 are implementation dependent */
7a387fff
TS
4912 default:
4913 goto die;
876d4b07 4914 }
8c0fdd85
TS
4915 break;
4916 case 10:
7a387fff
TS
4917 switch (sel) {
4918 case 0:
895c2d04 4919 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4920 rn = "EntryHi";
4921 break;
7a387fff
TS
4922 default:
4923 goto die;
876d4b07 4924 }
8c0fdd85
TS
4925 break;
4926 case 11:
7a387fff
TS
4927 switch (sel) {
4928 case 0:
895c2d04 4929 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4930 rn = "Compare";
4931 break;
4932 /* 6,7 are implementation dependent */
7a387fff
TS
4933 default:
4934 goto die;
876d4b07 4935 }
8c0fdd85
TS
4936 break;
4937 case 12:
7a387fff
TS
4938 switch (sel) {
4939 case 0:
867abc7e 4940 save_cpu_state(ctx, 1);
895c2d04 4941 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4942 /* BS_STOP isn't good enough here, hflags may have changed. */
4943 gen_save_pc(ctx->pc + 4);
4944 ctx->bstate = BS_EXCP;
2423f660
TS
4945 rn = "Status";
4946 break;
7a387fff 4947 case 1:
d75c135e 4948 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4949 gen_helper_mtc0_intctl(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 = "IntCtl";
4953 break;
7a387fff 4954 case 2:
d75c135e 4955 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4956 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4957 /* Stop translation as we may have switched the execution mode */
4958 ctx->bstate = BS_STOP;
2423f660
TS
4959 rn = "SRSCtl";
4960 break;
7a387fff 4961 case 3:
d75c135e 4962 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4963 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4964 /* Stop translation as we may have switched the execution mode */
4965 ctx->bstate = BS_STOP;
2423f660 4966 rn = "SRSMap";
fd88b6ab 4967 break;
7a387fff
TS
4968 default:
4969 goto die;
876d4b07 4970 }
8c0fdd85
TS
4971 break;
4972 case 13:
7a387fff
TS
4973 switch (sel) {
4974 case 0:
867abc7e 4975 save_cpu_state(ctx, 1);
895c2d04 4976 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4977 rn = "Cause";
4978 break;
7a387fff
TS
4979 default:
4980 goto die;
876d4b07 4981 }
8c0fdd85
TS
4982 break;
4983 case 14:
7a387fff
TS
4984 switch (sel) {
4985 case 0:
7db13fae 4986 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4987 rn = "EPC";
4988 break;
7a387fff
TS
4989 default:
4990 goto die;
876d4b07 4991 }
8c0fdd85
TS
4992 break;
4993 case 15:
7a387fff
TS
4994 switch (sel) {
4995 case 0:
2423f660
TS
4996 /* ignored */
4997 rn = "PRid";
4998 break;
7a387fff 4999 case 1:
d75c135e 5000 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5001 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5002 rn = "EBase";
5003 break;
7a387fff
TS
5004 default:
5005 goto die;
1579a72e 5006 }
8c0fdd85
TS
5007 break;
5008 case 16:
5009 switch (sel) {
5010 case 0:
895c2d04 5011 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5012 rn = "Config";
2423f660
TS
5013 /* Stop translation as we may have switched the execution mode */
5014 ctx->bstate = BS_STOP;
7a387fff
TS
5015 break;
5016 case 1:
e397ee33 5017 /* ignored, read only */
7a387fff
TS
5018 rn = "Config1";
5019 break;
5020 case 2:
895c2d04 5021 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5022 rn = "Config2";
2423f660
TS
5023 /* Stop translation as we may have switched the execution mode */
5024 ctx->bstate = BS_STOP;
8c0fdd85 5025 break;
7a387fff 5026 case 3:
e397ee33 5027 /* ignored, read only */
7a387fff
TS
5028 rn = "Config3";
5029 break;
e397ee33
TS
5030 /* 4,5 are reserved */
5031 /* 6,7 are implementation dependent */
5032 case 6:
5033 /* ignored */
5034 rn = "Config6";
5035 break;
5036 case 7:
5037 /* ignored */
5038 rn = "Config7";
5039 break;
8c0fdd85
TS
5040 default:
5041 rn = "Invalid config selector";
5042 goto die;
5043 }
5044 break;
5045 case 17:
7a387fff
TS
5046 switch (sel) {
5047 case 0:
895c2d04 5048 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5049 rn = "LLAddr";
5050 break;
7a387fff
TS
5051 default:
5052 goto die;
5053 }
8c0fdd85
TS
5054 break;
5055 case 18:
7a387fff 5056 switch (sel) {
fd88b6ab 5057 case 0 ... 7:
895c2d04 5058 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5059 rn = "WatchLo";
5060 break;
7a387fff
TS
5061 default:
5062 goto die;
5063 }
8c0fdd85
TS
5064 break;
5065 case 19:
7a387fff 5066 switch (sel) {
fd88b6ab 5067 case 0 ... 7:
895c2d04 5068 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5069 rn = "WatchHi";
5070 break;
7a387fff
TS
5071 default:
5072 goto die;
5073 }
8c0fdd85
TS
5074 break;
5075 case 20:
7a387fff
TS
5076 switch (sel) {
5077 case 0:
d26bc211 5078#if defined(TARGET_MIPS64)
d75c135e 5079 check_insn(ctx, ISA_MIPS3);
895c2d04 5080 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5081 rn = "XContext";
5082 break;
703eaf37 5083#endif
7a387fff
TS
5084 default:
5085 goto die;
5086 }
8c0fdd85
TS
5087 break;
5088 case 21:
7a387fff
TS
5089 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5090 switch (sel) {
5091 case 0:
895c2d04 5092 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5093 rn = "Framemask";
5094 break;
7a387fff
TS
5095 default:
5096 goto die;
5097 }
5098 break;
8c0fdd85 5099 case 22:
7a387fff
TS
5100 /* ignored */
5101 rn = "Diagnostic"; /* implementation dependent */
2423f660 5102 break;
8c0fdd85 5103 case 23:
7a387fff
TS
5104 switch (sel) {
5105 case 0:
895c2d04 5106 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5107 /* BS_STOP isn't good enough here, hflags may have changed. */
5108 gen_save_pc(ctx->pc + 4);
5109 ctx->bstate = BS_EXCP;
2423f660
TS
5110 rn = "Debug";
5111 break;
7a387fff 5112 case 1:
895c2d04 5113// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5114 rn = "TraceControl";
8487327a
TS
5115 /* Stop translation as we may have switched the execution mode */
5116 ctx->bstate = BS_STOP;
2423f660 5117// break;
7a387fff 5118 case 2:
895c2d04 5119// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5120 rn = "TraceControl2";
8487327a
TS
5121 /* Stop translation as we may have switched the execution mode */
5122 ctx->bstate = BS_STOP;
2423f660 5123// break;
7a387fff 5124 case 3:
8487327a
TS
5125 /* Stop translation as we may have switched the execution mode */
5126 ctx->bstate = BS_STOP;
895c2d04 5127// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5128 rn = "UserTraceData";
8487327a
TS
5129 /* Stop translation as we may have switched the execution mode */
5130 ctx->bstate = BS_STOP;
2423f660 5131// break;
7a387fff 5132 case 4:
895c2d04 5133// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5134 /* Stop translation as we may have switched the execution mode */
5135 ctx->bstate = BS_STOP;
2423f660
TS
5136 rn = "TraceBPC";
5137// break;
7a387fff
TS
5138 default:
5139 goto die;
5140 }
8c0fdd85
TS
5141 break;
5142 case 24:
7a387fff
TS
5143 switch (sel) {
5144 case 0:
f1aa6320 5145 /* EJTAG support */
7db13fae 5146 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5147 rn = "DEPC";
5148 break;
7a387fff
TS
5149 default:
5150 goto die;
5151 }
8c0fdd85
TS
5152 break;
5153 case 25:
7a387fff
TS
5154 switch (sel) {
5155 case 0:
895c2d04 5156 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5157 rn = "Performance0";
5158 break;
7a387fff 5159 case 1:
d9bea114 5160// gen_helper_mtc0_performance1(arg);
2423f660
TS
5161 rn = "Performance1";
5162// break;
7a387fff 5163 case 2:
d9bea114 5164// gen_helper_mtc0_performance2(arg);
2423f660
TS
5165 rn = "Performance2";
5166// break;
7a387fff 5167 case 3:
d9bea114 5168// gen_helper_mtc0_performance3(arg);
2423f660
TS
5169 rn = "Performance3";
5170// break;
7a387fff 5171 case 4:
d9bea114 5172// gen_helper_mtc0_performance4(arg);
2423f660
TS
5173 rn = "Performance4";
5174// break;
7a387fff 5175 case 5:
d9bea114 5176// gen_helper_mtc0_performance5(arg);
2423f660
TS
5177 rn = "Performance5";
5178// break;
7a387fff 5179 case 6:
d9bea114 5180// gen_helper_mtc0_performance6(arg);
2423f660
TS
5181 rn = "Performance6";
5182// break;
7a387fff 5183 case 7:
d9bea114 5184// gen_helper_mtc0_performance7(arg);
2423f660
TS
5185 rn = "Performance7";
5186// break;
7a387fff
TS
5187 default:
5188 goto die;
5189 }
8c0fdd85
TS
5190 break;
5191 case 26:
2423f660 5192 /* ignored */
8c0fdd85 5193 rn = "ECC";
2423f660 5194 break;
8c0fdd85 5195 case 27:
7a387fff
TS
5196 switch (sel) {
5197 case 0 ... 3:
2423f660
TS
5198 /* ignored */
5199 rn = "CacheErr";
5200 break;
7a387fff
TS
5201 default:
5202 goto die;
5203 }
8c0fdd85
TS
5204 break;
5205 case 28:
5206 switch (sel) {
5207 case 0:
7a387fff
TS
5208 case 2:
5209 case 4:
5210 case 6:
895c2d04 5211 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5212 rn = "TagLo";
5213 break;
7a387fff
TS
5214 case 1:
5215 case 3:
5216 case 5:
5217 case 7:
895c2d04 5218 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5219 rn = "DataLo";
5220 break;
8c0fdd85 5221 default:
8c0fdd85
TS
5222 goto die;
5223 }
5224 break;
5225 case 29:
7a387fff
TS
5226 switch (sel) {
5227 case 0:
5228 case 2:
5229 case 4:
5230 case 6:
895c2d04 5231 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5232 rn = "TagHi";
5233 break;
5234 case 1:
5235 case 3:
5236 case 5:
5237 case 7:
895c2d04 5238 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5239 rn = "DataHi";
5240 break;
5241 default:
5242 rn = "invalid sel";
5243 goto die;
5244 }
8c0fdd85
TS
5245 break;
5246 case 30:
7a387fff
TS
5247 switch (sel) {
5248 case 0:
7db13fae 5249 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5250 rn = "ErrorEPC";
5251 break;
7a387fff
TS
5252 default:
5253 goto die;
5254 }
8c0fdd85
TS
5255 break;
5256 case 31:
7a387fff
TS
5257 switch (sel) {
5258 case 0:
f1aa6320 5259 /* EJTAG support */
7db13fae 5260 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5261 rn = "DESAVE";
5262 break;
7a387fff
TS
5263 default:
5264 goto die;
5265 }
2423f660
TS
5266 /* Stop translation as we may have switched the execution mode */
5267 ctx->bstate = BS_STOP;
8c0fdd85
TS
5268 break;
5269 default:
8c0fdd85
TS
5270 goto die;
5271 }
2abf314d 5272 (void)rn; /* avoid a compiler warning */
d12d51d5 5273 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5274 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5275 if (use_icount) {
5276 gen_io_end();
5277 ctx->bstate = BS_STOP;
5278 }
8c0fdd85
TS
5279 return;
5280
5281die:
d12d51d5 5282 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5283 generate_exception(ctx, EXCP_RI);
5284}
5285
d26bc211 5286#if defined(TARGET_MIPS64)
d75c135e 5287static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5288{
5289 const char *rn = "invalid";
5290
e189e748 5291 if (sel != 0)
d75c135e 5292 check_insn(ctx, ISA_MIPS64);
e189e748 5293
9c2149c8
TS
5294 switch (reg) {
5295 case 0:
5296 switch (sel) {
5297 case 0:
7db13fae 5298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5299 rn = "Index";
5300 break;
5301 case 1:
d75c135e 5302 check_insn(ctx, ASE_MT);
895c2d04 5303 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5304 rn = "MVPControl";
ead9360e 5305 break;
9c2149c8 5306 case 2:
d75c135e 5307 check_insn(ctx, ASE_MT);
895c2d04 5308 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5309 rn = "MVPConf0";
ead9360e 5310 break;
9c2149c8 5311 case 3:
d75c135e 5312 check_insn(ctx, ASE_MT);
895c2d04 5313 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5314 rn = "MVPConf1";
ead9360e 5315 break;
9c2149c8
TS
5316 default:
5317 goto die;
5318 }
5319 break;
5320 case 1:
5321 switch (sel) {
5322 case 0:
895c2d04 5323 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5324 rn = "Random";
2423f660 5325 break;
9c2149c8 5326 case 1:
d75c135e 5327 check_insn(ctx, ASE_MT);
7db13fae 5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5329 rn = "VPEControl";
ead9360e 5330 break;
9c2149c8 5331 case 2:
d75c135e 5332 check_insn(ctx, ASE_MT);
7db13fae 5333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5334 rn = "VPEConf0";
ead9360e 5335 break;
9c2149c8 5336 case 3:
d75c135e 5337 check_insn(ctx, ASE_MT);
7db13fae 5338 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5339 rn = "VPEConf1";
ead9360e 5340 break;
9c2149c8 5341 case 4:
d75c135e 5342 check_insn(ctx, ASE_MT);
7db13fae 5343 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5344 rn = "YQMask";
ead9360e 5345 break;
9c2149c8 5346 case 5:
d75c135e 5347 check_insn(ctx, ASE_MT);
7db13fae 5348 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5349 rn = "VPESchedule";
ead9360e 5350 break;
9c2149c8 5351 case 6:
d75c135e 5352 check_insn(ctx, ASE_MT);
7db13fae 5353 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5354 rn = "VPEScheFBack";
ead9360e 5355 break;
9c2149c8 5356 case 7:
d75c135e 5357 check_insn(ctx, ASE_MT);
7db13fae 5358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5359 rn = "VPEOpt";
ead9360e 5360 break;
9c2149c8
TS
5361 default:
5362 goto die;
5363 }
5364 break;
5365 case 2:
5366 switch (sel) {
5367 case 0:
7db13fae 5368 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5369 rn = "EntryLo0";
5370 break;
9c2149c8 5371 case 1:
d75c135e 5372 check_insn(ctx, ASE_MT);
895c2d04 5373 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5374 rn = "TCStatus";
ead9360e 5375 break;
9c2149c8 5376 case 2:
d75c135e 5377 check_insn(ctx, ASE_MT);
895c2d04 5378 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5379 rn = "TCBind";
ead9360e 5380 break;
9c2149c8 5381 case 3:
d75c135e 5382 check_insn(ctx, ASE_MT);
895c2d04 5383 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5384 rn = "TCRestart";
ead9360e 5385 break;
9c2149c8 5386 case 4:
d75c135e 5387 check_insn(ctx, ASE_MT);
895c2d04 5388 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5389 rn = "TCHalt";
ead9360e 5390 break;
9c2149c8 5391 case 5:
d75c135e 5392 check_insn(ctx, ASE_MT);
895c2d04 5393 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5394 rn = "TCContext";
ead9360e 5395 break;
9c2149c8 5396 case 6:
d75c135e 5397 check_insn(ctx, ASE_MT);
895c2d04 5398 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5399 rn = "TCSchedule";
ead9360e 5400 break;
9c2149c8 5401 case 7:
d75c135e 5402 check_insn(ctx, ASE_MT);
895c2d04 5403 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5404 rn = "TCScheFBack";
ead9360e 5405 break;
9c2149c8
TS
5406 default:
5407 goto die;
5408 }
5409 break;
5410 case 3:
5411 switch (sel) {
5412 case 0:
7db13fae 5413 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5414 rn = "EntryLo1";
5415 break;
9c2149c8
TS
5416 default:
5417 goto die;
1579a72e 5418 }
9c2149c8
TS
5419 break;
5420 case 4:
5421 switch (sel) {
5422 case 0:
7db13fae 5423 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5424 rn = "Context";
5425 break;
9c2149c8 5426 case 1:
d9bea114 5427// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
5428 rn = "ContextConfig";
5429// break;
9c2149c8
TS
5430 default:
5431 goto die;
876d4b07 5432 }
9c2149c8
TS
5433 break;
5434 case 5:
5435 switch (sel) {
5436 case 0:
7db13fae 5437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5438 rn = "PageMask";
5439 break;
9c2149c8 5440 case 1:
d75c135e 5441 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5443 rn = "PageGrain";
5444 break;
9c2149c8
TS
5445 default:
5446 goto die;
876d4b07 5447 }
9c2149c8
TS
5448 break;
5449 case 6:
5450 switch (sel) {
5451 case 0:
7db13fae 5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5453 rn = "Wired";
5454 break;
9c2149c8 5455 case 1:
d75c135e 5456 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5458 rn = "SRSConf0";
ead9360e 5459 break;
9c2149c8 5460 case 2:
d75c135e 5461 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5463 rn = "SRSConf1";
ead9360e 5464 break;
9c2149c8 5465 case 3:
d75c135e 5466 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5468 rn = "SRSConf2";
ead9360e 5469 break;
9c2149c8 5470 case 4:
d75c135e 5471 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5473 rn = "SRSConf3";
ead9360e 5474 break;
9c2149c8 5475 case 5:
d75c135e 5476 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5478 rn = "SRSConf4";
ead9360e 5479 break;
9c2149c8
TS
5480 default:
5481 goto die;
876d4b07 5482 }
9c2149c8
TS
5483 break;
5484 case 7:
5485 switch (sel) {
5486 case 0:
d75c135e 5487 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5489 rn = "HWREna";
5490 break;
9c2149c8
TS
5491 default:
5492 goto die;
876d4b07 5493 }
9c2149c8
TS
5494 break;
5495 case 8:
5496 switch (sel) {
5497 case 0:
7db13fae 5498 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5499 rn = "BadVAddr";
2423f660 5500 break;
9c2149c8
TS
5501 default:
5502 goto die;
876d4b07 5503 }
9c2149c8
TS
5504 break;
5505 case 9:
5506 switch (sel) {
5507 case 0:
2e70f6ef
PB
5508 /* Mark as an IO operation because we read the time. */
5509 if (use_icount)
5510 gen_io_start();
895c2d04 5511 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5512 if (use_icount) {
5513 gen_io_end();
2e70f6ef 5514 }
55807224
EI
5515 /* Break the TB to be able to take timer interrupts immediately
5516 after reading count. */
5517 ctx->bstate = BS_STOP;
2423f660
TS
5518 rn = "Count";
5519 break;
5520 /* 6,7 are implementation dependent */
9c2149c8
TS
5521 default:
5522 goto die;
876d4b07 5523 }
9c2149c8
TS
5524 break;
5525 case 10:
5526 switch (sel) {
5527 case 0:
7db13fae 5528 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5529 rn = "EntryHi";
5530 break;
9c2149c8
TS
5531 default:
5532 goto die;
876d4b07 5533 }
9c2149c8
TS
5534 break;
5535 case 11:
5536 switch (sel) {
5537 case 0:
7db13fae 5538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5539 rn = "Compare";
5540 break;
876d4b07 5541 /* 6,7 are implementation dependent */
9c2149c8
TS
5542 default:
5543 goto die;
876d4b07 5544 }
9c2149c8
TS
5545 break;
5546 case 12:
5547 switch (sel) {
5548 case 0:
7db13fae 5549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5550 rn = "Status";
5551 break;
9c2149c8 5552 case 1:
d75c135e 5553 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5555 rn = "IntCtl";
5556 break;
9c2149c8 5557 case 2:
d75c135e 5558 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5560 rn = "SRSCtl";
5561 break;
9c2149c8 5562 case 3:
d75c135e 5563 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5565 rn = "SRSMap";
5566 break;
9c2149c8
TS
5567 default:
5568 goto die;
876d4b07 5569 }
9c2149c8
TS
5570 break;
5571 case 13:
5572 switch (sel) {
5573 case 0:
7db13fae 5574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5575 rn = "Cause";
5576 break;
9c2149c8
TS
5577 default:
5578 goto die;
876d4b07 5579 }
9c2149c8
TS
5580 break;
5581 case 14:
5582 switch (sel) {
5583 case 0:
7db13fae 5584 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5585 rn = "EPC";
5586 break;
9c2149c8
TS
5587 default:
5588 goto die;
876d4b07 5589 }
9c2149c8
TS
5590 break;
5591 case 15:
5592 switch (sel) {
5593 case 0:
7db13fae 5594 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5595 rn = "PRid";
5596 break;
9c2149c8 5597 case 1:
d75c135e 5598 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5600 rn = "EBase";
5601 break;
9c2149c8
TS
5602 default:
5603 goto die;
876d4b07 5604 }
9c2149c8
TS
5605 break;
5606 case 16:
5607 switch (sel) {
5608 case 0:
7db13fae 5609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5610 rn = "Config";
5611 break;
5612 case 1:
7db13fae 5613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5614 rn = "Config1";
5615 break;
5616 case 2:
7db13fae 5617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5618 rn = "Config2";
5619 break;
5620 case 3:
7db13fae 5621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5622 rn = "Config3";
5623 break;
5624 /* 6,7 are implementation dependent */
f0b3f3ae 5625 case 6:
7db13fae 5626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5627 rn = "Config6";
5628 break;
5629 case 7:
7db13fae 5630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5631 rn = "Config7";
5632 break;
9c2149c8
TS
5633 default:
5634 goto die;
5635 }
5636 break;
5637 case 17:
5638 switch (sel) {
5639 case 0:
895c2d04 5640 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5641 rn = "LLAddr";
5642 break;
9c2149c8
TS
5643 default:
5644 goto die;
5645 }
5646 break;
5647 case 18:
5648 switch (sel) {
fd88b6ab 5649 case 0 ... 7:
895c2d04 5650 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5651 rn = "WatchLo";
5652 break;
9c2149c8
TS
5653 default:
5654 goto die;
5655 }
5656 break;
5657 case 19:
5658 switch (sel) {
fd88b6ab 5659 case 0 ... 7:
895c2d04 5660 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5661 rn = "WatchHi";
5662 break;
9c2149c8
TS
5663 default:
5664 goto die;
5665 }
5666 break;
5667 case 20:
5668 switch (sel) {
5669 case 0:
d75c135e 5670 check_insn(ctx, ISA_MIPS3);
7db13fae 5671 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5672 rn = "XContext";
5673 break;
9c2149c8
TS
5674 default:
5675 goto die;
5676 }
5677 break;
5678 case 21:
5679 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5680 switch (sel) {
5681 case 0:
7db13fae 5682 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5683 rn = "Framemask";
5684 break;
9c2149c8
TS
5685 default:
5686 goto die;
5687 }
5688 break;
5689 case 22:
d9bea114 5690 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5691 rn = "'Diagnostic"; /* implementation dependent */
5692 break;
9c2149c8
TS
5693 case 23:
5694 switch (sel) {
5695 case 0:
895c2d04 5696 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5697 rn = "Debug";
5698 break;
9c2149c8 5699 case 1:
895c2d04 5700// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5701 rn = "TraceControl";
5702// break;
9c2149c8 5703 case 2:
895c2d04 5704// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5705 rn = "TraceControl2";
5706// break;
9c2149c8 5707 case 3:
895c2d04 5708// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5709 rn = "UserTraceData";
5710// break;
9c2149c8 5711 case 4:
895c2d04 5712// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5713 rn = "TraceBPC";
5714// break;
9c2149c8
TS
5715 default:
5716 goto die;
5717 }
5718 break;
5719 case 24:
5720 switch (sel) {
5721 case 0:
f0b3f3ae 5722 /* EJTAG support */
7db13fae 5723 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5724 rn = "DEPC";
5725 break;
9c2149c8
TS
5726 default:
5727 goto die;
5728 }
5729 break;
5730 case 25:
5731 switch (sel) {
5732 case 0:
7db13fae 5733 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5734 rn = "Performance0";
9c2149c8
TS
5735 break;
5736 case 1:
d9bea114 5737// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5738 rn = "Performance1";
5739// break;
9c2149c8 5740 case 2:
d9bea114 5741// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5742 rn = "Performance2";
5743// break;
9c2149c8 5744 case 3:
d9bea114 5745// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5746 rn = "Performance3";
5747// break;
9c2149c8 5748 case 4:
d9bea114 5749// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5750 rn = "Performance4";
5751// break;
9c2149c8 5752 case 5:
d9bea114 5753// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5754 rn = "Performance5";
5755// break;
9c2149c8 5756 case 6:
d9bea114 5757// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5758 rn = "Performance6";
5759// break;
9c2149c8 5760 case 7:
d9bea114 5761// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5762 rn = "Performance7";
5763// break;
9c2149c8
TS
5764 default:
5765 goto die;
5766 }
5767 break;
5768 case 26:
d9bea114 5769 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5770 rn = "ECC";
5771 break;
9c2149c8
TS
5772 case 27:
5773 switch (sel) {
5774 /* ignored */
5775 case 0 ... 3:
d9bea114 5776 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5777 rn = "CacheErr";
5778 break;
9c2149c8
TS
5779 default:
5780 goto die;
5781 }
5782 break;
5783 case 28:
5784 switch (sel) {
5785 case 0:
5786 case 2:
5787 case 4:
5788 case 6:
7db13fae 5789 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5790 rn = "TagLo";
5791 break;
5792 case 1:
5793 case 3:
5794 case 5:
5795 case 7:
7db13fae 5796 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5797 rn = "DataLo";
5798 break;
5799 default:
5800 goto die;
5801 }
5802 break;
5803 case 29:
5804 switch (sel) {
5805 case 0:
5806 case 2:
5807 case 4:
5808 case 6:
7db13fae 5809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5810 rn = "TagHi";
5811 break;
5812 case 1:
5813 case 3:
5814 case 5:
5815 case 7:
7db13fae 5816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5817 rn = "DataHi";
5818 break;
5819 default:
5820 goto die;
5821 }
5822 break;
5823 case 30:
5824 switch (sel) {
5825 case 0:
7db13fae 5826 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5827 rn = "ErrorEPC";
5828 break;
9c2149c8
TS
5829 default:
5830 goto die;
5831 }
5832 break;
5833 case 31:
5834 switch (sel) {
5835 case 0:
f0b3f3ae 5836 /* EJTAG support */
7db13fae 5837 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5838 rn = "DESAVE";
5839 break;
9c2149c8
TS
5840 default:
5841 goto die;
5842 }
5843 break;
5844 default:
876d4b07 5845 goto die;
9c2149c8 5846 }
2abf314d 5847 (void)rn; /* avoid a compiler warning */
d12d51d5 5848 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5849 return;
5850
5851die:
d12d51d5 5852 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5853 generate_exception(ctx, EXCP_RI);
5854}
5855
d75c135e 5856static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5857{
5858 const char *rn = "invalid";
5859
e189e748 5860 if (sel != 0)
d75c135e 5861 check_insn(ctx, ISA_MIPS64);
e189e748 5862
2e70f6ef
PB
5863 if (use_icount)
5864 gen_io_start();
5865
9c2149c8
TS
5866 switch (reg) {
5867 case 0:
5868 switch (sel) {
5869 case 0:
895c2d04 5870 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5871 rn = "Index";
5872 break;
5873 case 1:
d75c135e 5874 check_insn(ctx, ASE_MT);
895c2d04 5875 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5876 rn = "MVPControl";
ead9360e 5877 break;
9c2149c8 5878 case 2:
d75c135e 5879 check_insn(ctx, ASE_MT);
ead9360e 5880 /* ignored */
9c2149c8 5881 rn = "MVPConf0";
ead9360e 5882 break;
9c2149c8 5883 case 3:
d75c135e 5884 check_insn(ctx, ASE_MT);
ead9360e 5885 /* ignored */
9c2149c8 5886 rn = "MVPConf1";
ead9360e 5887 break;
9c2149c8
TS
5888 default:
5889 goto die;
5890 }
5891 break;
5892 case 1:
5893 switch (sel) {
5894 case 0:
2423f660 5895 /* ignored */
9c2149c8 5896 rn = "Random";
2423f660 5897 break;
9c2149c8 5898 case 1:
d75c135e 5899 check_insn(ctx, ASE_MT);
895c2d04 5900 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5901 rn = "VPEControl";
ead9360e 5902 break;
9c2149c8 5903 case 2:
d75c135e 5904 check_insn(ctx, ASE_MT);
895c2d04 5905 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5906 rn = "VPEConf0";
ead9360e 5907 break;
9c2149c8 5908 case 3:
d75c135e 5909 check_insn(ctx, ASE_MT);
895c2d04 5910 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5911 rn = "VPEConf1";
ead9360e 5912 break;
9c2149c8 5913 case 4:
d75c135e 5914 check_insn(ctx, ASE_MT);
895c2d04 5915 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5916 rn = "YQMask";
ead9360e 5917 break;
9c2149c8 5918 case 5:
d75c135e 5919 check_insn(ctx, ASE_MT);
7db13fae 5920 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5921 rn = "VPESchedule";
ead9360e 5922 break;
9c2149c8 5923 case 6:
d75c135e 5924 check_insn(ctx, ASE_MT);
7db13fae 5925 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5926 rn = "VPEScheFBack";
ead9360e 5927 break;
9c2149c8 5928 case 7:
d75c135e 5929 check_insn(ctx, ASE_MT);
895c2d04 5930 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5931 rn = "VPEOpt";
ead9360e 5932 break;
9c2149c8
TS
5933 default:
5934 goto die;
5935 }
5936 break;
5937 case 2:
5938 switch (sel) {
5939 case 0:
895c2d04 5940 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5941 rn = "EntryLo0";
5942 break;
9c2149c8 5943 case 1:
d75c135e 5944 check_insn(ctx, ASE_MT);
895c2d04 5945 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5946 rn = "TCStatus";
ead9360e 5947 break;
9c2149c8 5948 case 2:
d75c135e 5949 check_insn(ctx, ASE_MT);
895c2d04 5950 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5951 rn = "TCBind";
ead9360e 5952 break;
9c2149c8 5953 case 3:
d75c135e 5954 check_insn(ctx, ASE_MT);
895c2d04 5955 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5956 rn = "TCRestart";
ead9360e 5957 break;
9c2149c8 5958 case 4:
d75c135e 5959 check_insn(ctx, ASE_MT);
895c2d04 5960 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5961 rn = "TCHalt";
ead9360e 5962 break;
9c2149c8 5963 case 5:
d75c135e 5964 check_insn(ctx, ASE_MT);
895c2d04 5965 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5966 rn = "TCContext";
ead9360e 5967 break;
9c2149c8 5968 case 6:
d75c135e 5969 check_insn(ctx, ASE_MT);
895c2d04 5970 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5971 rn = "TCSchedule";
ead9360e 5972 break;
9c2149c8 5973 case 7:
d75c135e 5974 check_insn(ctx, ASE_MT);
895c2d04 5975 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5976 rn = "TCScheFBack";
ead9360e 5977 break;
9c2149c8
TS
5978 default:
5979 goto die;
5980 }
5981 break;
5982 case 3:
5983 switch (sel) {
5984 case 0:
895c2d04 5985 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5986 rn = "EntryLo1";
5987 break;
9c2149c8
TS
5988 default:
5989 goto die;
876d4b07 5990 }
9c2149c8
TS
5991 break;
5992 case 4:
5993 switch (sel) {
5994 case 0:
895c2d04 5995 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5996 rn = "Context";
5997 break;
9c2149c8 5998 case 1:
895c2d04 5999// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
6000 rn = "ContextConfig";
6001// break;
9c2149c8
TS
6002 default:
6003 goto die;
876d4b07 6004 }
9c2149c8
TS
6005 break;
6006 case 5:
6007 switch (sel) {
6008 case 0:
895c2d04 6009 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6010 rn = "PageMask";
6011 break;
9c2149c8 6012 case 1:
d75c135e 6013 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6014 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6015 rn = "PageGrain";
6016 break;
9c2149c8
TS
6017 default:
6018 goto die;
876d4b07 6019 }
9c2149c8
TS
6020 break;
6021 case 6:
6022 switch (sel) {
6023 case 0:
895c2d04 6024 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6025 rn = "Wired";
6026 break;
9c2149c8 6027 case 1:
d75c135e 6028 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6029 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6030 rn = "SRSConf0";
ead9360e 6031 break;
9c2149c8 6032 case 2:
d75c135e 6033 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6034 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6035 rn = "SRSConf1";
ead9360e 6036 break;
9c2149c8 6037 case 3:
d75c135e 6038 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6039 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6040 rn = "SRSConf2";
ead9360e 6041 break;
9c2149c8 6042 case 4:
d75c135e 6043 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6044 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6045 rn = "SRSConf3";
ead9360e 6046 break;
9c2149c8 6047 case 5:
d75c135e 6048 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6049 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6050 rn = "SRSConf4";
ead9360e 6051 break;
9c2149c8
TS
6052 default:
6053 goto die;
876d4b07 6054 }
9c2149c8
TS
6055 break;
6056 case 7:
6057 switch (sel) {
6058 case 0:
d75c135e 6059 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6060 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
6061 rn = "HWREna";
6062 break;
9c2149c8
TS
6063 default:
6064 goto die;
876d4b07 6065 }
9c2149c8
TS
6066 break;
6067 case 8:
6068 /* ignored */
f0b3f3ae 6069 rn = "BadVAddr";
9c2149c8
TS
6070 break;
6071 case 9:
6072 switch (sel) {
6073 case 0:
895c2d04 6074 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6075 rn = "Count";
6076 break;
876d4b07 6077 /* 6,7 are implementation dependent */
9c2149c8
TS
6078 default:
6079 goto die;
876d4b07
TS
6080 }
6081 /* Stop translation as we may have switched the execution mode */
6082 ctx->bstate = BS_STOP;
9c2149c8
TS
6083 break;
6084 case 10:
6085 switch (sel) {
6086 case 0:
895c2d04 6087 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6088 rn = "EntryHi";
6089 break;
9c2149c8
TS
6090 default:
6091 goto die;
876d4b07 6092 }
9c2149c8
TS
6093 break;
6094 case 11:
6095 switch (sel) {
6096 case 0:
895c2d04 6097 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6098 rn = "Compare";
6099 break;
876d4b07 6100 /* 6,7 are implementation dependent */
9c2149c8
TS
6101 default:
6102 goto die;
876d4b07 6103 }
de9a95f0
AJ
6104 /* Stop translation as we may have switched the execution mode */
6105 ctx->bstate = BS_STOP;
9c2149c8
TS
6106 break;
6107 case 12:
6108 switch (sel) {
6109 case 0:
867abc7e 6110 save_cpu_state(ctx, 1);
895c2d04 6111 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6112 /* BS_STOP isn't good enough here, hflags may have changed. */
6113 gen_save_pc(ctx->pc + 4);
6114 ctx->bstate = BS_EXCP;
2423f660
TS
6115 rn = "Status";
6116 break;
9c2149c8 6117 case 1:
d75c135e 6118 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6119 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6120 /* Stop translation as we may have switched the execution mode */
6121 ctx->bstate = BS_STOP;
2423f660
TS
6122 rn = "IntCtl";
6123 break;
9c2149c8 6124 case 2:
d75c135e 6125 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6126 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx->bstate = BS_STOP;
2423f660
TS
6129 rn = "SRSCtl";
6130 break;
9c2149c8 6131 case 3:
d75c135e 6132 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6133 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6134 /* Stop translation as we may have switched the execution mode */
6135 ctx->bstate = BS_STOP;
2423f660
TS
6136 rn = "SRSMap";
6137 break;
6138 default:
9c2149c8 6139 goto die;
876d4b07 6140 }
9c2149c8
TS
6141 break;
6142 case 13:
6143 switch (sel) {
6144 case 0:
867abc7e 6145 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6146 /* Mark as an IO operation because we may trigger a software
6147 interrupt. */
6148 if (use_icount) {
6149 gen_io_start();
6150 }
895c2d04 6151 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6152 if (use_icount) {
6153 gen_io_end();
6154 }
6155 /* Stop translation as we may have triggered an intetrupt */
6156 ctx->bstate = BS_STOP;
2423f660
TS
6157 rn = "Cause";
6158 break;
9c2149c8
TS
6159 default:
6160 goto die;
876d4b07 6161 }
9c2149c8
TS
6162 break;
6163 case 14:
6164 switch (sel) {
6165 case 0:
7db13fae 6166 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6167 rn = "EPC";
6168 break;
9c2149c8
TS
6169 default:
6170 goto die;
876d4b07 6171 }
9c2149c8
TS
6172 break;
6173 case 15:
6174 switch (sel) {
6175 case 0:
2423f660
TS
6176 /* ignored */
6177 rn = "PRid";
6178 break;
9c2149c8 6179 case 1:
d75c135e 6180 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6181 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6182 rn = "EBase";
6183 break;
9c2149c8
TS
6184 default:
6185 goto die;
876d4b07 6186 }
9c2149c8
TS
6187 break;
6188 case 16:
6189 switch (sel) {
6190 case 0:
895c2d04 6191 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6192 rn = "Config";
2423f660
TS
6193 /* Stop translation as we may have switched the execution mode */
6194 ctx->bstate = BS_STOP;
9c2149c8
TS
6195 break;
6196 case 1:
1fc7bf6e 6197 /* ignored, read only */
9c2149c8
TS
6198 rn = "Config1";
6199 break;
6200 case 2:
895c2d04 6201 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6202 rn = "Config2";
2423f660
TS
6203 /* Stop translation as we may have switched the execution mode */
6204 ctx->bstate = BS_STOP;
9c2149c8
TS
6205 break;
6206 case 3:
2423f660 6207 /* ignored */
9c2149c8
TS
6208 rn = "Config3";
6209 break;
6210 /* 6,7 are implementation dependent */
6211 default:
6212 rn = "Invalid config selector";
6213 goto die;
6214 }
9c2149c8
TS
6215 break;
6216 case 17:
6217 switch (sel) {
6218 case 0:
895c2d04 6219 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6220 rn = "LLAddr";
6221 break;
9c2149c8
TS
6222 default:
6223 goto die;
6224 }
6225 break;
6226 case 18:
6227 switch (sel) {
fd88b6ab 6228 case 0 ... 7:
895c2d04 6229 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6230 rn = "WatchLo";
6231 break;
9c2149c8
TS
6232 default:
6233 goto die;
6234 }
6235 break;
6236 case 19:
6237 switch (sel) {
fd88b6ab 6238 case 0 ... 7:
895c2d04 6239 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6240 rn = "WatchHi";
6241 break;
9c2149c8
TS
6242 default:
6243 goto die;
6244 }
6245 break;
6246 case 20:
6247 switch (sel) {
6248 case 0:
d75c135e 6249 check_insn(ctx, ISA_MIPS3);
895c2d04 6250 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6251 rn = "XContext";
6252 break;
9c2149c8
TS
6253 default:
6254 goto die;
6255 }
6256 break;
6257 case 21:
6258 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6259 switch (sel) {
6260 case 0:
895c2d04 6261 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6262 rn = "Framemask";
6263 break;
9c2149c8
TS
6264 default:
6265 goto die;
6266 }
6267 break;
6268 case 22:
6269 /* ignored */
6270 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6271 break;
9c2149c8
TS
6272 case 23:
6273 switch (sel) {
6274 case 0:
895c2d04 6275 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6276 /* BS_STOP isn't good enough here, hflags may have changed. */
6277 gen_save_pc(ctx->pc + 4);
6278 ctx->bstate = BS_EXCP;
2423f660
TS
6279 rn = "Debug";
6280 break;
9c2149c8 6281 case 1:
895c2d04 6282// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6283 /* Stop translation as we may have switched the execution mode */
6284 ctx->bstate = BS_STOP;
2423f660
TS
6285 rn = "TraceControl";
6286// break;
9c2149c8 6287 case 2:
895c2d04 6288// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6289 /* Stop translation as we may have switched the execution mode */
6290 ctx->bstate = BS_STOP;
2423f660
TS
6291 rn = "TraceControl2";
6292// break;
9c2149c8 6293 case 3:
895c2d04 6294// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6295 /* Stop translation as we may have switched the execution mode */
6296 ctx->bstate = BS_STOP;
2423f660
TS
6297 rn = "UserTraceData";
6298// break;
9c2149c8 6299 case 4:
895c2d04 6300// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6301 /* Stop translation as we may have switched the execution mode */
6302 ctx->bstate = BS_STOP;
2423f660
TS
6303 rn = "TraceBPC";
6304// break;
9c2149c8
TS
6305 default:
6306 goto die;
6307 }
9c2149c8
TS
6308 break;
6309 case 24:
6310 switch (sel) {
6311 case 0:
f1aa6320 6312 /* EJTAG support */
7db13fae 6313 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6314 rn = "DEPC";
6315 break;
9c2149c8
TS
6316 default:
6317 goto die;
6318 }
6319 break;
6320 case 25:
6321 switch (sel) {
6322 case 0:
895c2d04 6323 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6324 rn = "Performance0";
6325 break;
9c2149c8 6326 case 1:
895c2d04 6327// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6328 rn = "Performance1";
6329// break;
9c2149c8 6330 case 2:
895c2d04 6331// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6332 rn = "Performance2";
6333// break;
9c2149c8 6334 case 3:
895c2d04 6335// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6336 rn = "Performance3";
6337// break;
9c2149c8 6338 case 4:
895c2d04 6339// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6340 rn = "Performance4";
6341// break;
9c2149c8 6342 case 5:
895c2d04 6343// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6344 rn = "Performance5";
6345// break;
9c2149c8 6346 case 6:
895c2d04 6347// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6348 rn = "Performance6";
6349// break;
9c2149c8 6350 case 7:
895c2d04 6351// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6352 rn = "Performance7";
6353// break;
9c2149c8
TS
6354 default:
6355 goto die;
6356 }
876d4b07 6357 break;
9c2149c8 6358 case 26:
876d4b07 6359 /* ignored */
9c2149c8 6360 rn = "ECC";
876d4b07 6361 break;
9c2149c8
TS
6362 case 27:
6363 switch (sel) {
6364 case 0 ... 3:
2423f660
TS
6365 /* ignored */
6366 rn = "CacheErr";
6367 break;
9c2149c8
TS
6368 default:
6369 goto die;
6370 }
876d4b07 6371 break;
9c2149c8
TS
6372 case 28:
6373 switch (sel) {
6374 case 0:
6375 case 2:
6376 case 4:
6377 case 6:
895c2d04 6378 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6379 rn = "TagLo";
6380 break;
6381 case 1:
6382 case 3:
6383 case 5:
6384 case 7:
895c2d04 6385 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6386 rn = "DataLo";
6387 break;
6388 default:
6389 goto die;
6390 }
6391 break;
6392 case 29:
6393 switch (sel) {
6394 case 0:
6395 case 2:
6396 case 4:
6397 case 6:
895c2d04 6398 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6399 rn = "TagHi";
6400 break;
6401 case 1:
6402 case 3:
6403 case 5:
6404 case 7:
895c2d04 6405 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6406 rn = "DataHi";
6407 break;
6408 default:
6409 rn = "invalid sel";
6410 goto die;
6411 }
876d4b07 6412 break;
9c2149c8
TS
6413 case 30:
6414 switch (sel) {
6415 case 0:
7db13fae 6416 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6417 rn = "ErrorEPC";
6418 break;
9c2149c8
TS
6419 default:
6420 goto die;
6421 }
6422 break;
6423 case 31:
6424 switch (sel) {
6425 case 0:
f1aa6320 6426 /* EJTAG support */
7db13fae 6427 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6428 rn = "DESAVE";
6429 break;
9c2149c8
TS
6430 default:
6431 goto die;
6432 }
876d4b07
TS
6433 /* Stop translation as we may have switched the execution mode */
6434 ctx->bstate = BS_STOP;
9c2149c8
TS
6435 break;
6436 default:
876d4b07 6437 goto die;
9c2149c8 6438 }
2abf314d 6439 (void)rn; /* avoid a compiler warning */
d12d51d5 6440 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6441 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6442 if (use_icount) {
6443 gen_io_end();
6444 ctx->bstate = BS_STOP;
6445 }
9c2149c8
TS
6446 return;
6447
6448die:
d12d51d5 6449 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6450 generate_exception(ctx, EXCP_RI);
6451}
d26bc211 6452#endif /* TARGET_MIPS64 */
9c2149c8 6453
7db13fae 6454static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6455 int u, int sel, int h)
6456{
6457 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6458 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6459
6460 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6461 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6462 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6463 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6464 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6465 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6466 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6467 else if (u == 0) {
6468 switch (rt) {
5a25ce94
EI
6469 case 1:
6470 switch (sel) {
6471 case 1:
895c2d04 6472 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6473 break;
6474 case 2:
895c2d04 6475 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6476 break;
6477 default:
6478 goto die;
6479 break;
6480 }
6481 break;
ead9360e
TS
6482 case 2:
6483 switch (sel) {
6484 case 1:
895c2d04 6485 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6486 break;
6487 case 2:
895c2d04 6488 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6489 break;
6490 case 3:
895c2d04 6491 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6492 break;
6493 case 4:
895c2d04 6494 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6495 break;
6496 case 5:
895c2d04 6497 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6498 break;
6499 case 6:
895c2d04 6500 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6501 break;
6502 case 7:
895c2d04 6503 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6504 break;
6505 default:
d75c135e 6506 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6507 break;
6508 }
6509 break;
6510 case 10:
6511 switch (sel) {
6512 case 0:
895c2d04 6513 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6514 break;
6515 default:
d75c135e 6516 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6517 break;
6518 }
6519 case 12:
6520 switch (sel) {
6521 case 0:
895c2d04 6522 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6523 break;
6524 default:
d75c135e 6525 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6526 break;
6527 }
5a25ce94
EI
6528 case 13:
6529 switch (sel) {
6530 case 0:
895c2d04 6531 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6532 break;
6533 default:
6534 goto die;
6535 break;
6536 }
6537 break;
6538 case 14:
6539 switch (sel) {
6540 case 0:
895c2d04 6541 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6542 break;
6543 default:
6544 goto die;
6545 break;
6546 }
6547 break;
6548 case 15:
6549 switch (sel) {
6550 case 1:
895c2d04 6551 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6552 break;
6553 default:
6554 goto die;
6555 break;
6556 }
6557 break;
6558 case 16:
6559 switch (sel) {
6560 case 0 ... 7:
895c2d04 6561 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6562 break;
6563 default:
6564 goto die;
6565 break;
6566 }
6567 break;
ead9360e
TS
6568 case 23:
6569 switch (sel) {
6570 case 0:
895c2d04 6571 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6572 break;
6573 default:
d75c135e 6574 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6575 break;
6576 }
6577 break;
6578 default:
d75c135e 6579 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6580 }
6581 } else switch (sel) {
6582 /* GPR registers. */
6583 case 0:
895c2d04 6584 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6585 break;
6586 /* Auxiliary CPU registers */
6587 case 1:
6588 switch (rt) {
6589 case 0:
895c2d04 6590 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6591 break;
6592 case 1:
895c2d04 6593 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6594 break;
6595 case 2:
895c2d04 6596 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6597 break;
6598 case 4:
895c2d04 6599 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6600 break;
6601 case 5:
895c2d04 6602 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6603 break;
6604 case 6:
895c2d04 6605 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6606 break;
6607 case 8:
895c2d04 6608 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6609 break;
6610 case 9:
895c2d04 6611 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6612 break;
6613 case 10:
895c2d04 6614 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6615 break;
6616 case 12:
895c2d04 6617 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6618 break;
6619 case 13:
895c2d04 6620 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6621 break;
6622 case 14:
895c2d04 6623 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6624 break;
6625 case 16:
895c2d04 6626 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6627 break;
6628 default:
6629 goto die;
6630 }
6631 break;
6632 /* Floating point (COP1). */
6633 case 2:
6634 /* XXX: For now we support only a single FPU context. */
6635 if (h == 0) {
a7812ae4 6636 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6637
6638 gen_load_fpr32(fp0, rt);
6639 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6640 tcg_temp_free_i32(fp0);
ead9360e 6641 } else {
a7812ae4 6642 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6643
6644 gen_load_fpr32h(fp0, rt);
6645 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6646 tcg_temp_free_i32(fp0);
ead9360e
TS
6647 }
6648 break;
6649 case 3:
6650 /* XXX: For now we support only a single FPU context. */
895c2d04 6651 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6652 break;
6653 /* COP2: Not implemented. */
6654 case 4:
6655 case 5:
6656 /* fall through */
6657 default:
6658 goto die;
6659 }
d12d51d5 6660 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6661 gen_store_gpr(t0, rd);
6662 tcg_temp_free(t0);
ead9360e
TS
6663 return;
6664
6665die:
1a3fd9c3 6666 tcg_temp_free(t0);
d12d51d5 6667 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6668 generate_exception(ctx, EXCP_RI);
6669}
6670
7db13fae 6671static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6672 int u, int sel, int h)
6673{
6674 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6675 TCGv t0 = tcg_temp_local_new();
ead9360e 6676
1a3fd9c3 6677 gen_load_gpr(t0, rt);
ead9360e 6678 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6679 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6680 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6681 /* NOP */ ;
6682 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6683 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6684 /* NOP */ ;
6685 else if (u == 0) {
6686 switch (rd) {
5a25ce94
EI
6687 case 1:
6688 switch (sel) {
6689 case 1:
895c2d04 6690 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6691 break;
6692 case 2:
895c2d04 6693 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6694 break;
6695 default:
6696 goto die;
6697 break;
6698 }
6699 break;
ead9360e
TS
6700 case 2:
6701 switch (sel) {
6702 case 1:
895c2d04 6703 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6704 break;
6705 case 2:
895c2d04 6706 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6707 break;
6708 case 3:
895c2d04 6709 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6710 break;
6711 case 4:
895c2d04 6712 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6713 break;
6714 case 5:
895c2d04 6715 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6716 break;
6717 case 6:
895c2d04 6718 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6719 break;
6720 case 7:
895c2d04 6721 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6722 break;
6723 default:
d75c135e 6724 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6725 break;
6726 }
6727 break;
6728 case 10:
6729 switch (sel) {
6730 case 0:
895c2d04 6731 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6732 break;
6733 default:
d75c135e 6734 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6735 break;
6736 }
6737 case 12:
6738 switch (sel) {
6739 case 0:
895c2d04 6740 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6741 break;
6742 default:
d75c135e 6743 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6744 break;
6745 }
5a25ce94
EI
6746 case 13:
6747 switch (sel) {
6748 case 0:
895c2d04 6749 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6750 break;
6751 default:
6752 goto die;
6753 break;
6754 }
6755 break;
6756 case 15:
6757 switch (sel) {
6758 case 1:
895c2d04 6759 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6760 break;
6761 default:
6762 goto die;
6763 break;
6764 }
6765 break;
ead9360e
TS
6766 case 23:
6767 switch (sel) {
6768 case 0:
895c2d04 6769 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6770 break;
6771 default:
d75c135e 6772 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6773 break;
6774 }
6775 break;
6776 default:
d75c135e 6777 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6778 }
6779 } else switch (sel) {
6780 /* GPR registers. */
6781 case 0:
895c2d04 6782 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6783 break;
6784 /* Auxiliary CPU registers */
6785 case 1:
6786 switch (rd) {
6787 case 0:
895c2d04 6788 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6789 break;
6790 case 1:
895c2d04 6791 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6792 break;
6793 case 2:
895c2d04 6794 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6795 break;
6796 case 4:
895c2d04 6797 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6798 break;
6799 case 5:
895c2d04 6800 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6801 break;
6802 case 6:
895c2d04 6803 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6804 break;
6805 case 8:
895c2d04 6806 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6807 break;
6808 case 9:
895c2d04 6809 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6810 break;
6811 case 10:
895c2d04 6812 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6813 break;
6814 case 12:
895c2d04 6815 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6816 break;
6817 case 13:
895c2d04 6818 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6819 break;
6820 case 14:
895c2d04 6821 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6822 break;
6823 case 16:
895c2d04 6824 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6825 break;
6826 default:
6827 goto die;
6828 }
6829 break;
6830 /* Floating point (COP1). */
6831 case 2:
6832 /* XXX: For now we support only a single FPU context. */
6833 if (h == 0) {
a7812ae4 6834 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6835
6836 tcg_gen_trunc_tl_i32(fp0, t0);
6837 gen_store_fpr32(fp0, rd);
a7812ae4 6838 tcg_temp_free_i32(fp0);
ead9360e 6839 } else {
a7812ae4 6840 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6841
6842 tcg_gen_trunc_tl_i32(fp0, t0);
6843 gen_store_fpr32h(fp0, rd);
a7812ae4 6844 tcg_temp_free_i32(fp0);
ead9360e
TS
6845 }
6846 break;
6847 case 3:
6848 /* XXX: For now we support only a single FPU context. */
895c2d04 6849 gen_helper_0e1i(ctc1, t0, rd);
ead9360e
TS
6850 break;
6851 /* COP2: Not implemented. */
6852 case 4:
6853 case 5:
6854 /* fall through */
6855 default:
6856 goto die;
6857 }
d12d51d5 6858 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6859 tcg_temp_free(t0);
ead9360e
TS
6860 return;
6861
6862die:
1a3fd9c3 6863 tcg_temp_free(t0);
d12d51d5 6864 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6865 generate_exception(ctx, EXCP_RI);
6866}
6867
7db13fae 6868static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6869{
287c4b84 6870 const char *opn = "ldst";
6af0bf9c 6871
2e15497c 6872 check_cp0_enabled(ctx);
6af0bf9c
FB
6873 switch (opc) {
6874 case OPC_MFC0:
6875 if (rt == 0) {
ead9360e 6876 /* Treat as NOP. */
6af0bf9c
FB
6877 return;
6878 }
d75c135e 6879 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6880 opn = "mfc0";
6881 break;
6882 case OPC_MTC0:
1a3fd9c3 6883 {
1fc7bf6e 6884 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6885
6886 gen_load_gpr(t0, rt);
d75c135e 6887 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6888 tcg_temp_free(t0);
6889 }
6af0bf9c
FB
6890 opn = "mtc0";
6891 break;
d26bc211 6892#if defined(TARGET_MIPS64)
9c2149c8 6893 case OPC_DMFC0:
d75c135e 6894 check_insn(ctx, ISA_MIPS3);
9c2149c8 6895 if (rt == 0) {
ead9360e 6896 /* Treat as NOP. */
9c2149c8
TS
6897 return;
6898 }
d75c135e 6899 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6900 opn = "dmfc0";
6901 break;
6902 case OPC_DMTC0:
d75c135e 6903 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 6904 {
1fc7bf6e 6905 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6906
6907 gen_load_gpr(t0, rt);
d75c135e 6908 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6909 tcg_temp_free(t0);
6910 }
9c2149c8
TS
6911 opn = "dmtc0";
6912 break;
534ce69f 6913#endif
ead9360e 6914 case OPC_MFTR:
d75c135e 6915 check_insn(ctx, ASE_MT);
ead9360e
TS
6916 if (rd == 0) {
6917 /* Treat as NOP. */
6918 return;
6919 }
6c5c1e20 6920 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6921 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6922 opn = "mftr";
6923 break;
6924 case OPC_MTTR:
d75c135e 6925 check_insn(ctx, ASE_MT);
6c5c1e20 6926 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6927 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6928 opn = "mttr";
6929 break;
6af0bf9c 6930 case OPC_TLBWI:
6af0bf9c 6931 opn = "tlbwi";
c01fccd2 6932 if (!env->tlb->helper_tlbwi)
29929e34 6933 goto die;
895c2d04 6934 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6935 break;
6936 case OPC_TLBWR:
6af0bf9c 6937 opn = "tlbwr";
c01fccd2 6938 if (!env->tlb->helper_tlbwr)
29929e34 6939 goto die;
895c2d04 6940 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6941 break;
6942 case OPC_TLBP:
6af0bf9c 6943 opn = "tlbp";
c01fccd2 6944 if (!env->tlb->helper_tlbp)
29929e34 6945 goto die;
895c2d04 6946 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6947 break;
6948 case OPC_TLBR:
6af0bf9c 6949 opn = "tlbr";
c01fccd2 6950 if (!env->tlb->helper_tlbr)
29929e34 6951 goto die;
895c2d04 6952 gen_helper_tlbr(cpu_env);
6af0bf9c 6953 break;
6af0bf9c
FB
6954 case OPC_ERET:
6955 opn = "eret";
d75c135e 6956 check_insn(ctx, ISA_MIPS2);
895c2d04 6957 gen_helper_eret(cpu_env);
6af0bf9c
FB
6958 ctx->bstate = BS_EXCP;
6959 break;
6960 case OPC_DERET:
6961 opn = "deret";
d75c135e 6962 check_insn(ctx, ISA_MIPS32);
6af0bf9c 6963 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6964 MIPS_INVAL(opn);
6af0bf9c
FB
6965 generate_exception(ctx, EXCP_RI);
6966 } else {
895c2d04 6967 gen_helper_deret(cpu_env);
6af0bf9c
FB
6968 ctx->bstate = BS_EXCP;
6969 }
6970 break;
4ad40f36
FB
6971 case OPC_WAIT:
6972 opn = "wait";
d75c135e 6973 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6974 /* If we get an exception, we want to restart at next instruction */
6975 ctx->pc += 4;
6976 save_cpu_state(ctx, 1);
6977 ctx->pc -= 4;
895c2d04 6978 gen_helper_wait(cpu_env);
4ad40f36
FB
6979 ctx->bstate = BS_EXCP;
6980 break;
6af0bf9c 6981 default:
29929e34 6982 die:
923617a3 6983 MIPS_INVAL(opn);
6af0bf9c
FB
6984 generate_exception(ctx, EXCP_RI);
6985 return;
6986 }
2abf314d 6987 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
6988 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6989}
f1aa6320 6990#endif /* !CONFIG_USER_ONLY */
6af0bf9c 6991
6ea83fed 6992/* CP1 Branches (before delay slot) */
d75c135e
AJ
6993static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6994 int32_t cc, int32_t offset)
6ea83fed
FB
6995{
6996 target_ulong btarget;
923617a3 6997 const char *opn = "cp1 cond branch";
a7812ae4 6998 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 6999
e189e748 7000 if (cc != 0)
d75c135e 7001 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7002
6ea83fed
FB
7003 btarget = ctx->pc + 4 + offset;
7004
7a387fff
TS
7005 switch (op) {
7006 case OPC_BC1F:
d94536f4
AJ
7007 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7008 tcg_gen_not_i32(t0, t0);
7009 tcg_gen_andi_i32(t0, t0, 1);
7010 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7011 opn = "bc1f";
6ea83fed 7012 goto not_likely;
7a387fff 7013 case OPC_BC1FL:
d94536f4
AJ
7014 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7015 tcg_gen_not_i32(t0, t0);
7016 tcg_gen_andi_i32(t0, t0, 1);
7017 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7018 opn = "bc1fl";
6ea83fed 7019 goto likely;
7a387fff 7020 case OPC_BC1T:
d94536f4
AJ
7021 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7022 tcg_gen_andi_i32(t0, t0, 1);
7023 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7024 opn = "bc1t";
5a5012ec 7025 goto not_likely;
7a387fff 7026 case OPC_BC1TL:
d94536f4
AJ
7027 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7028 tcg_gen_andi_i32(t0, t0, 1);
7029 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7030 opn = "bc1tl";
6ea83fed
FB
7031 likely:
7032 ctx->hflags |= MIPS_HFLAG_BL;
7033 break;
5a5012ec 7034 case OPC_BC1FANY2:
a16336e4 7035 {
d94536f4
AJ
7036 TCGv_i32 t1 = tcg_temp_new_i32();
7037 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7038 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7039 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7040 tcg_temp_free_i32(t1);
d94536f4
AJ
7041 tcg_gen_andi_i32(t0, t0, 1);
7042 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7043 }
fd4a04eb 7044 opn = "bc1any2f";
5a5012ec
TS
7045 goto not_likely;
7046 case OPC_BC1TANY2:
a16336e4 7047 {
d94536f4
AJ
7048 TCGv_i32 t1 = tcg_temp_new_i32();
7049 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7050 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7051 tcg_gen_or_i32(t0, t0, t1);
7052 tcg_temp_free_i32(t1);
7053 tcg_gen_andi_i32(t0, t0, 1);
7054 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7055 }
fd4a04eb 7056 opn = "bc1any2t";
5a5012ec
TS
7057 goto not_likely;
7058 case OPC_BC1FANY4:
a16336e4 7059 {
d94536f4
AJ
7060 TCGv_i32 t1 = tcg_temp_new_i32();
7061 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7062 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7063 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7064 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7065 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7066 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7067 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7068 tcg_temp_free_i32(t1);
d94536f4
AJ
7069 tcg_gen_andi_i32(t0, t0, 1);
7070 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7071 }
fd4a04eb 7072 opn = "bc1any4f";
5a5012ec
TS
7073 goto not_likely;
7074 case OPC_BC1TANY4:
a16336e4 7075 {
d94536f4
AJ
7076 TCGv_i32 t1 = tcg_temp_new_i32();
7077 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7078 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7079 tcg_gen_or_i32(t0, t0, t1);
7080 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7081 tcg_gen_or_i32(t0, t0, t1);
7082 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7083 tcg_gen_or_i32(t0, t0, t1);
7084 tcg_temp_free_i32(t1);
7085 tcg_gen_andi_i32(t0, t0, 1);
7086 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7087 }
fd4a04eb 7088 opn = "bc1any4t";
5a5012ec
TS
7089 not_likely:
7090 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7091 break;
7092 default:
923617a3 7093 MIPS_INVAL(opn);
e397ee33 7094 generate_exception (ctx, EXCP_RI);
6c5c1e20 7095 goto out;
6ea83fed 7096 }
2abf314d 7097 (void)opn; /* avoid a compiler warning */
923617a3 7098 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7099 ctx->hflags, btarget);
7100 ctx->btarget = btarget;
6c5c1e20
TS
7101
7102 out:
a7812ae4 7103 tcg_temp_free_i32(t0);
6ea83fed
FB
7104}
7105
6af0bf9c 7106/* Coprocessor 1 (FPU) */
5a5012ec 7107
5a5012ec
TS
7108#define FOP(func, fmt) (((fmt) << 21) | (func))
7109
bf4120ad
NF
7110enum fopcode {
7111 OPC_ADD_S = FOP(0, FMT_S),
7112 OPC_SUB_S = FOP(1, FMT_S),
7113 OPC_MUL_S = FOP(2, FMT_S),
7114 OPC_DIV_S = FOP(3, FMT_S),
7115 OPC_SQRT_S = FOP(4, FMT_S),
7116 OPC_ABS_S = FOP(5, FMT_S),
7117 OPC_MOV_S = FOP(6, FMT_S),
7118 OPC_NEG_S = FOP(7, FMT_S),
7119 OPC_ROUND_L_S = FOP(8, FMT_S),
7120 OPC_TRUNC_L_S = FOP(9, FMT_S),
7121 OPC_CEIL_L_S = FOP(10, FMT_S),
7122 OPC_FLOOR_L_S = FOP(11, FMT_S),
7123 OPC_ROUND_W_S = FOP(12, FMT_S),
7124 OPC_TRUNC_W_S = FOP(13, FMT_S),
7125 OPC_CEIL_W_S = FOP(14, FMT_S),
7126 OPC_FLOOR_W_S = FOP(15, FMT_S),
7127 OPC_MOVCF_S = FOP(17, FMT_S),
7128 OPC_MOVZ_S = FOP(18, FMT_S),
7129 OPC_MOVN_S = FOP(19, FMT_S),
7130 OPC_RECIP_S = FOP(21, FMT_S),
7131 OPC_RSQRT_S = FOP(22, FMT_S),
7132 OPC_RECIP2_S = FOP(28, FMT_S),
7133 OPC_RECIP1_S = FOP(29, FMT_S),
7134 OPC_RSQRT1_S = FOP(30, FMT_S),
7135 OPC_RSQRT2_S = FOP(31, FMT_S),
7136 OPC_CVT_D_S = FOP(33, FMT_S),
7137 OPC_CVT_W_S = FOP(36, FMT_S),
7138 OPC_CVT_L_S = FOP(37, FMT_S),
7139 OPC_CVT_PS_S = FOP(38, FMT_S),
7140 OPC_CMP_F_S = FOP (48, FMT_S),
7141 OPC_CMP_UN_S = FOP (49, FMT_S),
7142 OPC_CMP_EQ_S = FOP (50, FMT_S),
7143 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7144 OPC_CMP_OLT_S = FOP (52, FMT_S),
7145 OPC_CMP_ULT_S = FOP (53, FMT_S),
7146 OPC_CMP_OLE_S = FOP (54, FMT_S),
7147 OPC_CMP_ULE_S = FOP (55, FMT_S),
7148 OPC_CMP_SF_S = FOP (56, FMT_S),
7149 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7150 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7151 OPC_CMP_NGL_S = FOP (59, FMT_S),
7152 OPC_CMP_LT_S = FOP (60, FMT_S),
7153 OPC_CMP_NGE_S = FOP (61, FMT_S),
7154 OPC_CMP_LE_S = FOP (62, FMT_S),
7155 OPC_CMP_NGT_S = FOP (63, FMT_S),
7156
7157 OPC_ADD_D = FOP(0, FMT_D),
7158 OPC_SUB_D = FOP(1, FMT_D),
7159 OPC_MUL_D = FOP(2, FMT_D),
7160 OPC_DIV_D = FOP(3, FMT_D),
7161 OPC_SQRT_D = FOP(4, FMT_D),
7162 OPC_ABS_D = FOP(5, FMT_D),
7163 OPC_MOV_D = FOP(6, FMT_D),
7164 OPC_NEG_D = FOP(7, FMT_D),
7165 OPC_ROUND_L_D = FOP(8, FMT_D),
7166 OPC_TRUNC_L_D = FOP(9, FMT_D),
7167 OPC_CEIL_L_D = FOP(10, FMT_D),
7168 OPC_FLOOR_L_D = FOP(11, FMT_D),
7169 OPC_ROUND_W_D = FOP(12, FMT_D),
7170 OPC_TRUNC_W_D = FOP(13, FMT_D),
7171 OPC_CEIL_W_D = FOP(14, FMT_D),
7172 OPC_FLOOR_W_D = FOP(15, FMT_D),
7173 OPC_MOVCF_D = FOP(17, FMT_D),
7174 OPC_MOVZ_D = FOP(18, FMT_D),
7175 OPC_MOVN_D = FOP(19, FMT_D),
7176 OPC_RECIP_D = FOP(21, FMT_D),
7177 OPC_RSQRT_D = FOP(22, FMT_D),
7178 OPC_RECIP2_D = FOP(28, FMT_D),
7179 OPC_RECIP1_D = FOP(29, FMT_D),
7180 OPC_RSQRT1_D = FOP(30, FMT_D),
7181 OPC_RSQRT2_D = FOP(31, FMT_D),
7182 OPC_CVT_S_D = FOP(32, FMT_D),
7183 OPC_CVT_W_D = FOP(36, FMT_D),
7184 OPC_CVT_L_D = FOP(37, FMT_D),
7185 OPC_CMP_F_D = FOP (48, FMT_D),
7186 OPC_CMP_UN_D = FOP (49, FMT_D),
7187 OPC_CMP_EQ_D = FOP (50, FMT_D),
7188 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7189 OPC_CMP_OLT_D = FOP (52, FMT_D),
7190 OPC_CMP_ULT_D = FOP (53, FMT_D),
7191 OPC_CMP_OLE_D = FOP (54, FMT_D),
7192 OPC_CMP_ULE_D = FOP (55, FMT_D),
7193 OPC_CMP_SF_D = FOP (56, FMT_D),
7194 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7195 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7196 OPC_CMP_NGL_D = FOP (59, FMT_D),
7197 OPC_CMP_LT_D = FOP (60, FMT_D),
7198 OPC_CMP_NGE_D = FOP (61, FMT_D),
7199 OPC_CMP_LE_D = FOP (62, FMT_D),
7200 OPC_CMP_NGT_D = FOP (63, FMT_D),
7201
7202 OPC_CVT_S_W = FOP(32, FMT_W),
7203 OPC_CVT_D_W = FOP(33, FMT_W),
7204 OPC_CVT_S_L = FOP(32, FMT_L),
7205 OPC_CVT_D_L = FOP(33, FMT_L),
7206 OPC_CVT_PS_PW = FOP(38, FMT_W),
7207
7208 OPC_ADD_PS = FOP(0, FMT_PS),
7209 OPC_SUB_PS = FOP(1, FMT_PS),
7210 OPC_MUL_PS = FOP(2, FMT_PS),
7211 OPC_DIV_PS = FOP(3, FMT_PS),
7212 OPC_ABS_PS = FOP(5, FMT_PS),
7213 OPC_MOV_PS = FOP(6, FMT_PS),
7214 OPC_NEG_PS = FOP(7, FMT_PS),
7215 OPC_MOVCF_PS = FOP(17, FMT_PS),
7216 OPC_MOVZ_PS = FOP(18, FMT_PS),
7217 OPC_MOVN_PS = FOP(19, FMT_PS),
7218 OPC_ADDR_PS = FOP(24, FMT_PS),
7219 OPC_MULR_PS = FOP(26, FMT_PS),
7220 OPC_RECIP2_PS = FOP(28, FMT_PS),
7221 OPC_RECIP1_PS = FOP(29, FMT_PS),
7222 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7223 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7224
7225 OPC_CVT_S_PU = FOP(32, FMT_PS),
7226 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7227 OPC_CVT_S_PL = FOP(40, FMT_PS),
7228 OPC_PLL_PS = FOP(44, FMT_PS),
7229 OPC_PLU_PS = FOP(45, FMT_PS),
7230 OPC_PUL_PS = FOP(46, FMT_PS),
7231 OPC_PUU_PS = FOP(47, FMT_PS),
7232 OPC_CMP_F_PS = FOP (48, FMT_PS),
7233 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7234 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7235 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7236 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7237 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7238 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7239 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7240 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7241 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7242 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7243 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7244 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7245 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7246 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7247 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7248};
7249
7a387fff 7250static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7251{
923617a3 7252 const char *opn = "cp1 move";
72c3a3ee 7253 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7254
7255 switch (opc) {
7256 case OPC_MFC1:
b6d96bed 7257 {
a7812ae4 7258 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7259
7260 gen_load_fpr32(fp0, fs);
7261 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7262 tcg_temp_free_i32(fp0);
6958549d 7263 }
6c5c1e20 7264 gen_store_gpr(t0, rt);
6ea83fed
FB
7265 opn = "mfc1";
7266 break;
7267 case OPC_MTC1:
6c5c1e20 7268 gen_load_gpr(t0, rt);
b6d96bed 7269 {
a7812ae4 7270 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7271
7272 tcg_gen_trunc_tl_i32(fp0, t0);
7273 gen_store_fpr32(fp0, fs);
a7812ae4 7274 tcg_temp_free_i32(fp0);
6958549d 7275 }
6ea83fed
FB
7276 opn = "mtc1";
7277 break;
7278 case OPC_CFC1:
895c2d04 7279 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7280 gen_store_gpr(t0, rt);
6ea83fed
FB
7281 opn = "cfc1";
7282 break;
7283 case OPC_CTC1:
6c5c1e20 7284 gen_load_gpr(t0, rt);
895c2d04 7285 gen_helper_0e1i(ctc1, t0, fs);
6ea83fed
FB
7286 opn = "ctc1";
7287 break;
72c3a3ee 7288#if defined(TARGET_MIPS64)
9c2149c8 7289 case OPC_DMFC1:
72c3a3ee 7290 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7291 gen_store_gpr(t0, rt);
5a5012ec
TS
7292 opn = "dmfc1";
7293 break;
9c2149c8 7294 case OPC_DMTC1:
6c5c1e20 7295 gen_load_gpr(t0, rt);
72c3a3ee 7296 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7297 opn = "dmtc1";
7298 break;
72c3a3ee 7299#endif
5a5012ec 7300 case OPC_MFHC1:
b6d96bed 7301 {
a7812ae4 7302 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7303
7304 gen_load_fpr32h(fp0, fs);
7305 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7306 tcg_temp_free_i32(fp0);
6958549d 7307 }
6c5c1e20 7308 gen_store_gpr(t0, rt);
5a5012ec
TS
7309 opn = "mfhc1";
7310 break;
7311 case OPC_MTHC1:
6c5c1e20 7312 gen_load_gpr(t0, rt);
b6d96bed 7313 {
a7812ae4 7314 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7315
7316 tcg_gen_trunc_tl_i32(fp0, t0);
7317 gen_store_fpr32h(fp0, fs);
a7812ae4 7318 tcg_temp_free_i32(fp0);
6958549d 7319 }
5a5012ec
TS
7320 opn = "mthc1";
7321 break;
6ea83fed 7322 default:
923617a3 7323 MIPS_INVAL(opn);
e397ee33 7324 generate_exception (ctx, EXCP_RI);
6c5c1e20 7325 goto out;
6ea83fed 7326 }
2abf314d 7327 (void)opn; /* avoid a compiler warning */
6ea83fed 7328 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7329
7330 out:
7331 tcg_temp_free(t0);
6ea83fed
FB
7332}
7333
5a5012ec
TS
7334static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7335{
af58f9ca 7336 int l1;
e214b9bb 7337 TCGCond cond;
af58f9ca
AJ
7338 TCGv_i32 t0;
7339
7340 if (rd == 0) {
7341 /* Treat as NOP. */
7342 return;
7343 }
6ea83fed 7344
e214b9bb 7345 if (tf)
e214b9bb 7346 cond = TCG_COND_EQ;
27848470
TS
7347 else
7348 cond = TCG_COND_NE;
7349
af58f9ca
AJ
7350 l1 = gen_new_label();
7351 t0 = tcg_temp_new_i32();
fa31af0e 7352 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7353 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7354 tcg_temp_free_i32(t0);
af58f9ca
AJ
7355 if (rs == 0) {
7356 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7357 } else {
7358 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7359 }
e214b9bb 7360 gen_set_label(l1);
5a5012ec
TS
7361}
7362
b6d96bed 7363static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7364{
a16336e4 7365 int cond;
cbc37b28 7366 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7367 int l1 = gen_new_label();
7368
a16336e4
TS
7369 if (tf)
7370 cond = TCG_COND_EQ;
7371 else
7372 cond = TCG_COND_NE;
7373
fa31af0e 7374 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7375 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7376 gen_load_fpr32(t0, fs);
7377 gen_store_fpr32(t0, fd);
a16336e4 7378 gen_set_label(l1);
cbc37b28 7379 tcg_temp_free_i32(t0);
5a5012ec 7380}
a16336e4 7381
b6d96bed 7382static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7383{
a16336e4 7384 int cond;
cbc37b28
AJ
7385 TCGv_i32 t0 = tcg_temp_new_i32();
7386 TCGv_i64 fp0;
a16336e4
TS
7387 int l1 = gen_new_label();
7388
a16336e4
TS
7389 if (tf)
7390 cond = TCG_COND_EQ;
7391 else
7392 cond = TCG_COND_NE;
7393
fa31af0e 7394 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7395 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7396 tcg_temp_free_i32(t0);
11f94258 7397 fp0 = tcg_temp_new_i64();
9bf3eb2c 7398 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7399 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7400 tcg_temp_free_i64(fp0);
cbc37b28 7401 gen_set_label(l1);
a16336e4
TS
7402}
7403
b6d96bed 7404static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
a16336e4
TS
7405{
7406 int cond;
cbc37b28 7407 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7408 int l1 = gen_new_label();
7409 int l2 = gen_new_label();
7410
7411 if (tf)
7412 cond = TCG_COND_EQ;
7413 else
7414 cond = TCG_COND_NE;
7415
fa31af0e 7416 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7417 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7418 gen_load_fpr32(t0, fs);
7419 gen_store_fpr32(t0, fd);
a16336e4 7420 gen_set_label(l1);
9bf3eb2c 7421
fa31af0e 7422 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28
AJ
7423 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7424 gen_load_fpr32h(t0, fs);
7425 gen_store_fpr32h(t0, fd);
52a0e9eb 7426 tcg_temp_free_i32(t0);
a16336e4 7427 gen_set_label(l2);
a16336e4
TS
7428}
7429
6ea83fed 7430
bf4120ad 7431static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7432 int ft, int fs, int fd, int cc)
6ea83fed 7433{
923617a3 7434 const char *opn = "farith";
6ea83fed
FB
7435 const char *condnames[] = {
7436 "c.f",
7437 "c.un",
7438 "c.eq",
7439 "c.ueq",
7440 "c.olt",
7441 "c.ult",
7442 "c.ole",
7443 "c.ule",
7444 "c.sf",
7445 "c.ngle",
7446 "c.seq",
7447 "c.ngl",
7448 "c.lt",
7449 "c.nge",
7450 "c.le",
7451 "c.ngt",
7452 };
5a1e8ffb
TS
7453 const char *condnames_abs[] = {
7454 "cabs.f",
7455 "cabs.un",
7456 "cabs.eq",
7457 "cabs.ueq",
7458 "cabs.olt",
7459 "cabs.ult",
7460 "cabs.ole",
7461 "cabs.ule",
7462 "cabs.sf",
7463 "cabs.ngle",
7464 "cabs.seq",
7465 "cabs.ngl",
7466 "cabs.lt",
7467 "cabs.nge",
7468 "cabs.le",
7469 "cabs.ngt",
7470 };
7471 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7472 uint32_t func = ctx->opcode & 0x3f;
7473
bf4120ad
NF
7474 switch (op1) {
7475 case OPC_ADD_S:
b6d96bed 7476 {
a7812ae4
PB
7477 TCGv_i32 fp0 = tcg_temp_new_i32();
7478 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7479
7480 gen_load_fpr32(fp0, fs);
7481 gen_load_fpr32(fp1, ft);
895c2d04 7482 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7483 tcg_temp_free_i32(fp1);
b6d96bed 7484 gen_store_fpr32(fp0, fd);
a7812ae4 7485 tcg_temp_free_i32(fp0);
b6d96bed 7486 }
5a5012ec 7487 opn = "add.s";
5a1e8ffb 7488 optype = BINOP;
5a5012ec 7489 break;
bf4120ad 7490 case OPC_SUB_S:
b6d96bed 7491 {
a7812ae4
PB
7492 TCGv_i32 fp0 = tcg_temp_new_i32();
7493 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7494
7495 gen_load_fpr32(fp0, fs);
7496 gen_load_fpr32(fp1, ft);
895c2d04 7497 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7498 tcg_temp_free_i32(fp1);
b6d96bed 7499 gen_store_fpr32(fp0, fd);
a7812ae4 7500 tcg_temp_free_i32(fp0);
b6d96bed 7501 }
5a5012ec 7502 opn = "sub.s";
5a1e8ffb 7503 optype = BINOP;
5a5012ec 7504 break;
bf4120ad 7505 case OPC_MUL_S:
b6d96bed 7506 {
a7812ae4
PB
7507 TCGv_i32 fp0 = tcg_temp_new_i32();
7508 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7509
7510 gen_load_fpr32(fp0, fs);
7511 gen_load_fpr32(fp1, ft);
895c2d04 7512 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7513 tcg_temp_free_i32(fp1);
b6d96bed 7514 gen_store_fpr32(fp0, fd);
a7812ae4 7515 tcg_temp_free_i32(fp0);
b6d96bed 7516 }
5a5012ec 7517 opn = "mul.s";
5a1e8ffb 7518 optype = BINOP;
5a5012ec 7519 break;
bf4120ad 7520 case OPC_DIV_S:
b6d96bed 7521 {
a7812ae4
PB
7522 TCGv_i32 fp0 = tcg_temp_new_i32();
7523 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7524
7525 gen_load_fpr32(fp0, fs);
7526 gen_load_fpr32(fp1, ft);
895c2d04 7527 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7528 tcg_temp_free_i32(fp1);
b6d96bed 7529 gen_store_fpr32(fp0, fd);
a7812ae4 7530 tcg_temp_free_i32(fp0);
b6d96bed 7531 }
5a5012ec 7532 opn = "div.s";
5a1e8ffb 7533 optype = BINOP;
5a5012ec 7534 break;
bf4120ad 7535 case OPC_SQRT_S:
b6d96bed 7536 {
a7812ae4 7537 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7538
7539 gen_load_fpr32(fp0, fs);
895c2d04 7540 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7541 gen_store_fpr32(fp0, fd);
a7812ae4 7542 tcg_temp_free_i32(fp0);
b6d96bed 7543 }
5a5012ec
TS
7544 opn = "sqrt.s";
7545 break;
bf4120ad 7546 case OPC_ABS_S:
b6d96bed 7547 {
a7812ae4 7548 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7549
7550 gen_load_fpr32(fp0, fs);
a7812ae4 7551 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7552 gen_store_fpr32(fp0, fd);
a7812ae4 7553 tcg_temp_free_i32(fp0);
b6d96bed 7554 }
5a5012ec
TS
7555 opn = "abs.s";
7556 break;
bf4120ad 7557 case OPC_MOV_S:
b6d96bed 7558 {
a7812ae4 7559 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7560
7561 gen_load_fpr32(fp0, fs);
7562 gen_store_fpr32(fp0, fd);
a7812ae4 7563 tcg_temp_free_i32(fp0);
b6d96bed 7564 }
5a5012ec
TS
7565 opn = "mov.s";
7566 break;
bf4120ad 7567 case OPC_NEG_S:
b6d96bed 7568 {
a7812ae4 7569 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7570
7571 gen_load_fpr32(fp0, fs);
a7812ae4 7572 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7573 gen_store_fpr32(fp0, fd);
a7812ae4 7574 tcg_temp_free_i32(fp0);
b6d96bed 7575 }
5a5012ec
TS
7576 opn = "neg.s";
7577 break;
bf4120ad 7578 case OPC_ROUND_L_S:
5e755519 7579 check_cp1_64bitmode(ctx);
b6d96bed 7580 {
a7812ae4
PB
7581 TCGv_i32 fp32 = tcg_temp_new_i32();
7582 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7583
7584 gen_load_fpr32(fp32, fs);
895c2d04 7585 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7586 tcg_temp_free_i32(fp32);
b6d96bed 7587 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7588 tcg_temp_free_i64(fp64);
b6d96bed 7589 }
5a5012ec
TS
7590 opn = "round.l.s";
7591 break;
bf4120ad 7592 case OPC_TRUNC_L_S:
5e755519 7593 check_cp1_64bitmode(ctx);
b6d96bed 7594 {
a7812ae4
PB
7595 TCGv_i32 fp32 = tcg_temp_new_i32();
7596 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7597
7598 gen_load_fpr32(fp32, fs);
895c2d04 7599 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7600 tcg_temp_free_i32(fp32);
b6d96bed 7601 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7602 tcg_temp_free_i64(fp64);
b6d96bed 7603 }
5a5012ec
TS
7604 opn = "trunc.l.s";
7605 break;
bf4120ad 7606 case OPC_CEIL_L_S:
5e755519 7607 check_cp1_64bitmode(ctx);
b6d96bed 7608 {
a7812ae4
PB
7609 TCGv_i32 fp32 = tcg_temp_new_i32();
7610 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7611
7612 gen_load_fpr32(fp32, fs);
895c2d04 7613 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7614 tcg_temp_free_i32(fp32);
b6d96bed 7615 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7616 tcg_temp_free_i64(fp64);
b6d96bed 7617 }
5a5012ec
TS
7618 opn = "ceil.l.s";
7619 break;
bf4120ad 7620 case OPC_FLOOR_L_S:
5e755519 7621 check_cp1_64bitmode(ctx);
b6d96bed 7622 {
a7812ae4
PB
7623 TCGv_i32 fp32 = tcg_temp_new_i32();
7624 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7625
7626 gen_load_fpr32(fp32, fs);
895c2d04 7627 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7628 tcg_temp_free_i32(fp32);
b6d96bed 7629 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7630 tcg_temp_free_i64(fp64);
b6d96bed 7631 }
5a5012ec
TS
7632 opn = "floor.l.s";
7633 break;
bf4120ad 7634 case OPC_ROUND_W_S:
b6d96bed 7635 {
a7812ae4 7636 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7637
7638 gen_load_fpr32(fp0, fs);
895c2d04 7639 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7640 gen_store_fpr32(fp0, fd);
a7812ae4 7641 tcg_temp_free_i32(fp0);
b6d96bed 7642 }
5a5012ec
TS
7643 opn = "round.w.s";
7644 break;
bf4120ad 7645 case OPC_TRUNC_W_S:
b6d96bed 7646 {
a7812ae4 7647 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7648
7649 gen_load_fpr32(fp0, fs);
895c2d04 7650 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7651 gen_store_fpr32(fp0, fd);
a7812ae4 7652 tcg_temp_free_i32(fp0);
b6d96bed 7653 }
5a5012ec
TS
7654 opn = "trunc.w.s";
7655 break;
bf4120ad 7656 case OPC_CEIL_W_S:
b6d96bed 7657 {
a7812ae4 7658 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7659
7660 gen_load_fpr32(fp0, fs);
895c2d04 7661 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7662 gen_store_fpr32(fp0, fd);
a7812ae4 7663 tcg_temp_free_i32(fp0);
b6d96bed 7664 }
5a5012ec
TS
7665 opn = "ceil.w.s";
7666 break;
bf4120ad 7667 case OPC_FLOOR_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_floorw_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 = "floor.w.s";
7677 break;
bf4120ad 7678 case OPC_MOVCF_S:
b6d96bed 7679 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7680 opn = "movcf.s";
7681 break;
bf4120ad 7682 case OPC_MOVZ_S:
a16336e4
TS
7683 {
7684 int l1 = gen_new_label();
c9297f4d 7685 TCGv_i32 fp0;
a16336e4 7686
c9297f4d
AJ
7687 if (ft != 0) {
7688 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7689 }
7690 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7691 gen_load_fpr32(fp0, fs);
7692 gen_store_fpr32(fp0, fd);
a7812ae4 7693 tcg_temp_free_i32(fp0);
a16336e4
TS
7694 gen_set_label(l1);
7695 }
5a5012ec
TS
7696 opn = "movz.s";
7697 break;
bf4120ad 7698 case OPC_MOVN_S:
a16336e4
TS
7699 {
7700 int l1 = gen_new_label();
c9297f4d
AJ
7701 TCGv_i32 fp0;
7702
7703 if (ft != 0) {
7704 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7705 fp0 = tcg_temp_new_i32();
7706 gen_load_fpr32(fp0, fs);
7707 gen_store_fpr32(fp0, fd);
7708 tcg_temp_free_i32(fp0);
7709 gen_set_label(l1);
7710 }
a16336e4 7711 }
5a5012ec
TS
7712 opn = "movn.s";
7713 break;
bf4120ad 7714 case OPC_RECIP_S:
b8aa4598 7715 check_cop1x(ctx);
b6d96bed 7716 {
a7812ae4 7717 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7718
7719 gen_load_fpr32(fp0, fs);
895c2d04 7720 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 7721 gen_store_fpr32(fp0, fd);
a7812ae4 7722 tcg_temp_free_i32(fp0);
b6d96bed 7723 }
57fa1fb3
TS
7724 opn = "recip.s";
7725 break;
bf4120ad 7726 case OPC_RSQRT_S:
b8aa4598 7727 check_cop1x(ctx);
b6d96bed 7728 {
a7812ae4 7729 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7730
7731 gen_load_fpr32(fp0, fs);
895c2d04 7732 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7733 gen_store_fpr32(fp0, fd);
a7812ae4 7734 tcg_temp_free_i32(fp0);
b6d96bed 7735 }
57fa1fb3
TS
7736 opn = "rsqrt.s";
7737 break;
bf4120ad 7738 case OPC_RECIP2_S:
5e755519 7739 check_cp1_64bitmode(ctx);
b6d96bed 7740 {
a7812ae4
PB
7741 TCGv_i32 fp0 = tcg_temp_new_i32();
7742 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7743
7744 gen_load_fpr32(fp0, fs);
d22d7289 7745 gen_load_fpr32(fp1, ft);
895c2d04 7746 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7747 tcg_temp_free_i32(fp1);
b6d96bed 7748 gen_store_fpr32(fp0, fd);
a7812ae4 7749 tcg_temp_free_i32(fp0);
b6d96bed 7750 }
57fa1fb3
TS
7751 opn = "recip2.s";
7752 break;
bf4120ad 7753 case OPC_RECIP1_S:
5e755519 7754 check_cp1_64bitmode(ctx);
b6d96bed 7755 {
a7812ae4 7756 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7757
7758 gen_load_fpr32(fp0, fs);
895c2d04 7759 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7760 gen_store_fpr32(fp0, fd);
a7812ae4 7761 tcg_temp_free_i32(fp0);
b6d96bed 7762 }
57fa1fb3
TS
7763 opn = "recip1.s";
7764 break;
bf4120ad 7765 case OPC_RSQRT1_S:
5e755519 7766 check_cp1_64bitmode(ctx);
b6d96bed 7767 {
a7812ae4 7768 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7769
7770 gen_load_fpr32(fp0, fs);
895c2d04 7771 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7772 gen_store_fpr32(fp0, fd);
a7812ae4 7773 tcg_temp_free_i32(fp0);
b6d96bed 7774 }
57fa1fb3
TS
7775 opn = "rsqrt1.s";
7776 break;
bf4120ad 7777 case OPC_RSQRT2_S:
5e755519 7778 check_cp1_64bitmode(ctx);
b6d96bed 7779 {
a7812ae4
PB
7780 TCGv_i32 fp0 = tcg_temp_new_i32();
7781 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7782
7783 gen_load_fpr32(fp0, fs);
7784 gen_load_fpr32(fp1, ft);
895c2d04 7785 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7786 tcg_temp_free_i32(fp1);
b6d96bed 7787 gen_store_fpr32(fp0, fd);
a7812ae4 7788 tcg_temp_free_i32(fp0);
b6d96bed 7789 }
57fa1fb3
TS
7790 opn = "rsqrt2.s";
7791 break;
bf4120ad 7792 case OPC_CVT_D_S:
5e755519 7793 check_cp1_registers(ctx, fd);
b6d96bed 7794 {
a7812ae4
PB
7795 TCGv_i32 fp32 = tcg_temp_new_i32();
7796 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7797
7798 gen_load_fpr32(fp32, fs);
895c2d04 7799 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7800 tcg_temp_free_i32(fp32);
b6d96bed 7801 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7802 tcg_temp_free_i64(fp64);
b6d96bed 7803 }
5a5012ec
TS
7804 opn = "cvt.d.s";
7805 break;
bf4120ad 7806 case OPC_CVT_W_S:
b6d96bed 7807 {
a7812ae4 7808 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7809
7810 gen_load_fpr32(fp0, fs);
895c2d04 7811 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7812 gen_store_fpr32(fp0, fd);
a7812ae4 7813 tcg_temp_free_i32(fp0);
b6d96bed 7814 }
5a5012ec
TS
7815 opn = "cvt.w.s";
7816 break;
bf4120ad 7817 case OPC_CVT_L_S:
5e755519 7818 check_cp1_64bitmode(ctx);
b6d96bed 7819 {
a7812ae4
PB
7820 TCGv_i32 fp32 = tcg_temp_new_i32();
7821 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7822
7823 gen_load_fpr32(fp32, fs);
895c2d04 7824 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7825 tcg_temp_free_i32(fp32);
b6d96bed 7826 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7827 tcg_temp_free_i64(fp64);
b6d96bed 7828 }
5a5012ec
TS
7829 opn = "cvt.l.s";
7830 break;
bf4120ad 7831 case OPC_CVT_PS_S:
5e755519 7832 check_cp1_64bitmode(ctx);
b6d96bed 7833 {
a7812ae4
PB
7834 TCGv_i64 fp64 = tcg_temp_new_i64();
7835 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7836 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7837
7838 gen_load_fpr32(fp32_0, fs);
7839 gen_load_fpr32(fp32_1, ft);
13d24f49 7840 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7841 tcg_temp_free_i32(fp32_1);
7842 tcg_temp_free_i32(fp32_0);
36aa55dc 7843 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7844 tcg_temp_free_i64(fp64);
b6d96bed 7845 }
5a5012ec
TS
7846 opn = "cvt.ps.s";
7847 break;
bf4120ad
NF
7848 case OPC_CMP_F_S:
7849 case OPC_CMP_UN_S:
7850 case OPC_CMP_EQ_S:
7851 case OPC_CMP_UEQ_S:
7852 case OPC_CMP_OLT_S:
7853 case OPC_CMP_ULT_S:
7854 case OPC_CMP_OLE_S:
7855 case OPC_CMP_ULE_S:
7856 case OPC_CMP_SF_S:
7857 case OPC_CMP_NGLE_S:
7858 case OPC_CMP_SEQ_S:
7859 case OPC_CMP_NGL_S:
7860 case OPC_CMP_LT_S:
7861 case OPC_CMP_NGE_S:
7862 case OPC_CMP_LE_S:
7863 case OPC_CMP_NGT_S:
8153667c
NF
7864 if (ctx->opcode & (1 << 6)) {
7865 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7866 opn = condnames_abs[func-48];
7867 } else {
7868 gen_cmp_s(ctx, func-48, ft, fs, cc);
7869 opn = condnames[func-48];
5a1e8ffb 7870 }
5a5012ec 7871 break;
bf4120ad 7872 case OPC_ADD_D:
5e755519 7873 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7874 {
a7812ae4
PB
7875 TCGv_i64 fp0 = tcg_temp_new_i64();
7876 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7877
7878 gen_load_fpr64(ctx, fp0, fs);
7879 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7880 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7881 tcg_temp_free_i64(fp1);
b6d96bed 7882 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7883 tcg_temp_free_i64(fp0);
b6d96bed 7884 }
6ea83fed 7885 opn = "add.d";
5a1e8ffb 7886 optype = BINOP;
6ea83fed 7887 break;
bf4120ad 7888 case OPC_SUB_D:
5e755519 7889 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7890 {
a7812ae4
PB
7891 TCGv_i64 fp0 = tcg_temp_new_i64();
7892 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7893
7894 gen_load_fpr64(ctx, fp0, fs);
7895 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7896 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7897 tcg_temp_free_i64(fp1);
b6d96bed 7898 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7899 tcg_temp_free_i64(fp0);
b6d96bed 7900 }
6ea83fed 7901 opn = "sub.d";
5a1e8ffb 7902 optype = BINOP;
6ea83fed 7903 break;
bf4120ad 7904 case OPC_MUL_D:
5e755519 7905 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7906 {
a7812ae4
PB
7907 TCGv_i64 fp0 = tcg_temp_new_i64();
7908 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7909
7910 gen_load_fpr64(ctx, fp0, fs);
7911 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7912 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7913 tcg_temp_free_i64(fp1);
b6d96bed 7914 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7915 tcg_temp_free_i64(fp0);
b6d96bed 7916 }
6ea83fed 7917 opn = "mul.d";
5a1e8ffb 7918 optype = BINOP;
6ea83fed 7919 break;
bf4120ad 7920 case OPC_DIV_D:
5e755519 7921 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7922 {
a7812ae4
PB
7923 TCGv_i64 fp0 = tcg_temp_new_i64();
7924 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7925
7926 gen_load_fpr64(ctx, fp0, fs);
7927 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7928 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7929 tcg_temp_free_i64(fp1);
b6d96bed 7930 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7931 tcg_temp_free_i64(fp0);
b6d96bed 7932 }
6ea83fed 7933 opn = "div.d";
5a1e8ffb 7934 optype = BINOP;
6ea83fed 7935 break;
bf4120ad 7936 case OPC_SQRT_D:
5e755519 7937 check_cp1_registers(ctx, fs | fd);
b6d96bed 7938 {
a7812ae4 7939 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7940
7941 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7942 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7943 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7944 tcg_temp_free_i64(fp0);
b6d96bed 7945 }
6ea83fed
FB
7946 opn = "sqrt.d";
7947 break;
bf4120ad 7948 case OPC_ABS_D:
5e755519 7949 check_cp1_registers(ctx, fs | fd);
b6d96bed 7950 {
a7812ae4 7951 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7952
7953 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7954 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7955 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7956 tcg_temp_free_i64(fp0);
b6d96bed 7957 }
6ea83fed
FB
7958 opn = "abs.d";
7959 break;
bf4120ad 7960 case OPC_MOV_D:
5e755519 7961 check_cp1_registers(ctx, fs | fd);
b6d96bed 7962 {
a7812ae4 7963 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7964
7965 gen_load_fpr64(ctx, fp0, fs);
7966 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7967 tcg_temp_free_i64(fp0);
b6d96bed 7968 }
6ea83fed
FB
7969 opn = "mov.d";
7970 break;
bf4120ad 7971 case OPC_NEG_D:
5e755519 7972 check_cp1_registers(ctx, fs | fd);
b6d96bed 7973 {
a7812ae4 7974 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7975
7976 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7977 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 7978 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7979 tcg_temp_free_i64(fp0);
b6d96bed 7980 }
6ea83fed
FB
7981 opn = "neg.d";
7982 break;
bf4120ad 7983 case OPC_ROUND_L_D:
5e755519 7984 check_cp1_64bitmode(ctx);
b6d96bed 7985 {
a7812ae4 7986 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7987
7988 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7989 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 7990 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7991 tcg_temp_free_i64(fp0);
b6d96bed 7992 }
5a5012ec
TS
7993 opn = "round.l.d";
7994 break;
bf4120ad 7995 case OPC_TRUNC_L_D:
5e755519 7996 check_cp1_64bitmode(ctx);
b6d96bed 7997 {
a7812ae4 7998 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7999
8000 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8001 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 8002 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8003 tcg_temp_free_i64(fp0);
b6d96bed 8004 }
5a5012ec
TS
8005 opn = "trunc.l.d";
8006 break;
bf4120ad 8007 case OPC_CEIL_L_D:
5e755519 8008 check_cp1_64bitmode(ctx);
b6d96bed 8009 {
a7812ae4 8010 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8011
8012 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8013 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8014 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8015 tcg_temp_free_i64(fp0);
b6d96bed 8016 }
5a5012ec
TS
8017 opn = "ceil.l.d";
8018 break;
bf4120ad 8019 case OPC_FLOOR_L_D:
5e755519 8020 check_cp1_64bitmode(ctx);
b6d96bed 8021 {
a7812ae4 8022 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8023
8024 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8025 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8026 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8027 tcg_temp_free_i64(fp0);
b6d96bed 8028 }
5a5012ec
TS
8029 opn = "floor.l.d";
8030 break;
bf4120ad 8031 case OPC_ROUND_W_D:
5e755519 8032 check_cp1_registers(ctx, fs);
b6d96bed 8033 {
a7812ae4
PB
8034 TCGv_i32 fp32 = tcg_temp_new_i32();
8035 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8036
8037 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8038 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8039 tcg_temp_free_i64(fp64);
b6d96bed 8040 gen_store_fpr32(fp32, fd);
a7812ae4 8041 tcg_temp_free_i32(fp32);
b6d96bed 8042 }
6ea83fed
FB
8043 opn = "round.w.d";
8044 break;
bf4120ad 8045 case OPC_TRUNC_W_D:
5e755519 8046 check_cp1_registers(ctx, fs);
b6d96bed 8047 {
a7812ae4
PB
8048 TCGv_i32 fp32 = tcg_temp_new_i32();
8049 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8050
8051 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8052 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8053 tcg_temp_free_i64(fp64);
b6d96bed 8054 gen_store_fpr32(fp32, fd);
a7812ae4 8055 tcg_temp_free_i32(fp32);
b6d96bed 8056 }
6ea83fed
FB
8057 opn = "trunc.w.d";
8058 break;
bf4120ad 8059 case OPC_CEIL_W_D:
5e755519 8060 check_cp1_registers(ctx, fs);
b6d96bed 8061 {
a7812ae4
PB
8062 TCGv_i32 fp32 = tcg_temp_new_i32();
8063 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8064
8065 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8066 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8067 tcg_temp_free_i64(fp64);
b6d96bed 8068 gen_store_fpr32(fp32, fd);
a7812ae4 8069 tcg_temp_free_i32(fp32);
b6d96bed 8070 }
6ea83fed
FB
8071 opn = "ceil.w.d";
8072 break;
bf4120ad 8073 case OPC_FLOOR_W_D:
5e755519 8074 check_cp1_registers(ctx, fs);
b6d96bed 8075 {
a7812ae4
PB
8076 TCGv_i32 fp32 = tcg_temp_new_i32();
8077 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8078
8079 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8080 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8081 tcg_temp_free_i64(fp64);
b6d96bed 8082 gen_store_fpr32(fp32, fd);
a7812ae4 8083 tcg_temp_free_i32(fp32);
b6d96bed 8084 }
7a387fff 8085 opn = "floor.w.d";
6ea83fed 8086 break;
bf4120ad 8087 case OPC_MOVCF_D:
b6d96bed 8088 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8089 opn = "movcf.d";
dd016883 8090 break;
bf4120ad 8091 case OPC_MOVZ_D:
a16336e4
TS
8092 {
8093 int l1 = gen_new_label();
c9297f4d 8094 TCGv_i64 fp0;
a16336e4 8095
c9297f4d
AJ
8096 if (ft != 0) {
8097 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8098 }
8099 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8100 gen_load_fpr64(ctx, fp0, fs);
8101 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8102 tcg_temp_free_i64(fp0);
a16336e4
TS
8103 gen_set_label(l1);
8104 }
5a5012ec
TS
8105 opn = "movz.d";
8106 break;
bf4120ad 8107 case OPC_MOVN_D:
a16336e4
TS
8108 {
8109 int l1 = gen_new_label();
c9297f4d
AJ
8110 TCGv_i64 fp0;
8111
8112 if (ft != 0) {
8113 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8114 fp0 = tcg_temp_new_i64();
8115 gen_load_fpr64(ctx, fp0, fs);
8116 gen_store_fpr64(ctx, fp0, fd);
8117 tcg_temp_free_i64(fp0);
8118 gen_set_label(l1);
8119 }
a16336e4 8120 }
5a5012ec 8121 opn = "movn.d";
6ea83fed 8122 break;
bf4120ad 8123 case OPC_RECIP_D:
b8aa4598 8124 check_cp1_64bitmode(ctx);
b6d96bed 8125 {
a7812ae4 8126 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8127
8128 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8129 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8130 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8131 tcg_temp_free_i64(fp0);
b6d96bed 8132 }
57fa1fb3
TS
8133 opn = "recip.d";
8134 break;
bf4120ad 8135 case OPC_RSQRT_D:
b8aa4598 8136 check_cp1_64bitmode(ctx);
b6d96bed 8137 {
a7812ae4 8138 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8139
8140 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8141 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8142 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8143 tcg_temp_free_i64(fp0);
b6d96bed 8144 }
57fa1fb3
TS
8145 opn = "rsqrt.d";
8146 break;
bf4120ad 8147 case OPC_RECIP2_D:
5e755519 8148 check_cp1_64bitmode(ctx);
b6d96bed 8149 {
a7812ae4
PB
8150 TCGv_i64 fp0 = tcg_temp_new_i64();
8151 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8152
8153 gen_load_fpr64(ctx, fp0, fs);
8154 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8155 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8156 tcg_temp_free_i64(fp1);
b6d96bed 8157 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8158 tcg_temp_free_i64(fp0);
b6d96bed 8159 }
57fa1fb3
TS
8160 opn = "recip2.d";
8161 break;
bf4120ad 8162 case OPC_RECIP1_D:
5e755519 8163 check_cp1_64bitmode(ctx);
b6d96bed 8164 {
a7812ae4 8165 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8166
8167 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8168 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8169 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8170 tcg_temp_free_i64(fp0);
b6d96bed 8171 }
57fa1fb3
TS
8172 opn = "recip1.d";
8173 break;
bf4120ad 8174 case OPC_RSQRT1_D:
5e755519 8175 check_cp1_64bitmode(ctx);
b6d96bed 8176 {
a7812ae4 8177 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8178
8179 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8180 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8181 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8182 tcg_temp_free_i64(fp0);
b6d96bed 8183 }
57fa1fb3
TS
8184 opn = "rsqrt1.d";
8185 break;
bf4120ad 8186 case OPC_RSQRT2_D:
5e755519 8187 check_cp1_64bitmode(ctx);
b6d96bed 8188 {
a7812ae4
PB
8189 TCGv_i64 fp0 = tcg_temp_new_i64();
8190 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8191
8192 gen_load_fpr64(ctx, fp0, fs);
8193 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8194 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8195 tcg_temp_free_i64(fp1);
b6d96bed 8196 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8197 tcg_temp_free_i64(fp0);
b6d96bed 8198 }
57fa1fb3
TS
8199 opn = "rsqrt2.d";
8200 break;
bf4120ad
NF
8201 case OPC_CMP_F_D:
8202 case OPC_CMP_UN_D:
8203 case OPC_CMP_EQ_D:
8204 case OPC_CMP_UEQ_D:
8205 case OPC_CMP_OLT_D:
8206 case OPC_CMP_ULT_D:
8207 case OPC_CMP_OLE_D:
8208 case OPC_CMP_ULE_D:
8209 case OPC_CMP_SF_D:
8210 case OPC_CMP_NGLE_D:
8211 case OPC_CMP_SEQ_D:
8212 case OPC_CMP_NGL_D:
8213 case OPC_CMP_LT_D:
8214 case OPC_CMP_NGE_D:
8215 case OPC_CMP_LE_D:
8216 case OPC_CMP_NGT_D:
8153667c
NF
8217 if (ctx->opcode & (1 << 6)) {
8218 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8219 opn = condnames_abs[func-48];
8220 } else {
8221 gen_cmp_d(ctx, func-48, ft, fs, cc);
8222 opn = condnames[func-48];
5a1e8ffb 8223 }
6ea83fed 8224 break;
bf4120ad 8225 case OPC_CVT_S_D:
5e755519 8226 check_cp1_registers(ctx, fs);
b6d96bed 8227 {
a7812ae4
PB
8228 TCGv_i32 fp32 = tcg_temp_new_i32();
8229 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8230
8231 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8232 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8233 tcg_temp_free_i64(fp64);
b6d96bed 8234 gen_store_fpr32(fp32, fd);
a7812ae4 8235 tcg_temp_free_i32(fp32);
b6d96bed 8236 }
5a5012ec
TS
8237 opn = "cvt.s.d";
8238 break;
bf4120ad 8239 case OPC_CVT_W_D:
5e755519 8240 check_cp1_registers(ctx, fs);
b6d96bed 8241 {
a7812ae4
PB
8242 TCGv_i32 fp32 = tcg_temp_new_i32();
8243 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8244
8245 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8246 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8247 tcg_temp_free_i64(fp64);
b6d96bed 8248 gen_store_fpr32(fp32, fd);
a7812ae4 8249 tcg_temp_free_i32(fp32);
b6d96bed 8250 }
5a5012ec
TS
8251 opn = "cvt.w.d";
8252 break;
bf4120ad 8253 case OPC_CVT_L_D:
5e755519 8254 check_cp1_64bitmode(ctx);
b6d96bed 8255 {
a7812ae4 8256 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8257
8258 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8259 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8260 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8261 tcg_temp_free_i64(fp0);
b6d96bed 8262 }
5a5012ec
TS
8263 opn = "cvt.l.d";
8264 break;
bf4120ad 8265 case OPC_CVT_S_W:
b6d96bed 8266 {
a7812ae4 8267 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8268
8269 gen_load_fpr32(fp0, fs);
895c2d04 8270 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8271 gen_store_fpr32(fp0, fd);
a7812ae4 8272 tcg_temp_free_i32(fp0);
b6d96bed 8273 }
5a5012ec 8274 opn = "cvt.s.w";
6ea83fed 8275 break;
bf4120ad 8276 case OPC_CVT_D_W:
5e755519 8277 check_cp1_registers(ctx, fd);
b6d96bed 8278 {
a7812ae4
PB
8279 TCGv_i32 fp32 = tcg_temp_new_i32();
8280 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8281
8282 gen_load_fpr32(fp32, fs);
895c2d04 8283 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8284 tcg_temp_free_i32(fp32);
b6d96bed 8285 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8286 tcg_temp_free_i64(fp64);
b6d96bed 8287 }
5a5012ec
TS
8288 opn = "cvt.d.w";
8289 break;
bf4120ad 8290 case OPC_CVT_S_L:
5e755519 8291 check_cp1_64bitmode(ctx);
b6d96bed 8292 {
a7812ae4
PB
8293 TCGv_i32 fp32 = tcg_temp_new_i32();
8294 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8295
8296 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8297 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8298 tcg_temp_free_i64(fp64);
b6d96bed 8299 gen_store_fpr32(fp32, fd);
a7812ae4 8300 tcg_temp_free_i32(fp32);
b6d96bed 8301 }
5a5012ec
TS
8302 opn = "cvt.s.l";
8303 break;
bf4120ad 8304 case OPC_CVT_D_L:
5e755519 8305 check_cp1_64bitmode(ctx);
b6d96bed 8306 {
a7812ae4 8307 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8308
8309 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8310 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8311 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8312 tcg_temp_free_i64(fp0);
b6d96bed 8313 }
5a5012ec
TS
8314 opn = "cvt.d.l";
8315 break;
bf4120ad 8316 case OPC_CVT_PS_PW:
5e755519 8317 check_cp1_64bitmode(ctx);
b6d96bed 8318 {
a7812ae4 8319 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8320
8321 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8322 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8323 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8324 tcg_temp_free_i64(fp0);
b6d96bed 8325 }
5a5012ec
TS
8326 opn = "cvt.ps.pw";
8327 break;
bf4120ad 8328 case OPC_ADD_PS:
5e755519 8329 check_cp1_64bitmode(ctx);
b6d96bed 8330 {
a7812ae4
PB
8331 TCGv_i64 fp0 = tcg_temp_new_i64();
8332 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8333
8334 gen_load_fpr64(ctx, fp0, fs);
8335 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8336 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8337 tcg_temp_free_i64(fp1);
b6d96bed 8338 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8339 tcg_temp_free_i64(fp0);
b6d96bed 8340 }
5a5012ec 8341 opn = "add.ps";
6ea83fed 8342 break;
bf4120ad 8343 case OPC_SUB_PS:
5e755519 8344 check_cp1_64bitmode(ctx);
b6d96bed 8345 {
a7812ae4
PB
8346 TCGv_i64 fp0 = tcg_temp_new_i64();
8347 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8348
8349 gen_load_fpr64(ctx, fp0, fs);
8350 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8351 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8352 tcg_temp_free_i64(fp1);
b6d96bed 8353 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8354 tcg_temp_free_i64(fp0);
b6d96bed 8355 }
5a5012ec 8356 opn = "sub.ps";
6ea83fed 8357 break;
bf4120ad 8358 case OPC_MUL_PS:
5e755519 8359 check_cp1_64bitmode(ctx);
b6d96bed 8360 {
a7812ae4
PB
8361 TCGv_i64 fp0 = tcg_temp_new_i64();
8362 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8363
8364 gen_load_fpr64(ctx, fp0, fs);
8365 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8366 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8367 tcg_temp_free_i64(fp1);
b6d96bed 8368 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8369 tcg_temp_free_i64(fp0);
b6d96bed 8370 }
5a5012ec 8371 opn = "mul.ps";
6ea83fed 8372 break;
bf4120ad 8373 case OPC_ABS_PS:
5e755519 8374 check_cp1_64bitmode(ctx);
b6d96bed 8375 {
a7812ae4 8376 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8377
8378 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8379 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8380 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8381 tcg_temp_free_i64(fp0);
b6d96bed 8382 }
5a5012ec 8383 opn = "abs.ps";
6ea83fed 8384 break;
bf4120ad 8385 case OPC_MOV_PS:
5e755519 8386 check_cp1_64bitmode(ctx);
b6d96bed 8387 {
a7812ae4 8388 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8389
8390 gen_load_fpr64(ctx, fp0, fs);
8391 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8392 tcg_temp_free_i64(fp0);
b6d96bed 8393 }
5a5012ec 8394 opn = "mov.ps";
6ea83fed 8395 break;
bf4120ad 8396 case OPC_NEG_PS:
5e755519 8397 check_cp1_64bitmode(ctx);
b6d96bed 8398 {
a7812ae4 8399 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8400
8401 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8402 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8403 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8404 tcg_temp_free_i64(fp0);
b6d96bed 8405 }
5a5012ec 8406 opn = "neg.ps";
6ea83fed 8407 break;
bf4120ad 8408 case OPC_MOVCF_PS:
5e755519 8409 check_cp1_64bitmode(ctx);
b6d96bed 8410 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8411 opn = "movcf.ps";
6ea83fed 8412 break;
bf4120ad 8413 case OPC_MOVZ_PS:
5e755519 8414 check_cp1_64bitmode(ctx);
a16336e4
TS
8415 {
8416 int l1 = gen_new_label();
30a3848b 8417 TCGv_i64 fp0;
a16336e4 8418
c9297f4d
AJ
8419 if (ft != 0)
8420 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8421 fp0 = tcg_temp_new_i64();
8422 gen_load_fpr64(ctx, fp0, fs);
8423 gen_store_fpr64(ctx, fp0, fd);
8424 tcg_temp_free_i64(fp0);
a16336e4
TS
8425 gen_set_label(l1);
8426 }
5a5012ec 8427 opn = "movz.ps";
6ea83fed 8428 break;
bf4120ad 8429 case OPC_MOVN_PS:
5e755519 8430 check_cp1_64bitmode(ctx);
a16336e4
TS
8431 {
8432 int l1 = gen_new_label();
30a3848b 8433 TCGv_i64 fp0;
c9297f4d
AJ
8434
8435 if (ft != 0) {
8436 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8437 fp0 = tcg_temp_new_i64();
8438 gen_load_fpr64(ctx, fp0, fs);
8439 gen_store_fpr64(ctx, fp0, fd);
8440 tcg_temp_free_i64(fp0);
8441 gen_set_label(l1);
8442 }
a16336e4 8443 }
5a5012ec 8444 opn = "movn.ps";
6ea83fed 8445 break;
bf4120ad 8446 case OPC_ADDR_PS:
5e755519 8447 check_cp1_64bitmode(ctx);
b6d96bed 8448 {
a7812ae4
PB
8449 TCGv_i64 fp0 = tcg_temp_new_i64();
8450 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8451
8452 gen_load_fpr64(ctx, fp0, ft);
8453 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8454 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8455 tcg_temp_free_i64(fp1);
b6d96bed 8456 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8457 tcg_temp_free_i64(fp0);
b6d96bed 8458 }
fbcc6828
TS
8459 opn = "addr.ps";
8460 break;
bf4120ad 8461 case OPC_MULR_PS:
5e755519 8462 check_cp1_64bitmode(ctx);
b6d96bed 8463 {
a7812ae4
PB
8464 TCGv_i64 fp0 = tcg_temp_new_i64();
8465 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8466
8467 gen_load_fpr64(ctx, fp0, ft);
8468 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8469 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8470 tcg_temp_free_i64(fp1);
b6d96bed 8471 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8472 tcg_temp_free_i64(fp0);
b6d96bed 8473 }
57fa1fb3
TS
8474 opn = "mulr.ps";
8475 break;
bf4120ad 8476 case OPC_RECIP2_PS:
5e755519 8477 check_cp1_64bitmode(ctx);
b6d96bed 8478 {
a7812ae4
PB
8479 TCGv_i64 fp0 = tcg_temp_new_i64();
8480 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8481
8482 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8483 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8484 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8485 tcg_temp_free_i64(fp1);
b6d96bed 8486 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8487 tcg_temp_free_i64(fp0);
b6d96bed 8488 }
57fa1fb3
TS
8489 opn = "recip2.ps";
8490 break;
bf4120ad 8491 case OPC_RECIP1_PS:
5e755519 8492 check_cp1_64bitmode(ctx);
b6d96bed 8493 {
a7812ae4 8494 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8495
8496 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8497 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8498 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8499 tcg_temp_free_i64(fp0);
b6d96bed 8500 }
57fa1fb3
TS
8501 opn = "recip1.ps";
8502 break;
bf4120ad 8503 case OPC_RSQRT1_PS:
5e755519 8504 check_cp1_64bitmode(ctx);
b6d96bed 8505 {
a7812ae4 8506 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8507
8508 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8509 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8510 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8511 tcg_temp_free_i64(fp0);
b6d96bed 8512 }
57fa1fb3
TS
8513 opn = "rsqrt1.ps";
8514 break;
bf4120ad 8515 case OPC_RSQRT2_PS:
5e755519 8516 check_cp1_64bitmode(ctx);
b6d96bed 8517 {
a7812ae4
PB
8518 TCGv_i64 fp0 = tcg_temp_new_i64();
8519 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8520
8521 gen_load_fpr64(ctx, fp0, fs);
8522 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8523 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8524 tcg_temp_free_i64(fp1);
b6d96bed 8525 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8526 tcg_temp_free_i64(fp0);
b6d96bed 8527 }
57fa1fb3
TS
8528 opn = "rsqrt2.ps";
8529 break;
bf4120ad 8530 case OPC_CVT_S_PU:
5e755519 8531 check_cp1_64bitmode(ctx);
b6d96bed 8532 {
a7812ae4 8533 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8534
8535 gen_load_fpr32h(fp0, fs);
895c2d04 8536 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8537 gen_store_fpr32(fp0, fd);
a7812ae4 8538 tcg_temp_free_i32(fp0);
b6d96bed 8539 }
5a5012ec 8540 opn = "cvt.s.pu";
dd016883 8541 break;
bf4120ad 8542 case OPC_CVT_PW_PS:
5e755519 8543 check_cp1_64bitmode(ctx);
b6d96bed 8544 {
a7812ae4 8545 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8546
8547 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8548 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8549 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8550 tcg_temp_free_i64(fp0);
b6d96bed 8551 }
5a5012ec 8552 opn = "cvt.pw.ps";
6ea83fed 8553 break;
bf4120ad 8554 case OPC_CVT_S_PL:
5e755519 8555 check_cp1_64bitmode(ctx);
b6d96bed 8556 {
a7812ae4 8557 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8558
8559 gen_load_fpr32(fp0, fs);
895c2d04 8560 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8561 gen_store_fpr32(fp0, fd);
a7812ae4 8562 tcg_temp_free_i32(fp0);
b6d96bed 8563 }
5a5012ec 8564 opn = "cvt.s.pl";
6ea83fed 8565 break;
bf4120ad 8566 case OPC_PLL_PS:
5e755519 8567 check_cp1_64bitmode(ctx);
b6d96bed 8568 {
a7812ae4
PB
8569 TCGv_i32 fp0 = tcg_temp_new_i32();
8570 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8571
8572 gen_load_fpr32(fp0, fs);
8573 gen_load_fpr32(fp1, ft);
8574 gen_store_fpr32h(fp0, fd);
8575 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8576 tcg_temp_free_i32(fp0);
8577 tcg_temp_free_i32(fp1);
b6d96bed 8578 }
5a5012ec 8579 opn = "pll.ps";
6ea83fed 8580 break;
bf4120ad 8581 case OPC_PLU_PS:
5e755519 8582 check_cp1_64bitmode(ctx);
b6d96bed 8583 {
a7812ae4
PB
8584 TCGv_i32 fp0 = tcg_temp_new_i32();
8585 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8586
8587 gen_load_fpr32(fp0, fs);
8588 gen_load_fpr32h(fp1, ft);
8589 gen_store_fpr32(fp1, fd);
8590 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8591 tcg_temp_free_i32(fp0);
8592 tcg_temp_free_i32(fp1);
b6d96bed 8593 }
5a5012ec
TS
8594 opn = "plu.ps";
8595 break;
bf4120ad 8596 case OPC_PUL_PS:
5e755519 8597 check_cp1_64bitmode(ctx);
b6d96bed 8598 {
a7812ae4
PB
8599 TCGv_i32 fp0 = tcg_temp_new_i32();
8600 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8601
8602 gen_load_fpr32h(fp0, fs);
8603 gen_load_fpr32(fp1, ft);
8604 gen_store_fpr32(fp1, fd);
8605 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8606 tcg_temp_free_i32(fp0);
8607 tcg_temp_free_i32(fp1);
b6d96bed 8608 }
5a5012ec
TS
8609 opn = "pul.ps";
8610 break;
bf4120ad 8611 case OPC_PUU_PS:
5e755519 8612 check_cp1_64bitmode(ctx);
b6d96bed 8613 {
a7812ae4
PB
8614 TCGv_i32 fp0 = tcg_temp_new_i32();
8615 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8616
8617 gen_load_fpr32h(fp0, fs);
8618 gen_load_fpr32h(fp1, ft);
8619 gen_store_fpr32(fp1, fd);
8620 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8621 tcg_temp_free_i32(fp0);
8622 tcg_temp_free_i32(fp1);
b6d96bed 8623 }
5a5012ec
TS
8624 opn = "puu.ps";
8625 break;
bf4120ad
NF
8626 case OPC_CMP_F_PS:
8627 case OPC_CMP_UN_PS:
8628 case OPC_CMP_EQ_PS:
8629 case OPC_CMP_UEQ_PS:
8630 case OPC_CMP_OLT_PS:
8631 case OPC_CMP_ULT_PS:
8632 case OPC_CMP_OLE_PS:
8633 case OPC_CMP_ULE_PS:
8634 case OPC_CMP_SF_PS:
8635 case OPC_CMP_NGLE_PS:
8636 case OPC_CMP_SEQ_PS:
8637 case OPC_CMP_NGL_PS:
8638 case OPC_CMP_LT_PS:
8639 case OPC_CMP_NGE_PS:
8640 case OPC_CMP_LE_PS:
8641 case OPC_CMP_NGT_PS:
8153667c
NF
8642 if (ctx->opcode & (1 << 6)) {
8643 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8644 opn = condnames_abs[func-48];
8645 } else {
8646 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8647 opn = condnames[func-48];
5a1e8ffb 8648 }
6ea83fed 8649 break;
5a5012ec 8650 default:
923617a3 8651 MIPS_INVAL(opn);
e397ee33 8652 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8653 return;
8654 }
2abf314d 8655 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8656 switch (optype) {
8657 case BINOP:
6ea83fed 8658 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8659 break;
8660 case CMPOP:
8661 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8662 break;
8663 default:
6ea83fed 8664 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8665 break;
8666 }
6ea83fed 8667}
6af0bf9c 8668
5a5012ec 8669/* Coprocessor 3 (FPU) */
5e755519
TS
8670static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8671 int fd, int fs, int base, int index)
7a387fff 8672{
923617a3 8673 const char *opn = "extended float load/store";
93b12ccc 8674 int store = 0;
4e2474d6 8675 TCGv t0 = tcg_temp_new();
7a387fff 8676
93b12ccc 8677 if (base == 0) {
6c5c1e20 8678 gen_load_gpr(t0, index);
93b12ccc 8679 } else if (index == 0) {
6c5c1e20 8680 gen_load_gpr(t0, base);
93b12ccc 8681 } else {
05168674 8682 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8683 }
5a5012ec 8684 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8685 memory access. */
5a5012ec
TS
8686 switch (opc) {
8687 case OPC_LWXC1:
8c0ab41f 8688 check_cop1x(ctx);
b6d96bed 8689 {
a7812ae4 8690 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8691
585c88d5
AJ
8692 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8693 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8694 gen_store_fpr32(fp0, fd);
a7812ae4 8695 tcg_temp_free_i32(fp0);
b6d96bed 8696 }
5a5012ec
TS
8697 opn = "lwxc1";
8698 break;
8699 case OPC_LDXC1:
8c0ab41f
AJ
8700 check_cop1x(ctx);
8701 check_cp1_registers(ctx, fd);
b6d96bed 8702 {
a7812ae4 8703 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8704
8705 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8706 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8707 tcg_temp_free_i64(fp0);
b6d96bed 8708 }
5a5012ec
TS
8709 opn = "ldxc1";
8710 break;
8711 case OPC_LUXC1:
8c0ab41f 8712 check_cp1_64bitmode(ctx);
6c5c1e20 8713 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8714 {
a7812ae4 8715 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8716
8717 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8718 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8719 tcg_temp_free_i64(fp0);
b6d96bed 8720 }
5a5012ec
TS
8721 opn = "luxc1";
8722 break;
8723 case OPC_SWXC1:
8c0ab41f 8724 check_cop1x(ctx);
b6d96bed 8725 {
a7812ae4 8726 TCGv_i32 fp0 = tcg_temp_new_i32();
585c88d5 8727 TCGv t1 = tcg_temp_new();
b6d96bed
TS
8728
8729 gen_load_fpr32(fp0, fs);
a7812ae4
PB
8730 tcg_gen_extu_i32_tl(t1, fp0);
8731 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8732 tcg_temp_free_i32(fp0);
a6035857 8733 tcg_temp_free(t1);
b6d96bed 8734 }
5a5012ec 8735 opn = "swxc1";
93b12ccc 8736 store = 1;
5a5012ec
TS
8737 break;
8738 case OPC_SDXC1:
8c0ab41f
AJ
8739 check_cop1x(ctx);
8740 check_cp1_registers(ctx, fs);
b6d96bed 8741 {
a7812ae4 8742 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8743
8744 gen_load_fpr64(ctx, fp0, fs);
8745 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8746 tcg_temp_free_i64(fp0);
b6d96bed 8747 }
5a5012ec 8748 opn = "sdxc1";
93b12ccc 8749 store = 1;
5a5012ec
TS
8750 break;
8751 case OPC_SUXC1:
8c0ab41f 8752 check_cp1_64bitmode(ctx);
6c5c1e20 8753 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8754 {
a7812ae4 8755 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8756
8757 gen_load_fpr64(ctx, fp0, fs);
8758 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8759 tcg_temp_free_i64(fp0);
b6d96bed 8760 }
5a5012ec 8761 opn = "suxc1";
93b12ccc 8762 store = 1;
5a5012ec 8763 break;
5a5012ec 8764 }
6c5c1e20 8765 tcg_temp_free(t0);
2abf314d 8766 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8767 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8768 regnames[index], regnames[base]);
5a5012ec
TS
8769}
8770
5e755519
TS
8771static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8772 int fd, int fr, int fs, int ft)
5a5012ec 8773{
923617a3 8774 const char *opn = "flt3_arith";
5a5012ec 8775
5a5012ec
TS
8776 switch (opc) {
8777 case OPC_ALNV_PS:
b8aa4598 8778 check_cp1_64bitmode(ctx);
a16336e4 8779 {
a7812ae4 8780 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8781 TCGv_i32 fp = tcg_temp_new_i32();
8782 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8783 int l1 = gen_new_label();
8784 int l2 = gen_new_label();
8785
6c5c1e20
TS
8786 gen_load_gpr(t0, fr);
8787 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8788
8789 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac
AJ
8790 gen_load_fpr32(fp, fs);
8791 gen_load_fpr32h(fph, fs);
8792 gen_store_fpr32(fp, fd);
8793 gen_store_fpr32h(fph, fd);
a16336e4
TS
8794 tcg_gen_br(l2);
8795 gen_set_label(l1);
6c5c1e20
TS
8796 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8797 tcg_temp_free(t0);
a16336e4 8798#ifdef TARGET_WORDS_BIGENDIAN
c905fdac
AJ
8799 gen_load_fpr32(fp, fs);
8800 gen_load_fpr32h(fph, ft);
8801 gen_store_fpr32h(fp, fd);
8802 gen_store_fpr32(fph, fd);
a16336e4 8803#else
c905fdac
AJ
8804 gen_load_fpr32h(fph, fs);
8805 gen_load_fpr32(fp, ft);
8806 gen_store_fpr32(fph, fd);
8807 gen_store_fpr32h(fp, fd);
a16336e4
TS
8808#endif
8809 gen_set_label(l2);
c905fdac
AJ
8810 tcg_temp_free_i32(fp);
8811 tcg_temp_free_i32(fph);
a16336e4 8812 }
5a5012ec
TS
8813 opn = "alnv.ps";
8814 break;
8815 case OPC_MADD_S:
b8aa4598 8816 check_cop1x(ctx);
b6d96bed 8817 {
a7812ae4
PB
8818 TCGv_i32 fp0 = tcg_temp_new_i32();
8819 TCGv_i32 fp1 = tcg_temp_new_i32();
8820 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8821
8822 gen_load_fpr32(fp0, fs);
8823 gen_load_fpr32(fp1, ft);
8824 gen_load_fpr32(fp2, fr);
b3d6cd44 8825 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8826 tcg_temp_free_i32(fp0);
8827 tcg_temp_free_i32(fp1);
b6d96bed 8828 gen_store_fpr32(fp2, fd);
a7812ae4 8829 tcg_temp_free_i32(fp2);
b6d96bed 8830 }
5a5012ec
TS
8831 opn = "madd.s";
8832 break;
8833 case OPC_MADD_D:
b8aa4598
TS
8834 check_cop1x(ctx);
8835 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8836 {
a7812ae4
PB
8837 TCGv_i64 fp0 = tcg_temp_new_i64();
8838 TCGv_i64 fp1 = tcg_temp_new_i64();
8839 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8840
8841 gen_load_fpr64(ctx, fp0, fs);
8842 gen_load_fpr64(ctx, fp1, ft);
8843 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8844 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8845 tcg_temp_free_i64(fp0);
8846 tcg_temp_free_i64(fp1);
b6d96bed 8847 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8848 tcg_temp_free_i64(fp2);
b6d96bed 8849 }
5a5012ec
TS
8850 opn = "madd.d";
8851 break;
8852 case OPC_MADD_PS:
b8aa4598 8853 check_cp1_64bitmode(ctx);
b6d96bed 8854 {
a7812ae4
PB
8855 TCGv_i64 fp0 = tcg_temp_new_i64();
8856 TCGv_i64 fp1 = tcg_temp_new_i64();
8857 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8858
8859 gen_load_fpr64(ctx, fp0, fs);
8860 gen_load_fpr64(ctx, fp1, ft);
8861 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8862 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8863 tcg_temp_free_i64(fp0);
8864 tcg_temp_free_i64(fp1);
b6d96bed 8865 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8866 tcg_temp_free_i64(fp2);
b6d96bed 8867 }
5a5012ec
TS
8868 opn = "madd.ps";
8869 break;
8870 case OPC_MSUB_S:
b8aa4598 8871 check_cop1x(ctx);
b6d96bed 8872 {
a7812ae4
PB
8873 TCGv_i32 fp0 = tcg_temp_new_i32();
8874 TCGv_i32 fp1 = tcg_temp_new_i32();
8875 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8876
8877 gen_load_fpr32(fp0, fs);
8878 gen_load_fpr32(fp1, ft);
8879 gen_load_fpr32(fp2, fr);
b3d6cd44 8880 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8881 tcg_temp_free_i32(fp0);
8882 tcg_temp_free_i32(fp1);
b6d96bed 8883 gen_store_fpr32(fp2, fd);
a7812ae4 8884 tcg_temp_free_i32(fp2);
b6d96bed 8885 }
5a5012ec
TS
8886 opn = "msub.s";
8887 break;
8888 case OPC_MSUB_D:
b8aa4598
TS
8889 check_cop1x(ctx);
8890 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8891 {
a7812ae4
PB
8892 TCGv_i64 fp0 = tcg_temp_new_i64();
8893 TCGv_i64 fp1 = tcg_temp_new_i64();
8894 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8895
8896 gen_load_fpr64(ctx, fp0, fs);
8897 gen_load_fpr64(ctx, fp1, ft);
8898 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8899 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8900 tcg_temp_free_i64(fp0);
8901 tcg_temp_free_i64(fp1);
b6d96bed 8902 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8903 tcg_temp_free_i64(fp2);
b6d96bed 8904 }
5a5012ec
TS
8905 opn = "msub.d";
8906 break;
8907 case OPC_MSUB_PS:
b8aa4598 8908 check_cp1_64bitmode(ctx);
b6d96bed 8909 {
a7812ae4
PB
8910 TCGv_i64 fp0 = tcg_temp_new_i64();
8911 TCGv_i64 fp1 = tcg_temp_new_i64();
8912 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8913
8914 gen_load_fpr64(ctx, fp0, fs);
8915 gen_load_fpr64(ctx, fp1, ft);
8916 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8917 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8918 tcg_temp_free_i64(fp0);
8919 tcg_temp_free_i64(fp1);
b6d96bed 8920 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8921 tcg_temp_free_i64(fp2);
b6d96bed 8922 }
5a5012ec
TS
8923 opn = "msub.ps";
8924 break;
8925 case OPC_NMADD_S:
b8aa4598 8926 check_cop1x(ctx);
b6d96bed 8927 {
a7812ae4
PB
8928 TCGv_i32 fp0 = tcg_temp_new_i32();
8929 TCGv_i32 fp1 = tcg_temp_new_i32();
8930 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8931
8932 gen_load_fpr32(fp0, fs);
8933 gen_load_fpr32(fp1, ft);
8934 gen_load_fpr32(fp2, fr);
b3d6cd44 8935 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8936 tcg_temp_free_i32(fp0);
8937 tcg_temp_free_i32(fp1);
b6d96bed 8938 gen_store_fpr32(fp2, fd);
a7812ae4 8939 tcg_temp_free_i32(fp2);
b6d96bed 8940 }
5a5012ec
TS
8941 opn = "nmadd.s";
8942 break;
8943 case OPC_NMADD_D:
b8aa4598
TS
8944 check_cop1x(ctx);
8945 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8946 {
a7812ae4
PB
8947 TCGv_i64 fp0 = tcg_temp_new_i64();
8948 TCGv_i64 fp1 = tcg_temp_new_i64();
8949 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8950
8951 gen_load_fpr64(ctx, fp0, fs);
8952 gen_load_fpr64(ctx, fp1, ft);
8953 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8954 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8955 tcg_temp_free_i64(fp0);
8956 tcg_temp_free_i64(fp1);
b6d96bed 8957 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8958 tcg_temp_free_i64(fp2);
b6d96bed 8959 }
5a5012ec
TS
8960 opn = "nmadd.d";
8961 break;
8962 case OPC_NMADD_PS:
b8aa4598 8963 check_cp1_64bitmode(ctx);
b6d96bed 8964 {
a7812ae4
PB
8965 TCGv_i64 fp0 = tcg_temp_new_i64();
8966 TCGv_i64 fp1 = tcg_temp_new_i64();
8967 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8968
8969 gen_load_fpr64(ctx, fp0, fs);
8970 gen_load_fpr64(ctx, fp1, ft);
8971 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8972 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8973 tcg_temp_free_i64(fp0);
8974 tcg_temp_free_i64(fp1);
b6d96bed 8975 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8976 tcg_temp_free_i64(fp2);
b6d96bed 8977 }
5a5012ec
TS
8978 opn = "nmadd.ps";
8979 break;
8980 case OPC_NMSUB_S:
b8aa4598 8981 check_cop1x(ctx);
b6d96bed 8982 {
a7812ae4
PB
8983 TCGv_i32 fp0 = tcg_temp_new_i32();
8984 TCGv_i32 fp1 = tcg_temp_new_i32();
8985 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8986
8987 gen_load_fpr32(fp0, fs);
8988 gen_load_fpr32(fp1, ft);
8989 gen_load_fpr32(fp2, fr);
b3d6cd44 8990 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8991 tcg_temp_free_i32(fp0);
8992 tcg_temp_free_i32(fp1);
b6d96bed 8993 gen_store_fpr32(fp2, fd);
a7812ae4 8994 tcg_temp_free_i32(fp2);
b6d96bed 8995 }
5a5012ec
TS
8996 opn = "nmsub.s";
8997 break;
8998 case OPC_NMSUB_D:
b8aa4598
TS
8999 check_cop1x(ctx);
9000 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9001 {
a7812ae4
PB
9002 TCGv_i64 fp0 = tcg_temp_new_i64();
9003 TCGv_i64 fp1 = tcg_temp_new_i64();
9004 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9005
9006 gen_load_fpr64(ctx, fp0, fs);
9007 gen_load_fpr64(ctx, fp1, ft);
9008 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9009 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9010 tcg_temp_free_i64(fp0);
9011 tcg_temp_free_i64(fp1);
b6d96bed 9012 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9013 tcg_temp_free_i64(fp2);
b6d96bed 9014 }
5a5012ec
TS
9015 opn = "nmsub.d";
9016 break;
9017 case OPC_NMSUB_PS:
b8aa4598 9018 check_cp1_64bitmode(ctx);
b6d96bed 9019 {
a7812ae4
PB
9020 TCGv_i64 fp0 = tcg_temp_new_i64();
9021 TCGv_i64 fp1 = tcg_temp_new_i64();
9022 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9023
9024 gen_load_fpr64(ctx, fp0, fs);
9025 gen_load_fpr64(ctx, fp1, ft);
9026 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9027 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9028 tcg_temp_free_i64(fp0);
9029 tcg_temp_free_i64(fp1);
b6d96bed 9030 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9031 tcg_temp_free_i64(fp2);
b6d96bed 9032 }
5a5012ec
TS
9033 opn = "nmsub.ps";
9034 break;
923617a3
TS
9035 default:
9036 MIPS_INVAL(opn);
5a5012ec
TS
9037 generate_exception (ctx, EXCP_RI);
9038 return;
9039 }
2abf314d 9040 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9041 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9042 fregnames[fs], fregnames[ft]);
7a387fff
TS
9043}
9044
d75c135e 9045static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9046{
9047 TCGv t0;
9048
b3167288
RH
9049#if !defined(CONFIG_USER_ONLY)
9050 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9051 Therefore only check the ISA in system mode. */
d75c135e 9052 check_insn(ctx, ISA_MIPS32R2);
b3167288 9053#endif
26ebe468
NF
9054 t0 = tcg_temp_new();
9055
9056 switch (rd) {
9057 case 0:
9058 save_cpu_state(ctx, 1);
895c2d04 9059 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9060 gen_store_gpr(t0, rt);
9061 break;
9062 case 1:
9063 save_cpu_state(ctx, 1);
895c2d04 9064 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9065 gen_store_gpr(t0, rt);
9066 break;
9067 case 2:
9068 save_cpu_state(ctx, 1);
895c2d04 9069 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9070 gen_store_gpr(t0, rt);
9071 break;
9072 case 3:
9073 save_cpu_state(ctx, 1);
895c2d04 9074 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9075 gen_store_gpr(t0, rt);
9076 break;
9077 case 29:
9078#if defined(CONFIG_USER_ONLY)
7db13fae 9079 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
26ebe468
NF
9080 gen_store_gpr(t0, rt);
9081 break;
9082#else
9083 /* XXX: Some CPUs implement this in hardware.
9084 Not supported yet. */
9085#endif
9086 default: /* Invalid */
9087 MIPS_INVAL("rdhwr");
9088 generate_exception(ctx, EXCP_RI);
9089 break;
9090 }
9091 tcg_temp_free(t0);
9092}
9093
d75c135e 9094static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9095{
9096 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9097 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9098 /* Branches completion */
9099 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9100 ctx->bstate = BS_BRANCH;
9101 save_cpu_state(ctx, 0);
9102 /* FIXME: Need to clear can_do_io. */
364d4831 9103 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9104 case MIPS_HFLAG_B:
9105 /* unconditional branch */
9106 MIPS_DEBUG("unconditional branch");
364d4831
NF
9107 if (proc_hflags & MIPS_HFLAG_BX) {
9108 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9109 }
c9602061
NF
9110 gen_goto_tb(ctx, 0, ctx->btarget);
9111 break;
9112 case MIPS_HFLAG_BL:
9113 /* blikely taken case */
9114 MIPS_DEBUG("blikely branch taken");
9115 gen_goto_tb(ctx, 0, ctx->btarget);
9116 break;
9117 case MIPS_HFLAG_BC:
9118 /* Conditional branch */
9119 MIPS_DEBUG("conditional branch");
9120 {
9121 int l1 = gen_new_label();
9122
9123 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9124 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9125 gen_set_label(l1);
9126 gen_goto_tb(ctx, 0, ctx->btarget);
9127 }
9128 break;
9129 case MIPS_HFLAG_BR:
9130 /* unconditional branch to register */
9131 MIPS_DEBUG("branch to register");
d75c135e 9132 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9133 TCGv t0 = tcg_temp_new();
9134 TCGv_i32 t1 = tcg_temp_new_i32();
9135
9136 tcg_gen_andi_tl(t0, btarget, 0x1);
9137 tcg_gen_trunc_tl_i32(t1, t0);
9138 tcg_temp_free(t0);
9139 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9140 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9141 tcg_gen_or_i32(hflags, hflags, t1);
9142 tcg_temp_free_i32(t1);
9143
9144 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9145 } else {
9146 tcg_gen_mov_tl(cpu_PC, btarget);
9147 }
c9602061
NF
9148 if (ctx->singlestep_enabled) {
9149 save_cpu_state(ctx, 0);
895c2d04 9150 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9151 }
9152 tcg_gen_exit_tb(0);
9153 break;
9154 default:
9155 MIPS_DEBUG("unknown branch");
9156 break;
9157 }
9158 }
9159}
9160
7a387fff 9161/* ISA extensions (ASEs) */
6af0bf9c 9162/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9163
9164/* MIPS16 major opcodes */
9165enum {
9166 M16_OPC_ADDIUSP = 0x00,
9167 M16_OPC_ADDIUPC = 0x01,
9168 M16_OPC_B = 0x02,
9169 M16_OPC_JAL = 0x03,
9170 M16_OPC_BEQZ = 0x04,
9171 M16_OPC_BNEQZ = 0x05,
9172 M16_OPC_SHIFT = 0x06,
9173 M16_OPC_LD = 0x07,
9174 M16_OPC_RRIA = 0x08,
9175 M16_OPC_ADDIU8 = 0x09,
9176 M16_OPC_SLTI = 0x0a,
9177 M16_OPC_SLTIU = 0x0b,
9178 M16_OPC_I8 = 0x0c,
9179 M16_OPC_LI = 0x0d,
9180 M16_OPC_CMPI = 0x0e,
9181 M16_OPC_SD = 0x0f,
9182 M16_OPC_LB = 0x10,
9183 M16_OPC_LH = 0x11,
9184 M16_OPC_LWSP = 0x12,
9185 M16_OPC_LW = 0x13,
9186 M16_OPC_LBU = 0x14,
9187 M16_OPC_LHU = 0x15,
9188 M16_OPC_LWPC = 0x16,
9189 M16_OPC_LWU = 0x17,
9190 M16_OPC_SB = 0x18,
9191 M16_OPC_SH = 0x19,
9192 M16_OPC_SWSP = 0x1a,
9193 M16_OPC_SW = 0x1b,
9194 M16_OPC_RRR = 0x1c,
9195 M16_OPC_RR = 0x1d,
9196 M16_OPC_EXTEND = 0x1e,
9197 M16_OPC_I64 = 0x1f
9198};
9199
9200/* I8 funct field */
9201enum {
9202 I8_BTEQZ = 0x0,
9203 I8_BTNEZ = 0x1,
9204 I8_SWRASP = 0x2,
9205 I8_ADJSP = 0x3,
9206 I8_SVRS = 0x4,
9207 I8_MOV32R = 0x5,
9208 I8_MOVR32 = 0x7
9209};
9210
9211/* RRR f field */
9212enum {
9213 RRR_DADDU = 0x0,
9214 RRR_ADDU = 0x1,
9215 RRR_DSUBU = 0x2,
9216 RRR_SUBU = 0x3
9217};
9218
9219/* RR funct field */
9220enum {
9221 RR_JR = 0x00,
9222 RR_SDBBP = 0x01,
9223 RR_SLT = 0x02,
9224 RR_SLTU = 0x03,
9225 RR_SLLV = 0x04,
9226 RR_BREAK = 0x05,
9227 RR_SRLV = 0x06,
9228 RR_SRAV = 0x07,
9229 RR_DSRL = 0x08,
9230 RR_CMP = 0x0a,
9231 RR_NEG = 0x0b,
9232 RR_AND = 0x0c,
9233 RR_OR = 0x0d,
9234 RR_XOR = 0x0e,
9235 RR_NOT = 0x0f,
9236 RR_MFHI = 0x10,
9237 RR_CNVT = 0x11,
9238 RR_MFLO = 0x12,
9239 RR_DSRA = 0x13,
9240 RR_DSLLV = 0x14,
9241 RR_DSRLV = 0x16,
9242 RR_DSRAV = 0x17,
9243 RR_MULT = 0x18,
9244 RR_MULTU = 0x19,
9245 RR_DIV = 0x1a,
9246 RR_DIVU = 0x1b,
9247 RR_DMULT = 0x1c,
9248 RR_DMULTU = 0x1d,
9249 RR_DDIV = 0x1e,
9250 RR_DDIVU = 0x1f
9251};
9252
9253/* I64 funct field */
9254enum {
9255 I64_LDSP = 0x0,
9256 I64_SDSP = 0x1,
9257 I64_SDRASP = 0x2,
9258 I64_DADJSP = 0x3,
9259 I64_LDPC = 0x4,
364d4831 9260 I64_DADDIU5 = 0x5,
6ea219d0
NF
9261 I64_DADDIUPC = 0x6,
9262 I64_DADDIUSP = 0x7
9263};
9264
9265/* RR ry field for CNVT */
9266enum {
9267 RR_RY_CNVT_ZEB = 0x0,
9268 RR_RY_CNVT_ZEH = 0x1,
9269 RR_RY_CNVT_ZEW = 0x2,
9270 RR_RY_CNVT_SEB = 0x4,
9271 RR_RY_CNVT_SEH = 0x5,
9272 RR_RY_CNVT_SEW = 0x6,
9273};
9274
364d4831
NF
9275static int xlat (int r)
9276{
9277 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9278
9279 return map[r];
9280}
9281
9282static void gen_mips16_save (DisasContext *ctx,
9283 int xsregs, int aregs,
9284 int do_ra, int do_s0, int do_s1,
9285 int framesize)
9286{
9287 TCGv t0 = tcg_temp_new();
9288 TCGv t1 = tcg_temp_new();
9289 int args, astatic;
9290
9291 switch (aregs) {
9292 case 0:
9293 case 1:
9294 case 2:
9295 case 3:
9296 case 11:
9297 args = 0;
9298 break;
9299 case 4:
9300 case 5:
9301 case 6:
9302 case 7:
9303 args = 1;
9304 break;
9305 case 8:
9306 case 9:
9307 case 10:
9308 args = 2;
9309 break;
9310 case 12:
9311 case 13:
9312 args = 3;
9313 break;
9314 case 14:
9315 args = 4;
9316 break;
9317 default:
9318 generate_exception(ctx, EXCP_RI);
9319 return;
9320 }
9321
9322 switch (args) {
9323 case 4:
9324 gen_base_offset_addr(ctx, t0, 29, 12);
9325 gen_load_gpr(t1, 7);
2910c6cb 9326 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9327 /* Fall through */
9328 case 3:
9329 gen_base_offset_addr(ctx, t0, 29, 8);
9330 gen_load_gpr(t1, 6);
2910c6cb 9331 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9332 /* Fall through */
9333 case 2:
9334 gen_base_offset_addr(ctx, t0, 29, 4);
9335 gen_load_gpr(t1, 5);
2910c6cb 9336 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9337 /* Fall through */
9338 case 1:
9339 gen_base_offset_addr(ctx, t0, 29, 0);
9340 gen_load_gpr(t1, 4);
2910c6cb 9341 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9342 }
9343
9344 gen_load_gpr(t0, 29);
9345
9346#define DECR_AND_STORE(reg) do { \
9347 tcg_gen_subi_tl(t0, t0, 4); \
9348 gen_load_gpr(t1, reg); \
2910c6cb 9349 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
364d4831
NF
9350 } while (0)
9351
9352 if (do_ra) {
9353 DECR_AND_STORE(31);
9354 }
9355
9356 switch (xsregs) {
9357 case 7:
9358 DECR_AND_STORE(30);
9359 /* Fall through */
9360 case 6:
9361 DECR_AND_STORE(23);
9362 /* Fall through */
9363 case 5:
9364 DECR_AND_STORE(22);
9365 /* Fall through */
9366 case 4:
9367 DECR_AND_STORE(21);
9368 /* Fall through */
9369 case 3:
9370 DECR_AND_STORE(20);
9371 /* Fall through */
9372 case 2:
9373 DECR_AND_STORE(19);
9374 /* Fall through */
9375 case 1:
9376 DECR_AND_STORE(18);
9377 }
9378
9379 if (do_s1) {
9380 DECR_AND_STORE(17);
9381 }
9382 if (do_s0) {
9383 DECR_AND_STORE(16);
9384 }
9385
9386 switch (aregs) {
9387 case 0:
9388 case 4:
9389 case 8:
9390 case 12:
9391 case 14:
9392 astatic = 0;
9393 break;
9394 case 1:
9395 case 5:
9396 case 9:
9397 case 13:
9398 astatic = 1;
9399 break;
9400 case 2:
9401 case 6:
9402 case 10:
9403 astatic = 2;
9404 break;
9405 case 3:
9406 case 7:
9407 astatic = 3;
9408 break;
9409 case 11:
9410 astatic = 4;
9411 break;
9412 default:
9413 generate_exception(ctx, EXCP_RI);
9414 return;
9415 }
9416
9417 if (astatic > 0) {
9418 DECR_AND_STORE(7);
9419 if (astatic > 1) {
9420 DECR_AND_STORE(6);
9421 if (astatic > 2) {
9422 DECR_AND_STORE(5);
9423 if (astatic > 3) {
9424 DECR_AND_STORE(4);
9425 }
9426 }
9427 }
9428 }
9429#undef DECR_AND_STORE
9430
9431 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9432 tcg_temp_free(t0);
9433 tcg_temp_free(t1);
9434}
9435
9436static void gen_mips16_restore (DisasContext *ctx,
9437 int xsregs, int aregs,
9438 int do_ra, int do_s0, int do_s1,
9439 int framesize)
9440{
9441 int astatic;
9442 TCGv t0 = tcg_temp_new();
9443 TCGv t1 = tcg_temp_new();
9444
9445 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9446
2910c6cb
AJ
9447#define DECR_AND_LOAD(reg) do { \
9448 tcg_gen_subi_tl(t0, t0, 4); \
9449 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9450 gen_store_gpr(t1, reg); \
364d4831
NF
9451 } while (0)
9452
9453 if (do_ra) {
9454 DECR_AND_LOAD(31);
9455 }
9456
9457 switch (xsregs) {
9458 case 7:
9459 DECR_AND_LOAD(30);
9460 /* Fall through */
9461 case 6:
9462 DECR_AND_LOAD(23);
9463 /* Fall through */
9464 case 5:
9465 DECR_AND_LOAD(22);
9466 /* Fall through */
9467 case 4:
9468 DECR_AND_LOAD(21);
9469 /* Fall through */
9470 case 3:
9471 DECR_AND_LOAD(20);
9472 /* Fall through */
9473 case 2:
9474 DECR_AND_LOAD(19);
9475 /* Fall through */
9476 case 1:
9477 DECR_AND_LOAD(18);
9478 }
9479
9480 if (do_s1) {
9481 DECR_AND_LOAD(17);
9482 }
9483 if (do_s0) {
9484 DECR_AND_LOAD(16);
9485 }
9486
9487 switch (aregs) {
9488 case 0:
9489 case 4:
9490 case 8:
9491 case 12:
9492 case 14:
9493 astatic = 0;
9494 break;
9495 case 1:
9496 case 5:
9497 case 9:
9498 case 13:
9499 astatic = 1;
9500 break;
9501 case 2:
9502 case 6:
9503 case 10:
9504 astatic = 2;
9505 break;
9506 case 3:
9507 case 7:
9508 astatic = 3;
9509 break;
9510 case 11:
9511 astatic = 4;
9512 break;
9513 default:
9514 generate_exception(ctx, EXCP_RI);
9515 return;
9516 }
9517
9518 if (astatic > 0) {
9519 DECR_AND_LOAD(7);
9520 if (astatic > 1) {
9521 DECR_AND_LOAD(6);
9522 if (astatic > 2) {
9523 DECR_AND_LOAD(5);
9524 if (astatic > 3) {
9525 DECR_AND_LOAD(4);
9526 }
9527 }
9528 }
9529 }
9530#undef DECR_AND_LOAD
9531
9532 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9533 tcg_temp_free(t0);
9534 tcg_temp_free(t1);
9535}
9536
9537static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9538 int is_64_bit, int extended)
9539{
9540 TCGv t0;
9541
9542 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9543 generate_exception(ctx, EXCP_RI);
9544 return;
9545 }
9546
9547 t0 = tcg_temp_new();
9548
9549 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9550 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9551 if (!is_64_bit) {
9552 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9553 }
9554
9555 tcg_temp_free(t0);
9556}
9557
9558#if defined(TARGET_MIPS64)
d75c135e 9559static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9560 int ry, int funct, int16_t offset,
9561 int extended)
9562{
9563 switch (funct) {
9564 case I64_LDSP:
9565 check_mips_64(ctx);
9566 offset = extended ? offset : offset << 3;
d75c135e 9567 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9568 break;
9569 case I64_SDSP:
9570 check_mips_64(ctx);
9571 offset = extended ? offset : offset << 3;
5c13fdfd 9572 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9573 break;
9574 case I64_SDRASP:
9575 check_mips_64(ctx);
9576 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9577 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9578 break;
9579 case I64_DADJSP:
9580 check_mips_64(ctx);
9581 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9582 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9583 break;
9584 case I64_LDPC:
9585 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9586 generate_exception(ctx, EXCP_RI);
9587 } else {
9588 offset = extended ? offset : offset << 3;
d75c135e 9589 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9590 }
9591 break;
9592 case I64_DADDIU5:
9593 check_mips_64(ctx);
9594 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9595 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9596 break;
9597 case I64_DADDIUPC:
9598 check_mips_64(ctx);
9599 offset = extended ? offset : offset << 2;
9600 gen_addiupc(ctx, ry, offset, 1, extended);
9601 break;
9602 case I64_DADDIUSP:
9603 check_mips_64(ctx);
9604 offset = extended ? offset : offset << 2;
d75c135e 9605 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9606 break;
9607 }
9608}
9609#endif
9610
7db13fae 9611static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9612 int *is_branch)
9613{
895c2d04 9614 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9615 int op, rx, ry, funct, sa;
9616 int16_t imm, offset;
9617
9618 ctx->opcode = (ctx->opcode << 16) | extend;
9619 op = (ctx->opcode >> 11) & 0x1f;
9620 sa = (ctx->opcode >> 22) & 0x1f;
9621 funct = (ctx->opcode >> 8) & 0x7;
9622 rx = xlat((ctx->opcode >> 8) & 0x7);
9623 ry = xlat((ctx->opcode >> 5) & 0x7);
9624 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9625 | ((ctx->opcode >> 21) & 0x3f) << 5
9626 | (ctx->opcode & 0x1f));
9627
9628 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9629 counterparts. */
9630 switch (op) {
9631 case M16_OPC_ADDIUSP:
d75c135e 9632 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9633 break;
9634 case M16_OPC_ADDIUPC:
9635 gen_addiupc(ctx, rx, imm, 0, 1);
9636 break;
9637 case M16_OPC_B:
9638 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9639 /* No delay slot, so just process as a normal instruction */
9640 break;
9641 case M16_OPC_BEQZ:
9642 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9643 /* No delay slot, so just process as a normal instruction */
9644 break;
9645 case M16_OPC_BNEQZ:
9646 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9647 /* No delay slot, so just process as a normal instruction */
9648 break;
9649 case M16_OPC_SHIFT:
9650 switch (ctx->opcode & 0x3) {
9651 case 0x0:
d75c135e 9652 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9653 break;
9654 case 0x1:
9655#if defined(TARGET_MIPS64)
9656 check_mips_64(ctx);
d75c135e 9657 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9658#else
9659 generate_exception(ctx, EXCP_RI);
9660#endif
9661 break;
9662 case 0x2:
d75c135e 9663 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9664 break;
9665 case 0x3:
d75c135e 9666 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9667 break;
9668 }
9669 break;
9670#if defined(TARGET_MIPS64)
9671 case M16_OPC_LD:
9672 check_mips_64(ctx);
d75c135e 9673 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9674 break;
9675#endif
9676 case M16_OPC_RRIA:
9677 imm = ctx->opcode & 0xf;
9678 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9679 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9680 imm = (int16_t) (imm << 1) >> 1;
9681 if ((ctx->opcode >> 4) & 0x1) {
9682#if defined(TARGET_MIPS64)
9683 check_mips_64(ctx);
d75c135e 9684 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9685#else
9686 generate_exception(ctx, EXCP_RI);
9687#endif
9688 } else {
d75c135e 9689 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9690 }
9691 break;
9692 case M16_OPC_ADDIU8:
d75c135e 9693 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9694 break;
9695 case M16_OPC_SLTI:
d75c135e 9696 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9697 break;
9698 case M16_OPC_SLTIU:
d75c135e 9699 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9700 break;
9701 case M16_OPC_I8:
9702 switch (funct) {
9703 case I8_BTEQZ:
9704 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9705 break;
9706 case I8_BTNEZ:
9707 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9708 break;
9709 case I8_SWRASP:
5c13fdfd 9710 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9711 break;
9712 case I8_ADJSP:
d75c135e 9713 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
9714 break;
9715 case I8_SVRS:
9716 {
9717 int xsregs = (ctx->opcode >> 24) & 0x7;
9718 int aregs = (ctx->opcode >> 16) & 0xf;
9719 int do_ra = (ctx->opcode >> 6) & 0x1;
9720 int do_s0 = (ctx->opcode >> 5) & 0x1;
9721 int do_s1 = (ctx->opcode >> 4) & 0x1;
9722 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9723 | (ctx->opcode & 0xf)) << 3;
9724
9725 if (ctx->opcode & (1 << 7)) {
9726 gen_mips16_save(ctx, xsregs, aregs,
9727 do_ra, do_s0, do_s1,
9728 framesize);
9729 } else {
9730 gen_mips16_restore(ctx, xsregs, aregs,
9731 do_ra, do_s0, do_s1,
9732 framesize);
9733 }
9734 }
9735 break;
9736 default:
9737 generate_exception(ctx, EXCP_RI);
9738 break;
9739 }
9740 break;
9741 case M16_OPC_LI:
9742 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9743 break;
9744 case M16_OPC_CMPI:
9745 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9746 break;
9747#if defined(TARGET_MIPS64)
9748 case M16_OPC_SD:
5c13fdfd 9749 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9750 break;
9751#endif
9752 case M16_OPC_LB:
d75c135e 9753 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9754 break;
9755 case M16_OPC_LH:
d75c135e 9756 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9757 break;
9758 case M16_OPC_LWSP:
d75c135e 9759 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9760 break;
9761 case M16_OPC_LW:
d75c135e 9762 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9763 break;
9764 case M16_OPC_LBU:
d75c135e 9765 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9766 break;
9767 case M16_OPC_LHU:
d75c135e 9768 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9769 break;
9770 case M16_OPC_LWPC:
d75c135e 9771 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9772 break;
9773#if defined(TARGET_MIPS64)
9774 case M16_OPC_LWU:
d75c135e 9775 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9776 break;
9777#endif
9778 case M16_OPC_SB:
5c13fdfd 9779 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9780 break;
9781 case M16_OPC_SH:
5c13fdfd 9782 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9783 break;
9784 case M16_OPC_SWSP:
5c13fdfd 9785 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9786 break;
9787 case M16_OPC_SW:
5c13fdfd 9788 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9789 break;
9790#if defined(TARGET_MIPS64)
9791 case M16_OPC_I64:
d75c135e 9792 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
9793 break;
9794#endif
9795 default:
9796 generate_exception(ctx, EXCP_RI);
9797 break;
9798 }
9799
9800 return 4;
9801}
9802
7db13fae 9803static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9804 int *is_branch)
9805{
9806 int rx, ry;
9807 int sa;
9808 int op, cnvt_op, op1, offset;
9809 int funct;
9810 int n_bytes;
9811
9812 op = (ctx->opcode >> 11) & 0x1f;
9813 sa = (ctx->opcode >> 2) & 0x7;
9814 sa = sa == 0 ? 8 : sa;
9815 rx = xlat((ctx->opcode >> 8) & 0x7);
9816 cnvt_op = (ctx->opcode >> 5) & 0x7;
9817 ry = xlat((ctx->opcode >> 5) & 0x7);
9818 op1 = offset = ctx->opcode & 0x1f;
9819
9820 n_bytes = 2;
9821
9822 switch (op) {
9823 case M16_OPC_ADDIUSP:
9824 {
9825 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9826
d75c135e 9827 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9828 }
9829 break;
9830 case M16_OPC_ADDIUPC:
9831 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9832 break;
9833 case M16_OPC_B:
9834 offset = (ctx->opcode & 0x7ff) << 1;
9835 offset = (int16_t)(offset << 4) >> 4;
9836 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9837 /* No delay slot, so just process as a normal instruction */
9838 break;
9839 case M16_OPC_JAL:
895c2d04 9840 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9841 offset = (((ctx->opcode & 0x1f) << 21)
9842 | ((ctx->opcode >> 5) & 0x1f) << 16
9843 | offset) << 2;
620e48f6 9844 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9845 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9846 n_bytes = 4;
9847 *is_branch = 1;
9848 break;
9849 case M16_OPC_BEQZ:
9850 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9851 /* No delay slot, so just process as a normal instruction */
9852 break;
9853 case M16_OPC_BNEQZ:
9854 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9855 /* No delay slot, so just process as a normal instruction */
9856 break;
9857 case M16_OPC_SHIFT:
9858 switch (ctx->opcode & 0x3) {
9859 case 0x0:
d75c135e 9860 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9861 break;
9862 case 0x1:
9863#if defined(TARGET_MIPS64)
9864 check_mips_64(ctx);
d75c135e 9865 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9866#else
9867 generate_exception(ctx, EXCP_RI);
9868#endif
9869 break;
9870 case 0x2:
d75c135e 9871 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9872 break;
9873 case 0x3:
d75c135e 9874 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9875 break;
9876 }
9877 break;
9878#if defined(TARGET_MIPS64)
9879 case M16_OPC_LD:
9880 check_mips_64(ctx);
d75c135e 9881 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9882 break;
9883#endif
9884 case M16_OPC_RRIA:
9885 {
9886 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9887
9888 if ((ctx->opcode >> 4) & 1) {
9889#if defined(TARGET_MIPS64)
9890 check_mips_64(ctx);
d75c135e 9891 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9892#else
9893 generate_exception(ctx, EXCP_RI);
9894#endif
9895 } else {
d75c135e 9896 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9897 }
9898 }
9899 break;
9900 case M16_OPC_ADDIU8:
9901 {
9902 int16_t imm = (int8_t) ctx->opcode;
9903
d75c135e 9904 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9905 }
9906 break;
9907 case M16_OPC_SLTI:
9908 {
9909 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9910 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9911 }
9912 break;
9913 case M16_OPC_SLTIU:
9914 {
9915 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9916 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9917 }
9918 break;
9919 case M16_OPC_I8:
9920 {
9921 int reg32;
9922
9923 funct = (ctx->opcode >> 8) & 0x7;
9924 switch (funct) {
9925 case I8_BTEQZ:
9926 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9927 ((int8_t)ctx->opcode) << 1);
9928 break;
9929 case I8_BTNEZ:
9930 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9931 ((int8_t)ctx->opcode) << 1);
9932 break;
9933 case I8_SWRASP:
5c13fdfd 9934 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9935 break;
9936 case I8_ADJSP:
d75c135e 9937 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
9938 ((int8_t)ctx->opcode) << 3);
9939 break;
9940 case I8_SVRS:
9941 {
9942 int do_ra = ctx->opcode & (1 << 6);
9943 int do_s0 = ctx->opcode & (1 << 5);
9944 int do_s1 = ctx->opcode & (1 << 4);
9945 int framesize = ctx->opcode & 0xf;
9946
9947 if (framesize == 0) {
9948 framesize = 128;
9949 } else {
9950 framesize = framesize << 3;
9951 }
9952
9953 if (ctx->opcode & (1 << 7)) {
9954 gen_mips16_save(ctx, 0, 0,
9955 do_ra, do_s0, do_s1, framesize);
9956 } else {
9957 gen_mips16_restore(ctx, 0, 0,
9958 do_ra, do_s0, do_s1, framesize);
9959 }
9960 }
9961 break;
9962 case I8_MOV32R:
9963 {
9964 int rz = xlat(ctx->opcode & 0x7);
9965
9966 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9967 ((ctx->opcode >> 5) & 0x7);
d75c135e 9968 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
9969 }
9970 break;
9971 case I8_MOVR32:
9972 reg32 = ctx->opcode & 0x1f;
d75c135e 9973 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
9974 break;
9975 default:
9976 generate_exception(ctx, EXCP_RI);
9977 break;
9978 }
9979 }
9980 break;
9981 case M16_OPC_LI:
9982 {
9983 int16_t imm = (uint8_t) ctx->opcode;
9984
d75c135e 9985 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
9986 }
9987 break;
9988 case M16_OPC_CMPI:
9989 {
9990 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9991 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
9992 }
9993 break;
9994#if defined(TARGET_MIPS64)
9995 case M16_OPC_SD:
9996 check_mips_64(ctx);
5c13fdfd 9997 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
9998 break;
9999#endif
10000 case M16_OPC_LB:
d75c135e 10001 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10002 break;
10003 case M16_OPC_LH:
d75c135e 10004 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
10005 break;
10006 case M16_OPC_LWSP:
d75c135e 10007 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10008 break;
10009 case M16_OPC_LW:
d75c135e 10010 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10011 break;
10012 case M16_OPC_LBU:
d75c135e 10013 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10014 break;
10015 case M16_OPC_LHU:
d75c135e 10016 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10017 break;
10018 case M16_OPC_LWPC:
d75c135e 10019 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10020 break;
10021#if defined (TARGET_MIPS64)
10022 case M16_OPC_LWU:
10023 check_mips_64(ctx);
d75c135e 10024 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10025 break;
10026#endif
10027 case M16_OPC_SB:
5c13fdfd 10028 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10029 break;
10030 case M16_OPC_SH:
5c13fdfd 10031 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10032 break;
10033 case M16_OPC_SWSP:
5c13fdfd 10034 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10035 break;
10036 case M16_OPC_SW:
5c13fdfd 10037 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10038 break;
10039 case M16_OPC_RRR:
10040 {
10041 int rz = xlat((ctx->opcode >> 2) & 0x7);
10042 int mips32_op;
10043
10044 switch (ctx->opcode & 0x3) {
10045 case RRR_ADDU:
10046 mips32_op = OPC_ADDU;
10047 break;
10048 case RRR_SUBU:
10049 mips32_op = OPC_SUBU;
10050 break;
10051#if defined(TARGET_MIPS64)
10052 case RRR_DADDU:
10053 mips32_op = OPC_DADDU;
10054 check_mips_64(ctx);
10055 break;
10056 case RRR_DSUBU:
10057 mips32_op = OPC_DSUBU;
10058 check_mips_64(ctx);
10059 break;
10060#endif
10061 default:
10062 generate_exception(ctx, EXCP_RI);
10063 goto done;
10064 }
10065
d75c135e 10066 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10067 done:
10068 ;
10069 }
10070 break;
10071 case M16_OPC_RR:
10072 switch (op1) {
10073 case RR_JR:
10074 {
10075 int nd = (ctx->opcode >> 7) & 0x1;
10076 int link = (ctx->opcode >> 6) & 0x1;
10077 int ra = (ctx->opcode >> 5) & 0x1;
10078
10079 if (link) {
620e48f6 10080 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10081 } else {
10082 op = OPC_JR;
10083 }
10084
10085 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10086 if (!nd) {
10087 *is_branch = 1;
10088 }
10089 }
10090 break;
10091 case RR_SDBBP:
10092 /* XXX: not clear which exception should be raised
10093 * when in debug mode...
10094 */
d75c135e 10095 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10096 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10097 generate_exception(ctx, EXCP_DBp);
10098 } else {
10099 generate_exception(ctx, EXCP_DBp);
10100 }
10101 break;
10102 case RR_SLT:
d75c135e 10103 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10104 break;
10105 case RR_SLTU:
d75c135e 10106 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10107 break;
10108 case RR_BREAK:
10109 generate_exception(ctx, EXCP_BREAK);
10110 break;
10111 case RR_SLLV:
d75c135e 10112 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10113 break;
10114 case RR_SRLV:
d75c135e 10115 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10116 break;
10117 case RR_SRAV:
d75c135e 10118 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10119 break;
10120#if defined (TARGET_MIPS64)
10121 case RR_DSRL:
10122 check_mips_64(ctx);
d75c135e 10123 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10124 break;
10125#endif
10126 case RR_CMP:
d75c135e 10127 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10128 break;
10129 case RR_NEG:
d75c135e 10130 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10131 break;
10132 case RR_AND:
d75c135e 10133 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10134 break;
10135 case RR_OR:
d75c135e 10136 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10137 break;
10138 case RR_XOR:
d75c135e 10139 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10140 break;
10141 case RR_NOT:
d75c135e 10142 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10143 break;
10144 case RR_MFHI:
10145 gen_HILO(ctx, OPC_MFHI, rx);
10146 break;
10147 case RR_CNVT:
10148 switch (cnvt_op) {
10149 case RR_RY_CNVT_ZEB:
10150 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10151 break;
10152 case RR_RY_CNVT_ZEH:
10153 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10154 break;
10155 case RR_RY_CNVT_SEB:
10156 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10157 break;
10158 case RR_RY_CNVT_SEH:
10159 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10160 break;
10161#if defined (TARGET_MIPS64)
10162 case RR_RY_CNVT_ZEW:
10163 check_mips_64(ctx);
10164 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10165 break;
10166 case RR_RY_CNVT_SEW:
10167 check_mips_64(ctx);
10168 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10169 break;
10170#endif
10171 default:
10172 generate_exception(ctx, EXCP_RI);
10173 break;
10174 }
10175 break;
10176 case RR_MFLO:
10177 gen_HILO(ctx, OPC_MFLO, rx);
10178 break;
10179#if defined (TARGET_MIPS64)
10180 case RR_DSRA:
10181 check_mips_64(ctx);
d75c135e 10182 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10183 break;
10184 case RR_DSLLV:
10185 check_mips_64(ctx);
d75c135e 10186 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10187 break;
10188 case RR_DSRLV:
10189 check_mips_64(ctx);
d75c135e 10190 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10191 break;
10192 case RR_DSRAV:
10193 check_mips_64(ctx);
d75c135e 10194 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10195 break;
10196#endif
10197 case RR_MULT:
10198 gen_muldiv(ctx, OPC_MULT, rx, ry);
10199 break;
10200 case RR_MULTU:
10201 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10202 break;
10203 case RR_DIV:
10204 gen_muldiv(ctx, OPC_DIV, rx, ry);
10205 break;
10206 case RR_DIVU:
10207 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10208 break;
10209#if defined (TARGET_MIPS64)
10210 case RR_DMULT:
10211 check_mips_64(ctx);
10212 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10213 break;
10214 case RR_DMULTU:
10215 check_mips_64(ctx);
10216 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10217 break;
10218 case RR_DDIV:
10219 check_mips_64(ctx);
10220 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10221 break;
10222 case RR_DDIVU:
10223 check_mips_64(ctx);
10224 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10225 break;
10226#endif
10227 default:
10228 generate_exception(ctx, EXCP_RI);
10229 break;
10230 }
10231 break;
10232 case M16_OPC_EXTEND:
10233 decode_extended_mips16_opc(env, ctx, is_branch);
10234 n_bytes = 4;
10235 break;
10236#if defined(TARGET_MIPS64)
10237 case M16_OPC_I64:
10238 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10239 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10240 break;
10241#endif
10242 default:
10243 generate_exception(ctx, EXCP_RI);
10244 break;
10245 }
10246
10247 return n_bytes;
10248}
10249
211da992 10250/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10251
211da992
WRC
10252/*
10253 * microMIPS32/microMIPS64 major opcodes
10254 *
10255 * 1. MIPS Architecture for Programmers Volume II-B:
10256 * The microMIPS32 Instruction Set (Revision 3.05)
10257 *
10258 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10259 *
10260 * 2. MIPS Architecture For Programmers Volume II-A:
10261 * The MIPS64 Instruction Set (Revision 3.51)
10262 */
6af0bf9c 10263
3c824109
NF
10264enum {
10265 POOL32A = 0x00,
10266 POOL16A = 0x01,
10267 LBU16 = 0x02,
10268 MOVE16 = 0x03,
10269 ADDI32 = 0x04,
10270 LBU32 = 0x05,
10271 SB32 = 0x06,
10272 LB32 = 0x07,
10273
10274 POOL32B = 0x08,
10275 POOL16B = 0x09,
10276 LHU16 = 0x0a,
10277 ANDI16 = 0x0b,
10278 ADDIU32 = 0x0c,
10279 LHU32 = 0x0d,
10280 SH32 = 0x0e,
10281 LH32 = 0x0f,
10282
10283 POOL32I = 0x10,
10284 POOL16C = 0x11,
10285 LWSP16 = 0x12,
10286 POOL16D = 0x13,
10287 ORI32 = 0x14,
10288 POOL32F = 0x15,
211da992
WRC
10289 POOL32S = 0x16, /* MIPS64 */
10290 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10291
211da992 10292 /* 0x1f is reserved */
3c824109
NF
10293 POOL32C = 0x18,
10294 LWGP16 = 0x19,
10295 LW16 = 0x1a,
10296 POOL16E = 0x1b,
10297 XORI32 = 0x1c,
10298 JALS32 = 0x1d,
10299 ADDIUPC = 0x1e,
3c824109
NF
10300
10301 /* 0x20 is reserved */
10302 RES_20 = 0x20,
10303 POOL16F = 0x21,
10304 SB16 = 0x22,
10305 BEQZ16 = 0x23,
10306 SLTI32 = 0x24,
10307 BEQ32 = 0x25,
10308 SWC132 = 0x26,
10309 LWC132 = 0x27,
10310
10311 /* 0x28 and 0x29 are reserved */
10312 RES_28 = 0x28,
10313 RES_29 = 0x29,
10314 SH16 = 0x2a,
10315 BNEZ16 = 0x2b,
10316 SLTIU32 = 0x2c,
10317 BNE32 = 0x2d,
10318 SDC132 = 0x2e,
10319 LDC132 = 0x2f,
10320
10321 /* 0x30 and 0x31 are reserved */
10322 RES_30 = 0x30,
10323 RES_31 = 0x31,
10324 SWSP16 = 0x32,
10325 B16 = 0x33,
10326 ANDI32 = 0x34,
10327 J32 = 0x35,
211da992
WRC
10328 SD32 = 0x36, /* MIPS64 */
10329 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10330
10331 /* 0x38 and 0x39 are reserved */
10332 RES_38 = 0x38,
10333 RES_39 = 0x39,
10334 SW16 = 0x3a,
10335 LI16 = 0x3b,
10336 JALX32 = 0x3c,
10337 JAL32 = 0x3d,
10338 SW32 = 0x3e,
10339 LW32 = 0x3f
10340};
10341
10342/* POOL32A encoding of minor opcode field */
10343
10344enum {
10345 /* These opcodes are distinguished only by bits 9..6; those bits are
10346 * what are recorded below. */
10347 SLL32 = 0x0,
10348 SRL32 = 0x1,
10349 SRA = 0x2,
10350 ROTR = 0x3,
10351
10352 SLLV = 0x0,
10353 SRLV = 0x1,
10354 SRAV = 0x2,
10355 ROTRV = 0x3,
10356 ADD = 0x4,
10357 ADDU32 = 0x5,
10358 SUB = 0x6,
10359 SUBU32 = 0x7,
10360 MUL = 0x8,
10361 AND = 0x9,
10362 OR32 = 0xa,
10363 NOR = 0xb,
10364 XOR32 = 0xc,
10365 SLT = 0xd,
10366 SLTU = 0xe,
10367
10368 MOVN = 0x0,
10369 MOVZ = 0x1,
10370 LWXS = 0x4,
10371
10372 /* The following can be distinguished by their lower 6 bits. */
10373 INS = 0x0c,
10374 EXT = 0x2c,
10375 POOL32AXF = 0x3c
10376};
10377
10378/* POOL32AXF encoding of minor opcode field extension */
10379
d132c79f
WRC
10380/*
10381 * 1. MIPS Architecture for Programmers Volume II-B:
10382 * The microMIPS32 Instruction Set (Revision 3.05)
10383 *
10384 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10385 *
10386 * 2. MIPS Architecture for Programmers VolumeIV-e:
10387 * The MIPS DSP Application-Specific Extension
10388 * to the microMIPS32 Architecture (Revision 2.34)
10389 *
10390 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10391 */
10392
3c824109
NF
10393enum {
10394 /* bits 11..6 */
10395 TEQ = 0x00,
10396 TGE = 0x08,
10397 TGEU = 0x10,
10398 TLT = 0x20,
10399 TLTU = 0x28,
10400 TNE = 0x30,
10401
10402 MFC0 = 0x03,
10403 MTC0 = 0x0b,
10404
d132c79f
WRC
10405 /* begin of microMIPS32 DSP */
10406
3c824109
NF
10407 /* bits 13..12 for 0x01 */
10408 MFHI_ACC = 0x0,
10409 MFLO_ACC = 0x1,
10410 MTHI_ACC = 0x2,
10411 MTLO_ACC = 0x3,
10412
10413 /* bits 13..12 for 0x2a */
10414 MADD_ACC = 0x0,
10415 MADDU_ACC = 0x1,
10416 MSUB_ACC = 0x2,
10417 MSUBU_ACC = 0x3,
10418
10419 /* bits 13..12 for 0x32 */
10420 MULT_ACC = 0x0,
6801038b 10421 MULTU_ACC = 0x1,
3c824109 10422
d132c79f
WRC
10423 /* end of microMIPS32 DSP */
10424
3c824109
NF
10425 /* bits 15..12 for 0x2c */
10426 SEB = 0x2,
10427 SEH = 0x3,
10428 CLO = 0x4,
10429 CLZ = 0x5,
10430 RDHWR = 0x6,
10431 WSBH = 0x7,
10432 MULT = 0x8,
10433 MULTU = 0x9,
10434 DIV = 0xa,
10435 DIVU = 0xb,
10436 MADD = 0xc,
10437 MADDU = 0xd,
10438 MSUB = 0xe,
10439 MSUBU = 0xf,
10440
10441 /* bits 15..12 for 0x34 */
10442 MFC2 = 0x4,
10443 MTC2 = 0x5,
10444 MFHC2 = 0x8,
10445 MTHC2 = 0x9,
10446 CFC2 = 0xc,
10447 CTC2 = 0xd,
10448
10449 /* bits 15..12 for 0x3c */
10450 JALR = 0x0,
10451 JR = 0x0, /* alias */
10452 JALR_HB = 0x1,
10453 JALRS = 0x4,
10454 JALRS_HB = 0x5,
10455
10456 /* bits 15..12 for 0x05 */
10457 RDPGPR = 0xe,
10458 WRPGPR = 0xf,
10459
10460 /* bits 15..12 for 0x0d */
10461 TLBP = 0x0,
10462 TLBR = 0x1,
10463 TLBWI = 0x2,
10464 TLBWR = 0x3,
10465 WAIT = 0x9,
10466 IRET = 0xd,
10467 DERET = 0xe,
10468 ERET = 0xf,
10469
10470 /* bits 15..12 for 0x15 */
10471 DMT = 0x0,
10472 DVPE = 0x1,
10473 EMT = 0x2,
10474 EVPE = 0x3,
10475
10476 /* bits 15..12 for 0x1d */
10477 DI = 0x4,
10478 EI = 0x5,
10479
10480 /* bits 15..12 for 0x2d */
10481 SYNC = 0x6,
10482 SYSCALL = 0x8,
10483 SDBBP = 0xd,
10484
10485 /* bits 15..12 for 0x35 */
10486 MFHI32 = 0x0,
10487 MFLO32 = 0x1,
10488 MTHI32 = 0x2,
10489 MTLO32 = 0x3,
10490};
10491
10492/* POOL32B encoding of minor opcode field (bits 15..12) */
10493
10494enum {
10495 LWC2 = 0x0,
10496 LWP = 0x1,
10497 LDP = 0x4,
10498 LWM32 = 0x5,
10499 CACHE = 0x6,
10500 LDM = 0x7,
10501 SWC2 = 0x8,
10502 SWP = 0x9,
10503 SDP = 0xc,
10504 SWM32 = 0xd,
10505 SDM = 0xf
10506};
10507
10508/* POOL32C encoding of minor opcode field (bits 15..12) */
10509
10510enum {
10511 LWL = 0x0,
10512 SWL = 0x8,
10513 LWR = 0x1,
10514 SWR = 0x9,
10515 PREF = 0x2,
10516 /* 0xa is reserved */
10517 LL = 0x3,
10518 SC = 0xb,
10519 LDL = 0x4,
10520 SDL = 0xc,
10521 LDR = 0x5,
10522 SDR = 0xd,
10523 /* 0x6 is reserved */
10524 LWU = 0xe,
10525 LLD = 0x7,
10526 SCD = 0xf
10527};
10528
10529/* POOL32F encoding of minor opcode field (bits 5..0) */
10530
10531enum {
10532 /* These are the bit 7..6 values */
10533 ADD_FMT = 0x0,
10534 MOVN_FMT = 0x0,
10535
10536 SUB_FMT = 0x1,
10537 MOVZ_FMT = 0x1,
10538
10539 MUL_FMT = 0x2,
10540
10541 DIV_FMT = 0x3,
10542
10543 /* These are the bit 8..6 values */
10544 RSQRT2_FMT = 0x0,
10545 MOVF_FMT = 0x0,
10546
10547 LWXC1 = 0x1,
10548 MOVT_FMT = 0x1,
10549
10550 PLL_PS = 0x2,
10551 SWXC1 = 0x2,
10552
10553 PLU_PS = 0x3,
10554 LDXC1 = 0x3,
10555
10556 PUL_PS = 0x4,
10557 SDXC1 = 0x4,
10558 RECIP2_FMT = 0x4,
10559
10560 PUU_PS = 0x5,
10561 LUXC1 = 0x5,
10562
10563 CVT_PS_S = 0x6,
10564 SUXC1 = 0x6,
10565 ADDR_PS = 0x6,
10566 PREFX = 0x6,
10567
10568 MULR_PS = 0x7,
10569
10570 MADD_S = 0x01,
10571 MADD_D = 0x09,
10572 MADD_PS = 0x11,
10573 ALNV_PS = 0x19,
10574 MSUB_S = 0x21,
10575 MSUB_D = 0x29,
10576 MSUB_PS = 0x31,
10577
10578 NMADD_S = 0x02,
10579 NMADD_D = 0x0a,
10580 NMADD_PS = 0x12,
10581 NMSUB_S = 0x22,
10582 NMSUB_D = 0x2a,
10583 NMSUB_PS = 0x32,
10584
10585 POOL32FXF = 0x3b,
10586
10587 CABS_COND_FMT = 0x1c, /* MIPS3D */
10588 C_COND_FMT = 0x3c
10589};
10590
10591/* POOL32Fxf encoding of minor opcode extension field */
10592
10593enum {
10594 CVT_L = 0x04,
10595 RSQRT_FMT = 0x08,
10596 FLOOR_L = 0x0c,
10597 CVT_PW_PS = 0x1c,
10598 CVT_W = 0x24,
10599 SQRT_FMT = 0x28,
10600 FLOOR_W = 0x2c,
10601 CVT_PS_PW = 0x3c,
10602 CFC1 = 0x40,
10603 RECIP_FMT = 0x48,
10604 CEIL_L = 0x4c,
10605 CTC1 = 0x60,
10606 CEIL_W = 0x6c,
10607 MFC1 = 0x80,
10608 CVT_S_PL = 0x84,
10609 TRUNC_L = 0x8c,
10610 MTC1 = 0xa0,
10611 CVT_S_PU = 0xa4,
10612 TRUNC_W = 0xac,
10613 MFHC1 = 0xc0,
10614 ROUND_L = 0xcc,
10615 MTHC1 = 0xe0,
10616 ROUND_W = 0xec,
10617
10618 MOV_FMT = 0x01,
10619 MOVF = 0x05,
10620 ABS_FMT = 0x0d,
10621 RSQRT1_FMT = 0x1d,
10622 MOVT = 0x25,
10623 NEG_FMT = 0x2d,
10624 CVT_D = 0x4d,
10625 RECIP1_FMT = 0x5d,
10626 CVT_S = 0x6d
10627};
10628
10629/* POOL32I encoding of minor opcode field (bits 25..21) */
10630
10631enum {
10632 BLTZ = 0x00,
10633 BLTZAL = 0x01,
10634 BGEZ = 0x02,
10635 BGEZAL = 0x03,
10636 BLEZ = 0x04,
10637 BNEZC = 0x05,
10638 BGTZ = 0x06,
10639 BEQZC = 0x07,
10640 TLTI = 0x08,
10641 TGEI = 0x09,
10642 TLTIU = 0x0a,
10643 TGEIU = 0x0b,
10644 TNEI = 0x0c,
10645 LUI = 0x0d,
10646 TEQI = 0x0e,
10647 SYNCI = 0x10,
10648 BLTZALS = 0x11,
10649 BGEZALS = 0x13,
10650 BC2F = 0x14,
10651 BC2T = 0x15,
10652 BPOSGE64 = 0x1a,
10653 BPOSGE32 = 0x1b,
10654 /* These overlap and are distinguished by bit16 of the instruction */
10655 BC1F = 0x1c,
10656 BC1T = 0x1d,
10657 BC1ANY2F = 0x1c,
10658 BC1ANY2T = 0x1d,
10659 BC1ANY4F = 0x1e,
10660 BC1ANY4T = 0x1f
10661};
10662
10663/* POOL16A encoding of minor opcode field */
10664
10665enum {
10666 ADDU16 = 0x0,
10667 SUBU16 = 0x1
10668};
10669
10670/* POOL16B encoding of minor opcode field */
10671
10672enum {
10673 SLL16 = 0x0,
10674 SRL16 = 0x1
10675};
10676
10677/* POOL16C encoding of minor opcode field */
10678
10679enum {
10680 NOT16 = 0x00,
10681 XOR16 = 0x04,
10682 AND16 = 0x08,
10683 OR16 = 0x0c,
10684 LWM16 = 0x10,
10685 SWM16 = 0x14,
10686 JR16 = 0x18,
10687 JRC16 = 0x1a,
10688 JALR16 = 0x1c,
10689 JALR16S = 0x1e,
10690 MFHI16 = 0x20,
10691 MFLO16 = 0x24,
10692 BREAK16 = 0x28,
10693 SDBBP16 = 0x2c,
10694 JRADDIUSP = 0x30
10695};
10696
10697/* POOL16D encoding of minor opcode field */
10698
10699enum {
10700 ADDIUS5 = 0x0,
10701 ADDIUSP = 0x1
10702};
10703
10704/* POOL16E encoding of minor opcode field */
10705
10706enum {
10707 ADDIUR2 = 0x0,
10708 ADDIUR1SP = 0x1
10709};
10710
10711static int mmreg (int r)
10712{
10713 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10714
10715 return map[r];
10716}
10717
10718/* Used for 16-bit store instructions. */
10719static int mmreg2 (int r)
10720{
10721 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10722
10723 return map[r];
10724}
10725
10726#define uMIPS_RD(op) ((op >> 7) & 0x7)
10727#define uMIPS_RS(op) ((op >> 4) & 0x7)
10728#define uMIPS_RS2(op) uMIPS_RS(op)
10729#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10730#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10731#define uMIPS_RS5(op) (op & 0x1f)
10732
10733/* Signed immediate */
10734#define SIMM(op, start, width) \
10735 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10736 << (32-width)) \
10737 >> (32-width))
10738/* Zero-extended immediate */
10739#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10740
d75c135e 10741static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
10742{
10743 int rd = mmreg(uMIPS_RD(ctx->opcode));
10744
d75c135e 10745 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
10746}
10747
d75c135e 10748static void gen_addiur2(DisasContext *ctx)
3c824109
NF
10749{
10750 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10751 int rd = mmreg(uMIPS_RD(ctx->opcode));
10752 int rs = mmreg(uMIPS_RS(ctx->opcode));
10753
d75c135e 10754 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
10755}
10756
d75c135e 10757static void gen_addiusp(DisasContext *ctx)
3c824109
NF
10758{
10759 int encoded = ZIMM(ctx->opcode, 1, 9);
10760 int decoded;
10761
10762 if (encoded <= 1) {
10763 decoded = 256 + encoded;
10764 } else if (encoded <= 255) {
10765 decoded = encoded;
10766 } else if (encoded <= 509) {
10767 decoded = encoded - 512;
10768 } else {
10769 decoded = encoded - 768;
10770 }
10771
d75c135e 10772 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
10773}
10774
d75c135e 10775static void gen_addius5(DisasContext *ctx)
3c824109
NF
10776{
10777 int imm = SIMM(ctx->opcode, 1, 4);
10778 int rd = (ctx->opcode >> 5) & 0x1f;
10779
d75c135e 10780 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
10781}
10782
d75c135e 10783static void gen_andi16(DisasContext *ctx)
3c824109
NF
10784{
10785 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10786 31, 32, 63, 64, 255, 32768, 65535 };
10787 int rd = mmreg(uMIPS_RD(ctx->opcode));
10788 int rs = mmreg(uMIPS_RS(ctx->opcode));
10789 int encoded = ZIMM(ctx->opcode, 0, 4);
10790
d75c135e 10791 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10792}
10793
10794static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10795 int base, int16_t offset)
10796{
e1050a76 10797 const char *opn = "ldst_multiple";
3c824109
NF
10798 TCGv t0, t1;
10799 TCGv_i32 t2;
10800
10801 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10802 generate_exception(ctx, EXCP_RI);
10803 return;
10804 }
10805
10806 t0 = tcg_temp_new();
10807
10808 gen_base_offset_addr(ctx, t0, base, offset);
10809
10810 t1 = tcg_const_tl(reglist);
10811 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10812
3c824109
NF
10813 save_cpu_state(ctx, 1);
10814 switch (opc) {
10815 case LWM32:
895c2d04 10816 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10817 opn = "lwm";
3c824109
NF
10818 break;
10819 case SWM32:
895c2d04 10820 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10821 opn = "swm";
3c824109
NF
10822 break;
10823#ifdef TARGET_MIPS64
10824 case LDM:
895c2d04 10825 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10826 opn = "ldm";
3c824109
NF
10827 break;
10828 case SDM:
895c2d04 10829 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10830 opn = "sdm";
3c824109 10831 break;
6af0bf9c 10832#endif
3c824109 10833 }
e1050a76 10834 (void)opn;
3c824109
NF
10835 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10836 tcg_temp_free(t0);
33087598 10837 tcg_temp_free(t1);
3c824109
NF
10838 tcg_temp_free_i32(t2);
10839}
6af0bf9c 10840
3c824109 10841
d75c135e 10842static void gen_pool16c_insn(DisasContext *ctx, int *is_branch)
6af0bf9c 10843{
3c824109
NF
10844 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10845 int rs = mmreg(ctx->opcode & 0x7);
10846 int opc;
6af0bf9c 10847
3c824109
NF
10848 switch (((ctx->opcode) >> 4) & 0x3f) {
10849 case NOT16 + 0:
10850 case NOT16 + 1:
10851 case NOT16 + 2:
10852 case NOT16 + 3:
d75c135e 10853 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10854 break;
10855 case XOR16 + 0:
10856 case XOR16 + 1:
10857 case XOR16 + 2:
10858 case XOR16 + 3:
d75c135e 10859 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10860 break;
10861 case AND16 + 0:
10862 case AND16 + 1:
10863 case AND16 + 2:
10864 case AND16 + 3:
d75c135e 10865 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10866 break;
10867 case OR16 + 0:
10868 case OR16 + 1:
10869 case OR16 + 2:
10870 case OR16 + 3:
d75c135e 10871 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10872 break;
10873 case LWM16 + 0:
10874 case LWM16 + 1:
10875 case LWM16 + 2:
10876 case LWM16 + 3:
10877 {
10878 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10879 int offset = ZIMM(ctx->opcode, 0, 4);
10880
10881 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10882 29, offset << 2);
10883 }
10884 break;
10885 case SWM16 + 0:
10886 case SWM16 + 1:
10887 case SWM16 + 2:
10888 case SWM16 + 3:
10889 {
10890 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10891 int offset = ZIMM(ctx->opcode, 0, 4);
10892
10893 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10894 29, offset << 2);
10895 }
10896 break;
10897 case JR16 + 0:
10898 case JR16 + 1:
10899 {
10900 int reg = ctx->opcode & 0x1f;
10901
10902 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10903 }
10904 *is_branch = 1;
10905 break;
10906 case JRC16 + 0:
10907 case JRC16 + 1:
10908 {
10909 int reg = ctx->opcode & 0x1f;
10910
10911 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10912 /* Let normal delay slot handling in our caller take us
10913 to the branch target. */
10914 }
10915 break;
10916 case JALR16 + 0:
10917 case JALR16 + 1:
10918 opc = OPC_JALR;
10919 goto do_jalr;
10920 case JALR16S + 0:
10921 case JALR16S + 1:
10922 opc = OPC_JALRS;
10923 do_jalr:
10924 {
10925 int reg = ctx->opcode & 0x1f;
10926
10927 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10928 }
10929 *is_branch = 1;
10930 break;
10931 case MFHI16 + 0:
10932 case MFHI16 + 1:
10933 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10934 break;
10935 case MFLO16 + 0:
10936 case MFLO16 + 1:
10937 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10938 break;
10939 case BREAK16:
10940 generate_exception(ctx, EXCP_BREAK);
10941 break;
10942 case SDBBP16:
10943 /* XXX: not clear which exception should be raised
10944 * when in debug mode...
10945 */
d75c135e 10946 check_insn(ctx, ISA_MIPS32);
3c824109
NF
10947 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10948 generate_exception(ctx, EXCP_DBp);
10949 } else {
10950 generate_exception(ctx, EXCP_DBp);
10951 }
10952 break;
10953 case JRADDIUSP + 0:
10954 case JRADDIUSP + 1:
10955 {
10956 int imm = ZIMM(ctx->opcode, 0, 5);
10957
10958 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 10959 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
10960 /* Let normal delay slot handling in our caller take us
10961 to the branch target. */
10962 }
10963 break;
10964 default:
10965 generate_exception(ctx, EXCP_RI);
10966 break;
10967 }
10968}
10969
10970static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10971{
10972 TCGv t0 = tcg_temp_new();
10973 TCGv t1 = tcg_temp_new();
10974
10975 gen_load_gpr(t0, base);
10976
10977 if (index != 0) {
10978 gen_load_gpr(t1, index);
10979 tcg_gen_shli_tl(t1, t1, 2);
10980 gen_op_addr_add(ctx, t0, t1, t0);
10981 }
10982
2910c6cb 10983 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
10984 gen_store_gpr(t1, rd);
10985
10986 tcg_temp_free(t0);
10987 tcg_temp_free(t1);
10988}
10989
10990static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10991 int base, int16_t offset)
10992{
10993 const char *opn = "ldst_pair";
10994 TCGv t0, t1;
10995
36c6711b 10996 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 10997 generate_exception(ctx, EXCP_RI);
d796321b
FB
10998 return;
10999 }
11000
3c824109
NF
11001 t0 = tcg_temp_new();
11002 t1 = tcg_temp_new();
8e9ade68 11003
3c824109
NF
11004 gen_base_offset_addr(ctx, t0, base, offset);
11005
11006 switch (opc) {
11007 case LWP:
36c6711b
EJ
11008 if (rd == base) {
11009 generate_exception(ctx, EXCP_RI);
11010 return;
11011 }
2910c6cb 11012 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11013 gen_store_gpr(t1, rd);
11014 tcg_gen_movi_tl(t1, 4);
11015 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11016 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11017 gen_store_gpr(t1, rd+1);
11018 opn = "lwp";
11019 break;
11020 case SWP:
3c824109 11021 gen_load_gpr(t1, rd);
2910c6cb 11022 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11023 tcg_gen_movi_tl(t1, 4);
11024 gen_op_addr_add(ctx, t0, t0, t1);
11025 gen_load_gpr(t1, rd+1);
2910c6cb 11026 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11027 opn = "swp";
11028 break;
11029#ifdef TARGET_MIPS64
11030 case LDP:
36c6711b
EJ
11031 if (rd == base) {
11032 generate_exception(ctx, EXCP_RI);
11033 return;
11034 }
2910c6cb 11035 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11036 gen_store_gpr(t1, rd);
11037 tcg_gen_movi_tl(t1, 8);
11038 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11039 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11040 gen_store_gpr(t1, rd+1);
11041 opn = "ldp";
11042 break;
11043 case SDP:
3c824109 11044 gen_load_gpr(t1, rd);
2910c6cb 11045 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11046 tcg_gen_movi_tl(t1, 8);
11047 gen_op_addr_add(ctx, t0, t0, t1);
11048 gen_load_gpr(t1, rd+1);
2910c6cb 11049 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11050 opn = "sdp";
11051 break;
11052#endif
6af0bf9c 11053 }
2abf314d 11054 (void)opn; /* avoid a compiler warning */
3c824109
NF
11055 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11056 tcg_temp_free(t0);
11057 tcg_temp_free(t1);
11058}
618b0fe9 11059
7db13fae 11060static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
3c824109
NF
11061 int *is_branch)
11062{
11063 int extension = (ctx->opcode >> 6) & 0x3f;
11064 int minor = (ctx->opcode >> 12) & 0xf;
11065 uint32_t mips32_op;
11066
11067 switch (extension) {
11068 case TEQ:
11069 mips32_op = OPC_TEQ;
11070 goto do_trap;
11071 case TGE:
11072 mips32_op = OPC_TGE;
11073 goto do_trap;
11074 case TGEU:
11075 mips32_op = OPC_TGEU;
11076 goto do_trap;
11077 case TLT:
11078 mips32_op = OPC_TLT;
11079 goto do_trap;
11080 case TLTU:
11081 mips32_op = OPC_TLTU;
11082 goto do_trap;
11083 case TNE:
11084 mips32_op = OPC_TNE;
11085 do_trap:
11086 gen_trap(ctx, mips32_op, rs, rt, -1);
11087 break;
11088#ifndef CONFIG_USER_ONLY
11089 case MFC0:
11090 case MFC0 + 32:
2e15497c 11091 check_cp0_enabled(ctx);
3c824109
NF
11092 if (rt == 0) {
11093 /* Treat as NOP. */
11094 break;
11095 }
d75c135e 11096 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11097 break;
11098 case MTC0:
11099 case MTC0 + 32:
2e15497c 11100 check_cp0_enabled(ctx);
3c824109
NF
11101 {
11102 TCGv t0 = tcg_temp_new();
618b0fe9 11103
3c824109 11104 gen_load_gpr(t0, rt);
d75c135e 11105 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11106 tcg_temp_free(t0);
11107 }
11108 break;
11109#endif
11110 case 0x2c:
11111 switch (minor) {
11112 case SEB:
11113 gen_bshfl(ctx, OPC_SEB, rs, rt);
11114 break;
11115 case SEH:
11116 gen_bshfl(ctx, OPC_SEH, rs, rt);
11117 break;
11118 case CLO:
11119 mips32_op = OPC_CLO;
11120 goto do_cl;
11121 case CLZ:
11122 mips32_op = OPC_CLZ;
11123 do_cl:
d75c135e 11124 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11125 gen_cl(ctx, mips32_op, rt, rs);
11126 break;
11127 case RDHWR:
d75c135e 11128 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11129 break;
11130 case WSBH:
11131 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11132 break;
11133 case MULT:
11134 mips32_op = OPC_MULT;
11135 goto do_muldiv;
11136 case MULTU:
11137 mips32_op = OPC_MULTU;
11138 goto do_muldiv;
11139 case DIV:
11140 mips32_op = OPC_DIV;
11141 goto do_muldiv;
11142 case DIVU:
11143 mips32_op = OPC_DIVU;
11144 goto do_muldiv;
11145 case MADD:
11146 mips32_op = OPC_MADD;
11147 goto do_muldiv;
11148 case MADDU:
11149 mips32_op = OPC_MADDU;
11150 goto do_muldiv;
11151 case MSUB:
11152 mips32_op = OPC_MSUB;
11153 goto do_muldiv;
11154 case MSUBU:
11155 mips32_op = OPC_MSUBU;
11156 do_muldiv:
d75c135e 11157 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11158 gen_muldiv(ctx, mips32_op, rs, rt);
11159 break;
11160 default:
11161 goto pool32axf_invalid;
11162 }
11163 break;
11164 case 0x34:
11165 switch (minor) {
11166 case MFC2:
11167 case MTC2:
11168 case MFHC2:
11169 case MTHC2:
11170 case CFC2:
11171 case CTC2:
11172 generate_exception_err(ctx, EXCP_CpU, 2);
11173 break;
11174 default:
11175 goto pool32axf_invalid;
11176 }
11177 break;
11178 case 0x3c:
11179 switch (minor) {
11180 case JALR:
11181 case JALR_HB:
11182 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11183 *is_branch = 1;
11184 break;
11185 case JALRS:
11186 case JALRS_HB:
11187 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11188 *is_branch = 1;
11189 break;
11190 default:
11191 goto pool32axf_invalid;
11192 }
11193 break;
11194 case 0x05:
11195 switch (minor) {
11196 case RDPGPR:
2e15497c 11197 check_cp0_enabled(ctx);
d75c135e 11198 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11199 gen_load_srsgpr(rt, rs);
11200 break;
11201 case WRPGPR:
2e15497c 11202 check_cp0_enabled(ctx);
d75c135e 11203 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11204 gen_store_srsgpr(rt, rs);
11205 break;
11206 default:
11207 goto pool32axf_invalid;
11208 }
11209 break;
11210#ifndef CONFIG_USER_ONLY
11211 case 0x0d:
11212 switch (minor) {
11213 case TLBP:
11214 mips32_op = OPC_TLBP;
11215 goto do_cp0;
11216 case TLBR:
11217 mips32_op = OPC_TLBR;
11218 goto do_cp0;
11219 case TLBWI:
11220 mips32_op = OPC_TLBWI;
11221 goto do_cp0;
11222 case TLBWR:
11223 mips32_op = OPC_TLBWR;
11224 goto do_cp0;
11225 case WAIT:
11226 mips32_op = OPC_WAIT;
11227 goto do_cp0;
11228 case DERET:
11229 mips32_op = OPC_DERET;
11230 goto do_cp0;
11231 case ERET:
11232 mips32_op = OPC_ERET;
11233 do_cp0:
11234 gen_cp0(env, ctx, mips32_op, rt, rs);
11235 break;
11236 default:
11237 goto pool32axf_invalid;
11238 }
11239 break;
11240 case 0x1d:
11241 switch (minor) {
11242 case DI:
2e15497c 11243 check_cp0_enabled(ctx);
3c824109
NF
11244 {
11245 TCGv t0 = tcg_temp_new();
11246
11247 save_cpu_state(ctx, 1);
895c2d04 11248 gen_helper_di(t0, cpu_env);
3c824109
NF
11249 gen_store_gpr(t0, rs);
11250 /* Stop translation as we may have switched the execution mode */
11251 ctx->bstate = BS_STOP;
11252 tcg_temp_free(t0);
11253 }
11254 break;
11255 case EI:
2e15497c 11256 check_cp0_enabled(ctx);
3c824109
NF
11257 {
11258 TCGv t0 = tcg_temp_new();
11259
11260 save_cpu_state(ctx, 1);
895c2d04 11261 gen_helper_ei(t0, cpu_env);
3c824109
NF
11262 gen_store_gpr(t0, rs);
11263 /* Stop translation as we may have switched the execution mode */
11264 ctx->bstate = BS_STOP;
11265 tcg_temp_free(t0);
11266 }
11267 break;
11268 default:
11269 goto pool32axf_invalid;
11270 }
11271 break;
11272#endif
11273 case 0x2d:
11274 switch (minor) {
11275 case SYNC:
11276 /* NOP */
11277 break;
11278 case SYSCALL:
11279 generate_exception(ctx, EXCP_SYSCALL);
11280 ctx->bstate = BS_STOP;
11281 break;
11282 case SDBBP:
d75c135e 11283 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11284 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11285 generate_exception(ctx, EXCP_DBp);
11286 } else {
11287 generate_exception(ctx, EXCP_DBp);
11288 }
11289 break;
11290 default:
11291 goto pool32axf_invalid;
11292 }
11293 break;
11294 case 0x35:
11295 switch (minor) {
11296 case MFHI32:
11297 gen_HILO(ctx, OPC_MFHI, rs);
11298 break;
11299 case MFLO32:
11300 gen_HILO(ctx, OPC_MFLO, rs);
11301 break;
11302 case MTHI32:
11303 gen_HILO(ctx, OPC_MTHI, rs);
11304 break;
11305 case MTLO32:
11306 gen_HILO(ctx, OPC_MTLO, rs);
11307 break;
11308 default:
11309 goto pool32axf_invalid;
11310 }
11311 break;
11312 default:
11313 pool32axf_invalid:
11314 MIPS_INVAL("pool32axf");
11315 generate_exception(ctx, EXCP_RI);
11316 break;
11317 }
11318}
11319
11320/* Values for microMIPS fmt field. Variable-width, depending on which
11321 formats the instruction supports. */
11322
11323enum {
11324 FMT_SD_S = 0,
11325 FMT_SD_D = 1,
11326
11327 FMT_SDPS_S = 0,
11328 FMT_SDPS_D = 1,
11329 FMT_SDPS_PS = 2,
11330
11331 FMT_SWL_S = 0,
11332 FMT_SWL_W = 1,
11333 FMT_SWL_L = 2,
11334
11335 FMT_DWL_D = 0,
11336 FMT_DWL_W = 1,
11337 FMT_DWL_L = 2
11338};
11339
d75c135e 11340static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11341{
11342 int extension = (ctx->opcode >> 6) & 0x3ff;
11343 uint32_t mips32_op;
11344
11345#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11346#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11347#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11348
11349 switch (extension) {
11350 case FLOAT_1BIT_FMT(CFC1, 0):
11351 mips32_op = OPC_CFC1;
11352 goto do_cp1;
11353 case FLOAT_1BIT_FMT(CTC1, 0):
11354 mips32_op = OPC_CTC1;
11355 goto do_cp1;
11356 case FLOAT_1BIT_FMT(MFC1, 0):
11357 mips32_op = OPC_MFC1;
11358 goto do_cp1;
11359 case FLOAT_1BIT_FMT(MTC1, 0):
11360 mips32_op = OPC_MTC1;
11361 goto do_cp1;
11362 case FLOAT_1BIT_FMT(MFHC1, 0):
11363 mips32_op = OPC_MFHC1;
11364 goto do_cp1;
11365 case FLOAT_1BIT_FMT(MTHC1, 0):
11366 mips32_op = OPC_MTHC1;
11367 do_cp1:
11368 gen_cp1(ctx, mips32_op, rt, rs);
11369 break;
11370
11371 /* Reciprocal square root */
11372 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11373 mips32_op = OPC_RSQRT_S;
11374 goto do_unaryfp;
11375 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11376 mips32_op = OPC_RSQRT_D;
11377 goto do_unaryfp;
11378
11379 /* Square root */
11380 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11381 mips32_op = OPC_SQRT_S;
11382 goto do_unaryfp;
11383 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11384 mips32_op = OPC_SQRT_D;
11385 goto do_unaryfp;
11386
11387 /* Reciprocal */
11388 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11389 mips32_op = OPC_RECIP_S;
11390 goto do_unaryfp;
11391 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11392 mips32_op = OPC_RECIP_D;
11393 goto do_unaryfp;
11394
11395 /* Floor */
11396 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11397 mips32_op = OPC_FLOOR_L_S;
11398 goto do_unaryfp;
11399 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11400 mips32_op = OPC_FLOOR_L_D;
11401 goto do_unaryfp;
11402 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11403 mips32_op = OPC_FLOOR_W_S;
11404 goto do_unaryfp;
11405 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11406 mips32_op = OPC_FLOOR_W_D;
11407 goto do_unaryfp;
11408
11409 /* Ceiling */
11410 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11411 mips32_op = OPC_CEIL_L_S;
11412 goto do_unaryfp;
11413 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11414 mips32_op = OPC_CEIL_L_D;
11415 goto do_unaryfp;
11416 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11417 mips32_op = OPC_CEIL_W_S;
11418 goto do_unaryfp;
11419 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11420 mips32_op = OPC_CEIL_W_D;
11421 goto do_unaryfp;
11422
11423 /* Truncation */
11424 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11425 mips32_op = OPC_TRUNC_L_S;
11426 goto do_unaryfp;
11427 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11428 mips32_op = OPC_TRUNC_L_D;
11429 goto do_unaryfp;
11430 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11431 mips32_op = OPC_TRUNC_W_S;
11432 goto do_unaryfp;
11433 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11434 mips32_op = OPC_TRUNC_W_D;
11435 goto do_unaryfp;
11436
11437 /* Round */
11438 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11439 mips32_op = OPC_ROUND_L_S;
11440 goto do_unaryfp;
11441 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11442 mips32_op = OPC_ROUND_L_D;
11443 goto do_unaryfp;
11444 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11445 mips32_op = OPC_ROUND_W_S;
11446 goto do_unaryfp;
11447 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11448 mips32_op = OPC_ROUND_W_D;
11449 goto do_unaryfp;
11450
11451 /* Integer to floating-point conversion */
11452 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11453 mips32_op = OPC_CVT_L_S;
11454 goto do_unaryfp;
11455 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11456 mips32_op = OPC_CVT_L_D;
11457 goto do_unaryfp;
11458 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11459 mips32_op = OPC_CVT_W_S;
11460 goto do_unaryfp;
11461 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11462 mips32_op = OPC_CVT_W_D;
11463 goto do_unaryfp;
11464
11465 /* Paired-foo conversions */
11466 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11467 mips32_op = OPC_CVT_S_PL;
11468 goto do_unaryfp;
11469 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11470 mips32_op = OPC_CVT_S_PU;
11471 goto do_unaryfp;
11472 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11473 mips32_op = OPC_CVT_PW_PS;
11474 goto do_unaryfp;
11475 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11476 mips32_op = OPC_CVT_PS_PW;
11477 goto do_unaryfp;
11478
11479 /* Floating-point moves */
11480 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11481 mips32_op = OPC_MOV_S;
11482 goto do_unaryfp;
11483 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11484 mips32_op = OPC_MOV_D;
11485 goto do_unaryfp;
11486 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11487 mips32_op = OPC_MOV_PS;
11488 goto do_unaryfp;
11489
11490 /* Absolute value */
11491 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11492 mips32_op = OPC_ABS_S;
11493 goto do_unaryfp;
11494 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11495 mips32_op = OPC_ABS_D;
11496 goto do_unaryfp;
11497 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11498 mips32_op = OPC_ABS_PS;
11499 goto do_unaryfp;
11500
11501 /* Negation */
11502 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11503 mips32_op = OPC_NEG_S;
11504 goto do_unaryfp;
11505 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11506 mips32_op = OPC_NEG_D;
11507 goto do_unaryfp;
11508 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11509 mips32_op = OPC_NEG_PS;
11510 goto do_unaryfp;
11511
11512 /* Reciprocal square root step */
11513 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11514 mips32_op = OPC_RSQRT1_S;
11515 goto do_unaryfp;
11516 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11517 mips32_op = OPC_RSQRT1_D;
11518 goto do_unaryfp;
11519 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11520 mips32_op = OPC_RSQRT1_PS;
11521 goto do_unaryfp;
11522
11523 /* Reciprocal step */
11524 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11525 mips32_op = OPC_RECIP1_S;
11526 goto do_unaryfp;
11527 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11528 mips32_op = OPC_RECIP1_S;
11529 goto do_unaryfp;
11530 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11531 mips32_op = OPC_RECIP1_PS;
11532 goto do_unaryfp;
11533
11534 /* Conversions from double */
11535 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11536 mips32_op = OPC_CVT_D_S;
11537 goto do_unaryfp;
11538 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11539 mips32_op = OPC_CVT_D_W;
11540 goto do_unaryfp;
11541 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11542 mips32_op = OPC_CVT_D_L;
11543 goto do_unaryfp;
11544
11545 /* Conversions from single */
11546 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11547 mips32_op = OPC_CVT_S_D;
11548 goto do_unaryfp;
11549 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11550 mips32_op = OPC_CVT_S_W;
11551 goto do_unaryfp;
11552 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11553 mips32_op = OPC_CVT_S_L;
11554 do_unaryfp:
11555 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11556 break;
11557
11558 /* Conditional moves on floating-point codes */
11559 case COND_FLOAT_MOV(MOVT, 0):
11560 case COND_FLOAT_MOV(MOVT, 1):
11561 case COND_FLOAT_MOV(MOVT, 2):
11562 case COND_FLOAT_MOV(MOVT, 3):
11563 case COND_FLOAT_MOV(MOVT, 4):
11564 case COND_FLOAT_MOV(MOVT, 5):
11565 case COND_FLOAT_MOV(MOVT, 6):
11566 case COND_FLOAT_MOV(MOVT, 7):
11567 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11568 break;
11569 case COND_FLOAT_MOV(MOVF, 0):
11570 case COND_FLOAT_MOV(MOVF, 1):
11571 case COND_FLOAT_MOV(MOVF, 2):
11572 case COND_FLOAT_MOV(MOVF, 3):
11573 case COND_FLOAT_MOV(MOVF, 4):
11574 case COND_FLOAT_MOV(MOVF, 5):
11575 case COND_FLOAT_MOV(MOVF, 6):
11576 case COND_FLOAT_MOV(MOVF, 7):
11577 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11578 break;
11579 default:
11580 MIPS_INVAL("pool32fxf");
11581 generate_exception(ctx, EXCP_RI);
11582 break;
11583 }
11584}
11585
7db13fae 11586static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
3c824109
NF
11587 uint16_t insn_hw1, int *is_branch)
11588{
11589 int32_t offset;
11590 uint16_t insn;
11591 int rt, rs, rd, rr;
11592 int16_t imm;
11593 uint32_t op, minor, mips32_op;
11594 uint32_t cond, fmt, cc;
11595
895c2d04 11596 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11597 ctx->opcode = (ctx->opcode << 16) | insn;
11598
11599 rt = (ctx->opcode >> 21) & 0x1f;
11600 rs = (ctx->opcode >> 16) & 0x1f;
11601 rd = (ctx->opcode >> 11) & 0x1f;
11602 rr = (ctx->opcode >> 6) & 0x1f;
11603 imm = (int16_t) ctx->opcode;
11604
11605 op = (ctx->opcode >> 26) & 0x3f;
11606 switch (op) {
11607 case POOL32A:
11608 minor = ctx->opcode & 0x3f;
11609 switch (minor) {
11610 case 0x00:
11611 minor = (ctx->opcode >> 6) & 0xf;
11612 switch (minor) {
11613 case SLL32:
11614 mips32_op = OPC_SLL;
11615 goto do_shifti;
11616 case SRA:
11617 mips32_op = OPC_SRA;
11618 goto do_shifti;
11619 case SRL32:
11620 mips32_op = OPC_SRL;
11621 goto do_shifti;
11622 case ROTR:
11623 mips32_op = OPC_ROTR;
11624 do_shifti:
d75c135e 11625 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
11626 break;
11627 default:
11628 goto pool32a_invalid;
11629 }
11630 break;
11631 case 0x10:
11632 minor = (ctx->opcode >> 6) & 0xf;
11633 switch (minor) {
11634 /* Arithmetic */
11635 case ADD:
11636 mips32_op = OPC_ADD;
11637 goto do_arith;
11638 case ADDU32:
11639 mips32_op = OPC_ADDU;
11640 goto do_arith;
11641 case SUB:
11642 mips32_op = OPC_SUB;
11643 goto do_arith;
11644 case SUBU32:
11645 mips32_op = OPC_SUBU;
11646 goto do_arith;
11647 case MUL:
11648 mips32_op = OPC_MUL;
11649 do_arith:
d75c135e 11650 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11651 break;
11652 /* Shifts */
11653 case SLLV:
11654 mips32_op = OPC_SLLV;
11655 goto do_shift;
11656 case SRLV:
11657 mips32_op = OPC_SRLV;
11658 goto do_shift;
11659 case SRAV:
11660 mips32_op = OPC_SRAV;
11661 goto do_shift;
11662 case ROTRV:
11663 mips32_op = OPC_ROTRV;
11664 do_shift:
d75c135e 11665 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11666 break;
11667 /* Logical operations */
11668 case AND:
11669 mips32_op = OPC_AND;
11670 goto do_logic;
11671 case OR32:
11672 mips32_op = OPC_OR;
11673 goto do_logic;
11674 case NOR:
11675 mips32_op = OPC_NOR;
11676 goto do_logic;
11677 case XOR32:
11678 mips32_op = OPC_XOR;
11679 do_logic:
d75c135e 11680 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11681 break;
11682 /* Set less than */
11683 case SLT:
11684 mips32_op = OPC_SLT;
11685 goto do_slt;
11686 case SLTU:
11687 mips32_op = OPC_SLTU;
11688 do_slt:
d75c135e 11689 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11690 break;
11691 default:
11692 goto pool32a_invalid;
11693 }
11694 break;
11695 case 0x18:
11696 minor = (ctx->opcode >> 6) & 0xf;
11697 switch (minor) {
11698 /* Conditional moves */
11699 case MOVN:
11700 mips32_op = OPC_MOVN;
11701 goto do_cmov;
11702 case MOVZ:
11703 mips32_op = OPC_MOVZ;
11704 do_cmov:
d75c135e 11705 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11706 break;
11707 case LWXS:
11708 gen_ldxs(ctx, rs, rt, rd);
11709 break;
11710 default:
11711 goto pool32a_invalid;
11712 }
11713 break;
11714 case INS:
11715 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11716 return;
11717 case EXT:
11718 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11719 return;
11720 case POOL32AXF:
11721 gen_pool32axf(env, ctx, rt, rs, is_branch);
11722 break;
11723 case 0x07:
11724 generate_exception(ctx, EXCP_BREAK);
11725 break;
11726 default:
11727 pool32a_invalid:
11728 MIPS_INVAL("pool32a");
11729 generate_exception(ctx, EXCP_RI);
11730 break;
11731 }
11732 break;
11733 case POOL32B:
11734 minor = (ctx->opcode >> 12) & 0xf;
11735 switch (minor) {
11736 case CACHE:
2e15497c 11737 check_cp0_enabled(ctx);
3c824109
NF
11738 /* Treat as no-op. */
11739 break;
11740 case LWC2:
11741 case SWC2:
11742 /* COP2: Not implemented. */
11743 generate_exception_err(ctx, EXCP_CpU, 2);
11744 break;
11745 case LWP:
11746 case SWP:
11747#ifdef TARGET_MIPS64
11748 case LDP:
11749 case SDP:
11750#endif
11751 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11752 break;
11753 case LWM32:
11754 case SWM32:
11755#ifdef TARGET_MIPS64
11756 case LDM:
11757 case SDM:
11758#endif
11759 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11760 break;
11761 default:
11762 MIPS_INVAL("pool32b");
11763 generate_exception(ctx, EXCP_RI);
11764 break;
11765 }
11766 break;
11767 case POOL32F:
11768 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11769 minor = ctx->opcode & 0x3f;
11770 check_cp1_enabled(ctx);
11771 switch (minor) {
11772 case ALNV_PS:
11773 mips32_op = OPC_ALNV_PS;
11774 goto do_madd;
11775 case MADD_S:
11776 mips32_op = OPC_MADD_S;
11777 goto do_madd;
11778 case MADD_D:
11779 mips32_op = OPC_MADD_D;
11780 goto do_madd;
11781 case MADD_PS:
11782 mips32_op = OPC_MADD_PS;
11783 goto do_madd;
11784 case MSUB_S:
11785 mips32_op = OPC_MSUB_S;
11786 goto do_madd;
11787 case MSUB_D:
11788 mips32_op = OPC_MSUB_D;
11789 goto do_madd;
11790 case MSUB_PS:
11791 mips32_op = OPC_MSUB_PS;
11792 goto do_madd;
11793 case NMADD_S:
11794 mips32_op = OPC_NMADD_S;
11795 goto do_madd;
11796 case NMADD_D:
11797 mips32_op = OPC_NMADD_D;
11798 goto do_madd;
11799 case NMADD_PS:
11800 mips32_op = OPC_NMADD_PS;
11801 goto do_madd;
11802 case NMSUB_S:
11803 mips32_op = OPC_NMSUB_S;
11804 goto do_madd;
11805 case NMSUB_D:
11806 mips32_op = OPC_NMSUB_D;
11807 goto do_madd;
11808 case NMSUB_PS:
11809 mips32_op = OPC_NMSUB_PS;
11810 do_madd:
11811 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11812 break;
11813 case CABS_COND_FMT:
11814 cond = (ctx->opcode >> 6) & 0xf;
11815 cc = (ctx->opcode >> 13) & 0x7;
11816 fmt = (ctx->opcode >> 10) & 0x3;
11817 switch (fmt) {
11818 case 0x0:
11819 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11820 break;
11821 case 0x1:
11822 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11823 break;
11824 case 0x2:
11825 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11826 break;
11827 default:
11828 goto pool32f_invalid;
11829 }
11830 break;
11831 case C_COND_FMT:
11832 cond = (ctx->opcode >> 6) & 0xf;
11833 cc = (ctx->opcode >> 13) & 0x7;
11834 fmt = (ctx->opcode >> 10) & 0x3;
11835 switch (fmt) {
11836 case 0x0:
11837 gen_cmp_s(ctx, cond, rt, rs, cc);
11838 break;
11839 case 0x1:
11840 gen_cmp_d(ctx, cond, rt, rs, cc);
11841 break;
11842 case 0x2:
11843 gen_cmp_ps(ctx, cond, rt, rs, cc);
11844 break;
11845 default:
11846 goto pool32f_invalid;
11847 }
11848 break;
11849 case POOL32FXF:
d75c135e 11850 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
11851 break;
11852 case 0x00:
11853 /* PLL foo */
11854 switch ((ctx->opcode >> 6) & 0x7) {
11855 case PLL_PS:
11856 mips32_op = OPC_PLL_PS;
11857 goto do_ps;
11858 case PLU_PS:
11859 mips32_op = OPC_PLU_PS;
11860 goto do_ps;
11861 case PUL_PS:
11862 mips32_op = OPC_PUL_PS;
11863 goto do_ps;
11864 case PUU_PS:
11865 mips32_op = OPC_PUU_PS;
11866 goto do_ps;
11867 case CVT_PS_S:
11868 mips32_op = OPC_CVT_PS_S;
11869 do_ps:
11870 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11871 break;
11872 default:
11873 goto pool32f_invalid;
11874 }
11875 break;
11876 case 0x08:
11877 /* [LS][WDU]XC1 */
11878 switch ((ctx->opcode >> 6) & 0x7) {
11879 case LWXC1:
11880 mips32_op = OPC_LWXC1;
11881 goto do_ldst_cp1;
11882 case SWXC1:
11883 mips32_op = OPC_SWXC1;
11884 goto do_ldst_cp1;
11885 case LDXC1:
11886 mips32_op = OPC_LDXC1;
11887 goto do_ldst_cp1;
11888 case SDXC1:
11889 mips32_op = OPC_SDXC1;
11890 goto do_ldst_cp1;
11891 case LUXC1:
11892 mips32_op = OPC_LUXC1;
11893 goto do_ldst_cp1;
11894 case SUXC1:
11895 mips32_op = OPC_SUXC1;
11896 do_ldst_cp1:
11897 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11898 break;
11899 default:
11900 goto pool32f_invalid;
11901 }
11902 break;
11903 case 0x18:
11904 /* 3D insns */
11905 fmt = (ctx->opcode >> 9) & 0x3;
11906 switch ((ctx->opcode >> 6) & 0x7) {
11907 case RSQRT2_FMT:
11908 switch (fmt) {
11909 case FMT_SDPS_S:
11910 mips32_op = OPC_RSQRT2_S;
11911 goto do_3d;
11912 case FMT_SDPS_D:
11913 mips32_op = OPC_RSQRT2_D;
11914 goto do_3d;
11915 case FMT_SDPS_PS:
11916 mips32_op = OPC_RSQRT2_PS;
11917 goto do_3d;
11918 default:
11919 goto pool32f_invalid;
11920 }
11921 break;
11922 case RECIP2_FMT:
11923 switch (fmt) {
11924 case FMT_SDPS_S:
11925 mips32_op = OPC_RECIP2_S;
11926 goto do_3d;
11927 case FMT_SDPS_D:
11928 mips32_op = OPC_RECIP2_D;
11929 goto do_3d;
11930 case FMT_SDPS_PS:
11931 mips32_op = OPC_RECIP2_PS;
11932 goto do_3d;
11933 default:
11934 goto pool32f_invalid;
11935 }
11936 break;
11937 case ADDR_PS:
11938 mips32_op = OPC_ADDR_PS;
11939 goto do_3d;
11940 case MULR_PS:
11941 mips32_op = OPC_MULR_PS;
11942 do_3d:
11943 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11944 break;
11945 default:
11946 goto pool32f_invalid;
11947 }
11948 break;
11949 case 0x20:
11950 /* MOV[FT].fmt and PREFX */
11951 cc = (ctx->opcode >> 13) & 0x7;
11952 fmt = (ctx->opcode >> 9) & 0x3;
11953 switch ((ctx->opcode >> 6) & 0x7) {
11954 case MOVF_FMT:
11955 switch (fmt) {
11956 case FMT_SDPS_S:
11957 gen_movcf_s(rs, rt, cc, 0);
11958 break;
11959 case FMT_SDPS_D:
11960 gen_movcf_d(ctx, rs, rt, cc, 0);
11961 break;
11962 case FMT_SDPS_PS:
11963 gen_movcf_ps(rs, rt, cc, 0);
11964 break;
11965 default:
11966 goto pool32f_invalid;
11967 }
11968 break;
11969 case MOVT_FMT:
11970 switch (fmt) {
11971 case FMT_SDPS_S:
11972 gen_movcf_s(rs, rt, cc, 1);
11973 break;
11974 case FMT_SDPS_D:
11975 gen_movcf_d(ctx, rs, rt, cc, 1);
11976 break;
11977 case FMT_SDPS_PS:
11978 gen_movcf_ps(rs, rt, cc, 1);
11979 break;
11980 default:
11981 goto pool32f_invalid;
11982 }
11983 break;
11984 case PREFX:
11985 break;
11986 default:
11987 goto pool32f_invalid;
11988 }
11989 break;
11990#define FINSN_3ARG_SDPS(prfx) \
11991 switch ((ctx->opcode >> 8) & 0x3) { \
11992 case FMT_SDPS_S: \
11993 mips32_op = OPC_##prfx##_S; \
11994 goto do_fpop; \
11995 case FMT_SDPS_D: \
11996 mips32_op = OPC_##prfx##_D; \
11997 goto do_fpop; \
11998 case FMT_SDPS_PS: \
11999 mips32_op = OPC_##prfx##_PS; \
12000 goto do_fpop; \
12001 default: \
12002 goto pool32f_invalid; \
12003 }
12004 case 0x30:
12005 /* regular FP ops */
12006 switch ((ctx->opcode >> 6) & 0x3) {
12007 case ADD_FMT:
12008 FINSN_3ARG_SDPS(ADD);
12009 break;
12010 case SUB_FMT:
12011 FINSN_3ARG_SDPS(SUB);
12012 break;
12013 case MUL_FMT:
12014 FINSN_3ARG_SDPS(MUL);
12015 break;
12016 case DIV_FMT:
12017 fmt = (ctx->opcode >> 8) & 0x3;
12018 if (fmt == 1) {
12019 mips32_op = OPC_DIV_D;
12020 } else if (fmt == 0) {
12021 mips32_op = OPC_DIV_S;
12022 } else {
12023 goto pool32f_invalid;
12024 }
12025 goto do_fpop;
12026 default:
12027 goto pool32f_invalid;
12028 }
12029 break;
12030 case 0x38:
12031 /* cmovs */
12032 switch ((ctx->opcode >> 6) & 0x3) {
12033 case MOVN_FMT:
12034 FINSN_3ARG_SDPS(MOVN);
12035 break;
12036 case MOVZ_FMT:
12037 FINSN_3ARG_SDPS(MOVZ);
12038 break;
12039 default:
12040 goto pool32f_invalid;
12041 }
12042 break;
12043 do_fpop:
12044 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12045 break;
12046 default:
12047 pool32f_invalid:
12048 MIPS_INVAL("pool32f");
12049 generate_exception(ctx, EXCP_RI);
12050 break;
12051 }
12052 } else {
12053 generate_exception_err(ctx, EXCP_CpU, 1);
12054 }
12055 break;
12056 case POOL32I:
12057 minor = (ctx->opcode >> 21) & 0x1f;
12058 switch (minor) {
12059 case BLTZ:
12060 mips32_op = OPC_BLTZ;
12061 goto do_branch;
12062 case BLTZAL:
12063 mips32_op = OPC_BLTZAL;
12064 goto do_branch;
12065 case BLTZALS:
12066 mips32_op = OPC_BLTZALS;
12067 goto do_branch;
12068 case BGEZ:
12069 mips32_op = OPC_BGEZ;
12070 goto do_branch;
12071 case BGEZAL:
12072 mips32_op = OPC_BGEZAL;
12073 goto do_branch;
12074 case BGEZALS:
12075 mips32_op = OPC_BGEZALS;
12076 goto do_branch;
12077 case BLEZ:
12078 mips32_op = OPC_BLEZ;
12079 goto do_branch;
12080 case BGTZ:
12081 mips32_op = OPC_BGTZ;
12082 do_branch:
12083 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12084 *is_branch = 1;
12085 break;
12086
12087 /* Traps */
12088 case TLTI:
12089 mips32_op = OPC_TLTI;
12090 goto do_trapi;
12091 case TGEI:
12092 mips32_op = OPC_TGEI;
12093 goto do_trapi;
12094 case TLTIU:
12095 mips32_op = OPC_TLTIU;
12096 goto do_trapi;
12097 case TGEIU:
12098 mips32_op = OPC_TGEIU;
12099 goto do_trapi;
12100 case TNEI:
12101 mips32_op = OPC_TNEI;
12102 goto do_trapi;
12103 case TEQI:
12104 mips32_op = OPC_TEQI;
12105 do_trapi:
12106 gen_trap(ctx, mips32_op, rs, -1, imm);
12107 break;
12108
12109 case BNEZC:
12110 case BEQZC:
12111 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12112 4, rs, 0, imm << 1);
12113 /* Compact branches don't have a delay slot, so just let
12114 the normal delay slot handling take us to the branch
12115 target. */
12116 break;
12117 case LUI:
d75c135e 12118 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12119 break;
12120 case SYNCI:
12121 break;
12122 case BC2F:
12123 case BC2T:
12124 /* COP2: Not implemented. */
12125 generate_exception_err(ctx, EXCP_CpU, 2);
12126 break;
12127 case BC1F:
12128 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12129 goto do_cp1branch;
12130 case BC1T:
12131 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12132 goto do_cp1branch;
12133 case BC1ANY4F:
12134 mips32_op = OPC_BC1FANY4;
12135 goto do_cp1mips3d;
12136 case BC1ANY4T:
12137 mips32_op = OPC_BC1TANY4;
12138 do_cp1mips3d:
12139 check_cop1x(ctx);
d75c135e 12140 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12141 /* Fall through */
12142 do_cp1branch:
d75c135e 12143 gen_compute_branch1(ctx, mips32_op,
3c824109
NF
12144 (ctx->opcode >> 18) & 0x7, imm << 1);
12145 *is_branch = 1;
12146 break;
12147 case BPOSGE64:
12148 case BPOSGE32:
12149 /* MIPS DSP: not implemented */
12150 /* Fall through */
12151 default:
12152 MIPS_INVAL("pool32i");
12153 generate_exception(ctx, EXCP_RI);
12154 break;
12155 }
12156 break;
12157 case POOL32C:
12158 minor = (ctx->opcode >> 12) & 0xf;
12159 switch (minor) {
12160 case LWL:
12161 mips32_op = OPC_LWL;
5c13fdfd 12162 goto do_ld_lr;
3c824109
NF
12163 case SWL:
12164 mips32_op = OPC_SWL;
5c13fdfd 12165 goto do_st_lr;
3c824109
NF
12166 case LWR:
12167 mips32_op = OPC_LWR;
5c13fdfd 12168 goto do_ld_lr;
3c824109
NF
12169 case SWR:
12170 mips32_op = OPC_SWR;
5c13fdfd 12171 goto do_st_lr;
3c824109
NF
12172#if defined(TARGET_MIPS64)
12173 case LDL:
12174 mips32_op = OPC_LDL;
5c13fdfd 12175 goto do_ld_lr;
3c824109
NF
12176 case SDL:
12177 mips32_op = OPC_SDL;
5c13fdfd 12178 goto do_st_lr;
3c824109
NF
12179 case LDR:
12180 mips32_op = OPC_LDR;
5c13fdfd 12181 goto do_ld_lr;
3c824109
NF
12182 case SDR:
12183 mips32_op = OPC_SDR;
5c13fdfd 12184 goto do_st_lr;
3c824109
NF
12185 case LWU:
12186 mips32_op = OPC_LWU;
5c13fdfd 12187 goto do_ld_lr;
3c824109
NF
12188 case LLD:
12189 mips32_op = OPC_LLD;
5c13fdfd 12190 goto do_ld_lr;
3c824109
NF
12191#endif
12192 case LL:
12193 mips32_op = OPC_LL;
5c13fdfd
AJ
12194 goto do_ld_lr;
12195 do_ld_lr:
d75c135e 12196 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12197 break;
12198 do_st_lr:
12199 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12200 break;
12201 case SC:
12202 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12203 break;
12204#if defined(TARGET_MIPS64)
12205 case SCD:
12206 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12207 break;
12208#endif
12209 case PREF:
12210 /* Treat as no-op */
12211 break;
12212 default:
12213 MIPS_INVAL("pool32c");
12214 generate_exception(ctx, EXCP_RI);
12215 break;
12216 }
12217 break;
12218 case ADDI32:
12219 mips32_op = OPC_ADDI;
12220 goto do_addi;
12221 case ADDIU32:
12222 mips32_op = OPC_ADDIU;
12223 do_addi:
d75c135e 12224 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12225 break;
12226
12227 /* Logical operations */
12228 case ORI32:
12229 mips32_op = OPC_ORI;
12230 goto do_logici;
12231 case XORI32:
12232 mips32_op = OPC_XORI;
12233 goto do_logici;
12234 case ANDI32:
12235 mips32_op = OPC_ANDI;
12236 do_logici:
d75c135e 12237 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12238 break;
12239
12240 /* Set less than immediate */
12241 case SLTI32:
12242 mips32_op = OPC_SLTI;
12243 goto do_slti;
12244 case SLTIU32:
12245 mips32_op = OPC_SLTIU;
12246 do_slti:
d75c135e 12247 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12248 break;
12249 case JALX32:
12250 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12251 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12252 *is_branch = 1;
12253 break;
12254 case JALS32:
12255 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12256 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12257 *is_branch = 1;
12258 break;
12259 case BEQ32:
12260 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12261 *is_branch = 1;
12262 break;
12263 case BNE32:
12264 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12265 *is_branch = 1;
12266 break;
12267 case J32:
12268 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12269 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12270 *is_branch = 1;
12271 break;
12272 case JAL32:
12273 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12274 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12275 *is_branch = 1;
12276 break;
12277 /* Floating point (COP1) */
12278 case LWC132:
12279 mips32_op = OPC_LWC1;
12280 goto do_cop1;
12281 case LDC132:
12282 mips32_op = OPC_LDC1;
12283 goto do_cop1;
12284 case SWC132:
12285 mips32_op = OPC_SWC1;
12286 goto do_cop1;
12287 case SDC132:
12288 mips32_op = OPC_SDC1;
12289 do_cop1:
12290 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12291 break;
12292 case ADDIUPC:
12293 {
12294 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12295 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12296
12297 gen_addiupc(ctx, reg, offset, 0, 0);
12298 }
12299 break;
12300 /* Loads and stores */
12301 case LB32:
12302 mips32_op = OPC_LB;
5c13fdfd 12303 goto do_ld;
3c824109
NF
12304 case LBU32:
12305 mips32_op = OPC_LBU;
5c13fdfd 12306 goto do_ld;
3c824109
NF
12307 case LH32:
12308 mips32_op = OPC_LH;
5c13fdfd 12309 goto do_ld;
3c824109
NF
12310 case LHU32:
12311 mips32_op = OPC_LHU;
5c13fdfd 12312 goto do_ld;
3c824109
NF
12313 case LW32:
12314 mips32_op = OPC_LW;
5c13fdfd 12315 goto do_ld;
3c824109
NF
12316#ifdef TARGET_MIPS64
12317 case LD32:
12318 mips32_op = OPC_LD;
5c13fdfd 12319 goto do_ld;
3c824109
NF
12320 case SD32:
12321 mips32_op = OPC_SD;
5c13fdfd 12322 goto do_st;
3c824109
NF
12323#endif
12324 case SB32:
12325 mips32_op = OPC_SB;
5c13fdfd 12326 goto do_st;
3c824109
NF
12327 case SH32:
12328 mips32_op = OPC_SH;
5c13fdfd 12329 goto do_st;
3c824109
NF
12330 case SW32:
12331 mips32_op = OPC_SW;
5c13fdfd
AJ
12332 goto do_st;
12333 do_ld:
d75c135e 12334 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12335 break;
12336 do_st:
12337 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12338 break;
12339 default:
12340 generate_exception(ctx, EXCP_RI);
12341 break;
12342 }
12343}
12344
7db13fae 12345static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
12346{
12347 uint32_t op;
12348
12349 /* make sure instructions are on a halfword boundary */
12350 if (ctx->pc & 0x1) {
12351 env->CP0_BadVAddr = ctx->pc;
12352 generate_exception(ctx, EXCP_AdEL);
12353 ctx->bstate = BS_STOP;
12354 return 2;
12355 }
12356
12357 op = (ctx->opcode >> 10) & 0x3f;
12358 /* Enforce properly-sized instructions in a delay slot */
12359 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12360 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12361
12362 switch (op) {
12363 case POOL32A:
12364 case POOL32B:
12365 case POOL32I:
12366 case POOL32C:
12367 case ADDI32:
12368 case ADDIU32:
12369 case ORI32:
12370 case XORI32:
12371 case SLTI32:
12372 case SLTIU32:
12373 case ANDI32:
12374 case JALX32:
12375 case LBU32:
12376 case LHU32:
12377 case POOL32F:
12378 case JALS32:
12379 case BEQ32:
12380 case BNE32:
12381 case J32:
12382 case JAL32:
12383 case SB32:
12384 case SH32:
12385 case POOL32S:
12386 case ADDIUPC:
12387 case SWC132:
12388 case SDC132:
12389 case SD32:
12390 case SW32:
12391 case LB32:
12392 case LH32:
12393 case DADDIU32:
3c824109
NF
12394 case LWC132:
12395 case LDC132:
12396 case LD32:
12397 case LW32:
12398 if (bits & MIPS_HFLAG_BDS16) {
12399 generate_exception(ctx, EXCP_RI);
12400 /* Just stop translation; the user is confused. */
12401 ctx->bstate = BS_STOP;
12402 return 2;
12403 }
12404 break;
12405 case POOL16A:
12406 case POOL16B:
12407 case POOL16C:
12408 case LWGP16:
12409 case POOL16F:
12410 case LBU16:
12411 case LHU16:
12412 case LWSP16:
12413 case LW16:
12414 case SB16:
12415 case SH16:
12416 case SWSP16:
12417 case SW16:
12418 case MOVE16:
12419 case ANDI16:
12420 case POOL16D:
12421 case POOL16E:
12422 case BEQZ16:
12423 case BNEZ16:
12424 case B16:
12425 case LI16:
12426 if (bits & MIPS_HFLAG_BDS32) {
12427 generate_exception(ctx, EXCP_RI);
12428 /* Just stop translation; the user is confused. */
12429 ctx->bstate = BS_STOP;
12430 return 2;
12431 }
12432 break;
12433 default:
12434 break;
12435 }
12436 }
12437 switch (op) {
12438 case POOL16A:
12439 {
12440 int rd = mmreg(uMIPS_RD(ctx->opcode));
12441 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12442 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12443 uint32_t opc = 0;
12444
12445 switch (ctx->opcode & 0x1) {
12446 case ADDU16:
12447 opc = OPC_ADDU;
12448 break;
12449 case SUBU16:
12450 opc = OPC_SUBU;
12451 break;
12452 }
12453
d75c135e 12454 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12455 }
12456 break;
12457 case POOL16B:
12458 {
12459 int rd = mmreg(uMIPS_RD(ctx->opcode));
12460 int rs = mmreg(uMIPS_RS(ctx->opcode));
12461 int amount = (ctx->opcode >> 1) & 0x7;
12462 uint32_t opc = 0;
12463 amount = amount == 0 ? 8 : amount;
12464
12465 switch (ctx->opcode & 0x1) {
12466 case SLL16:
12467 opc = OPC_SLL;
12468 break;
12469 case SRL16:
12470 opc = OPC_SRL;
12471 break;
12472 }
12473
d75c135e 12474 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12475 }
12476 break;
12477 case POOL16C:
d75c135e 12478 gen_pool16c_insn(ctx, is_branch);
3c824109
NF
12479 break;
12480 case LWGP16:
12481 {
12482 int rd = mmreg(uMIPS_RD(ctx->opcode));
12483 int rb = 28; /* GP */
12484 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12485
d75c135e 12486 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12487 }
12488 break;
12489 case POOL16F:
12490 if (ctx->opcode & 1) {
12491 generate_exception(ctx, EXCP_RI);
12492 } else {
12493 /* MOVEP */
12494 int enc_dest = uMIPS_RD(ctx->opcode);
12495 int enc_rt = uMIPS_RS2(ctx->opcode);
12496 int enc_rs = uMIPS_RS1(ctx->opcode);
12497 int rd, rs, re, rt;
12498 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12499 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12500 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12501
12502 rd = rd_enc[enc_dest];
12503 re = re_enc[enc_dest];
12504 rs = rs_rt_enc[enc_rs];
12505 rt = rs_rt_enc[enc_rt];
12506
d75c135e
AJ
12507 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12508 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12509 }
12510 break;
12511 case LBU16:
12512 {
12513 int rd = mmreg(uMIPS_RD(ctx->opcode));
12514 int rb = mmreg(uMIPS_RS(ctx->opcode));
12515 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12516 offset = (offset == 0xf ? -1 : offset);
12517
d75c135e 12518 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12519 }
12520 break;
12521 case LHU16:
12522 {
12523 int rd = mmreg(uMIPS_RD(ctx->opcode));
12524 int rb = mmreg(uMIPS_RS(ctx->opcode));
12525 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12526
d75c135e 12527 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12528 }
12529 break;
12530 case LWSP16:
12531 {
12532 int rd = (ctx->opcode >> 5) & 0x1f;
12533 int rb = 29; /* SP */
12534 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12535
d75c135e 12536 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12537 }
12538 break;
12539 case LW16:
12540 {
12541 int rd = mmreg(uMIPS_RD(ctx->opcode));
12542 int rb = mmreg(uMIPS_RS(ctx->opcode));
12543 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12544
d75c135e 12545 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12546 }
12547 break;
12548 case SB16:
12549 {
12550 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12551 int rb = mmreg(uMIPS_RS(ctx->opcode));
12552 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12553
5c13fdfd 12554 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12555 }
12556 break;
12557 case SH16:
12558 {
12559 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12560 int rb = mmreg(uMIPS_RS(ctx->opcode));
12561 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12562
5c13fdfd 12563 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12564 }
12565 break;
12566 case SWSP16:
12567 {
12568 int rd = (ctx->opcode >> 5) & 0x1f;
12569 int rb = 29; /* SP */
12570 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12571
5c13fdfd 12572 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12573 }
12574 break;
12575 case SW16:
12576 {
12577 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12578 int rb = mmreg(uMIPS_RS(ctx->opcode));
12579 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12580
5c13fdfd 12581 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12582 }
12583 break;
12584 case MOVE16:
12585 {
12586 int rd = uMIPS_RD5(ctx->opcode);
12587 int rs = uMIPS_RS5(ctx->opcode);
12588
d75c135e 12589 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12590 }
12591 break;
12592 case ANDI16:
d75c135e 12593 gen_andi16(ctx);
3c824109
NF
12594 break;
12595 case POOL16D:
12596 switch (ctx->opcode & 0x1) {
12597 case ADDIUS5:
d75c135e 12598 gen_addius5(ctx);
3c824109
NF
12599 break;
12600 case ADDIUSP:
d75c135e 12601 gen_addiusp(ctx);
3c824109
NF
12602 break;
12603 }
12604 break;
12605 case POOL16E:
12606 switch (ctx->opcode & 0x1) {
12607 case ADDIUR2:
d75c135e 12608 gen_addiur2(ctx);
3c824109
NF
12609 break;
12610 case ADDIUR1SP:
d75c135e 12611 gen_addiur1sp(ctx);
3c824109
NF
12612 break;
12613 }
12614 break;
12615 case B16:
12616 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12617 SIMM(ctx->opcode, 0, 10) << 1);
12618 *is_branch = 1;
12619 break;
12620 case BNEZ16:
12621 case BEQZ16:
12622 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12623 mmreg(uMIPS_RD(ctx->opcode)),
12624 0, SIMM(ctx->opcode, 0, 7) << 1);
12625 *is_branch = 1;
12626 break;
12627 case LI16:
12628 {
12629 int reg = mmreg(uMIPS_RD(ctx->opcode));
12630 int imm = ZIMM(ctx->opcode, 0, 7);
12631
12632 imm = (imm == 0x7f ? -1 : imm);
12633 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12634 }
12635 break;
12636 case RES_20:
12637 case RES_28:
12638 case RES_29:
12639 case RES_30:
12640 case RES_31:
12641 case RES_38:
12642 case RES_39:
12643 generate_exception(ctx, EXCP_RI);
12644 break;
12645 default:
12646 decode_micromips32_opc (env, ctx, op, is_branch);
12647 return 4;
12648 }
12649
12650 return 2;
12651}
12652
12653/* SmartMIPS extension to MIPS32 */
12654
12655#if defined(TARGET_MIPS64)
12656
12657/* MDMX extension to MIPS64 */
12658
12659#endif
12660
9b1a1d68 12661/* MIPSDSP functions. */
d75c135e 12662static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12663 int rd, int base, int offset)
12664{
12665 const char *opn = "ldx";
12666 TCGv t0;
12667
9b1a1d68
JL
12668 check_dsp(ctx);
12669 t0 = tcg_temp_new();
12670
12671 if (base == 0) {
12672 gen_load_gpr(t0, offset);
12673 } else if (offset == 0) {
12674 gen_load_gpr(t0, base);
12675 } else {
12676 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12677 }
12678
9b1a1d68
JL
12679 switch (opc) {
12680 case OPC_LBUX:
2910c6cb 12681 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12682 gen_store_gpr(t0, rd);
12683 opn = "lbux";
12684 break;
12685 case OPC_LHX:
2910c6cb 12686 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12687 gen_store_gpr(t0, rd);
12688 opn = "lhx";
12689 break;
12690 case OPC_LWX:
2910c6cb 12691 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12692 gen_store_gpr(t0, rd);
12693 opn = "lwx";
12694 break;
12695#if defined(TARGET_MIPS64)
12696 case OPC_LDX:
2910c6cb 12697 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12698 gen_store_gpr(t0, rd);
12699 opn = "ldx";
12700 break;
12701#endif
12702 }
12703 (void)opn; /* avoid a compiler warning */
12704 MIPS_DEBUG("%s %s, %s(%s)", opn,
12705 regnames[rd], regnames[offset], regnames[base]);
12706 tcg_temp_free(t0);
12707}
12708
461c08df
JL
12709static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12710 int ret, int v1, int v2)
12711{
12712 const char *opn = "mipsdsp arith";
12713 TCGv v1_t;
12714 TCGv v2_t;
12715
12716 if (ret == 0) {
12717 /* Treat as NOP. */
12718 MIPS_DEBUG("NOP");
12719 return;
12720 }
12721
12722 v1_t = tcg_temp_new();
12723 v2_t = tcg_temp_new();
12724
12725 gen_load_gpr(v1_t, v1);
12726 gen_load_gpr(v2_t, v2);
12727
12728 switch (op1) {
12729 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12730 case OPC_MULT_G_2E:
12731 check_dspr2(ctx);
12732 switch (op2) {
12733 case OPC_ADDUH_QB:
12734 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12735 break;
12736 case OPC_ADDUH_R_QB:
12737 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12738 break;
12739 case OPC_ADDQH_PH:
12740 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12741 break;
12742 case OPC_ADDQH_R_PH:
12743 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12744 break;
12745 case OPC_ADDQH_W:
12746 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12747 break;
12748 case OPC_ADDQH_R_W:
12749 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12750 break;
12751 case OPC_SUBUH_QB:
12752 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12753 break;
12754 case OPC_SUBUH_R_QB:
12755 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12756 break;
12757 case OPC_SUBQH_PH:
12758 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12759 break;
12760 case OPC_SUBQH_R_PH:
12761 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12762 break;
12763 case OPC_SUBQH_W:
12764 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12765 break;
12766 case OPC_SUBQH_R_W:
12767 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12768 break;
12769 }
12770 break;
12771 case OPC_ABSQ_S_PH_DSP:
12772 switch (op2) {
12773 case OPC_ABSQ_S_QB:
12774 check_dspr2(ctx);
12775 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12776 break;
12777 case OPC_ABSQ_S_PH:
12778 check_dsp(ctx);
12779 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12780 break;
12781 case OPC_ABSQ_S_W:
12782 check_dsp(ctx);
12783 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12784 break;
12785 case OPC_PRECEQ_W_PHL:
12786 check_dsp(ctx);
12787 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12788 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12789 break;
12790 case OPC_PRECEQ_W_PHR:
12791 check_dsp(ctx);
12792 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12793 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12794 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12795 break;
12796 case OPC_PRECEQU_PH_QBL:
12797 check_dsp(ctx);
12798 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12799 break;
12800 case OPC_PRECEQU_PH_QBR:
12801 check_dsp(ctx);
12802 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12803 break;
12804 case OPC_PRECEQU_PH_QBLA:
12805 check_dsp(ctx);
12806 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12807 break;
12808 case OPC_PRECEQU_PH_QBRA:
12809 check_dsp(ctx);
12810 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12811 break;
12812 case OPC_PRECEU_PH_QBL:
12813 check_dsp(ctx);
12814 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12815 break;
12816 case OPC_PRECEU_PH_QBR:
12817 check_dsp(ctx);
12818 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12819 break;
12820 case OPC_PRECEU_PH_QBLA:
12821 check_dsp(ctx);
12822 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12823 break;
12824 case OPC_PRECEU_PH_QBRA:
12825 check_dsp(ctx);
12826 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12827 break;
12828 }
12829 break;
12830 case OPC_ADDU_QB_DSP:
12831 switch (op2) {
12832 case OPC_ADDQ_PH:
12833 check_dsp(ctx);
12834 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12835 break;
12836 case OPC_ADDQ_S_PH:
12837 check_dsp(ctx);
12838 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12839 break;
12840 case OPC_ADDQ_S_W:
12841 check_dsp(ctx);
12842 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12843 break;
12844 case OPC_ADDU_QB:
12845 check_dsp(ctx);
12846 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12847 break;
12848 case OPC_ADDU_S_QB:
12849 check_dsp(ctx);
12850 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12851 break;
12852 case OPC_ADDU_PH:
12853 check_dspr2(ctx);
12854 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12855 break;
12856 case OPC_ADDU_S_PH:
12857 check_dspr2(ctx);
12858 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12859 break;
12860 case OPC_SUBQ_PH:
12861 check_dsp(ctx);
12862 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12863 break;
12864 case OPC_SUBQ_S_PH:
12865 check_dsp(ctx);
12866 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12867 break;
12868 case OPC_SUBQ_S_W:
12869 check_dsp(ctx);
12870 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12871 break;
12872 case OPC_SUBU_QB:
12873 check_dsp(ctx);
12874 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12875 break;
12876 case OPC_SUBU_S_QB:
12877 check_dsp(ctx);
12878 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12879 break;
12880 case OPC_SUBU_PH:
12881 check_dspr2(ctx);
12882 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12883 break;
12884 case OPC_SUBU_S_PH:
12885 check_dspr2(ctx);
12886 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12887 break;
12888 case OPC_ADDSC:
12889 check_dsp(ctx);
12890 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12891 break;
12892 case OPC_ADDWC:
12893 check_dsp(ctx);
12894 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12895 break;
12896 case OPC_MODSUB:
12897 check_dsp(ctx);
12898 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12899 break;
12900 case OPC_RADDU_W_QB:
12901 check_dsp(ctx);
12902 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12903 break;
12904 }
12905 break;
12906 case OPC_CMPU_EQ_QB_DSP:
12907 switch (op2) {
12908 case OPC_PRECR_QB_PH:
12909 check_dspr2(ctx);
12910 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12911 break;
12912 case OPC_PRECRQ_QB_PH:
12913 check_dsp(ctx);
12914 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12915 break;
12916 case OPC_PRECR_SRA_PH_W:
12917 check_dspr2(ctx);
12918 {
12919 TCGv_i32 sa_t = tcg_const_i32(v2);
12920 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12921 cpu_gpr[ret]);
12922 tcg_temp_free_i32(sa_t);
12923 break;
12924 }
12925 case OPC_PRECR_SRA_R_PH_W:
12926 check_dspr2(ctx);
12927 {
12928 TCGv_i32 sa_t = tcg_const_i32(v2);
12929 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12930 cpu_gpr[ret]);
12931 tcg_temp_free_i32(sa_t);
12932 break;
12933 }
12934 case OPC_PRECRQ_PH_W:
12935 check_dsp(ctx);
12936 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12937 break;
12938 case OPC_PRECRQ_RS_PH_W:
12939 check_dsp(ctx);
12940 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12941 break;
12942 case OPC_PRECRQU_S_QB_PH:
12943 check_dsp(ctx);
12944 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12945 break;
12946 }
12947 break;
12948#ifdef TARGET_MIPS64
12949 case OPC_ABSQ_S_QH_DSP:
12950 switch (op2) {
12951 case OPC_PRECEQ_L_PWL:
12952 check_dsp(ctx);
12953 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12954 break;
12955 case OPC_PRECEQ_L_PWR:
12956 check_dsp(ctx);
12957 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12958 break;
12959 case OPC_PRECEQ_PW_QHL:
12960 check_dsp(ctx);
12961 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12962 break;
12963 case OPC_PRECEQ_PW_QHR:
12964 check_dsp(ctx);
12965 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12966 break;
12967 case OPC_PRECEQ_PW_QHLA:
12968 check_dsp(ctx);
12969 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12970 break;
12971 case OPC_PRECEQ_PW_QHRA:
12972 check_dsp(ctx);
12973 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12974 break;
12975 case OPC_PRECEQU_QH_OBL:
12976 check_dsp(ctx);
12977 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12978 break;
12979 case OPC_PRECEQU_QH_OBR:
12980 check_dsp(ctx);
12981 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12982 break;
12983 case OPC_PRECEQU_QH_OBLA:
12984 check_dsp(ctx);
12985 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12986 break;
12987 case OPC_PRECEQU_QH_OBRA:
12988 check_dsp(ctx);
12989 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12990 break;
12991 case OPC_PRECEU_QH_OBL:
12992 check_dsp(ctx);
12993 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12994 break;
12995 case OPC_PRECEU_QH_OBR:
12996 check_dsp(ctx);
12997 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12998 break;
12999 case OPC_PRECEU_QH_OBLA:
13000 check_dsp(ctx);
13001 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13002 break;
13003 case OPC_PRECEU_QH_OBRA:
13004 check_dsp(ctx);
13005 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13006 break;
13007 case OPC_ABSQ_S_OB:
13008 check_dspr2(ctx);
13009 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13010 break;
13011 case OPC_ABSQ_S_PW:
13012 check_dsp(ctx);
13013 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13014 break;
13015 case OPC_ABSQ_S_QH:
13016 check_dsp(ctx);
13017 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13018 break;
13019 }
13020 break;
13021 case OPC_ADDU_OB_DSP:
13022 switch (op2) {
13023 case OPC_RADDU_L_OB:
13024 check_dsp(ctx);
13025 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13026 break;
13027 case OPC_SUBQ_PW:
13028 check_dsp(ctx);
13029 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13030 break;
13031 case OPC_SUBQ_S_PW:
13032 check_dsp(ctx);
13033 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13034 break;
13035 case OPC_SUBQ_QH:
13036 check_dsp(ctx);
13037 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13038 break;
13039 case OPC_SUBQ_S_QH:
13040 check_dsp(ctx);
13041 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13042 break;
13043 case OPC_SUBU_OB:
13044 check_dsp(ctx);
13045 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13046 break;
13047 case OPC_SUBU_S_OB:
13048 check_dsp(ctx);
13049 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13050 break;
13051 case OPC_SUBU_QH:
13052 check_dspr2(ctx);
13053 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13054 break;
13055 case OPC_SUBU_S_QH:
13056 check_dspr2(ctx);
13057 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13058 break;
13059 case OPC_SUBUH_OB:
13060 check_dspr2(ctx);
13061 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13062 break;
13063 case OPC_SUBUH_R_OB:
13064 check_dspr2(ctx);
13065 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13066 break;
13067 case OPC_ADDQ_PW:
13068 check_dsp(ctx);
13069 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13070 break;
13071 case OPC_ADDQ_S_PW:
13072 check_dsp(ctx);
13073 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13074 break;
13075 case OPC_ADDQ_QH:
13076 check_dsp(ctx);
13077 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13078 break;
13079 case OPC_ADDQ_S_QH:
13080 check_dsp(ctx);
13081 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13082 break;
13083 case OPC_ADDU_OB:
13084 check_dsp(ctx);
13085 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13086 break;
13087 case OPC_ADDU_S_OB:
13088 check_dsp(ctx);
13089 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13090 break;
13091 case OPC_ADDU_QH:
13092 check_dspr2(ctx);
13093 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13094 break;
13095 case OPC_ADDU_S_QH:
13096 check_dspr2(ctx);
13097 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13098 break;
13099 case OPC_ADDUH_OB:
13100 check_dspr2(ctx);
13101 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13102 break;
13103 case OPC_ADDUH_R_OB:
13104 check_dspr2(ctx);
13105 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13106 break;
13107 }
13108 break;
13109 case OPC_CMPU_EQ_OB_DSP:
13110 switch (op2) {
13111 case OPC_PRECR_OB_QH:
13112 check_dspr2(ctx);
13113 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13114 break;
13115 case OPC_PRECR_SRA_QH_PW:
13116 check_dspr2(ctx);
13117 {
13118 TCGv_i32 ret_t = tcg_const_i32(ret);
13119 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13120 tcg_temp_free_i32(ret_t);
13121 break;
13122 }
13123 case OPC_PRECR_SRA_R_QH_PW:
13124 check_dspr2(ctx);
13125 {
13126 TCGv_i32 sa_v = tcg_const_i32(ret);
13127 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13128 tcg_temp_free_i32(sa_v);
13129 break;
13130 }
13131 case OPC_PRECRQ_OB_QH:
13132 check_dsp(ctx);
13133 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13134 break;
13135 case OPC_PRECRQ_PW_L:
13136 check_dsp(ctx);
13137 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13138 break;
13139 case OPC_PRECRQ_QH_PW:
13140 check_dsp(ctx);
13141 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13142 break;
13143 case OPC_PRECRQ_RS_QH_PW:
13144 check_dsp(ctx);
13145 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13146 break;
13147 case OPC_PRECRQU_S_OB_QH:
13148 check_dsp(ctx);
13149 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13150 break;
13151 }
13152 break;
13153#endif
13154 }
13155
13156 tcg_temp_free(v1_t);
13157 tcg_temp_free(v2_t);
13158
13159 (void)opn; /* avoid a compiler warning */
13160 MIPS_DEBUG("%s", opn);
13161}
9b1a1d68 13162
77c5fa8b
JL
13163static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13164 int ret, int v1, int v2)
13165{
13166 uint32_t op2;
13167 const char *opn = "mipsdsp shift";
13168 TCGv t0;
13169 TCGv v1_t;
13170 TCGv v2_t;
13171
13172 if (ret == 0) {
13173 /* Treat as NOP. */
13174 MIPS_DEBUG("NOP");
13175 return;
13176 }
13177
13178 t0 = tcg_temp_new();
13179 v1_t = tcg_temp_new();
13180 v2_t = tcg_temp_new();
13181
13182 tcg_gen_movi_tl(t0, v1);
13183 gen_load_gpr(v1_t, v1);
13184 gen_load_gpr(v2_t, v2);
13185
13186 switch (opc) {
13187 case OPC_SHLL_QB_DSP:
13188 {
13189 op2 = MASK_SHLL_QB(ctx->opcode);
13190 switch (op2) {
13191 case OPC_SHLL_QB:
13192 check_dsp(ctx);
13193 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13194 break;
13195 case OPC_SHLLV_QB:
13196 check_dsp(ctx);
13197 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13198 break;
13199 case OPC_SHLL_PH:
13200 check_dsp(ctx);
13201 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13202 break;
13203 case OPC_SHLLV_PH:
13204 check_dsp(ctx);
13205 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13206 break;
13207 case OPC_SHLL_S_PH:
13208 check_dsp(ctx);
13209 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13210 break;
13211 case OPC_SHLLV_S_PH:
13212 check_dsp(ctx);
13213 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13214 break;
13215 case OPC_SHLL_S_W:
13216 check_dsp(ctx);
13217 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13218 break;
13219 case OPC_SHLLV_S_W:
13220 check_dsp(ctx);
13221 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13222 break;
13223 case OPC_SHRL_QB:
13224 check_dsp(ctx);
13225 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13226 break;
13227 case OPC_SHRLV_QB:
13228 check_dsp(ctx);
13229 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13230 break;
13231 case OPC_SHRL_PH:
13232 check_dspr2(ctx);
13233 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13234 break;
13235 case OPC_SHRLV_PH:
13236 check_dspr2(ctx);
13237 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13238 break;
13239 case OPC_SHRA_QB:
13240 check_dspr2(ctx);
13241 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13242 break;
13243 case OPC_SHRA_R_QB:
13244 check_dspr2(ctx);
13245 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13246 break;
13247 case OPC_SHRAV_QB:
13248 check_dspr2(ctx);
13249 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13250 break;
13251 case OPC_SHRAV_R_QB:
13252 check_dspr2(ctx);
13253 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13254 break;
13255 case OPC_SHRA_PH:
13256 check_dsp(ctx);
13257 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13258 break;
13259 case OPC_SHRA_R_PH:
13260 check_dsp(ctx);
13261 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13262 break;
13263 case OPC_SHRAV_PH:
13264 check_dsp(ctx);
13265 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13266 break;
13267 case OPC_SHRAV_R_PH:
13268 check_dsp(ctx);
13269 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13270 break;
13271 case OPC_SHRA_R_W:
13272 check_dsp(ctx);
13273 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13274 break;
13275 case OPC_SHRAV_R_W:
13276 check_dsp(ctx);
13277 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13278 break;
13279 default: /* Invalid */
13280 MIPS_INVAL("MASK SHLL.QB");
13281 generate_exception(ctx, EXCP_RI);
13282 break;
13283 }
13284 break;
13285 }
13286#ifdef TARGET_MIPS64
13287 case OPC_SHLL_OB_DSP:
13288 op2 = MASK_SHLL_OB(ctx->opcode);
13289 switch (op2) {
13290 case OPC_SHLL_PW:
13291 check_dsp(ctx);
13292 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13293 break;
13294 case OPC_SHLLV_PW:
13295 check_dsp(ctx);
13296 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13297 break;
13298 case OPC_SHLL_S_PW:
13299 check_dsp(ctx);
13300 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13301 break;
13302 case OPC_SHLLV_S_PW:
13303 check_dsp(ctx);
13304 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13305 break;
13306 case OPC_SHLL_OB:
13307 check_dsp(ctx);
13308 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13309 break;
13310 case OPC_SHLLV_OB:
13311 check_dsp(ctx);
13312 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13313 break;
13314 case OPC_SHLL_QH:
13315 check_dsp(ctx);
13316 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13317 break;
13318 case OPC_SHLLV_QH:
13319 check_dsp(ctx);
13320 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13321 break;
13322 case OPC_SHLL_S_QH:
13323 check_dsp(ctx);
13324 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13325 break;
13326 case OPC_SHLLV_S_QH:
13327 check_dsp(ctx);
13328 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13329 break;
13330 case OPC_SHRA_OB:
13331 check_dspr2(ctx);
13332 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13333 break;
13334 case OPC_SHRAV_OB:
13335 check_dspr2(ctx);
13336 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13337 break;
13338 case OPC_SHRA_R_OB:
13339 check_dspr2(ctx);
13340 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13341 break;
13342 case OPC_SHRAV_R_OB:
13343 check_dspr2(ctx);
13344 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13345 break;
13346 case OPC_SHRA_PW:
13347 check_dsp(ctx);
13348 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13349 break;
13350 case OPC_SHRAV_PW:
13351 check_dsp(ctx);
13352 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13353 break;
13354 case OPC_SHRA_R_PW:
13355 check_dsp(ctx);
13356 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13357 break;
13358 case OPC_SHRAV_R_PW:
13359 check_dsp(ctx);
13360 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13361 break;
13362 case OPC_SHRA_QH:
13363 check_dsp(ctx);
13364 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13365 break;
13366 case OPC_SHRAV_QH:
13367 check_dsp(ctx);
13368 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13369 break;
13370 case OPC_SHRA_R_QH:
13371 check_dsp(ctx);
13372 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13373 break;
13374 case OPC_SHRAV_R_QH:
13375 check_dsp(ctx);
13376 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13377 break;
13378 case OPC_SHRL_OB:
13379 check_dsp(ctx);
13380 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13381 break;
13382 case OPC_SHRLV_OB:
13383 check_dsp(ctx);
13384 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13385 break;
13386 case OPC_SHRL_QH:
13387 check_dspr2(ctx);
13388 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13389 break;
13390 case OPC_SHRLV_QH:
13391 check_dspr2(ctx);
13392 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13393 break;
13394 default: /* Invalid */
13395 MIPS_INVAL("MASK SHLL.OB");
13396 generate_exception(ctx, EXCP_RI);
13397 break;
13398 }
13399 break;
13400#endif
13401 }
13402
13403 tcg_temp_free(t0);
13404 tcg_temp_free(v1_t);
13405 tcg_temp_free(v2_t);
13406 (void)opn; /* avoid a compiler warning */
13407 MIPS_DEBUG("%s", opn);
13408}
13409
a22260ae
JL
13410static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13411 int ret, int v1, int v2, int check_ret)
13412{
13413 const char *opn = "mipsdsp multiply";
13414 TCGv_i32 t0;
13415 TCGv v1_t;
13416 TCGv v2_t;
13417
13418 if ((ret == 0) && (check_ret == 1)) {
13419 /* Treat as NOP. */
13420 MIPS_DEBUG("NOP");
13421 return;
13422 }
13423
13424 t0 = tcg_temp_new_i32();
13425 v1_t = tcg_temp_new();
13426 v2_t = tcg_temp_new();
13427
13428 tcg_gen_movi_i32(t0, ret);
13429 gen_load_gpr(v1_t, v1);
13430 gen_load_gpr(v2_t, v2);
13431
13432 switch (op1) {
13433 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13434 * the same mask and op1. */
13435 case OPC_MULT_G_2E:
13436 switch (op2) {
13437 case OPC_MUL_PH:
13438 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13439 break;
13440 case OPC_MUL_S_PH:
13441 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13442 break;
13443 case OPC_MULQ_S_W:
13444 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13445 break;
13446 case OPC_MULQ_RS_W:
13447 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13448 break;
13449 }
13450 break;
13451 case OPC_DPA_W_PH_DSP:
13452 switch (op2) {
13453 case OPC_DPAU_H_QBL:
13454 check_dsp(ctx);
13455 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13456 break;
13457 case OPC_DPAU_H_QBR:
13458 check_dsp(ctx);
13459 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13460 break;
13461 case OPC_DPSU_H_QBL:
13462 check_dsp(ctx);
13463 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13464 break;
13465 case OPC_DPSU_H_QBR:
13466 check_dsp(ctx);
13467 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13468 break;
13469 case OPC_DPA_W_PH:
13470 check_dspr2(ctx);
13471 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13472 break;
13473 case OPC_DPAX_W_PH:
13474 check_dspr2(ctx);
13475 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13476 break;
13477 case OPC_DPAQ_S_W_PH:
13478 check_dsp(ctx);
13479 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13480 break;
13481 case OPC_DPAQX_S_W_PH:
13482 check_dspr2(ctx);
13483 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13484 break;
13485 case OPC_DPAQX_SA_W_PH:
13486 check_dspr2(ctx);
13487 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13488 break;
13489 case OPC_DPS_W_PH:
13490 check_dspr2(ctx);
13491 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13492 break;
13493 case OPC_DPSX_W_PH:
13494 check_dspr2(ctx);
13495 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13496 break;
13497 case OPC_DPSQ_S_W_PH:
13498 check_dsp(ctx);
13499 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13500 break;
13501 case OPC_DPSQX_S_W_PH:
13502 check_dspr2(ctx);
13503 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13504 break;
13505 case OPC_DPSQX_SA_W_PH:
13506 check_dspr2(ctx);
13507 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13508 break;
13509 case OPC_MULSAQ_S_W_PH:
13510 check_dsp(ctx);
13511 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13512 break;
13513 case OPC_DPAQ_SA_L_W:
13514 check_dsp(ctx);
13515 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13516 break;
13517 case OPC_DPSQ_SA_L_W:
13518 check_dsp(ctx);
13519 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13520 break;
13521 case OPC_MAQ_S_W_PHL:
13522 check_dsp(ctx);
13523 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13524 break;
13525 case OPC_MAQ_S_W_PHR:
13526 check_dsp(ctx);
13527 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13528 break;
13529 case OPC_MAQ_SA_W_PHL:
13530 check_dsp(ctx);
13531 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13532 break;
13533 case OPC_MAQ_SA_W_PHR:
13534 check_dsp(ctx);
13535 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13536 break;
13537 case OPC_MULSA_W_PH:
13538 check_dspr2(ctx);
13539 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13540 break;
13541 }
13542 break;
13543#ifdef TARGET_MIPS64
13544 case OPC_DPAQ_W_QH_DSP:
13545 {
13546 int ac = ret & 0x03;
13547 tcg_gen_movi_i32(t0, ac);
13548
13549 switch (op2) {
13550 case OPC_DMADD:
13551 check_dsp(ctx);
13552 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13553 break;
13554 case OPC_DMADDU:
13555 check_dsp(ctx);
13556 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13557 break;
13558 case OPC_DMSUB:
13559 check_dsp(ctx);
13560 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13561 break;
13562 case OPC_DMSUBU:
13563 check_dsp(ctx);
13564 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13565 break;
13566 case OPC_DPA_W_QH:
13567 check_dspr2(ctx);
13568 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13569 break;
13570 case OPC_DPAQ_S_W_QH:
13571 check_dsp(ctx);
13572 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13573 break;
13574 case OPC_DPAQ_SA_L_PW:
13575 check_dsp(ctx);
13576 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13577 break;
13578 case OPC_DPAU_H_OBL:
13579 check_dsp(ctx);
13580 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13581 break;
13582 case OPC_DPAU_H_OBR:
13583 check_dsp(ctx);
13584 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13585 break;
13586 case OPC_DPS_W_QH:
13587 check_dspr2(ctx);
13588 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13589 break;
13590 case OPC_DPSQ_S_W_QH:
13591 check_dsp(ctx);
13592 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13593 break;
13594 case OPC_DPSQ_SA_L_PW:
13595 check_dsp(ctx);
13596 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13597 break;
13598 case OPC_DPSU_H_OBL:
13599 check_dsp(ctx);
13600 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13601 break;
13602 case OPC_DPSU_H_OBR:
13603 check_dsp(ctx);
13604 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13605 break;
13606 case OPC_MAQ_S_L_PWL:
13607 check_dsp(ctx);
13608 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13609 break;
13610 case OPC_MAQ_S_L_PWR:
13611 check_dsp(ctx);
13612 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13613 break;
13614 case OPC_MAQ_S_W_QHLL:
13615 check_dsp(ctx);
13616 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13617 break;
13618 case OPC_MAQ_SA_W_QHLL:
13619 check_dsp(ctx);
13620 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13621 break;
13622 case OPC_MAQ_S_W_QHLR:
13623 check_dsp(ctx);
13624 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13625 break;
13626 case OPC_MAQ_SA_W_QHLR:
13627 check_dsp(ctx);
13628 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13629 break;
13630 case OPC_MAQ_S_W_QHRL:
13631 check_dsp(ctx);
13632 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13633 break;
13634 case OPC_MAQ_SA_W_QHRL:
13635 check_dsp(ctx);
13636 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13637 break;
13638 case OPC_MAQ_S_W_QHRR:
13639 check_dsp(ctx);
13640 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13641 break;
13642 case OPC_MAQ_SA_W_QHRR:
13643 check_dsp(ctx);
13644 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13645 break;
13646 case OPC_MULSAQ_S_L_PW:
13647 check_dsp(ctx);
13648 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13649 break;
13650 case OPC_MULSAQ_S_W_QH:
13651 check_dsp(ctx);
13652 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13653 break;
13654 }
13655 }
13656 break;
13657#endif
13658 case OPC_ADDU_QB_DSP:
13659 switch (op2) {
13660 case OPC_MULEU_S_PH_QBL:
13661 check_dsp(ctx);
13662 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13663 break;
13664 case OPC_MULEU_S_PH_QBR:
13665 check_dsp(ctx);
13666 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13667 break;
13668 case OPC_MULQ_RS_PH:
13669 check_dsp(ctx);
13670 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13671 break;
13672 case OPC_MULEQ_S_W_PHL:
13673 check_dsp(ctx);
13674 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13675 break;
13676 case OPC_MULEQ_S_W_PHR:
13677 check_dsp(ctx);
13678 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13679 break;
13680 case OPC_MULQ_S_PH:
13681 check_dspr2(ctx);
13682 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13683 break;
13684 }
13685 break;
13686#ifdef TARGET_MIPS64
13687 case OPC_ADDU_OB_DSP:
13688 switch (op2) {
13689 case OPC_MULEQ_S_PW_QHL:
13690 check_dsp(ctx);
13691 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13692 break;
13693 case OPC_MULEQ_S_PW_QHR:
13694 check_dsp(ctx);
13695 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13696 break;
13697 case OPC_MULEU_S_QH_OBL:
13698 check_dsp(ctx);
13699 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13700 break;
13701 case OPC_MULEU_S_QH_OBR:
13702 check_dsp(ctx);
13703 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13704 break;
13705 case OPC_MULQ_RS_QH:
13706 check_dsp(ctx);
13707 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13708 break;
13709 }
13710 break;
13711#endif
13712 }
13713
13714 tcg_temp_free_i32(t0);
13715 tcg_temp_free(v1_t);
13716 tcg_temp_free(v2_t);
13717
13718 (void)opn; /* avoid a compiler warning */
13719 MIPS_DEBUG("%s", opn);
13720
13721}
13722
d75c135e 13723static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13724 int ret, int val)
13725{
13726 const char *opn = "mipsdsp Bit/ Manipulation";
13727 int16_t imm;
13728 TCGv t0;
13729 TCGv val_t;
13730
13731 if (ret == 0) {
13732 /* Treat as NOP. */
13733 MIPS_DEBUG("NOP");
13734 return;
13735 }
13736
13737 t0 = tcg_temp_new();
13738 val_t = tcg_temp_new();
13739 gen_load_gpr(val_t, val);
13740
13741 switch (op1) {
13742 case OPC_ABSQ_S_PH_DSP:
13743 switch (op2) {
13744 case OPC_BITREV:
13745 check_dsp(ctx);
13746 gen_helper_bitrev(cpu_gpr[ret], val_t);
13747 break;
13748 case OPC_REPL_QB:
13749 check_dsp(ctx);
13750 {
13751 target_long result;
13752 imm = (ctx->opcode >> 16) & 0xFF;
13753 result = (uint32_t)imm << 24 |
13754 (uint32_t)imm << 16 |
13755 (uint32_t)imm << 8 |
13756 (uint32_t)imm;
13757 result = (int32_t)result;
13758 tcg_gen_movi_tl(cpu_gpr[ret], result);
13759 }
13760 break;
13761 case OPC_REPLV_QB:
13762 check_dsp(ctx);
13763 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13764 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13765 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13766 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13767 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13768 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13769 break;
13770 case OPC_REPL_PH:
13771 check_dsp(ctx);
13772 {
13773 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13774 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13775 tcg_gen_movi_tl(cpu_gpr[ret], \
13776 (target_long)((int32_t)imm << 16 | \
c4aaba92 13777 (uint16_t)imm));
1cb6686c
JL
13778 }
13779 break;
13780 case OPC_REPLV_PH:
13781 check_dsp(ctx);
13782 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13783 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13784 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13785 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13786 break;
13787 }
13788 break;
13789#ifdef TARGET_MIPS64
13790 case OPC_ABSQ_S_QH_DSP:
13791 switch (op2) {
13792 case OPC_REPL_OB:
13793 check_dsp(ctx);
13794 {
13795 target_long temp;
13796
13797 imm = (ctx->opcode >> 16) & 0xFF;
13798 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13799 temp = (temp << 16) | temp;
13800 temp = (temp << 32) | temp;
13801 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13802 break;
13803 }
13804 case OPC_REPL_PW:
13805 check_dsp(ctx);
13806 {
13807 target_long temp;
13808
13809 imm = (ctx->opcode >> 16) & 0x03FF;
13810 imm = (int16_t)(imm << 6) >> 6;
13811 temp = ((target_long)imm << 32) \
13812 | ((target_long)imm & 0xFFFFFFFF);
13813 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13814 break;
13815 }
13816 case OPC_REPL_QH:
13817 check_dsp(ctx);
13818 {
13819 target_long temp;
13820
13821 imm = (ctx->opcode >> 16) & 0x03FF;
13822 imm = (int16_t)(imm << 6) >> 6;
13823
13824 temp = ((uint64_t)(uint16_t)imm << 48) |
13825 ((uint64_t)(uint16_t)imm << 32) |
13826 ((uint64_t)(uint16_t)imm << 16) |
13827 (uint64_t)(uint16_t)imm;
13828 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13829 break;
13830 }
13831 case OPC_REPLV_OB:
13832 check_dsp(ctx);
13833 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13834 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13835 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13836 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13837 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13838 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13839 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13840 break;
13841 case OPC_REPLV_PW:
13842 check_dsp(ctx);
13843 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13844 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13845 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13846 break;
13847 case OPC_REPLV_QH:
13848 check_dsp(ctx);
13849 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13850 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13851 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13852 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13853 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13854 break;
13855 }
13856 break;
13857#endif
13858 }
13859 tcg_temp_free(t0);
13860 tcg_temp_free(val_t);
13861
13862 (void)opn; /* avoid a compiler warning */
13863 MIPS_DEBUG("%s", opn);
13864}
13865
26690560
JL
13866static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13867 uint32_t op1, uint32_t op2,
13868 int ret, int v1, int v2, int check_ret)
13869{
13870 const char *opn = "mipsdsp add compare pick";
26690560
JL
13871 TCGv t1;
13872 TCGv v1_t;
13873 TCGv v2_t;
13874
13875 if ((ret == 0) && (check_ret == 1)) {
13876 /* Treat as NOP. */
13877 MIPS_DEBUG("NOP");
13878 return;
13879 }
13880
26690560
JL
13881 t1 = tcg_temp_new();
13882 v1_t = tcg_temp_new();
13883 v2_t = tcg_temp_new();
13884
13885 gen_load_gpr(v1_t, v1);
13886 gen_load_gpr(v2_t, v2);
13887
13888 switch (op1) {
26690560
JL
13889 case OPC_CMPU_EQ_QB_DSP:
13890 switch (op2) {
13891 case OPC_CMPU_EQ_QB:
13892 check_dsp(ctx);
13893 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13894 break;
13895 case OPC_CMPU_LT_QB:
13896 check_dsp(ctx);
13897 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13898 break;
13899 case OPC_CMPU_LE_QB:
13900 check_dsp(ctx);
13901 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13902 break;
13903 case OPC_CMPGU_EQ_QB:
13904 check_dsp(ctx);
13905 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13906 break;
13907 case OPC_CMPGU_LT_QB:
13908 check_dsp(ctx);
13909 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13910 break;
13911 case OPC_CMPGU_LE_QB:
13912 check_dsp(ctx);
13913 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13914 break;
13915 case OPC_CMPGDU_EQ_QB:
13916 check_dspr2(ctx);
13917 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13918 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13919 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13920 tcg_gen_shli_tl(t1, t1, 24);
13921 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13922 break;
13923 case OPC_CMPGDU_LT_QB:
13924 check_dspr2(ctx);
13925 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13926 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13927 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13928 tcg_gen_shli_tl(t1, t1, 24);
13929 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13930 break;
13931 case OPC_CMPGDU_LE_QB:
13932 check_dspr2(ctx);
13933 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13934 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13935 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13936 tcg_gen_shli_tl(t1, t1, 24);
13937 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13938 break;
13939 case OPC_CMP_EQ_PH:
13940 check_dsp(ctx);
13941 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13942 break;
13943 case OPC_CMP_LT_PH:
13944 check_dsp(ctx);
13945 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13946 break;
13947 case OPC_CMP_LE_PH:
13948 check_dsp(ctx);
13949 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13950 break;
13951 case OPC_PICK_QB:
13952 check_dsp(ctx);
13953 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13954 break;
13955 case OPC_PICK_PH:
13956 check_dsp(ctx);
13957 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13958 break;
13959 case OPC_PACKRL_PH:
13960 check_dsp(ctx);
13961 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13962 break;
13963 }
13964 break;
13965#ifdef TARGET_MIPS64
13966 case OPC_CMPU_EQ_OB_DSP:
13967 switch (op2) {
13968 case OPC_CMP_EQ_PW:
13969 check_dsp(ctx);
13970 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13971 break;
13972 case OPC_CMP_LT_PW:
13973 check_dsp(ctx);
13974 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13975 break;
13976 case OPC_CMP_LE_PW:
13977 check_dsp(ctx);
13978 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13979 break;
13980 case OPC_CMP_EQ_QH:
13981 check_dsp(ctx);
13982 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13983 break;
13984 case OPC_CMP_LT_QH:
13985 check_dsp(ctx);
13986 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13987 break;
13988 case OPC_CMP_LE_QH:
13989 check_dsp(ctx);
13990 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13991 break;
13992 case OPC_CMPGDU_EQ_OB:
13993 check_dspr2(ctx);
13994 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13995 break;
13996 case OPC_CMPGDU_LT_OB:
13997 check_dspr2(ctx);
13998 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13999 break;
14000 case OPC_CMPGDU_LE_OB:
14001 check_dspr2(ctx);
14002 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14003 break;
14004 case OPC_CMPGU_EQ_OB:
14005 check_dsp(ctx);
14006 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14007 break;
14008 case OPC_CMPGU_LT_OB:
14009 check_dsp(ctx);
14010 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14011 break;
14012 case OPC_CMPGU_LE_OB:
14013 check_dsp(ctx);
14014 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14015 break;
14016 case OPC_CMPU_EQ_OB:
14017 check_dsp(ctx);
14018 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14019 break;
14020 case OPC_CMPU_LT_OB:
14021 check_dsp(ctx);
14022 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14023 break;
14024 case OPC_CMPU_LE_OB:
14025 check_dsp(ctx);
14026 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14027 break;
14028 case OPC_PACKRL_PW:
14029 check_dsp(ctx);
14030 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14031 break;
14032 case OPC_PICK_OB:
14033 check_dsp(ctx);
14034 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14035 break;
14036 case OPC_PICK_PW:
14037 check_dsp(ctx);
14038 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14039 break;
14040 case OPC_PICK_QH:
14041 check_dsp(ctx);
14042 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14043 break;
14044 }
14045 break;
df6126a7
AJ
14046#endif
14047 }
14048
14049 tcg_temp_free(t1);
14050 tcg_temp_free(v1_t);
14051 tcg_temp_free(v2_t);
14052
14053 (void)opn; /* avoid a compiler warning */
14054 MIPS_DEBUG("%s", opn);
14055}
14056
14057static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14058 uint32_t op1, int rt, int rs, int sa)
14059{
14060 const char *opn = "mipsdsp append/dappend";
14061 TCGv t0;
14062
14063 check_dspr2(ctx);
14064
14065 if (rt == 0) {
14066 /* Treat as NOP. */
14067 MIPS_DEBUG("NOP");
14068 return;
14069 }
14070
14071 t0 = tcg_temp_new();
14072 gen_load_gpr(t0, rs);
14073
14074 switch (op1) {
14075 case OPC_APPEND_DSP:
14076 switch (MASK_APPEND(ctx->opcode)) {
14077 case OPC_APPEND:
14078 if (sa != 0) {
14079 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14080 }
14081 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14082 break;
14083 case OPC_PREPEND:
14084 if (sa != 0) {
14085 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14086 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14087 tcg_gen_shli_tl(t0, t0, 32 - sa);
14088 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14089 }
14090 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14091 break;
14092 case OPC_BALIGN:
14093 sa &= 3;
14094 if (sa != 0 && sa != 2) {
14095 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14096 tcg_gen_ext32u_tl(t0, t0);
14097 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14098 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14099 }
14100 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14101 break;
14102 default: /* Invalid */
14103 MIPS_INVAL("MASK APPEND");
14104 generate_exception(ctx, EXCP_RI);
14105 break;
14106 }
14107 break;
14108#ifdef TARGET_MIPS64
26690560 14109 case OPC_DAPPEND_DSP:
df6126a7 14110 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 14111 case OPC_DAPPEND:
df6126a7
AJ
14112 if (sa != 0) {
14113 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14114 }
26690560
JL
14115 break;
14116 case OPC_PREPENDD:
df6126a7
AJ
14117 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14118 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14119 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
14120 break;
14121 case OPC_PREPENDW:
df6126a7
AJ
14122 if (sa != 0) {
14123 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14124 tcg_gen_shli_tl(t0, t0, 64 - sa);
14125 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14126 }
26690560
JL
14127 break;
14128 case OPC_DBALIGN:
df6126a7
AJ
14129 sa &= 7;
14130 if (sa != 0 && sa != 2 && sa != 4) {
14131 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14132 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14133 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14134 }
26690560
JL
14135 break;
14136 default: /* Invalid */
14137 MIPS_INVAL("MASK DAPPEND");
14138 generate_exception(ctx, EXCP_RI);
14139 break;
14140 }
14141 break;
14142#endif
14143 }
df6126a7 14144 tcg_temp_free(t0);
26690560
JL
14145 (void)opn; /* avoid a compiler warning */
14146 MIPS_DEBUG("%s", opn);
14147}
14148
b53371ed
JL
14149static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14150 int ret, int v1, int v2, int check_ret)
14151
14152{
14153 const char *opn = "mipsdsp accumulator";
14154 TCGv t0;
14155 TCGv t1;
14156 TCGv v1_t;
14157 TCGv v2_t;
14158 int16_t imm;
14159
14160 if ((ret == 0) && (check_ret == 1)) {
14161 /* Treat as NOP. */
14162 MIPS_DEBUG("NOP");
14163 return;
14164 }
14165
14166 t0 = tcg_temp_new();
14167 t1 = tcg_temp_new();
14168 v1_t = tcg_temp_new();
14169 v2_t = tcg_temp_new();
14170
14171 gen_load_gpr(v1_t, v1);
14172 gen_load_gpr(v2_t, v2);
14173
14174 switch (op1) {
14175 case OPC_EXTR_W_DSP:
14176 check_dsp(ctx);
14177 switch (op2) {
14178 case OPC_EXTR_W:
14179 tcg_gen_movi_tl(t0, v2);
14180 tcg_gen_movi_tl(t1, v1);
14181 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14182 break;
14183 case OPC_EXTR_R_W:
14184 tcg_gen_movi_tl(t0, v2);
14185 tcg_gen_movi_tl(t1, v1);
14186 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14187 break;
14188 case OPC_EXTR_RS_W:
14189 tcg_gen_movi_tl(t0, v2);
14190 tcg_gen_movi_tl(t1, v1);
14191 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14192 break;
14193 case OPC_EXTR_S_H:
14194 tcg_gen_movi_tl(t0, v2);
14195 tcg_gen_movi_tl(t1, v1);
14196 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14197 break;
14198 case OPC_EXTRV_S_H:
14199 tcg_gen_movi_tl(t0, v2);
14200 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14201 break;
14202 case OPC_EXTRV_W:
14203 tcg_gen_movi_tl(t0, v2);
14204 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14205 break;
14206 case OPC_EXTRV_R_W:
14207 tcg_gen_movi_tl(t0, v2);
14208 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14209 break;
14210 case OPC_EXTRV_RS_W:
14211 tcg_gen_movi_tl(t0, v2);
14212 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14213 break;
14214 case OPC_EXTP:
14215 tcg_gen_movi_tl(t0, v2);
14216 tcg_gen_movi_tl(t1, v1);
14217 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14218 break;
14219 case OPC_EXTPV:
14220 tcg_gen_movi_tl(t0, v2);
14221 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14222 break;
14223 case OPC_EXTPDP:
14224 tcg_gen_movi_tl(t0, v2);
14225 tcg_gen_movi_tl(t1, v1);
14226 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14227 break;
14228 case OPC_EXTPDPV:
14229 tcg_gen_movi_tl(t0, v2);
14230 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14231 break;
14232 case OPC_SHILO:
14233 imm = (ctx->opcode >> 20) & 0x3F;
14234 tcg_gen_movi_tl(t0, ret);
14235 tcg_gen_movi_tl(t1, imm);
14236 gen_helper_shilo(t0, t1, cpu_env);
14237 break;
14238 case OPC_SHILOV:
14239 tcg_gen_movi_tl(t0, ret);
14240 gen_helper_shilo(t0, v1_t, cpu_env);
14241 break;
14242 case OPC_MTHLIP:
14243 tcg_gen_movi_tl(t0, ret);
14244 gen_helper_mthlip(t0, v1_t, cpu_env);
14245 break;
14246 case OPC_WRDSP:
14247 imm = (ctx->opcode >> 11) & 0x3FF;
14248 tcg_gen_movi_tl(t0, imm);
14249 gen_helper_wrdsp(v1_t, t0, cpu_env);
14250 break;
14251 case OPC_RDDSP:
14252 imm = (ctx->opcode >> 16) & 0x03FF;
14253 tcg_gen_movi_tl(t0, imm);
14254 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14255 break;
14256 }
14257 break;
14258#ifdef TARGET_MIPS64
14259 case OPC_DEXTR_W_DSP:
14260 check_dsp(ctx);
14261 switch (op2) {
14262 case OPC_DMTHLIP:
14263 tcg_gen_movi_tl(t0, ret);
14264 gen_helper_dmthlip(v1_t, t0, cpu_env);
14265 break;
14266 case OPC_DSHILO:
14267 {
14268 int shift = (ctx->opcode >> 19) & 0x7F;
14269 int ac = (ctx->opcode >> 11) & 0x03;
14270 tcg_gen_movi_tl(t0, shift);
14271 tcg_gen_movi_tl(t1, ac);
14272 gen_helper_dshilo(t0, t1, cpu_env);
14273 break;
14274 }
14275 case OPC_DSHILOV:
14276 {
14277 int ac = (ctx->opcode >> 11) & 0x03;
14278 tcg_gen_movi_tl(t0, ac);
14279 gen_helper_dshilo(v1_t, t0, cpu_env);
14280 break;
14281 }
14282 case OPC_DEXTP:
14283 tcg_gen_movi_tl(t0, v2);
14284 tcg_gen_movi_tl(t1, v1);
14285
14286 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14287 break;
14288 case OPC_DEXTPV:
14289 tcg_gen_movi_tl(t0, v2);
14290 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14291 break;
14292 case OPC_DEXTPDP:
14293 tcg_gen_movi_tl(t0, v2);
14294 tcg_gen_movi_tl(t1, v1);
14295 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14296 break;
14297 case OPC_DEXTPDPV:
14298 tcg_gen_movi_tl(t0, v2);
14299 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14300 break;
14301 case OPC_DEXTR_L:
14302 tcg_gen_movi_tl(t0, v2);
14303 tcg_gen_movi_tl(t1, v1);
14304 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14305 break;
14306 case OPC_DEXTR_R_L:
14307 tcg_gen_movi_tl(t0, v2);
14308 tcg_gen_movi_tl(t1, v1);
14309 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14310 break;
14311 case OPC_DEXTR_RS_L:
14312 tcg_gen_movi_tl(t0, v2);
14313 tcg_gen_movi_tl(t1, v1);
14314 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14315 break;
14316 case OPC_DEXTR_W:
14317 tcg_gen_movi_tl(t0, v2);
14318 tcg_gen_movi_tl(t1, v1);
14319 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14320 break;
14321 case OPC_DEXTR_R_W:
14322 tcg_gen_movi_tl(t0, v2);
14323 tcg_gen_movi_tl(t1, v1);
14324 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14325 break;
14326 case OPC_DEXTR_RS_W:
14327 tcg_gen_movi_tl(t0, v2);
14328 tcg_gen_movi_tl(t1, v1);
14329 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14330 break;
14331 case OPC_DEXTR_S_H:
14332 tcg_gen_movi_tl(t0, v2);
14333 tcg_gen_movi_tl(t1, v1);
14334 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14335 break;
14336 case OPC_DEXTRV_S_H:
14337 tcg_gen_movi_tl(t0, v2);
14338 tcg_gen_movi_tl(t1, v1);
14339 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14340 break;
14341 case OPC_DEXTRV_L:
14342 tcg_gen_movi_tl(t0, v2);
14343 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14344 break;
14345 case OPC_DEXTRV_R_L:
14346 tcg_gen_movi_tl(t0, v2);
14347 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14348 break;
14349 case OPC_DEXTRV_RS_L:
14350 tcg_gen_movi_tl(t0, v2);
14351 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14352 break;
14353 case OPC_DEXTRV_W:
14354 tcg_gen_movi_tl(t0, v2);
14355 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14356 break;
14357 case OPC_DEXTRV_R_W:
14358 tcg_gen_movi_tl(t0, v2);
14359 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14360 break;
14361 case OPC_DEXTRV_RS_W:
14362 tcg_gen_movi_tl(t0, v2);
14363 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14364 break;
14365 }
14366 break;
14367#endif
14368 }
14369
14370 tcg_temp_free(t0);
14371 tcg_temp_free(t1);
14372 tcg_temp_free(v1_t);
14373 tcg_temp_free(v2_t);
14374
14375 (void)opn; /* avoid a compiler warning */
14376 MIPS_DEBUG("%s", opn);
14377}
14378
9b1a1d68
JL
14379/* End MIPSDSP functions. */
14380
7db13fae 14381static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
14382{
14383 int32_t offset;
14384 int rs, rt, rd, sa;
14385 uint32_t op, op1, op2;
14386 int16_t imm;
14387
14388 /* make sure instructions are on a word boundary */
14389 if (ctx->pc & 0x3) {
14390 env->CP0_BadVAddr = ctx->pc;
14391 generate_exception(ctx, EXCP_AdEL);
14392 return;
14393 }
14394
14395 /* Handle blikely not taken case */
14396 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14397 int l1 = gen_new_label();
14398
14399 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14400 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14401 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14402 gen_goto_tb(ctx, 1, ctx->pc + 4);
14403 gen_set_label(l1);
14404 }
14405
fdefe51c 14406 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14407 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14408 }
3c824109
NF
14409
14410 op = MASK_OP_MAJOR(ctx->opcode);
14411 rs = (ctx->opcode >> 21) & 0x1f;
14412 rt = (ctx->opcode >> 16) & 0x1f;
14413 rd = (ctx->opcode >> 11) & 0x1f;
14414 sa = (ctx->opcode >> 6) & 0x1f;
14415 imm = (int16_t)ctx->opcode;
14416 switch (op) {
7a387fff
TS
14417 case OPC_SPECIAL:
14418 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14419 switch (op1) {
324d9e32
AJ
14420 case OPC_SLL: /* Shift with immediate */
14421 case OPC_SRA:
d75c135e 14422 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14423 break;
ea63e2c3
NF
14424 case OPC_SRL:
14425 switch ((ctx->opcode >> 21) & 0x1f) {
14426 case 1:
14427 /* rotr is decoded as srl on non-R2 CPUs */
d75c135e 14428 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14429 op1 = OPC_ROTR;
14430 }
14431 /* Fallthrough */
14432 case 0:
d75c135e 14433 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14434 break;
14435 default:
14436 generate_exception(ctx, EXCP_RI);
14437 break;
14438 }
14439 break;
460f00c4
AJ
14440 case OPC_MOVN: /* Conditional move */
14441 case OPC_MOVZ:
d75c135e 14442 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
aa8f4009 14443 INSN_LOONGSON2E | INSN_LOONGSON2F);
d75c135e 14444 gen_cond_move(ctx, op1, rd, rs, rt);
460f00c4
AJ
14445 break;
14446 case OPC_ADD ... OPC_SUBU:
d75c135e 14447 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14448 break;
460f00c4 14449 case OPC_SLLV: /* Shifts */
460f00c4 14450 case OPC_SRAV:
d75c135e 14451 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14452 break;
ea63e2c3
NF
14453 case OPC_SRLV:
14454 switch ((ctx->opcode >> 6) & 0x1f) {
14455 case 1:
14456 /* rotrv is decoded as srlv on non-R2 CPUs */
d75c135e 14457 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14458 op1 = OPC_ROTRV;
14459 }
14460 /* Fallthrough */
14461 case 0:
d75c135e 14462 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14463 break;
14464 default:
14465 generate_exception(ctx, EXCP_RI);
14466 break;
14467 }
14468 break;
460f00c4
AJ
14469 case OPC_SLT: /* Set on less than */
14470 case OPC_SLTU:
d75c135e 14471 gen_slt(ctx, op1, rd, rs, rt);
460f00c4
AJ
14472 break;
14473 case OPC_AND: /* Logic*/
14474 case OPC_OR:
14475 case OPC_NOR:
14476 case OPC_XOR:
d75c135e 14477 gen_logic(ctx, op1, rd, rs, rt);
460f00c4 14478 break;
7a387fff 14479 case OPC_MULT ... OPC_DIVU:
e9c71dd1 14480 if (sa) {
d75c135e 14481 check_insn(ctx, INSN_VR54XX);
e9c71dd1
TS
14482 op1 = MASK_MUL_VR54XX(ctx->opcode);
14483 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14484 } else
14485 gen_muldiv(ctx, op1, rs, rt);
7a387fff
TS
14486 break;
14487 case OPC_JR ... OPC_JALR:
7dca4ad0 14488 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061
NF
14489 *is_branch = 1;
14490 break;
7a387fff
TS
14491 case OPC_TGE ... OPC_TEQ: /* Traps */
14492 case OPC_TNE:
14493 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14494 break;
7a387fff
TS
14495 case OPC_MFHI: /* Move from HI/LO */
14496 case OPC_MFLO:
14497 gen_HILO(ctx, op1, rd);
6af0bf9c 14498 break;
7a387fff
TS
14499 case OPC_MTHI:
14500 case OPC_MTLO: /* Move to HI/LO */
14501 gen_HILO(ctx, op1, rs);
6af0bf9c 14502 break;
b48cfdff
TS
14503 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14504#ifdef MIPS_STRICT_STANDARD
14505 MIPS_INVAL("PMON / selsl");
14506 generate_exception(ctx, EXCP_RI);
14507#else
895c2d04 14508 gen_helper_0e0i(pmon, sa);
b48cfdff 14509#endif
7a387fff
TS
14510 break;
14511 case OPC_SYSCALL:
6af0bf9c 14512 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14513 ctx->bstate = BS_STOP;
6af0bf9c 14514 break;
7a387fff 14515 case OPC_BREAK:
6af0bf9c
FB
14516 generate_exception(ctx, EXCP_BREAK);
14517 break;
b48cfdff
TS
14518 case OPC_SPIM:
14519#ifdef MIPS_STRICT_STANDARD
14520 MIPS_INVAL("SPIM");
14521 generate_exception(ctx, EXCP_RI);
14522#else
7a387fff
TS
14523 /* Implemented as RI exception for now. */
14524 MIPS_INVAL("spim (unofficial)");
14525 generate_exception(ctx, EXCP_RI);
b48cfdff 14526#endif
6af0bf9c 14527 break;
7a387fff 14528 case OPC_SYNC:
ead9360e 14529 /* Treat as NOP. */
6af0bf9c 14530 break;
4ad40f36 14531
7a387fff 14532 case OPC_MOVCI:
d75c135e 14533 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14534 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14535 check_cp1_enabled(ctx);
36d23958
TS
14536 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14537 (ctx->opcode >> 16) & 1);
14538 } else {
e397ee33 14539 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14540 }
4ad40f36
FB
14541 break;
14542
d26bc211 14543#if defined(TARGET_MIPS64)
7a387fff
TS
14544 /* MIPS64 specific opcodes */
14545 case OPC_DSLL:
324d9e32 14546 case OPC_DSRA:
7a387fff 14547 case OPC_DSLL32:
324d9e32 14548 case OPC_DSRA32:
d75c135e 14549 check_insn(ctx, ISA_MIPS3);
e189e748 14550 check_mips_64(ctx);
d75c135e 14551 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14552 break;
ea63e2c3
NF
14553 case OPC_DSRL:
14554 switch ((ctx->opcode >> 21) & 0x1f) {
14555 case 1:
14556 /* drotr is decoded as dsrl on non-R2 CPUs */
d75c135e 14557 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14558 op1 = OPC_DROTR;
14559 }
14560 /* Fallthrough */
14561 case 0:
d75c135e 14562 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14563 check_mips_64(ctx);
d75c135e 14564 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14565 break;
14566 default:
14567 generate_exception(ctx, EXCP_RI);
14568 break;
14569 }
14570 break;
14571 case OPC_DSRL32:
14572 switch ((ctx->opcode >> 21) & 0x1f) {
14573 case 1:
14574 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
d75c135e 14575 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14576 op1 = OPC_DROTR32;
14577 }
14578 /* Fallthrough */
14579 case 0:
d75c135e 14580 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14581 check_mips_64(ctx);
d75c135e 14582 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14583 break;
14584 default:
14585 generate_exception(ctx, EXCP_RI);
14586 break;
14587 }
14588 break;
7a387fff 14589 case OPC_DADD ... OPC_DSUBU:
d75c135e 14590 check_insn(ctx, ISA_MIPS3);
e189e748 14591 check_mips_64(ctx);
d75c135e 14592 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14593 break;
460f00c4
AJ
14594 case OPC_DSLLV:
14595 case OPC_DSRAV:
d75c135e 14596 check_insn(ctx, ISA_MIPS3);
460f00c4 14597 check_mips_64(ctx);
d75c135e 14598 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14599 break;
ea63e2c3
NF
14600 case OPC_DSRLV:
14601 switch ((ctx->opcode >> 6) & 0x1f) {
14602 case 1:
14603 /* drotrv is decoded as dsrlv on non-R2 CPUs */
d75c135e 14604 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14605 op1 = OPC_DROTRV;
14606 }
14607 /* Fallthrough */
14608 case 0:
d75c135e 14609 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14610 check_mips_64(ctx);
d75c135e 14611 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14612 break;
14613 default:
14614 generate_exception(ctx, EXCP_RI);
14615 break;
14616 }
14617 break;
7a387fff 14618 case OPC_DMULT ... OPC_DDIVU:
d75c135e 14619 check_insn(ctx, ISA_MIPS3);
e189e748 14620 check_mips_64(ctx);
7a387fff
TS
14621 gen_muldiv(ctx, op1, rs, rt);
14622 break;
6af0bf9c
FB
14623#endif
14624 default: /* Invalid */
14625 MIPS_INVAL("special");
14626 generate_exception(ctx, EXCP_RI);
14627 break;
14628 }
14629 break;
7a387fff
TS
14630 case OPC_SPECIAL2:
14631 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14632 switch (op1) {
7a387fff
TS
14633 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14634 case OPC_MSUB ... OPC_MSUBU:
d75c135e 14635 check_insn(ctx, ISA_MIPS32);
7a387fff 14636 gen_muldiv(ctx, op1, rs, rt);
6af0bf9c 14637 break;
7a387fff 14638 case OPC_MUL:
d75c135e 14639 gen_arith(ctx, op1, rd, rs, rt);
6af0bf9c 14640 break;
20e1fb52
AJ
14641 case OPC_CLO:
14642 case OPC_CLZ:
d75c135e 14643 check_insn(ctx, ISA_MIPS32);
7a387fff 14644 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14645 break;
7a387fff 14646 case OPC_SDBBP:
6af0bf9c
FB
14647 /* XXX: not clear which exception should be raised
14648 * when in debug mode...
14649 */
d75c135e 14650 check_insn(ctx, ISA_MIPS32);
6af0bf9c
FB
14651 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14652 generate_exception(ctx, EXCP_DBp);
14653 } else {
14654 generate_exception(ctx, EXCP_DBp);
14655 }
ead9360e 14656 /* Treat as NOP. */
6af0bf9c 14657 break;
161f85e6
AJ
14658 case OPC_DIV_G_2F:
14659 case OPC_DIVU_G_2F:
14660 case OPC_MULT_G_2F:
14661 case OPC_MULTU_G_2F:
14662 case OPC_MOD_G_2F:
14663 case OPC_MODU_G_2F:
d75c135e 14664 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14665 gen_loongson_integer(ctx, op1, rd, rs, rt);
14666 break;
d26bc211 14667#if defined(TARGET_MIPS64)
20e1fb52
AJ
14668 case OPC_DCLO:
14669 case OPC_DCLZ:
d75c135e 14670 check_insn(ctx, ISA_MIPS64);
e189e748 14671 check_mips_64(ctx);
7a387fff
TS
14672 gen_cl(ctx, op1, rd, rs);
14673 break;
161f85e6
AJ
14674 case OPC_DMULT_G_2F:
14675 case OPC_DMULTU_G_2F:
14676 case OPC_DDIV_G_2F:
14677 case OPC_DDIVU_G_2F:
14678 case OPC_DMOD_G_2F:
14679 case OPC_DMODU_G_2F:
d75c135e 14680 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14681 gen_loongson_integer(ctx, op1, rd, rs, rt);
14682 break;
7a387fff 14683#endif
6af0bf9c
FB
14684 default: /* Invalid */
14685 MIPS_INVAL("special2");
14686 generate_exception(ctx, EXCP_RI);
14687 break;
14688 }
14689 break;
7a387fff 14690 case OPC_SPECIAL3:
2b0233ab
TS
14691 op1 = MASK_SPECIAL3(ctx->opcode);
14692 switch (op1) {
14693 case OPC_EXT:
14694 case OPC_INS:
d75c135e 14695 check_insn(ctx, ISA_MIPS32R2);
2b0233ab
TS
14696 gen_bitops(ctx, op1, rt, rs, sa, rd);
14697 break;
14698 case OPC_BSHFL:
d75c135e 14699 check_insn(ctx, ISA_MIPS32R2);
2b0233ab 14700 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14701 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14702 break;
1579a72e 14703 case OPC_RDHWR:
d75c135e 14704 gen_rdhwr(ctx, rt, rd);
1579a72e 14705 break;
ead9360e 14706 case OPC_FORK:
d75c135e 14707 check_insn(ctx, ASE_MT);
6c5c1e20 14708 {
35fbce2c
AJ
14709 TCGv t0 = tcg_temp_new();
14710 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14711
14712 gen_load_gpr(t0, rt);
14713 gen_load_gpr(t1, rs);
a7812ae4 14714 gen_helper_fork(t0, t1);
6c5c1e20
TS
14715 tcg_temp_free(t0);
14716 tcg_temp_free(t1);
14717 }
ead9360e
TS
14718 break;
14719 case OPC_YIELD:
d75c135e 14720 check_insn(ctx, ASE_MT);
6c5c1e20 14721 {
35fbce2c 14722 TCGv t0 = tcg_temp_new();
6c5c1e20 14723
35fbce2c 14724 save_cpu_state(ctx, 1);
6c5c1e20 14725 gen_load_gpr(t0, rs);
895c2d04 14726 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14727 gen_store_gpr(t0, rd);
14728 tcg_temp_free(t0);
14729 }
ead9360e 14730 break;
161f85e6 14731 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14732 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14733 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14734 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14735 * the same mask and op1. */
d75c135e 14736 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
461c08df
JL
14737 op2 = MASK_ADDUH_QB(ctx->opcode);
14738 switch (op2) {
14739 case OPC_ADDUH_QB:
14740 case OPC_ADDUH_R_QB:
14741 case OPC_ADDQH_PH:
14742 case OPC_ADDQH_R_PH:
14743 case OPC_ADDQH_W:
14744 case OPC_ADDQH_R_W:
14745 case OPC_SUBUH_QB:
14746 case OPC_SUBUH_R_QB:
14747 case OPC_SUBQH_PH:
14748 case OPC_SUBQH_R_PH:
14749 case OPC_SUBQH_W:
14750 case OPC_SUBQH_R_W:
14751 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14752 break;
a22260ae
JL
14753 case OPC_MUL_PH:
14754 case OPC_MUL_S_PH:
14755 case OPC_MULQ_S_W:
14756 case OPC_MULQ_RS_W:
14757 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14758 break;
461c08df
JL
14759 default:
14760 MIPS_INVAL("MASK ADDUH.QB");
14761 generate_exception(ctx, EXCP_RI);
14762 break;
14763 }
d75c135e 14764 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
461c08df
JL
14765 gen_loongson_integer(ctx, op1, rd, rs, rt);
14766 } else {
14767 generate_exception(ctx, EXCP_RI);
14768 }
161f85e6 14769 break;
9b1a1d68
JL
14770 case OPC_LX_DSP:
14771 op2 = MASK_LX(ctx->opcode);
14772 switch (op2) {
14773#if defined(TARGET_MIPS64)
14774 case OPC_LDX:
14775#endif
14776 case OPC_LBUX:
14777 case OPC_LHX:
14778 case OPC_LWX:
d75c135e 14779 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
9b1a1d68
JL
14780 break;
14781 default: /* Invalid */
14782 MIPS_INVAL("MASK LX");
14783 generate_exception(ctx, EXCP_RI);
14784 break;
14785 }
14786 break;
461c08df
JL
14787 case OPC_ABSQ_S_PH_DSP:
14788 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14789 switch (op2) {
14790 case OPC_ABSQ_S_QB:
14791 case OPC_ABSQ_S_PH:
14792 case OPC_ABSQ_S_W:
14793 case OPC_PRECEQ_W_PHL:
14794 case OPC_PRECEQ_W_PHR:
14795 case OPC_PRECEQU_PH_QBL:
14796 case OPC_PRECEQU_PH_QBR:
14797 case OPC_PRECEQU_PH_QBLA:
14798 case OPC_PRECEQU_PH_QBRA:
14799 case OPC_PRECEU_PH_QBL:
14800 case OPC_PRECEU_PH_QBR:
14801 case OPC_PRECEU_PH_QBLA:
14802 case OPC_PRECEU_PH_QBRA:
14803 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14804 break;
1cb6686c
JL
14805 case OPC_BITREV:
14806 case OPC_REPL_QB:
14807 case OPC_REPLV_QB:
14808 case OPC_REPL_PH:
14809 case OPC_REPLV_PH:
d75c135e 14810 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 14811 break;
461c08df
JL
14812 default:
14813 MIPS_INVAL("MASK ABSQ_S.PH");
14814 generate_exception(ctx, EXCP_RI);
14815 break;
14816 }
14817 break;
14818 case OPC_ADDU_QB_DSP:
14819 op2 = MASK_ADDU_QB(ctx->opcode);
14820 switch (op2) {
14821 case OPC_ADDQ_PH:
14822 case OPC_ADDQ_S_PH:
14823 case OPC_ADDQ_S_W:
14824 case OPC_ADDU_QB:
14825 case OPC_ADDU_S_QB:
14826 case OPC_ADDU_PH:
14827 case OPC_ADDU_S_PH:
14828 case OPC_SUBQ_PH:
14829 case OPC_SUBQ_S_PH:
14830 case OPC_SUBQ_S_W:
14831 case OPC_SUBU_QB:
14832 case OPC_SUBU_S_QB:
14833 case OPC_SUBU_PH:
14834 case OPC_SUBU_S_PH:
14835 case OPC_ADDSC:
14836 case OPC_ADDWC:
14837 case OPC_MODSUB:
14838 case OPC_RADDU_W_QB:
14839 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14840 break;
a22260ae
JL
14841 case OPC_MULEU_S_PH_QBL:
14842 case OPC_MULEU_S_PH_QBR:
14843 case OPC_MULQ_RS_PH:
14844 case OPC_MULEQ_S_W_PHL:
14845 case OPC_MULEQ_S_W_PHR:
14846 case OPC_MULQ_S_PH:
14847 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14848 break;
461c08df
JL
14849 default: /* Invalid */
14850 MIPS_INVAL("MASK ADDU.QB");
14851 generate_exception(ctx, EXCP_RI);
14852 break;
14853
14854 }
14855 break;
14856 case OPC_CMPU_EQ_QB_DSP:
14857 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14858 switch (op2) {
14859 case OPC_PRECR_SRA_PH_W:
14860 case OPC_PRECR_SRA_R_PH_W:
14861 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14862 break;
14863 case OPC_PRECR_QB_PH:
14864 case OPC_PRECRQ_QB_PH:
14865 case OPC_PRECRQ_PH_W:
14866 case OPC_PRECRQ_RS_PH_W:
14867 case OPC_PRECRQU_S_QB_PH:
14868 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14869 break;
26690560
JL
14870 case OPC_CMPU_EQ_QB:
14871 case OPC_CMPU_LT_QB:
14872 case OPC_CMPU_LE_QB:
14873 case OPC_CMP_EQ_PH:
14874 case OPC_CMP_LT_PH:
14875 case OPC_CMP_LE_PH:
14876 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14877 break;
14878 case OPC_CMPGU_EQ_QB:
14879 case OPC_CMPGU_LT_QB:
14880 case OPC_CMPGU_LE_QB:
14881 case OPC_CMPGDU_EQ_QB:
14882 case OPC_CMPGDU_LT_QB:
14883 case OPC_CMPGDU_LE_QB:
14884 case OPC_PICK_QB:
14885 case OPC_PICK_PH:
14886 case OPC_PACKRL_PH:
14887 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14888 break;
461c08df
JL
14889 default: /* Invalid */
14890 MIPS_INVAL("MASK CMPU.EQ.QB");
14891 generate_exception(ctx, EXCP_RI);
14892 break;
14893 }
14894 break;
77c5fa8b
JL
14895 case OPC_SHLL_QB_DSP:
14896 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14897 break;
a22260ae
JL
14898 case OPC_DPA_W_PH_DSP:
14899 op2 = MASK_DPA_W_PH(ctx->opcode);
14900 switch (op2) {
14901 case OPC_DPAU_H_QBL:
14902 case OPC_DPAU_H_QBR:
14903 case OPC_DPSU_H_QBL:
14904 case OPC_DPSU_H_QBR:
14905 case OPC_DPA_W_PH:
14906 case OPC_DPAX_W_PH:
14907 case OPC_DPAQ_S_W_PH:
14908 case OPC_DPAQX_S_W_PH:
14909 case OPC_DPAQX_SA_W_PH:
14910 case OPC_DPS_W_PH:
14911 case OPC_DPSX_W_PH:
14912 case OPC_DPSQ_S_W_PH:
14913 case OPC_DPSQX_S_W_PH:
14914 case OPC_DPSQX_SA_W_PH:
14915 case OPC_MULSAQ_S_W_PH:
14916 case OPC_DPAQ_SA_L_W:
14917 case OPC_DPSQ_SA_L_W:
14918 case OPC_MAQ_S_W_PHL:
14919 case OPC_MAQ_S_W_PHR:
14920 case OPC_MAQ_SA_W_PHL:
14921 case OPC_MAQ_SA_W_PHR:
14922 case OPC_MULSA_W_PH:
14923 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14924 break;
14925 default: /* Invalid */
14926 MIPS_INVAL("MASK DPAW.PH");
14927 generate_exception(ctx, EXCP_RI);
14928 break;
14929 }
14930 break;
1cb6686c
JL
14931 case OPC_INSV_DSP:
14932 op2 = MASK_INSV(ctx->opcode);
14933 switch (op2) {
14934 case OPC_INSV:
14935 check_dsp(ctx);
14936 {
14937 TCGv t0, t1;
14938
14939 if (rt == 0) {
14940 MIPS_DEBUG("NOP");
14941 break;
14942 }
14943
14944 t0 = tcg_temp_new();
14945 t1 = tcg_temp_new();
14946
14947 gen_load_gpr(t0, rt);
14948 gen_load_gpr(t1, rs);
14949
14950 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14951
14952 tcg_temp_free(t0);
14953 tcg_temp_free(t1);
14954 break;
14955 }
14956 default: /* Invalid */
14957 MIPS_INVAL("MASK INSV");
14958 generate_exception(ctx, EXCP_RI);
14959 break;
14960 }
14961 break;
26690560 14962 case OPC_APPEND_DSP:
df6126a7 14963 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 14964 break;
b53371ed
JL
14965 case OPC_EXTR_W_DSP:
14966 op2 = MASK_EXTR_W(ctx->opcode);
14967 switch (op2) {
14968 case OPC_EXTR_W:
14969 case OPC_EXTR_R_W:
14970 case OPC_EXTR_RS_W:
14971 case OPC_EXTR_S_H:
14972 case OPC_EXTRV_S_H:
14973 case OPC_EXTRV_W:
14974 case OPC_EXTRV_R_W:
14975 case OPC_EXTRV_RS_W:
14976 case OPC_EXTP:
14977 case OPC_EXTPV:
14978 case OPC_EXTPDP:
14979 case OPC_EXTPDPV:
14980 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14981 break;
14982 case OPC_RDDSP:
14983 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14984 break;
14985 case OPC_SHILO:
14986 case OPC_SHILOV:
14987 case OPC_MTHLIP:
14988 case OPC_WRDSP:
14989 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14990 break;
14991 default: /* Invalid */
14992 MIPS_INVAL("MASK EXTR.W");
14993 generate_exception(ctx, EXCP_RI);
14994 break;
14995 }
14996 break;
d26bc211 14997#if defined(TARGET_MIPS64)
1579a72e
TS
14998 case OPC_DEXTM ... OPC_DEXT:
14999 case OPC_DINSM ... OPC_DINS:
d75c135e 15000 check_insn(ctx, ISA_MIPS64R2);
e189e748 15001 check_mips_64(ctx);
1579a72e 15002 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 15003 break;
1579a72e 15004 case OPC_DBSHFL:
d75c135e 15005 check_insn(ctx, ISA_MIPS64R2);
e189e748 15006 check_mips_64(ctx);
1579a72e 15007 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 15008 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 15009 break;
161f85e6
AJ
15010 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15011 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15012 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
d75c135e 15013 check_insn(ctx, INSN_LOONGSON2E);
161f85e6
AJ
15014 gen_loongson_integer(ctx, op1, rd, rs, rt);
15015 break;
461c08df
JL
15016 case OPC_ABSQ_S_QH_DSP:
15017 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15018 switch (op2) {
15019 case OPC_PRECEQ_L_PWL:
15020 case OPC_PRECEQ_L_PWR:
15021 case OPC_PRECEQ_PW_QHL:
15022 case OPC_PRECEQ_PW_QHR:
15023 case OPC_PRECEQ_PW_QHLA:
15024 case OPC_PRECEQ_PW_QHRA:
15025 case OPC_PRECEQU_QH_OBL:
15026 case OPC_PRECEQU_QH_OBR:
15027 case OPC_PRECEQU_QH_OBLA:
15028 case OPC_PRECEQU_QH_OBRA:
15029 case OPC_PRECEU_QH_OBL:
15030 case OPC_PRECEU_QH_OBR:
15031 case OPC_PRECEU_QH_OBLA:
15032 case OPC_PRECEU_QH_OBRA:
15033 case OPC_ABSQ_S_OB:
15034 case OPC_ABSQ_S_PW:
15035 case OPC_ABSQ_S_QH:
15036 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15037 break;
1cb6686c
JL
15038 case OPC_REPL_OB:
15039 case OPC_REPL_PW:
15040 case OPC_REPL_QH:
15041 case OPC_REPLV_OB:
15042 case OPC_REPLV_PW:
15043 case OPC_REPLV_QH:
d75c135e 15044 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 15045 break;
461c08df
JL
15046 default: /* Invalid */
15047 MIPS_INVAL("MASK ABSQ_S.QH");
15048 generate_exception(ctx, EXCP_RI);
15049 break;
15050 }
15051 break;
15052 case OPC_ADDU_OB_DSP:
15053 op2 = MASK_ADDU_OB(ctx->opcode);
15054 switch (op2) {
15055 case OPC_RADDU_L_OB:
15056 case OPC_SUBQ_PW:
15057 case OPC_SUBQ_S_PW:
15058 case OPC_SUBQ_QH:
15059 case OPC_SUBQ_S_QH:
15060 case OPC_SUBU_OB:
15061 case OPC_SUBU_S_OB:
15062 case OPC_SUBU_QH:
15063 case OPC_SUBU_S_QH:
15064 case OPC_SUBUH_OB:
15065 case OPC_SUBUH_R_OB:
15066 case OPC_ADDQ_PW:
15067 case OPC_ADDQ_S_PW:
15068 case OPC_ADDQ_QH:
15069 case OPC_ADDQ_S_QH:
15070 case OPC_ADDU_OB:
15071 case OPC_ADDU_S_OB:
15072 case OPC_ADDU_QH:
15073 case OPC_ADDU_S_QH:
15074 case OPC_ADDUH_OB:
15075 case OPC_ADDUH_R_OB:
15076 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15077 break;
a22260ae
JL
15078 case OPC_MULEQ_S_PW_QHL:
15079 case OPC_MULEQ_S_PW_QHR:
15080 case OPC_MULEU_S_QH_OBL:
15081 case OPC_MULEU_S_QH_OBR:
15082 case OPC_MULQ_RS_QH:
15083 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15084 break;
461c08df
JL
15085 default: /* Invalid */
15086 MIPS_INVAL("MASK ADDU.OB");
15087 generate_exception(ctx, EXCP_RI);
15088 break;
15089 }
15090 break;
15091 case OPC_CMPU_EQ_OB_DSP:
15092 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15093 switch (op2) {
15094 case OPC_PRECR_SRA_QH_PW:
15095 case OPC_PRECR_SRA_R_QH_PW:
15096 /* Return value is rt. */
15097 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15098 break;
15099 case OPC_PRECR_OB_QH:
15100 case OPC_PRECRQ_OB_QH:
15101 case OPC_PRECRQ_PW_L:
15102 case OPC_PRECRQ_QH_PW:
15103 case OPC_PRECRQ_RS_QH_PW:
15104 case OPC_PRECRQU_S_OB_QH:
15105 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15106 break;
26690560
JL
15107 case OPC_CMPU_EQ_OB:
15108 case OPC_CMPU_LT_OB:
15109 case OPC_CMPU_LE_OB:
15110 case OPC_CMP_EQ_QH:
15111 case OPC_CMP_LT_QH:
15112 case OPC_CMP_LE_QH:
15113 case OPC_CMP_EQ_PW:
15114 case OPC_CMP_LT_PW:
15115 case OPC_CMP_LE_PW:
15116 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15117 break;
15118 case OPC_CMPGDU_EQ_OB:
15119 case OPC_CMPGDU_LT_OB:
15120 case OPC_CMPGDU_LE_OB:
15121 case OPC_CMPGU_EQ_OB:
15122 case OPC_CMPGU_LT_OB:
15123 case OPC_CMPGU_LE_OB:
15124 case OPC_PACKRL_PW:
15125 case OPC_PICK_OB:
15126 case OPC_PICK_PW:
15127 case OPC_PICK_QH:
15128 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15129 break;
461c08df
JL
15130 default: /* Invalid */
15131 MIPS_INVAL("MASK CMPU_EQ.OB");
15132 generate_exception(ctx, EXCP_RI);
15133 break;
15134 }
15135 break;
26690560 15136 case OPC_DAPPEND_DSP:
df6126a7 15137 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 15138 break;
b53371ed
JL
15139 case OPC_DEXTR_W_DSP:
15140 op2 = MASK_DEXTR_W(ctx->opcode);
15141 switch (op2) {
15142 case OPC_DEXTP:
15143 case OPC_DEXTPDP:
15144 case OPC_DEXTPDPV:
15145 case OPC_DEXTPV:
15146 case OPC_DEXTR_L:
15147 case OPC_DEXTR_R_L:
15148 case OPC_DEXTR_RS_L:
15149 case OPC_DEXTR_W:
15150 case OPC_DEXTR_R_W:
15151 case OPC_DEXTR_RS_W:
15152 case OPC_DEXTR_S_H:
15153 case OPC_DEXTRV_L:
15154 case OPC_DEXTRV_R_L:
15155 case OPC_DEXTRV_RS_L:
15156 case OPC_DEXTRV_S_H:
15157 case OPC_DEXTRV_W:
15158 case OPC_DEXTRV_R_W:
15159 case OPC_DEXTRV_RS_W:
15160 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15161 break;
15162 case OPC_DMTHLIP:
15163 case OPC_DSHILO:
15164 case OPC_DSHILOV:
15165 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15166 break;
15167 default: /* Invalid */
15168 MIPS_INVAL("MASK EXTR.W");
15169 generate_exception(ctx, EXCP_RI);
15170 break;
15171 }
15172 break;
a22260ae
JL
15173 case OPC_DPAQ_W_QH_DSP:
15174 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15175 switch (op2) {
15176 case OPC_DPAU_H_OBL:
15177 case OPC_DPAU_H_OBR:
15178 case OPC_DPSU_H_OBL:
15179 case OPC_DPSU_H_OBR:
15180 case OPC_DPA_W_QH:
15181 case OPC_DPAQ_S_W_QH:
15182 case OPC_DPS_W_QH:
15183 case OPC_DPSQ_S_W_QH:
15184 case OPC_MULSAQ_S_W_QH:
15185 case OPC_DPAQ_SA_L_PW:
15186 case OPC_DPSQ_SA_L_PW:
15187 case OPC_MULSAQ_S_L_PW:
15188 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15189 break;
15190 case OPC_MAQ_S_W_QHLL:
15191 case OPC_MAQ_S_W_QHLR:
15192 case OPC_MAQ_S_W_QHRL:
15193 case OPC_MAQ_S_W_QHRR:
15194 case OPC_MAQ_SA_W_QHLL:
15195 case OPC_MAQ_SA_W_QHLR:
15196 case OPC_MAQ_SA_W_QHRL:
15197 case OPC_MAQ_SA_W_QHRR:
15198 case OPC_MAQ_S_L_PWL:
15199 case OPC_MAQ_S_L_PWR:
15200 case OPC_DMADD:
15201 case OPC_DMADDU:
15202 case OPC_DMSUB:
15203 case OPC_DMSUBU:
15204 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15205 break;
15206 default: /* Invalid */
15207 MIPS_INVAL("MASK DPAQ.W.QH");
15208 generate_exception(ctx, EXCP_RI);
15209 break;
15210 }
15211 break;
1cb6686c
JL
15212 case OPC_DINSV_DSP:
15213 op2 = MASK_INSV(ctx->opcode);
15214 switch (op2) {
15215 case OPC_DINSV:
15216 {
15217 TCGv t0, t1;
15218
15219 if (rt == 0) {
15220 MIPS_DEBUG("NOP");
15221 break;
15222 }
15223 check_dsp(ctx);
15224
15225 t0 = tcg_temp_new();
15226 t1 = tcg_temp_new();
15227
15228 gen_load_gpr(t0, rt);
15229 gen_load_gpr(t1, rs);
15230
15231 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15232 break;
15233 }
15234 default: /* Invalid */
15235 MIPS_INVAL("MASK DINSV");
15236 generate_exception(ctx, EXCP_RI);
15237 break;
15238 }
15239 break;
77c5fa8b
JL
15240 case OPC_SHLL_OB_DSP:
15241 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15242 break;
7a387fff
TS
15243#endif
15244 default: /* Invalid */
15245 MIPS_INVAL("special3");
15246 generate_exception(ctx, EXCP_RI);
15247 break;
15248 }
15249 break;
15250 case OPC_REGIMM:
15251 op1 = MASK_REGIMM(ctx->opcode);
15252 switch (op1) {
15253 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15254 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15255 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061
NF
15256 *is_branch = 1;
15257 break;
7a387fff
TS
15258 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15259 case OPC_TNEI:
15260 gen_trap(ctx, op1, rs, -1, imm);
15261 break;
15262 case OPC_SYNCI:
d75c135e 15263 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15264 /* Treat as NOP. */
6af0bf9c 15265 break;
e45a93e2
JL
15266 case OPC_BPOSGE32: /* MIPS DSP branch */
15267#if defined(TARGET_MIPS64)
15268 case OPC_BPOSGE64:
15269#endif
15270 check_dsp(ctx);
15271 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15272 *is_branch = 1;
15273 break;
6af0bf9c 15274 default: /* Invalid */
923617a3 15275 MIPS_INVAL("regimm");
6af0bf9c
FB
15276 generate_exception(ctx, EXCP_RI);
15277 break;
15278 }
15279 break;
7a387fff 15280 case OPC_CP0:
387a8fe5 15281 check_cp0_enabled(ctx);
7a387fff 15282 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15283 switch (op1) {
7a387fff
TS
15284 case OPC_MFC0:
15285 case OPC_MTC0:
ead9360e
TS
15286 case OPC_MFTR:
15287 case OPC_MTTR:
d26bc211 15288#if defined(TARGET_MIPS64)
7a387fff
TS
15289 case OPC_DMFC0:
15290 case OPC_DMTC0:
15291#endif
f1aa6320 15292#ifndef CONFIG_USER_ONLY
932e71cd 15293 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15294#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15295 break;
15296 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15297#ifndef CONFIG_USER_ONLY
932e71cd 15298 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15299#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15300 break;
15301 case OPC_MFMC0:
8706c382 15302#ifndef CONFIG_USER_ONLY
932e71cd 15303 {
35fbce2c 15304 TCGv t0 = tcg_temp_new();
6c5c1e20 15305
0eaef5aa 15306 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15307 switch (op2) {
15308 case OPC_DMT:
d75c135e 15309 check_insn(ctx, ASE_MT);
9ed5726c 15310 gen_helper_dmt(t0);
35fbce2c 15311 gen_store_gpr(t0, rt);
6c5c1e20
TS
15312 break;
15313 case OPC_EMT:
d75c135e 15314 check_insn(ctx, ASE_MT);
9ed5726c 15315 gen_helper_emt(t0);
35fbce2c 15316 gen_store_gpr(t0, rt);
da80682b 15317 break;
6c5c1e20 15318 case OPC_DVPE:
d75c135e 15319 check_insn(ctx, ASE_MT);
895c2d04 15320 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15321 gen_store_gpr(t0, rt);
6c5c1e20
TS
15322 break;
15323 case OPC_EVPE:
d75c135e 15324 check_insn(ctx, ASE_MT);
895c2d04 15325 gen_helper_evpe(t0, cpu_env);
35fbce2c 15326 gen_store_gpr(t0, rt);
6c5c1e20
TS
15327 break;
15328 case OPC_DI:
d75c135e 15329 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15330 save_cpu_state(ctx, 1);
895c2d04 15331 gen_helper_di(t0, cpu_env);
35fbce2c 15332 gen_store_gpr(t0, rt);
6c5c1e20
TS
15333 /* Stop translation as we may have switched the execution mode */
15334 ctx->bstate = BS_STOP;
15335 break;
15336 case OPC_EI:
d75c135e 15337 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15338 save_cpu_state(ctx, 1);
895c2d04 15339 gen_helper_ei(t0, cpu_env);
35fbce2c 15340 gen_store_gpr(t0, rt);
6c5c1e20
TS
15341 /* Stop translation as we may have switched the execution mode */
15342 ctx->bstate = BS_STOP;
15343 break;
15344 default: /* Invalid */
15345 MIPS_INVAL("mfmc0");
15346 generate_exception(ctx, EXCP_RI);
15347 break;
15348 }
6c5c1e20 15349 tcg_temp_free(t0);
7a387fff 15350 }
0eaef5aa 15351#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15352 break;
7a387fff 15353 case OPC_RDPGPR:
d75c135e 15354 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15355 gen_load_srsgpr(rt, rd);
ead9360e 15356 break;
7a387fff 15357 case OPC_WRPGPR:
d75c135e 15358 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15359 gen_store_srsgpr(rt, rd);
38121543 15360 break;
6af0bf9c 15361 default:
923617a3 15362 MIPS_INVAL("cp0");
7a387fff 15363 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15364 break;
15365 }
15366 break;
324d9e32
AJ
15367 case OPC_ADDI: /* Arithmetic with immediate opcode */
15368 case OPC_ADDIU:
d75c135e 15369 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15370 break;
324d9e32
AJ
15371 case OPC_SLTI: /* Set on less than with immediate opcode */
15372 case OPC_SLTIU:
d75c135e 15373 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15374 break;
15375 case OPC_ANDI: /* Arithmetic with immediate opcode */
15376 case OPC_LUI:
15377 case OPC_ORI:
15378 case OPC_XORI:
d75c135e 15379 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15380 break;
7a387fff
TS
15381 case OPC_J ... OPC_JAL: /* Jump */
15382 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15383 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061
NF
15384 *is_branch = 1;
15385 break;
7a387fff
TS
15386 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15387 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15388 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061
NF
15389 *is_branch = 1;
15390 break;
7a387fff 15391 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15392 case OPC_LL:
d75c135e 15393 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15394 break;
7a387fff
TS
15395 case OPC_SB ... OPC_SW:
15396 case OPC_SWR:
5c13fdfd 15397 gen_st(ctx, op, rt, rs, imm);
7a387fff 15398 break;
d66c7132
AJ
15399 case OPC_SC:
15400 gen_st_cond(ctx, op, rt, rs, imm);
15401 break;
7a387fff 15402 case OPC_CACHE:
2e15497c 15403 check_cp0_enabled(ctx);
d75c135e 15404 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15405 /* Treat as NOP. */
34ae7b51 15406 break;
7a387fff 15407 case OPC_PREF:
d75c135e 15408 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15409 /* Treat as NOP. */
6af0bf9c 15410 break;
4ad40f36 15411
923617a3 15412 /* Floating point (COP1). */
7a387fff
TS
15413 case OPC_LWC1:
15414 case OPC_LDC1:
15415 case OPC_SWC1:
15416 case OPC_SDC1:
26ebe468 15417 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15418 break;
15419
7a387fff 15420 case OPC_CP1:
36d23958 15421 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15422 check_cp1_enabled(ctx);
36d23958
TS
15423 op1 = MASK_CP1(ctx->opcode);
15424 switch (op1) {
3a95e3a7
TS
15425 case OPC_MFHC1:
15426 case OPC_MTHC1:
d75c135e 15427 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
15428 case OPC_MFC1:
15429 case OPC_CFC1:
15430 case OPC_MTC1:
15431 case OPC_CTC1:
e189e748
TS
15432 gen_cp1(ctx, op1, rt, rd);
15433 break;
d26bc211 15434#if defined(TARGET_MIPS64)
36d23958
TS
15435 case OPC_DMFC1:
15436 case OPC_DMTC1:
d75c135e 15437 check_insn(ctx, ISA_MIPS3);
36d23958
TS
15438 gen_cp1(ctx, op1, rt, rd);
15439 break;
e189e748 15440#endif
fbcc6828
TS
15441 case OPC_BC1ANY2:
15442 case OPC_BC1ANY4:
b8aa4598 15443 check_cop1x(ctx);
d75c135e 15444 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
15445 /* fall through */
15446 case OPC_BC1:
d75c135e 15447 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15448 (rt >> 2) & 0x7, imm << 2);
c9602061
NF
15449 *is_branch = 1;
15450 break;
36d23958
TS
15451 case OPC_S_FMT:
15452 case OPC_D_FMT:
15453 case OPC_W_FMT:
15454 case OPC_L_FMT:
5a5012ec 15455 case OPC_PS_FMT:
bf4120ad 15456 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15457 (imm >> 8) & 0x7);
36d23958
TS
15458 break;
15459 default:
923617a3 15460 MIPS_INVAL("cp1");
e397ee33 15461 generate_exception (ctx, EXCP_RI);
36d23958
TS
15462 break;
15463 }
15464 } else {
15465 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15466 }
4ad40f36
FB
15467 break;
15468
15469 /* COP2. */
7a387fff
TS
15470 case OPC_LWC2:
15471 case OPC_LDC2:
15472 case OPC_SWC2:
15473 case OPC_SDC2:
7a387fff 15474 /* COP2: Not implemented. */
4ad40f36
FB
15475 generate_exception_err(ctx, EXCP_CpU, 2);
15476 break;
bd277fa1 15477 case OPC_CP2:
d75c135e 15478 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
15479 /* Note that these instructions use different fields. */
15480 gen_loongson_multimedia(ctx, sa, rd, rt);
15481 break;
4ad40f36 15482
7a387fff 15483 case OPC_CP3:
36d23958 15484 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15485 check_cp1_enabled(ctx);
36d23958
TS
15486 op1 = MASK_CP3(ctx->opcode);
15487 switch (op1) {
5a5012ec
TS
15488 case OPC_LWXC1:
15489 case OPC_LDXC1:
15490 case OPC_LUXC1:
15491 case OPC_SWXC1:
15492 case OPC_SDXC1:
15493 case OPC_SUXC1:
93b12ccc 15494 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15495 break;
e0c84da7 15496 case OPC_PREFX:
ead9360e 15497 /* Treat as NOP. */
e0c84da7 15498 break;
5a5012ec
TS
15499 case OPC_ALNV_PS:
15500 case OPC_MADD_S:
15501 case OPC_MADD_D:
15502 case OPC_MADD_PS:
15503 case OPC_MSUB_S:
15504 case OPC_MSUB_D:
15505 case OPC_MSUB_PS:
15506 case OPC_NMADD_S:
15507 case OPC_NMADD_D:
15508 case OPC_NMADD_PS:
15509 case OPC_NMSUB_S:
15510 case OPC_NMSUB_D:
15511 case OPC_NMSUB_PS:
15512 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15513 break;
36d23958 15514 default:
923617a3 15515 MIPS_INVAL("cp3");
e397ee33 15516 generate_exception (ctx, EXCP_RI);
36d23958
TS
15517 break;
15518 }
15519 } else {
e397ee33 15520 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15521 }
4ad40f36
FB
15522 break;
15523
d26bc211 15524#if defined(TARGET_MIPS64)
7a387fff
TS
15525 /* MIPS64 opcodes */
15526 case OPC_LWU:
15527 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15528 case OPC_LLD:
15529 case OPC_LD:
d75c135e 15530 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15531 check_mips_64(ctx);
d75c135e 15532 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
15533 break;
15534 case OPC_SDL ... OPC_SDR:
7a387fff 15535 case OPC_SD:
d75c135e 15536 check_insn(ctx, ISA_MIPS3);
e189e748 15537 check_mips_64(ctx);
5c13fdfd 15538 gen_st(ctx, op, rt, rs, imm);
7a387fff 15539 break;
d66c7132 15540 case OPC_SCD:
d75c135e 15541 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
15542 check_mips_64(ctx);
15543 gen_st_cond(ctx, op, rt, rs, imm);
15544 break;
324d9e32
AJ
15545 case OPC_DADDI:
15546 case OPC_DADDIU:
d75c135e 15547 check_insn(ctx, ISA_MIPS3);
e189e748 15548 check_mips_64(ctx);
d75c135e 15549 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15550 break;
6af0bf9c 15551#endif
7a387fff 15552 case OPC_JALX:
d75c135e 15553 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15554 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15555 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15556 *is_branch = 1;
15557 break;
7a387fff 15558 case OPC_MDMX:
d75c135e 15559 check_insn(ctx, ASE_MDMX);
7a387fff 15560 /* MDMX: Not implemented. */
6af0bf9c 15561 default: /* Invalid */
923617a3 15562 MIPS_INVAL("major opcode");
6af0bf9c
FB
15563 generate_exception(ctx, EXCP_RI);
15564 break;
15565 }
6af0bf9c
FB
15566}
15567
2cfc5f17 15568static inline void
7db13fae 15569gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
820e00f2 15570 int search_pc)
6af0bf9c 15571{
278d0702 15572 DisasContext ctx;
6af0bf9c
FB
15573 target_ulong pc_start;
15574 uint16_t *gen_opc_end;
a1d1bb31 15575 CPUBreakpoint *bp;
6af0bf9c 15576 int j, lj = -1;
2e70f6ef
PB
15577 int num_insns;
15578 int max_insns;
c9602061
NF
15579 int insn_bytes;
15580 int is_branch;
6af0bf9c 15581
93fcfe39
AL
15582 if (search_pc)
15583 qemu_log("search pc %d\n", search_pc);
4ad40f36 15584
6af0bf9c 15585 pc_start = tb->pc;
92414b31 15586 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15587 ctx.pc = pc_start;
4ad40f36 15588 ctx.saved_pc = -1;
7b270ef2 15589 ctx.singlestep_enabled = env->singlestep_enabled;
d75c135e 15590 ctx.insn_flags = env->insn_flags;
6af0bf9c
FB
15591 ctx.tb = tb;
15592 ctx.bstate = BS_NONE;
4ad40f36 15593 /* Restore delay slot state from the tb context. */
c068688b 15594 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
fd4a04eb 15595 restore_cpu_state(env, &ctx);
932e71cd 15596#ifdef CONFIG_USER_ONLY
0eaef5aa 15597 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15598#else
0eaef5aa 15599 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15600#endif
2e70f6ef
PB
15601 num_insns = 0;
15602 max_insns = tb->cflags & CF_COUNT_MASK;
15603 if (max_insns == 0)
15604 max_insns = CF_COUNT_MASK;
d12d51d5 15605 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
2e70f6ef 15606 gen_icount_start();
faf7aaa9 15607 while (ctx.bstate == BS_NONE) {
72cf2d4f
BS
15608 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15609 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 15610 if (bp->pc == ctx.pc) {
278d0702 15611 save_cpu_state(&ctx, 1);
4ad40f36 15612 ctx.bstate = BS_BRANCH;
895c2d04 15613 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15614 /* Include the breakpoint location or the tb won't
15615 * be flushed when it must be. */
15616 ctx.pc += 4;
4ad40f36
FB
15617 goto done_generating;
15618 }
15619 }
15620 }
15621
6af0bf9c 15622 if (search_pc) {
92414b31 15623 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15624 if (lj < j) {
15625 lj++;
15626 while (lj < j)
ab1103de 15627 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 15628 }
25983cad 15629 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 15630 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15631 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 15632 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 15633 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 15634 }
2e70f6ef
PB
15635 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15636 gen_io_start();
c9602061
NF
15637
15638 is_branch = 0;
364d4831 15639 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15640 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061
NF
15641 insn_bytes = 4;
15642 decode_opc(env, &ctx, &is_branch);
d75c135e 15643 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 15644 ctx.opcode = cpu_lduw_code(env, ctx.pc);
3c824109 15645 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
d75c135e 15646 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 15647 ctx.opcode = cpu_lduw_code(env, ctx.pc);
364d4831 15648 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
c9602061
NF
15649 } else {
15650 generate_exception(&ctx, EXCP_RI);
3c824109 15651 ctx.bstate = BS_STOP;
c9602061
NF
15652 break;
15653 }
15654 if (!is_branch) {
d75c135e 15655 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
15656 }
15657 ctx.pc += insn_bytes;
15658
2e70f6ef 15659 num_insns++;
4ad40f36 15660
7b270ef2
NF
15661 /* Execute a branch and its delay slot as a single instruction.
15662 This is what GDB expects and is consistent with what the
15663 hardware does (e.g. if a delay slot instruction faults, the
15664 reported PC is the PC of the branch). */
15665 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
4ad40f36
FB
15666 break;
15667
6af0bf9c
FB
15668 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15669 break;
4ad40f36 15670
efd7f486 15671 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 15672 break;
efd7f486 15673 }
faf7aaa9 15674
2e70f6ef
PB
15675 if (num_insns >= max_insns)
15676 break;
1b530a6d
AJ
15677
15678 if (singlestep)
15679 break;
6af0bf9c 15680 }
2e70f6ef
PB
15681 if (tb->cflags & CF_LAST_IO)
15682 gen_io_end();
7b270ef2 15683 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15684 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15685 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15686 } else {
6958549d 15687 switch (ctx.bstate) {
16c00cb2 15688 case BS_STOP:
df1561e2
TS
15689 gen_goto_tb(&ctx, 0, ctx.pc);
15690 break;
16c00cb2 15691 case BS_NONE:
278d0702 15692 save_cpu_state(&ctx, 0);
16c00cb2
TS
15693 gen_goto_tb(&ctx, 0, ctx.pc);
15694 break;
5a5012ec 15695 case BS_EXCP:
57fec1fe 15696 tcg_gen_exit_tb(0);
16c00cb2 15697 break;
5a5012ec
TS
15698 case BS_BRANCH:
15699 default:
15700 break;
6958549d 15701 }
6af0bf9c 15702 }
4ad40f36 15703done_generating:
2e70f6ef 15704 gen_icount_end(tb, num_insns);
efd7f486 15705 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 15706 if (search_pc) {
92414b31 15707 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15708 lj++;
15709 while (lj <= j)
ab1103de 15710 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15711 } else {
15712 tb->size = ctx.pc - pc_start;
2e70f6ef 15713 tb->icount = num_insns;
6af0bf9c
FB
15714 }
15715#ifdef DEBUG_DISAS
d12d51d5 15716 LOG_DISAS("\n");
8fec2b8c 15717 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 15718 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 15719 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 15720 qemu_log("\n");
6af0bf9c
FB
15721 }
15722#endif
6af0bf9c
FB
15723}
15724
7db13fae 15725void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15726{
2cfc5f17 15727 gen_intermediate_code_internal(env, tb, 0);
6af0bf9c
FB
15728}
15729
7db13fae 15730void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15731{
2cfc5f17 15732 gen_intermediate_code_internal(env, tb, 1);
6af0bf9c
FB
15733}
15734
7db13fae 15735static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15736 int flags)
6ea83fed
FB
15737{
15738 int i;
5e755519 15739 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15740
2a5612e6
SW
15741#define printfpr(fp) \
15742 do { \
15743 if (is_fpu64) \
15744 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15745 " fd:%13g fs:%13g psu: %13g\n", \
15746 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15747 (double)(fp)->fd, \
15748 (double)(fp)->fs[FP_ENDIAN_IDX], \
15749 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15750 else { \
15751 fpr_t tmp; \
15752 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15753 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15754 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15755 " fd:%13g fs:%13g psu:%13g\n", \
15756 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15757 (double)tmp.fd, \
15758 (double)tmp.fs[FP_ENDIAN_IDX], \
15759 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15760 } \
6ea83fed
FB
15761 } while(0)
15762
5a5012ec 15763
9a78eead
SW
15764 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15765 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15766 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15767 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15768 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15769 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15770 }
15771
15772#undef printfpr
15773}
15774
d26bc211 15775#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15776/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15777 sign-extended values on 64bit machines. */
c570fd16
TS
15778
15779#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15780
8706c382 15781static void
7db13fae 15782cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15783 fprintf_function cpu_fprintf,
8706c382 15784 int flags)
c570fd16
TS
15785{
15786 int i;
15787
b5dc7732
TS
15788 if (!SIGN_EXT_P(env->active_tc.PC))
15789 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15790 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15791 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15792 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15793 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15794 if (!SIGN_EXT_P(env->btarget))
3594c774 15795 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15796
15797 for (i = 0; i < 32; i++) {
b5dc7732
TS
15798 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15799 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15800 }
15801
15802 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15803 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15804 if (!SIGN_EXT_P(env->lladdr))
15805 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15806}
15807#endif
15808
7db13fae 15809void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
6af0bf9c
FB
15810 int flags)
15811{
15812 int i;
3b46e624 15813
a7200c9f
SW
15814 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15815 " LO=0x" TARGET_FMT_lx " ds %04x "
15816 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15817 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15818 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15819 for (i = 0; i < 32; i++) {
15820 if ((i & 3) == 0)
15821 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15822 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15823 if ((i & 3) == 3)
15824 cpu_fprintf(f, "\n");
15825 }
568b600d 15826
3594c774 15827 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15828 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15829 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15830 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15831 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15832 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15833#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15834 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15835#endif
6af0bf9c
FB
15836}
15837
39454628
TS
15838static void mips_tcg_init(void)
15839{
f01be154 15840 int i;
39454628
TS
15841 static int inited;
15842
15843 /* Initialize various static tables. */
15844 if (inited)
6958549d 15845 return;
39454628 15846
a7812ae4 15847 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15848 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15849 for (i = 1; i < 32; i++)
a7812ae4 15850 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15851 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15852 regnames[i]);
d73ee8a2
RH
15853
15854 for (i = 0; i < 32; i++) {
15855 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15856 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15857 }
15858
a7812ae4 15859 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15860 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15861 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15862 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15863 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15864 regnames_HI[i]);
a7812ae4 15865 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15866 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15867 regnames_LO[i]);
a7812ae4 15868 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15869 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15870 regnames_ACX[i]);
15871 }
a7812ae4 15872 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15873 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15874 "DSPControl");
1ba74fb8 15875 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15876 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15877 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15878 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15879 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15880 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15881
a7812ae4 15882 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15883 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15884 "fcr0");
15885 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15886 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15887 "fcr31");
39454628 15888
7dd9e556 15889 /* register helpers */
a7812ae4 15890#define GEN_HELPER 2
7dd9e556
TS
15891#include "helper.h"
15892
39454628
TS
15893 inited = 1;
15894}
15895
aaed909a
FB
15896#include "translate_init.c"
15897
30bf942d 15898MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15899{
0f71a709 15900 MIPSCPU *cpu;
6af0bf9c 15901 CPUMIPSState *env;
c227f099 15902 const mips_def_t *def;
6af0bf9c 15903
aaed909a
FB
15904 def = cpu_mips_find_by_name(cpu_model);
15905 if (!def)
15906 return NULL;
0f71a709
AF
15907 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15908 env = &cpu->env;
aaed909a 15909 env->cpu_model = def;
51cc2e78 15910 env->cpu_model_str = cpu_model;
aaed909a 15911
51cc2e78
BS
15912#ifndef CONFIG_USER_ONLY
15913 mmu_init(env, def);
15914#endif
15915 fpu_init(env, def);
15916 mvp_init(env, def);
39454628 15917 mips_tcg_init();
3bd4122e 15918 cpu_reset(CPU(cpu));
0bf46a40 15919 qemu_init_vcpu(env);
30bf942d 15920 return cpu;
6ae81775
TS
15921}
15922
1bba0dc9 15923void cpu_state_reset(CPUMIPSState *env)
6ae81775 15924{
55e5c285
AF
15925#ifndef CONFIG_USER_ONLY
15926 MIPSCPU *cpu = mips_env_get_cpu(env);
15927 CPUState *cs = CPU(cpu);
15928#endif
6ae81775 15929
51cc2e78
BS
15930 /* Reset registers to their default values */
15931 env->CP0_PRid = env->cpu_model->CP0_PRid;
15932 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15933#ifdef TARGET_WORDS_BIGENDIAN
15934 env->CP0_Config0 |= (1 << CP0C0_BE);
15935#endif
15936 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15937 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15938 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15939 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15940 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
15941 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15942 << env->cpu_model->CP0_LLAddr_shift;
15943 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
15944 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15945 env->CCRes = env->cpu_model->CCRes;
15946 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15947 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15948 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15949 env->current_tc = 0;
15950 env->SEGBITS = env->cpu_model->SEGBITS;
15951 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15952#if defined(TARGET_MIPS64)
15953 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15954 env->SEGMask |= 3ULL << 62;
15955 }
15956#endif
15957 env->PABITS = env->cpu_model->PABITS;
15958 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15959 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15960 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15961 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15962 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15963 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15964 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15965 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15966 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15967 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15968 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 15969 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
15970 env->insn_flags = env->cpu_model->insn_flags;
15971
0eaef5aa 15972#if defined(CONFIG_USER_ONLY)
03e6e501 15973 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
94159135
MI
15974 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15975 hardware registers. */
15976 env->CP0_HWREna |= 0x0000000F;
91a75935 15977 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 15978 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 15979 }
853c3240
JL
15980 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15981 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15982 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15983 env->hflags |= MIPS_HFLAG_DSP;
15984 }
932e71cd
AJ
15985#else
15986 if (env->hflags & MIPS_HFLAG_BMASK) {
15987 /* If the exception was raised from a delay slot,
15988 come back to the jump. */
15989 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 15990 } else {
932e71cd
AJ
15991 env->CP0_ErrorEPC = env->active_tc.PC;
15992 }
15993 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
15994 env->CP0_Random = env->tlb->nb_tlb - 1;
15995 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 15996 env->CP0_Wired = 0;
55e5c285 15997 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
932e71cd
AJ
15998 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15999 /* vectored interrupts not implemented, timer on int 7,
16000 no performance counters. */
16001 env->CP0_IntCtl = 0xe0000000;
16002 {
16003 int i;
16004
16005 for (i = 0; i < 7; i++) {
16006 env->CP0_WatchLo[i] = 0;
16007 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 16008 }
932e71cd
AJ
16009 env->CP0_WatchLo[7] = 0;
16010 env->CP0_WatchHi[7] = 0;
fd88b6ab 16011 }
932e71cd
AJ
16012 /* Count register increments in debug mode, EJTAG version 1 */
16013 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756
EI
16014
16015 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16016 int i;
16017
16018 /* Only TC0 on VPE 0 starts as active. */
16019 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 16020 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
16021 env->tcs[i].CP0_TCHalt = 1;
16022 }
16023 env->active_tc.CP0_TCHalt = 1;
16024 env->halted = 1;
16025
55e5c285 16026 if (cs->cpu_index == 0) {
9e56e756
EI
16027 /* VPE0 starts up enabled. */
16028 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16029 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16030
16031 /* TC0 starts up unhalted. */
16032 env->halted = 0;
16033 env->active_tc.CP0_TCHalt = 0;
16034 env->tcs[0].CP0_TCHalt = 0;
16035 /* With thread 0 active. */
16036 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16037 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16038 }
16039 }
51cc2e78 16040#endif
03e6e501 16041 compute_hflags(env);
6af0bf9c 16042 env->exception_index = EXCP_NONE;
6af0bf9c 16043}
d2856f1a 16044
7db13fae 16045void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16046{
25983cad 16047 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16048 env->hflags &= ~MIPS_HFLAG_BMASK;
16049 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16050 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16051 case MIPS_HFLAG_BR:
16052 break;
16053 case MIPS_HFLAG_BC:
16054 case MIPS_HFLAG_BL:
16055 case MIPS_HFLAG_B:
16056 env->btarget = gen_opc_btarget[pc_pos];
16057 break;
16058 }
d2856f1a 16059}