]> git.proxmox.com Git - qemu.git/blame - target-mips/translate.c
introduce new vma archive format
[qemu.git] / target-mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
6af0bf9c 24#include "cpu.h"
76cad711 25#include "disas/disas.h"
57fec1fe 26#include "tcg-op.h"
6af0bf9c 27
a7812ae4
PB
28#include "helper.h"
29#define GEN_HELPER 1
30#include "helper.h"
31
fb7729e2 32#define MIPS_DEBUG_DISAS 0
c570fd16 33//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c 34
7a387fff
TS
35/* MIPS major opcodes */
36#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
37
38enum {
39 /* indirect opcode tables */
7a387fff
TS
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 48 /* arithmetic with immediate */
7a387fff
TS
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
324d9e32 53 /* logic with immediate */
7a387fff
TS
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
324d9e32 58 /* arithmetic with immediate */
7a387fff
TS
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
e37e863f 61 /* Jump and branches */
7a387fff
TS
62 OPC_J = (0x02 << 26),
63 OPC_JAL = (0x03 << 26),
620e48f6 64 OPC_JALS = OPC_JAL | 0x5,
7a387fff
TS
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
620e48f6 74 OPC_JALXS = OPC_JALX | 0x5,
e37e863f 75 /* Load and stores */
7a387fff
TS
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
364d4831 82 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
364d4831 97 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
e37e863f 101 /* Floating point load/store */
7a387fff
TS
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
e37e863f 112 /* Cache and prefetch */
7a387fff
TS
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
e37e863f
FB
117};
118
119/* MIPS special opcodes */
7a387fff
TS
120#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
121
e37e863f
FB
122enum {
123 /* Shifts */
7a387fff 124 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 129 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 133 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 141 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 147 /* Multiplication / division */
7a387fff
TS
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
e37e863f 156 /* 2 registers arithmetic / logic */
7a387fff
TS
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 171 /* Jumps */
7a387fff
TS
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
364d4831 174 OPC_JALRC = OPC_JALR | (0x5 << 6),
620e48f6 175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
e37e863f 176 /* Traps */
7a387fff
TS
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 183 /* HI / LO registers load & stores */
7a387fff
TS
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 188 /* Conditional moves */
7a387fff
TS
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 191
7a387fff 192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
193
194 /* Special */
a0d700e4 195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
200
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
208};
209
e9c71dd1
TS
210/* Multiplication variants of the vr54xx. */
211#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
212
213enum {
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
228};
229
7a387fff
TS
230/* REGIMM (rt field) opcodes */
231#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
232
233enum {
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
3c824109 239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
7a387fff
TS
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
3c824109 242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
7a387fff
TS
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
e37e863f
FB
251};
252
7a387fff
TS
253/* Special2 opcodes */
254#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
255
e37e863f 256enum {
7a387fff
TS
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
263 /* Loongson 2F */
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 276 /* Misc */
7a387fff
TS
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 281 /* Special */
7a387fff
TS
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
283};
284
285/* Special3 opcodes */
286#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
287
288enum {
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
302
303 /* Loongson 2E */
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
316
317 /* MIPS DSP Load */
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 339 /* MIPS DSP Append Sub-class */
26690560 340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
e37e863f
FB
345};
346
7a387fff
TS
347/* BSHFL opcodes */
348#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
349
e37e863f 350enum {
7a387fff
TS
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
e37e863f
FB
354};
355
7a387fff
TS
356/* DBSHFL opcodes */
357#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
358
e37e863f 359enum {
7a387fff
TS
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
e37e863f
FB
362};
363
e45a93e2
JL
364/* MIPS DSP REGIMM opcodes */
365enum {
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
368};
369
9b1a1d68
JL
370#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
371/* MIPS DSP Load */
372enum {
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
377};
378
461c08df
JL
379#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
380enum {
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
407};
408
409#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
411enum {
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
430};
431
432#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
433enum {
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
454};
455
456#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457enum {
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 482};
a22260ae 483
77c5fa8b
JL
484#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485enum {
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
509};
461c08df 510
a22260ae
JL
511#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
512enum {
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
536};
537
1cb6686c
JL
538#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539enum {
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
542};
543
26690560
JL
544#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545enum {
df6126a7 546 /* MIPS DSP Append Sub-class */
26690560
JL
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
550};
551
b53371ed
JL
552#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553enum {
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
572};
573
461c08df
JL
574#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 601};
461c08df 602
461c08df
JL
603#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604enum {
a22260ae
JL
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
633};
461c08df 634
461c08df
JL
635#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636enum {
26690560
JL
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
666};
461c08df 667
26690560
JL
668#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669enum {
df6126a7 670 /* DSP Append Sub-class */
26690560
JL
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
675};
26690560 676
b53371ed
JL
677#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678enum {
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
701};
702
1cb6686c
JL
703#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704enum {
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
707};
1cb6686c 708
a22260ae
JL
709#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710enum {
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
738};
a22260ae 739
77c5fa8b
JL
740#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741enum {
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
769};
77c5fa8b 770
7a387fff
TS
771/* Coprocessor 0 (rs field) */
772#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
773
6ea83fed 774enum {
7a387fff
TS
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 787};
7a387fff
TS
788
789/* MFMC0 opcodes */
b48cfdff 790#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
791
792enum {
ead9360e
TS
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
799};
800
801/* Coprocessor 0 (with rs == C0) */
802#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
803
804enum {
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
813};
814
815/* Coprocessor 1 (rs field) */
816#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
817
bf4120ad
NF
818/* Values for the fmt field in FP instructions */
819enum {
820 /* 0 - 15 are reserved */
e459440a
AJ
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
828 /* 23 - 31 are reserved */
829};
830
7a387fff
TS
831enum {
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
e459440a
AJ
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
7a387fff
TS
850};
851
5a5012ec
TS
852#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
854
7a387fff
TS
855enum {
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
860};
861
5a5012ec
TS
862enum {
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
865};
866
867enum {
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
870};
7a387fff
TS
871
872#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
873
874enum {
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
884};
885
bd277fa1
RH
886#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
887
888enum {
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
897
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
906
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
915
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
924
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
931
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
938
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
945
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
952
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
959
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
966
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
973
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
980};
981
982
e0c84da7
TS
983#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
984
985enum {
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1001 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1006};
1007
39454628 1008/* global register indices */
a7812ae4
PB
1009static TCGv_ptr cpu_env;
1010static TCGv cpu_gpr[32], cpu_PC;
4b2eb8d2 1011static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
41db4607
AJ
1012static TCGv cpu_dspctrl, btarget, bcond;
1013static TCGv_i32 hflags;
a7812ae4 1014static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1015static TCGv_i64 fpu_f64[32];
aa0bf00b 1016
1a7ff922 1017static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1018static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1019
022c62cb 1020#include "exec/gen-icount.h"
2e70f6ef 1021
895c2d04 1022#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1024 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1025 tcg_temp_free_i32(helper_tmp); \
1026 } while(0)
be24bb4f 1027
895c2d04 1028#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1031 tcg_temp_free_i32(helper_tmp); \
1032 } while(0)
be24bb4f 1033
895c2d04
BS
1034#define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1038 } while(0)
1039
1040#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1044 } while(0)
1045
1046#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1050 } while(0)
1051
1052#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1055 tcg_temp_free_i32(helper_tmp); \
1056 } while(0)
be24bb4f 1057
895c2d04 1058#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1061 tcg_temp_free_i32(helper_tmp); \
1062 } while(0)
c239529e 1063
8e9ade68
TS
1064typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1067 uint32_t opcode;
7b270ef2 1068 int singlestep_enabled;
d75c135e 1069 int insn_flags;
8e9ade68
TS
1070 /* Routine used to access memory */
1071 int mem_idx;
1072 uint32_t hflags, saved_hflags;
1073 int bstate;
1074 target_ulong btarget;
1075} DisasContext;
1076
1077enum {
1078 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1079 * exception condition */
8e9ade68
TS
1080 BS_STOP = 1, /* We want to stop translation for any reason */
1081 BS_BRANCH = 2, /* We reached a branch condition */
1082 BS_EXCP = 3, /* We reached an exception condition */
1083};
1084
d73ee8a2
RH
1085static const char * const regnames[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1090};
6af0bf9c 1091
d73ee8a2
RH
1092static const char * const regnames_HI[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1094};
4b2eb8d2 1095
d73ee8a2
RH
1096static const char * const regnames_LO[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1098};
4b2eb8d2 1099
d73ee8a2
RH
1100static const char * const regnames_ACX[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1102};
4b2eb8d2 1103
d73ee8a2
RH
1104static const char * const fregnames[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1109};
958fb4a9 1110
fb7729e2
RH
1111#define MIPS_DEBUG(fmt, ...) \
1112 do { \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1117 } \
1118 } while (0)
1119
1120#define LOG_DISAS(...) \
1121 do { \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1124 } \
1125 } while (0)
958fb4a9 1126
8e9ade68 1127#define MIPS_INVAL(op) \
8e9ade68 1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1130
8e9ade68
TS
1131/* General purpose registers moves. */
1132static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1133{
8e9ade68
TS
1134 if (reg == 0)
1135 tcg_gen_movi_tl(t, 0);
1136 else
4b2eb8d2 1137 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1138}
1139
8e9ade68 1140static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1141{
8e9ade68 1142 if (reg != 0)
4b2eb8d2 1143 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1144}
1145
b10fa3c9 1146/* Moves to/from ACX register. */
4b2eb8d2 1147static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1148{
4b2eb8d2 1149 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1150}
1151
4b2eb8d2 1152static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1153{
4b2eb8d2 1154 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1155}
1156
8e9ade68 1157/* Moves to/from shadow registers. */
be24bb4f 1158static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1159{
d9bea114 1160 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1161
1162 if (from == 0)
d9bea114 1163 tcg_gen_movi_tl(t0, 0);
8e9ade68 1164 else {
d9bea114 1165 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1166 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1167
7db13fae 1168 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1169 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1170 tcg_gen_andi_i32(t2, t2, 0xf);
1171 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1172 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1173 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1174
d9bea114 1175 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1176 tcg_temp_free_ptr(addr);
d9bea114 1177 tcg_temp_free_i32(t2);
8e9ade68 1178 }
d9bea114
AJ
1179 gen_store_gpr(t0, to);
1180 tcg_temp_free(t0);
aaa9128a
TS
1181}
1182
be24bb4f 1183static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1184{
be24bb4f 1185 if (to != 0) {
d9bea114
AJ
1186 TCGv t0 = tcg_temp_new();
1187 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1188 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1189
d9bea114 1190 gen_load_gpr(t0, from);
7db13fae 1191 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1192 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1193 tcg_gen_andi_i32(t2, t2, 0xf);
1194 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1195 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1196 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1197
d9bea114 1198 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1199 tcg_temp_free_ptr(addr);
d9bea114
AJ
1200 tcg_temp_free_i32(t2);
1201 tcg_temp_free(t0);
8e9ade68 1202 }
aaa9128a
TS
1203}
1204
aaa9128a 1205/* Floating point register moves. */
d73ee8a2 1206static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1207{
d73ee8a2 1208 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1209}
1210
d73ee8a2 1211static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1212{
d73ee8a2
RH
1213 TCGv_i64 t64 = tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64, t);
1215 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1216 tcg_temp_free_i64(t64);
6d066274
AJ
1217}
1218
d73ee8a2 1219static void gen_load_fpr32h(TCGv_i32 t, int reg)
6d066274 1220{
d73ee8a2
RH
1221 TCGv_i64 t64 = tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1223 tcg_gen_trunc_i64_i32(t, t64);
1224 tcg_temp_free_i64(t64);
6d066274
AJ
1225}
1226
d73ee8a2 1227static void gen_store_fpr32h(TCGv_i32 t, int reg)
6d066274 1228{
d73ee8a2
RH
1229 TCGv_i64 t64 = tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64, t);
1231 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1232 tcg_temp_free_i64(t64);
aa0bf00b 1233}
6ea83fed 1234
d73ee8a2 1235static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1236{
f364515c 1237 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1238 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1239 } else {
d73ee8a2 1240 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1241 }
1242}
6ea83fed 1243
d73ee8a2 1244static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1245{
f364515c 1246 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1247 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1248 } else {
d73ee8a2
RH
1249 TCGv_i64 t0;
1250 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1251 t0 = tcg_temp_new_i64();
6d066274 1252 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1253 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1254 tcg_temp_free_i64(t0);
aa0bf00b
TS
1255 }
1256}
6ea83fed 1257
d94536f4 1258static inline int get_fp_bit (int cc)
a16336e4 1259{
d94536f4
AJ
1260 if (cc)
1261 return 24 + cc;
1262 else
1263 return 23;
a16336e4
TS
1264}
1265
30898801 1266/* Tests */
8e9ade68
TS
1267static inline void gen_save_pc(target_ulong pc)
1268{
1eb75d4a 1269 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1270}
30898801 1271
356265ae 1272static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1273{
d12d51d5 1274 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1275 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1276 gen_save_pc(ctx->pc);
6af0bf9c
FB
1277 ctx->saved_pc = ctx->pc;
1278 }
1279 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1280 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1281 ctx->saved_hflags = ctx->hflags;
364d4831 1282 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1283 case MIPS_HFLAG_BR:
5a5012ec
TS
1284 break;
1285 case MIPS_HFLAG_BC:
5a5012ec 1286 case MIPS_HFLAG_BL:
5a5012ec 1287 case MIPS_HFLAG_B:
d077b6f7 1288 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1289 break;
6af0bf9c
FB
1290 }
1291 }
1292}
1293
7db13fae 1294static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1295{
fd4a04eb 1296 ctx->saved_hflags = ctx->hflags;
364d4831 1297 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1298 case MIPS_HFLAG_BR:
fd4a04eb
TS
1299 break;
1300 case MIPS_HFLAG_BC:
1301 case MIPS_HFLAG_BL:
39454628 1302 case MIPS_HFLAG_B:
fd4a04eb 1303 ctx->btarget = env->btarget;
fd4a04eb 1304 break;
5a5012ec
TS
1305 }
1306}
1307
356265ae 1308static inline void
48d38ca5 1309generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1310{
a7812ae4
PB
1311 TCGv_i32 texcp = tcg_const_i32(excp);
1312 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1313 save_cpu_state(ctx, 1);
895c2d04 1314 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1315 tcg_temp_free_i32(terr);
1316 tcg_temp_free_i32(texcp);
aaa9128a
TS
1317}
1318
356265ae 1319static inline void
48d38ca5 1320generate_exception (DisasContext *ctx, int excp)
aaa9128a 1321{
6af0bf9c 1322 save_cpu_state(ctx, 1);
895c2d04 1323 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1324}
1325
48d38ca5 1326/* Addresses computation */
941694d0 1327static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1328{
941694d0 1329 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1330
1331#if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1335 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1336 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1337 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1338 }
1339#endif
4ad40f36
FB
1340}
1341
356265ae 1342static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1343{
fe253235 1344 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1345 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1346}
1347
356265ae 1348static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1349{
fe253235 1350 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1351 generate_exception_err(ctx, EXCP_CpU, 1);
1352}
1353
b8aa4598
TS
1354/* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1356 opcode tables. */
1357
356265ae 1358static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1359{
1360 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1361 generate_exception(ctx, EXCP_RI);
1362}
1363
1364/* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1366
356265ae 1367static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1368{
b8aa4598 1369 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1370 generate_exception(ctx, EXCP_RI);
1371}
1372
1373/*
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 *
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 */
356265ae 1384static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1385{
fe253235 1386 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1387 generate_exception(ctx, EXCP_RI);
1388}
1389
853c3240
JL
1390/* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1392 */
1393
1394static inline void check_dsp(DisasContext *ctx)
1395{
1396 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1397 if (ctx->insn_flags & ASE_DSP) {
1398 generate_exception(ctx, EXCP_DSPDIS);
1399 } else {
1400 generate_exception(ctx, EXCP_RI);
1401 }
853c3240
JL
1402 }
1403}
1404
1405static inline void check_dspr2(DisasContext *ctx)
1406{
1407 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1408 if (ctx->insn_flags & ASE_DSP) {
1409 generate_exception(ctx, EXCP_DSPDIS);
1410 } else {
1411 generate_exception(ctx, EXCP_RI);
1412 }
853c3240
JL
1413 }
1414}
1415
3a95e3a7 1416/* This code generates a "reserved instruction" exception if the
e189e748 1417 CPU does not support the instruction set corresponding to flags. */
d75c135e 1418static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1419{
d75c135e 1420 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1421 generate_exception(ctx, EXCP_RI);
d75c135e 1422 }
3a95e3a7
TS
1423}
1424
e189e748
TS
1425/* This code generates a "reserved instruction" exception if 64-bit
1426 instructions are not enabled. */
356265ae 1427static inline void check_mips_64(DisasContext *ctx)
e189e748 1428{
fe253235 1429 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1430 generate_exception(ctx, EXCP_RI);
1431}
1432
8153667c
NF
1433/* Define small wrappers for gen_load_fpr* so that we have a uniform
1434 calling interface for 32 and 64-bit FPRs. No sense in changing
1435 all callers for gen_load_fpr32 when we need the CTX parameter for
1436 this one use. */
1437#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1440static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1441 int ft, int fs, int cc) \
1442{ \
1443 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1444 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1445 switch (ifmt) { \
1446 case FMT_PS: \
1447 check_cp1_64bitmode(ctx); \
1448 break; \
1449 case FMT_D: \
1450 if (abs) { \
1451 check_cop1x(ctx); \
1452 } \
1453 check_cp1_registers(ctx, fs | ft); \
1454 break; \
1455 case FMT_S: \
1456 if (abs) { \
1457 check_cop1x(ctx); \
1458 } \
1459 break; \
1460 } \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1463 switch (n) { \
895c2d04
BS
1464 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1465 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1466 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1467 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1468 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1469 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1470 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1471 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1472 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1473 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1475 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1476 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1477 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1478 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1479 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1480 default: abort(); \
1481 } \
1482 tcg_temp_free_i##bits (fp0); \
1483 tcg_temp_free_i##bits (fp1); \
1484}
1485
1486FOP_CONDS(, 0, d, FMT_D, 64)
1487FOP_CONDS(abs, 1, d, FMT_D, 64)
1488FOP_CONDS(, 0, s, FMT_S, 32)
1489FOP_CONDS(abs, 1, s, FMT_S, 32)
1490FOP_CONDS(, 0, ps, FMT_PS, 64)
1491FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1492#undef FOP_CONDS
1493#undef gen_ldcmp_fpr32
1494#undef gen_ldcmp_fpr64
1495
958fb4a9 1496/* load/store instructions. */
e7139c44 1497#ifdef CONFIG_USER_ONLY
d9bea114 1498#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1499static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1500{ \
1501 TCGv t0 = tcg_temp_new(); \
1502 tcg_gen_mov_tl(t0, arg1); \
1503 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1504 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1505 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1506 tcg_temp_free(t0); \
aaa9128a 1507}
e7139c44
AJ
1508#else
1509#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1510static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1511{ \
895c2d04 1512 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1513}
1514#endif
aaa9128a
TS
1515OP_LD_ATOMIC(ll,ld32s);
1516#if defined(TARGET_MIPS64)
1517OP_LD_ATOMIC(lld,ld64);
1518#endif
1519#undef OP_LD_ATOMIC
1520
590bc601
PB
1521#ifdef CONFIG_USER_ONLY
1522#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1523static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1524{ \
1525 TCGv t0 = tcg_temp_new(); \
1526 int l1 = gen_new_label(); \
1527 int l2 = gen_new_label(); \
1528 \
1529 tcg_gen_andi_tl(t0, arg2, almask); \
1530 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1531 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1532 generate_exception(ctx, EXCP_AdES); \
1533 gen_set_label(l1); \
7db13fae 1534 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1535 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1536 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1537 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1538 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1539 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1540 gen_set_label(l2); \
1541 tcg_gen_movi_tl(t0, 0); \
1542 gen_store_gpr(t0, rt); \
1543 tcg_temp_free(t0); \
1544}
1545#else
1546#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1547static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1548{ \
1549 TCGv t0 = tcg_temp_new(); \
895c2d04 1550 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1551 gen_store_gpr(t0, rt); \
590bc601
PB
1552 tcg_temp_free(t0); \
1553}
1554#endif
590bc601 1555OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1556#if defined(TARGET_MIPS64)
590bc601 1557OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1558#endif
1559#undef OP_ST_ATOMIC
1560
662d7485
NF
1561static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1562 int base, int16_t offset)
1563{
1564 if (base == 0) {
1565 tcg_gen_movi_tl(addr, offset);
1566 } else if (offset == 0) {
1567 gen_load_gpr(addr, base);
1568 } else {
1569 tcg_gen_movi_tl(addr, offset);
1570 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1571 }
1572}
1573
364d4831
NF
1574static target_ulong pc_relative_pc (DisasContext *ctx)
1575{
1576 target_ulong pc = ctx->pc;
1577
1578 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1579 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1580
1581 pc -= branch_bytes;
1582 }
1583
1584 pc &= ~(target_ulong)3;
1585 return pc;
1586}
1587
5c13fdfd 1588/* Load */
d75c135e
AJ
1589static void gen_ld(DisasContext *ctx, uint32_t opc,
1590 int rt, int base, int16_t offset)
6af0bf9c 1591{
5c13fdfd 1592 const char *opn = "ld";
fc40787a 1593 TCGv t0, t1, t2;
afa88c3a 1594
d75c135e 1595 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1596 /* Loongson CPU uses a load to zero register for prefetch.
1597 We emulate it as a NOP. On other CPU we must perform the
1598 actual memory access. */
1599 MIPS_DEBUG("NOP");
1600 return;
1601 }
6af0bf9c 1602
afa88c3a 1603 t0 = tcg_temp_new();
662d7485 1604 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1605
6af0bf9c 1606 switch (opc) {
d26bc211 1607#if defined(TARGET_MIPS64)
6e473128 1608 case OPC_LWU:
2910c6cb 1609 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
78723684 1610 gen_store_gpr(t0, rt);
6e473128
TS
1611 opn = "lwu";
1612 break;
6af0bf9c 1613 case OPC_LD:
2910c6cb 1614 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
78723684 1615 gen_store_gpr(t0, rt);
6af0bf9c
FB
1616 opn = "ld";
1617 break;
7a387fff 1618 case OPC_LLD:
b835e919 1619 save_cpu_state(ctx, 1);
5c13fdfd 1620 op_ld_lld(t0, t0, ctx);
78723684 1621 gen_store_gpr(t0, rt);
7a387fff
TS
1622 opn = "lld";
1623 break;
6af0bf9c 1624 case OPC_LDL:
3cee3050 1625 t1 = tcg_temp_new();
fc40787a
AJ
1626 tcg_gen_andi_tl(t1, t0, 7);
1627#ifndef TARGET_WORDS_BIGENDIAN
1628 tcg_gen_xori_tl(t1, t1, 7);
1629#endif
1630 tcg_gen_shli_tl(t1, t1, 3);
1631 tcg_gen_andi_tl(t0, t0, ~7);
1632 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1633 tcg_gen_shl_tl(t0, t0, t1);
1634 tcg_gen_xori_tl(t1, t1, 63);
1635 t2 = tcg_const_tl(0x7fffffffffffffffull);
1636 tcg_gen_shr_tl(t2, t2, t1);
78723684 1637 gen_load_gpr(t1, rt);
fc40787a
AJ
1638 tcg_gen_and_tl(t1, t1, t2);
1639 tcg_temp_free(t2);
1640 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1641 tcg_temp_free(t1);
fc40787a 1642 gen_store_gpr(t0, rt);
6af0bf9c
FB
1643 opn = "ldl";
1644 break;
6af0bf9c 1645 case OPC_LDR:
3cee3050 1646 t1 = tcg_temp_new();
fc40787a
AJ
1647 tcg_gen_andi_tl(t1, t0, 7);
1648#ifdef TARGET_WORDS_BIGENDIAN
1649 tcg_gen_xori_tl(t1, t1, 7);
1650#endif
1651 tcg_gen_shli_tl(t1, t1, 3);
1652 tcg_gen_andi_tl(t0, t0, ~7);
1653 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1654 tcg_gen_shr_tl(t0, t0, t1);
1655 tcg_gen_xori_tl(t1, t1, 63);
1656 t2 = tcg_const_tl(0xfffffffffffffffeull);
1657 tcg_gen_shl_tl(t2, t2, t1);
78723684 1658 gen_load_gpr(t1, rt);
fc40787a
AJ
1659 tcg_gen_and_tl(t1, t1, t2);
1660 tcg_temp_free(t2);
1661 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1662 tcg_temp_free(t1);
fc40787a 1663 gen_store_gpr(t0, rt);
6af0bf9c
FB
1664 opn = "ldr";
1665 break;
364d4831 1666 case OPC_LDPC:
3cee3050 1667 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1668 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1669 tcg_temp_free(t1);
2910c6cb 1670 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
364d4831 1671 gen_store_gpr(t0, rt);
5c13fdfd 1672 opn = "ldpc";
364d4831 1673 break;
6af0bf9c 1674#endif
364d4831 1675 case OPC_LWPC:
3cee3050 1676 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1677 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1678 tcg_temp_free(t1);
2910c6cb 1679 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
364d4831 1680 gen_store_gpr(t0, rt);
5c13fdfd 1681 opn = "lwpc";
364d4831 1682 break;
6af0bf9c 1683 case OPC_LW:
2910c6cb 1684 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
78723684 1685 gen_store_gpr(t0, rt);
6af0bf9c
FB
1686 opn = "lw";
1687 break;
6af0bf9c 1688 case OPC_LH:
2910c6cb 1689 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
78723684 1690 gen_store_gpr(t0, rt);
6af0bf9c
FB
1691 opn = "lh";
1692 break;
6af0bf9c 1693 case OPC_LHU:
2910c6cb 1694 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
78723684 1695 gen_store_gpr(t0, rt);
6af0bf9c
FB
1696 opn = "lhu";
1697 break;
1698 case OPC_LB:
2910c6cb 1699 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
78723684 1700 gen_store_gpr(t0, rt);
6af0bf9c
FB
1701 opn = "lb";
1702 break;
6af0bf9c 1703 case OPC_LBU:
2910c6cb 1704 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
78723684 1705 gen_store_gpr(t0, rt);
6af0bf9c
FB
1706 opn = "lbu";
1707 break;
1708 case OPC_LWL:
3cee3050 1709 t1 = tcg_temp_new();
fc40787a
AJ
1710 tcg_gen_andi_tl(t1, t0, 3);
1711#ifndef TARGET_WORDS_BIGENDIAN
1712 tcg_gen_xori_tl(t1, t1, 3);
1713#endif
1714 tcg_gen_shli_tl(t1, t1, 3);
1715 tcg_gen_andi_tl(t0, t0, ~3);
1716 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1717 tcg_gen_shl_tl(t0, t0, t1);
1718 tcg_gen_xori_tl(t1, t1, 31);
1719 t2 = tcg_const_tl(0x7fffffffull);
1720 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1721 gen_load_gpr(t1, rt);
fc40787a
AJ
1722 tcg_gen_and_tl(t1, t1, t2);
1723 tcg_temp_free(t2);
1724 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1725 tcg_temp_free(t1);
fc40787a
AJ
1726 tcg_gen_ext32s_tl(t0, t0);
1727 gen_store_gpr(t0, rt);
6af0bf9c
FB
1728 opn = "lwl";
1729 break;
6af0bf9c 1730 case OPC_LWR:
3cee3050 1731 t1 = tcg_temp_new();
fc40787a
AJ
1732 tcg_gen_andi_tl(t1, t0, 3);
1733#ifdef TARGET_WORDS_BIGENDIAN
1734 tcg_gen_xori_tl(t1, t1, 3);
1735#endif
1736 tcg_gen_shli_tl(t1, t1, 3);
1737 tcg_gen_andi_tl(t0, t0, ~3);
1738 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1739 tcg_gen_shr_tl(t0, t0, t1);
1740 tcg_gen_xori_tl(t1, t1, 31);
1741 t2 = tcg_const_tl(0xfffffffeull);
1742 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1743 gen_load_gpr(t1, rt);
fc40787a
AJ
1744 tcg_gen_and_tl(t1, t1, t2);
1745 tcg_temp_free(t2);
1746 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1747 tcg_temp_free(t1);
c728154b 1748 tcg_gen_ext32s_tl(t0, t0);
fc40787a 1749 gen_store_gpr(t0, rt);
6af0bf9c
FB
1750 opn = "lwr";
1751 break;
6af0bf9c 1752 case OPC_LL:
e7139c44 1753 save_cpu_state(ctx, 1);
5c13fdfd 1754 op_ld_ll(t0, t0, ctx);
78723684 1755 gen_store_gpr(t0, rt);
6af0bf9c
FB
1756 opn = "ll";
1757 break;
d66c7132 1758 }
2abf314d 1759 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1760 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1761 tcg_temp_free(t0);
d66c7132
AJ
1762}
1763
5c13fdfd
AJ
1764/* Store */
1765static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1766 int base, int16_t offset)
1767{
1768 const char *opn = "st";
1769 TCGv t0 = tcg_temp_new();
1770 TCGv t1 = tcg_temp_new();
1771
1772 gen_base_offset_addr(ctx, t0, base, offset);
1773 gen_load_gpr(t1, rt);
1774 switch (opc) {
1775#if defined(TARGET_MIPS64)
1776 case OPC_SD:
2910c6cb 1777 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1778 opn = "sd";
1779 break;
1780 case OPC_SDL:
1781 save_cpu_state(ctx, 1);
895c2d04 1782 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1783 opn = "sdl";
1784 break;
1785 case OPC_SDR:
1786 save_cpu_state(ctx, 1);
895c2d04 1787 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1788 opn = "sdr";
1789 break;
1790#endif
1791 case OPC_SW:
2910c6cb 1792 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1793 opn = "sw";
1794 break;
1795 case OPC_SH:
2910c6cb 1796 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1797 opn = "sh";
1798 break;
1799 case OPC_SB:
2910c6cb 1800 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1801 opn = "sb";
1802 break;
1803 case OPC_SWL:
1804 save_cpu_state(ctx, 1);
895c2d04 1805 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1806 opn = "swl";
1807 break;
1808 case OPC_SWR:
1809 save_cpu_state(ctx, 1);
895c2d04 1810 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1811 opn = "swr";
1812 break;
1813 }
2abf314d 1814 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1815 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1816 tcg_temp_free(t0);
1817 tcg_temp_free(t1);
1818}
1819
1820
d66c7132
AJ
1821/* Store conditional */
1822static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1823 int base, int16_t offset)
1824{
1825 const char *opn = "st_cond";
1826 TCGv t0, t1;
1827
2d2826b9 1828#ifdef CONFIG_USER_ONLY
d66c7132 1829 t0 = tcg_temp_local_new();
d66c7132 1830 t1 = tcg_temp_local_new();
2d2826b9
AJ
1831#else
1832 t0 = tcg_temp_new();
1833 t1 = tcg_temp_new();
1834#endif
1835 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1836 gen_load_gpr(t1, rt);
1837 switch (opc) {
1838#if defined(TARGET_MIPS64)
1839 case OPC_SCD:
b835e919 1840 save_cpu_state(ctx, 1);
5c13fdfd 1841 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1842 opn = "scd";
1843 break;
1844#endif
6af0bf9c 1845 case OPC_SC:
e7139c44 1846 save_cpu_state(ctx, 1);
5c13fdfd 1847 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1848 opn = "sc";
1849 break;
6af0bf9c 1850 }
2abf314d 1851 (void)opn; /* avoid a compiler warning */
6af0bf9c 1852 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1853 tcg_temp_free(t1);
d66c7132 1854 tcg_temp_free(t0);
6af0bf9c
FB
1855}
1856
6ea83fed 1857/* Load and store */
7a387fff 1858static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1859 int base, int16_t offset)
6ea83fed 1860{
923617a3 1861 const char *opn = "flt_ldst";
4e2474d6 1862 TCGv t0 = tcg_temp_new();
6ea83fed 1863
662d7485 1864 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1865 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1866 memory access. */
6ea83fed
FB
1867 switch (opc) {
1868 case OPC_LWC1:
b6d96bed 1869 {
a7812ae4 1870 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1871
c407df81
AJ
1872 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1873 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 1874 gen_store_fpr32(fp0, ft);
a7812ae4 1875 tcg_temp_free_i32(fp0);
b6d96bed 1876 }
6ea83fed
FB
1877 opn = "lwc1";
1878 break;
1879 case OPC_SWC1:
b6d96bed 1880 {
a7812ae4
PB
1881 TCGv_i32 fp0 = tcg_temp_new_i32();
1882 TCGv t1 = tcg_temp_new();
b6d96bed
TS
1883
1884 gen_load_fpr32(fp0, ft);
a7812ae4
PB
1885 tcg_gen_extu_i32_tl(t1, fp0);
1886 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1887 tcg_temp_free(t1);
1888 tcg_temp_free_i32(fp0);
b6d96bed 1889 }
6ea83fed
FB
1890 opn = "swc1";
1891 break;
1892 case OPC_LDC1:
b6d96bed 1893 {
a7812ae4 1894 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1895
1896 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1897 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1898 tcg_temp_free_i64(fp0);
b6d96bed 1899 }
6ea83fed
FB
1900 opn = "ldc1";
1901 break;
1902 case OPC_SDC1:
b6d96bed 1903 {
a7812ae4 1904 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1905
1906 gen_load_fpr64(ctx, fp0, ft);
1907 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 1908 tcg_temp_free_i64(fp0);
b6d96bed 1909 }
6ea83fed
FB
1910 opn = "sdc1";
1911 break;
1912 default:
923617a3 1913 MIPS_INVAL(opn);
e397ee33 1914 generate_exception(ctx, EXCP_RI);
78723684 1915 goto out;
6ea83fed 1916 }
2abf314d 1917 (void)opn; /* avoid a compiler warning */
6ea83fed 1918 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1919 out:
1920 tcg_temp_free(t0);
6ea83fed 1921}
6ea83fed 1922
7db13fae 1923static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
26ebe468
NF
1924 uint32_t op, int rt, int rs, int16_t imm)
1925{
1926 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1927 check_cp1_enabled(ctx);
1928 gen_flt_ldst(ctx, op, rt, rs, imm);
1929 } else {
1930 generate_exception_err(ctx, EXCP_CpU, 1);
1931 }
1932}
1933
6af0bf9c 1934/* Arithmetic with immediate operand */
d75c135e
AJ
1935static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1936 int rt, int rs, int16_t imm)
6af0bf9c 1937{
324d9e32 1938 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1939 const char *opn = "imm arith";
6af0bf9c 1940
7a387fff 1941 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1942 /* If no destination, treat it as a NOP.
1943 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1944 MIPS_DEBUG("NOP");
324d9e32 1945 return;
6af0bf9c
FB
1946 }
1947 switch (opc) {
1948 case OPC_ADDI:
48d38ca5 1949 {
324d9e32
AJ
1950 TCGv t0 = tcg_temp_local_new();
1951 TCGv t1 = tcg_temp_new();
1952 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1953 int l1 = gen_new_label();
1954
324d9e32
AJ
1955 gen_load_gpr(t1, rs);
1956 tcg_gen_addi_tl(t0, t1, uimm);
1957 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1958
324d9e32
AJ
1959 tcg_gen_xori_tl(t1, t1, ~uimm);
1960 tcg_gen_xori_tl(t2, t0, uimm);
1961 tcg_gen_and_tl(t1, t1, t2);
1962 tcg_temp_free(t2);
1963 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1964 tcg_temp_free(t1);
48d38ca5
TS
1965 /* operands of same sign, result different sign */
1966 generate_exception(ctx, EXCP_OVERFLOW);
1967 gen_set_label(l1);
78723684 1968 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1969 gen_store_gpr(t0, rt);
1970 tcg_temp_free(t0);
48d38ca5 1971 }
6af0bf9c
FB
1972 opn = "addi";
1973 break;
1974 case OPC_ADDIU:
324d9e32
AJ
1975 if (rs != 0) {
1976 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1977 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1978 } else {
1979 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1980 }
6af0bf9c
FB
1981 opn = "addiu";
1982 break;
d26bc211 1983#if defined(TARGET_MIPS64)
7a387fff 1984 case OPC_DADDI:
48d38ca5 1985 {
324d9e32
AJ
1986 TCGv t0 = tcg_temp_local_new();
1987 TCGv t1 = tcg_temp_new();
1988 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1989 int l1 = gen_new_label();
1990
324d9e32
AJ
1991 gen_load_gpr(t1, rs);
1992 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1993
324d9e32
AJ
1994 tcg_gen_xori_tl(t1, t1, ~uimm);
1995 tcg_gen_xori_tl(t2, t0, uimm);
1996 tcg_gen_and_tl(t1, t1, t2);
1997 tcg_temp_free(t2);
1998 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1999 tcg_temp_free(t1);
48d38ca5
TS
2000 /* operands of same sign, result different sign */
2001 generate_exception(ctx, EXCP_OVERFLOW);
2002 gen_set_label(l1);
324d9e32
AJ
2003 gen_store_gpr(t0, rt);
2004 tcg_temp_free(t0);
48d38ca5 2005 }
7a387fff
TS
2006 opn = "daddi";
2007 break;
2008 case OPC_DADDIU:
324d9e32
AJ
2009 if (rs != 0) {
2010 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2011 } else {
2012 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2013 }
7a387fff
TS
2014 opn = "daddiu";
2015 break;
2016#endif
324d9e32 2017 }
2abf314d 2018 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2019 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2020}
2021
2022/* Logic with immediate operand */
d75c135e 2023static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2024 int rt, int rs, int16_t imm)
324d9e32
AJ
2025{
2026 target_ulong uimm;
324d9e32
AJ
2027
2028 if (rt == 0) {
2029 /* If no destination, treat it as a NOP. */
2030 MIPS_DEBUG("NOP");
2031 return;
2032 }
2033 uimm = (uint16_t)imm;
2034 switch (opc) {
6af0bf9c 2035 case OPC_ANDI:
324d9e32
AJ
2036 if (likely(rs != 0))
2037 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2038 else
2039 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2040 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2041 regnames[rs], uimm);
6af0bf9c
FB
2042 break;
2043 case OPC_ORI:
324d9e32
AJ
2044 if (rs != 0)
2045 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2046 else
2047 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2048 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2049 regnames[rs], uimm);
6af0bf9c
FB
2050 break;
2051 case OPC_XORI:
324d9e32
AJ
2052 if (likely(rs != 0))
2053 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2054 else
2055 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2056 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2057 regnames[rs], uimm);
6af0bf9c
FB
2058 break;
2059 case OPC_LUI:
324d9e32 2060 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2061 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2062 break;
2063
2064 default:
2065 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2066 break;
324d9e32 2067 }
324d9e32
AJ
2068}
2069
2070/* Set on less than with immediate operand */
d75c135e 2071static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2072 int rt, int rs, int16_t imm)
324d9e32
AJ
2073{
2074 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2075 const char *opn = "imm arith";
2076 TCGv t0;
2077
2078 if (rt == 0) {
2079 /* If no destination, treat it as a NOP. */
2080 MIPS_DEBUG("NOP");
2081 return;
2082 }
2083 t0 = tcg_temp_new();
2084 gen_load_gpr(t0, rs);
2085 switch (opc) {
2086 case OPC_SLTI:
e68dd28f 2087 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2088 opn = "slti";
2089 break;
2090 case OPC_SLTIU:
e68dd28f 2091 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2092 opn = "sltiu";
2093 break;
2094 }
2abf314d 2095 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2096 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2097 tcg_temp_free(t0);
2098}
2099
2100/* Shifts with immediate operand */
d75c135e 2101static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2102 int rt, int rs, int16_t imm)
2103{
2104 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2105 const char *opn = "imm shift";
2106 TCGv t0;
2107
2108 if (rt == 0) {
2109 /* If no destination, treat it as a NOP. */
2110 MIPS_DEBUG("NOP");
2111 return;
2112 }
2113
2114 t0 = tcg_temp_new();
2115 gen_load_gpr(t0, rs);
2116 switch (opc) {
6af0bf9c 2117 case OPC_SLL:
78723684 2118 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2119 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2120 opn = "sll";
2121 break;
2122 case OPC_SRA:
324d9e32 2123 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2124 opn = "sra";
2125 break;
2126 case OPC_SRL:
ea63e2c3
NF
2127 if (uimm != 0) {
2128 tcg_gen_ext32u_tl(t0, t0);
2129 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2130 } else {
2131 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2132 }
ea63e2c3
NF
2133 opn = "srl";
2134 break;
2135 case OPC_ROTR:
2136 if (uimm != 0) {
2137 TCGv_i32 t1 = tcg_temp_new_i32();
2138
2139 tcg_gen_trunc_tl_i32(t1, t0);
2140 tcg_gen_rotri_i32(t1, t1, uimm);
2141 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2142 tcg_temp_free_i32(t1);
3399e30f
NF
2143 } else {
2144 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2145 }
2146 opn = "rotr";
7a387fff 2147 break;
d26bc211 2148#if defined(TARGET_MIPS64)
7a387fff 2149 case OPC_DSLL:
324d9e32 2150 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2151 opn = "dsll";
2152 break;
2153 case OPC_DSRA:
324d9e32 2154 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2155 opn = "dsra";
2156 break;
2157 case OPC_DSRL:
ea63e2c3
NF
2158 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2159 opn = "dsrl";
2160 break;
2161 case OPC_DROTR:
2162 if (uimm != 0) {
2163 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2164 } else {
2165 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2166 }
ea63e2c3 2167 opn = "drotr";
7a387fff
TS
2168 break;
2169 case OPC_DSLL32:
324d9e32 2170 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2171 opn = "dsll32";
2172 break;
2173 case OPC_DSRA32:
324d9e32 2174 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2175 opn = "dsra32";
2176 break;
2177 case OPC_DSRL32:
ea63e2c3
NF
2178 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2179 opn = "dsrl32";
2180 break;
2181 case OPC_DROTR32:
2182 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2183 opn = "drotr32";
6af0bf9c 2184 break;
7a387fff 2185#endif
6af0bf9c 2186 }
2abf314d 2187 (void)opn; /* avoid a compiler warning */
93b12ccc 2188 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2189 tcg_temp_free(t0);
6af0bf9c
FB
2190}
2191
2192/* Arithmetic */
d75c135e
AJ
2193static void gen_arith(DisasContext *ctx, uint32_t opc,
2194 int rd, int rs, int rt)
6af0bf9c 2195{
923617a3 2196 const char *opn = "arith";
6af0bf9c 2197
7a387fff
TS
2198 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2199 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2200 /* If no destination, treat it as a NOP.
2201 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2202 MIPS_DEBUG("NOP");
460f00c4 2203 return;
185f0762 2204 }
460f00c4 2205
6af0bf9c
FB
2206 switch (opc) {
2207 case OPC_ADD:
48d38ca5 2208 {
460f00c4
AJ
2209 TCGv t0 = tcg_temp_local_new();
2210 TCGv t1 = tcg_temp_new();
2211 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2212 int l1 = gen_new_label();
2213
460f00c4
AJ
2214 gen_load_gpr(t1, rs);
2215 gen_load_gpr(t2, rt);
2216 tcg_gen_add_tl(t0, t1, t2);
2217 tcg_gen_ext32s_tl(t0, t0);
2218 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2219 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2220 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2221 tcg_temp_free(t2);
2222 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2223 tcg_temp_free(t1);
48d38ca5
TS
2224 /* operands of same sign, result different sign */
2225 generate_exception(ctx, EXCP_OVERFLOW);
2226 gen_set_label(l1);
460f00c4
AJ
2227 gen_store_gpr(t0, rd);
2228 tcg_temp_free(t0);
48d38ca5 2229 }
6af0bf9c
FB
2230 opn = "add";
2231 break;
2232 case OPC_ADDU:
460f00c4
AJ
2233 if (rs != 0 && rt != 0) {
2234 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2235 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2236 } else if (rs == 0 && rt != 0) {
2237 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2238 } else if (rs != 0 && rt == 0) {
2239 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2240 } else {
2241 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2242 }
6af0bf9c
FB
2243 opn = "addu";
2244 break;
2245 case OPC_SUB:
48d38ca5 2246 {
460f00c4
AJ
2247 TCGv t0 = tcg_temp_local_new();
2248 TCGv t1 = tcg_temp_new();
2249 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2250 int l1 = gen_new_label();
2251
460f00c4
AJ
2252 gen_load_gpr(t1, rs);
2253 gen_load_gpr(t2, rt);
2254 tcg_gen_sub_tl(t0, t1, t2);
2255 tcg_gen_ext32s_tl(t0, t0);
2256 tcg_gen_xor_tl(t2, t1, t2);
2257 tcg_gen_xor_tl(t1, t0, t1);
2258 tcg_gen_and_tl(t1, t1, t2);
2259 tcg_temp_free(t2);
2260 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2261 tcg_temp_free(t1);
31e3104f 2262 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2263 generate_exception(ctx, EXCP_OVERFLOW);
2264 gen_set_label(l1);
460f00c4
AJ
2265 gen_store_gpr(t0, rd);
2266 tcg_temp_free(t0);
48d38ca5 2267 }
6af0bf9c
FB
2268 opn = "sub";
2269 break;
2270 case OPC_SUBU:
460f00c4
AJ
2271 if (rs != 0 && rt != 0) {
2272 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2273 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2274 } else if (rs == 0 && rt != 0) {
2275 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2276 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2277 } else if (rs != 0 && rt == 0) {
2278 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2279 } else {
2280 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2281 }
6af0bf9c
FB
2282 opn = "subu";
2283 break;
d26bc211 2284#if defined(TARGET_MIPS64)
7a387fff 2285 case OPC_DADD:
48d38ca5 2286 {
460f00c4
AJ
2287 TCGv t0 = tcg_temp_local_new();
2288 TCGv t1 = tcg_temp_new();
2289 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2290 int l1 = gen_new_label();
2291
460f00c4
AJ
2292 gen_load_gpr(t1, rs);
2293 gen_load_gpr(t2, rt);
2294 tcg_gen_add_tl(t0, t1, t2);
2295 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2296 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2297 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2298 tcg_temp_free(t2);
2299 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2300 tcg_temp_free(t1);
48d38ca5
TS
2301 /* operands of same sign, result different sign */
2302 generate_exception(ctx, EXCP_OVERFLOW);
2303 gen_set_label(l1);
460f00c4
AJ
2304 gen_store_gpr(t0, rd);
2305 tcg_temp_free(t0);
48d38ca5 2306 }
7a387fff
TS
2307 opn = "dadd";
2308 break;
2309 case OPC_DADDU:
460f00c4
AJ
2310 if (rs != 0 && rt != 0) {
2311 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2312 } else if (rs == 0 && rt != 0) {
2313 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2314 } else if (rs != 0 && rt == 0) {
2315 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2316 } else {
2317 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2318 }
7a387fff
TS
2319 opn = "daddu";
2320 break;
2321 case OPC_DSUB:
48d38ca5 2322 {
460f00c4
AJ
2323 TCGv t0 = tcg_temp_local_new();
2324 TCGv t1 = tcg_temp_new();
2325 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2326 int l1 = gen_new_label();
2327
460f00c4
AJ
2328 gen_load_gpr(t1, rs);
2329 gen_load_gpr(t2, rt);
2330 tcg_gen_sub_tl(t0, t1, t2);
2331 tcg_gen_xor_tl(t2, t1, t2);
2332 tcg_gen_xor_tl(t1, t0, t1);
2333 tcg_gen_and_tl(t1, t1, t2);
2334 tcg_temp_free(t2);
2335 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2336 tcg_temp_free(t1);
31e3104f 2337 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2338 generate_exception(ctx, EXCP_OVERFLOW);
2339 gen_set_label(l1);
460f00c4
AJ
2340 gen_store_gpr(t0, rd);
2341 tcg_temp_free(t0);
48d38ca5 2342 }
7a387fff
TS
2343 opn = "dsub";
2344 break;
2345 case OPC_DSUBU:
460f00c4
AJ
2346 if (rs != 0 && rt != 0) {
2347 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2348 } else if (rs == 0 && rt != 0) {
2349 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2350 } else if (rs != 0 && rt == 0) {
2351 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2352 } else {
2353 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2354 }
7a387fff
TS
2355 opn = "dsubu";
2356 break;
2357#endif
460f00c4
AJ
2358 case OPC_MUL:
2359 if (likely(rs != 0 && rt != 0)) {
2360 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2361 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2362 } else {
2363 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2364 }
2365 opn = "mul";
6af0bf9c 2366 break;
460f00c4 2367 }
2abf314d 2368 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2369 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2370}
2371
2372/* Conditional move */
d75c135e 2373static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2374 int rd, int rs, int rt)
460f00c4
AJ
2375{
2376 const char *opn = "cond move";
acf12465 2377 TCGv t0, t1, t2;
460f00c4
AJ
2378
2379 if (rd == 0) {
acf12465 2380 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2381 MIPS_DEBUG("NOP");
2382 return;
2383 }
2384
acf12465
AJ
2385 t0 = tcg_temp_new();
2386 gen_load_gpr(t0, rt);
2387 t1 = tcg_const_tl(0);
2388 t2 = tcg_temp_new();
2389 gen_load_gpr(t2, rs);
460f00c4
AJ
2390 switch (opc) {
2391 case OPC_MOVN:
acf12465 2392 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2393 opn = "movn";
6af0bf9c 2394 break;
460f00c4 2395 case OPC_MOVZ:
acf12465 2396 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2397 opn = "movz";
2398 break;
2399 }
acf12465
AJ
2400 tcg_temp_free(t2);
2401 tcg_temp_free(t1);
2402 tcg_temp_free(t0);
460f00c4 2403
2abf314d 2404 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2405 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2406}
2407
2408/* Logic */
d75c135e 2409static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2410 int rd, int rs, int rt)
460f00c4
AJ
2411{
2412 const char *opn = "logic";
2413
2414 if (rd == 0) {
2415 /* If no destination, treat it as a NOP. */
2416 MIPS_DEBUG("NOP");
2417 return;
2418 }
2419
2420 switch (opc) {
6af0bf9c 2421 case OPC_AND:
460f00c4
AJ
2422 if (likely(rs != 0 && rt != 0)) {
2423 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2424 } else {
2425 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2426 }
6af0bf9c
FB
2427 opn = "and";
2428 break;
2429 case OPC_NOR:
460f00c4
AJ
2430 if (rs != 0 && rt != 0) {
2431 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2432 } else if (rs == 0 && rt != 0) {
2433 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2434 } else if (rs != 0 && rt == 0) {
2435 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2436 } else {
2437 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2438 }
6af0bf9c
FB
2439 opn = "nor";
2440 break;
2441 case OPC_OR:
460f00c4
AJ
2442 if (likely(rs != 0 && rt != 0)) {
2443 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2444 } else if (rs == 0 && rt != 0) {
2445 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2446 } else if (rs != 0 && rt == 0) {
2447 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2448 } else {
2449 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2450 }
6af0bf9c
FB
2451 opn = "or";
2452 break;
2453 case OPC_XOR:
460f00c4
AJ
2454 if (likely(rs != 0 && rt != 0)) {
2455 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2456 } else if (rs == 0 && rt != 0) {
2457 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2458 } else if (rs != 0 && rt == 0) {
2459 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2460 } else {
2461 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2462 }
6af0bf9c
FB
2463 opn = "xor";
2464 break;
460f00c4 2465 }
2abf314d 2466 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2467 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2468}
2469
2470/* Set on lower than */
d75c135e 2471static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2472 int rd, int rs, int rt)
460f00c4
AJ
2473{
2474 const char *opn = "slt";
2475 TCGv t0, t1;
2476
2477 if (rd == 0) {
2478 /* If no destination, treat it as a NOP. */
2479 MIPS_DEBUG("NOP");
2480 return;
2481 }
2482
2483 t0 = tcg_temp_new();
2484 t1 = tcg_temp_new();
2485 gen_load_gpr(t0, rs);
2486 gen_load_gpr(t1, rt);
2487 switch (opc) {
2488 case OPC_SLT:
e68dd28f 2489 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2490 opn = "slt";
6af0bf9c 2491 break;
460f00c4 2492 case OPC_SLTU:
e68dd28f 2493 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2494 opn = "sltu";
2495 break;
2496 }
2abf314d 2497 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2498 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2499 tcg_temp_free(t0);
2500 tcg_temp_free(t1);
2501}
20c4c97c 2502
460f00c4 2503/* Shifts */
d75c135e
AJ
2504static void gen_shift(DisasContext *ctx, uint32_t opc,
2505 int rd, int rs, int rt)
460f00c4
AJ
2506{
2507 const char *opn = "shifts";
2508 TCGv t0, t1;
20c4c97c 2509
460f00c4
AJ
2510 if (rd == 0) {
2511 /* If no destination, treat it as a NOP.
2512 For add & sub, we must generate the overflow exception when needed. */
2513 MIPS_DEBUG("NOP");
2514 return;
2515 }
2516
2517 t0 = tcg_temp_new();
2518 t1 = tcg_temp_new();
2519 gen_load_gpr(t0, rs);
2520 gen_load_gpr(t1, rt);
2521 switch (opc) {
6af0bf9c 2522 case OPC_SLLV:
78723684
TS
2523 tcg_gen_andi_tl(t0, t0, 0x1f);
2524 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2525 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2526 opn = "sllv";
2527 break;
2528 case OPC_SRAV:
78723684 2529 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2530 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2531 opn = "srav";
2532 break;
2533 case OPC_SRLV:
ea63e2c3
NF
2534 tcg_gen_ext32u_tl(t1, t1);
2535 tcg_gen_andi_tl(t0, t0, 0x1f);
2536 tcg_gen_shr_tl(t0, t1, t0);
2537 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2538 opn = "srlv";
2539 break;
2540 case OPC_ROTRV:
2541 {
2542 TCGv_i32 t2 = tcg_temp_new_i32();
2543 TCGv_i32 t3 = tcg_temp_new_i32();
2544
2545 tcg_gen_trunc_tl_i32(t2, t0);
2546 tcg_gen_trunc_tl_i32(t3, t1);
2547 tcg_gen_andi_i32(t2, t2, 0x1f);
2548 tcg_gen_rotr_i32(t2, t3, t2);
2549 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2550 tcg_temp_free_i32(t2);
2551 tcg_temp_free_i32(t3);
2552 opn = "rotrv";
5a63bcb2 2553 }
7a387fff 2554 break;
d26bc211 2555#if defined(TARGET_MIPS64)
7a387fff 2556 case OPC_DSLLV:
78723684 2557 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2558 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2559 opn = "dsllv";
2560 break;
2561 case OPC_DSRAV:
78723684 2562 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2563 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2564 opn = "dsrav";
2565 break;
2566 case OPC_DSRLV:
ea63e2c3
NF
2567 tcg_gen_andi_tl(t0, t0, 0x3f);
2568 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2569 opn = "dsrlv";
2570 break;
2571 case OPC_DROTRV:
2572 tcg_gen_andi_tl(t0, t0, 0x3f);
2573 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2574 opn = "drotrv";
6af0bf9c 2575 break;
7a387fff 2576#endif
6af0bf9c 2577 }
2abf314d 2578 (void)opn; /* avoid a compiler warning */
6af0bf9c 2579 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2580 tcg_temp_free(t0);
2581 tcg_temp_free(t1);
6af0bf9c
FB
2582}
2583
2584/* Arithmetic on HI/LO registers */
7a387fff 2585static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
6af0bf9c 2586{
923617a3 2587 const char *opn = "hilo";
4133498f 2588 unsigned int acc;
6af0bf9c
FB
2589
2590 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2591 /* Treat as NOP. */
6af0bf9c 2592 MIPS_DEBUG("NOP");
a1f6684d 2593 return;
6af0bf9c 2594 }
4133498f
JL
2595
2596 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2597 acc = ((ctx->opcode) >> 21) & 0x03;
2598 } else {
2599 acc = ((ctx->opcode) >> 11) & 0x03;
2600 }
2601
2602 if (acc != 0) {
2603 check_dsp(ctx);
2604 }
2605
6af0bf9c
FB
2606 switch (opc) {
2607 case OPC_MFHI:
4133498f
JL
2608#if defined(TARGET_MIPS64)
2609 if (acc != 0) {
2610 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2611 } else
2612#endif
2613 {
2614 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2615 }
6af0bf9c
FB
2616 opn = "mfhi";
2617 break;
2618 case OPC_MFLO:
4133498f
JL
2619#if defined(TARGET_MIPS64)
2620 if (acc != 0) {
2621 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2622 } else
2623#endif
2624 {
2625 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2626 }
6af0bf9c
FB
2627 opn = "mflo";
2628 break;
2629 case OPC_MTHI:
4133498f
JL
2630 if (reg != 0) {
2631#if defined(TARGET_MIPS64)
2632 if (acc != 0) {
2633 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2634 } else
2635#endif
2636 {
2637 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2638 }
2639 } else {
2640 tcg_gen_movi_tl(cpu_HI[acc], 0);
2641 }
6af0bf9c
FB
2642 opn = "mthi";
2643 break;
2644 case OPC_MTLO:
4133498f
JL
2645 if (reg != 0) {
2646#if defined(TARGET_MIPS64)
2647 if (acc != 0) {
2648 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2649 } else
2650#endif
2651 {
2652 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2653 }
2654 } else {
2655 tcg_gen_movi_tl(cpu_LO[acc], 0);
2656 }
6af0bf9c
FB
2657 opn = "mtlo";
2658 break;
6af0bf9c 2659 }
2abf314d 2660 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2661 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2662}
2663
7a387fff 2664static void gen_muldiv (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2665 int rs, int rt)
2666{
923617a3 2667 const char *opn = "mul/div";
d45f89f4 2668 TCGv t0, t1;
4133498f 2669 unsigned int acc;
d45f89f4 2670
51127181
AJ
2671 t0 = tcg_temp_new();
2672 t1 = tcg_temp_new();
6af0bf9c 2673
78723684
TS
2674 gen_load_gpr(t0, rs);
2675 gen_load_gpr(t1, rt);
51127181 2676
6af0bf9c
FB
2677 switch (opc) {
2678 case OPC_DIV:
48d38ca5 2679 {
51127181
AJ
2680 TCGv t2 = tcg_temp_new();
2681 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2682 tcg_gen_ext32s_tl(t0, t0);
2683 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2684 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2685 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2686 tcg_gen_and_tl(t2, t2, t3);
2687 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2688 tcg_gen_or_tl(t2, t2, t3);
2689 tcg_gen_movi_tl(t3, 0);
2690 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
d45f89f4
AJ
2691 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2692 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2693 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2694 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
51127181
AJ
2695 tcg_temp_free(t3);
2696 tcg_temp_free(t2);
48d38ca5 2697 }
6af0bf9c
FB
2698 opn = "div";
2699 break;
2700 case OPC_DIVU:
48d38ca5 2701 {
51127181
AJ
2702 TCGv t2 = tcg_const_tl(0);
2703 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
2704 tcg_gen_ext32u_tl(t0, t0);
2705 tcg_gen_ext32u_tl(t1, t1);
51127181 2706 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
d45f89f4
AJ
2707 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2708 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2709 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2710 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
51127181
AJ
2711 tcg_temp_free(t3);
2712 tcg_temp_free(t2);
48d38ca5 2713 }
6af0bf9c
FB
2714 opn = "divu";
2715 break;
2716 case OPC_MULT:
214c465f 2717 {
d45f89f4
AJ
2718 TCGv_i64 t2 = tcg_temp_new_i64();
2719 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2720 acc = ((ctx->opcode) >> 11) & 0x03;
2721 if (acc != 0) {
2722 check_dsp(ctx);
2723 }
d45f89f4
AJ
2724
2725 tcg_gen_ext_tl_i64(t2, t0);
2726 tcg_gen_ext_tl_i64(t3, t1);
2727 tcg_gen_mul_i64(t2, t2, t3);
2728 tcg_temp_free_i64(t3);
2729 tcg_gen_trunc_i64_tl(t0, t2);
2730 tcg_gen_shri_i64(t2, t2, 32);
2731 tcg_gen_trunc_i64_tl(t1, t2);
2732 tcg_temp_free_i64(t2);
4133498f
JL
2733 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2734 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2735 }
6af0bf9c
FB
2736 opn = "mult";
2737 break;
2738 case OPC_MULTU:
214c465f 2739 {
d45f89f4
AJ
2740 TCGv_i64 t2 = tcg_temp_new_i64();
2741 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2742 acc = ((ctx->opcode) >> 11) & 0x03;
2743 if (acc != 0) {
2744 check_dsp(ctx);
2745 }
214c465f 2746
78723684
TS
2747 tcg_gen_ext32u_tl(t0, t0);
2748 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2749 tcg_gen_extu_tl_i64(t2, t0);
2750 tcg_gen_extu_tl_i64(t3, t1);
2751 tcg_gen_mul_i64(t2, t2, t3);
2752 tcg_temp_free_i64(t3);
2753 tcg_gen_trunc_i64_tl(t0, t2);
2754 tcg_gen_shri_i64(t2, t2, 32);
2755 tcg_gen_trunc_i64_tl(t1, t2);
2756 tcg_temp_free_i64(t2);
4133498f
JL
2757 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2758 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2759 }
6af0bf9c
FB
2760 opn = "multu";
2761 break;
d26bc211 2762#if defined(TARGET_MIPS64)
7a387fff 2763 case OPC_DDIV:
48d38ca5 2764 {
51127181
AJ
2765 TCGv t2 = tcg_temp_new();
2766 TCGv t3 = tcg_temp_new();
2767 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2768 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2769 tcg_gen_and_tl(t2, t2, t3);
2770 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2771 tcg_gen_or_tl(t2, t2, t3);
2772 tcg_gen_movi_tl(t3, 0);
2773 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2774 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2775 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2776 tcg_temp_free(t3);
2777 tcg_temp_free(t2);
48d38ca5 2778 }
7a387fff
TS
2779 opn = "ddiv";
2780 break;
2781 case OPC_DDIVU:
48d38ca5 2782 {
51127181
AJ
2783 TCGv t2 = tcg_const_tl(0);
2784 TCGv t3 = tcg_const_tl(1);
2785 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
b10fa3c9
AJ
2786 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2787 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
51127181
AJ
2788 tcg_temp_free(t3);
2789 tcg_temp_free(t2);
48d38ca5 2790 }
7a387fff
TS
2791 opn = "ddivu";
2792 break;
2793 case OPC_DMULT:
895c2d04 2794 gen_helper_dmult(cpu_env, t0, t1);
7a387fff
TS
2795 opn = "dmult";
2796 break;
2797 case OPC_DMULTU:
895c2d04 2798 gen_helper_dmultu(cpu_env, t0, t1);
7a387fff
TS
2799 opn = "dmultu";
2800 break;
2801#endif
6af0bf9c 2802 case OPC_MADD:
214c465f 2803 {
d45f89f4
AJ
2804 TCGv_i64 t2 = tcg_temp_new_i64();
2805 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2806 acc = ((ctx->opcode) >> 11) & 0x03;
2807 if (acc != 0) {
2808 check_dsp(ctx);
2809 }
d45f89f4
AJ
2810
2811 tcg_gen_ext_tl_i64(t2, t0);
2812 tcg_gen_ext_tl_i64(t3, t1);
2813 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2814 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2815 tcg_gen_add_i64(t2, t2, t3);
2816 tcg_temp_free_i64(t3);
2817 tcg_gen_trunc_i64_tl(t0, t2);
2818 tcg_gen_shri_i64(t2, t2, 32);
2819 tcg_gen_trunc_i64_tl(t1, t2);
2820 tcg_temp_free_i64(t2);
4133498f
JL
2821 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2822 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2823 }
6af0bf9c
FB
2824 opn = "madd";
2825 break;
2826 case OPC_MADDU:
4133498f 2827 {
d45f89f4
AJ
2828 TCGv_i64 t2 = tcg_temp_new_i64();
2829 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2830 acc = ((ctx->opcode) >> 11) & 0x03;
2831 if (acc != 0) {
2832 check_dsp(ctx);
2833 }
214c465f 2834
78723684
TS
2835 tcg_gen_ext32u_tl(t0, t0);
2836 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2837 tcg_gen_extu_tl_i64(t2, t0);
2838 tcg_gen_extu_tl_i64(t3, t1);
2839 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2840 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2841 tcg_gen_add_i64(t2, t2, t3);
2842 tcg_temp_free_i64(t3);
2843 tcg_gen_trunc_i64_tl(t0, t2);
2844 tcg_gen_shri_i64(t2, t2, 32);
2845 tcg_gen_trunc_i64_tl(t1, t2);
2846 tcg_temp_free_i64(t2);
4133498f
JL
2847 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2848 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2849 }
6af0bf9c
FB
2850 opn = "maddu";
2851 break;
2852 case OPC_MSUB:
214c465f 2853 {
d45f89f4
AJ
2854 TCGv_i64 t2 = tcg_temp_new_i64();
2855 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2856 acc = ((ctx->opcode) >> 11) & 0x03;
2857 if (acc != 0) {
2858 check_dsp(ctx);
2859 }
d45f89f4
AJ
2860
2861 tcg_gen_ext_tl_i64(t2, t0);
2862 tcg_gen_ext_tl_i64(t3, t1);
2863 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2864 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2865 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2866 tcg_temp_free_i64(t3);
2867 tcg_gen_trunc_i64_tl(t0, t2);
2868 tcg_gen_shri_i64(t2, t2, 32);
2869 tcg_gen_trunc_i64_tl(t1, t2);
2870 tcg_temp_free_i64(t2);
4133498f
JL
2871 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2872 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2873 }
6af0bf9c
FB
2874 opn = "msub";
2875 break;
2876 case OPC_MSUBU:
214c465f 2877 {
d45f89f4
AJ
2878 TCGv_i64 t2 = tcg_temp_new_i64();
2879 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2880 acc = ((ctx->opcode) >> 11) & 0x03;
2881 if (acc != 0) {
2882 check_dsp(ctx);
2883 }
214c465f 2884
78723684
TS
2885 tcg_gen_ext32u_tl(t0, t0);
2886 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2887 tcg_gen_extu_tl_i64(t2, t0);
2888 tcg_gen_extu_tl_i64(t3, t1);
2889 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2890 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2891 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2892 tcg_temp_free_i64(t3);
2893 tcg_gen_trunc_i64_tl(t0, t2);
2894 tcg_gen_shri_i64(t2, t2, 32);
2895 tcg_gen_trunc_i64_tl(t1, t2);
2896 tcg_temp_free_i64(t2);
4133498f
JL
2897 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2898 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2899 }
6af0bf9c
FB
2900 opn = "msubu";
2901 break;
2902 default:
923617a3 2903 MIPS_INVAL(opn);
6af0bf9c 2904 generate_exception(ctx, EXCP_RI);
78723684 2905 goto out;
6af0bf9c 2906 }
2abf314d 2907 (void)opn; /* avoid a compiler warning */
6af0bf9c 2908 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2909 out:
2910 tcg_temp_free(t0);
2911 tcg_temp_free(t1);
6af0bf9c
FB
2912}
2913
e9c71dd1
TS
2914static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2915 int rd, int rs, int rt)
2916{
2917 const char *opn = "mul vr54xx";
f157bfe1
AJ
2918 TCGv t0 = tcg_temp_new();
2919 TCGv t1 = tcg_temp_new();
e9c71dd1 2920
6c5c1e20
TS
2921 gen_load_gpr(t0, rs);
2922 gen_load_gpr(t1, rt);
e9c71dd1
TS
2923
2924 switch (opc) {
2925 case OPC_VR54XX_MULS:
895c2d04 2926 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2927 opn = "muls";
6958549d 2928 break;
e9c71dd1 2929 case OPC_VR54XX_MULSU:
895c2d04 2930 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2931 opn = "mulsu";
6958549d 2932 break;
e9c71dd1 2933 case OPC_VR54XX_MACC:
895c2d04 2934 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2935 opn = "macc";
6958549d 2936 break;
e9c71dd1 2937 case OPC_VR54XX_MACCU:
895c2d04 2938 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2939 opn = "maccu";
6958549d 2940 break;
e9c71dd1 2941 case OPC_VR54XX_MSAC:
895c2d04 2942 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2943 opn = "msac";
6958549d 2944 break;
e9c71dd1 2945 case OPC_VR54XX_MSACU:
895c2d04 2946 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2947 opn = "msacu";
6958549d 2948 break;
e9c71dd1 2949 case OPC_VR54XX_MULHI:
895c2d04 2950 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2951 opn = "mulhi";
6958549d 2952 break;
e9c71dd1 2953 case OPC_VR54XX_MULHIU:
895c2d04 2954 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2955 opn = "mulhiu";
6958549d 2956 break;
e9c71dd1 2957 case OPC_VR54XX_MULSHI:
895c2d04 2958 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2959 opn = "mulshi";
6958549d 2960 break;
e9c71dd1 2961 case OPC_VR54XX_MULSHIU:
895c2d04 2962 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2963 opn = "mulshiu";
6958549d 2964 break;
e9c71dd1 2965 case OPC_VR54XX_MACCHI:
895c2d04 2966 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2967 opn = "macchi";
6958549d 2968 break;
e9c71dd1 2969 case OPC_VR54XX_MACCHIU:
895c2d04 2970 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2971 opn = "macchiu";
6958549d 2972 break;
e9c71dd1 2973 case OPC_VR54XX_MSACHI:
895c2d04 2974 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2975 opn = "msachi";
6958549d 2976 break;
e9c71dd1 2977 case OPC_VR54XX_MSACHIU:
895c2d04 2978 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2979 opn = "msachiu";
6958549d 2980 break;
e9c71dd1
TS
2981 default:
2982 MIPS_INVAL("mul vr54xx");
2983 generate_exception(ctx, EXCP_RI);
6c5c1e20 2984 goto out;
e9c71dd1 2985 }
6c5c1e20 2986 gen_store_gpr(t0, rd);
2abf314d 2987 (void)opn; /* avoid a compiler warning */
e9c71dd1 2988 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2989
2990 out:
2991 tcg_temp_free(t0);
2992 tcg_temp_free(t1);
e9c71dd1
TS
2993}
2994
7a387fff 2995static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2996 int rd, int rs)
2997{
923617a3 2998 const char *opn = "CLx";
20e1fb52 2999 TCGv t0;
6c5c1e20 3000
6af0bf9c 3001 if (rd == 0) {
ead9360e 3002 /* Treat as NOP. */
6af0bf9c 3003 MIPS_DEBUG("NOP");
20e1fb52 3004 return;
6af0bf9c 3005 }
20e1fb52 3006 t0 = tcg_temp_new();
6c5c1e20 3007 gen_load_gpr(t0, rs);
6af0bf9c
FB
3008 switch (opc) {
3009 case OPC_CLO:
20e1fb52 3010 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3011 opn = "clo";
3012 break;
3013 case OPC_CLZ:
20e1fb52 3014 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3015 opn = "clz";
3016 break;
d26bc211 3017#if defined(TARGET_MIPS64)
7a387fff 3018 case OPC_DCLO:
20e1fb52 3019 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3020 opn = "dclo";
3021 break;
3022 case OPC_DCLZ:
20e1fb52 3023 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3024 opn = "dclz";
3025 break;
3026#endif
6af0bf9c 3027 }
2abf314d 3028 (void)opn; /* avoid a compiler warning */
6af0bf9c 3029 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3030 tcg_temp_free(t0);
6af0bf9c
FB
3031}
3032
161f85e6 3033/* Godson integer instructions */
bd277fa1
RH
3034static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3035 int rd, int rs, int rt)
161f85e6
AJ
3036{
3037 const char *opn = "loongson";
3038 TCGv t0, t1;
3039
3040 if (rd == 0) {
3041 /* Treat as NOP. */
3042 MIPS_DEBUG("NOP");
3043 return;
3044 }
3045
3046 switch (opc) {
3047 case OPC_MULT_G_2E:
3048 case OPC_MULT_G_2F:
3049 case OPC_MULTU_G_2E:
3050 case OPC_MULTU_G_2F:
3051#if defined(TARGET_MIPS64)
3052 case OPC_DMULT_G_2E:
3053 case OPC_DMULT_G_2F:
3054 case OPC_DMULTU_G_2E:
3055 case OPC_DMULTU_G_2F:
3056#endif
3057 t0 = tcg_temp_new();
3058 t1 = tcg_temp_new();
3059 break;
3060 default:
3061 t0 = tcg_temp_local_new();
3062 t1 = tcg_temp_local_new();
3063 break;
3064 }
3065
3066 gen_load_gpr(t0, rs);
3067 gen_load_gpr(t1, rt);
3068
3069 switch (opc) {
3070 case OPC_MULT_G_2E:
3071 case OPC_MULT_G_2F:
3072 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3073 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3074 opn = "mult.g";
3075 break;
3076 case OPC_MULTU_G_2E:
3077 case OPC_MULTU_G_2F:
3078 tcg_gen_ext32u_tl(t0, t0);
3079 tcg_gen_ext32u_tl(t1, t1);
3080 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3081 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3082 opn = "multu.g";
3083 break;
3084 case OPC_DIV_G_2E:
3085 case OPC_DIV_G_2F:
3086 {
3087 int l1 = gen_new_label();
3088 int l2 = gen_new_label();
3089 int l3 = gen_new_label();
3090 tcg_gen_ext32s_tl(t0, t0);
3091 tcg_gen_ext32s_tl(t1, t1);
3092 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3093 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3094 tcg_gen_br(l3);
3095 gen_set_label(l1);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3097 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3098 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3099 tcg_gen_br(l3);
3100 gen_set_label(l2);
3101 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3102 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3103 gen_set_label(l3);
3104 }
3105 opn = "div.g";
3106 break;
3107 case OPC_DIVU_G_2E:
3108 case OPC_DIVU_G_2F:
3109 {
3110 int l1 = gen_new_label();
3111 int l2 = gen_new_label();
3112 tcg_gen_ext32u_tl(t0, t0);
3113 tcg_gen_ext32u_tl(t1, t1);
3114 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3115 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3116 tcg_gen_br(l2);
3117 gen_set_label(l1);
3118 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3119 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3120 gen_set_label(l2);
3121 }
3122 opn = "divu.g";
3123 break;
3124 case OPC_MOD_G_2E:
3125 case OPC_MOD_G_2F:
3126 {
3127 int l1 = gen_new_label();
3128 int l2 = gen_new_label();
3129 int l3 = gen_new_label();
3130 tcg_gen_ext32u_tl(t0, t0);
3131 tcg_gen_ext32u_tl(t1, t1);
3132 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3133 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3134 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3135 gen_set_label(l1);
3136 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3137 tcg_gen_br(l3);
3138 gen_set_label(l2);
3139 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3140 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3141 gen_set_label(l3);
3142 }
3143 opn = "mod.g";
3144 break;
3145 case OPC_MODU_G_2E:
3146 case OPC_MODU_G_2F:
3147 {
3148 int l1 = gen_new_label();
3149 int l2 = gen_new_label();
3150 tcg_gen_ext32u_tl(t0, t0);
3151 tcg_gen_ext32u_tl(t1, t1);
3152 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3153 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3154 tcg_gen_br(l2);
3155 gen_set_label(l1);
3156 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3157 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3158 gen_set_label(l2);
3159 }
3160 opn = "modu.g";
3161 break;
3162#if defined(TARGET_MIPS64)
3163 case OPC_DMULT_G_2E:
3164 case OPC_DMULT_G_2F:
3165 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3166 opn = "dmult.g";
3167 break;
3168 case OPC_DMULTU_G_2E:
3169 case OPC_DMULTU_G_2F:
3170 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3171 opn = "dmultu.g";
3172 break;
3173 case OPC_DDIV_G_2E:
3174 case OPC_DDIV_G_2F:
3175 {
3176 int l1 = gen_new_label();
3177 int l2 = gen_new_label();
3178 int l3 = gen_new_label();
3179 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3180 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3181 tcg_gen_br(l3);
3182 gen_set_label(l1);
3183 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3184 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3185 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3186 tcg_gen_br(l3);
3187 gen_set_label(l2);
3188 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3189 gen_set_label(l3);
3190 }
3191 opn = "ddiv.g";
3192 break;
3193 case OPC_DDIVU_G_2E:
3194 case OPC_DDIVU_G_2F:
3195 {
3196 int l1 = gen_new_label();
3197 int l2 = gen_new_label();
3198 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3199 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3200 tcg_gen_br(l2);
3201 gen_set_label(l1);
3202 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3203 gen_set_label(l2);
3204 }
3205 opn = "ddivu.g";
3206 break;
3207 case OPC_DMOD_G_2E:
3208 case OPC_DMOD_G_2F:
3209 {
3210 int l1 = gen_new_label();
3211 int l2 = gen_new_label();
3212 int l3 = gen_new_label();
3213 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3214 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3215 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3216 gen_set_label(l1);
3217 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3218 tcg_gen_br(l3);
3219 gen_set_label(l2);
3220 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3221 gen_set_label(l3);
3222 }
3223 opn = "dmod.g";
3224 break;
3225 case OPC_DMODU_G_2E:
3226 case OPC_DMODU_G_2F:
3227 {
3228 int l1 = gen_new_label();
3229 int l2 = gen_new_label();
3230 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3231 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3232 tcg_gen_br(l2);
3233 gen_set_label(l1);
3234 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3235 gen_set_label(l2);
3236 }
3237 opn = "dmodu.g";
3238 break;
3239#endif
3240 }
3241
2abf314d 3242 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3243 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3244 tcg_temp_free(t0);
3245 tcg_temp_free(t1);
3246}
3247
bd277fa1
RH
3248/* Loongson multimedia instructions */
3249static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3250{
3251 const char *opn = "loongson_cp2";
3252 uint32_t opc, shift_max;
3253 TCGv_i64 t0, t1;
3254
3255 opc = MASK_LMI(ctx->opcode);
3256 switch (opc) {
3257 case OPC_ADD_CP2:
3258 case OPC_SUB_CP2:
3259 case OPC_DADD_CP2:
3260 case OPC_DSUB_CP2:
3261 t0 = tcg_temp_local_new_i64();
3262 t1 = tcg_temp_local_new_i64();
3263 break;
3264 default:
3265 t0 = tcg_temp_new_i64();
3266 t1 = tcg_temp_new_i64();
3267 break;
3268 }
3269
3270 gen_load_fpr64(ctx, t0, rs);
3271 gen_load_fpr64(ctx, t1, rt);
3272
3273#define LMI_HELPER(UP, LO) \
3274 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3275#define LMI_HELPER_1(UP, LO) \
3276 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3277#define LMI_DIRECT(UP, LO, OP) \
3278 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3279
3280 switch (opc) {
3281 LMI_HELPER(PADDSH, paddsh);
3282 LMI_HELPER(PADDUSH, paddush);
3283 LMI_HELPER(PADDH, paddh);
3284 LMI_HELPER(PADDW, paddw);
3285 LMI_HELPER(PADDSB, paddsb);
3286 LMI_HELPER(PADDUSB, paddusb);
3287 LMI_HELPER(PADDB, paddb);
3288
3289 LMI_HELPER(PSUBSH, psubsh);
3290 LMI_HELPER(PSUBUSH, psubush);
3291 LMI_HELPER(PSUBH, psubh);
3292 LMI_HELPER(PSUBW, psubw);
3293 LMI_HELPER(PSUBSB, psubsb);
3294 LMI_HELPER(PSUBUSB, psubusb);
3295 LMI_HELPER(PSUBB, psubb);
3296
3297 LMI_HELPER(PSHUFH, pshufh);
3298 LMI_HELPER(PACKSSWH, packsswh);
3299 LMI_HELPER(PACKSSHB, packsshb);
3300 LMI_HELPER(PACKUSHB, packushb);
3301
3302 LMI_HELPER(PUNPCKLHW, punpcklhw);
3303 LMI_HELPER(PUNPCKHHW, punpckhhw);
3304 LMI_HELPER(PUNPCKLBH, punpcklbh);
3305 LMI_HELPER(PUNPCKHBH, punpckhbh);
3306 LMI_HELPER(PUNPCKLWD, punpcklwd);
3307 LMI_HELPER(PUNPCKHWD, punpckhwd);
3308
3309 LMI_HELPER(PAVGH, pavgh);
3310 LMI_HELPER(PAVGB, pavgb);
3311 LMI_HELPER(PMAXSH, pmaxsh);
3312 LMI_HELPER(PMINSH, pminsh);
3313 LMI_HELPER(PMAXUB, pmaxub);
3314 LMI_HELPER(PMINUB, pminub);
3315
3316 LMI_HELPER(PCMPEQW, pcmpeqw);
3317 LMI_HELPER(PCMPGTW, pcmpgtw);
3318 LMI_HELPER(PCMPEQH, pcmpeqh);
3319 LMI_HELPER(PCMPGTH, pcmpgth);
3320 LMI_HELPER(PCMPEQB, pcmpeqb);
3321 LMI_HELPER(PCMPGTB, pcmpgtb);
3322
3323 LMI_HELPER(PSLLW, psllw);
3324 LMI_HELPER(PSLLH, psllh);
3325 LMI_HELPER(PSRLW, psrlw);
3326 LMI_HELPER(PSRLH, psrlh);
3327 LMI_HELPER(PSRAW, psraw);
3328 LMI_HELPER(PSRAH, psrah);
3329
3330 LMI_HELPER(PMULLH, pmullh);
3331 LMI_HELPER(PMULHH, pmulhh);
3332 LMI_HELPER(PMULHUH, pmulhuh);
3333 LMI_HELPER(PMADDHW, pmaddhw);
3334
3335 LMI_HELPER(PASUBUB, pasubub);
3336 LMI_HELPER_1(BIADD, biadd);
3337 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3338
3339 LMI_DIRECT(PADDD, paddd, add);
3340 LMI_DIRECT(PSUBD, psubd, sub);
3341 LMI_DIRECT(XOR_CP2, xor, xor);
3342 LMI_DIRECT(NOR_CP2, nor, nor);
3343 LMI_DIRECT(AND_CP2, and, and);
3344 LMI_DIRECT(PANDN, pandn, andc);
3345 LMI_DIRECT(OR, or, or);
3346
3347 case OPC_PINSRH_0:
3348 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3349 opn = "pinsrh_0";
3350 break;
3351 case OPC_PINSRH_1:
3352 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3353 opn = "pinsrh_1";
3354 break;
3355 case OPC_PINSRH_2:
3356 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3357 opn = "pinsrh_2";
3358 break;
3359 case OPC_PINSRH_3:
3360 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3361 opn = "pinsrh_3";
3362 break;
3363
3364 case OPC_PEXTRH:
3365 tcg_gen_andi_i64(t1, t1, 3);
3366 tcg_gen_shli_i64(t1, t1, 4);
3367 tcg_gen_shr_i64(t0, t0, t1);
3368 tcg_gen_ext16u_i64(t0, t0);
3369 opn = "pextrh";
3370 break;
3371
3372 case OPC_ADDU_CP2:
3373 tcg_gen_add_i64(t0, t0, t1);
3374 tcg_gen_ext32s_i64(t0, t0);
3375 opn = "addu";
3376 break;
3377 case OPC_SUBU_CP2:
3378 tcg_gen_sub_i64(t0, t0, t1);
3379 tcg_gen_ext32s_i64(t0, t0);
3380 opn = "addu";
3381 break;
3382
3383 case OPC_SLL_CP2:
3384 opn = "sll";
3385 shift_max = 32;
3386 goto do_shift;
3387 case OPC_SRL_CP2:
3388 opn = "srl";
3389 shift_max = 32;
3390 goto do_shift;
3391 case OPC_SRA_CP2:
3392 opn = "sra";
3393 shift_max = 32;
3394 goto do_shift;
3395 case OPC_DSLL_CP2:
3396 opn = "dsll";
3397 shift_max = 64;
3398 goto do_shift;
3399 case OPC_DSRL_CP2:
3400 opn = "dsrl";
3401 shift_max = 64;
3402 goto do_shift;
3403 case OPC_DSRA_CP2:
3404 opn = "dsra";
3405 shift_max = 64;
3406 goto do_shift;
3407 do_shift:
3408 /* Make sure shift count isn't TCG undefined behaviour. */
3409 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3410
3411 switch (opc) {
3412 case OPC_SLL_CP2:
3413 case OPC_DSLL_CP2:
3414 tcg_gen_shl_i64(t0, t0, t1);
3415 break;
3416 case OPC_SRA_CP2:
3417 case OPC_DSRA_CP2:
3418 /* Since SRA is UndefinedResult without sign-extended inputs,
3419 we can treat SRA and DSRA the same. */
3420 tcg_gen_sar_i64(t0, t0, t1);
3421 break;
3422 case OPC_SRL_CP2:
3423 /* We want to shift in zeros for SRL; zero-extend first. */
3424 tcg_gen_ext32u_i64(t0, t0);
3425 /* FALLTHRU */
3426 case OPC_DSRL_CP2:
3427 tcg_gen_shr_i64(t0, t0, t1);
3428 break;
3429 }
3430
3431 if (shift_max == 32) {
3432 tcg_gen_ext32s_i64(t0, t0);
3433 }
3434
3435 /* Shifts larger than MAX produce zero. */
3436 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3437 tcg_gen_neg_i64(t1, t1);
3438 tcg_gen_and_i64(t0, t0, t1);
3439 break;
3440
3441 case OPC_ADD_CP2:
3442 case OPC_DADD_CP2:
3443 {
3444 TCGv_i64 t2 = tcg_temp_new_i64();
3445 int lab = gen_new_label();
3446
3447 tcg_gen_mov_i64(t2, t0);
3448 tcg_gen_add_i64(t0, t1, t2);
3449 if (opc == OPC_ADD_CP2) {
3450 tcg_gen_ext32s_i64(t0, t0);
3451 }
3452 tcg_gen_xor_i64(t1, t1, t2);
3453 tcg_gen_xor_i64(t2, t2, t0);
3454 tcg_gen_andc_i64(t1, t2, t1);
3455 tcg_temp_free_i64(t2);
3456 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3457 generate_exception(ctx, EXCP_OVERFLOW);
3458 gen_set_label(lab);
3459
3460 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3461 break;
3462 }
3463
3464 case OPC_SUB_CP2:
3465 case OPC_DSUB_CP2:
3466 {
3467 TCGv_i64 t2 = tcg_temp_new_i64();
3468 int lab = gen_new_label();
3469
3470 tcg_gen_mov_i64(t2, t0);
3471 tcg_gen_sub_i64(t0, t1, t2);
3472 if (opc == OPC_SUB_CP2) {
3473 tcg_gen_ext32s_i64(t0, t0);
3474 }
3475 tcg_gen_xor_i64(t1, t1, t2);
3476 tcg_gen_xor_i64(t2, t2, t0);
3477 tcg_gen_and_i64(t1, t1, t2);
3478 tcg_temp_free_i64(t2);
3479 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3480 generate_exception(ctx, EXCP_OVERFLOW);
3481 gen_set_label(lab);
3482
3483 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3484 break;
3485 }
3486
3487 case OPC_PMULUW:
3488 tcg_gen_ext32u_i64(t0, t0);
3489 tcg_gen_ext32u_i64(t1, t1);
3490 tcg_gen_mul_i64(t0, t0, t1);
3491 opn = "pmuluw";
3492 break;
3493
3494 case OPC_SEQU_CP2:
3495 case OPC_SEQ_CP2:
3496 case OPC_SLTU_CP2:
3497 case OPC_SLT_CP2:
3498 case OPC_SLEU_CP2:
3499 case OPC_SLE_CP2:
3500 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3501 FD field is the CC field? */
3502 default:
3503 MIPS_INVAL(opn);
3504 generate_exception(ctx, EXCP_RI);
3505 return;
3506 }
3507
3508#undef LMI_HELPER
3509#undef LMI_DIRECT
3510
3511 gen_store_fpr64(ctx, t0, rd);
3512
3513 (void)opn; /* avoid a compiler warning */
3514 MIPS_DEBUG("%s %s, %s, %s", opn,
3515 fregnames[rd], fregnames[rs], fregnames[rt]);
3516 tcg_temp_free_i64(t0);
3517 tcg_temp_free_i64(t1);
3518}
3519
6af0bf9c 3520/* Traps */
7a387fff 3521static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3522 int rs, int rt, int16_t imm)
3523{
3524 int cond;
cdc0faa6 3525 TCGv t0 = tcg_temp_new();
1ba74fb8 3526 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3527
3528 cond = 0;
3529 /* Load needed operands */
3530 switch (opc) {
3531 case OPC_TEQ:
3532 case OPC_TGE:
3533 case OPC_TGEU:
3534 case OPC_TLT:
3535 case OPC_TLTU:
3536 case OPC_TNE:
3537 /* Compare two registers */
3538 if (rs != rt) {
be24bb4f
TS
3539 gen_load_gpr(t0, rs);
3540 gen_load_gpr(t1, rt);
6af0bf9c
FB
3541 cond = 1;
3542 }
179e32bb 3543 break;
6af0bf9c
FB
3544 case OPC_TEQI:
3545 case OPC_TGEI:
3546 case OPC_TGEIU:
3547 case OPC_TLTI:
3548 case OPC_TLTIU:
3549 case OPC_TNEI:
3550 /* Compare register to immediate */
3551 if (rs != 0 || imm != 0) {
be24bb4f
TS
3552 gen_load_gpr(t0, rs);
3553 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3554 cond = 1;
3555 }
3556 break;
3557 }
3558 if (cond == 0) {
3559 switch (opc) {
3560 case OPC_TEQ: /* rs == rs */
3561 case OPC_TEQI: /* r0 == 0 */
3562 case OPC_TGE: /* rs >= rs */
3563 case OPC_TGEI: /* r0 >= 0 */
3564 case OPC_TGEU: /* rs >= rs unsigned */
3565 case OPC_TGEIU: /* r0 >= 0 unsigned */
3566 /* Always trap */
cdc0faa6 3567 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3568 break;
3569 case OPC_TLT: /* rs < rs */
3570 case OPC_TLTI: /* r0 < 0 */
3571 case OPC_TLTU: /* rs < rs unsigned */
3572 case OPC_TLTIU: /* r0 < 0 unsigned */
3573 case OPC_TNE: /* rs != rs */
3574 case OPC_TNEI: /* r0 != 0 */
ead9360e 3575 /* Never trap: treat as NOP. */
cdc0faa6 3576 break;
6af0bf9c
FB
3577 }
3578 } else {
cdc0faa6
AJ
3579 int l1 = gen_new_label();
3580
6af0bf9c
FB
3581 switch (opc) {
3582 case OPC_TEQ:
3583 case OPC_TEQI:
cdc0faa6 3584 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3585 break;
3586 case OPC_TGE:
3587 case OPC_TGEI:
cdc0faa6 3588 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3589 break;
3590 case OPC_TGEU:
3591 case OPC_TGEIU:
cdc0faa6 3592 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3593 break;
3594 case OPC_TLT:
3595 case OPC_TLTI:
cdc0faa6 3596 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3597 break;
3598 case OPC_TLTU:
3599 case OPC_TLTIU:
cdc0faa6 3600 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3601 break;
3602 case OPC_TNE:
3603 case OPC_TNEI:
cdc0faa6 3604 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3605 break;
6af0bf9c 3606 }
cdc0faa6 3607 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3608 gen_set_label(l1);
3609 }
be24bb4f
TS
3610 tcg_temp_free(t0);
3611 tcg_temp_free(t1);
6af0bf9c
FB
3612}
3613
356265ae 3614static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3615{
6e256c93
FB
3616 TranslationBlock *tb;
3617 tb = ctx->tb;
7b270ef2
NF
3618 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3619 likely(!ctx->singlestep_enabled)) {
57fec1fe 3620 tcg_gen_goto_tb(n);
9b9e4393 3621 gen_save_pc(dest);
4b4a72e5 3622 tcg_gen_exit_tb((tcg_target_long)tb + n);
6e256c93 3623 } else {
9b9e4393 3624 gen_save_pc(dest);
7b270ef2
NF
3625 if (ctx->singlestep_enabled) {
3626 save_cpu_state(ctx, 0);
895c2d04 3627 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3628 }
57fec1fe 3629 tcg_gen_exit_tb(0);
6e256c93 3630 }
c53be334
FB
3631}
3632
6af0bf9c 3633/* Branches (before delay slot) */
7a387fff 3634static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3635 int insn_bytes,
6af0bf9c
FB
3636 int rs, int rt, int32_t offset)
3637{
d077b6f7 3638 target_ulong btgt = -1;
3ad4bb2d 3639 int blink = 0;
2fdbad25 3640 int bcond_compute = 0;
1ba74fb8
AJ
3641 TCGv t0 = tcg_temp_new();
3642 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3643
3644 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3645#ifdef MIPS_DEBUG_DISAS
d12d51d5 3646 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3647#endif
3ad4bb2d 3648 generate_exception(ctx, EXCP_RI);
6c5c1e20 3649 goto out;
3ad4bb2d 3650 }
6af0bf9c 3651
6af0bf9c
FB
3652 /* Load needed operands */
3653 switch (opc) {
3654 case OPC_BEQ:
3655 case OPC_BEQL:
3656 case OPC_BNE:
3657 case OPC_BNEL:
3658 /* Compare two registers */
3659 if (rs != rt) {
6c5c1e20
TS
3660 gen_load_gpr(t0, rs);
3661 gen_load_gpr(t1, rt);
2fdbad25 3662 bcond_compute = 1;
6af0bf9c 3663 }
7dca4ad0 3664 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3665 break;
3666 case OPC_BGEZ:
3667 case OPC_BGEZAL:
3c824109 3668 case OPC_BGEZALS:
6af0bf9c
FB
3669 case OPC_BGEZALL:
3670 case OPC_BGEZL:
3671 case OPC_BGTZ:
3672 case OPC_BGTZL:
3673 case OPC_BLEZ:
3674 case OPC_BLEZL:
3675 case OPC_BLTZ:
3676 case OPC_BLTZAL:
3c824109 3677 case OPC_BLTZALS:
6af0bf9c
FB
3678 case OPC_BLTZALL:
3679 case OPC_BLTZL:
3680 /* Compare to zero */
3681 if (rs != 0) {
6c5c1e20 3682 gen_load_gpr(t0, rs);
2fdbad25 3683 bcond_compute = 1;
6af0bf9c 3684 }
7dca4ad0 3685 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3686 break;
e45a93e2
JL
3687 case OPC_BPOSGE32:
3688#if defined(TARGET_MIPS64)
3689 case OPC_BPOSGE64:
3690 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3691#else
3692 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3693#endif
3694 bcond_compute = 1;
3695 btgt = ctx->pc + insn_bytes + offset;
3696 break;
6af0bf9c
FB
3697 case OPC_J:
3698 case OPC_JAL:
364d4831 3699 case OPC_JALX:
620e48f6
NF
3700 case OPC_JALS:
3701 case OPC_JALXS:
6af0bf9c 3702 /* Jump to immediate */
7dca4ad0 3703 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3704 break;
3705 case OPC_JR:
3706 case OPC_JALR:
364d4831 3707 case OPC_JALRC:
620e48f6 3708 case OPC_JALRS:
6af0bf9c 3709 /* Jump to register */
7a387fff
TS
3710 if (offset != 0 && offset != 16) {
3711 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3712 others are reserved. */
923617a3 3713 MIPS_INVAL("jump hint");
6af0bf9c 3714 generate_exception(ctx, EXCP_RI);
6c5c1e20 3715 goto out;
6af0bf9c 3716 }
d077b6f7 3717 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3718 break;
3719 default:
3720 MIPS_INVAL("branch/jump");
3721 generate_exception(ctx, EXCP_RI);
6c5c1e20 3722 goto out;
6af0bf9c 3723 }
2fdbad25 3724 if (bcond_compute == 0) {
6af0bf9c
FB
3725 /* No condition to be computed */
3726 switch (opc) {
3727 case OPC_BEQ: /* rx == rx */
3728 case OPC_BEQL: /* rx == rx likely */
3729 case OPC_BGEZ: /* 0 >= 0 */
3730 case OPC_BGEZL: /* 0 >= 0 likely */
3731 case OPC_BLEZ: /* 0 <= 0 */
3732 case OPC_BLEZL: /* 0 <= 0 likely */
3733 /* Always take */
4ad40f36 3734 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3735 MIPS_DEBUG("balways");
3736 break;
3c824109 3737 case OPC_BGEZALS:
6af0bf9c
FB
3738 case OPC_BGEZAL: /* 0 >= 0 */
3739 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3740 ctx->hflags |= (opc == OPC_BGEZALS
3741 ? MIPS_HFLAG_BDS16
3742 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3743 /* Always take and link */
3744 blink = 31;
4ad40f36 3745 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3746 MIPS_DEBUG("balways and link");
3747 break;
3748 case OPC_BNE: /* rx != rx */
3749 case OPC_BGTZ: /* 0 > 0 */
3750 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3751 /* Treat as NOP. */
6af0bf9c 3752 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3753 goto out;
3c824109 3754 case OPC_BLTZALS:
eeef26cd 3755 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3756 ctx->hflags |= (opc == OPC_BLTZALS
3757 ? MIPS_HFLAG_BDS16
3758 : MIPS_HFLAG_BDS32);
3759 /* Handle as an unconditional branch to get correct delay
3760 slot checking. */
3761 blink = 31;
3762 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3763 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3764 MIPS_DEBUG("bnever and link");
3c824109 3765 break;
eeef26cd 3766 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3767 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3768 /* Skip the instruction in the delay slot */
3769 MIPS_DEBUG("bnever, link and skip");
3770 ctx->pc += 4;
6c5c1e20 3771 goto out;
6af0bf9c
FB
3772 case OPC_BNEL: /* rx != rx likely */
3773 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3774 case OPC_BLTZL: /* 0 < 0 likely */
3775 /* Skip the instruction in the delay slot */
3776 MIPS_DEBUG("bnever and skip");
9898128f 3777 ctx->pc += 4;
6c5c1e20 3778 goto out;
6af0bf9c 3779 case OPC_J:
4ad40f36 3780 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3781 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3782 break;
620e48f6 3783 case OPC_JALXS:
364d4831
NF
3784 case OPC_JALX:
3785 ctx->hflags |= MIPS_HFLAG_BX;
3786 /* Fallthrough */
620e48f6 3787 case OPC_JALS:
6af0bf9c
FB
3788 case OPC_JAL:
3789 blink = 31;
4ad40f36 3790 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3791 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3792 ? MIPS_HFLAG_BDS16
3793 : MIPS_HFLAG_BDS32);
d077b6f7 3794 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3795 break;
3796 case OPC_JR:
4ad40f36 3797 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3798 if (insn_bytes == 4)
3799 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3800 MIPS_DEBUG("jr %s", regnames[rs]);
3801 break;
620e48f6 3802 case OPC_JALRS:
6af0bf9c 3803 case OPC_JALR:
364d4831 3804 case OPC_JALRC:
6af0bf9c 3805 blink = rt;
4ad40f36 3806 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3807 ctx->hflags |= (opc == OPC_JALRS
3808 ? MIPS_HFLAG_BDS16
3809 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3810 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3811 break;
3812 default:
3813 MIPS_INVAL("branch/jump");
3814 generate_exception(ctx, EXCP_RI);
6c5c1e20 3815 goto out;
6af0bf9c
FB
3816 }
3817 } else {
3818 switch (opc) {
3819 case OPC_BEQ:
e68dd28f 3820 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3821 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3822 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3823 goto not_likely;
3824 case OPC_BEQL:
e68dd28f 3825 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3826 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3827 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3828 goto likely;
3829 case OPC_BNE:
e68dd28f 3830 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3831 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3832 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3833 goto not_likely;
3834 case OPC_BNEL:
e68dd28f 3835 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3836 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3837 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3838 goto likely;
3839 case OPC_BGEZ:
e68dd28f 3840 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3841 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3842 goto not_likely;
3843 case OPC_BGEZL:
e68dd28f 3844 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3845 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3846 goto likely;
3c824109 3847 case OPC_BGEZALS:
6af0bf9c 3848 case OPC_BGEZAL:
3c824109
NF
3849 ctx->hflags |= (opc == OPC_BGEZALS
3850 ? MIPS_HFLAG_BDS16
3851 : MIPS_HFLAG_BDS32);
e68dd28f 3852 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3853 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3854 blink = 31;
3855 goto not_likely;
3856 case OPC_BGEZALL:
e68dd28f 3857 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3858 blink = 31;
d077b6f7 3859 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3860 goto likely;
3861 case OPC_BGTZ:
e68dd28f 3862 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3863 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3864 goto not_likely;
3865 case OPC_BGTZL:
e68dd28f 3866 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3867 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3868 goto likely;
3869 case OPC_BLEZ:
e68dd28f 3870 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3871 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3872 goto not_likely;
3873 case OPC_BLEZL:
e68dd28f 3874 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3875 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3876 goto likely;
3877 case OPC_BLTZ:
e68dd28f 3878 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3879 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3880 goto not_likely;
3881 case OPC_BLTZL:
e68dd28f 3882 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3883 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3884 goto likely;
e45a93e2
JL
3885 case OPC_BPOSGE32:
3886 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3887 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3888 goto not_likely;
3889#if defined(TARGET_MIPS64)
3890 case OPC_BPOSGE64:
3891 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3892 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3893 goto not_likely;
3894#endif
3c824109 3895 case OPC_BLTZALS:
6af0bf9c 3896 case OPC_BLTZAL:
3c824109
NF
3897 ctx->hflags |= (opc == OPC_BLTZALS
3898 ? MIPS_HFLAG_BDS16
3899 : MIPS_HFLAG_BDS32);
e68dd28f 3900 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3901 blink = 31;
d077b6f7 3902 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3903 not_likely:
4ad40f36 3904 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3905 break;
3906 case OPC_BLTZALL:
e68dd28f 3907 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3908 blink = 31;
d077b6f7 3909 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3910 likely:
4ad40f36 3911 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3912 break;
c53f4a62
TS
3913 default:
3914 MIPS_INVAL("conditional branch/jump");
3915 generate_exception(ctx, EXCP_RI);
6c5c1e20 3916 goto out;
6af0bf9c 3917 }
6af0bf9c 3918 }
923617a3 3919 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3920 blink, ctx->hflags, btgt);
9b9e4393 3921
d077b6f7 3922 ctx->btarget = btgt;
6af0bf9c 3923 if (blink > 0) {
364d4831
NF
3924 int post_delay = insn_bytes;
3925 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3926
3927 if (opc != OPC_JALRC)
3928 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3929
3930 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3931 }
6c5c1e20
TS
3932
3933 out:
364d4831
NF
3934 if (insn_bytes == 2)
3935 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3936 tcg_temp_free(t0);
3937 tcg_temp_free(t1);
6af0bf9c
FB
3938}
3939
7a387fff
TS
3940/* special3 bitfield operations */
3941static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3942 int rs, int lsb, int msb)
7a387fff 3943{
a7812ae4
PB
3944 TCGv t0 = tcg_temp_new();
3945 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
3946
3947 gen_load_gpr(t1, rs);
7a387fff
TS
3948 switch (opc) {
3949 case OPC_EXT:
3950 if (lsb + msb > 31)
3951 goto fail;
505ad7c2
AJ
3952 tcg_gen_shri_tl(t0, t1, lsb);
3953 if (msb != 31) {
3954 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3955 } else {
3956 tcg_gen_ext32s_tl(t0, t0);
3957 }
7a387fff 3958 break;
c6d6dd7c 3959#if defined(TARGET_MIPS64)
7a387fff 3960 case OPC_DEXTM:
505ad7c2
AJ
3961 tcg_gen_shri_tl(t0, t1, lsb);
3962 if (msb != 31) {
3963 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3964 }
7a387fff
TS
3965 break;
3966 case OPC_DEXTU:
505ad7c2
AJ
3967 tcg_gen_shri_tl(t0, t1, lsb + 32);
3968 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3969 break;
3970 case OPC_DEXT:
505ad7c2
AJ
3971 tcg_gen_shri_tl(t0, t1, lsb);
3972 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3973 break;
c6d6dd7c 3974#endif
7a387fff
TS
3975 case OPC_INS:
3976 if (lsb > msb)
3977 goto fail;
6c5c1e20 3978 gen_load_gpr(t0, rt);
e0d002f1 3979 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 3980 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3981 break;
c6d6dd7c 3982#if defined(TARGET_MIPS64)
7a387fff 3983 case OPC_DINSM:
6c5c1e20 3984 gen_load_gpr(t0, rt);
e0d002f1 3985 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
3986 break;
3987 case OPC_DINSU:
6c5c1e20 3988 gen_load_gpr(t0, rt);
e0d002f1 3989 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
3990 break;
3991 case OPC_DINS:
6c5c1e20 3992 gen_load_gpr(t0, rt);
e0d002f1 3993 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 3994 break;
c6d6dd7c 3995#endif
7a387fff
TS
3996 default:
3997fail:
3998 MIPS_INVAL("bitops");
3999 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4000 tcg_temp_free(t0);
4001 tcg_temp_free(t1);
7a387fff
TS
4002 return;
4003 }
6c5c1e20
TS
4004 gen_store_gpr(t0, rt);
4005 tcg_temp_free(t0);
4006 tcg_temp_free(t1);
7a387fff
TS
4007}
4008
49bcf33c
AJ
4009static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4010{
3a55fa47 4011 TCGv t0;
49bcf33c 4012
3a55fa47
AJ
4013 if (rd == 0) {
4014 /* If no destination, treat it as a NOP. */
4015 MIPS_DEBUG("NOP");
4016 return;
4017 }
4018
4019 t0 = tcg_temp_new();
4020 gen_load_gpr(t0, rt);
49bcf33c
AJ
4021 switch (op2) {
4022 case OPC_WSBH:
3a55fa47
AJ
4023 {
4024 TCGv t1 = tcg_temp_new();
4025
4026 tcg_gen_shri_tl(t1, t0, 8);
4027 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4028 tcg_gen_shli_tl(t0, t0, 8);
4029 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4030 tcg_gen_or_tl(t0, t0, t1);
4031 tcg_temp_free(t1);
4032 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4033 }
49bcf33c
AJ
4034 break;
4035 case OPC_SEB:
3a55fa47 4036 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4037 break;
4038 case OPC_SEH:
3a55fa47 4039 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4040 break;
4041#if defined(TARGET_MIPS64)
4042 case OPC_DSBH:
3a55fa47
AJ
4043 {
4044 TCGv t1 = tcg_temp_new();
4045
4046 tcg_gen_shri_tl(t1, t0, 8);
4047 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4048 tcg_gen_shli_tl(t0, t0, 8);
4049 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4050 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4051 tcg_temp_free(t1);
4052 }
49bcf33c
AJ
4053 break;
4054 case OPC_DSHD:
3a55fa47
AJ
4055 {
4056 TCGv t1 = tcg_temp_new();
4057
4058 tcg_gen_shri_tl(t1, t0, 16);
4059 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4060 tcg_gen_shli_tl(t0, t0, 16);
4061 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4062 tcg_gen_or_tl(t0, t0, t1);
4063 tcg_gen_shri_tl(t1, t0, 32);
4064 tcg_gen_shli_tl(t0, t0, 32);
4065 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4066 tcg_temp_free(t1);
4067 }
49bcf33c
AJ
4068 break;
4069#endif
4070 default:
4071 MIPS_INVAL("bsfhl");
4072 generate_exception(ctx, EXCP_RI);
4073 tcg_temp_free(t0);
49bcf33c
AJ
4074 return;
4075 }
49bcf33c 4076 tcg_temp_free(t0);
49bcf33c
AJ
4077}
4078
f1aa6320 4079#ifndef CONFIG_USER_ONLY
0eaef5aa 4080/* CP0 (MMU and control) */
d9bea114 4081static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4082{
d9bea114 4083 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4084
d9bea114
AJ
4085 tcg_gen_ld_i32(t0, cpu_env, off);
4086 tcg_gen_ext_i32_tl(arg, t0);
4087 tcg_temp_free_i32(t0);
4f57689a
TS
4088}
4089
d9bea114 4090static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4091{
d9bea114
AJ
4092 tcg_gen_ld_tl(arg, cpu_env, off);
4093 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4094}
4095
d9bea114 4096static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4097{
d9bea114 4098 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4099
d9bea114
AJ
4100 tcg_gen_trunc_tl_i32(t0, arg);
4101 tcg_gen_st_i32(t0, cpu_env, off);
4102 tcg_temp_free_i32(t0);
f1aa6320
TS
4103}
4104
d9bea114 4105static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4106{
d9bea114
AJ
4107 tcg_gen_ext32s_tl(arg, arg);
4108 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4109}
4110
d75c135e 4111static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4112{
7a387fff 4113 const char *rn = "invalid";
873eb012 4114
e189e748 4115 if (sel != 0)
d75c135e 4116 check_insn(ctx, ISA_MIPS32);
e189e748 4117
873eb012
TS
4118 switch (reg) {
4119 case 0:
7a387fff
TS
4120 switch (sel) {
4121 case 0:
7db13fae 4122 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4123 rn = "Index";
4124 break;
4125 case 1:
d75c135e 4126 check_insn(ctx, ASE_MT);
895c2d04 4127 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4128 rn = "MVPControl";
ead9360e 4129 break;
7a387fff 4130 case 2:
d75c135e 4131 check_insn(ctx, ASE_MT);
895c2d04 4132 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4133 rn = "MVPConf0";
ead9360e 4134 break;
7a387fff 4135 case 3:
d75c135e 4136 check_insn(ctx, ASE_MT);
895c2d04 4137 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4138 rn = "MVPConf1";
ead9360e 4139 break;
7a387fff
TS
4140 default:
4141 goto die;
4142 }
873eb012
TS
4143 break;
4144 case 1:
7a387fff
TS
4145 switch (sel) {
4146 case 0:
895c2d04 4147 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4148 rn = "Random";
2423f660 4149 break;
7a387fff 4150 case 1:
d75c135e 4151 check_insn(ctx, ASE_MT);
7db13fae 4152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4153 rn = "VPEControl";
ead9360e 4154 break;
7a387fff 4155 case 2:
d75c135e 4156 check_insn(ctx, ASE_MT);
7db13fae 4157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4158 rn = "VPEConf0";
ead9360e 4159 break;
7a387fff 4160 case 3:
d75c135e 4161 check_insn(ctx, ASE_MT);
7db13fae 4162 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4163 rn = "VPEConf1";
ead9360e 4164 break;
7a387fff 4165 case 4:
d75c135e 4166 check_insn(ctx, ASE_MT);
7db13fae 4167 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4168 rn = "YQMask";
ead9360e 4169 break;
7a387fff 4170 case 5:
d75c135e 4171 check_insn(ctx, ASE_MT);
7db13fae 4172 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4173 rn = "VPESchedule";
ead9360e 4174 break;
7a387fff 4175 case 6:
d75c135e 4176 check_insn(ctx, ASE_MT);
7db13fae 4177 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4178 rn = "VPEScheFBack";
ead9360e 4179 break;
7a387fff 4180 case 7:
d75c135e 4181 check_insn(ctx, ASE_MT);
7db13fae 4182 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4183 rn = "VPEOpt";
ead9360e 4184 break;
7a387fff
TS
4185 default:
4186 goto die;
4187 }
873eb012
TS
4188 break;
4189 case 2:
7a387fff
TS
4190 switch (sel) {
4191 case 0:
7db13fae 4192 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4193 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4194 rn = "EntryLo0";
4195 break;
7a387fff 4196 case 1:
d75c135e 4197 check_insn(ctx, ASE_MT);
895c2d04 4198 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4199 rn = "TCStatus";
ead9360e 4200 break;
7a387fff 4201 case 2:
d75c135e 4202 check_insn(ctx, ASE_MT);
895c2d04 4203 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4204 rn = "TCBind";
ead9360e 4205 break;
7a387fff 4206 case 3:
d75c135e 4207 check_insn(ctx, ASE_MT);
895c2d04 4208 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4209 rn = "TCRestart";
ead9360e 4210 break;
7a387fff 4211 case 4:
d75c135e 4212 check_insn(ctx, ASE_MT);
895c2d04 4213 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4214 rn = "TCHalt";
ead9360e 4215 break;
7a387fff 4216 case 5:
d75c135e 4217 check_insn(ctx, ASE_MT);
895c2d04 4218 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4219 rn = "TCContext";
ead9360e 4220 break;
7a387fff 4221 case 6:
d75c135e 4222 check_insn(ctx, ASE_MT);
895c2d04 4223 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4224 rn = "TCSchedule";
ead9360e 4225 break;
7a387fff 4226 case 7:
d75c135e 4227 check_insn(ctx, ASE_MT);
895c2d04 4228 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4229 rn = "TCScheFBack";
ead9360e 4230 break;
7a387fff
TS
4231 default:
4232 goto die;
4233 }
873eb012
TS
4234 break;
4235 case 3:
7a387fff
TS
4236 switch (sel) {
4237 case 0:
7db13fae 4238 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4239 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4240 rn = "EntryLo1";
4241 break;
7a387fff
TS
4242 default:
4243 goto die;
1579a72e 4244 }
873eb012
TS
4245 break;
4246 case 4:
7a387fff
TS
4247 switch (sel) {
4248 case 0:
7db13fae 4249 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4250 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4251 rn = "Context";
4252 break;
7a387fff 4253 case 1:
d9bea114 4254// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
4255 rn = "ContextConfig";
4256// break;
7a387fff
TS
4257 default:
4258 goto die;
1579a72e 4259 }
873eb012
TS
4260 break;
4261 case 5:
7a387fff
TS
4262 switch (sel) {
4263 case 0:
7db13fae 4264 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4265 rn = "PageMask";
4266 break;
7a387fff 4267 case 1:
d75c135e 4268 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4269 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4270 rn = "PageGrain";
4271 break;
7a387fff
TS
4272 default:
4273 goto die;
1579a72e 4274 }
873eb012
TS
4275 break;
4276 case 6:
7a387fff
TS
4277 switch (sel) {
4278 case 0:
7db13fae 4279 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4280 rn = "Wired";
4281 break;
7a387fff 4282 case 1:
d75c135e 4283 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4285 rn = "SRSConf0";
ead9360e 4286 break;
7a387fff 4287 case 2:
d75c135e 4288 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4289 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4290 rn = "SRSConf1";
ead9360e 4291 break;
7a387fff 4292 case 3:
d75c135e 4293 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4295 rn = "SRSConf2";
ead9360e 4296 break;
7a387fff 4297 case 4:
d75c135e 4298 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4300 rn = "SRSConf3";
ead9360e 4301 break;
7a387fff 4302 case 5:
d75c135e 4303 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4305 rn = "SRSConf4";
ead9360e 4306 break;
7a387fff
TS
4307 default:
4308 goto die;
1579a72e 4309 }
873eb012 4310 break;
8c0fdd85 4311 case 7:
7a387fff
TS
4312 switch (sel) {
4313 case 0:
d75c135e 4314 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4316 rn = "HWREna";
4317 break;
7a387fff
TS
4318 default:
4319 goto die;
1579a72e 4320 }
8c0fdd85 4321 break;
873eb012 4322 case 8:
7a387fff
TS
4323 switch (sel) {
4324 case 0:
7db13fae 4325 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4326 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4327 rn = "BadVAddr";
2423f660 4328 break;
7a387fff
TS
4329 default:
4330 goto die;
4331 }
873eb012
TS
4332 break;
4333 case 9:
7a387fff
TS
4334 switch (sel) {
4335 case 0:
2e70f6ef
PB
4336 /* Mark as an IO operation because we read the time. */
4337 if (use_icount)
4338 gen_io_start();
895c2d04 4339 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4340 if (use_icount) {
4341 gen_io_end();
2e70f6ef 4342 }
55807224
EI
4343 /* Break the TB to be able to take timer interrupts immediately
4344 after reading count. */
4345 ctx->bstate = BS_STOP;
2423f660
TS
4346 rn = "Count";
4347 break;
4348 /* 6,7 are implementation dependent */
7a387fff
TS
4349 default:
4350 goto die;
2423f660 4351 }
873eb012
TS
4352 break;
4353 case 10:
7a387fff
TS
4354 switch (sel) {
4355 case 0:
7db13fae 4356 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4357 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4358 rn = "EntryHi";
4359 break;
7a387fff
TS
4360 default:
4361 goto die;
1579a72e 4362 }
873eb012
TS
4363 break;
4364 case 11:
7a387fff
TS
4365 switch (sel) {
4366 case 0:
7db13fae 4367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4368 rn = "Compare";
4369 break;
4370 /* 6,7 are implementation dependent */
7a387fff
TS
4371 default:
4372 goto die;
2423f660 4373 }
873eb012
TS
4374 break;
4375 case 12:
7a387fff
TS
4376 switch (sel) {
4377 case 0:
7db13fae 4378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4379 rn = "Status";
4380 break;
7a387fff 4381 case 1:
d75c135e 4382 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4383 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4384 rn = "IntCtl";
4385 break;
7a387fff 4386 case 2:
d75c135e 4387 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4389 rn = "SRSCtl";
4390 break;
7a387fff 4391 case 3:
d75c135e 4392 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4393 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4394 rn = "SRSMap";
fd88b6ab 4395 break;
7a387fff
TS
4396 default:
4397 goto die;
4398 }
873eb012
TS
4399 break;
4400 case 13:
7a387fff
TS
4401 switch (sel) {
4402 case 0:
7db13fae 4403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4404 rn = "Cause";
4405 break;
7a387fff
TS
4406 default:
4407 goto die;
4408 }
873eb012
TS
4409 break;
4410 case 14:
7a387fff
TS
4411 switch (sel) {
4412 case 0:
7db13fae 4413 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4414 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4415 rn = "EPC";
4416 break;
7a387fff
TS
4417 default:
4418 goto die;
1579a72e 4419 }
873eb012
TS
4420 break;
4421 case 15:
7a387fff
TS
4422 switch (sel) {
4423 case 0:
7db13fae 4424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4425 rn = "PRid";
4426 break;
7a387fff 4427 case 1:
d75c135e 4428 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4430 rn = "EBase";
4431 break;
7a387fff
TS
4432 default:
4433 goto die;
4434 }
873eb012
TS
4435 break;
4436 case 16:
4437 switch (sel) {
4438 case 0:
7db13fae 4439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4440 rn = "Config";
4441 break;
4442 case 1:
7db13fae 4443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4444 rn = "Config1";
4445 break;
7a387fff 4446 case 2:
7db13fae 4447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4448 rn = "Config2";
4449 break;
4450 case 3:
7db13fae 4451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4452 rn = "Config3";
4453 break;
e397ee33
TS
4454 /* 4,5 are reserved */
4455 /* 6,7 are implementation dependent */
4456 case 6:
7db13fae 4457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4458 rn = "Config6";
4459 break;
4460 case 7:
7db13fae 4461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4462 rn = "Config7";
4463 break;
873eb012 4464 default:
873eb012
TS
4465 goto die;
4466 }
4467 break;
4468 case 17:
7a387fff
TS
4469 switch (sel) {
4470 case 0:
895c2d04 4471 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4472 rn = "LLAddr";
4473 break;
7a387fff
TS
4474 default:
4475 goto die;
4476 }
873eb012
TS
4477 break;
4478 case 18:
7a387fff 4479 switch (sel) {
fd88b6ab 4480 case 0 ... 7:
895c2d04 4481 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4482 rn = "WatchLo";
4483 break;
7a387fff
TS
4484 default:
4485 goto die;
4486 }
873eb012
TS
4487 break;
4488 case 19:
7a387fff 4489 switch (sel) {
fd88b6ab 4490 case 0 ...7:
895c2d04 4491 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4492 rn = "WatchHi";
4493 break;
7a387fff
TS
4494 default:
4495 goto die;
4496 }
873eb012 4497 break;
8c0fdd85 4498 case 20:
7a387fff
TS
4499 switch (sel) {
4500 case 0:
d26bc211 4501#if defined(TARGET_MIPS64)
d75c135e 4502 check_insn(ctx, ISA_MIPS3);
7db13fae 4503 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4504 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4505 rn = "XContext";
4506 break;
703eaf37 4507#endif
7a387fff
TS
4508 default:
4509 goto die;
4510 }
8c0fdd85
TS
4511 break;
4512 case 21:
7a387fff
TS
4513 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4514 switch (sel) {
4515 case 0:
7db13fae 4516 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4517 rn = "Framemask";
4518 break;
7a387fff
TS
4519 default:
4520 goto die;
4521 }
8c0fdd85
TS
4522 break;
4523 case 22:
d9bea114 4524 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4525 rn = "'Diagnostic"; /* implementation dependent */
4526 break;
873eb012 4527 case 23:
7a387fff
TS
4528 switch (sel) {
4529 case 0:
895c2d04 4530 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4531 rn = "Debug";
4532 break;
7a387fff 4533 case 1:
d9bea114 4534// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4535 rn = "TraceControl";
4536// break;
7a387fff 4537 case 2:
d9bea114 4538// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4539 rn = "TraceControl2";
4540// break;
7a387fff 4541 case 3:
d9bea114 4542// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4543 rn = "UserTraceData";
4544// break;
7a387fff 4545 case 4:
d9bea114 4546// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4547 rn = "TraceBPC";
4548// break;
7a387fff
TS
4549 default:
4550 goto die;
4551 }
873eb012
TS
4552 break;
4553 case 24:
7a387fff
TS
4554 switch (sel) {
4555 case 0:
f0b3f3ae 4556 /* EJTAG support */
7db13fae 4557 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4558 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4559 rn = "DEPC";
4560 break;
7a387fff
TS
4561 default:
4562 goto die;
4563 }
873eb012 4564 break;
8c0fdd85 4565 case 25:
7a387fff
TS
4566 switch (sel) {
4567 case 0:
7db13fae 4568 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4569 rn = "Performance0";
7a387fff
TS
4570 break;
4571 case 1:
d9bea114 4572// gen_helper_mfc0_performance1(arg);
2423f660
TS
4573 rn = "Performance1";
4574// break;
7a387fff 4575 case 2:
d9bea114 4576// gen_helper_mfc0_performance2(arg);
2423f660
TS
4577 rn = "Performance2";
4578// break;
7a387fff 4579 case 3:
d9bea114 4580// gen_helper_mfc0_performance3(arg);
2423f660
TS
4581 rn = "Performance3";
4582// break;
7a387fff 4583 case 4:
d9bea114 4584// gen_helper_mfc0_performance4(arg);
2423f660
TS
4585 rn = "Performance4";
4586// break;
7a387fff 4587 case 5:
d9bea114 4588// gen_helper_mfc0_performance5(arg);
2423f660
TS
4589 rn = "Performance5";
4590// break;
7a387fff 4591 case 6:
d9bea114 4592// gen_helper_mfc0_performance6(arg);
2423f660
TS
4593 rn = "Performance6";
4594// break;
7a387fff 4595 case 7:
d9bea114 4596// gen_helper_mfc0_performance7(arg);
2423f660
TS
4597 rn = "Performance7";
4598// break;
7a387fff
TS
4599 default:
4600 goto die;
4601 }
8c0fdd85
TS
4602 break;
4603 case 26:
d9bea114 4604 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4605 rn = "ECC";
4606 break;
8c0fdd85 4607 case 27:
7a387fff 4608 switch (sel) {
7a387fff 4609 case 0 ... 3:
d9bea114 4610 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4611 rn = "CacheErr";
4612 break;
7a387fff
TS
4613 default:
4614 goto die;
4615 }
8c0fdd85 4616 break;
873eb012
TS
4617 case 28:
4618 switch (sel) {
4619 case 0:
7a387fff
TS
4620 case 2:
4621 case 4:
4622 case 6:
7db13fae 4623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4624 rn = "TagLo";
4625 break;
4626 case 1:
7a387fff
TS
4627 case 3:
4628 case 5:
4629 case 7:
7db13fae 4630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4631 rn = "DataLo";
4632 break;
4633 default:
873eb012
TS
4634 goto die;
4635 }
4636 break;
8c0fdd85 4637 case 29:
7a387fff
TS
4638 switch (sel) {
4639 case 0:
4640 case 2:
4641 case 4:
4642 case 6:
7db13fae 4643 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4644 rn = "TagHi";
4645 break;
4646 case 1:
4647 case 3:
4648 case 5:
4649 case 7:
7db13fae 4650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4651 rn = "DataHi";
4652 break;
4653 default:
4654 goto die;
4655 }
8c0fdd85 4656 break;
873eb012 4657 case 30:
7a387fff
TS
4658 switch (sel) {
4659 case 0:
7db13fae 4660 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4661 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4662 rn = "ErrorEPC";
4663 break;
7a387fff
TS
4664 default:
4665 goto die;
4666 }
873eb012
TS
4667 break;
4668 case 31:
7a387fff
TS
4669 switch (sel) {
4670 case 0:
f0b3f3ae 4671 /* EJTAG support */
7db13fae 4672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4673 rn = "DESAVE";
4674 break;
7a387fff
TS
4675 default:
4676 goto die;
4677 }
873eb012
TS
4678 break;
4679 default:
873eb012
TS
4680 goto die;
4681 }
2abf314d 4682 (void)rn; /* avoid a compiler warning */
d12d51d5 4683 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4684 return;
4685
4686die:
d12d51d5 4687 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4688 generate_exception(ctx, EXCP_RI);
4689}
4690
d75c135e 4691static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4692{
7a387fff
TS
4693 const char *rn = "invalid";
4694
e189e748 4695 if (sel != 0)
d75c135e 4696 check_insn(ctx, ISA_MIPS32);
e189e748 4697
2e70f6ef
PB
4698 if (use_icount)
4699 gen_io_start();
4700
8c0fdd85
TS
4701 switch (reg) {
4702 case 0:
7a387fff
TS
4703 switch (sel) {
4704 case 0:
895c2d04 4705 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4706 rn = "Index";
4707 break;
4708 case 1:
d75c135e 4709 check_insn(ctx, ASE_MT);
895c2d04 4710 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4711 rn = "MVPControl";
ead9360e 4712 break;
7a387fff 4713 case 2:
d75c135e 4714 check_insn(ctx, ASE_MT);
ead9360e 4715 /* ignored */
7a387fff 4716 rn = "MVPConf0";
ead9360e 4717 break;
7a387fff 4718 case 3:
d75c135e 4719 check_insn(ctx, ASE_MT);
ead9360e 4720 /* ignored */
7a387fff 4721 rn = "MVPConf1";
ead9360e 4722 break;
7a387fff
TS
4723 default:
4724 goto die;
4725 }
8c0fdd85
TS
4726 break;
4727 case 1:
7a387fff
TS
4728 switch (sel) {
4729 case 0:
2423f660 4730 /* ignored */
7a387fff 4731 rn = "Random";
2423f660 4732 break;
7a387fff 4733 case 1:
d75c135e 4734 check_insn(ctx, ASE_MT);
895c2d04 4735 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4736 rn = "VPEControl";
ead9360e 4737 break;
7a387fff 4738 case 2:
d75c135e 4739 check_insn(ctx, ASE_MT);
895c2d04 4740 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4741 rn = "VPEConf0";
ead9360e 4742 break;
7a387fff 4743 case 3:
d75c135e 4744 check_insn(ctx, ASE_MT);
895c2d04 4745 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4746 rn = "VPEConf1";
ead9360e 4747 break;
7a387fff 4748 case 4:
d75c135e 4749 check_insn(ctx, ASE_MT);
895c2d04 4750 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4751 rn = "YQMask";
ead9360e 4752 break;
7a387fff 4753 case 5:
d75c135e 4754 check_insn(ctx, ASE_MT);
7db13fae 4755 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4756 rn = "VPESchedule";
ead9360e 4757 break;
7a387fff 4758 case 6:
d75c135e 4759 check_insn(ctx, ASE_MT);
7db13fae 4760 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4761 rn = "VPEScheFBack";
ead9360e 4762 break;
7a387fff 4763 case 7:
d75c135e 4764 check_insn(ctx, ASE_MT);
895c2d04 4765 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4766 rn = "VPEOpt";
ead9360e 4767 break;
7a387fff
TS
4768 default:
4769 goto die;
4770 }
8c0fdd85
TS
4771 break;
4772 case 2:
7a387fff
TS
4773 switch (sel) {
4774 case 0:
895c2d04 4775 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4776 rn = "EntryLo0";
4777 break;
7a387fff 4778 case 1:
d75c135e 4779 check_insn(ctx, ASE_MT);
895c2d04 4780 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4781 rn = "TCStatus";
ead9360e 4782 break;
7a387fff 4783 case 2:
d75c135e 4784 check_insn(ctx, ASE_MT);
895c2d04 4785 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4786 rn = "TCBind";
ead9360e 4787 break;
7a387fff 4788 case 3:
d75c135e 4789 check_insn(ctx, ASE_MT);
895c2d04 4790 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4791 rn = "TCRestart";
ead9360e 4792 break;
7a387fff 4793 case 4:
d75c135e 4794 check_insn(ctx, ASE_MT);
895c2d04 4795 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4796 rn = "TCHalt";
ead9360e 4797 break;
7a387fff 4798 case 5:
d75c135e 4799 check_insn(ctx, ASE_MT);
895c2d04 4800 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4801 rn = "TCContext";
ead9360e 4802 break;
7a387fff 4803 case 6:
d75c135e 4804 check_insn(ctx, ASE_MT);
895c2d04 4805 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4806 rn = "TCSchedule";
ead9360e 4807 break;
7a387fff 4808 case 7:
d75c135e 4809 check_insn(ctx, ASE_MT);
895c2d04 4810 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4811 rn = "TCScheFBack";
ead9360e 4812 break;
7a387fff
TS
4813 default:
4814 goto die;
4815 }
8c0fdd85
TS
4816 break;
4817 case 3:
7a387fff
TS
4818 switch (sel) {
4819 case 0:
895c2d04 4820 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4821 rn = "EntryLo1";
4822 break;
7a387fff
TS
4823 default:
4824 goto die;
876d4b07 4825 }
8c0fdd85
TS
4826 break;
4827 case 4:
7a387fff
TS
4828 switch (sel) {
4829 case 0:
895c2d04 4830 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4831 rn = "Context";
4832 break;
7a387fff 4833 case 1:
895c2d04 4834// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
4835 rn = "ContextConfig";
4836// break;
7a387fff
TS
4837 default:
4838 goto die;
876d4b07 4839 }
8c0fdd85
TS
4840 break;
4841 case 5:
7a387fff
TS
4842 switch (sel) {
4843 case 0:
895c2d04 4844 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4845 rn = "PageMask";
4846 break;
7a387fff 4847 case 1:
d75c135e 4848 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4849 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4850 rn = "PageGrain";
4851 break;
7a387fff
TS
4852 default:
4853 goto die;
876d4b07 4854 }
8c0fdd85
TS
4855 break;
4856 case 6:
7a387fff
TS
4857 switch (sel) {
4858 case 0:
895c2d04 4859 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4860 rn = "Wired";
4861 break;
7a387fff 4862 case 1:
d75c135e 4863 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4864 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4865 rn = "SRSConf0";
ead9360e 4866 break;
7a387fff 4867 case 2:
d75c135e 4868 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4869 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4870 rn = "SRSConf1";
ead9360e 4871 break;
7a387fff 4872 case 3:
d75c135e 4873 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4874 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4875 rn = "SRSConf2";
ead9360e 4876 break;
7a387fff 4877 case 4:
d75c135e 4878 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4879 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4880 rn = "SRSConf3";
ead9360e 4881 break;
7a387fff 4882 case 5:
d75c135e 4883 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4884 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4885 rn = "SRSConf4";
ead9360e 4886 break;
7a387fff
TS
4887 default:
4888 goto die;
876d4b07 4889 }
8c0fdd85
TS
4890 break;
4891 case 7:
7a387fff
TS
4892 switch (sel) {
4893 case 0:
d75c135e 4894 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4895 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
4896 rn = "HWREna";
4897 break;
7a387fff
TS
4898 default:
4899 goto die;
876d4b07 4900 }
8c0fdd85
TS
4901 break;
4902 case 8:
7a387fff 4903 /* ignored */
f0b3f3ae 4904 rn = "BadVAddr";
8c0fdd85
TS
4905 break;
4906 case 9:
7a387fff
TS
4907 switch (sel) {
4908 case 0:
895c2d04 4909 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4910 rn = "Count";
4911 break;
876d4b07 4912 /* 6,7 are implementation dependent */
7a387fff
TS
4913 default:
4914 goto die;
876d4b07 4915 }
8c0fdd85
TS
4916 break;
4917 case 10:
7a387fff
TS
4918 switch (sel) {
4919 case 0:
895c2d04 4920 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4921 rn = "EntryHi";
4922 break;
7a387fff
TS
4923 default:
4924 goto die;
876d4b07 4925 }
8c0fdd85
TS
4926 break;
4927 case 11:
7a387fff
TS
4928 switch (sel) {
4929 case 0:
895c2d04 4930 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4931 rn = "Compare";
4932 break;
4933 /* 6,7 are implementation dependent */
7a387fff
TS
4934 default:
4935 goto die;
876d4b07 4936 }
8c0fdd85
TS
4937 break;
4938 case 12:
7a387fff
TS
4939 switch (sel) {
4940 case 0:
867abc7e 4941 save_cpu_state(ctx, 1);
895c2d04 4942 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4943 /* BS_STOP isn't good enough here, hflags may have changed. */
4944 gen_save_pc(ctx->pc + 4);
4945 ctx->bstate = BS_EXCP;
2423f660
TS
4946 rn = "Status";
4947 break;
7a387fff 4948 case 1:
d75c135e 4949 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4950 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4951 /* Stop translation as we may have switched the execution mode */
4952 ctx->bstate = BS_STOP;
2423f660
TS
4953 rn = "IntCtl";
4954 break;
7a387fff 4955 case 2:
d75c135e 4956 check_insn(ctx, ISA_MIPS32R2);
895c2d04 4957 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4958 /* Stop translation as we may have switched the execution mode */
4959 ctx->bstate = BS_STOP;
2423f660
TS
4960 rn = "SRSCtl";
4961 break;
7a387fff 4962 case 3:
d75c135e 4963 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4964 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4965 /* Stop translation as we may have switched the execution mode */
4966 ctx->bstate = BS_STOP;
2423f660 4967 rn = "SRSMap";
fd88b6ab 4968 break;
7a387fff
TS
4969 default:
4970 goto die;
876d4b07 4971 }
8c0fdd85
TS
4972 break;
4973 case 13:
7a387fff
TS
4974 switch (sel) {
4975 case 0:
867abc7e 4976 save_cpu_state(ctx, 1);
895c2d04 4977 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4978 rn = "Cause";
4979 break;
7a387fff
TS
4980 default:
4981 goto die;
876d4b07 4982 }
8c0fdd85
TS
4983 break;
4984 case 14:
7a387fff
TS
4985 switch (sel) {
4986 case 0:
7db13fae 4987 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4988 rn = "EPC";
4989 break;
7a387fff
TS
4990 default:
4991 goto die;
876d4b07 4992 }
8c0fdd85
TS
4993 break;
4994 case 15:
7a387fff
TS
4995 switch (sel) {
4996 case 0:
2423f660
TS
4997 /* ignored */
4998 rn = "PRid";
4999 break;
7a387fff 5000 case 1:
d75c135e 5001 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5002 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5003 rn = "EBase";
5004 break;
7a387fff
TS
5005 default:
5006 goto die;
1579a72e 5007 }
8c0fdd85
TS
5008 break;
5009 case 16:
5010 switch (sel) {
5011 case 0:
895c2d04 5012 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5013 rn = "Config";
2423f660
TS
5014 /* Stop translation as we may have switched the execution mode */
5015 ctx->bstate = BS_STOP;
7a387fff
TS
5016 break;
5017 case 1:
e397ee33 5018 /* ignored, read only */
7a387fff
TS
5019 rn = "Config1";
5020 break;
5021 case 2:
895c2d04 5022 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5023 rn = "Config2";
2423f660
TS
5024 /* Stop translation as we may have switched the execution mode */
5025 ctx->bstate = BS_STOP;
8c0fdd85 5026 break;
7a387fff 5027 case 3:
e397ee33 5028 /* ignored, read only */
7a387fff
TS
5029 rn = "Config3";
5030 break;
e397ee33
TS
5031 /* 4,5 are reserved */
5032 /* 6,7 are implementation dependent */
5033 case 6:
5034 /* ignored */
5035 rn = "Config6";
5036 break;
5037 case 7:
5038 /* ignored */
5039 rn = "Config7";
5040 break;
8c0fdd85
TS
5041 default:
5042 rn = "Invalid config selector";
5043 goto die;
5044 }
5045 break;
5046 case 17:
7a387fff
TS
5047 switch (sel) {
5048 case 0:
895c2d04 5049 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5050 rn = "LLAddr";
5051 break;
7a387fff
TS
5052 default:
5053 goto die;
5054 }
8c0fdd85
TS
5055 break;
5056 case 18:
7a387fff 5057 switch (sel) {
fd88b6ab 5058 case 0 ... 7:
895c2d04 5059 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5060 rn = "WatchLo";
5061 break;
7a387fff
TS
5062 default:
5063 goto die;
5064 }
8c0fdd85
TS
5065 break;
5066 case 19:
7a387fff 5067 switch (sel) {
fd88b6ab 5068 case 0 ... 7:
895c2d04 5069 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5070 rn = "WatchHi";
5071 break;
7a387fff
TS
5072 default:
5073 goto die;
5074 }
8c0fdd85
TS
5075 break;
5076 case 20:
7a387fff
TS
5077 switch (sel) {
5078 case 0:
d26bc211 5079#if defined(TARGET_MIPS64)
d75c135e 5080 check_insn(ctx, ISA_MIPS3);
895c2d04 5081 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5082 rn = "XContext";
5083 break;
703eaf37 5084#endif
7a387fff
TS
5085 default:
5086 goto die;
5087 }
8c0fdd85
TS
5088 break;
5089 case 21:
7a387fff
TS
5090 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5091 switch (sel) {
5092 case 0:
895c2d04 5093 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5094 rn = "Framemask";
5095 break;
7a387fff
TS
5096 default:
5097 goto die;
5098 }
5099 break;
8c0fdd85 5100 case 22:
7a387fff
TS
5101 /* ignored */
5102 rn = "Diagnostic"; /* implementation dependent */
2423f660 5103 break;
8c0fdd85 5104 case 23:
7a387fff
TS
5105 switch (sel) {
5106 case 0:
895c2d04 5107 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5108 /* BS_STOP isn't good enough here, hflags may have changed. */
5109 gen_save_pc(ctx->pc + 4);
5110 ctx->bstate = BS_EXCP;
2423f660
TS
5111 rn = "Debug";
5112 break;
7a387fff 5113 case 1:
895c2d04 5114// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5115 rn = "TraceControl";
8487327a
TS
5116 /* Stop translation as we may have switched the execution mode */
5117 ctx->bstate = BS_STOP;
2423f660 5118// break;
7a387fff 5119 case 2:
895c2d04 5120// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5121 rn = "TraceControl2";
8487327a
TS
5122 /* Stop translation as we may have switched the execution mode */
5123 ctx->bstate = BS_STOP;
2423f660 5124// break;
7a387fff 5125 case 3:
8487327a
TS
5126 /* Stop translation as we may have switched the execution mode */
5127 ctx->bstate = BS_STOP;
895c2d04 5128// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5129 rn = "UserTraceData";
8487327a
TS
5130 /* Stop translation as we may have switched the execution mode */
5131 ctx->bstate = BS_STOP;
2423f660 5132// break;
7a387fff 5133 case 4:
895c2d04 5134// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5135 /* Stop translation as we may have switched the execution mode */
5136 ctx->bstate = BS_STOP;
2423f660
TS
5137 rn = "TraceBPC";
5138// break;
7a387fff
TS
5139 default:
5140 goto die;
5141 }
8c0fdd85
TS
5142 break;
5143 case 24:
7a387fff
TS
5144 switch (sel) {
5145 case 0:
f1aa6320 5146 /* EJTAG support */
7db13fae 5147 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5148 rn = "DEPC";
5149 break;
7a387fff
TS
5150 default:
5151 goto die;
5152 }
8c0fdd85
TS
5153 break;
5154 case 25:
7a387fff
TS
5155 switch (sel) {
5156 case 0:
895c2d04 5157 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5158 rn = "Performance0";
5159 break;
7a387fff 5160 case 1:
d9bea114 5161// gen_helper_mtc0_performance1(arg);
2423f660
TS
5162 rn = "Performance1";
5163// break;
7a387fff 5164 case 2:
d9bea114 5165// gen_helper_mtc0_performance2(arg);
2423f660
TS
5166 rn = "Performance2";
5167// break;
7a387fff 5168 case 3:
d9bea114 5169// gen_helper_mtc0_performance3(arg);
2423f660
TS
5170 rn = "Performance3";
5171// break;
7a387fff 5172 case 4:
d9bea114 5173// gen_helper_mtc0_performance4(arg);
2423f660
TS
5174 rn = "Performance4";
5175// break;
7a387fff 5176 case 5:
d9bea114 5177// gen_helper_mtc0_performance5(arg);
2423f660
TS
5178 rn = "Performance5";
5179// break;
7a387fff 5180 case 6:
d9bea114 5181// gen_helper_mtc0_performance6(arg);
2423f660
TS
5182 rn = "Performance6";
5183// break;
7a387fff 5184 case 7:
d9bea114 5185// gen_helper_mtc0_performance7(arg);
2423f660
TS
5186 rn = "Performance7";
5187// break;
7a387fff
TS
5188 default:
5189 goto die;
5190 }
8c0fdd85
TS
5191 break;
5192 case 26:
2423f660 5193 /* ignored */
8c0fdd85 5194 rn = "ECC";
2423f660 5195 break;
8c0fdd85 5196 case 27:
7a387fff
TS
5197 switch (sel) {
5198 case 0 ... 3:
2423f660
TS
5199 /* ignored */
5200 rn = "CacheErr";
5201 break;
7a387fff
TS
5202 default:
5203 goto die;
5204 }
8c0fdd85
TS
5205 break;
5206 case 28:
5207 switch (sel) {
5208 case 0:
7a387fff
TS
5209 case 2:
5210 case 4:
5211 case 6:
895c2d04 5212 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5213 rn = "TagLo";
5214 break;
7a387fff
TS
5215 case 1:
5216 case 3:
5217 case 5:
5218 case 7:
895c2d04 5219 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5220 rn = "DataLo";
5221 break;
8c0fdd85 5222 default:
8c0fdd85
TS
5223 goto die;
5224 }
5225 break;
5226 case 29:
7a387fff
TS
5227 switch (sel) {
5228 case 0:
5229 case 2:
5230 case 4:
5231 case 6:
895c2d04 5232 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5233 rn = "TagHi";
5234 break;
5235 case 1:
5236 case 3:
5237 case 5:
5238 case 7:
895c2d04 5239 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5240 rn = "DataHi";
5241 break;
5242 default:
5243 rn = "invalid sel";
5244 goto die;
5245 }
8c0fdd85
TS
5246 break;
5247 case 30:
7a387fff
TS
5248 switch (sel) {
5249 case 0:
7db13fae 5250 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5251 rn = "ErrorEPC";
5252 break;
7a387fff
TS
5253 default:
5254 goto die;
5255 }
8c0fdd85
TS
5256 break;
5257 case 31:
7a387fff
TS
5258 switch (sel) {
5259 case 0:
f1aa6320 5260 /* EJTAG support */
7db13fae 5261 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5262 rn = "DESAVE";
5263 break;
7a387fff
TS
5264 default:
5265 goto die;
5266 }
2423f660
TS
5267 /* Stop translation as we may have switched the execution mode */
5268 ctx->bstate = BS_STOP;
8c0fdd85
TS
5269 break;
5270 default:
8c0fdd85
TS
5271 goto die;
5272 }
2abf314d 5273 (void)rn; /* avoid a compiler warning */
d12d51d5 5274 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5275 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5276 if (use_icount) {
5277 gen_io_end();
5278 ctx->bstate = BS_STOP;
5279 }
8c0fdd85
TS
5280 return;
5281
5282die:
d12d51d5 5283 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5284 generate_exception(ctx, EXCP_RI);
5285}
5286
d26bc211 5287#if defined(TARGET_MIPS64)
d75c135e 5288static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5289{
5290 const char *rn = "invalid";
5291
e189e748 5292 if (sel != 0)
d75c135e 5293 check_insn(ctx, ISA_MIPS64);
e189e748 5294
9c2149c8
TS
5295 switch (reg) {
5296 case 0:
5297 switch (sel) {
5298 case 0:
7db13fae 5299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5300 rn = "Index";
5301 break;
5302 case 1:
d75c135e 5303 check_insn(ctx, ASE_MT);
895c2d04 5304 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5305 rn = "MVPControl";
ead9360e 5306 break;
9c2149c8 5307 case 2:
d75c135e 5308 check_insn(ctx, ASE_MT);
895c2d04 5309 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5310 rn = "MVPConf0";
ead9360e 5311 break;
9c2149c8 5312 case 3:
d75c135e 5313 check_insn(ctx, ASE_MT);
895c2d04 5314 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5315 rn = "MVPConf1";
ead9360e 5316 break;
9c2149c8
TS
5317 default:
5318 goto die;
5319 }
5320 break;
5321 case 1:
5322 switch (sel) {
5323 case 0:
895c2d04 5324 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5325 rn = "Random";
2423f660 5326 break;
9c2149c8 5327 case 1:
d75c135e 5328 check_insn(ctx, ASE_MT);
7db13fae 5329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5330 rn = "VPEControl";
ead9360e 5331 break;
9c2149c8 5332 case 2:
d75c135e 5333 check_insn(ctx, ASE_MT);
7db13fae 5334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5335 rn = "VPEConf0";
ead9360e 5336 break;
9c2149c8 5337 case 3:
d75c135e 5338 check_insn(ctx, ASE_MT);
7db13fae 5339 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5340 rn = "VPEConf1";
ead9360e 5341 break;
9c2149c8 5342 case 4:
d75c135e 5343 check_insn(ctx, ASE_MT);
7db13fae 5344 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5345 rn = "YQMask";
ead9360e 5346 break;
9c2149c8 5347 case 5:
d75c135e 5348 check_insn(ctx, ASE_MT);
7db13fae 5349 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5350 rn = "VPESchedule";
ead9360e 5351 break;
9c2149c8 5352 case 6:
d75c135e 5353 check_insn(ctx, ASE_MT);
7db13fae 5354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5355 rn = "VPEScheFBack";
ead9360e 5356 break;
9c2149c8 5357 case 7:
d75c135e 5358 check_insn(ctx, ASE_MT);
7db13fae 5359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5360 rn = "VPEOpt";
ead9360e 5361 break;
9c2149c8
TS
5362 default:
5363 goto die;
5364 }
5365 break;
5366 case 2:
5367 switch (sel) {
5368 case 0:
7db13fae 5369 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5370 rn = "EntryLo0";
5371 break;
9c2149c8 5372 case 1:
d75c135e 5373 check_insn(ctx, ASE_MT);
895c2d04 5374 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5375 rn = "TCStatus";
ead9360e 5376 break;
9c2149c8 5377 case 2:
d75c135e 5378 check_insn(ctx, ASE_MT);
895c2d04 5379 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5380 rn = "TCBind";
ead9360e 5381 break;
9c2149c8 5382 case 3:
d75c135e 5383 check_insn(ctx, ASE_MT);
895c2d04 5384 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5385 rn = "TCRestart";
ead9360e 5386 break;
9c2149c8 5387 case 4:
d75c135e 5388 check_insn(ctx, ASE_MT);
895c2d04 5389 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5390 rn = "TCHalt";
ead9360e 5391 break;
9c2149c8 5392 case 5:
d75c135e 5393 check_insn(ctx, ASE_MT);
895c2d04 5394 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5395 rn = "TCContext";
ead9360e 5396 break;
9c2149c8 5397 case 6:
d75c135e 5398 check_insn(ctx, ASE_MT);
895c2d04 5399 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5400 rn = "TCSchedule";
ead9360e 5401 break;
9c2149c8 5402 case 7:
d75c135e 5403 check_insn(ctx, ASE_MT);
895c2d04 5404 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5405 rn = "TCScheFBack";
ead9360e 5406 break;
9c2149c8
TS
5407 default:
5408 goto die;
5409 }
5410 break;
5411 case 3:
5412 switch (sel) {
5413 case 0:
7db13fae 5414 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5415 rn = "EntryLo1";
5416 break;
9c2149c8
TS
5417 default:
5418 goto die;
1579a72e 5419 }
9c2149c8
TS
5420 break;
5421 case 4:
5422 switch (sel) {
5423 case 0:
7db13fae 5424 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5425 rn = "Context";
5426 break;
9c2149c8 5427 case 1:
d9bea114 5428// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
5429 rn = "ContextConfig";
5430// break;
9c2149c8
TS
5431 default:
5432 goto die;
876d4b07 5433 }
9c2149c8
TS
5434 break;
5435 case 5:
5436 switch (sel) {
5437 case 0:
7db13fae 5438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5439 rn = "PageMask";
5440 break;
9c2149c8 5441 case 1:
d75c135e 5442 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5444 rn = "PageGrain";
5445 break;
9c2149c8
TS
5446 default:
5447 goto die;
876d4b07 5448 }
9c2149c8
TS
5449 break;
5450 case 6:
5451 switch (sel) {
5452 case 0:
7db13fae 5453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5454 rn = "Wired";
5455 break;
9c2149c8 5456 case 1:
d75c135e 5457 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5459 rn = "SRSConf0";
ead9360e 5460 break;
9c2149c8 5461 case 2:
d75c135e 5462 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5464 rn = "SRSConf1";
ead9360e 5465 break;
9c2149c8 5466 case 3:
d75c135e 5467 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5469 rn = "SRSConf2";
ead9360e 5470 break;
9c2149c8 5471 case 4:
d75c135e 5472 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5474 rn = "SRSConf3";
ead9360e 5475 break;
9c2149c8 5476 case 5:
d75c135e 5477 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5479 rn = "SRSConf4";
ead9360e 5480 break;
9c2149c8
TS
5481 default:
5482 goto die;
876d4b07 5483 }
9c2149c8
TS
5484 break;
5485 case 7:
5486 switch (sel) {
5487 case 0:
d75c135e 5488 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5489 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5490 rn = "HWREna";
5491 break;
9c2149c8
TS
5492 default:
5493 goto die;
876d4b07 5494 }
9c2149c8
TS
5495 break;
5496 case 8:
5497 switch (sel) {
5498 case 0:
7db13fae 5499 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5500 rn = "BadVAddr";
2423f660 5501 break;
9c2149c8
TS
5502 default:
5503 goto die;
876d4b07 5504 }
9c2149c8
TS
5505 break;
5506 case 9:
5507 switch (sel) {
5508 case 0:
2e70f6ef
PB
5509 /* Mark as an IO operation because we read the time. */
5510 if (use_icount)
5511 gen_io_start();
895c2d04 5512 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5513 if (use_icount) {
5514 gen_io_end();
2e70f6ef 5515 }
55807224
EI
5516 /* Break the TB to be able to take timer interrupts immediately
5517 after reading count. */
5518 ctx->bstate = BS_STOP;
2423f660
TS
5519 rn = "Count";
5520 break;
5521 /* 6,7 are implementation dependent */
9c2149c8
TS
5522 default:
5523 goto die;
876d4b07 5524 }
9c2149c8
TS
5525 break;
5526 case 10:
5527 switch (sel) {
5528 case 0:
7db13fae 5529 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5530 rn = "EntryHi";
5531 break;
9c2149c8
TS
5532 default:
5533 goto die;
876d4b07 5534 }
9c2149c8
TS
5535 break;
5536 case 11:
5537 switch (sel) {
5538 case 0:
7db13fae 5539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5540 rn = "Compare";
5541 break;
876d4b07 5542 /* 6,7 are implementation dependent */
9c2149c8
TS
5543 default:
5544 goto die;
876d4b07 5545 }
9c2149c8
TS
5546 break;
5547 case 12:
5548 switch (sel) {
5549 case 0:
7db13fae 5550 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5551 rn = "Status";
5552 break;
9c2149c8 5553 case 1:
d75c135e 5554 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5555 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5556 rn = "IntCtl";
5557 break;
9c2149c8 5558 case 2:
d75c135e 5559 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5561 rn = "SRSCtl";
5562 break;
9c2149c8 5563 case 3:
d75c135e 5564 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5566 rn = "SRSMap";
5567 break;
9c2149c8
TS
5568 default:
5569 goto die;
876d4b07 5570 }
9c2149c8
TS
5571 break;
5572 case 13:
5573 switch (sel) {
5574 case 0:
7db13fae 5575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5576 rn = "Cause";
5577 break;
9c2149c8
TS
5578 default:
5579 goto die;
876d4b07 5580 }
9c2149c8
TS
5581 break;
5582 case 14:
5583 switch (sel) {
5584 case 0:
7db13fae 5585 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5586 rn = "EPC";
5587 break;
9c2149c8
TS
5588 default:
5589 goto die;
876d4b07 5590 }
9c2149c8
TS
5591 break;
5592 case 15:
5593 switch (sel) {
5594 case 0:
7db13fae 5595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5596 rn = "PRid";
5597 break;
9c2149c8 5598 case 1:
d75c135e 5599 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5601 rn = "EBase";
5602 break;
9c2149c8
TS
5603 default:
5604 goto die;
876d4b07 5605 }
9c2149c8
TS
5606 break;
5607 case 16:
5608 switch (sel) {
5609 case 0:
7db13fae 5610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5611 rn = "Config";
5612 break;
5613 case 1:
7db13fae 5614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5615 rn = "Config1";
5616 break;
5617 case 2:
7db13fae 5618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5619 rn = "Config2";
5620 break;
5621 case 3:
7db13fae 5622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5623 rn = "Config3";
5624 break;
5625 /* 6,7 are implementation dependent */
f0b3f3ae 5626 case 6:
7db13fae 5627 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5628 rn = "Config6";
5629 break;
5630 case 7:
7db13fae 5631 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5632 rn = "Config7";
5633 break;
9c2149c8
TS
5634 default:
5635 goto die;
5636 }
5637 break;
5638 case 17:
5639 switch (sel) {
5640 case 0:
895c2d04 5641 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5642 rn = "LLAddr";
5643 break;
9c2149c8
TS
5644 default:
5645 goto die;
5646 }
5647 break;
5648 case 18:
5649 switch (sel) {
fd88b6ab 5650 case 0 ... 7:
895c2d04 5651 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5652 rn = "WatchLo";
5653 break;
9c2149c8
TS
5654 default:
5655 goto die;
5656 }
5657 break;
5658 case 19:
5659 switch (sel) {
fd88b6ab 5660 case 0 ... 7:
895c2d04 5661 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5662 rn = "WatchHi";
5663 break;
9c2149c8
TS
5664 default:
5665 goto die;
5666 }
5667 break;
5668 case 20:
5669 switch (sel) {
5670 case 0:
d75c135e 5671 check_insn(ctx, ISA_MIPS3);
7db13fae 5672 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5673 rn = "XContext";
5674 break;
9c2149c8
TS
5675 default:
5676 goto die;
5677 }
5678 break;
5679 case 21:
5680 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5681 switch (sel) {
5682 case 0:
7db13fae 5683 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5684 rn = "Framemask";
5685 break;
9c2149c8
TS
5686 default:
5687 goto die;
5688 }
5689 break;
5690 case 22:
d9bea114 5691 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5692 rn = "'Diagnostic"; /* implementation dependent */
5693 break;
9c2149c8
TS
5694 case 23:
5695 switch (sel) {
5696 case 0:
895c2d04 5697 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5698 rn = "Debug";
5699 break;
9c2149c8 5700 case 1:
895c2d04 5701// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5702 rn = "TraceControl";
5703// break;
9c2149c8 5704 case 2:
895c2d04 5705// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5706 rn = "TraceControl2";
5707// break;
9c2149c8 5708 case 3:
895c2d04 5709// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5710 rn = "UserTraceData";
5711// break;
9c2149c8 5712 case 4:
895c2d04 5713// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5714 rn = "TraceBPC";
5715// break;
9c2149c8
TS
5716 default:
5717 goto die;
5718 }
5719 break;
5720 case 24:
5721 switch (sel) {
5722 case 0:
f0b3f3ae 5723 /* EJTAG support */
7db13fae 5724 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5725 rn = "DEPC";
5726 break;
9c2149c8
TS
5727 default:
5728 goto die;
5729 }
5730 break;
5731 case 25:
5732 switch (sel) {
5733 case 0:
7db13fae 5734 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5735 rn = "Performance0";
9c2149c8
TS
5736 break;
5737 case 1:
d9bea114 5738// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5739 rn = "Performance1";
5740// break;
9c2149c8 5741 case 2:
d9bea114 5742// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5743 rn = "Performance2";
5744// break;
9c2149c8 5745 case 3:
d9bea114 5746// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5747 rn = "Performance3";
5748// break;
9c2149c8 5749 case 4:
d9bea114 5750// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5751 rn = "Performance4";
5752// break;
9c2149c8 5753 case 5:
d9bea114 5754// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5755 rn = "Performance5";
5756// break;
9c2149c8 5757 case 6:
d9bea114 5758// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5759 rn = "Performance6";
5760// break;
9c2149c8 5761 case 7:
d9bea114 5762// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5763 rn = "Performance7";
5764// break;
9c2149c8
TS
5765 default:
5766 goto die;
5767 }
5768 break;
5769 case 26:
d9bea114 5770 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5771 rn = "ECC";
5772 break;
9c2149c8
TS
5773 case 27:
5774 switch (sel) {
5775 /* ignored */
5776 case 0 ... 3:
d9bea114 5777 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5778 rn = "CacheErr";
5779 break;
9c2149c8
TS
5780 default:
5781 goto die;
5782 }
5783 break;
5784 case 28:
5785 switch (sel) {
5786 case 0:
5787 case 2:
5788 case 4:
5789 case 6:
7db13fae 5790 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5791 rn = "TagLo";
5792 break;
5793 case 1:
5794 case 3:
5795 case 5:
5796 case 7:
7db13fae 5797 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5798 rn = "DataLo";
5799 break;
5800 default:
5801 goto die;
5802 }
5803 break;
5804 case 29:
5805 switch (sel) {
5806 case 0:
5807 case 2:
5808 case 4:
5809 case 6:
7db13fae 5810 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5811 rn = "TagHi";
5812 break;
5813 case 1:
5814 case 3:
5815 case 5:
5816 case 7:
7db13fae 5817 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5818 rn = "DataHi";
5819 break;
5820 default:
5821 goto die;
5822 }
5823 break;
5824 case 30:
5825 switch (sel) {
5826 case 0:
7db13fae 5827 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5828 rn = "ErrorEPC";
5829 break;
9c2149c8
TS
5830 default:
5831 goto die;
5832 }
5833 break;
5834 case 31:
5835 switch (sel) {
5836 case 0:
f0b3f3ae 5837 /* EJTAG support */
7db13fae 5838 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5839 rn = "DESAVE";
5840 break;
9c2149c8
TS
5841 default:
5842 goto die;
5843 }
5844 break;
5845 default:
876d4b07 5846 goto die;
9c2149c8 5847 }
2abf314d 5848 (void)rn; /* avoid a compiler warning */
d12d51d5 5849 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5850 return;
5851
5852die:
d12d51d5 5853 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5854 generate_exception(ctx, EXCP_RI);
5855}
5856
d75c135e 5857static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5858{
5859 const char *rn = "invalid";
5860
e189e748 5861 if (sel != 0)
d75c135e 5862 check_insn(ctx, ISA_MIPS64);
e189e748 5863
2e70f6ef
PB
5864 if (use_icount)
5865 gen_io_start();
5866
9c2149c8
TS
5867 switch (reg) {
5868 case 0:
5869 switch (sel) {
5870 case 0:
895c2d04 5871 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5872 rn = "Index";
5873 break;
5874 case 1:
d75c135e 5875 check_insn(ctx, ASE_MT);
895c2d04 5876 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5877 rn = "MVPControl";
ead9360e 5878 break;
9c2149c8 5879 case 2:
d75c135e 5880 check_insn(ctx, ASE_MT);
ead9360e 5881 /* ignored */
9c2149c8 5882 rn = "MVPConf0";
ead9360e 5883 break;
9c2149c8 5884 case 3:
d75c135e 5885 check_insn(ctx, ASE_MT);
ead9360e 5886 /* ignored */
9c2149c8 5887 rn = "MVPConf1";
ead9360e 5888 break;
9c2149c8
TS
5889 default:
5890 goto die;
5891 }
5892 break;
5893 case 1:
5894 switch (sel) {
5895 case 0:
2423f660 5896 /* ignored */
9c2149c8 5897 rn = "Random";
2423f660 5898 break;
9c2149c8 5899 case 1:
d75c135e 5900 check_insn(ctx, ASE_MT);
895c2d04 5901 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5902 rn = "VPEControl";
ead9360e 5903 break;
9c2149c8 5904 case 2:
d75c135e 5905 check_insn(ctx, ASE_MT);
895c2d04 5906 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5907 rn = "VPEConf0";
ead9360e 5908 break;
9c2149c8 5909 case 3:
d75c135e 5910 check_insn(ctx, ASE_MT);
895c2d04 5911 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5912 rn = "VPEConf1";
ead9360e 5913 break;
9c2149c8 5914 case 4:
d75c135e 5915 check_insn(ctx, ASE_MT);
895c2d04 5916 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5917 rn = "YQMask";
ead9360e 5918 break;
9c2149c8 5919 case 5:
d75c135e 5920 check_insn(ctx, ASE_MT);
7db13fae 5921 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5922 rn = "VPESchedule";
ead9360e 5923 break;
9c2149c8 5924 case 6:
d75c135e 5925 check_insn(ctx, ASE_MT);
7db13fae 5926 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5927 rn = "VPEScheFBack";
ead9360e 5928 break;
9c2149c8 5929 case 7:
d75c135e 5930 check_insn(ctx, ASE_MT);
895c2d04 5931 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5932 rn = "VPEOpt";
ead9360e 5933 break;
9c2149c8
TS
5934 default:
5935 goto die;
5936 }
5937 break;
5938 case 2:
5939 switch (sel) {
5940 case 0:
895c2d04 5941 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5942 rn = "EntryLo0";
5943 break;
9c2149c8 5944 case 1:
d75c135e 5945 check_insn(ctx, ASE_MT);
895c2d04 5946 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5947 rn = "TCStatus";
ead9360e 5948 break;
9c2149c8 5949 case 2:
d75c135e 5950 check_insn(ctx, ASE_MT);
895c2d04 5951 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5952 rn = "TCBind";
ead9360e 5953 break;
9c2149c8 5954 case 3:
d75c135e 5955 check_insn(ctx, ASE_MT);
895c2d04 5956 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5957 rn = "TCRestart";
ead9360e 5958 break;
9c2149c8 5959 case 4:
d75c135e 5960 check_insn(ctx, ASE_MT);
895c2d04 5961 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5962 rn = "TCHalt";
ead9360e 5963 break;
9c2149c8 5964 case 5:
d75c135e 5965 check_insn(ctx, ASE_MT);
895c2d04 5966 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5967 rn = "TCContext";
ead9360e 5968 break;
9c2149c8 5969 case 6:
d75c135e 5970 check_insn(ctx, ASE_MT);
895c2d04 5971 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5972 rn = "TCSchedule";
ead9360e 5973 break;
9c2149c8 5974 case 7:
d75c135e 5975 check_insn(ctx, ASE_MT);
895c2d04 5976 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5977 rn = "TCScheFBack";
ead9360e 5978 break;
9c2149c8
TS
5979 default:
5980 goto die;
5981 }
5982 break;
5983 case 3:
5984 switch (sel) {
5985 case 0:
895c2d04 5986 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5987 rn = "EntryLo1";
5988 break;
9c2149c8
TS
5989 default:
5990 goto die;
876d4b07 5991 }
9c2149c8
TS
5992 break;
5993 case 4:
5994 switch (sel) {
5995 case 0:
895c2d04 5996 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5997 rn = "Context";
5998 break;
9c2149c8 5999 case 1:
895c2d04 6000// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
6001 rn = "ContextConfig";
6002// break;
9c2149c8
TS
6003 default:
6004 goto die;
876d4b07 6005 }
9c2149c8
TS
6006 break;
6007 case 5:
6008 switch (sel) {
6009 case 0:
895c2d04 6010 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6011 rn = "PageMask";
6012 break;
9c2149c8 6013 case 1:
d75c135e 6014 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6015 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6016 rn = "PageGrain";
6017 break;
9c2149c8
TS
6018 default:
6019 goto die;
876d4b07 6020 }
9c2149c8
TS
6021 break;
6022 case 6:
6023 switch (sel) {
6024 case 0:
895c2d04 6025 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6026 rn = "Wired";
6027 break;
9c2149c8 6028 case 1:
d75c135e 6029 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6030 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6031 rn = "SRSConf0";
ead9360e 6032 break;
9c2149c8 6033 case 2:
d75c135e 6034 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6035 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6036 rn = "SRSConf1";
ead9360e 6037 break;
9c2149c8 6038 case 3:
d75c135e 6039 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6040 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6041 rn = "SRSConf2";
ead9360e 6042 break;
9c2149c8 6043 case 4:
d75c135e 6044 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6045 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6046 rn = "SRSConf3";
ead9360e 6047 break;
9c2149c8 6048 case 5:
d75c135e 6049 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6050 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6051 rn = "SRSConf4";
ead9360e 6052 break;
9c2149c8
TS
6053 default:
6054 goto die;
876d4b07 6055 }
9c2149c8
TS
6056 break;
6057 case 7:
6058 switch (sel) {
6059 case 0:
d75c135e 6060 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6061 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
6062 rn = "HWREna";
6063 break;
9c2149c8
TS
6064 default:
6065 goto die;
876d4b07 6066 }
9c2149c8
TS
6067 break;
6068 case 8:
6069 /* ignored */
f0b3f3ae 6070 rn = "BadVAddr";
9c2149c8
TS
6071 break;
6072 case 9:
6073 switch (sel) {
6074 case 0:
895c2d04 6075 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6076 rn = "Count";
6077 break;
876d4b07 6078 /* 6,7 are implementation dependent */
9c2149c8
TS
6079 default:
6080 goto die;
876d4b07
TS
6081 }
6082 /* Stop translation as we may have switched the execution mode */
6083 ctx->bstate = BS_STOP;
9c2149c8
TS
6084 break;
6085 case 10:
6086 switch (sel) {
6087 case 0:
895c2d04 6088 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6089 rn = "EntryHi";
6090 break;
9c2149c8
TS
6091 default:
6092 goto die;
876d4b07 6093 }
9c2149c8
TS
6094 break;
6095 case 11:
6096 switch (sel) {
6097 case 0:
895c2d04 6098 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6099 rn = "Compare";
6100 break;
876d4b07 6101 /* 6,7 are implementation dependent */
9c2149c8
TS
6102 default:
6103 goto die;
876d4b07 6104 }
de9a95f0
AJ
6105 /* Stop translation as we may have switched the execution mode */
6106 ctx->bstate = BS_STOP;
9c2149c8
TS
6107 break;
6108 case 12:
6109 switch (sel) {
6110 case 0:
867abc7e 6111 save_cpu_state(ctx, 1);
895c2d04 6112 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6113 /* BS_STOP isn't good enough here, hflags may have changed. */
6114 gen_save_pc(ctx->pc + 4);
6115 ctx->bstate = BS_EXCP;
2423f660
TS
6116 rn = "Status";
6117 break;
9c2149c8 6118 case 1:
d75c135e 6119 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6120 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6121 /* Stop translation as we may have switched the execution mode */
6122 ctx->bstate = BS_STOP;
2423f660
TS
6123 rn = "IntCtl";
6124 break;
9c2149c8 6125 case 2:
d75c135e 6126 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6127 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6128 /* Stop translation as we may have switched the execution mode */
6129 ctx->bstate = BS_STOP;
2423f660
TS
6130 rn = "SRSCtl";
6131 break;
9c2149c8 6132 case 3:
d75c135e 6133 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6134 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6135 /* Stop translation as we may have switched the execution mode */
6136 ctx->bstate = BS_STOP;
2423f660
TS
6137 rn = "SRSMap";
6138 break;
6139 default:
9c2149c8 6140 goto die;
876d4b07 6141 }
9c2149c8
TS
6142 break;
6143 case 13:
6144 switch (sel) {
6145 case 0:
867abc7e 6146 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6147 /* Mark as an IO operation because we may trigger a software
6148 interrupt. */
6149 if (use_icount) {
6150 gen_io_start();
6151 }
895c2d04 6152 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6153 if (use_icount) {
6154 gen_io_end();
6155 }
6156 /* Stop translation as we may have triggered an intetrupt */
6157 ctx->bstate = BS_STOP;
2423f660
TS
6158 rn = "Cause";
6159 break;
9c2149c8
TS
6160 default:
6161 goto die;
876d4b07 6162 }
9c2149c8
TS
6163 break;
6164 case 14:
6165 switch (sel) {
6166 case 0:
7db13fae 6167 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6168 rn = "EPC";
6169 break;
9c2149c8
TS
6170 default:
6171 goto die;
876d4b07 6172 }
9c2149c8
TS
6173 break;
6174 case 15:
6175 switch (sel) {
6176 case 0:
2423f660
TS
6177 /* ignored */
6178 rn = "PRid";
6179 break;
9c2149c8 6180 case 1:
d75c135e 6181 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6182 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6183 rn = "EBase";
6184 break;
9c2149c8
TS
6185 default:
6186 goto die;
876d4b07 6187 }
9c2149c8
TS
6188 break;
6189 case 16:
6190 switch (sel) {
6191 case 0:
895c2d04 6192 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6193 rn = "Config";
2423f660
TS
6194 /* Stop translation as we may have switched the execution mode */
6195 ctx->bstate = BS_STOP;
9c2149c8
TS
6196 break;
6197 case 1:
1fc7bf6e 6198 /* ignored, read only */
9c2149c8
TS
6199 rn = "Config1";
6200 break;
6201 case 2:
895c2d04 6202 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6203 rn = "Config2";
2423f660
TS
6204 /* Stop translation as we may have switched the execution mode */
6205 ctx->bstate = BS_STOP;
9c2149c8
TS
6206 break;
6207 case 3:
2423f660 6208 /* ignored */
9c2149c8
TS
6209 rn = "Config3";
6210 break;
6211 /* 6,7 are implementation dependent */
6212 default:
6213 rn = "Invalid config selector";
6214 goto die;
6215 }
9c2149c8
TS
6216 break;
6217 case 17:
6218 switch (sel) {
6219 case 0:
895c2d04 6220 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6221 rn = "LLAddr";
6222 break;
9c2149c8
TS
6223 default:
6224 goto die;
6225 }
6226 break;
6227 case 18:
6228 switch (sel) {
fd88b6ab 6229 case 0 ... 7:
895c2d04 6230 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6231 rn = "WatchLo";
6232 break;
9c2149c8
TS
6233 default:
6234 goto die;
6235 }
6236 break;
6237 case 19:
6238 switch (sel) {
fd88b6ab 6239 case 0 ... 7:
895c2d04 6240 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6241 rn = "WatchHi";
6242 break;
9c2149c8
TS
6243 default:
6244 goto die;
6245 }
6246 break;
6247 case 20:
6248 switch (sel) {
6249 case 0:
d75c135e 6250 check_insn(ctx, ISA_MIPS3);
895c2d04 6251 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6252 rn = "XContext";
6253 break;
9c2149c8
TS
6254 default:
6255 goto die;
6256 }
6257 break;
6258 case 21:
6259 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6260 switch (sel) {
6261 case 0:
895c2d04 6262 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6263 rn = "Framemask";
6264 break;
9c2149c8
TS
6265 default:
6266 goto die;
6267 }
6268 break;
6269 case 22:
6270 /* ignored */
6271 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6272 break;
9c2149c8
TS
6273 case 23:
6274 switch (sel) {
6275 case 0:
895c2d04 6276 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6277 /* BS_STOP isn't good enough here, hflags may have changed. */
6278 gen_save_pc(ctx->pc + 4);
6279 ctx->bstate = BS_EXCP;
2423f660
TS
6280 rn = "Debug";
6281 break;
9c2149c8 6282 case 1:
895c2d04 6283// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6284 /* Stop translation as we may have switched the execution mode */
6285 ctx->bstate = BS_STOP;
2423f660
TS
6286 rn = "TraceControl";
6287// break;
9c2149c8 6288 case 2:
895c2d04 6289// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6290 /* Stop translation as we may have switched the execution mode */
6291 ctx->bstate = BS_STOP;
2423f660
TS
6292 rn = "TraceControl2";
6293// break;
9c2149c8 6294 case 3:
895c2d04 6295// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6296 /* Stop translation as we may have switched the execution mode */
6297 ctx->bstate = BS_STOP;
2423f660
TS
6298 rn = "UserTraceData";
6299// break;
9c2149c8 6300 case 4:
895c2d04 6301// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6302 /* Stop translation as we may have switched the execution mode */
6303 ctx->bstate = BS_STOP;
2423f660
TS
6304 rn = "TraceBPC";
6305// break;
9c2149c8
TS
6306 default:
6307 goto die;
6308 }
9c2149c8
TS
6309 break;
6310 case 24:
6311 switch (sel) {
6312 case 0:
f1aa6320 6313 /* EJTAG support */
7db13fae 6314 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6315 rn = "DEPC";
6316 break;
9c2149c8
TS
6317 default:
6318 goto die;
6319 }
6320 break;
6321 case 25:
6322 switch (sel) {
6323 case 0:
895c2d04 6324 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6325 rn = "Performance0";
6326 break;
9c2149c8 6327 case 1:
895c2d04 6328// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6329 rn = "Performance1";
6330// break;
9c2149c8 6331 case 2:
895c2d04 6332// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6333 rn = "Performance2";
6334// break;
9c2149c8 6335 case 3:
895c2d04 6336// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6337 rn = "Performance3";
6338// break;
9c2149c8 6339 case 4:
895c2d04 6340// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6341 rn = "Performance4";
6342// break;
9c2149c8 6343 case 5:
895c2d04 6344// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6345 rn = "Performance5";
6346// break;
9c2149c8 6347 case 6:
895c2d04 6348// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6349 rn = "Performance6";
6350// break;
9c2149c8 6351 case 7:
895c2d04 6352// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6353 rn = "Performance7";
6354// break;
9c2149c8
TS
6355 default:
6356 goto die;
6357 }
876d4b07 6358 break;
9c2149c8 6359 case 26:
876d4b07 6360 /* ignored */
9c2149c8 6361 rn = "ECC";
876d4b07 6362 break;
9c2149c8
TS
6363 case 27:
6364 switch (sel) {
6365 case 0 ... 3:
2423f660
TS
6366 /* ignored */
6367 rn = "CacheErr";
6368 break;
9c2149c8
TS
6369 default:
6370 goto die;
6371 }
876d4b07 6372 break;
9c2149c8
TS
6373 case 28:
6374 switch (sel) {
6375 case 0:
6376 case 2:
6377 case 4:
6378 case 6:
895c2d04 6379 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6380 rn = "TagLo";
6381 break;
6382 case 1:
6383 case 3:
6384 case 5:
6385 case 7:
895c2d04 6386 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6387 rn = "DataLo";
6388 break;
6389 default:
6390 goto die;
6391 }
6392 break;
6393 case 29:
6394 switch (sel) {
6395 case 0:
6396 case 2:
6397 case 4:
6398 case 6:
895c2d04 6399 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6400 rn = "TagHi";
6401 break;
6402 case 1:
6403 case 3:
6404 case 5:
6405 case 7:
895c2d04 6406 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6407 rn = "DataHi";
6408 break;
6409 default:
6410 rn = "invalid sel";
6411 goto die;
6412 }
876d4b07 6413 break;
9c2149c8
TS
6414 case 30:
6415 switch (sel) {
6416 case 0:
7db13fae 6417 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6418 rn = "ErrorEPC";
6419 break;
9c2149c8
TS
6420 default:
6421 goto die;
6422 }
6423 break;
6424 case 31:
6425 switch (sel) {
6426 case 0:
f1aa6320 6427 /* EJTAG support */
7db13fae 6428 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6429 rn = "DESAVE";
6430 break;
9c2149c8
TS
6431 default:
6432 goto die;
6433 }
876d4b07
TS
6434 /* Stop translation as we may have switched the execution mode */
6435 ctx->bstate = BS_STOP;
9c2149c8
TS
6436 break;
6437 default:
876d4b07 6438 goto die;
9c2149c8 6439 }
2abf314d 6440 (void)rn; /* avoid a compiler warning */
d12d51d5 6441 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6442 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6443 if (use_icount) {
6444 gen_io_end();
6445 ctx->bstate = BS_STOP;
6446 }
9c2149c8
TS
6447 return;
6448
6449die:
d12d51d5 6450 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6451 generate_exception(ctx, EXCP_RI);
6452}
d26bc211 6453#endif /* TARGET_MIPS64 */
9c2149c8 6454
7db13fae 6455static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6456 int u, int sel, int h)
6457{
6458 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6459 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6460
6461 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6462 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6463 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6464 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6465 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6466 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6467 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6468 else if (u == 0) {
6469 switch (rt) {
5a25ce94
EI
6470 case 1:
6471 switch (sel) {
6472 case 1:
895c2d04 6473 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6474 break;
6475 case 2:
895c2d04 6476 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6477 break;
6478 default:
6479 goto die;
6480 break;
6481 }
6482 break;
ead9360e
TS
6483 case 2:
6484 switch (sel) {
6485 case 1:
895c2d04 6486 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6487 break;
6488 case 2:
895c2d04 6489 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6490 break;
6491 case 3:
895c2d04 6492 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6493 break;
6494 case 4:
895c2d04 6495 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6496 break;
6497 case 5:
895c2d04 6498 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6499 break;
6500 case 6:
895c2d04 6501 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6502 break;
6503 case 7:
895c2d04 6504 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6505 break;
6506 default:
d75c135e 6507 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6508 break;
6509 }
6510 break;
6511 case 10:
6512 switch (sel) {
6513 case 0:
895c2d04 6514 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6515 break;
6516 default:
d75c135e 6517 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6518 break;
6519 }
6520 case 12:
6521 switch (sel) {
6522 case 0:
895c2d04 6523 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6524 break;
6525 default:
d75c135e 6526 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6527 break;
6528 }
5a25ce94
EI
6529 case 13:
6530 switch (sel) {
6531 case 0:
895c2d04 6532 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6533 break;
6534 default:
6535 goto die;
6536 break;
6537 }
6538 break;
6539 case 14:
6540 switch (sel) {
6541 case 0:
895c2d04 6542 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6543 break;
6544 default:
6545 goto die;
6546 break;
6547 }
6548 break;
6549 case 15:
6550 switch (sel) {
6551 case 1:
895c2d04 6552 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6553 break;
6554 default:
6555 goto die;
6556 break;
6557 }
6558 break;
6559 case 16:
6560 switch (sel) {
6561 case 0 ... 7:
895c2d04 6562 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6563 break;
6564 default:
6565 goto die;
6566 break;
6567 }
6568 break;
ead9360e
TS
6569 case 23:
6570 switch (sel) {
6571 case 0:
895c2d04 6572 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6573 break;
6574 default:
d75c135e 6575 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6576 break;
6577 }
6578 break;
6579 default:
d75c135e 6580 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6581 }
6582 } else switch (sel) {
6583 /* GPR registers. */
6584 case 0:
895c2d04 6585 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6586 break;
6587 /* Auxiliary CPU registers */
6588 case 1:
6589 switch (rt) {
6590 case 0:
895c2d04 6591 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6592 break;
6593 case 1:
895c2d04 6594 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6595 break;
6596 case 2:
895c2d04 6597 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6598 break;
6599 case 4:
895c2d04 6600 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6601 break;
6602 case 5:
895c2d04 6603 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6604 break;
6605 case 6:
895c2d04 6606 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6607 break;
6608 case 8:
895c2d04 6609 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6610 break;
6611 case 9:
895c2d04 6612 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6613 break;
6614 case 10:
895c2d04 6615 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6616 break;
6617 case 12:
895c2d04 6618 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6619 break;
6620 case 13:
895c2d04 6621 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6622 break;
6623 case 14:
895c2d04 6624 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6625 break;
6626 case 16:
895c2d04 6627 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6628 break;
6629 default:
6630 goto die;
6631 }
6632 break;
6633 /* Floating point (COP1). */
6634 case 2:
6635 /* XXX: For now we support only a single FPU context. */
6636 if (h == 0) {
a7812ae4 6637 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6638
6639 gen_load_fpr32(fp0, rt);
6640 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6641 tcg_temp_free_i32(fp0);
ead9360e 6642 } else {
a7812ae4 6643 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6644
6645 gen_load_fpr32h(fp0, rt);
6646 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6647 tcg_temp_free_i32(fp0);
ead9360e
TS
6648 }
6649 break;
6650 case 3:
6651 /* XXX: For now we support only a single FPU context. */
895c2d04 6652 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6653 break;
6654 /* COP2: Not implemented. */
6655 case 4:
6656 case 5:
6657 /* fall through */
6658 default:
6659 goto die;
6660 }
d12d51d5 6661 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6662 gen_store_gpr(t0, rd);
6663 tcg_temp_free(t0);
ead9360e
TS
6664 return;
6665
6666die:
1a3fd9c3 6667 tcg_temp_free(t0);
d12d51d5 6668 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6669 generate_exception(ctx, EXCP_RI);
6670}
6671
7db13fae 6672static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6673 int u, int sel, int h)
6674{
6675 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6676 TCGv t0 = tcg_temp_local_new();
ead9360e 6677
1a3fd9c3 6678 gen_load_gpr(t0, rt);
ead9360e 6679 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6680 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6681 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6682 /* NOP */ ;
6683 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6684 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6685 /* NOP */ ;
6686 else if (u == 0) {
6687 switch (rd) {
5a25ce94
EI
6688 case 1:
6689 switch (sel) {
6690 case 1:
895c2d04 6691 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6692 break;
6693 case 2:
895c2d04 6694 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6695 break;
6696 default:
6697 goto die;
6698 break;
6699 }
6700 break;
ead9360e
TS
6701 case 2:
6702 switch (sel) {
6703 case 1:
895c2d04 6704 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6705 break;
6706 case 2:
895c2d04 6707 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6708 break;
6709 case 3:
895c2d04 6710 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6711 break;
6712 case 4:
895c2d04 6713 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6714 break;
6715 case 5:
895c2d04 6716 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6717 break;
6718 case 6:
895c2d04 6719 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6720 break;
6721 case 7:
895c2d04 6722 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6723 break;
6724 default:
d75c135e 6725 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6726 break;
6727 }
6728 break;
6729 case 10:
6730 switch (sel) {
6731 case 0:
895c2d04 6732 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6733 break;
6734 default:
d75c135e 6735 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6736 break;
6737 }
6738 case 12:
6739 switch (sel) {
6740 case 0:
895c2d04 6741 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6742 break;
6743 default:
d75c135e 6744 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6745 break;
6746 }
5a25ce94
EI
6747 case 13:
6748 switch (sel) {
6749 case 0:
895c2d04 6750 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6751 break;
6752 default:
6753 goto die;
6754 break;
6755 }
6756 break;
6757 case 15:
6758 switch (sel) {
6759 case 1:
895c2d04 6760 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6761 break;
6762 default:
6763 goto die;
6764 break;
6765 }
6766 break;
ead9360e
TS
6767 case 23:
6768 switch (sel) {
6769 case 0:
895c2d04 6770 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6771 break;
6772 default:
d75c135e 6773 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6774 break;
6775 }
6776 break;
6777 default:
d75c135e 6778 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
6779 }
6780 } else switch (sel) {
6781 /* GPR registers. */
6782 case 0:
895c2d04 6783 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6784 break;
6785 /* Auxiliary CPU registers */
6786 case 1:
6787 switch (rd) {
6788 case 0:
895c2d04 6789 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6790 break;
6791 case 1:
895c2d04 6792 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6793 break;
6794 case 2:
895c2d04 6795 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6796 break;
6797 case 4:
895c2d04 6798 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6799 break;
6800 case 5:
895c2d04 6801 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6802 break;
6803 case 6:
895c2d04 6804 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6805 break;
6806 case 8:
895c2d04 6807 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6808 break;
6809 case 9:
895c2d04 6810 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6811 break;
6812 case 10:
895c2d04 6813 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6814 break;
6815 case 12:
895c2d04 6816 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6817 break;
6818 case 13:
895c2d04 6819 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6820 break;
6821 case 14:
895c2d04 6822 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6823 break;
6824 case 16:
895c2d04 6825 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6826 break;
6827 default:
6828 goto die;
6829 }
6830 break;
6831 /* Floating point (COP1). */
6832 case 2:
6833 /* XXX: For now we support only a single FPU context. */
6834 if (h == 0) {
a7812ae4 6835 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6836
6837 tcg_gen_trunc_tl_i32(fp0, t0);
6838 gen_store_fpr32(fp0, rd);
a7812ae4 6839 tcg_temp_free_i32(fp0);
ead9360e 6840 } else {
a7812ae4 6841 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6842
6843 tcg_gen_trunc_tl_i32(fp0, t0);
6844 gen_store_fpr32h(fp0, rd);
a7812ae4 6845 tcg_temp_free_i32(fp0);
ead9360e
TS
6846 }
6847 break;
6848 case 3:
6849 /* XXX: For now we support only a single FPU context. */
895c2d04 6850 gen_helper_0e1i(ctc1, t0, rd);
ead9360e
TS
6851 break;
6852 /* COP2: Not implemented. */
6853 case 4:
6854 case 5:
6855 /* fall through */
6856 default:
6857 goto die;
6858 }
d12d51d5 6859 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6860 tcg_temp_free(t0);
ead9360e
TS
6861 return;
6862
6863die:
1a3fd9c3 6864 tcg_temp_free(t0);
d12d51d5 6865 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6866 generate_exception(ctx, EXCP_RI);
6867}
6868
7db13fae 6869static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6870{
287c4b84 6871 const char *opn = "ldst";
6af0bf9c 6872
2e15497c 6873 check_cp0_enabled(ctx);
6af0bf9c
FB
6874 switch (opc) {
6875 case OPC_MFC0:
6876 if (rt == 0) {
ead9360e 6877 /* Treat as NOP. */
6af0bf9c
FB
6878 return;
6879 }
d75c135e 6880 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6881 opn = "mfc0";
6882 break;
6883 case OPC_MTC0:
1a3fd9c3 6884 {
1fc7bf6e 6885 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6886
6887 gen_load_gpr(t0, rt);
d75c135e 6888 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6889 tcg_temp_free(t0);
6890 }
6af0bf9c
FB
6891 opn = "mtc0";
6892 break;
d26bc211 6893#if defined(TARGET_MIPS64)
9c2149c8 6894 case OPC_DMFC0:
d75c135e 6895 check_insn(ctx, ISA_MIPS3);
9c2149c8 6896 if (rt == 0) {
ead9360e 6897 /* Treat as NOP. */
9c2149c8
TS
6898 return;
6899 }
d75c135e 6900 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6901 opn = "dmfc0";
6902 break;
6903 case OPC_DMTC0:
d75c135e 6904 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 6905 {
1fc7bf6e 6906 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6907
6908 gen_load_gpr(t0, rt);
d75c135e 6909 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
6910 tcg_temp_free(t0);
6911 }
9c2149c8
TS
6912 opn = "dmtc0";
6913 break;
534ce69f 6914#endif
ead9360e 6915 case OPC_MFTR:
d75c135e 6916 check_insn(ctx, ASE_MT);
ead9360e
TS
6917 if (rd == 0) {
6918 /* Treat as NOP. */
6919 return;
6920 }
6c5c1e20 6921 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6922 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6923 opn = "mftr";
6924 break;
6925 case OPC_MTTR:
d75c135e 6926 check_insn(ctx, ASE_MT);
6c5c1e20 6927 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6928 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6929 opn = "mttr";
6930 break;
6af0bf9c 6931 case OPC_TLBWI:
6af0bf9c 6932 opn = "tlbwi";
c01fccd2 6933 if (!env->tlb->helper_tlbwi)
29929e34 6934 goto die;
895c2d04 6935 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6936 break;
6937 case OPC_TLBWR:
6af0bf9c 6938 opn = "tlbwr";
c01fccd2 6939 if (!env->tlb->helper_tlbwr)
29929e34 6940 goto die;
895c2d04 6941 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6942 break;
6943 case OPC_TLBP:
6af0bf9c 6944 opn = "tlbp";
c01fccd2 6945 if (!env->tlb->helper_tlbp)
29929e34 6946 goto die;
895c2d04 6947 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6948 break;
6949 case OPC_TLBR:
6af0bf9c 6950 opn = "tlbr";
c01fccd2 6951 if (!env->tlb->helper_tlbr)
29929e34 6952 goto die;
895c2d04 6953 gen_helper_tlbr(cpu_env);
6af0bf9c 6954 break;
6af0bf9c
FB
6955 case OPC_ERET:
6956 opn = "eret";
d75c135e 6957 check_insn(ctx, ISA_MIPS2);
895c2d04 6958 gen_helper_eret(cpu_env);
6af0bf9c
FB
6959 ctx->bstate = BS_EXCP;
6960 break;
6961 case OPC_DERET:
6962 opn = "deret";
d75c135e 6963 check_insn(ctx, ISA_MIPS32);
6af0bf9c 6964 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6965 MIPS_INVAL(opn);
6af0bf9c
FB
6966 generate_exception(ctx, EXCP_RI);
6967 } else {
895c2d04 6968 gen_helper_deret(cpu_env);
6af0bf9c
FB
6969 ctx->bstate = BS_EXCP;
6970 }
6971 break;
4ad40f36
FB
6972 case OPC_WAIT:
6973 opn = "wait";
d75c135e 6974 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6975 /* If we get an exception, we want to restart at next instruction */
6976 ctx->pc += 4;
6977 save_cpu_state(ctx, 1);
6978 ctx->pc -= 4;
895c2d04 6979 gen_helper_wait(cpu_env);
4ad40f36
FB
6980 ctx->bstate = BS_EXCP;
6981 break;
6af0bf9c 6982 default:
29929e34 6983 die:
923617a3 6984 MIPS_INVAL(opn);
6af0bf9c
FB
6985 generate_exception(ctx, EXCP_RI);
6986 return;
6987 }
2abf314d 6988 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
6989 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6990}
f1aa6320 6991#endif /* !CONFIG_USER_ONLY */
6af0bf9c 6992
6ea83fed 6993/* CP1 Branches (before delay slot) */
d75c135e
AJ
6994static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6995 int32_t cc, int32_t offset)
6ea83fed
FB
6996{
6997 target_ulong btarget;
923617a3 6998 const char *opn = "cp1 cond branch";
a7812ae4 6999 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7000
e189e748 7001 if (cc != 0)
d75c135e 7002 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7003
6ea83fed
FB
7004 btarget = ctx->pc + 4 + offset;
7005
7a387fff
TS
7006 switch (op) {
7007 case OPC_BC1F:
d94536f4
AJ
7008 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7009 tcg_gen_not_i32(t0, t0);
7010 tcg_gen_andi_i32(t0, t0, 1);
7011 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7012 opn = "bc1f";
6ea83fed 7013 goto not_likely;
7a387fff 7014 case OPC_BC1FL:
d94536f4
AJ
7015 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7016 tcg_gen_not_i32(t0, t0);
7017 tcg_gen_andi_i32(t0, t0, 1);
7018 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7019 opn = "bc1fl";
6ea83fed 7020 goto likely;
7a387fff 7021 case OPC_BC1T:
d94536f4
AJ
7022 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7023 tcg_gen_andi_i32(t0, t0, 1);
7024 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7025 opn = "bc1t";
5a5012ec 7026 goto not_likely;
7a387fff 7027 case OPC_BC1TL:
d94536f4
AJ
7028 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7029 tcg_gen_andi_i32(t0, t0, 1);
7030 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7031 opn = "bc1tl";
6ea83fed
FB
7032 likely:
7033 ctx->hflags |= MIPS_HFLAG_BL;
7034 break;
5a5012ec 7035 case OPC_BC1FANY2:
a16336e4 7036 {
d94536f4
AJ
7037 TCGv_i32 t1 = tcg_temp_new_i32();
7038 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7039 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7040 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7041 tcg_temp_free_i32(t1);
d94536f4
AJ
7042 tcg_gen_andi_i32(t0, t0, 1);
7043 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7044 }
fd4a04eb 7045 opn = "bc1any2f";
5a5012ec
TS
7046 goto not_likely;
7047 case OPC_BC1TANY2:
a16336e4 7048 {
d94536f4
AJ
7049 TCGv_i32 t1 = tcg_temp_new_i32();
7050 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7051 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7052 tcg_gen_or_i32(t0, t0, t1);
7053 tcg_temp_free_i32(t1);
7054 tcg_gen_andi_i32(t0, t0, 1);
7055 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7056 }
fd4a04eb 7057 opn = "bc1any2t";
5a5012ec
TS
7058 goto not_likely;
7059 case OPC_BC1FANY4:
a16336e4 7060 {
d94536f4
AJ
7061 TCGv_i32 t1 = tcg_temp_new_i32();
7062 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7063 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7064 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7065 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7066 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7067 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7068 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7069 tcg_temp_free_i32(t1);
d94536f4
AJ
7070 tcg_gen_andi_i32(t0, t0, 1);
7071 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7072 }
fd4a04eb 7073 opn = "bc1any4f";
5a5012ec
TS
7074 goto not_likely;
7075 case OPC_BC1TANY4:
a16336e4 7076 {
d94536f4
AJ
7077 TCGv_i32 t1 = tcg_temp_new_i32();
7078 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7079 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7080 tcg_gen_or_i32(t0, t0, t1);
7081 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7082 tcg_gen_or_i32(t0, t0, t1);
7083 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7084 tcg_gen_or_i32(t0, t0, t1);
7085 tcg_temp_free_i32(t1);
7086 tcg_gen_andi_i32(t0, t0, 1);
7087 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7088 }
fd4a04eb 7089 opn = "bc1any4t";
5a5012ec
TS
7090 not_likely:
7091 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7092 break;
7093 default:
923617a3 7094 MIPS_INVAL(opn);
e397ee33 7095 generate_exception (ctx, EXCP_RI);
6c5c1e20 7096 goto out;
6ea83fed 7097 }
2abf314d 7098 (void)opn; /* avoid a compiler warning */
923617a3 7099 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7100 ctx->hflags, btarget);
7101 ctx->btarget = btarget;
6c5c1e20
TS
7102
7103 out:
a7812ae4 7104 tcg_temp_free_i32(t0);
6ea83fed
FB
7105}
7106
6af0bf9c 7107/* Coprocessor 1 (FPU) */
5a5012ec 7108
5a5012ec
TS
7109#define FOP(func, fmt) (((fmt) << 21) | (func))
7110
bf4120ad
NF
7111enum fopcode {
7112 OPC_ADD_S = FOP(0, FMT_S),
7113 OPC_SUB_S = FOP(1, FMT_S),
7114 OPC_MUL_S = FOP(2, FMT_S),
7115 OPC_DIV_S = FOP(3, FMT_S),
7116 OPC_SQRT_S = FOP(4, FMT_S),
7117 OPC_ABS_S = FOP(5, FMT_S),
7118 OPC_MOV_S = FOP(6, FMT_S),
7119 OPC_NEG_S = FOP(7, FMT_S),
7120 OPC_ROUND_L_S = FOP(8, FMT_S),
7121 OPC_TRUNC_L_S = FOP(9, FMT_S),
7122 OPC_CEIL_L_S = FOP(10, FMT_S),
7123 OPC_FLOOR_L_S = FOP(11, FMT_S),
7124 OPC_ROUND_W_S = FOP(12, FMT_S),
7125 OPC_TRUNC_W_S = FOP(13, FMT_S),
7126 OPC_CEIL_W_S = FOP(14, FMT_S),
7127 OPC_FLOOR_W_S = FOP(15, FMT_S),
7128 OPC_MOVCF_S = FOP(17, FMT_S),
7129 OPC_MOVZ_S = FOP(18, FMT_S),
7130 OPC_MOVN_S = FOP(19, FMT_S),
7131 OPC_RECIP_S = FOP(21, FMT_S),
7132 OPC_RSQRT_S = FOP(22, FMT_S),
7133 OPC_RECIP2_S = FOP(28, FMT_S),
7134 OPC_RECIP1_S = FOP(29, FMT_S),
7135 OPC_RSQRT1_S = FOP(30, FMT_S),
7136 OPC_RSQRT2_S = FOP(31, FMT_S),
7137 OPC_CVT_D_S = FOP(33, FMT_S),
7138 OPC_CVT_W_S = FOP(36, FMT_S),
7139 OPC_CVT_L_S = FOP(37, FMT_S),
7140 OPC_CVT_PS_S = FOP(38, FMT_S),
7141 OPC_CMP_F_S = FOP (48, FMT_S),
7142 OPC_CMP_UN_S = FOP (49, FMT_S),
7143 OPC_CMP_EQ_S = FOP (50, FMT_S),
7144 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7145 OPC_CMP_OLT_S = FOP (52, FMT_S),
7146 OPC_CMP_ULT_S = FOP (53, FMT_S),
7147 OPC_CMP_OLE_S = FOP (54, FMT_S),
7148 OPC_CMP_ULE_S = FOP (55, FMT_S),
7149 OPC_CMP_SF_S = FOP (56, FMT_S),
7150 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7151 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7152 OPC_CMP_NGL_S = FOP (59, FMT_S),
7153 OPC_CMP_LT_S = FOP (60, FMT_S),
7154 OPC_CMP_NGE_S = FOP (61, FMT_S),
7155 OPC_CMP_LE_S = FOP (62, FMT_S),
7156 OPC_CMP_NGT_S = FOP (63, FMT_S),
7157
7158 OPC_ADD_D = FOP(0, FMT_D),
7159 OPC_SUB_D = FOP(1, FMT_D),
7160 OPC_MUL_D = FOP(2, FMT_D),
7161 OPC_DIV_D = FOP(3, FMT_D),
7162 OPC_SQRT_D = FOP(4, FMT_D),
7163 OPC_ABS_D = FOP(5, FMT_D),
7164 OPC_MOV_D = FOP(6, FMT_D),
7165 OPC_NEG_D = FOP(7, FMT_D),
7166 OPC_ROUND_L_D = FOP(8, FMT_D),
7167 OPC_TRUNC_L_D = FOP(9, FMT_D),
7168 OPC_CEIL_L_D = FOP(10, FMT_D),
7169 OPC_FLOOR_L_D = FOP(11, FMT_D),
7170 OPC_ROUND_W_D = FOP(12, FMT_D),
7171 OPC_TRUNC_W_D = FOP(13, FMT_D),
7172 OPC_CEIL_W_D = FOP(14, FMT_D),
7173 OPC_FLOOR_W_D = FOP(15, FMT_D),
7174 OPC_MOVCF_D = FOP(17, FMT_D),
7175 OPC_MOVZ_D = FOP(18, FMT_D),
7176 OPC_MOVN_D = FOP(19, FMT_D),
7177 OPC_RECIP_D = FOP(21, FMT_D),
7178 OPC_RSQRT_D = FOP(22, FMT_D),
7179 OPC_RECIP2_D = FOP(28, FMT_D),
7180 OPC_RECIP1_D = FOP(29, FMT_D),
7181 OPC_RSQRT1_D = FOP(30, FMT_D),
7182 OPC_RSQRT2_D = FOP(31, FMT_D),
7183 OPC_CVT_S_D = FOP(32, FMT_D),
7184 OPC_CVT_W_D = FOP(36, FMT_D),
7185 OPC_CVT_L_D = FOP(37, FMT_D),
7186 OPC_CMP_F_D = FOP (48, FMT_D),
7187 OPC_CMP_UN_D = FOP (49, FMT_D),
7188 OPC_CMP_EQ_D = FOP (50, FMT_D),
7189 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7190 OPC_CMP_OLT_D = FOP (52, FMT_D),
7191 OPC_CMP_ULT_D = FOP (53, FMT_D),
7192 OPC_CMP_OLE_D = FOP (54, FMT_D),
7193 OPC_CMP_ULE_D = FOP (55, FMT_D),
7194 OPC_CMP_SF_D = FOP (56, FMT_D),
7195 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7196 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7197 OPC_CMP_NGL_D = FOP (59, FMT_D),
7198 OPC_CMP_LT_D = FOP (60, FMT_D),
7199 OPC_CMP_NGE_D = FOP (61, FMT_D),
7200 OPC_CMP_LE_D = FOP (62, FMT_D),
7201 OPC_CMP_NGT_D = FOP (63, FMT_D),
7202
7203 OPC_CVT_S_W = FOP(32, FMT_W),
7204 OPC_CVT_D_W = FOP(33, FMT_W),
7205 OPC_CVT_S_L = FOP(32, FMT_L),
7206 OPC_CVT_D_L = FOP(33, FMT_L),
7207 OPC_CVT_PS_PW = FOP(38, FMT_W),
7208
7209 OPC_ADD_PS = FOP(0, FMT_PS),
7210 OPC_SUB_PS = FOP(1, FMT_PS),
7211 OPC_MUL_PS = FOP(2, FMT_PS),
7212 OPC_DIV_PS = FOP(3, FMT_PS),
7213 OPC_ABS_PS = FOP(5, FMT_PS),
7214 OPC_MOV_PS = FOP(6, FMT_PS),
7215 OPC_NEG_PS = FOP(7, FMT_PS),
7216 OPC_MOVCF_PS = FOP(17, FMT_PS),
7217 OPC_MOVZ_PS = FOP(18, FMT_PS),
7218 OPC_MOVN_PS = FOP(19, FMT_PS),
7219 OPC_ADDR_PS = FOP(24, FMT_PS),
7220 OPC_MULR_PS = FOP(26, FMT_PS),
7221 OPC_RECIP2_PS = FOP(28, FMT_PS),
7222 OPC_RECIP1_PS = FOP(29, FMT_PS),
7223 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7224 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7225
7226 OPC_CVT_S_PU = FOP(32, FMT_PS),
7227 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7228 OPC_CVT_S_PL = FOP(40, FMT_PS),
7229 OPC_PLL_PS = FOP(44, FMT_PS),
7230 OPC_PLU_PS = FOP(45, FMT_PS),
7231 OPC_PUL_PS = FOP(46, FMT_PS),
7232 OPC_PUU_PS = FOP(47, FMT_PS),
7233 OPC_CMP_F_PS = FOP (48, FMT_PS),
7234 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7235 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7236 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7237 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7238 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7239 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7240 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7241 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7242 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7243 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7244 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7245 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7246 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7247 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7248 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7249};
7250
7a387fff 7251static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7252{
923617a3 7253 const char *opn = "cp1 move";
72c3a3ee 7254 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7255
7256 switch (opc) {
7257 case OPC_MFC1:
b6d96bed 7258 {
a7812ae4 7259 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7260
7261 gen_load_fpr32(fp0, fs);
7262 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7263 tcg_temp_free_i32(fp0);
6958549d 7264 }
6c5c1e20 7265 gen_store_gpr(t0, rt);
6ea83fed
FB
7266 opn = "mfc1";
7267 break;
7268 case OPC_MTC1:
6c5c1e20 7269 gen_load_gpr(t0, rt);
b6d96bed 7270 {
a7812ae4 7271 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7272
7273 tcg_gen_trunc_tl_i32(fp0, t0);
7274 gen_store_fpr32(fp0, fs);
a7812ae4 7275 tcg_temp_free_i32(fp0);
6958549d 7276 }
6ea83fed
FB
7277 opn = "mtc1";
7278 break;
7279 case OPC_CFC1:
895c2d04 7280 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7281 gen_store_gpr(t0, rt);
6ea83fed
FB
7282 opn = "cfc1";
7283 break;
7284 case OPC_CTC1:
6c5c1e20 7285 gen_load_gpr(t0, rt);
895c2d04 7286 gen_helper_0e1i(ctc1, t0, fs);
6ea83fed
FB
7287 opn = "ctc1";
7288 break;
72c3a3ee 7289#if defined(TARGET_MIPS64)
9c2149c8 7290 case OPC_DMFC1:
72c3a3ee 7291 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7292 gen_store_gpr(t0, rt);
5a5012ec
TS
7293 opn = "dmfc1";
7294 break;
9c2149c8 7295 case OPC_DMTC1:
6c5c1e20 7296 gen_load_gpr(t0, rt);
72c3a3ee 7297 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7298 opn = "dmtc1";
7299 break;
72c3a3ee 7300#endif
5a5012ec 7301 case OPC_MFHC1:
b6d96bed 7302 {
a7812ae4 7303 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7304
7305 gen_load_fpr32h(fp0, fs);
7306 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7307 tcg_temp_free_i32(fp0);
6958549d 7308 }
6c5c1e20 7309 gen_store_gpr(t0, rt);
5a5012ec
TS
7310 opn = "mfhc1";
7311 break;
7312 case OPC_MTHC1:
6c5c1e20 7313 gen_load_gpr(t0, rt);
b6d96bed 7314 {
a7812ae4 7315 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7316
7317 tcg_gen_trunc_tl_i32(fp0, t0);
7318 gen_store_fpr32h(fp0, fs);
a7812ae4 7319 tcg_temp_free_i32(fp0);
6958549d 7320 }
5a5012ec
TS
7321 opn = "mthc1";
7322 break;
6ea83fed 7323 default:
923617a3 7324 MIPS_INVAL(opn);
e397ee33 7325 generate_exception (ctx, EXCP_RI);
6c5c1e20 7326 goto out;
6ea83fed 7327 }
2abf314d 7328 (void)opn; /* avoid a compiler warning */
6ea83fed 7329 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7330
7331 out:
7332 tcg_temp_free(t0);
6ea83fed
FB
7333}
7334
5a5012ec
TS
7335static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7336{
af58f9ca 7337 int l1;
e214b9bb 7338 TCGCond cond;
af58f9ca
AJ
7339 TCGv_i32 t0;
7340
7341 if (rd == 0) {
7342 /* Treat as NOP. */
7343 return;
7344 }
6ea83fed 7345
e214b9bb 7346 if (tf)
e214b9bb 7347 cond = TCG_COND_EQ;
27848470
TS
7348 else
7349 cond = TCG_COND_NE;
7350
af58f9ca
AJ
7351 l1 = gen_new_label();
7352 t0 = tcg_temp_new_i32();
fa31af0e 7353 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7354 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7355 tcg_temp_free_i32(t0);
af58f9ca
AJ
7356 if (rs == 0) {
7357 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7358 } else {
7359 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7360 }
e214b9bb 7361 gen_set_label(l1);
5a5012ec
TS
7362}
7363
b6d96bed 7364static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7365{
a16336e4 7366 int cond;
cbc37b28 7367 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7368 int l1 = gen_new_label();
7369
a16336e4
TS
7370 if (tf)
7371 cond = TCG_COND_EQ;
7372 else
7373 cond = TCG_COND_NE;
7374
fa31af0e 7375 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7376 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7377 gen_load_fpr32(t0, fs);
7378 gen_store_fpr32(t0, fd);
a16336e4 7379 gen_set_label(l1);
cbc37b28 7380 tcg_temp_free_i32(t0);
5a5012ec 7381}
a16336e4 7382
b6d96bed 7383static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7384{
a16336e4 7385 int cond;
cbc37b28
AJ
7386 TCGv_i32 t0 = tcg_temp_new_i32();
7387 TCGv_i64 fp0;
a16336e4
TS
7388 int l1 = gen_new_label();
7389
a16336e4
TS
7390 if (tf)
7391 cond = TCG_COND_EQ;
7392 else
7393 cond = TCG_COND_NE;
7394
fa31af0e 7395 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7396 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7397 tcg_temp_free_i32(t0);
11f94258 7398 fp0 = tcg_temp_new_i64();
9bf3eb2c 7399 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7400 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7401 tcg_temp_free_i64(fp0);
cbc37b28 7402 gen_set_label(l1);
a16336e4
TS
7403}
7404
b6d96bed 7405static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
a16336e4
TS
7406{
7407 int cond;
cbc37b28 7408 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7409 int l1 = gen_new_label();
7410 int l2 = gen_new_label();
7411
7412 if (tf)
7413 cond = TCG_COND_EQ;
7414 else
7415 cond = TCG_COND_NE;
7416
fa31af0e 7417 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7418 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7419 gen_load_fpr32(t0, fs);
7420 gen_store_fpr32(t0, fd);
a16336e4 7421 gen_set_label(l1);
9bf3eb2c 7422
fa31af0e 7423 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28
AJ
7424 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7425 gen_load_fpr32h(t0, fs);
7426 gen_store_fpr32h(t0, fd);
52a0e9eb 7427 tcg_temp_free_i32(t0);
a16336e4 7428 gen_set_label(l2);
a16336e4
TS
7429}
7430
6ea83fed 7431
bf4120ad 7432static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7433 int ft, int fs, int fd, int cc)
6ea83fed 7434{
923617a3 7435 const char *opn = "farith";
6ea83fed
FB
7436 const char *condnames[] = {
7437 "c.f",
7438 "c.un",
7439 "c.eq",
7440 "c.ueq",
7441 "c.olt",
7442 "c.ult",
7443 "c.ole",
7444 "c.ule",
7445 "c.sf",
7446 "c.ngle",
7447 "c.seq",
7448 "c.ngl",
7449 "c.lt",
7450 "c.nge",
7451 "c.le",
7452 "c.ngt",
7453 };
5a1e8ffb
TS
7454 const char *condnames_abs[] = {
7455 "cabs.f",
7456 "cabs.un",
7457 "cabs.eq",
7458 "cabs.ueq",
7459 "cabs.olt",
7460 "cabs.ult",
7461 "cabs.ole",
7462 "cabs.ule",
7463 "cabs.sf",
7464 "cabs.ngle",
7465 "cabs.seq",
7466 "cabs.ngl",
7467 "cabs.lt",
7468 "cabs.nge",
7469 "cabs.le",
7470 "cabs.ngt",
7471 };
7472 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7473 uint32_t func = ctx->opcode & 0x3f;
7474
bf4120ad
NF
7475 switch (op1) {
7476 case OPC_ADD_S:
b6d96bed 7477 {
a7812ae4
PB
7478 TCGv_i32 fp0 = tcg_temp_new_i32();
7479 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7480
7481 gen_load_fpr32(fp0, fs);
7482 gen_load_fpr32(fp1, ft);
895c2d04 7483 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7484 tcg_temp_free_i32(fp1);
b6d96bed 7485 gen_store_fpr32(fp0, fd);
a7812ae4 7486 tcg_temp_free_i32(fp0);
b6d96bed 7487 }
5a5012ec 7488 opn = "add.s";
5a1e8ffb 7489 optype = BINOP;
5a5012ec 7490 break;
bf4120ad 7491 case OPC_SUB_S:
b6d96bed 7492 {
a7812ae4
PB
7493 TCGv_i32 fp0 = tcg_temp_new_i32();
7494 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7495
7496 gen_load_fpr32(fp0, fs);
7497 gen_load_fpr32(fp1, ft);
895c2d04 7498 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7499 tcg_temp_free_i32(fp1);
b6d96bed 7500 gen_store_fpr32(fp0, fd);
a7812ae4 7501 tcg_temp_free_i32(fp0);
b6d96bed 7502 }
5a5012ec 7503 opn = "sub.s";
5a1e8ffb 7504 optype = BINOP;
5a5012ec 7505 break;
bf4120ad 7506 case OPC_MUL_S:
b6d96bed 7507 {
a7812ae4
PB
7508 TCGv_i32 fp0 = tcg_temp_new_i32();
7509 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7510
7511 gen_load_fpr32(fp0, fs);
7512 gen_load_fpr32(fp1, ft);
895c2d04 7513 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7514 tcg_temp_free_i32(fp1);
b6d96bed 7515 gen_store_fpr32(fp0, fd);
a7812ae4 7516 tcg_temp_free_i32(fp0);
b6d96bed 7517 }
5a5012ec 7518 opn = "mul.s";
5a1e8ffb 7519 optype = BINOP;
5a5012ec 7520 break;
bf4120ad 7521 case OPC_DIV_S:
b6d96bed 7522 {
a7812ae4
PB
7523 TCGv_i32 fp0 = tcg_temp_new_i32();
7524 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7525
7526 gen_load_fpr32(fp0, fs);
7527 gen_load_fpr32(fp1, ft);
895c2d04 7528 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7529 tcg_temp_free_i32(fp1);
b6d96bed 7530 gen_store_fpr32(fp0, fd);
a7812ae4 7531 tcg_temp_free_i32(fp0);
b6d96bed 7532 }
5a5012ec 7533 opn = "div.s";
5a1e8ffb 7534 optype = BINOP;
5a5012ec 7535 break;
bf4120ad 7536 case OPC_SQRT_S:
b6d96bed 7537 {
a7812ae4 7538 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7539
7540 gen_load_fpr32(fp0, fs);
895c2d04 7541 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7542 gen_store_fpr32(fp0, fd);
a7812ae4 7543 tcg_temp_free_i32(fp0);
b6d96bed 7544 }
5a5012ec
TS
7545 opn = "sqrt.s";
7546 break;
bf4120ad 7547 case OPC_ABS_S:
b6d96bed 7548 {
a7812ae4 7549 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7550
7551 gen_load_fpr32(fp0, fs);
a7812ae4 7552 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7553 gen_store_fpr32(fp0, fd);
a7812ae4 7554 tcg_temp_free_i32(fp0);
b6d96bed 7555 }
5a5012ec
TS
7556 opn = "abs.s";
7557 break;
bf4120ad 7558 case OPC_MOV_S:
b6d96bed 7559 {
a7812ae4 7560 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7561
7562 gen_load_fpr32(fp0, fs);
7563 gen_store_fpr32(fp0, fd);
a7812ae4 7564 tcg_temp_free_i32(fp0);
b6d96bed 7565 }
5a5012ec
TS
7566 opn = "mov.s";
7567 break;
bf4120ad 7568 case OPC_NEG_S:
b6d96bed 7569 {
a7812ae4 7570 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7571
7572 gen_load_fpr32(fp0, fs);
a7812ae4 7573 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7574 gen_store_fpr32(fp0, fd);
a7812ae4 7575 tcg_temp_free_i32(fp0);
b6d96bed 7576 }
5a5012ec
TS
7577 opn = "neg.s";
7578 break;
bf4120ad 7579 case OPC_ROUND_L_S:
5e755519 7580 check_cp1_64bitmode(ctx);
b6d96bed 7581 {
a7812ae4
PB
7582 TCGv_i32 fp32 = tcg_temp_new_i32();
7583 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7584
7585 gen_load_fpr32(fp32, fs);
895c2d04 7586 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7587 tcg_temp_free_i32(fp32);
b6d96bed 7588 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7589 tcg_temp_free_i64(fp64);
b6d96bed 7590 }
5a5012ec
TS
7591 opn = "round.l.s";
7592 break;
bf4120ad 7593 case OPC_TRUNC_L_S:
5e755519 7594 check_cp1_64bitmode(ctx);
b6d96bed 7595 {
a7812ae4
PB
7596 TCGv_i32 fp32 = tcg_temp_new_i32();
7597 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7598
7599 gen_load_fpr32(fp32, fs);
895c2d04 7600 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7601 tcg_temp_free_i32(fp32);
b6d96bed 7602 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7603 tcg_temp_free_i64(fp64);
b6d96bed 7604 }
5a5012ec
TS
7605 opn = "trunc.l.s";
7606 break;
bf4120ad 7607 case OPC_CEIL_L_S:
5e755519 7608 check_cp1_64bitmode(ctx);
b6d96bed 7609 {
a7812ae4
PB
7610 TCGv_i32 fp32 = tcg_temp_new_i32();
7611 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7612
7613 gen_load_fpr32(fp32, fs);
895c2d04 7614 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7615 tcg_temp_free_i32(fp32);
b6d96bed 7616 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7617 tcg_temp_free_i64(fp64);
b6d96bed 7618 }
5a5012ec
TS
7619 opn = "ceil.l.s";
7620 break;
bf4120ad 7621 case OPC_FLOOR_L_S:
5e755519 7622 check_cp1_64bitmode(ctx);
b6d96bed 7623 {
a7812ae4
PB
7624 TCGv_i32 fp32 = tcg_temp_new_i32();
7625 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7626
7627 gen_load_fpr32(fp32, fs);
895c2d04 7628 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7629 tcg_temp_free_i32(fp32);
b6d96bed 7630 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7631 tcg_temp_free_i64(fp64);
b6d96bed 7632 }
5a5012ec
TS
7633 opn = "floor.l.s";
7634 break;
bf4120ad 7635 case OPC_ROUND_W_S:
b6d96bed 7636 {
a7812ae4 7637 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7638
7639 gen_load_fpr32(fp0, fs);
895c2d04 7640 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7641 gen_store_fpr32(fp0, fd);
a7812ae4 7642 tcg_temp_free_i32(fp0);
b6d96bed 7643 }
5a5012ec
TS
7644 opn = "round.w.s";
7645 break;
bf4120ad 7646 case OPC_TRUNC_W_S:
b6d96bed 7647 {
a7812ae4 7648 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7649
7650 gen_load_fpr32(fp0, fs);
895c2d04 7651 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7652 gen_store_fpr32(fp0, fd);
a7812ae4 7653 tcg_temp_free_i32(fp0);
b6d96bed 7654 }
5a5012ec
TS
7655 opn = "trunc.w.s";
7656 break;
bf4120ad 7657 case OPC_CEIL_W_S:
b6d96bed 7658 {
a7812ae4 7659 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7660
7661 gen_load_fpr32(fp0, fs);
895c2d04 7662 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7663 gen_store_fpr32(fp0, fd);
a7812ae4 7664 tcg_temp_free_i32(fp0);
b6d96bed 7665 }
5a5012ec
TS
7666 opn = "ceil.w.s";
7667 break;
bf4120ad 7668 case OPC_FLOOR_W_S:
b6d96bed 7669 {
a7812ae4 7670 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7671
7672 gen_load_fpr32(fp0, fs);
895c2d04 7673 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7674 gen_store_fpr32(fp0, fd);
a7812ae4 7675 tcg_temp_free_i32(fp0);
b6d96bed 7676 }
5a5012ec
TS
7677 opn = "floor.w.s";
7678 break;
bf4120ad 7679 case OPC_MOVCF_S:
b6d96bed 7680 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7681 opn = "movcf.s";
7682 break;
bf4120ad 7683 case OPC_MOVZ_S:
a16336e4
TS
7684 {
7685 int l1 = gen_new_label();
c9297f4d 7686 TCGv_i32 fp0;
a16336e4 7687
c9297f4d
AJ
7688 if (ft != 0) {
7689 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7690 }
7691 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7692 gen_load_fpr32(fp0, fs);
7693 gen_store_fpr32(fp0, fd);
a7812ae4 7694 tcg_temp_free_i32(fp0);
a16336e4
TS
7695 gen_set_label(l1);
7696 }
5a5012ec
TS
7697 opn = "movz.s";
7698 break;
bf4120ad 7699 case OPC_MOVN_S:
a16336e4
TS
7700 {
7701 int l1 = gen_new_label();
c9297f4d
AJ
7702 TCGv_i32 fp0;
7703
7704 if (ft != 0) {
7705 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7706 fp0 = tcg_temp_new_i32();
7707 gen_load_fpr32(fp0, fs);
7708 gen_store_fpr32(fp0, fd);
7709 tcg_temp_free_i32(fp0);
7710 gen_set_label(l1);
7711 }
a16336e4 7712 }
5a5012ec
TS
7713 opn = "movn.s";
7714 break;
bf4120ad 7715 case OPC_RECIP_S:
b8aa4598 7716 check_cop1x(ctx);
b6d96bed 7717 {
a7812ae4 7718 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7719
7720 gen_load_fpr32(fp0, fs);
895c2d04 7721 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 7722 gen_store_fpr32(fp0, fd);
a7812ae4 7723 tcg_temp_free_i32(fp0);
b6d96bed 7724 }
57fa1fb3
TS
7725 opn = "recip.s";
7726 break;
bf4120ad 7727 case OPC_RSQRT_S:
b8aa4598 7728 check_cop1x(ctx);
b6d96bed 7729 {
a7812ae4 7730 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7731
7732 gen_load_fpr32(fp0, fs);
895c2d04 7733 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7734 gen_store_fpr32(fp0, fd);
a7812ae4 7735 tcg_temp_free_i32(fp0);
b6d96bed 7736 }
57fa1fb3
TS
7737 opn = "rsqrt.s";
7738 break;
bf4120ad 7739 case OPC_RECIP2_S:
5e755519 7740 check_cp1_64bitmode(ctx);
b6d96bed 7741 {
a7812ae4
PB
7742 TCGv_i32 fp0 = tcg_temp_new_i32();
7743 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7744
7745 gen_load_fpr32(fp0, fs);
d22d7289 7746 gen_load_fpr32(fp1, ft);
895c2d04 7747 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7748 tcg_temp_free_i32(fp1);
b6d96bed 7749 gen_store_fpr32(fp0, fd);
a7812ae4 7750 tcg_temp_free_i32(fp0);
b6d96bed 7751 }
57fa1fb3
TS
7752 opn = "recip2.s";
7753 break;
bf4120ad 7754 case OPC_RECIP1_S:
5e755519 7755 check_cp1_64bitmode(ctx);
b6d96bed 7756 {
a7812ae4 7757 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7758
7759 gen_load_fpr32(fp0, fs);
895c2d04 7760 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7761 gen_store_fpr32(fp0, fd);
a7812ae4 7762 tcg_temp_free_i32(fp0);
b6d96bed 7763 }
57fa1fb3
TS
7764 opn = "recip1.s";
7765 break;
bf4120ad 7766 case OPC_RSQRT1_S:
5e755519 7767 check_cp1_64bitmode(ctx);
b6d96bed 7768 {
a7812ae4 7769 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7770
7771 gen_load_fpr32(fp0, fs);
895c2d04 7772 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7773 gen_store_fpr32(fp0, fd);
a7812ae4 7774 tcg_temp_free_i32(fp0);
b6d96bed 7775 }
57fa1fb3
TS
7776 opn = "rsqrt1.s";
7777 break;
bf4120ad 7778 case OPC_RSQRT2_S:
5e755519 7779 check_cp1_64bitmode(ctx);
b6d96bed 7780 {
a7812ae4
PB
7781 TCGv_i32 fp0 = tcg_temp_new_i32();
7782 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7783
7784 gen_load_fpr32(fp0, fs);
7785 gen_load_fpr32(fp1, ft);
895c2d04 7786 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7787 tcg_temp_free_i32(fp1);
b6d96bed 7788 gen_store_fpr32(fp0, fd);
a7812ae4 7789 tcg_temp_free_i32(fp0);
b6d96bed 7790 }
57fa1fb3
TS
7791 opn = "rsqrt2.s";
7792 break;
bf4120ad 7793 case OPC_CVT_D_S:
5e755519 7794 check_cp1_registers(ctx, fd);
b6d96bed 7795 {
a7812ae4
PB
7796 TCGv_i32 fp32 = tcg_temp_new_i32();
7797 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7798
7799 gen_load_fpr32(fp32, fs);
895c2d04 7800 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7801 tcg_temp_free_i32(fp32);
b6d96bed 7802 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7803 tcg_temp_free_i64(fp64);
b6d96bed 7804 }
5a5012ec
TS
7805 opn = "cvt.d.s";
7806 break;
bf4120ad 7807 case OPC_CVT_W_S:
b6d96bed 7808 {
a7812ae4 7809 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7810
7811 gen_load_fpr32(fp0, fs);
895c2d04 7812 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7813 gen_store_fpr32(fp0, fd);
a7812ae4 7814 tcg_temp_free_i32(fp0);
b6d96bed 7815 }
5a5012ec
TS
7816 opn = "cvt.w.s";
7817 break;
bf4120ad 7818 case OPC_CVT_L_S:
5e755519 7819 check_cp1_64bitmode(ctx);
b6d96bed 7820 {
a7812ae4
PB
7821 TCGv_i32 fp32 = tcg_temp_new_i32();
7822 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7823
7824 gen_load_fpr32(fp32, fs);
895c2d04 7825 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7826 tcg_temp_free_i32(fp32);
b6d96bed 7827 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7828 tcg_temp_free_i64(fp64);
b6d96bed 7829 }
5a5012ec
TS
7830 opn = "cvt.l.s";
7831 break;
bf4120ad 7832 case OPC_CVT_PS_S:
5e755519 7833 check_cp1_64bitmode(ctx);
b6d96bed 7834 {
a7812ae4
PB
7835 TCGv_i64 fp64 = tcg_temp_new_i64();
7836 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7837 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7838
7839 gen_load_fpr32(fp32_0, fs);
7840 gen_load_fpr32(fp32_1, ft);
13d24f49 7841 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7842 tcg_temp_free_i32(fp32_1);
7843 tcg_temp_free_i32(fp32_0);
36aa55dc 7844 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7845 tcg_temp_free_i64(fp64);
b6d96bed 7846 }
5a5012ec
TS
7847 opn = "cvt.ps.s";
7848 break;
bf4120ad
NF
7849 case OPC_CMP_F_S:
7850 case OPC_CMP_UN_S:
7851 case OPC_CMP_EQ_S:
7852 case OPC_CMP_UEQ_S:
7853 case OPC_CMP_OLT_S:
7854 case OPC_CMP_ULT_S:
7855 case OPC_CMP_OLE_S:
7856 case OPC_CMP_ULE_S:
7857 case OPC_CMP_SF_S:
7858 case OPC_CMP_NGLE_S:
7859 case OPC_CMP_SEQ_S:
7860 case OPC_CMP_NGL_S:
7861 case OPC_CMP_LT_S:
7862 case OPC_CMP_NGE_S:
7863 case OPC_CMP_LE_S:
7864 case OPC_CMP_NGT_S:
8153667c
NF
7865 if (ctx->opcode & (1 << 6)) {
7866 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7867 opn = condnames_abs[func-48];
7868 } else {
7869 gen_cmp_s(ctx, func-48, ft, fs, cc);
7870 opn = condnames[func-48];
5a1e8ffb 7871 }
5a5012ec 7872 break;
bf4120ad 7873 case OPC_ADD_D:
5e755519 7874 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7875 {
a7812ae4
PB
7876 TCGv_i64 fp0 = tcg_temp_new_i64();
7877 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7878
7879 gen_load_fpr64(ctx, fp0, fs);
7880 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7881 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7882 tcg_temp_free_i64(fp1);
b6d96bed 7883 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7884 tcg_temp_free_i64(fp0);
b6d96bed 7885 }
6ea83fed 7886 opn = "add.d";
5a1e8ffb 7887 optype = BINOP;
6ea83fed 7888 break;
bf4120ad 7889 case OPC_SUB_D:
5e755519 7890 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7891 {
a7812ae4
PB
7892 TCGv_i64 fp0 = tcg_temp_new_i64();
7893 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7894
7895 gen_load_fpr64(ctx, fp0, fs);
7896 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7897 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7898 tcg_temp_free_i64(fp1);
b6d96bed 7899 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7900 tcg_temp_free_i64(fp0);
b6d96bed 7901 }
6ea83fed 7902 opn = "sub.d";
5a1e8ffb 7903 optype = BINOP;
6ea83fed 7904 break;
bf4120ad 7905 case OPC_MUL_D:
5e755519 7906 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7907 {
a7812ae4
PB
7908 TCGv_i64 fp0 = tcg_temp_new_i64();
7909 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7910
7911 gen_load_fpr64(ctx, fp0, fs);
7912 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7913 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7914 tcg_temp_free_i64(fp1);
b6d96bed 7915 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7916 tcg_temp_free_i64(fp0);
b6d96bed 7917 }
6ea83fed 7918 opn = "mul.d";
5a1e8ffb 7919 optype = BINOP;
6ea83fed 7920 break;
bf4120ad 7921 case OPC_DIV_D:
5e755519 7922 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7923 {
a7812ae4
PB
7924 TCGv_i64 fp0 = tcg_temp_new_i64();
7925 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7926
7927 gen_load_fpr64(ctx, fp0, fs);
7928 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7929 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7930 tcg_temp_free_i64(fp1);
b6d96bed 7931 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7932 tcg_temp_free_i64(fp0);
b6d96bed 7933 }
6ea83fed 7934 opn = "div.d";
5a1e8ffb 7935 optype = BINOP;
6ea83fed 7936 break;
bf4120ad 7937 case OPC_SQRT_D:
5e755519 7938 check_cp1_registers(ctx, fs | fd);
b6d96bed 7939 {
a7812ae4 7940 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7941
7942 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7943 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7944 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7945 tcg_temp_free_i64(fp0);
b6d96bed 7946 }
6ea83fed
FB
7947 opn = "sqrt.d";
7948 break;
bf4120ad 7949 case OPC_ABS_D:
5e755519 7950 check_cp1_registers(ctx, fs | fd);
b6d96bed 7951 {
a7812ae4 7952 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7953
7954 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7955 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7956 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7957 tcg_temp_free_i64(fp0);
b6d96bed 7958 }
6ea83fed
FB
7959 opn = "abs.d";
7960 break;
bf4120ad 7961 case OPC_MOV_D:
5e755519 7962 check_cp1_registers(ctx, fs | fd);
b6d96bed 7963 {
a7812ae4 7964 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7965
7966 gen_load_fpr64(ctx, fp0, fs);
7967 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7968 tcg_temp_free_i64(fp0);
b6d96bed 7969 }
6ea83fed
FB
7970 opn = "mov.d";
7971 break;
bf4120ad 7972 case OPC_NEG_D:
5e755519 7973 check_cp1_registers(ctx, fs | fd);
b6d96bed 7974 {
a7812ae4 7975 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7976
7977 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7978 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 7979 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7980 tcg_temp_free_i64(fp0);
b6d96bed 7981 }
6ea83fed
FB
7982 opn = "neg.d";
7983 break;
bf4120ad 7984 case OPC_ROUND_L_D:
5e755519 7985 check_cp1_64bitmode(ctx);
b6d96bed 7986 {
a7812ae4 7987 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7988
7989 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7990 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 7991 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7992 tcg_temp_free_i64(fp0);
b6d96bed 7993 }
5a5012ec
TS
7994 opn = "round.l.d";
7995 break;
bf4120ad 7996 case OPC_TRUNC_L_D:
5e755519 7997 check_cp1_64bitmode(ctx);
b6d96bed 7998 {
a7812ae4 7999 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8000
8001 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8002 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 8003 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8004 tcg_temp_free_i64(fp0);
b6d96bed 8005 }
5a5012ec
TS
8006 opn = "trunc.l.d";
8007 break;
bf4120ad 8008 case OPC_CEIL_L_D:
5e755519 8009 check_cp1_64bitmode(ctx);
b6d96bed 8010 {
a7812ae4 8011 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8012
8013 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8014 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8015 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8016 tcg_temp_free_i64(fp0);
b6d96bed 8017 }
5a5012ec
TS
8018 opn = "ceil.l.d";
8019 break;
bf4120ad 8020 case OPC_FLOOR_L_D:
5e755519 8021 check_cp1_64bitmode(ctx);
b6d96bed 8022 {
a7812ae4 8023 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8024
8025 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8026 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8027 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8028 tcg_temp_free_i64(fp0);
b6d96bed 8029 }
5a5012ec
TS
8030 opn = "floor.l.d";
8031 break;
bf4120ad 8032 case OPC_ROUND_W_D:
5e755519 8033 check_cp1_registers(ctx, fs);
b6d96bed 8034 {
a7812ae4
PB
8035 TCGv_i32 fp32 = tcg_temp_new_i32();
8036 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8037
8038 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8039 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8040 tcg_temp_free_i64(fp64);
b6d96bed 8041 gen_store_fpr32(fp32, fd);
a7812ae4 8042 tcg_temp_free_i32(fp32);
b6d96bed 8043 }
6ea83fed
FB
8044 opn = "round.w.d";
8045 break;
bf4120ad 8046 case OPC_TRUNC_W_D:
5e755519 8047 check_cp1_registers(ctx, fs);
b6d96bed 8048 {
a7812ae4
PB
8049 TCGv_i32 fp32 = tcg_temp_new_i32();
8050 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8051
8052 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8053 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8054 tcg_temp_free_i64(fp64);
b6d96bed 8055 gen_store_fpr32(fp32, fd);
a7812ae4 8056 tcg_temp_free_i32(fp32);
b6d96bed 8057 }
6ea83fed
FB
8058 opn = "trunc.w.d";
8059 break;
bf4120ad 8060 case OPC_CEIL_W_D:
5e755519 8061 check_cp1_registers(ctx, fs);
b6d96bed 8062 {
a7812ae4
PB
8063 TCGv_i32 fp32 = tcg_temp_new_i32();
8064 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8065
8066 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8067 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8068 tcg_temp_free_i64(fp64);
b6d96bed 8069 gen_store_fpr32(fp32, fd);
a7812ae4 8070 tcg_temp_free_i32(fp32);
b6d96bed 8071 }
6ea83fed
FB
8072 opn = "ceil.w.d";
8073 break;
bf4120ad 8074 case OPC_FLOOR_W_D:
5e755519 8075 check_cp1_registers(ctx, fs);
b6d96bed 8076 {
a7812ae4
PB
8077 TCGv_i32 fp32 = tcg_temp_new_i32();
8078 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8079
8080 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8081 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8082 tcg_temp_free_i64(fp64);
b6d96bed 8083 gen_store_fpr32(fp32, fd);
a7812ae4 8084 tcg_temp_free_i32(fp32);
b6d96bed 8085 }
7a387fff 8086 opn = "floor.w.d";
6ea83fed 8087 break;
bf4120ad 8088 case OPC_MOVCF_D:
b6d96bed 8089 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8090 opn = "movcf.d";
dd016883 8091 break;
bf4120ad 8092 case OPC_MOVZ_D:
a16336e4
TS
8093 {
8094 int l1 = gen_new_label();
c9297f4d 8095 TCGv_i64 fp0;
a16336e4 8096
c9297f4d
AJ
8097 if (ft != 0) {
8098 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8099 }
8100 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8101 gen_load_fpr64(ctx, fp0, fs);
8102 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8103 tcg_temp_free_i64(fp0);
a16336e4
TS
8104 gen_set_label(l1);
8105 }
5a5012ec
TS
8106 opn = "movz.d";
8107 break;
bf4120ad 8108 case OPC_MOVN_D:
a16336e4
TS
8109 {
8110 int l1 = gen_new_label();
c9297f4d
AJ
8111 TCGv_i64 fp0;
8112
8113 if (ft != 0) {
8114 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8115 fp0 = tcg_temp_new_i64();
8116 gen_load_fpr64(ctx, fp0, fs);
8117 gen_store_fpr64(ctx, fp0, fd);
8118 tcg_temp_free_i64(fp0);
8119 gen_set_label(l1);
8120 }
a16336e4 8121 }
5a5012ec 8122 opn = "movn.d";
6ea83fed 8123 break;
bf4120ad 8124 case OPC_RECIP_D:
b8aa4598 8125 check_cp1_64bitmode(ctx);
b6d96bed 8126 {
a7812ae4 8127 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8128
8129 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8130 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8131 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8132 tcg_temp_free_i64(fp0);
b6d96bed 8133 }
57fa1fb3
TS
8134 opn = "recip.d";
8135 break;
bf4120ad 8136 case OPC_RSQRT_D:
b8aa4598 8137 check_cp1_64bitmode(ctx);
b6d96bed 8138 {
a7812ae4 8139 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8140
8141 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8142 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8143 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8144 tcg_temp_free_i64(fp0);
b6d96bed 8145 }
57fa1fb3
TS
8146 opn = "rsqrt.d";
8147 break;
bf4120ad 8148 case OPC_RECIP2_D:
5e755519 8149 check_cp1_64bitmode(ctx);
b6d96bed 8150 {
a7812ae4
PB
8151 TCGv_i64 fp0 = tcg_temp_new_i64();
8152 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8153
8154 gen_load_fpr64(ctx, fp0, fs);
8155 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8156 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8157 tcg_temp_free_i64(fp1);
b6d96bed 8158 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8159 tcg_temp_free_i64(fp0);
b6d96bed 8160 }
57fa1fb3
TS
8161 opn = "recip2.d";
8162 break;
bf4120ad 8163 case OPC_RECIP1_D:
5e755519 8164 check_cp1_64bitmode(ctx);
b6d96bed 8165 {
a7812ae4 8166 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8167
8168 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8169 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8170 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8171 tcg_temp_free_i64(fp0);
b6d96bed 8172 }
57fa1fb3
TS
8173 opn = "recip1.d";
8174 break;
bf4120ad 8175 case OPC_RSQRT1_D:
5e755519 8176 check_cp1_64bitmode(ctx);
b6d96bed 8177 {
a7812ae4 8178 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8179
8180 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8181 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8182 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8183 tcg_temp_free_i64(fp0);
b6d96bed 8184 }
57fa1fb3
TS
8185 opn = "rsqrt1.d";
8186 break;
bf4120ad 8187 case OPC_RSQRT2_D:
5e755519 8188 check_cp1_64bitmode(ctx);
b6d96bed 8189 {
a7812ae4
PB
8190 TCGv_i64 fp0 = tcg_temp_new_i64();
8191 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8192
8193 gen_load_fpr64(ctx, fp0, fs);
8194 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8195 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8196 tcg_temp_free_i64(fp1);
b6d96bed 8197 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8198 tcg_temp_free_i64(fp0);
b6d96bed 8199 }
57fa1fb3
TS
8200 opn = "rsqrt2.d";
8201 break;
bf4120ad
NF
8202 case OPC_CMP_F_D:
8203 case OPC_CMP_UN_D:
8204 case OPC_CMP_EQ_D:
8205 case OPC_CMP_UEQ_D:
8206 case OPC_CMP_OLT_D:
8207 case OPC_CMP_ULT_D:
8208 case OPC_CMP_OLE_D:
8209 case OPC_CMP_ULE_D:
8210 case OPC_CMP_SF_D:
8211 case OPC_CMP_NGLE_D:
8212 case OPC_CMP_SEQ_D:
8213 case OPC_CMP_NGL_D:
8214 case OPC_CMP_LT_D:
8215 case OPC_CMP_NGE_D:
8216 case OPC_CMP_LE_D:
8217 case OPC_CMP_NGT_D:
8153667c
NF
8218 if (ctx->opcode & (1 << 6)) {
8219 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8220 opn = condnames_abs[func-48];
8221 } else {
8222 gen_cmp_d(ctx, func-48, ft, fs, cc);
8223 opn = condnames[func-48];
5a1e8ffb 8224 }
6ea83fed 8225 break;
bf4120ad 8226 case OPC_CVT_S_D:
5e755519 8227 check_cp1_registers(ctx, fs);
b6d96bed 8228 {
a7812ae4
PB
8229 TCGv_i32 fp32 = tcg_temp_new_i32();
8230 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8231
8232 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8233 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8234 tcg_temp_free_i64(fp64);
b6d96bed 8235 gen_store_fpr32(fp32, fd);
a7812ae4 8236 tcg_temp_free_i32(fp32);
b6d96bed 8237 }
5a5012ec
TS
8238 opn = "cvt.s.d";
8239 break;
bf4120ad 8240 case OPC_CVT_W_D:
5e755519 8241 check_cp1_registers(ctx, fs);
b6d96bed 8242 {
a7812ae4
PB
8243 TCGv_i32 fp32 = tcg_temp_new_i32();
8244 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8245
8246 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8247 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8248 tcg_temp_free_i64(fp64);
b6d96bed 8249 gen_store_fpr32(fp32, fd);
a7812ae4 8250 tcg_temp_free_i32(fp32);
b6d96bed 8251 }
5a5012ec
TS
8252 opn = "cvt.w.d";
8253 break;
bf4120ad 8254 case OPC_CVT_L_D:
5e755519 8255 check_cp1_64bitmode(ctx);
b6d96bed 8256 {
a7812ae4 8257 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8258
8259 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8260 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8261 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8262 tcg_temp_free_i64(fp0);
b6d96bed 8263 }
5a5012ec
TS
8264 opn = "cvt.l.d";
8265 break;
bf4120ad 8266 case OPC_CVT_S_W:
b6d96bed 8267 {
a7812ae4 8268 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8269
8270 gen_load_fpr32(fp0, fs);
895c2d04 8271 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8272 gen_store_fpr32(fp0, fd);
a7812ae4 8273 tcg_temp_free_i32(fp0);
b6d96bed 8274 }
5a5012ec 8275 opn = "cvt.s.w";
6ea83fed 8276 break;
bf4120ad 8277 case OPC_CVT_D_W:
5e755519 8278 check_cp1_registers(ctx, fd);
b6d96bed 8279 {
a7812ae4
PB
8280 TCGv_i32 fp32 = tcg_temp_new_i32();
8281 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8282
8283 gen_load_fpr32(fp32, fs);
895c2d04 8284 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8285 tcg_temp_free_i32(fp32);
b6d96bed 8286 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8287 tcg_temp_free_i64(fp64);
b6d96bed 8288 }
5a5012ec
TS
8289 opn = "cvt.d.w";
8290 break;
bf4120ad 8291 case OPC_CVT_S_L:
5e755519 8292 check_cp1_64bitmode(ctx);
b6d96bed 8293 {
a7812ae4
PB
8294 TCGv_i32 fp32 = tcg_temp_new_i32();
8295 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8296
8297 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8298 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8299 tcg_temp_free_i64(fp64);
b6d96bed 8300 gen_store_fpr32(fp32, fd);
a7812ae4 8301 tcg_temp_free_i32(fp32);
b6d96bed 8302 }
5a5012ec
TS
8303 opn = "cvt.s.l";
8304 break;
bf4120ad 8305 case OPC_CVT_D_L:
5e755519 8306 check_cp1_64bitmode(ctx);
b6d96bed 8307 {
a7812ae4 8308 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8309
8310 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8311 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8312 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8313 tcg_temp_free_i64(fp0);
b6d96bed 8314 }
5a5012ec
TS
8315 opn = "cvt.d.l";
8316 break;
bf4120ad 8317 case OPC_CVT_PS_PW:
5e755519 8318 check_cp1_64bitmode(ctx);
b6d96bed 8319 {
a7812ae4 8320 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8321
8322 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8323 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8324 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8325 tcg_temp_free_i64(fp0);
b6d96bed 8326 }
5a5012ec
TS
8327 opn = "cvt.ps.pw";
8328 break;
bf4120ad 8329 case OPC_ADD_PS:
5e755519 8330 check_cp1_64bitmode(ctx);
b6d96bed 8331 {
a7812ae4
PB
8332 TCGv_i64 fp0 = tcg_temp_new_i64();
8333 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8334
8335 gen_load_fpr64(ctx, fp0, fs);
8336 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8337 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8338 tcg_temp_free_i64(fp1);
b6d96bed 8339 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8340 tcg_temp_free_i64(fp0);
b6d96bed 8341 }
5a5012ec 8342 opn = "add.ps";
6ea83fed 8343 break;
bf4120ad 8344 case OPC_SUB_PS:
5e755519 8345 check_cp1_64bitmode(ctx);
b6d96bed 8346 {
a7812ae4
PB
8347 TCGv_i64 fp0 = tcg_temp_new_i64();
8348 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8349
8350 gen_load_fpr64(ctx, fp0, fs);
8351 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8352 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8353 tcg_temp_free_i64(fp1);
b6d96bed 8354 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8355 tcg_temp_free_i64(fp0);
b6d96bed 8356 }
5a5012ec 8357 opn = "sub.ps";
6ea83fed 8358 break;
bf4120ad 8359 case OPC_MUL_PS:
5e755519 8360 check_cp1_64bitmode(ctx);
b6d96bed 8361 {
a7812ae4
PB
8362 TCGv_i64 fp0 = tcg_temp_new_i64();
8363 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8364
8365 gen_load_fpr64(ctx, fp0, fs);
8366 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8367 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8368 tcg_temp_free_i64(fp1);
b6d96bed 8369 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8370 tcg_temp_free_i64(fp0);
b6d96bed 8371 }
5a5012ec 8372 opn = "mul.ps";
6ea83fed 8373 break;
bf4120ad 8374 case OPC_ABS_PS:
5e755519 8375 check_cp1_64bitmode(ctx);
b6d96bed 8376 {
a7812ae4 8377 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8378
8379 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8380 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8381 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8382 tcg_temp_free_i64(fp0);
b6d96bed 8383 }
5a5012ec 8384 opn = "abs.ps";
6ea83fed 8385 break;
bf4120ad 8386 case OPC_MOV_PS:
5e755519 8387 check_cp1_64bitmode(ctx);
b6d96bed 8388 {
a7812ae4 8389 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8390
8391 gen_load_fpr64(ctx, fp0, fs);
8392 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8393 tcg_temp_free_i64(fp0);
b6d96bed 8394 }
5a5012ec 8395 opn = "mov.ps";
6ea83fed 8396 break;
bf4120ad 8397 case OPC_NEG_PS:
5e755519 8398 check_cp1_64bitmode(ctx);
b6d96bed 8399 {
a7812ae4 8400 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8401
8402 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8403 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8404 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8405 tcg_temp_free_i64(fp0);
b6d96bed 8406 }
5a5012ec 8407 opn = "neg.ps";
6ea83fed 8408 break;
bf4120ad 8409 case OPC_MOVCF_PS:
5e755519 8410 check_cp1_64bitmode(ctx);
b6d96bed 8411 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8412 opn = "movcf.ps";
6ea83fed 8413 break;
bf4120ad 8414 case OPC_MOVZ_PS:
5e755519 8415 check_cp1_64bitmode(ctx);
a16336e4
TS
8416 {
8417 int l1 = gen_new_label();
30a3848b 8418 TCGv_i64 fp0;
a16336e4 8419
c9297f4d
AJ
8420 if (ft != 0)
8421 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8422 fp0 = tcg_temp_new_i64();
8423 gen_load_fpr64(ctx, fp0, fs);
8424 gen_store_fpr64(ctx, fp0, fd);
8425 tcg_temp_free_i64(fp0);
a16336e4
TS
8426 gen_set_label(l1);
8427 }
5a5012ec 8428 opn = "movz.ps";
6ea83fed 8429 break;
bf4120ad 8430 case OPC_MOVN_PS:
5e755519 8431 check_cp1_64bitmode(ctx);
a16336e4
TS
8432 {
8433 int l1 = gen_new_label();
30a3848b 8434 TCGv_i64 fp0;
c9297f4d
AJ
8435
8436 if (ft != 0) {
8437 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8438 fp0 = tcg_temp_new_i64();
8439 gen_load_fpr64(ctx, fp0, fs);
8440 gen_store_fpr64(ctx, fp0, fd);
8441 tcg_temp_free_i64(fp0);
8442 gen_set_label(l1);
8443 }
a16336e4 8444 }
5a5012ec 8445 opn = "movn.ps";
6ea83fed 8446 break;
bf4120ad 8447 case OPC_ADDR_PS:
5e755519 8448 check_cp1_64bitmode(ctx);
b6d96bed 8449 {
a7812ae4
PB
8450 TCGv_i64 fp0 = tcg_temp_new_i64();
8451 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8452
8453 gen_load_fpr64(ctx, fp0, ft);
8454 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8455 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8456 tcg_temp_free_i64(fp1);
b6d96bed 8457 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8458 tcg_temp_free_i64(fp0);
b6d96bed 8459 }
fbcc6828
TS
8460 opn = "addr.ps";
8461 break;
bf4120ad 8462 case OPC_MULR_PS:
5e755519 8463 check_cp1_64bitmode(ctx);
b6d96bed 8464 {
a7812ae4
PB
8465 TCGv_i64 fp0 = tcg_temp_new_i64();
8466 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8467
8468 gen_load_fpr64(ctx, fp0, ft);
8469 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8470 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8471 tcg_temp_free_i64(fp1);
b6d96bed 8472 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8473 tcg_temp_free_i64(fp0);
b6d96bed 8474 }
57fa1fb3
TS
8475 opn = "mulr.ps";
8476 break;
bf4120ad 8477 case OPC_RECIP2_PS:
5e755519 8478 check_cp1_64bitmode(ctx);
b6d96bed 8479 {
a7812ae4
PB
8480 TCGv_i64 fp0 = tcg_temp_new_i64();
8481 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8482
8483 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8484 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8485 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8486 tcg_temp_free_i64(fp1);
b6d96bed 8487 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8488 tcg_temp_free_i64(fp0);
b6d96bed 8489 }
57fa1fb3
TS
8490 opn = "recip2.ps";
8491 break;
bf4120ad 8492 case OPC_RECIP1_PS:
5e755519 8493 check_cp1_64bitmode(ctx);
b6d96bed 8494 {
a7812ae4 8495 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8496
8497 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8498 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8499 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8500 tcg_temp_free_i64(fp0);
b6d96bed 8501 }
57fa1fb3
TS
8502 opn = "recip1.ps";
8503 break;
bf4120ad 8504 case OPC_RSQRT1_PS:
5e755519 8505 check_cp1_64bitmode(ctx);
b6d96bed 8506 {
a7812ae4 8507 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8508
8509 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8510 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8511 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8512 tcg_temp_free_i64(fp0);
b6d96bed 8513 }
57fa1fb3
TS
8514 opn = "rsqrt1.ps";
8515 break;
bf4120ad 8516 case OPC_RSQRT2_PS:
5e755519 8517 check_cp1_64bitmode(ctx);
b6d96bed 8518 {
a7812ae4
PB
8519 TCGv_i64 fp0 = tcg_temp_new_i64();
8520 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8521
8522 gen_load_fpr64(ctx, fp0, fs);
8523 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8524 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8525 tcg_temp_free_i64(fp1);
b6d96bed 8526 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8527 tcg_temp_free_i64(fp0);
b6d96bed 8528 }
57fa1fb3
TS
8529 opn = "rsqrt2.ps";
8530 break;
bf4120ad 8531 case OPC_CVT_S_PU:
5e755519 8532 check_cp1_64bitmode(ctx);
b6d96bed 8533 {
a7812ae4 8534 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8535
8536 gen_load_fpr32h(fp0, fs);
895c2d04 8537 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8538 gen_store_fpr32(fp0, fd);
a7812ae4 8539 tcg_temp_free_i32(fp0);
b6d96bed 8540 }
5a5012ec 8541 opn = "cvt.s.pu";
dd016883 8542 break;
bf4120ad 8543 case OPC_CVT_PW_PS:
5e755519 8544 check_cp1_64bitmode(ctx);
b6d96bed 8545 {
a7812ae4 8546 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8547
8548 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8549 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8550 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8551 tcg_temp_free_i64(fp0);
b6d96bed 8552 }
5a5012ec 8553 opn = "cvt.pw.ps";
6ea83fed 8554 break;
bf4120ad 8555 case OPC_CVT_S_PL:
5e755519 8556 check_cp1_64bitmode(ctx);
b6d96bed 8557 {
a7812ae4 8558 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8559
8560 gen_load_fpr32(fp0, fs);
895c2d04 8561 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8562 gen_store_fpr32(fp0, fd);
a7812ae4 8563 tcg_temp_free_i32(fp0);
b6d96bed 8564 }
5a5012ec 8565 opn = "cvt.s.pl";
6ea83fed 8566 break;
bf4120ad 8567 case OPC_PLL_PS:
5e755519 8568 check_cp1_64bitmode(ctx);
b6d96bed 8569 {
a7812ae4
PB
8570 TCGv_i32 fp0 = tcg_temp_new_i32();
8571 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8572
8573 gen_load_fpr32(fp0, fs);
8574 gen_load_fpr32(fp1, ft);
8575 gen_store_fpr32h(fp0, fd);
8576 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8577 tcg_temp_free_i32(fp0);
8578 tcg_temp_free_i32(fp1);
b6d96bed 8579 }
5a5012ec 8580 opn = "pll.ps";
6ea83fed 8581 break;
bf4120ad 8582 case OPC_PLU_PS:
5e755519 8583 check_cp1_64bitmode(ctx);
b6d96bed 8584 {
a7812ae4
PB
8585 TCGv_i32 fp0 = tcg_temp_new_i32();
8586 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8587
8588 gen_load_fpr32(fp0, fs);
8589 gen_load_fpr32h(fp1, ft);
8590 gen_store_fpr32(fp1, fd);
8591 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8592 tcg_temp_free_i32(fp0);
8593 tcg_temp_free_i32(fp1);
b6d96bed 8594 }
5a5012ec
TS
8595 opn = "plu.ps";
8596 break;
bf4120ad 8597 case OPC_PUL_PS:
5e755519 8598 check_cp1_64bitmode(ctx);
b6d96bed 8599 {
a7812ae4
PB
8600 TCGv_i32 fp0 = tcg_temp_new_i32();
8601 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8602
8603 gen_load_fpr32h(fp0, fs);
8604 gen_load_fpr32(fp1, ft);
8605 gen_store_fpr32(fp1, fd);
8606 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8607 tcg_temp_free_i32(fp0);
8608 tcg_temp_free_i32(fp1);
b6d96bed 8609 }
5a5012ec
TS
8610 opn = "pul.ps";
8611 break;
bf4120ad 8612 case OPC_PUU_PS:
5e755519 8613 check_cp1_64bitmode(ctx);
b6d96bed 8614 {
a7812ae4
PB
8615 TCGv_i32 fp0 = tcg_temp_new_i32();
8616 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8617
8618 gen_load_fpr32h(fp0, fs);
8619 gen_load_fpr32h(fp1, ft);
8620 gen_store_fpr32(fp1, fd);
8621 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8622 tcg_temp_free_i32(fp0);
8623 tcg_temp_free_i32(fp1);
b6d96bed 8624 }
5a5012ec
TS
8625 opn = "puu.ps";
8626 break;
bf4120ad
NF
8627 case OPC_CMP_F_PS:
8628 case OPC_CMP_UN_PS:
8629 case OPC_CMP_EQ_PS:
8630 case OPC_CMP_UEQ_PS:
8631 case OPC_CMP_OLT_PS:
8632 case OPC_CMP_ULT_PS:
8633 case OPC_CMP_OLE_PS:
8634 case OPC_CMP_ULE_PS:
8635 case OPC_CMP_SF_PS:
8636 case OPC_CMP_NGLE_PS:
8637 case OPC_CMP_SEQ_PS:
8638 case OPC_CMP_NGL_PS:
8639 case OPC_CMP_LT_PS:
8640 case OPC_CMP_NGE_PS:
8641 case OPC_CMP_LE_PS:
8642 case OPC_CMP_NGT_PS:
8153667c
NF
8643 if (ctx->opcode & (1 << 6)) {
8644 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8645 opn = condnames_abs[func-48];
8646 } else {
8647 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8648 opn = condnames[func-48];
5a1e8ffb 8649 }
6ea83fed 8650 break;
5a5012ec 8651 default:
923617a3 8652 MIPS_INVAL(opn);
e397ee33 8653 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8654 return;
8655 }
2abf314d 8656 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8657 switch (optype) {
8658 case BINOP:
6ea83fed 8659 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8660 break;
8661 case CMPOP:
8662 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8663 break;
8664 default:
6ea83fed 8665 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8666 break;
8667 }
6ea83fed 8668}
6af0bf9c 8669
5a5012ec 8670/* Coprocessor 3 (FPU) */
5e755519
TS
8671static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8672 int fd, int fs, int base, int index)
7a387fff 8673{
923617a3 8674 const char *opn = "extended float load/store";
93b12ccc 8675 int store = 0;
4e2474d6 8676 TCGv t0 = tcg_temp_new();
7a387fff 8677
93b12ccc 8678 if (base == 0) {
6c5c1e20 8679 gen_load_gpr(t0, index);
93b12ccc 8680 } else if (index == 0) {
6c5c1e20 8681 gen_load_gpr(t0, base);
93b12ccc 8682 } else {
05168674 8683 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8684 }
5a5012ec 8685 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8686 memory access. */
5a5012ec
TS
8687 switch (opc) {
8688 case OPC_LWXC1:
8c0ab41f 8689 check_cop1x(ctx);
b6d96bed 8690 {
a7812ae4 8691 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8692
585c88d5
AJ
8693 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8694 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8695 gen_store_fpr32(fp0, fd);
a7812ae4 8696 tcg_temp_free_i32(fp0);
b6d96bed 8697 }
5a5012ec
TS
8698 opn = "lwxc1";
8699 break;
8700 case OPC_LDXC1:
8c0ab41f
AJ
8701 check_cop1x(ctx);
8702 check_cp1_registers(ctx, fd);
b6d96bed 8703 {
a7812ae4 8704 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8705
8706 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8707 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8708 tcg_temp_free_i64(fp0);
b6d96bed 8709 }
5a5012ec
TS
8710 opn = "ldxc1";
8711 break;
8712 case OPC_LUXC1:
8c0ab41f 8713 check_cp1_64bitmode(ctx);
6c5c1e20 8714 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8715 {
a7812ae4 8716 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8717
8718 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8719 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8720 tcg_temp_free_i64(fp0);
b6d96bed 8721 }
5a5012ec
TS
8722 opn = "luxc1";
8723 break;
8724 case OPC_SWXC1:
8c0ab41f 8725 check_cop1x(ctx);
b6d96bed 8726 {
a7812ae4 8727 TCGv_i32 fp0 = tcg_temp_new_i32();
585c88d5 8728 TCGv t1 = tcg_temp_new();
b6d96bed
TS
8729
8730 gen_load_fpr32(fp0, fs);
a7812ae4
PB
8731 tcg_gen_extu_i32_tl(t1, fp0);
8732 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8733 tcg_temp_free_i32(fp0);
a6035857 8734 tcg_temp_free(t1);
b6d96bed 8735 }
5a5012ec 8736 opn = "swxc1";
93b12ccc 8737 store = 1;
5a5012ec
TS
8738 break;
8739 case OPC_SDXC1:
8c0ab41f
AJ
8740 check_cop1x(ctx);
8741 check_cp1_registers(ctx, fs);
b6d96bed 8742 {
a7812ae4 8743 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8744
8745 gen_load_fpr64(ctx, fp0, fs);
8746 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8747 tcg_temp_free_i64(fp0);
b6d96bed 8748 }
5a5012ec 8749 opn = "sdxc1";
93b12ccc 8750 store = 1;
5a5012ec
TS
8751 break;
8752 case OPC_SUXC1:
8c0ab41f 8753 check_cp1_64bitmode(ctx);
6c5c1e20 8754 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8755 {
a7812ae4 8756 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8757
8758 gen_load_fpr64(ctx, fp0, fs);
8759 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8760 tcg_temp_free_i64(fp0);
b6d96bed 8761 }
5a5012ec 8762 opn = "suxc1";
93b12ccc 8763 store = 1;
5a5012ec 8764 break;
5a5012ec 8765 }
6c5c1e20 8766 tcg_temp_free(t0);
2abf314d 8767 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8768 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8769 regnames[index], regnames[base]);
5a5012ec
TS
8770}
8771
5e755519
TS
8772static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8773 int fd, int fr, int fs, int ft)
5a5012ec 8774{
923617a3 8775 const char *opn = "flt3_arith";
5a5012ec 8776
5a5012ec
TS
8777 switch (opc) {
8778 case OPC_ALNV_PS:
b8aa4598 8779 check_cp1_64bitmode(ctx);
a16336e4 8780 {
a7812ae4 8781 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8782 TCGv_i32 fp = tcg_temp_new_i32();
8783 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8784 int l1 = gen_new_label();
8785 int l2 = gen_new_label();
8786
6c5c1e20
TS
8787 gen_load_gpr(t0, fr);
8788 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8789
8790 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac
AJ
8791 gen_load_fpr32(fp, fs);
8792 gen_load_fpr32h(fph, fs);
8793 gen_store_fpr32(fp, fd);
8794 gen_store_fpr32h(fph, fd);
a16336e4
TS
8795 tcg_gen_br(l2);
8796 gen_set_label(l1);
6c5c1e20
TS
8797 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8798 tcg_temp_free(t0);
a16336e4 8799#ifdef TARGET_WORDS_BIGENDIAN
c905fdac
AJ
8800 gen_load_fpr32(fp, fs);
8801 gen_load_fpr32h(fph, ft);
8802 gen_store_fpr32h(fp, fd);
8803 gen_store_fpr32(fph, fd);
a16336e4 8804#else
c905fdac
AJ
8805 gen_load_fpr32h(fph, fs);
8806 gen_load_fpr32(fp, ft);
8807 gen_store_fpr32(fph, fd);
8808 gen_store_fpr32h(fp, fd);
a16336e4
TS
8809#endif
8810 gen_set_label(l2);
c905fdac
AJ
8811 tcg_temp_free_i32(fp);
8812 tcg_temp_free_i32(fph);
a16336e4 8813 }
5a5012ec
TS
8814 opn = "alnv.ps";
8815 break;
8816 case OPC_MADD_S:
b8aa4598 8817 check_cop1x(ctx);
b6d96bed 8818 {
a7812ae4
PB
8819 TCGv_i32 fp0 = tcg_temp_new_i32();
8820 TCGv_i32 fp1 = tcg_temp_new_i32();
8821 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8822
8823 gen_load_fpr32(fp0, fs);
8824 gen_load_fpr32(fp1, ft);
8825 gen_load_fpr32(fp2, fr);
b3d6cd44 8826 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8827 tcg_temp_free_i32(fp0);
8828 tcg_temp_free_i32(fp1);
b6d96bed 8829 gen_store_fpr32(fp2, fd);
a7812ae4 8830 tcg_temp_free_i32(fp2);
b6d96bed 8831 }
5a5012ec
TS
8832 opn = "madd.s";
8833 break;
8834 case OPC_MADD_D:
b8aa4598
TS
8835 check_cop1x(ctx);
8836 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8837 {
a7812ae4
PB
8838 TCGv_i64 fp0 = tcg_temp_new_i64();
8839 TCGv_i64 fp1 = tcg_temp_new_i64();
8840 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8841
8842 gen_load_fpr64(ctx, fp0, fs);
8843 gen_load_fpr64(ctx, fp1, ft);
8844 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8845 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8846 tcg_temp_free_i64(fp0);
8847 tcg_temp_free_i64(fp1);
b6d96bed 8848 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8849 tcg_temp_free_i64(fp2);
b6d96bed 8850 }
5a5012ec
TS
8851 opn = "madd.d";
8852 break;
8853 case OPC_MADD_PS:
b8aa4598 8854 check_cp1_64bitmode(ctx);
b6d96bed 8855 {
a7812ae4
PB
8856 TCGv_i64 fp0 = tcg_temp_new_i64();
8857 TCGv_i64 fp1 = tcg_temp_new_i64();
8858 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8859
8860 gen_load_fpr64(ctx, fp0, fs);
8861 gen_load_fpr64(ctx, fp1, ft);
8862 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8863 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8864 tcg_temp_free_i64(fp0);
8865 tcg_temp_free_i64(fp1);
b6d96bed 8866 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8867 tcg_temp_free_i64(fp2);
b6d96bed 8868 }
5a5012ec
TS
8869 opn = "madd.ps";
8870 break;
8871 case OPC_MSUB_S:
b8aa4598 8872 check_cop1x(ctx);
b6d96bed 8873 {
a7812ae4
PB
8874 TCGv_i32 fp0 = tcg_temp_new_i32();
8875 TCGv_i32 fp1 = tcg_temp_new_i32();
8876 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8877
8878 gen_load_fpr32(fp0, fs);
8879 gen_load_fpr32(fp1, ft);
8880 gen_load_fpr32(fp2, fr);
b3d6cd44 8881 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8882 tcg_temp_free_i32(fp0);
8883 tcg_temp_free_i32(fp1);
b6d96bed 8884 gen_store_fpr32(fp2, fd);
a7812ae4 8885 tcg_temp_free_i32(fp2);
b6d96bed 8886 }
5a5012ec
TS
8887 opn = "msub.s";
8888 break;
8889 case OPC_MSUB_D:
b8aa4598
TS
8890 check_cop1x(ctx);
8891 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8892 {
a7812ae4
PB
8893 TCGv_i64 fp0 = tcg_temp_new_i64();
8894 TCGv_i64 fp1 = tcg_temp_new_i64();
8895 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8896
8897 gen_load_fpr64(ctx, fp0, fs);
8898 gen_load_fpr64(ctx, fp1, ft);
8899 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8900 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8901 tcg_temp_free_i64(fp0);
8902 tcg_temp_free_i64(fp1);
b6d96bed 8903 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8904 tcg_temp_free_i64(fp2);
b6d96bed 8905 }
5a5012ec
TS
8906 opn = "msub.d";
8907 break;
8908 case OPC_MSUB_PS:
b8aa4598 8909 check_cp1_64bitmode(ctx);
b6d96bed 8910 {
a7812ae4
PB
8911 TCGv_i64 fp0 = tcg_temp_new_i64();
8912 TCGv_i64 fp1 = tcg_temp_new_i64();
8913 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8914
8915 gen_load_fpr64(ctx, fp0, fs);
8916 gen_load_fpr64(ctx, fp1, ft);
8917 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8918 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8919 tcg_temp_free_i64(fp0);
8920 tcg_temp_free_i64(fp1);
b6d96bed 8921 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8922 tcg_temp_free_i64(fp2);
b6d96bed 8923 }
5a5012ec
TS
8924 opn = "msub.ps";
8925 break;
8926 case OPC_NMADD_S:
b8aa4598 8927 check_cop1x(ctx);
b6d96bed 8928 {
a7812ae4
PB
8929 TCGv_i32 fp0 = tcg_temp_new_i32();
8930 TCGv_i32 fp1 = tcg_temp_new_i32();
8931 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8932
8933 gen_load_fpr32(fp0, fs);
8934 gen_load_fpr32(fp1, ft);
8935 gen_load_fpr32(fp2, fr);
b3d6cd44 8936 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8937 tcg_temp_free_i32(fp0);
8938 tcg_temp_free_i32(fp1);
b6d96bed 8939 gen_store_fpr32(fp2, fd);
a7812ae4 8940 tcg_temp_free_i32(fp2);
b6d96bed 8941 }
5a5012ec
TS
8942 opn = "nmadd.s";
8943 break;
8944 case OPC_NMADD_D:
b8aa4598
TS
8945 check_cop1x(ctx);
8946 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8947 {
a7812ae4
PB
8948 TCGv_i64 fp0 = tcg_temp_new_i64();
8949 TCGv_i64 fp1 = tcg_temp_new_i64();
8950 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8951
8952 gen_load_fpr64(ctx, fp0, fs);
8953 gen_load_fpr64(ctx, fp1, ft);
8954 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8955 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8956 tcg_temp_free_i64(fp0);
8957 tcg_temp_free_i64(fp1);
b6d96bed 8958 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8959 tcg_temp_free_i64(fp2);
b6d96bed 8960 }
5a5012ec
TS
8961 opn = "nmadd.d";
8962 break;
8963 case OPC_NMADD_PS:
b8aa4598 8964 check_cp1_64bitmode(ctx);
b6d96bed 8965 {
a7812ae4
PB
8966 TCGv_i64 fp0 = tcg_temp_new_i64();
8967 TCGv_i64 fp1 = tcg_temp_new_i64();
8968 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8969
8970 gen_load_fpr64(ctx, fp0, fs);
8971 gen_load_fpr64(ctx, fp1, ft);
8972 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8973 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8974 tcg_temp_free_i64(fp0);
8975 tcg_temp_free_i64(fp1);
b6d96bed 8976 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8977 tcg_temp_free_i64(fp2);
b6d96bed 8978 }
5a5012ec
TS
8979 opn = "nmadd.ps";
8980 break;
8981 case OPC_NMSUB_S:
b8aa4598 8982 check_cop1x(ctx);
b6d96bed 8983 {
a7812ae4
PB
8984 TCGv_i32 fp0 = tcg_temp_new_i32();
8985 TCGv_i32 fp1 = tcg_temp_new_i32();
8986 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8987
8988 gen_load_fpr32(fp0, fs);
8989 gen_load_fpr32(fp1, ft);
8990 gen_load_fpr32(fp2, fr);
b3d6cd44 8991 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8992 tcg_temp_free_i32(fp0);
8993 tcg_temp_free_i32(fp1);
b6d96bed 8994 gen_store_fpr32(fp2, fd);
a7812ae4 8995 tcg_temp_free_i32(fp2);
b6d96bed 8996 }
5a5012ec
TS
8997 opn = "nmsub.s";
8998 break;
8999 case OPC_NMSUB_D:
b8aa4598
TS
9000 check_cop1x(ctx);
9001 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9002 {
a7812ae4
PB
9003 TCGv_i64 fp0 = tcg_temp_new_i64();
9004 TCGv_i64 fp1 = tcg_temp_new_i64();
9005 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9006
9007 gen_load_fpr64(ctx, fp0, fs);
9008 gen_load_fpr64(ctx, fp1, ft);
9009 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9010 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9011 tcg_temp_free_i64(fp0);
9012 tcg_temp_free_i64(fp1);
b6d96bed 9013 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9014 tcg_temp_free_i64(fp2);
b6d96bed 9015 }
5a5012ec
TS
9016 opn = "nmsub.d";
9017 break;
9018 case OPC_NMSUB_PS:
b8aa4598 9019 check_cp1_64bitmode(ctx);
b6d96bed 9020 {
a7812ae4
PB
9021 TCGv_i64 fp0 = tcg_temp_new_i64();
9022 TCGv_i64 fp1 = tcg_temp_new_i64();
9023 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9024
9025 gen_load_fpr64(ctx, fp0, fs);
9026 gen_load_fpr64(ctx, fp1, ft);
9027 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9028 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9029 tcg_temp_free_i64(fp0);
9030 tcg_temp_free_i64(fp1);
b6d96bed 9031 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9032 tcg_temp_free_i64(fp2);
b6d96bed 9033 }
5a5012ec
TS
9034 opn = "nmsub.ps";
9035 break;
923617a3
TS
9036 default:
9037 MIPS_INVAL(opn);
5a5012ec
TS
9038 generate_exception (ctx, EXCP_RI);
9039 return;
9040 }
2abf314d 9041 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9042 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9043 fregnames[fs], fregnames[ft]);
7a387fff
TS
9044}
9045
d75c135e 9046static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9047{
9048 TCGv t0;
9049
b3167288
RH
9050#if !defined(CONFIG_USER_ONLY)
9051 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9052 Therefore only check the ISA in system mode. */
d75c135e 9053 check_insn(ctx, ISA_MIPS32R2);
b3167288 9054#endif
26ebe468
NF
9055 t0 = tcg_temp_new();
9056
9057 switch (rd) {
9058 case 0:
9059 save_cpu_state(ctx, 1);
895c2d04 9060 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9061 gen_store_gpr(t0, rt);
9062 break;
9063 case 1:
9064 save_cpu_state(ctx, 1);
895c2d04 9065 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9066 gen_store_gpr(t0, rt);
9067 break;
9068 case 2:
9069 save_cpu_state(ctx, 1);
895c2d04 9070 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9071 gen_store_gpr(t0, rt);
9072 break;
9073 case 3:
9074 save_cpu_state(ctx, 1);
895c2d04 9075 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9076 gen_store_gpr(t0, rt);
9077 break;
9078 case 29:
9079#if defined(CONFIG_USER_ONLY)
7db13fae 9080 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
26ebe468
NF
9081 gen_store_gpr(t0, rt);
9082 break;
9083#else
9084 /* XXX: Some CPUs implement this in hardware.
9085 Not supported yet. */
9086#endif
9087 default: /* Invalid */
9088 MIPS_INVAL("rdhwr");
9089 generate_exception(ctx, EXCP_RI);
9090 break;
9091 }
9092 tcg_temp_free(t0);
9093}
9094
d75c135e 9095static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9096{
9097 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9098 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9099 /* Branches completion */
9100 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9101 ctx->bstate = BS_BRANCH;
9102 save_cpu_state(ctx, 0);
9103 /* FIXME: Need to clear can_do_io. */
364d4831 9104 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9105 case MIPS_HFLAG_B:
9106 /* unconditional branch */
9107 MIPS_DEBUG("unconditional branch");
364d4831
NF
9108 if (proc_hflags & MIPS_HFLAG_BX) {
9109 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9110 }
c9602061
NF
9111 gen_goto_tb(ctx, 0, ctx->btarget);
9112 break;
9113 case MIPS_HFLAG_BL:
9114 /* blikely taken case */
9115 MIPS_DEBUG("blikely branch taken");
9116 gen_goto_tb(ctx, 0, ctx->btarget);
9117 break;
9118 case MIPS_HFLAG_BC:
9119 /* Conditional branch */
9120 MIPS_DEBUG("conditional branch");
9121 {
9122 int l1 = gen_new_label();
9123
9124 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9125 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9126 gen_set_label(l1);
9127 gen_goto_tb(ctx, 0, ctx->btarget);
9128 }
9129 break;
9130 case MIPS_HFLAG_BR:
9131 /* unconditional branch to register */
9132 MIPS_DEBUG("branch to register");
d75c135e 9133 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9134 TCGv t0 = tcg_temp_new();
9135 TCGv_i32 t1 = tcg_temp_new_i32();
9136
9137 tcg_gen_andi_tl(t0, btarget, 0x1);
9138 tcg_gen_trunc_tl_i32(t1, t0);
9139 tcg_temp_free(t0);
9140 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9141 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9142 tcg_gen_or_i32(hflags, hflags, t1);
9143 tcg_temp_free_i32(t1);
9144
9145 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9146 } else {
9147 tcg_gen_mov_tl(cpu_PC, btarget);
9148 }
c9602061
NF
9149 if (ctx->singlestep_enabled) {
9150 save_cpu_state(ctx, 0);
895c2d04 9151 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9152 }
9153 tcg_gen_exit_tb(0);
9154 break;
9155 default:
9156 MIPS_DEBUG("unknown branch");
9157 break;
9158 }
9159 }
9160}
9161
7a387fff 9162/* ISA extensions (ASEs) */
6af0bf9c 9163/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9164
9165/* MIPS16 major opcodes */
9166enum {
9167 M16_OPC_ADDIUSP = 0x00,
9168 M16_OPC_ADDIUPC = 0x01,
9169 M16_OPC_B = 0x02,
9170 M16_OPC_JAL = 0x03,
9171 M16_OPC_BEQZ = 0x04,
9172 M16_OPC_BNEQZ = 0x05,
9173 M16_OPC_SHIFT = 0x06,
9174 M16_OPC_LD = 0x07,
9175 M16_OPC_RRIA = 0x08,
9176 M16_OPC_ADDIU8 = 0x09,
9177 M16_OPC_SLTI = 0x0a,
9178 M16_OPC_SLTIU = 0x0b,
9179 M16_OPC_I8 = 0x0c,
9180 M16_OPC_LI = 0x0d,
9181 M16_OPC_CMPI = 0x0e,
9182 M16_OPC_SD = 0x0f,
9183 M16_OPC_LB = 0x10,
9184 M16_OPC_LH = 0x11,
9185 M16_OPC_LWSP = 0x12,
9186 M16_OPC_LW = 0x13,
9187 M16_OPC_LBU = 0x14,
9188 M16_OPC_LHU = 0x15,
9189 M16_OPC_LWPC = 0x16,
9190 M16_OPC_LWU = 0x17,
9191 M16_OPC_SB = 0x18,
9192 M16_OPC_SH = 0x19,
9193 M16_OPC_SWSP = 0x1a,
9194 M16_OPC_SW = 0x1b,
9195 M16_OPC_RRR = 0x1c,
9196 M16_OPC_RR = 0x1d,
9197 M16_OPC_EXTEND = 0x1e,
9198 M16_OPC_I64 = 0x1f
9199};
9200
9201/* I8 funct field */
9202enum {
9203 I8_BTEQZ = 0x0,
9204 I8_BTNEZ = 0x1,
9205 I8_SWRASP = 0x2,
9206 I8_ADJSP = 0x3,
9207 I8_SVRS = 0x4,
9208 I8_MOV32R = 0x5,
9209 I8_MOVR32 = 0x7
9210};
9211
9212/* RRR f field */
9213enum {
9214 RRR_DADDU = 0x0,
9215 RRR_ADDU = 0x1,
9216 RRR_DSUBU = 0x2,
9217 RRR_SUBU = 0x3
9218};
9219
9220/* RR funct field */
9221enum {
9222 RR_JR = 0x00,
9223 RR_SDBBP = 0x01,
9224 RR_SLT = 0x02,
9225 RR_SLTU = 0x03,
9226 RR_SLLV = 0x04,
9227 RR_BREAK = 0x05,
9228 RR_SRLV = 0x06,
9229 RR_SRAV = 0x07,
9230 RR_DSRL = 0x08,
9231 RR_CMP = 0x0a,
9232 RR_NEG = 0x0b,
9233 RR_AND = 0x0c,
9234 RR_OR = 0x0d,
9235 RR_XOR = 0x0e,
9236 RR_NOT = 0x0f,
9237 RR_MFHI = 0x10,
9238 RR_CNVT = 0x11,
9239 RR_MFLO = 0x12,
9240 RR_DSRA = 0x13,
9241 RR_DSLLV = 0x14,
9242 RR_DSRLV = 0x16,
9243 RR_DSRAV = 0x17,
9244 RR_MULT = 0x18,
9245 RR_MULTU = 0x19,
9246 RR_DIV = 0x1a,
9247 RR_DIVU = 0x1b,
9248 RR_DMULT = 0x1c,
9249 RR_DMULTU = 0x1d,
9250 RR_DDIV = 0x1e,
9251 RR_DDIVU = 0x1f
9252};
9253
9254/* I64 funct field */
9255enum {
9256 I64_LDSP = 0x0,
9257 I64_SDSP = 0x1,
9258 I64_SDRASP = 0x2,
9259 I64_DADJSP = 0x3,
9260 I64_LDPC = 0x4,
364d4831 9261 I64_DADDIU5 = 0x5,
6ea219d0
NF
9262 I64_DADDIUPC = 0x6,
9263 I64_DADDIUSP = 0x7
9264};
9265
9266/* RR ry field for CNVT */
9267enum {
9268 RR_RY_CNVT_ZEB = 0x0,
9269 RR_RY_CNVT_ZEH = 0x1,
9270 RR_RY_CNVT_ZEW = 0x2,
9271 RR_RY_CNVT_SEB = 0x4,
9272 RR_RY_CNVT_SEH = 0x5,
9273 RR_RY_CNVT_SEW = 0x6,
9274};
9275
364d4831
NF
9276static int xlat (int r)
9277{
9278 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9279
9280 return map[r];
9281}
9282
9283static void gen_mips16_save (DisasContext *ctx,
9284 int xsregs, int aregs,
9285 int do_ra, int do_s0, int do_s1,
9286 int framesize)
9287{
9288 TCGv t0 = tcg_temp_new();
9289 TCGv t1 = tcg_temp_new();
9290 int args, astatic;
9291
9292 switch (aregs) {
9293 case 0:
9294 case 1:
9295 case 2:
9296 case 3:
9297 case 11:
9298 args = 0;
9299 break;
9300 case 4:
9301 case 5:
9302 case 6:
9303 case 7:
9304 args = 1;
9305 break;
9306 case 8:
9307 case 9:
9308 case 10:
9309 args = 2;
9310 break;
9311 case 12:
9312 case 13:
9313 args = 3;
9314 break;
9315 case 14:
9316 args = 4;
9317 break;
9318 default:
9319 generate_exception(ctx, EXCP_RI);
9320 return;
9321 }
9322
9323 switch (args) {
9324 case 4:
9325 gen_base_offset_addr(ctx, t0, 29, 12);
9326 gen_load_gpr(t1, 7);
2910c6cb 9327 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9328 /* Fall through */
9329 case 3:
9330 gen_base_offset_addr(ctx, t0, 29, 8);
9331 gen_load_gpr(t1, 6);
2910c6cb 9332 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9333 /* Fall through */
9334 case 2:
9335 gen_base_offset_addr(ctx, t0, 29, 4);
9336 gen_load_gpr(t1, 5);
2910c6cb 9337 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9338 /* Fall through */
9339 case 1:
9340 gen_base_offset_addr(ctx, t0, 29, 0);
9341 gen_load_gpr(t1, 4);
2910c6cb 9342 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9343 }
9344
9345 gen_load_gpr(t0, 29);
9346
9347#define DECR_AND_STORE(reg) do { \
9348 tcg_gen_subi_tl(t0, t0, 4); \
9349 gen_load_gpr(t1, reg); \
2910c6cb 9350 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
364d4831
NF
9351 } while (0)
9352
9353 if (do_ra) {
9354 DECR_AND_STORE(31);
9355 }
9356
9357 switch (xsregs) {
9358 case 7:
9359 DECR_AND_STORE(30);
9360 /* Fall through */
9361 case 6:
9362 DECR_AND_STORE(23);
9363 /* Fall through */
9364 case 5:
9365 DECR_AND_STORE(22);
9366 /* Fall through */
9367 case 4:
9368 DECR_AND_STORE(21);
9369 /* Fall through */
9370 case 3:
9371 DECR_AND_STORE(20);
9372 /* Fall through */
9373 case 2:
9374 DECR_AND_STORE(19);
9375 /* Fall through */
9376 case 1:
9377 DECR_AND_STORE(18);
9378 }
9379
9380 if (do_s1) {
9381 DECR_AND_STORE(17);
9382 }
9383 if (do_s0) {
9384 DECR_AND_STORE(16);
9385 }
9386
9387 switch (aregs) {
9388 case 0:
9389 case 4:
9390 case 8:
9391 case 12:
9392 case 14:
9393 astatic = 0;
9394 break;
9395 case 1:
9396 case 5:
9397 case 9:
9398 case 13:
9399 astatic = 1;
9400 break;
9401 case 2:
9402 case 6:
9403 case 10:
9404 astatic = 2;
9405 break;
9406 case 3:
9407 case 7:
9408 astatic = 3;
9409 break;
9410 case 11:
9411 astatic = 4;
9412 break;
9413 default:
9414 generate_exception(ctx, EXCP_RI);
9415 return;
9416 }
9417
9418 if (astatic > 0) {
9419 DECR_AND_STORE(7);
9420 if (astatic > 1) {
9421 DECR_AND_STORE(6);
9422 if (astatic > 2) {
9423 DECR_AND_STORE(5);
9424 if (astatic > 3) {
9425 DECR_AND_STORE(4);
9426 }
9427 }
9428 }
9429 }
9430#undef DECR_AND_STORE
9431
9432 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9433 tcg_temp_free(t0);
9434 tcg_temp_free(t1);
9435}
9436
9437static void gen_mips16_restore (DisasContext *ctx,
9438 int xsregs, int aregs,
9439 int do_ra, int do_s0, int do_s1,
9440 int framesize)
9441{
9442 int astatic;
9443 TCGv t0 = tcg_temp_new();
9444 TCGv t1 = tcg_temp_new();
9445
9446 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9447
2910c6cb
AJ
9448#define DECR_AND_LOAD(reg) do { \
9449 tcg_gen_subi_tl(t0, t0, 4); \
17e8fef1 9450 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
2910c6cb 9451 gen_store_gpr(t1, reg); \
364d4831
NF
9452 } while (0)
9453
9454 if (do_ra) {
9455 DECR_AND_LOAD(31);
9456 }
9457
9458 switch (xsregs) {
9459 case 7:
9460 DECR_AND_LOAD(30);
9461 /* Fall through */
9462 case 6:
9463 DECR_AND_LOAD(23);
9464 /* Fall through */
9465 case 5:
9466 DECR_AND_LOAD(22);
9467 /* Fall through */
9468 case 4:
9469 DECR_AND_LOAD(21);
9470 /* Fall through */
9471 case 3:
9472 DECR_AND_LOAD(20);
9473 /* Fall through */
9474 case 2:
9475 DECR_AND_LOAD(19);
9476 /* Fall through */
9477 case 1:
9478 DECR_AND_LOAD(18);
9479 }
9480
9481 if (do_s1) {
9482 DECR_AND_LOAD(17);
9483 }
9484 if (do_s0) {
9485 DECR_AND_LOAD(16);
9486 }
9487
9488 switch (aregs) {
9489 case 0:
9490 case 4:
9491 case 8:
9492 case 12:
9493 case 14:
9494 astatic = 0;
9495 break;
9496 case 1:
9497 case 5:
9498 case 9:
9499 case 13:
9500 astatic = 1;
9501 break;
9502 case 2:
9503 case 6:
9504 case 10:
9505 astatic = 2;
9506 break;
9507 case 3:
9508 case 7:
9509 astatic = 3;
9510 break;
9511 case 11:
9512 astatic = 4;
9513 break;
9514 default:
9515 generate_exception(ctx, EXCP_RI);
9516 return;
9517 }
9518
9519 if (astatic > 0) {
9520 DECR_AND_LOAD(7);
9521 if (astatic > 1) {
9522 DECR_AND_LOAD(6);
9523 if (astatic > 2) {
9524 DECR_AND_LOAD(5);
9525 if (astatic > 3) {
9526 DECR_AND_LOAD(4);
9527 }
9528 }
9529 }
9530 }
9531#undef DECR_AND_LOAD
9532
9533 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9534 tcg_temp_free(t0);
9535 tcg_temp_free(t1);
9536}
9537
9538static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9539 int is_64_bit, int extended)
9540{
9541 TCGv t0;
9542
9543 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9544 generate_exception(ctx, EXCP_RI);
9545 return;
9546 }
9547
9548 t0 = tcg_temp_new();
9549
9550 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9551 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9552 if (!is_64_bit) {
9553 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9554 }
9555
9556 tcg_temp_free(t0);
9557}
9558
9559#if defined(TARGET_MIPS64)
d75c135e 9560static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9561 int ry, int funct, int16_t offset,
9562 int extended)
9563{
9564 switch (funct) {
9565 case I64_LDSP:
9566 check_mips_64(ctx);
9567 offset = extended ? offset : offset << 3;
d75c135e 9568 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9569 break;
9570 case I64_SDSP:
9571 check_mips_64(ctx);
9572 offset = extended ? offset : offset << 3;
5c13fdfd 9573 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9574 break;
9575 case I64_SDRASP:
9576 check_mips_64(ctx);
9577 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9578 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9579 break;
9580 case I64_DADJSP:
9581 check_mips_64(ctx);
9582 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9583 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9584 break;
9585 case I64_LDPC:
9586 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9587 generate_exception(ctx, EXCP_RI);
9588 } else {
9589 offset = extended ? offset : offset << 3;
d75c135e 9590 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9591 }
9592 break;
9593 case I64_DADDIU5:
9594 check_mips_64(ctx);
9595 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9596 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9597 break;
9598 case I64_DADDIUPC:
9599 check_mips_64(ctx);
9600 offset = extended ? offset : offset << 2;
9601 gen_addiupc(ctx, ry, offset, 1, extended);
9602 break;
9603 case I64_DADDIUSP:
9604 check_mips_64(ctx);
9605 offset = extended ? offset : offset << 2;
d75c135e 9606 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9607 break;
9608 }
9609}
9610#endif
9611
7db13fae 9612static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9613 int *is_branch)
9614{
895c2d04 9615 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9616 int op, rx, ry, funct, sa;
9617 int16_t imm, offset;
9618
9619 ctx->opcode = (ctx->opcode << 16) | extend;
9620 op = (ctx->opcode >> 11) & 0x1f;
9621 sa = (ctx->opcode >> 22) & 0x1f;
9622 funct = (ctx->opcode >> 8) & 0x7;
9623 rx = xlat((ctx->opcode >> 8) & 0x7);
9624 ry = xlat((ctx->opcode >> 5) & 0x7);
9625 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9626 | ((ctx->opcode >> 21) & 0x3f) << 5
9627 | (ctx->opcode & 0x1f));
9628
9629 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9630 counterparts. */
9631 switch (op) {
9632 case M16_OPC_ADDIUSP:
d75c135e 9633 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9634 break;
9635 case M16_OPC_ADDIUPC:
9636 gen_addiupc(ctx, rx, imm, 0, 1);
9637 break;
9638 case M16_OPC_B:
9639 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9640 /* No delay slot, so just process as a normal instruction */
9641 break;
9642 case M16_OPC_BEQZ:
9643 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9644 /* No delay slot, so just process as a normal instruction */
9645 break;
9646 case M16_OPC_BNEQZ:
9647 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9648 /* No delay slot, so just process as a normal instruction */
9649 break;
9650 case M16_OPC_SHIFT:
9651 switch (ctx->opcode & 0x3) {
9652 case 0x0:
d75c135e 9653 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9654 break;
9655 case 0x1:
9656#if defined(TARGET_MIPS64)
9657 check_mips_64(ctx);
d75c135e 9658 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9659#else
9660 generate_exception(ctx, EXCP_RI);
9661#endif
9662 break;
9663 case 0x2:
d75c135e 9664 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9665 break;
9666 case 0x3:
d75c135e 9667 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9668 break;
9669 }
9670 break;
9671#if defined(TARGET_MIPS64)
9672 case M16_OPC_LD:
9673 check_mips_64(ctx);
d75c135e 9674 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9675 break;
9676#endif
9677 case M16_OPC_RRIA:
9678 imm = ctx->opcode & 0xf;
9679 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9680 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9681 imm = (int16_t) (imm << 1) >> 1;
9682 if ((ctx->opcode >> 4) & 0x1) {
9683#if defined(TARGET_MIPS64)
9684 check_mips_64(ctx);
d75c135e 9685 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9686#else
9687 generate_exception(ctx, EXCP_RI);
9688#endif
9689 } else {
d75c135e 9690 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9691 }
9692 break;
9693 case M16_OPC_ADDIU8:
d75c135e 9694 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9695 break;
9696 case M16_OPC_SLTI:
d75c135e 9697 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9698 break;
9699 case M16_OPC_SLTIU:
d75c135e 9700 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9701 break;
9702 case M16_OPC_I8:
9703 switch (funct) {
9704 case I8_BTEQZ:
9705 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9706 break;
9707 case I8_BTNEZ:
9708 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9709 break;
9710 case I8_SWRASP:
5c13fdfd 9711 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9712 break;
9713 case I8_ADJSP:
d75c135e 9714 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
9715 break;
9716 case I8_SVRS:
9717 {
9718 int xsregs = (ctx->opcode >> 24) & 0x7;
9719 int aregs = (ctx->opcode >> 16) & 0xf;
9720 int do_ra = (ctx->opcode >> 6) & 0x1;
9721 int do_s0 = (ctx->opcode >> 5) & 0x1;
9722 int do_s1 = (ctx->opcode >> 4) & 0x1;
9723 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9724 | (ctx->opcode & 0xf)) << 3;
9725
9726 if (ctx->opcode & (1 << 7)) {
9727 gen_mips16_save(ctx, xsregs, aregs,
9728 do_ra, do_s0, do_s1,
9729 framesize);
9730 } else {
9731 gen_mips16_restore(ctx, xsregs, aregs,
9732 do_ra, do_s0, do_s1,
9733 framesize);
9734 }
9735 }
9736 break;
9737 default:
9738 generate_exception(ctx, EXCP_RI);
9739 break;
9740 }
9741 break;
9742 case M16_OPC_LI:
9743 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9744 break;
9745 case M16_OPC_CMPI:
9746 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9747 break;
9748#if defined(TARGET_MIPS64)
9749 case M16_OPC_SD:
5c13fdfd 9750 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9751 break;
9752#endif
9753 case M16_OPC_LB:
d75c135e 9754 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9755 break;
9756 case M16_OPC_LH:
d75c135e 9757 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9758 break;
9759 case M16_OPC_LWSP:
d75c135e 9760 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9761 break;
9762 case M16_OPC_LW:
d75c135e 9763 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9764 break;
9765 case M16_OPC_LBU:
d75c135e 9766 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9767 break;
9768 case M16_OPC_LHU:
d75c135e 9769 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9770 break;
9771 case M16_OPC_LWPC:
d75c135e 9772 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9773 break;
9774#if defined(TARGET_MIPS64)
9775 case M16_OPC_LWU:
d75c135e 9776 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9777 break;
9778#endif
9779 case M16_OPC_SB:
5c13fdfd 9780 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9781 break;
9782 case M16_OPC_SH:
5c13fdfd 9783 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9784 break;
9785 case M16_OPC_SWSP:
5c13fdfd 9786 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9787 break;
9788 case M16_OPC_SW:
5c13fdfd 9789 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9790 break;
9791#if defined(TARGET_MIPS64)
9792 case M16_OPC_I64:
d75c135e 9793 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
9794 break;
9795#endif
9796 default:
9797 generate_exception(ctx, EXCP_RI);
9798 break;
9799 }
9800
9801 return 4;
9802}
9803
7db13fae 9804static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9805 int *is_branch)
9806{
9807 int rx, ry;
9808 int sa;
9809 int op, cnvt_op, op1, offset;
9810 int funct;
9811 int n_bytes;
9812
9813 op = (ctx->opcode >> 11) & 0x1f;
9814 sa = (ctx->opcode >> 2) & 0x7;
9815 sa = sa == 0 ? 8 : sa;
9816 rx = xlat((ctx->opcode >> 8) & 0x7);
9817 cnvt_op = (ctx->opcode >> 5) & 0x7;
9818 ry = xlat((ctx->opcode >> 5) & 0x7);
9819 op1 = offset = ctx->opcode & 0x1f;
9820
9821 n_bytes = 2;
9822
9823 switch (op) {
9824 case M16_OPC_ADDIUSP:
9825 {
9826 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9827
d75c135e 9828 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9829 }
9830 break;
9831 case M16_OPC_ADDIUPC:
9832 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9833 break;
9834 case M16_OPC_B:
9835 offset = (ctx->opcode & 0x7ff) << 1;
9836 offset = (int16_t)(offset << 4) >> 4;
9837 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9838 /* No delay slot, so just process as a normal instruction */
9839 break;
9840 case M16_OPC_JAL:
895c2d04 9841 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9842 offset = (((ctx->opcode & 0x1f) << 21)
9843 | ((ctx->opcode >> 5) & 0x1f) << 16
9844 | offset) << 2;
620e48f6 9845 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9846 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9847 n_bytes = 4;
9848 *is_branch = 1;
9849 break;
9850 case M16_OPC_BEQZ:
9851 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9852 /* No delay slot, so just process as a normal instruction */
9853 break;
9854 case M16_OPC_BNEQZ:
9855 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9856 /* No delay slot, so just process as a normal instruction */
9857 break;
9858 case M16_OPC_SHIFT:
9859 switch (ctx->opcode & 0x3) {
9860 case 0x0:
d75c135e 9861 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9862 break;
9863 case 0x1:
9864#if defined(TARGET_MIPS64)
9865 check_mips_64(ctx);
d75c135e 9866 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
9867#else
9868 generate_exception(ctx, EXCP_RI);
9869#endif
9870 break;
9871 case 0x2:
d75c135e 9872 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
9873 break;
9874 case 0x3:
d75c135e 9875 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
9876 break;
9877 }
9878 break;
9879#if defined(TARGET_MIPS64)
9880 case M16_OPC_LD:
9881 check_mips_64(ctx);
d75c135e 9882 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9883 break;
9884#endif
9885 case M16_OPC_RRIA:
9886 {
9887 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9888
9889 if ((ctx->opcode >> 4) & 1) {
9890#if defined(TARGET_MIPS64)
9891 check_mips_64(ctx);
d75c135e 9892 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
9893#else
9894 generate_exception(ctx, EXCP_RI);
9895#endif
9896 } else {
d75c135e 9897 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
9898 }
9899 }
9900 break;
9901 case M16_OPC_ADDIU8:
9902 {
9903 int16_t imm = (int8_t) ctx->opcode;
9904
d75c135e 9905 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
9906 }
9907 break;
9908 case M16_OPC_SLTI:
9909 {
9910 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9911 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9912 }
9913 break;
9914 case M16_OPC_SLTIU:
9915 {
9916 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9917 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9918 }
9919 break;
9920 case M16_OPC_I8:
9921 {
9922 int reg32;
9923
9924 funct = (ctx->opcode >> 8) & 0x7;
9925 switch (funct) {
9926 case I8_BTEQZ:
9927 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9928 ((int8_t)ctx->opcode) << 1);
9929 break;
9930 case I8_BTNEZ:
9931 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9932 ((int8_t)ctx->opcode) << 1);
9933 break;
9934 case I8_SWRASP:
5c13fdfd 9935 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9936 break;
9937 case I8_ADJSP:
d75c135e 9938 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
9939 ((int8_t)ctx->opcode) << 3);
9940 break;
9941 case I8_SVRS:
9942 {
9943 int do_ra = ctx->opcode & (1 << 6);
9944 int do_s0 = ctx->opcode & (1 << 5);
9945 int do_s1 = ctx->opcode & (1 << 4);
9946 int framesize = ctx->opcode & 0xf;
9947
9948 if (framesize == 0) {
9949 framesize = 128;
9950 } else {
9951 framesize = framesize << 3;
9952 }
9953
9954 if (ctx->opcode & (1 << 7)) {
9955 gen_mips16_save(ctx, 0, 0,
9956 do_ra, do_s0, do_s1, framesize);
9957 } else {
9958 gen_mips16_restore(ctx, 0, 0,
9959 do_ra, do_s0, do_s1, framesize);
9960 }
9961 }
9962 break;
9963 case I8_MOV32R:
9964 {
9965 int rz = xlat(ctx->opcode & 0x7);
9966
9967 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9968 ((ctx->opcode >> 5) & 0x7);
d75c135e 9969 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
9970 }
9971 break;
9972 case I8_MOVR32:
9973 reg32 = ctx->opcode & 0x1f;
d75c135e 9974 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
9975 break;
9976 default:
9977 generate_exception(ctx, EXCP_RI);
9978 break;
9979 }
9980 }
9981 break;
9982 case M16_OPC_LI:
9983 {
9984 int16_t imm = (uint8_t) ctx->opcode;
9985
d75c135e 9986 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
9987 }
9988 break;
9989 case M16_OPC_CMPI:
9990 {
9991 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 9992 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
9993 }
9994 break;
9995#if defined(TARGET_MIPS64)
9996 case M16_OPC_SD:
9997 check_mips_64(ctx);
5c13fdfd 9998 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
9999 break;
10000#endif
10001 case M16_OPC_LB:
d75c135e 10002 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10003 break;
10004 case M16_OPC_LH:
d75c135e 10005 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
10006 break;
10007 case M16_OPC_LWSP:
d75c135e 10008 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10009 break;
10010 case M16_OPC_LW:
d75c135e 10011 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10012 break;
10013 case M16_OPC_LBU:
d75c135e 10014 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10015 break;
10016 case M16_OPC_LHU:
d75c135e 10017 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10018 break;
10019 case M16_OPC_LWPC:
d75c135e 10020 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10021 break;
10022#if defined (TARGET_MIPS64)
10023 case M16_OPC_LWU:
10024 check_mips_64(ctx);
d75c135e 10025 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10026 break;
10027#endif
10028 case M16_OPC_SB:
5c13fdfd 10029 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10030 break;
10031 case M16_OPC_SH:
5c13fdfd 10032 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10033 break;
10034 case M16_OPC_SWSP:
5c13fdfd 10035 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10036 break;
10037 case M16_OPC_SW:
5c13fdfd 10038 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10039 break;
10040 case M16_OPC_RRR:
10041 {
10042 int rz = xlat((ctx->opcode >> 2) & 0x7);
10043 int mips32_op;
10044
10045 switch (ctx->opcode & 0x3) {
10046 case RRR_ADDU:
10047 mips32_op = OPC_ADDU;
10048 break;
10049 case RRR_SUBU:
10050 mips32_op = OPC_SUBU;
10051 break;
10052#if defined(TARGET_MIPS64)
10053 case RRR_DADDU:
10054 mips32_op = OPC_DADDU;
10055 check_mips_64(ctx);
10056 break;
10057 case RRR_DSUBU:
10058 mips32_op = OPC_DSUBU;
10059 check_mips_64(ctx);
10060 break;
10061#endif
10062 default:
10063 generate_exception(ctx, EXCP_RI);
10064 goto done;
10065 }
10066
d75c135e 10067 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10068 done:
10069 ;
10070 }
10071 break;
10072 case M16_OPC_RR:
10073 switch (op1) {
10074 case RR_JR:
10075 {
10076 int nd = (ctx->opcode >> 7) & 0x1;
10077 int link = (ctx->opcode >> 6) & 0x1;
10078 int ra = (ctx->opcode >> 5) & 0x1;
10079
10080 if (link) {
620e48f6 10081 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10082 } else {
10083 op = OPC_JR;
10084 }
10085
10086 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10087 if (!nd) {
10088 *is_branch = 1;
10089 }
10090 }
10091 break;
10092 case RR_SDBBP:
10093 /* XXX: not clear which exception should be raised
10094 * when in debug mode...
10095 */
d75c135e 10096 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10097 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10098 generate_exception(ctx, EXCP_DBp);
10099 } else {
10100 generate_exception(ctx, EXCP_DBp);
10101 }
10102 break;
10103 case RR_SLT:
d75c135e 10104 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10105 break;
10106 case RR_SLTU:
d75c135e 10107 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10108 break;
10109 case RR_BREAK:
10110 generate_exception(ctx, EXCP_BREAK);
10111 break;
10112 case RR_SLLV:
d75c135e 10113 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10114 break;
10115 case RR_SRLV:
d75c135e 10116 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10117 break;
10118 case RR_SRAV:
d75c135e 10119 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10120 break;
10121#if defined (TARGET_MIPS64)
10122 case RR_DSRL:
10123 check_mips_64(ctx);
d75c135e 10124 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10125 break;
10126#endif
10127 case RR_CMP:
d75c135e 10128 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10129 break;
10130 case RR_NEG:
d75c135e 10131 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10132 break;
10133 case RR_AND:
d75c135e 10134 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10135 break;
10136 case RR_OR:
d75c135e 10137 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10138 break;
10139 case RR_XOR:
d75c135e 10140 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10141 break;
10142 case RR_NOT:
d75c135e 10143 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10144 break;
10145 case RR_MFHI:
10146 gen_HILO(ctx, OPC_MFHI, rx);
10147 break;
10148 case RR_CNVT:
10149 switch (cnvt_op) {
10150 case RR_RY_CNVT_ZEB:
10151 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10152 break;
10153 case RR_RY_CNVT_ZEH:
10154 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10155 break;
10156 case RR_RY_CNVT_SEB:
10157 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10158 break;
10159 case RR_RY_CNVT_SEH:
10160 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10161 break;
10162#if defined (TARGET_MIPS64)
10163 case RR_RY_CNVT_ZEW:
10164 check_mips_64(ctx);
10165 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10166 break;
10167 case RR_RY_CNVT_SEW:
10168 check_mips_64(ctx);
10169 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10170 break;
10171#endif
10172 default:
10173 generate_exception(ctx, EXCP_RI);
10174 break;
10175 }
10176 break;
10177 case RR_MFLO:
10178 gen_HILO(ctx, OPC_MFLO, rx);
10179 break;
10180#if defined (TARGET_MIPS64)
10181 case RR_DSRA:
10182 check_mips_64(ctx);
d75c135e 10183 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10184 break;
10185 case RR_DSLLV:
10186 check_mips_64(ctx);
d75c135e 10187 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10188 break;
10189 case RR_DSRLV:
10190 check_mips_64(ctx);
d75c135e 10191 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10192 break;
10193 case RR_DSRAV:
10194 check_mips_64(ctx);
d75c135e 10195 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10196 break;
10197#endif
10198 case RR_MULT:
10199 gen_muldiv(ctx, OPC_MULT, rx, ry);
10200 break;
10201 case RR_MULTU:
10202 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10203 break;
10204 case RR_DIV:
10205 gen_muldiv(ctx, OPC_DIV, rx, ry);
10206 break;
10207 case RR_DIVU:
10208 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10209 break;
10210#if defined (TARGET_MIPS64)
10211 case RR_DMULT:
10212 check_mips_64(ctx);
10213 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10214 break;
10215 case RR_DMULTU:
10216 check_mips_64(ctx);
10217 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10218 break;
10219 case RR_DDIV:
10220 check_mips_64(ctx);
10221 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10222 break;
10223 case RR_DDIVU:
10224 check_mips_64(ctx);
10225 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10226 break;
10227#endif
10228 default:
10229 generate_exception(ctx, EXCP_RI);
10230 break;
10231 }
10232 break;
10233 case M16_OPC_EXTEND:
10234 decode_extended_mips16_opc(env, ctx, is_branch);
10235 n_bytes = 4;
10236 break;
10237#if defined(TARGET_MIPS64)
10238 case M16_OPC_I64:
10239 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10240 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10241 break;
10242#endif
10243 default:
10244 generate_exception(ctx, EXCP_RI);
10245 break;
10246 }
10247
10248 return n_bytes;
10249}
10250
211da992 10251/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10252
211da992
WRC
10253/*
10254 * microMIPS32/microMIPS64 major opcodes
10255 *
10256 * 1. MIPS Architecture for Programmers Volume II-B:
10257 * The microMIPS32 Instruction Set (Revision 3.05)
10258 *
10259 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10260 *
10261 * 2. MIPS Architecture For Programmers Volume II-A:
10262 * The MIPS64 Instruction Set (Revision 3.51)
10263 */
6af0bf9c 10264
3c824109
NF
10265enum {
10266 POOL32A = 0x00,
10267 POOL16A = 0x01,
10268 LBU16 = 0x02,
10269 MOVE16 = 0x03,
10270 ADDI32 = 0x04,
10271 LBU32 = 0x05,
10272 SB32 = 0x06,
10273 LB32 = 0x07,
10274
10275 POOL32B = 0x08,
10276 POOL16B = 0x09,
10277 LHU16 = 0x0a,
10278 ANDI16 = 0x0b,
10279 ADDIU32 = 0x0c,
10280 LHU32 = 0x0d,
10281 SH32 = 0x0e,
10282 LH32 = 0x0f,
10283
10284 POOL32I = 0x10,
10285 POOL16C = 0x11,
10286 LWSP16 = 0x12,
10287 POOL16D = 0x13,
10288 ORI32 = 0x14,
10289 POOL32F = 0x15,
211da992
WRC
10290 POOL32S = 0x16, /* MIPS64 */
10291 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10292
211da992 10293 /* 0x1f is reserved */
3c824109
NF
10294 POOL32C = 0x18,
10295 LWGP16 = 0x19,
10296 LW16 = 0x1a,
10297 POOL16E = 0x1b,
10298 XORI32 = 0x1c,
10299 JALS32 = 0x1d,
10300 ADDIUPC = 0x1e,
3c824109
NF
10301
10302 /* 0x20 is reserved */
10303 RES_20 = 0x20,
10304 POOL16F = 0x21,
10305 SB16 = 0x22,
10306 BEQZ16 = 0x23,
10307 SLTI32 = 0x24,
10308 BEQ32 = 0x25,
10309 SWC132 = 0x26,
10310 LWC132 = 0x27,
10311
10312 /* 0x28 and 0x29 are reserved */
10313 RES_28 = 0x28,
10314 RES_29 = 0x29,
10315 SH16 = 0x2a,
10316 BNEZ16 = 0x2b,
10317 SLTIU32 = 0x2c,
10318 BNE32 = 0x2d,
10319 SDC132 = 0x2e,
10320 LDC132 = 0x2f,
10321
10322 /* 0x30 and 0x31 are reserved */
10323 RES_30 = 0x30,
10324 RES_31 = 0x31,
10325 SWSP16 = 0x32,
10326 B16 = 0x33,
10327 ANDI32 = 0x34,
10328 J32 = 0x35,
211da992
WRC
10329 SD32 = 0x36, /* MIPS64 */
10330 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10331
10332 /* 0x38 and 0x39 are reserved */
10333 RES_38 = 0x38,
10334 RES_39 = 0x39,
10335 SW16 = 0x3a,
10336 LI16 = 0x3b,
10337 JALX32 = 0x3c,
10338 JAL32 = 0x3d,
10339 SW32 = 0x3e,
10340 LW32 = 0x3f
10341};
10342
10343/* POOL32A encoding of minor opcode field */
10344
10345enum {
10346 /* These opcodes are distinguished only by bits 9..6; those bits are
10347 * what are recorded below. */
10348 SLL32 = 0x0,
10349 SRL32 = 0x1,
10350 SRA = 0x2,
10351 ROTR = 0x3,
10352
10353 SLLV = 0x0,
10354 SRLV = 0x1,
10355 SRAV = 0x2,
10356 ROTRV = 0x3,
10357 ADD = 0x4,
10358 ADDU32 = 0x5,
10359 SUB = 0x6,
10360 SUBU32 = 0x7,
10361 MUL = 0x8,
10362 AND = 0x9,
10363 OR32 = 0xa,
10364 NOR = 0xb,
10365 XOR32 = 0xc,
10366 SLT = 0xd,
10367 SLTU = 0xe,
10368
10369 MOVN = 0x0,
10370 MOVZ = 0x1,
10371 LWXS = 0x4,
10372
10373 /* The following can be distinguished by their lower 6 bits. */
10374 INS = 0x0c,
10375 EXT = 0x2c,
10376 POOL32AXF = 0x3c
10377};
10378
10379/* POOL32AXF encoding of minor opcode field extension */
10380
d132c79f
WRC
10381/*
10382 * 1. MIPS Architecture for Programmers Volume II-B:
10383 * The microMIPS32 Instruction Set (Revision 3.05)
10384 *
10385 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10386 *
10387 * 2. MIPS Architecture for Programmers VolumeIV-e:
10388 * The MIPS DSP Application-Specific Extension
10389 * to the microMIPS32 Architecture (Revision 2.34)
10390 *
10391 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10392 */
10393
3c824109
NF
10394enum {
10395 /* bits 11..6 */
10396 TEQ = 0x00,
10397 TGE = 0x08,
10398 TGEU = 0x10,
10399 TLT = 0x20,
10400 TLTU = 0x28,
10401 TNE = 0x30,
10402
10403 MFC0 = 0x03,
10404 MTC0 = 0x0b,
10405
d132c79f
WRC
10406 /* begin of microMIPS32 DSP */
10407
3c824109
NF
10408 /* bits 13..12 for 0x01 */
10409 MFHI_ACC = 0x0,
10410 MFLO_ACC = 0x1,
10411 MTHI_ACC = 0x2,
10412 MTLO_ACC = 0x3,
10413
10414 /* bits 13..12 for 0x2a */
10415 MADD_ACC = 0x0,
10416 MADDU_ACC = 0x1,
10417 MSUB_ACC = 0x2,
10418 MSUBU_ACC = 0x3,
10419
10420 /* bits 13..12 for 0x32 */
10421 MULT_ACC = 0x0,
6801038b 10422 MULTU_ACC = 0x1,
3c824109 10423
d132c79f
WRC
10424 /* end of microMIPS32 DSP */
10425
3c824109
NF
10426 /* bits 15..12 for 0x2c */
10427 SEB = 0x2,
10428 SEH = 0x3,
10429 CLO = 0x4,
10430 CLZ = 0x5,
10431 RDHWR = 0x6,
10432 WSBH = 0x7,
10433 MULT = 0x8,
10434 MULTU = 0x9,
10435 DIV = 0xa,
10436 DIVU = 0xb,
10437 MADD = 0xc,
10438 MADDU = 0xd,
10439 MSUB = 0xe,
10440 MSUBU = 0xf,
10441
10442 /* bits 15..12 for 0x34 */
10443 MFC2 = 0x4,
10444 MTC2 = 0x5,
10445 MFHC2 = 0x8,
10446 MTHC2 = 0x9,
10447 CFC2 = 0xc,
10448 CTC2 = 0xd,
10449
10450 /* bits 15..12 for 0x3c */
10451 JALR = 0x0,
10452 JR = 0x0, /* alias */
10453 JALR_HB = 0x1,
10454 JALRS = 0x4,
10455 JALRS_HB = 0x5,
10456
10457 /* bits 15..12 for 0x05 */
10458 RDPGPR = 0xe,
10459 WRPGPR = 0xf,
10460
10461 /* bits 15..12 for 0x0d */
10462 TLBP = 0x0,
10463 TLBR = 0x1,
10464 TLBWI = 0x2,
10465 TLBWR = 0x3,
10466 WAIT = 0x9,
10467 IRET = 0xd,
10468 DERET = 0xe,
10469 ERET = 0xf,
10470
10471 /* bits 15..12 for 0x15 */
10472 DMT = 0x0,
10473 DVPE = 0x1,
10474 EMT = 0x2,
10475 EVPE = 0x3,
10476
10477 /* bits 15..12 for 0x1d */
10478 DI = 0x4,
10479 EI = 0x5,
10480
10481 /* bits 15..12 for 0x2d */
10482 SYNC = 0x6,
10483 SYSCALL = 0x8,
10484 SDBBP = 0xd,
10485
10486 /* bits 15..12 for 0x35 */
10487 MFHI32 = 0x0,
10488 MFLO32 = 0x1,
10489 MTHI32 = 0x2,
10490 MTLO32 = 0x3,
10491};
10492
10493/* POOL32B encoding of minor opcode field (bits 15..12) */
10494
10495enum {
10496 LWC2 = 0x0,
10497 LWP = 0x1,
10498 LDP = 0x4,
10499 LWM32 = 0x5,
10500 CACHE = 0x6,
10501 LDM = 0x7,
10502 SWC2 = 0x8,
10503 SWP = 0x9,
10504 SDP = 0xc,
10505 SWM32 = 0xd,
10506 SDM = 0xf
10507};
10508
10509/* POOL32C encoding of minor opcode field (bits 15..12) */
10510
10511enum {
10512 LWL = 0x0,
10513 SWL = 0x8,
10514 LWR = 0x1,
10515 SWR = 0x9,
10516 PREF = 0x2,
10517 /* 0xa is reserved */
10518 LL = 0x3,
10519 SC = 0xb,
10520 LDL = 0x4,
10521 SDL = 0xc,
10522 LDR = 0x5,
10523 SDR = 0xd,
10524 /* 0x6 is reserved */
10525 LWU = 0xe,
10526 LLD = 0x7,
10527 SCD = 0xf
10528};
10529
10530/* POOL32F encoding of minor opcode field (bits 5..0) */
10531
10532enum {
10533 /* These are the bit 7..6 values */
10534 ADD_FMT = 0x0,
10535 MOVN_FMT = 0x0,
10536
10537 SUB_FMT = 0x1,
10538 MOVZ_FMT = 0x1,
10539
10540 MUL_FMT = 0x2,
10541
10542 DIV_FMT = 0x3,
10543
10544 /* These are the bit 8..6 values */
10545 RSQRT2_FMT = 0x0,
10546 MOVF_FMT = 0x0,
10547
10548 LWXC1 = 0x1,
10549 MOVT_FMT = 0x1,
10550
10551 PLL_PS = 0x2,
10552 SWXC1 = 0x2,
10553
10554 PLU_PS = 0x3,
10555 LDXC1 = 0x3,
10556
10557 PUL_PS = 0x4,
10558 SDXC1 = 0x4,
10559 RECIP2_FMT = 0x4,
10560
10561 PUU_PS = 0x5,
10562 LUXC1 = 0x5,
10563
10564 CVT_PS_S = 0x6,
10565 SUXC1 = 0x6,
10566 ADDR_PS = 0x6,
10567 PREFX = 0x6,
10568
10569 MULR_PS = 0x7,
10570
10571 MADD_S = 0x01,
10572 MADD_D = 0x09,
10573 MADD_PS = 0x11,
10574 ALNV_PS = 0x19,
10575 MSUB_S = 0x21,
10576 MSUB_D = 0x29,
10577 MSUB_PS = 0x31,
10578
10579 NMADD_S = 0x02,
10580 NMADD_D = 0x0a,
10581 NMADD_PS = 0x12,
10582 NMSUB_S = 0x22,
10583 NMSUB_D = 0x2a,
10584 NMSUB_PS = 0x32,
10585
10586 POOL32FXF = 0x3b,
10587
10588 CABS_COND_FMT = 0x1c, /* MIPS3D */
10589 C_COND_FMT = 0x3c
10590};
10591
10592/* POOL32Fxf encoding of minor opcode extension field */
10593
10594enum {
10595 CVT_L = 0x04,
10596 RSQRT_FMT = 0x08,
10597 FLOOR_L = 0x0c,
10598 CVT_PW_PS = 0x1c,
10599 CVT_W = 0x24,
10600 SQRT_FMT = 0x28,
10601 FLOOR_W = 0x2c,
10602 CVT_PS_PW = 0x3c,
10603 CFC1 = 0x40,
10604 RECIP_FMT = 0x48,
10605 CEIL_L = 0x4c,
10606 CTC1 = 0x60,
10607 CEIL_W = 0x6c,
10608 MFC1 = 0x80,
10609 CVT_S_PL = 0x84,
10610 TRUNC_L = 0x8c,
10611 MTC1 = 0xa0,
10612 CVT_S_PU = 0xa4,
10613 TRUNC_W = 0xac,
10614 MFHC1 = 0xc0,
10615 ROUND_L = 0xcc,
10616 MTHC1 = 0xe0,
10617 ROUND_W = 0xec,
10618
10619 MOV_FMT = 0x01,
10620 MOVF = 0x05,
10621 ABS_FMT = 0x0d,
10622 RSQRT1_FMT = 0x1d,
10623 MOVT = 0x25,
10624 NEG_FMT = 0x2d,
10625 CVT_D = 0x4d,
10626 RECIP1_FMT = 0x5d,
10627 CVT_S = 0x6d
10628};
10629
10630/* POOL32I encoding of minor opcode field (bits 25..21) */
10631
10632enum {
10633 BLTZ = 0x00,
10634 BLTZAL = 0x01,
10635 BGEZ = 0x02,
10636 BGEZAL = 0x03,
10637 BLEZ = 0x04,
10638 BNEZC = 0x05,
10639 BGTZ = 0x06,
10640 BEQZC = 0x07,
10641 TLTI = 0x08,
10642 TGEI = 0x09,
10643 TLTIU = 0x0a,
10644 TGEIU = 0x0b,
10645 TNEI = 0x0c,
10646 LUI = 0x0d,
10647 TEQI = 0x0e,
10648 SYNCI = 0x10,
10649 BLTZALS = 0x11,
10650 BGEZALS = 0x13,
10651 BC2F = 0x14,
10652 BC2T = 0x15,
10653 BPOSGE64 = 0x1a,
10654 BPOSGE32 = 0x1b,
10655 /* These overlap and are distinguished by bit16 of the instruction */
10656 BC1F = 0x1c,
10657 BC1T = 0x1d,
10658 BC1ANY2F = 0x1c,
10659 BC1ANY2T = 0x1d,
10660 BC1ANY4F = 0x1e,
10661 BC1ANY4T = 0x1f
10662};
10663
10664/* POOL16A encoding of minor opcode field */
10665
10666enum {
10667 ADDU16 = 0x0,
10668 SUBU16 = 0x1
10669};
10670
10671/* POOL16B encoding of minor opcode field */
10672
10673enum {
10674 SLL16 = 0x0,
10675 SRL16 = 0x1
10676};
10677
10678/* POOL16C encoding of minor opcode field */
10679
10680enum {
10681 NOT16 = 0x00,
10682 XOR16 = 0x04,
10683 AND16 = 0x08,
10684 OR16 = 0x0c,
10685 LWM16 = 0x10,
10686 SWM16 = 0x14,
10687 JR16 = 0x18,
10688 JRC16 = 0x1a,
10689 JALR16 = 0x1c,
10690 JALR16S = 0x1e,
10691 MFHI16 = 0x20,
10692 MFLO16 = 0x24,
10693 BREAK16 = 0x28,
10694 SDBBP16 = 0x2c,
10695 JRADDIUSP = 0x30
10696};
10697
10698/* POOL16D encoding of minor opcode field */
10699
10700enum {
10701 ADDIUS5 = 0x0,
10702 ADDIUSP = 0x1
10703};
10704
10705/* POOL16E encoding of minor opcode field */
10706
10707enum {
10708 ADDIUR2 = 0x0,
10709 ADDIUR1SP = 0x1
10710};
10711
10712static int mmreg (int r)
10713{
10714 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10715
10716 return map[r];
10717}
10718
10719/* Used for 16-bit store instructions. */
10720static int mmreg2 (int r)
10721{
10722 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10723
10724 return map[r];
10725}
10726
10727#define uMIPS_RD(op) ((op >> 7) & 0x7)
10728#define uMIPS_RS(op) ((op >> 4) & 0x7)
10729#define uMIPS_RS2(op) uMIPS_RS(op)
10730#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10731#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10732#define uMIPS_RS5(op) (op & 0x1f)
10733
10734/* Signed immediate */
10735#define SIMM(op, start, width) \
10736 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10737 << (32-width)) \
10738 >> (32-width))
10739/* Zero-extended immediate */
10740#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10741
d75c135e 10742static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
10743{
10744 int rd = mmreg(uMIPS_RD(ctx->opcode));
10745
d75c135e 10746 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
10747}
10748
d75c135e 10749static void gen_addiur2(DisasContext *ctx)
3c824109
NF
10750{
10751 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10752 int rd = mmreg(uMIPS_RD(ctx->opcode));
10753 int rs = mmreg(uMIPS_RS(ctx->opcode));
10754
d75c135e 10755 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
10756}
10757
d75c135e 10758static void gen_addiusp(DisasContext *ctx)
3c824109
NF
10759{
10760 int encoded = ZIMM(ctx->opcode, 1, 9);
10761 int decoded;
10762
10763 if (encoded <= 1) {
10764 decoded = 256 + encoded;
10765 } else if (encoded <= 255) {
10766 decoded = encoded;
10767 } else if (encoded <= 509) {
10768 decoded = encoded - 512;
10769 } else {
10770 decoded = encoded - 768;
10771 }
10772
d75c135e 10773 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
10774}
10775
d75c135e 10776static void gen_addius5(DisasContext *ctx)
3c824109
NF
10777{
10778 int imm = SIMM(ctx->opcode, 1, 4);
10779 int rd = (ctx->opcode >> 5) & 0x1f;
10780
d75c135e 10781 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
10782}
10783
d75c135e 10784static void gen_andi16(DisasContext *ctx)
3c824109
NF
10785{
10786 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10787 31, 32, 63, 64, 255, 32768, 65535 };
10788 int rd = mmreg(uMIPS_RD(ctx->opcode));
10789 int rs = mmreg(uMIPS_RS(ctx->opcode));
10790 int encoded = ZIMM(ctx->opcode, 0, 4);
10791
d75c135e 10792 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10793}
10794
10795static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10796 int base, int16_t offset)
10797{
e1050a76 10798 const char *opn = "ldst_multiple";
3c824109
NF
10799 TCGv t0, t1;
10800 TCGv_i32 t2;
10801
10802 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10803 generate_exception(ctx, EXCP_RI);
10804 return;
10805 }
10806
10807 t0 = tcg_temp_new();
10808
10809 gen_base_offset_addr(ctx, t0, base, offset);
10810
10811 t1 = tcg_const_tl(reglist);
10812 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10813
3c824109
NF
10814 save_cpu_state(ctx, 1);
10815 switch (opc) {
10816 case LWM32:
895c2d04 10817 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10818 opn = "lwm";
3c824109
NF
10819 break;
10820 case SWM32:
895c2d04 10821 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10822 opn = "swm";
3c824109
NF
10823 break;
10824#ifdef TARGET_MIPS64
10825 case LDM:
895c2d04 10826 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10827 opn = "ldm";
3c824109
NF
10828 break;
10829 case SDM:
895c2d04 10830 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10831 opn = "sdm";
3c824109 10832 break;
6af0bf9c 10833#endif
3c824109 10834 }
e1050a76 10835 (void)opn;
3c824109
NF
10836 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10837 tcg_temp_free(t0);
33087598 10838 tcg_temp_free(t1);
3c824109
NF
10839 tcg_temp_free_i32(t2);
10840}
6af0bf9c 10841
3c824109 10842
d75c135e 10843static void gen_pool16c_insn(DisasContext *ctx, int *is_branch)
6af0bf9c 10844{
3c824109
NF
10845 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10846 int rs = mmreg(ctx->opcode & 0x7);
10847 int opc;
6af0bf9c 10848
3c824109
NF
10849 switch (((ctx->opcode) >> 4) & 0x3f) {
10850 case NOT16 + 0:
10851 case NOT16 + 1:
10852 case NOT16 + 2:
10853 case NOT16 + 3:
d75c135e 10854 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10855 break;
10856 case XOR16 + 0:
10857 case XOR16 + 1:
10858 case XOR16 + 2:
10859 case XOR16 + 3:
d75c135e 10860 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10861 break;
10862 case AND16 + 0:
10863 case AND16 + 1:
10864 case AND16 + 2:
10865 case AND16 + 3:
d75c135e 10866 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10867 break;
10868 case OR16 + 0:
10869 case OR16 + 1:
10870 case OR16 + 2:
10871 case OR16 + 3:
d75c135e 10872 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10873 break;
10874 case LWM16 + 0:
10875 case LWM16 + 1:
10876 case LWM16 + 2:
10877 case LWM16 + 3:
10878 {
10879 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10880 int offset = ZIMM(ctx->opcode, 0, 4);
10881
10882 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10883 29, offset << 2);
10884 }
10885 break;
10886 case SWM16 + 0:
10887 case SWM16 + 1:
10888 case SWM16 + 2:
10889 case SWM16 + 3:
10890 {
10891 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10892 int offset = ZIMM(ctx->opcode, 0, 4);
10893
10894 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10895 29, offset << 2);
10896 }
10897 break;
10898 case JR16 + 0:
10899 case JR16 + 1:
10900 {
10901 int reg = ctx->opcode & 0x1f;
10902
10903 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10904 }
10905 *is_branch = 1;
10906 break;
10907 case JRC16 + 0:
10908 case JRC16 + 1:
10909 {
10910 int reg = ctx->opcode & 0x1f;
10911
10912 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10913 /* Let normal delay slot handling in our caller take us
10914 to the branch target. */
10915 }
10916 break;
10917 case JALR16 + 0:
10918 case JALR16 + 1:
10919 opc = OPC_JALR;
10920 goto do_jalr;
10921 case JALR16S + 0:
10922 case JALR16S + 1:
10923 opc = OPC_JALRS;
10924 do_jalr:
10925 {
10926 int reg = ctx->opcode & 0x1f;
10927
10928 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10929 }
10930 *is_branch = 1;
10931 break;
10932 case MFHI16 + 0:
10933 case MFHI16 + 1:
10934 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10935 break;
10936 case MFLO16 + 0:
10937 case MFLO16 + 1:
10938 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10939 break;
10940 case BREAK16:
10941 generate_exception(ctx, EXCP_BREAK);
10942 break;
10943 case SDBBP16:
10944 /* XXX: not clear which exception should be raised
10945 * when in debug mode...
10946 */
d75c135e 10947 check_insn(ctx, ISA_MIPS32);
3c824109
NF
10948 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10949 generate_exception(ctx, EXCP_DBp);
10950 } else {
10951 generate_exception(ctx, EXCP_DBp);
10952 }
10953 break;
10954 case JRADDIUSP + 0:
10955 case JRADDIUSP + 1:
10956 {
10957 int imm = ZIMM(ctx->opcode, 0, 5);
10958
10959 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 10960 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
10961 /* Let normal delay slot handling in our caller take us
10962 to the branch target. */
10963 }
10964 break;
10965 default:
10966 generate_exception(ctx, EXCP_RI);
10967 break;
10968 }
10969}
10970
10971static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10972{
10973 TCGv t0 = tcg_temp_new();
10974 TCGv t1 = tcg_temp_new();
10975
10976 gen_load_gpr(t0, base);
10977
10978 if (index != 0) {
10979 gen_load_gpr(t1, index);
10980 tcg_gen_shli_tl(t1, t1, 2);
10981 gen_op_addr_add(ctx, t0, t1, t0);
10982 }
10983
2910c6cb 10984 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
10985 gen_store_gpr(t1, rd);
10986
10987 tcg_temp_free(t0);
10988 tcg_temp_free(t1);
10989}
10990
10991static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10992 int base, int16_t offset)
10993{
10994 const char *opn = "ldst_pair";
10995 TCGv t0, t1;
10996
36c6711b 10997 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 10998 generate_exception(ctx, EXCP_RI);
d796321b
FB
10999 return;
11000 }
11001
3c824109
NF
11002 t0 = tcg_temp_new();
11003 t1 = tcg_temp_new();
8e9ade68 11004
3c824109
NF
11005 gen_base_offset_addr(ctx, t0, base, offset);
11006
11007 switch (opc) {
11008 case LWP:
36c6711b
EJ
11009 if (rd == base) {
11010 generate_exception(ctx, EXCP_RI);
11011 return;
11012 }
2910c6cb 11013 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11014 gen_store_gpr(t1, rd);
11015 tcg_gen_movi_tl(t1, 4);
11016 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11017 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11018 gen_store_gpr(t1, rd+1);
11019 opn = "lwp";
11020 break;
11021 case SWP:
3c824109 11022 gen_load_gpr(t1, rd);
2910c6cb 11023 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11024 tcg_gen_movi_tl(t1, 4);
11025 gen_op_addr_add(ctx, t0, t0, t1);
11026 gen_load_gpr(t1, rd+1);
2910c6cb 11027 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11028 opn = "swp";
11029 break;
11030#ifdef TARGET_MIPS64
11031 case LDP:
36c6711b
EJ
11032 if (rd == base) {
11033 generate_exception(ctx, EXCP_RI);
11034 return;
11035 }
2910c6cb 11036 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11037 gen_store_gpr(t1, rd);
11038 tcg_gen_movi_tl(t1, 8);
11039 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11040 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11041 gen_store_gpr(t1, rd+1);
11042 opn = "ldp";
11043 break;
11044 case SDP:
3c824109 11045 gen_load_gpr(t1, rd);
2910c6cb 11046 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11047 tcg_gen_movi_tl(t1, 8);
11048 gen_op_addr_add(ctx, t0, t0, t1);
11049 gen_load_gpr(t1, rd+1);
2910c6cb 11050 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11051 opn = "sdp";
11052 break;
11053#endif
6af0bf9c 11054 }
2abf314d 11055 (void)opn; /* avoid a compiler warning */
3c824109
NF
11056 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11057 tcg_temp_free(t0);
11058 tcg_temp_free(t1);
11059}
618b0fe9 11060
7db13fae 11061static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
3c824109
NF
11062 int *is_branch)
11063{
11064 int extension = (ctx->opcode >> 6) & 0x3f;
11065 int minor = (ctx->opcode >> 12) & 0xf;
11066 uint32_t mips32_op;
11067
11068 switch (extension) {
11069 case TEQ:
11070 mips32_op = OPC_TEQ;
11071 goto do_trap;
11072 case TGE:
11073 mips32_op = OPC_TGE;
11074 goto do_trap;
11075 case TGEU:
11076 mips32_op = OPC_TGEU;
11077 goto do_trap;
11078 case TLT:
11079 mips32_op = OPC_TLT;
11080 goto do_trap;
11081 case TLTU:
11082 mips32_op = OPC_TLTU;
11083 goto do_trap;
11084 case TNE:
11085 mips32_op = OPC_TNE;
11086 do_trap:
11087 gen_trap(ctx, mips32_op, rs, rt, -1);
11088 break;
11089#ifndef CONFIG_USER_ONLY
11090 case MFC0:
11091 case MFC0 + 32:
2e15497c 11092 check_cp0_enabled(ctx);
3c824109
NF
11093 if (rt == 0) {
11094 /* Treat as NOP. */
11095 break;
11096 }
d75c135e 11097 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11098 break;
11099 case MTC0:
11100 case MTC0 + 32:
2e15497c 11101 check_cp0_enabled(ctx);
3c824109
NF
11102 {
11103 TCGv t0 = tcg_temp_new();
618b0fe9 11104
3c824109 11105 gen_load_gpr(t0, rt);
d75c135e 11106 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11107 tcg_temp_free(t0);
11108 }
11109 break;
11110#endif
11111 case 0x2c:
11112 switch (minor) {
11113 case SEB:
11114 gen_bshfl(ctx, OPC_SEB, rs, rt);
11115 break;
11116 case SEH:
11117 gen_bshfl(ctx, OPC_SEH, rs, rt);
11118 break;
11119 case CLO:
11120 mips32_op = OPC_CLO;
11121 goto do_cl;
11122 case CLZ:
11123 mips32_op = OPC_CLZ;
11124 do_cl:
d75c135e 11125 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11126 gen_cl(ctx, mips32_op, rt, rs);
11127 break;
11128 case RDHWR:
d75c135e 11129 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11130 break;
11131 case WSBH:
11132 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11133 break;
11134 case MULT:
11135 mips32_op = OPC_MULT;
11136 goto do_muldiv;
11137 case MULTU:
11138 mips32_op = OPC_MULTU;
11139 goto do_muldiv;
11140 case DIV:
11141 mips32_op = OPC_DIV;
11142 goto do_muldiv;
11143 case DIVU:
11144 mips32_op = OPC_DIVU;
11145 goto do_muldiv;
11146 case MADD:
11147 mips32_op = OPC_MADD;
11148 goto do_muldiv;
11149 case MADDU:
11150 mips32_op = OPC_MADDU;
11151 goto do_muldiv;
11152 case MSUB:
11153 mips32_op = OPC_MSUB;
11154 goto do_muldiv;
11155 case MSUBU:
11156 mips32_op = OPC_MSUBU;
11157 do_muldiv:
d75c135e 11158 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11159 gen_muldiv(ctx, mips32_op, rs, rt);
11160 break;
11161 default:
11162 goto pool32axf_invalid;
11163 }
11164 break;
11165 case 0x34:
11166 switch (minor) {
11167 case MFC2:
11168 case MTC2:
11169 case MFHC2:
11170 case MTHC2:
11171 case CFC2:
11172 case CTC2:
11173 generate_exception_err(ctx, EXCP_CpU, 2);
11174 break;
11175 default:
11176 goto pool32axf_invalid;
11177 }
11178 break;
11179 case 0x3c:
11180 switch (minor) {
11181 case JALR:
11182 case JALR_HB:
11183 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11184 *is_branch = 1;
11185 break;
11186 case JALRS:
11187 case JALRS_HB:
11188 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11189 *is_branch = 1;
11190 break;
11191 default:
11192 goto pool32axf_invalid;
11193 }
11194 break;
11195 case 0x05:
11196 switch (minor) {
11197 case RDPGPR:
2e15497c 11198 check_cp0_enabled(ctx);
d75c135e 11199 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11200 gen_load_srsgpr(rt, rs);
11201 break;
11202 case WRPGPR:
2e15497c 11203 check_cp0_enabled(ctx);
d75c135e 11204 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11205 gen_store_srsgpr(rt, rs);
11206 break;
11207 default:
11208 goto pool32axf_invalid;
11209 }
11210 break;
11211#ifndef CONFIG_USER_ONLY
11212 case 0x0d:
11213 switch (minor) {
11214 case TLBP:
11215 mips32_op = OPC_TLBP;
11216 goto do_cp0;
11217 case TLBR:
11218 mips32_op = OPC_TLBR;
11219 goto do_cp0;
11220 case TLBWI:
11221 mips32_op = OPC_TLBWI;
11222 goto do_cp0;
11223 case TLBWR:
11224 mips32_op = OPC_TLBWR;
11225 goto do_cp0;
11226 case WAIT:
11227 mips32_op = OPC_WAIT;
11228 goto do_cp0;
11229 case DERET:
11230 mips32_op = OPC_DERET;
11231 goto do_cp0;
11232 case ERET:
11233 mips32_op = OPC_ERET;
11234 do_cp0:
11235 gen_cp0(env, ctx, mips32_op, rt, rs);
11236 break;
11237 default:
11238 goto pool32axf_invalid;
11239 }
11240 break;
11241 case 0x1d:
11242 switch (minor) {
11243 case DI:
2e15497c 11244 check_cp0_enabled(ctx);
3c824109
NF
11245 {
11246 TCGv t0 = tcg_temp_new();
11247
11248 save_cpu_state(ctx, 1);
895c2d04 11249 gen_helper_di(t0, cpu_env);
3c824109
NF
11250 gen_store_gpr(t0, rs);
11251 /* Stop translation as we may have switched the execution mode */
11252 ctx->bstate = BS_STOP;
11253 tcg_temp_free(t0);
11254 }
11255 break;
11256 case EI:
2e15497c 11257 check_cp0_enabled(ctx);
3c824109
NF
11258 {
11259 TCGv t0 = tcg_temp_new();
11260
11261 save_cpu_state(ctx, 1);
895c2d04 11262 gen_helper_ei(t0, cpu_env);
3c824109
NF
11263 gen_store_gpr(t0, rs);
11264 /* Stop translation as we may have switched the execution mode */
11265 ctx->bstate = BS_STOP;
11266 tcg_temp_free(t0);
11267 }
11268 break;
11269 default:
11270 goto pool32axf_invalid;
11271 }
11272 break;
11273#endif
11274 case 0x2d:
11275 switch (minor) {
11276 case SYNC:
11277 /* NOP */
11278 break;
11279 case SYSCALL:
11280 generate_exception(ctx, EXCP_SYSCALL);
11281 ctx->bstate = BS_STOP;
11282 break;
11283 case SDBBP:
d75c135e 11284 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11285 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11286 generate_exception(ctx, EXCP_DBp);
11287 } else {
11288 generate_exception(ctx, EXCP_DBp);
11289 }
11290 break;
11291 default:
11292 goto pool32axf_invalid;
11293 }
11294 break;
11295 case 0x35:
11296 switch (minor) {
11297 case MFHI32:
11298 gen_HILO(ctx, OPC_MFHI, rs);
11299 break;
11300 case MFLO32:
11301 gen_HILO(ctx, OPC_MFLO, rs);
11302 break;
11303 case MTHI32:
11304 gen_HILO(ctx, OPC_MTHI, rs);
11305 break;
11306 case MTLO32:
11307 gen_HILO(ctx, OPC_MTLO, rs);
11308 break;
11309 default:
11310 goto pool32axf_invalid;
11311 }
11312 break;
11313 default:
11314 pool32axf_invalid:
11315 MIPS_INVAL("pool32axf");
11316 generate_exception(ctx, EXCP_RI);
11317 break;
11318 }
11319}
11320
11321/* Values for microMIPS fmt field. Variable-width, depending on which
11322 formats the instruction supports. */
11323
11324enum {
11325 FMT_SD_S = 0,
11326 FMT_SD_D = 1,
11327
11328 FMT_SDPS_S = 0,
11329 FMT_SDPS_D = 1,
11330 FMT_SDPS_PS = 2,
11331
11332 FMT_SWL_S = 0,
11333 FMT_SWL_W = 1,
11334 FMT_SWL_L = 2,
11335
11336 FMT_DWL_D = 0,
11337 FMT_DWL_W = 1,
11338 FMT_DWL_L = 2
11339};
11340
d75c135e 11341static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11342{
11343 int extension = (ctx->opcode >> 6) & 0x3ff;
11344 uint32_t mips32_op;
11345
11346#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11347#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11348#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11349
11350 switch (extension) {
11351 case FLOAT_1BIT_FMT(CFC1, 0):
11352 mips32_op = OPC_CFC1;
11353 goto do_cp1;
11354 case FLOAT_1BIT_FMT(CTC1, 0):
11355 mips32_op = OPC_CTC1;
11356 goto do_cp1;
11357 case FLOAT_1BIT_FMT(MFC1, 0):
11358 mips32_op = OPC_MFC1;
11359 goto do_cp1;
11360 case FLOAT_1BIT_FMT(MTC1, 0):
11361 mips32_op = OPC_MTC1;
11362 goto do_cp1;
11363 case FLOAT_1BIT_FMT(MFHC1, 0):
11364 mips32_op = OPC_MFHC1;
11365 goto do_cp1;
11366 case FLOAT_1BIT_FMT(MTHC1, 0):
11367 mips32_op = OPC_MTHC1;
11368 do_cp1:
11369 gen_cp1(ctx, mips32_op, rt, rs);
11370 break;
11371
11372 /* Reciprocal square root */
11373 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11374 mips32_op = OPC_RSQRT_S;
11375 goto do_unaryfp;
11376 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11377 mips32_op = OPC_RSQRT_D;
11378 goto do_unaryfp;
11379
11380 /* Square root */
11381 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11382 mips32_op = OPC_SQRT_S;
11383 goto do_unaryfp;
11384 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11385 mips32_op = OPC_SQRT_D;
11386 goto do_unaryfp;
11387
11388 /* Reciprocal */
11389 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11390 mips32_op = OPC_RECIP_S;
11391 goto do_unaryfp;
11392 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11393 mips32_op = OPC_RECIP_D;
11394 goto do_unaryfp;
11395
11396 /* Floor */
11397 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11398 mips32_op = OPC_FLOOR_L_S;
11399 goto do_unaryfp;
11400 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11401 mips32_op = OPC_FLOOR_L_D;
11402 goto do_unaryfp;
11403 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11404 mips32_op = OPC_FLOOR_W_S;
11405 goto do_unaryfp;
11406 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11407 mips32_op = OPC_FLOOR_W_D;
11408 goto do_unaryfp;
11409
11410 /* Ceiling */
11411 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11412 mips32_op = OPC_CEIL_L_S;
11413 goto do_unaryfp;
11414 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11415 mips32_op = OPC_CEIL_L_D;
11416 goto do_unaryfp;
11417 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11418 mips32_op = OPC_CEIL_W_S;
11419 goto do_unaryfp;
11420 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11421 mips32_op = OPC_CEIL_W_D;
11422 goto do_unaryfp;
11423
11424 /* Truncation */
11425 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11426 mips32_op = OPC_TRUNC_L_S;
11427 goto do_unaryfp;
11428 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11429 mips32_op = OPC_TRUNC_L_D;
11430 goto do_unaryfp;
11431 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11432 mips32_op = OPC_TRUNC_W_S;
11433 goto do_unaryfp;
11434 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11435 mips32_op = OPC_TRUNC_W_D;
11436 goto do_unaryfp;
11437
11438 /* Round */
11439 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11440 mips32_op = OPC_ROUND_L_S;
11441 goto do_unaryfp;
11442 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11443 mips32_op = OPC_ROUND_L_D;
11444 goto do_unaryfp;
11445 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11446 mips32_op = OPC_ROUND_W_S;
11447 goto do_unaryfp;
11448 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11449 mips32_op = OPC_ROUND_W_D;
11450 goto do_unaryfp;
11451
11452 /* Integer to floating-point conversion */
11453 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11454 mips32_op = OPC_CVT_L_S;
11455 goto do_unaryfp;
11456 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11457 mips32_op = OPC_CVT_L_D;
11458 goto do_unaryfp;
11459 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11460 mips32_op = OPC_CVT_W_S;
11461 goto do_unaryfp;
11462 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11463 mips32_op = OPC_CVT_W_D;
11464 goto do_unaryfp;
11465
11466 /* Paired-foo conversions */
11467 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11468 mips32_op = OPC_CVT_S_PL;
11469 goto do_unaryfp;
11470 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11471 mips32_op = OPC_CVT_S_PU;
11472 goto do_unaryfp;
11473 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11474 mips32_op = OPC_CVT_PW_PS;
11475 goto do_unaryfp;
11476 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11477 mips32_op = OPC_CVT_PS_PW;
11478 goto do_unaryfp;
11479
11480 /* Floating-point moves */
11481 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11482 mips32_op = OPC_MOV_S;
11483 goto do_unaryfp;
11484 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11485 mips32_op = OPC_MOV_D;
11486 goto do_unaryfp;
11487 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11488 mips32_op = OPC_MOV_PS;
11489 goto do_unaryfp;
11490
11491 /* Absolute value */
11492 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11493 mips32_op = OPC_ABS_S;
11494 goto do_unaryfp;
11495 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11496 mips32_op = OPC_ABS_D;
11497 goto do_unaryfp;
11498 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11499 mips32_op = OPC_ABS_PS;
11500 goto do_unaryfp;
11501
11502 /* Negation */
11503 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11504 mips32_op = OPC_NEG_S;
11505 goto do_unaryfp;
11506 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11507 mips32_op = OPC_NEG_D;
11508 goto do_unaryfp;
11509 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11510 mips32_op = OPC_NEG_PS;
11511 goto do_unaryfp;
11512
11513 /* Reciprocal square root step */
11514 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11515 mips32_op = OPC_RSQRT1_S;
11516 goto do_unaryfp;
11517 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11518 mips32_op = OPC_RSQRT1_D;
11519 goto do_unaryfp;
11520 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11521 mips32_op = OPC_RSQRT1_PS;
11522 goto do_unaryfp;
11523
11524 /* Reciprocal step */
11525 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11526 mips32_op = OPC_RECIP1_S;
11527 goto do_unaryfp;
11528 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11529 mips32_op = OPC_RECIP1_S;
11530 goto do_unaryfp;
11531 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11532 mips32_op = OPC_RECIP1_PS;
11533 goto do_unaryfp;
11534
11535 /* Conversions from double */
11536 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11537 mips32_op = OPC_CVT_D_S;
11538 goto do_unaryfp;
11539 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11540 mips32_op = OPC_CVT_D_W;
11541 goto do_unaryfp;
11542 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11543 mips32_op = OPC_CVT_D_L;
11544 goto do_unaryfp;
11545
11546 /* Conversions from single */
11547 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11548 mips32_op = OPC_CVT_S_D;
11549 goto do_unaryfp;
11550 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11551 mips32_op = OPC_CVT_S_W;
11552 goto do_unaryfp;
11553 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11554 mips32_op = OPC_CVT_S_L;
11555 do_unaryfp:
11556 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11557 break;
11558
11559 /* Conditional moves on floating-point codes */
11560 case COND_FLOAT_MOV(MOVT, 0):
11561 case COND_FLOAT_MOV(MOVT, 1):
11562 case COND_FLOAT_MOV(MOVT, 2):
11563 case COND_FLOAT_MOV(MOVT, 3):
11564 case COND_FLOAT_MOV(MOVT, 4):
11565 case COND_FLOAT_MOV(MOVT, 5):
11566 case COND_FLOAT_MOV(MOVT, 6):
11567 case COND_FLOAT_MOV(MOVT, 7):
11568 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11569 break;
11570 case COND_FLOAT_MOV(MOVF, 0):
11571 case COND_FLOAT_MOV(MOVF, 1):
11572 case COND_FLOAT_MOV(MOVF, 2):
11573 case COND_FLOAT_MOV(MOVF, 3):
11574 case COND_FLOAT_MOV(MOVF, 4):
11575 case COND_FLOAT_MOV(MOVF, 5):
11576 case COND_FLOAT_MOV(MOVF, 6):
11577 case COND_FLOAT_MOV(MOVF, 7):
11578 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11579 break;
11580 default:
11581 MIPS_INVAL("pool32fxf");
11582 generate_exception(ctx, EXCP_RI);
11583 break;
11584 }
11585}
11586
7db13fae 11587static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
3c824109
NF
11588 uint16_t insn_hw1, int *is_branch)
11589{
11590 int32_t offset;
11591 uint16_t insn;
11592 int rt, rs, rd, rr;
11593 int16_t imm;
11594 uint32_t op, minor, mips32_op;
11595 uint32_t cond, fmt, cc;
11596
895c2d04 11597 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11598 ctx->opcode = (ctx->opcode << 16) | insn;
11599
11600 rt = (ctx->opcode >> 21) & 0x1f;
11601 rs = (ctx->opcode >> 16) & 0x1f;
11602 rd = (ctx->opcode >> 11) & 0x1f;
11603 rr = (ctx->opcode >> 6) & 0x1f;
11604 imm = (int16_t) ctx->opcode;
11605
11606 op = (ctx->opcode >> 26) & 0x3f;
11607 switch (op) {
11608 case POOL32A:
11609 minor = ctx->opcode & 0x3f;
11610 switch (minor) {
11611 case 0x00:
11612 minor = (ctx->opcode >> 6) & 0xf;
11613 switch (minor) {
11614 case SLL32:
11615 mips32_op = OPC_SLL;
11616 goto do_shifti;
11617 case SRA:
11618 mips32_op = OPC_SRA;
11619 goto do_shifti;
11620 case SRL32:
11621 mips32_op = OPC_SRL;
11622 goto do_shifti;
11623 case ROTR:
11624 mips32_op = OPC_ROTR;
11625 do_shifti:
d75c135e 11626 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
11627 break;
11628 default:
11629 goto pool32a_invalid;
11630 }
11631 break;
11632 case 0x10:
11633 minor = (ctx->opcode >> 6) & 0xf;
11634 switch (minor) {
11635 /* Arithmetic */
11636 case ADD:
11637 mips32_op = OPC_ADD;
11638 goto do_arith;
11639 case ADDU32:
11640 mips32_op = OPC_ADDU;
11641 goto do_arith;
11642 case SUB:
11643 mips32_op = OPC_SUB;
11644 goto do_arith;
11645 case SUBU32:
11646 mips32_op = OPC_SUBU;
11647 goto do_arith;
11648 case MUL:
11649 mips32_op = OPC_MUL;
11650 do_arith:
d75c135e 11651 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11652 break;
11653 /* Shifts */
11654 case SLLV:
11655 mips32_op = OPC_SLLV;
11656 goto do_shift;
11657 case SRLV:
11658 mips32_op = OPC_SRLV;
11659 goto do_shift;
11660 case SRAV:
11661 mips32_op = OPC_SRAV;
11662 goto do_shift;
11663 case ROTRV:
11664 mips32_op = OPC_ROTRV;
11665 do_shift:
d75c135e 11666 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11667 break;
11668 /* Logical operations */
11669 case AND:
11670 mips32_op = OPC_AND;
11671 goto do_logic;
11672 case OR32:
11673 mips32_op = OPC_OR;
11674 goto do_logic;
11675 case NOR:
11676 mips32_op = OPC_NOR;
11677 goto do_logic;
11678 case XOR32:
11679 mips32_op = OPC_XOR;
11680 do_logic:
d75c135e 11681 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11682 break;
11683 /* Set less than */
11684 case SLT:
11685 mips32_op = OPC_SLT;
11686 goto do_slt;
11687 case SLTU:
11688 mips32_op = OPC_SLTU;
11689 do_slt:
d75c135e 11690 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11691 break;
11692 default:
11693 goto pool32a_invalid;
11694 }
11695 break;
11696 case 0x18:
11697 minor = (ctx->opcode >> 6) & 0xf;
11698 switch (minor) {
11699 /* Conditional moves */
11700 case MOVN:
11701 mips32_op = OPC_MOVN;
11702 goto do_cmov;
11703 case MOVZ:
11704 mips32_op = OPC_MOVZ;
11705 do_cmov:
d75c135e 11706 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
11707 break;
11708 case LWXS:
11709 gen_ldxs(ctx, rs, rt, rd);
11710 break;
11711 default:
11712 goto pool32a_invalid;
11713 }
11714 break;
11715 case INS:
11716 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11717 return;
11718 case EXT:
11719 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11720 return;
11721 case POOL32AXF:
11722 gen_pool32axf(env, ctx, rt, rs, is_branch);
11723 break;
11724 case 0x07:
11725 generate_exception(ctx, EXCP_BREAK);
11726 break;
11727 default:
11728 pool32a_invalid:
11729 MIPS_INVAL("pool32a");
11730 generate_exception(ctx, EXCP_RI);
11731 break;
11732 }
11733 break;
11734 case POOL32B:
11735 minor = (ctx->opcode >> 12) & 0xf;
11736 switch (minor) {
11737 case CACHE:
2e15497c 11738 check_cp0_enabled(ctx);
3c824109
NF
11739 /* Treat as no-op. */
11740 break;
11741 case LWC2:
11742 case SWC2:
11743 /* COP2: Not implemented. */
11744 generate_exception_err(ctx, EXCP_CpU, 2);
11745 break;
11746 case LWP:
11747 case SWP:
11748#ifdef TARGET_MIPS64
11749 case LDP:
11750 case SDP:
11751#endif
11752 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11753 break;
11754 case LWM32:
11755 case SWM32:
11756#ifdef TARGET_MIPS64
11757 case LDM:
11758 case SDM:
11759#endif
11760 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11761 break;
11762 default:
11763 MIPS_INVAL("pool32b");
11764 generate_exception(ctx, EXCP_RI);
11765 break;
11766 }
11767 break;
11768 case POOL32F:
11769 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11770 minor = ctx->opcode & 0x3f;
11771 check_cp1_enabled(ctx);
11772 switch (minor) {
11773 case ALNV_PS:
11774 mips32_op = OPC_ALNV_PS;
11775 goto do_madd;
11776 case MADD_S:
11777 mips32_op = OPC_MADD_S;
11778 goto do_madd;
11779 case MADD_D:
11780 mips32_op = OPC_MADD_D;
11781 goto do_madd;
11782 case MADD_PS:
11783 mips32_op = OPC_MADD_PS;
11784 goto do_madd;
11785 case MSUB_S:
11786 mips32_op = OPC_MSUB_S;
11787 goto do_madd;
11788 case MSUB_D:
11789 mips32_op = OPC_MSUB_D;
11790 goto do_madd;
11791 case MSUB_PS:
11792 mips32_op = OPC_MSUB_PS;
11793 goto do_madd;
11794 case NMADD_S:
11795 mips32_op = OPC_NMADD_S;
11796 goto do_madd;
11797 case NMADD_D:
11798 mips32_op = OPC_NMADD_D;
11799 goto do_madd;
11800 case NMADD_PS:
11801 mips32_op = OPC_NMADD_PS;
11802 goto do_madd;
11803 case NMSUB_S:
11804 mips32_op = OPC_NMSUB_S;
11805 goto do_madd;
11806 case NMSUB_D:
11807 mips32_op = OPC_NMSUB_D;
11808 goto do_madd;
11809 case NMSUB_PS:
11810 mips32_op = OPC_NMSUB_PS;
11811 do_madd:
11812 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11813 break;
11814 case CABS_COND_FMT:
11815 cond = (ctx->opcode >> 6) & 0xf;
11816 cc = (ctx->opcode >> 13) & 0x7;
11817 fmt = (ctx->opcode >> 10) & 0x3;
11818 switch (fmt) {
11819 case 0x0:
11820 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11821 break;
11822 case 0x1:
11823 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11824 break;
11825 case 0x2:
11826 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11827 break;
11828 default:
11829 goto pool32f_invalid;
11830 }
11831 break;
11832 case C_COND_FMT:
11833 cond = (ctx->opcode >> 6) & 0xf;
11834 cc = (ctx->opcode >> 13) & 0x7;
11835 fmt = (ctx->opcode >> 10) & 0x3;
11836 switch (fmt) {
11837 case 0x0:
11838 gen_cmp_s(ctx, cond, rt, rs, cc);
11839 break;
11840 case 0x1:
11841 gen_cmp_d(ctx, cond, rt, rs, cc);
11842 break;
11843 case 0x2:
11844 gen_cmp_ps(ctx, cond, rt, rs, cc);
11845 break;
11846 default:
11847 goto pool32f_invalid;
11848 }
11849 break;
11850 case POOL32FXF:
d75c135e 11851 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
11852 break;
11853 case 0x00:
11854 /* PLL foo */
11855 switch ((ctx->opcode >> 6) & 0x7) {
11856 case PLL_PS:
11857 mips32_op = OPC_PLL_PS;
11858 goto do_ps;
11859 case PLU_PS:
11860 mips32_op = OPC_PLU_PS;
11861 goto do_ps;
11862 case PUL_PS:
11863 mips32_op = OPC_PUL_PS;
11864 goto do_ps;
11865 case PUU_PS:
11866 mips32_op = OPC_PUU_PS;
11867 goto do_ps;
11868 case CVT_PS_S:
11869 mips32_op = OPC_CVT_PS_S;
11870 do_ps:
11871 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11872 break;
11873 default:
11874 goto pool32f_invalid;
11875 }
11876 break;
11877 case 0x08:
11878 /* [LS][WDU]XC1 */
11879 switch ((ctx->opcode >> 6) & 0x7) {
11880 case LWXC1:
11881 mips32_op = OPC_LWXC1;
11882 goto do_ldst_cp1;
11883 case SWXC1:
11884 mips32_op = OPC_SWXC1;
11885 goto do_ldst_cp1;
11886 case LDXC1:
11887 mips32_op = OPC_LDXC1;
11888 goto do_ldst_cp1;
11889 case SDXC1:
11890 mips32_op = OPC_SDXC1;
11891 goto do_ldst_cp1;
11892 case LUXC1:
11893 mips32_op = OPC_LUXC1;
11894 goto do_ldst_cp1;
11895 case SUXC1:
11896 mips32_op = OPC_SUXC1;
11897 do_ldst_cp1:
11898 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11899 break;
11900 default:
11901 goto pool32f_invalid;
11902 }
11903 break;
11904 case 0x18:
11905 /* 3D insns */
11906 fmt = (ctx->opcode >> 9) & 0x3;
11907 switch ((ctx->opcode >> 6) & 0x7) {
11908 case RSQRT2_FMT:
11909 switch (fmt) {
11910 case FMT_SDPS_S:
11911 mips32_op = OPC_RSQRT2_S;
11912 goto do_3d;
11913 case FMT_SDPS_D:
11914 mips32_op = OPC_RSQRT2_D;
11915 goto do_3d;
11916 case FMT_SDPS_PS:
11917 mips32_op = OPC_RSQRT2_PS;
11918 goto do_3d;
11919 default:
11920 goto pool32f_invalid;
11921 }
11922 break;
11923 case RECIP2_FMT:
11924 switch (fmt) {
11925 case FMT_SDPS_S:
11926 mips32_op = OPC_RECIP2_S;
11927 goto do_3d;
11928 case FMT_SDPS_D:
11929 mips32_op = OPC_RECIP2_D;
11930 goto do_3d;
11931 case FMT_SDPS_PS:
11932 mips32_op = OPC_RECIP2_PS;
11933 goto do_3d;
11934 default:
11935 goto pool32f_invalid;
11936 }
11937 break;
11938 case ADDR_PS:
11939 mips32_op = OPC_ADDR_PS;
11940 goto do_3d;
11941 case MULR_PS:
11942 mips32_op = OPC_MULR_PS;
11943 do_3d:
11944 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11945 break;
11946 default:
11947 goto pool32f_invalid;
11948 }
11949 break;
11950 case 0x20:
11951 /* MOV[FT].fmt and PREFX */
11952 cc = (ctx->opcode >> 13) & 0x7;
11953 fmt = (ctx->opcode >> 9) & 0x3;
11954 switch ((ctx->opcode >> 6) & 0x7) {
11955 case MOVF_FMT:
11956 switch (fmt) {
11957 case FMT_SDPS_S:
11958 gen_movcf_s(rs, rt, cc, 0);
11959 break;
11960 case FMT_SDPS_D:
11961 gen_movcf_d(ctx, rs, rt, cc, 0);
11962 break;
11963 case FMT_SDPS_PS:
11964 gen_movcf_ps(rs, rt, cc, 0);
11965 break;
11966 default:
11967 goto pool32f_invalid;
11968 }
11969 break;
11970 case MOVT_FMT:
11971 switch (fmt) {
11972 case FMT_SDPS_S:
11973 gen_movcf_s(rs, rt, cc, 1);
11974 break;
11975 case FMT_SDPS_D:
11976 gen_movcf_d(ctx, rs, rt, cc, 1);
11977 break;
11978 case FMT_SDPS_PS:
11979 gen_movcf_ps(rs, rt, cc, 1);
11980 break;
11981 default:
11982 goto pool32f_invalid;
11983 }
11984 break;
11985 case PREFX:
11986 break;
11987 default:
11988 goto pool32f_invalid;
11989 }
11990 break;
11991#define FINSN_3ARG_SDPS(prfx) \
11992 switch ((ctx->opcode >> 8) & 0x3) { \
11993 case FMT_SDPS_S: \
11994 mips32_op = OPC_##prfx##_S; \
11995 goto do_fpop; \
11996 case FMT_SDPS_D: \
11997 mips32_op = OPC_##prfx##_D; \
11998 goto do_fpop; \
11999 case FMT_SDPS_PS: \
12000 mips32_op = OPC_##prfx##_PS; \
12001 goto do_fpop; \
12002 default: \
12003 goto pool32f_invalid; \
12004 }
12005 case 0x30:
12006 /* regular FP ops */
12007 switch ((ctx->opcode >> 6) & 0x3) {
12008 case ADD_FMT:
12009 FINSN_3ARG_SDPS(ADD);
12010 break;
12011 case SUB_FMT:
12012 FINSN_3ARG_SDPS(SUB);
12013 break;
12014 case MUL_FMT:
12015 FINSN_3ARG_SDPS(MUL);
12016 break;
12017 case DIV_FMT:
12018 fmt = (ctx->opcode >> 8) & 0x3;
12019 if (fmt == 1) {
12020 mips32_op = OPC_DIV_D;
12021 } else if (fmt == 0) {
12022 mips32_op = OPC_DIV_S;
12023 } else {
12024 goto pool32f_invalid;
12025 }
12026 goto do_fpop;
12027 default:
12028 goto pool32f_invalid;
12029 }
12030 break;
12031 case 0x38:
12032 /* cmovs */
12033 switch ((ctx->opcode >> 6) & 0x3) {
12034 case MOVN_FMT:
12035 FINSN_3ARG_SDPS(MOVN);
12036 break;
12037 case MOVZ_FMT:
12038 FINSN_3ARG_SDPS(MOVZ);
12039 break;
12040 default:
12041 goto pool32f_invalid;
12042 }
12043 break;
12044 do_fpop:
12045 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12046 break;
12047 default:
12048 pool32f_invalid:
12049 MIPS_INVAL("pool32f");
12050 generate_exception(ctx, EXCP_RI);
12051 break;
12052 }
12053 } else {
12054 generate_exception_err(ctx, EXCP_CpU, 1);
12055 }
12056 break;
12057 case POOL32I:
12058 minor = (ctx->opcode >> 21) & 0x1f;
12059 switch (minor) {
12060 case BLTZ:
12061 mips32_op = OPC_BLTZ;
12062 goto do_branch;
12063 case BLTZAL:
12064 mips32_op = OPC_BLTZAL;
12065 goto do_branch;
12066 case BLTZALS:
12067 mips32_op = OPC_BLTZALS;
12068 goto do_branch;
12069 case BGEZ:
12070 mips32_op = OPC_BGEZ;
12071 goto do_branch;
12072 case BGEZAL:
12073 mips32_op = OPC_BGEZAL;
12074 goto do_branch;
12075 case BGEZALS:
12076 mips32_op = OPC_BGEZALS;
12077 goto do_branch;
12078 case BLEZ:
12079 mips32_op = OPC_BLEZ;
12080 goto do_branch;
12081 case BGTZ:
12082 mips32_op = OPC_BGTZ;
12083 do_branch:
12084 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12085 *is_branch = 1;
12086 break;
12087
12088 /* Traps */
12089 case TLTI:
12090 mips32_op = OPC_TLTI;
12091 goto do_trapi;
12092 case TGEI:
12093 mips32_op = OPC_TGEI;
12094 goto do_trapi;
12095 case TLTIU:
12096 mips32_op = OPC_TLTIU;
12097 goto do_trapi;
12098 case TGEIU:
12099 mips32_op = OPC_TGEIU;
12100 goto do_trapi;
12101 case TNEI:
12102 mips32_op = OPC_TNEI;
12103 goto do_trapi;
12104 case TEQI:
12105 mips32_op = OPC_TEQI;
12106 do_trapi:
12107 gen_trap(ctx, mips32_op, rs, -1, imm);
12108 break;
12109
12110 case BNEZC:
12111 case BEQZC:
12112 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12113 4, rs, 0, imm << 1);
12114 /* Compact branches don't have a delay slot, so just let
12115 the normal delay slot handling take us to the branch
12116 target. */
12117 break;
12118 case LUI:
d75c135e 12119 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12120 break;
12121 case SYNCI:
12122 break;
12123 case BC2F:
12124 case BC2T:
12125 /* COP2: Not implemented. */
12126 generate_exception_err(ctx, EXCP_CpU, 2);
12127 break;
12128 case BC1F:
12129 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12130 goto do_cp1branch;
12131 case BC1T:
12132 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12133 goto do_cp1branch;
12134 case BC1ANY4F:
12135 mips32_op = OPC_BC1FANY4;
12136 goto do_cp1mips3d;
12137 case BC1ANY4T:
12138 mips32_op = OPC_BC1TANY4;
12139 do_cp1mips3d:
12140 check_cop1x(ctx);
d75c135e 12141 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12142 /* Fall through */
12143 do_cp1branch:
d75c135e 12144 gen_compute_branch1(ctx, mips32_op,
3c824109
NF
12145 (ctx->opcode >> 18) & 0x7, imm << 1);
12146 *is_branch = 1;
12147 break;
12148 case BPOSGE64:
12149 case BPOSGE32:
12150 /* MIPS DSP: not implemented */
12151 /* Fall through */
12152 default:
12153 MIPS_INVAL("pool32i");
12154 generate_exception(ctx, EXCP_RI);
12155 break;
12156 }
12157 break;
12158 case POOL32C:
12159 minor = (ctx->opcode >> 12) & 0xf;
12160 switch (minor) {
12161 case LWL:
12162 mips32_op = OPC_LWL;
5c13fdfd 12163 goto do_ld_lr;
3c824109
NF
12164 case SWL:
12165 mips32_op = OPC_SWL;
5c13fdfd 12166 goto do_st_lr;
3c824109
NF
12167 case LWR:
12168 mips32_op = OPC_LWR;
5c13fdfd 12169 goto do_ld_lr;
3c824109
NF
12170 case SWR:
12171 mips32_op = OPC_SWR;
5c13fdfd 12172 goto do_st_lr;
3c824109
NF
12173#if defined(TARGET_MIPS64)
12174 case LDL:
12175 mips32_op = OPC_LDL;
5c13fdfd 12176 goto do_ld_lr;
3c824109
NF
12177 case SDL:
12178 mips32_op = OPC_SDL;
5c13fdfd 12179 goto do_st_lr;
3c824109
NF
12180 case LDR:
12181 mips32_op = OPC_LDR;
5c13fdfd 12182 goto do_ld_lr;
3c824109
NF
12183 case SDR:
12184 mips32_op = OPC_SDR;
5c13fdfd 12185 goto do_st_lr;
3c824109
NF
12186 case LWU:
12187 mips32_op = OPC_LWU;
5c13fdfd 12188 goto do_ld_lr;
3c824109
NF
12189 case LLD:
12190 mips32_op = OPC_LLD;
5c13fdfd 12191 goto do_ld_lr;
3c824109
NF
12192#endif
12193 case LL:
12194 mips32_op = OPC_LL;
5c13fdfd
AJ
12195 goto do_ld_lr;
12196 do_ld_lr:
d75c135e 12197 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12198 break;
12199 do_st_lr:
12200 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12201 break;
12202 case SC:
12203 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12204 break;
12205#if defined(TARGET_MIPS64)
12206 case SCD:
12207 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12208 break;
12209#endif
12210 case PREF:
12211 /* Treat as no-op */
12212 break;
12213 default:
12214 MIPS_INVAL("pool32c");
12215 generate_exception(ctx, EXCP_RI);
12216 break;
12217 }
12218 break;
12219 case ADDI32:
12220 mips32_op = OPC_ADDI;
12221 goto do_addi;
12222 case ADDIU32:
12223 mips32_op = OPC_ADDIU;
12224 do_addi:
d75c135e 12225 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12226 break;
12227
12228 /* Logical operations */
12229 case ORI32:
12230 mips32_op = OPC_ORI;
12231 goto do_logici;
12232 case XORI32:
12233 mips32_op = OPC_XORI;
12234 goto do_logici;
12235 case ANDI32:
12236 mips32_op = OPC_ANDI;
12237 do_logici:
d75c135e 12238 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12239 break;
12240
12241 /* Set less than immediate */
12242 case SLTI32:
12243 mips32_op = OPC_SLTI;
12244 goto do_slti;
12245 case SLTIU32:
12246 mips32_op = OPC_SLTIU;
12247 do_slti:
d75c135e 12248 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12249 break;
12250 case JALX32:
12251 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12252 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12253 *is_branch = 1;
12254 break;
12255 case JALS32:
12256 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12257 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12258 *is_branch = 1;
12259 break;
12260 case BEQ32:
12261 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12262 *is_branch = 1;
12263 break;
12264 case BNE32:
12265 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12266 *is_branch = 1;
12267 break;
12268 case J32:
12269 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12270 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12271 *is_branch = 1;
12272 break;
12273 case JAL32:
12274 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12275 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12276 *is_branch = 1;
12277 break;
12278 /* Floating point (COP1) */
12279 case LWC132:
12280 mips32_op = OPC_LWC1;
12281 goto do_cop1;
12282 case LDC132:
12283 mips32_op = OPC_LDC1;
12284 goto do_cop1;
12285 case SWC132:
12286 mips32_op = OPC_SWC1;
12287 goto do_cop1;
12288 case SDC132:
12289 mips32_op = OPC_SDC1;
12290 do_cop1:
12291 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12292 break;
12293 case ADDIUPC:
12294 {
12295 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12296 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12297
12298 gen_addiupc(ctx, reg, offset, 0, 0);
12299 }
12300 break;
12301 /* Loads and stores */
12302 case LB32:
12303 mips32_op = OPC_LB;
5c13fdfd 12304 goto do_ld;
3c824109
NF
12305 case LBU32:
12306 mips32_op = OPC_LBU;
5c13fdfd 12307 goto do_ld;
3c824109
NF
12308 case LH32:
12309 mips32_op = OPC_LH;
5c13fdfd 12310 goto do_ld;
3c824109
NF
12311 case LHU32:
12312 mips32_op = OPC_LHU;
5c13fdfd 12313 goto do_ld;
3c824109
NF
12314 case LW32:
12315 mips32_op = OPC_LW;
5c13fdfd 12316 goto do_ld;
3c824109
NF
12317#ifdef TARGET_MIPS64
12318 case LD32:
12319 mips32_op = OPC_LD;
5c13fdfd 12320 goto do_ld;
3c824109
NF
12321 case SD32:
12322 mips32_op = OPC_SD;
5c13fdfd 12323 goto do_st;
3c824109
NF
12324#endif
12325 case SB32:
12326 mips32_op = OPC_SB;
5c13fdfd 12327 goto do_st;
3c824109
NF
12328 case SH32:
12329 mips32_op = OPC_SH;
5c13fdfd 12330 goto do_st;
3c824109
NF
12331 case SW32:
12332 mips32_op = OPC_SW;
5c13fdfd
AJ
12333 goto do_st;
12334 do_ld:
d75c135e 12335 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12336 break;
12337 do_st:
12338 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12339 break;
12340 default:
12341 generate_exception(ctx, EXCP_RI);
12342 break;
12343 }
12344}
12345
7db13fae 12346static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
12347{
12348 uint32_t op;
12349
12350 /* make sure instructions are on a halfword boundary */
12351 if (ctx->pc & 0x1) {
12352 env->CP0_BadVAddr = ctx->pc;
12353 generate_exception(ctx, EXCP_AdEL);
12354 ctx->bstate = BS_STOP;
12355 return 2;
12356 }
12357
12358 op = (ctx->opcode >> 10) & 0x3f;
12359 /* Enforce properly-sized instructions in a delay slot */
12360 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12361 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12362
12363 switch (op) {
12364 case POOL32A:
12365 case POOL32B:
12366 case POOL32I:
12367 case POOL32C:
12368 case ADDI32:
12369 case ADDIU32:
12370 case ORI32:
12371 case XORI32:
12372 case SLTI32:
12373 case SLTIU32:
12374 case ANDI32:
12375 case JALX32:
12376 case LBU32:
12377 case LHU32:
12378 case POOL32F:
12379 case JALS32:
12380 case BEQ32:
12381 case BNE32:
12382 case J32:
12383 case JAL32:
12384 case SB32:
12385 case SH32:
12386 case POOL32S:
12387 case ADDIUPC:
12388 case SWC132:
12389 case SDC132:
12390 case SD32:
12391 case SW32:
12392 case LB32:
12393 case LH32:
12394 case DADDIU32:
3c824109
NF
12395 case LWC132:
12396 case LDC132:
12397 case LD32:
12398 case LW32:
12399 if (bits & MIPS_HFLAG_BDS16) {
12400 generate_exception(ctx, EXCP_RI);
12401 /* Just stop translation; the user is confused. */
12402 ctx->bstate = BS_STOP;
12403 return 2;
12404 }
12405 break;
12406 case POOL16A:
12407 case POOL16B:
12408 case POOL16C:
12409 case LWGP16:
12410 case POOL16F:
12411 case LBU16:
12412 case LHU16:
12413 case LWSP16:
12414 case LW16:
12415 case SB16:
12416 case SH16:
12417 case SWSP16:
12418 case SW16:
12419 case MOVE16:
12420 case ANDI16:
12421 case POOL16D:
12422 case POOL16E:
12423 case BEQZ16:
12424 case BNEZ16:
12425 case B16:
12426 case LI16:
12427 if (bits & MIPS_HFLAG_BDS32) {
12428 generate_exception(ctx, EXCP_RI);
12429 /* Just stop translation; the user is confused. */
12430 ctx->bstate = BS_STOP;
12431 return 2;
12432 }
12433 break;
12434 default:
12435 break;
12436 }
12437 }
12438 switch (op) {
12439 case POOL16A:
12440 {
12441 int rd = mmreg(uMIPS_RD(ctx->opcode));
12442 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12443 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12444 uint32_t opc = 0;
12445
12446 switch (ctx->opcode & 0x1) {
12447 case ADDU16:
12448 opc = OPC_ADDU;
12449 break;
12450 case SUBU16:
12451 opc = OPC_SUBU;
12452 break;
12453 }
12454
d75c135e 12455 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12456 }
12457 break;
12458 case POOL16B:
12459 {
12460 int rd = mmreg(uMIPS_RD(ctx->opcode));
12461 int rs = mmreg(uMIPS_RS(ctx->opcode));
12462 int amount = (ctx->opcode >> 1) & 0x7;
12463 uint32_t opc = 0;
12464 amount = amount == 0 ? 8 : amount;
12465
12466 switch (ctx->opcode & 0x1) {
12467 case SLL16:
12468 opc = OPC_SLL;
12469 break;
12470 case SRL16:
12471 opc = OPC_SRL;
12472 break;
12473 }
12474
d75c135e 12475 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12476 }
12477 break;
12478 case POOL16C:
d75c135e 12479 gen_pool16c_insn(ctx, is_branch);
3c824109
NF
12480 break;
12481 case LWGP16:
12482 {
12483 int rd = mmreg(uMIPS_RD(ctx->opcode));
12484 int rb = 28; /* GP */
12485 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12486
d75c135e 12487 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12488 }
12489 break;
12490 case POOL16F:
12491 if (ctx->opcode & 1) {
12492 generate_exception(ctx, EXCP_RI);
12493 } else {
12494 /* MOVEP */
12495 int enc_dest = uMIPS_RD(ctx->opcode);
12496 int enc_rt = uMIPS_RS2(ctx->opcode);
12497 int enc_rs = uMIPS_RS1(ctx->opcode);
12498 int rd, rs, re, rt;
12499 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12500 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12501 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12502
12503 rd = rd_enc[enc_dest];
12504 re = re_enc[enc_dest];
12505 rs = rs_rt_enc[enc_rs];
12506 rt = rs_rt_enc[enc_rt];
12507
d75c135e
AJ
12508 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12509 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12510 }
12511 break;
12512 case LBU16:
12513 {
12514 int rd = mmreg(uMIPS_RD(ctx->opcode));
12515 int rb = mmreg(uMIPS_RS(ctx->opcode));
12516 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12517 offset = (offset == 0xf ? -1 : offset);
12518
d75c135e 12519 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12520 }
12521 break;
12522 case LHU16:
12523 {
12524 int rd = mmreg(uMIPS_RD(ctx->opcode));
12525 int rb = mmreg(uMIPS_RS(ctx->opcode));
12526 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12527
d75c135e 12528 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12529 }
12530 break;
12531 case LWSP16:
12532 {
12533 int rd = (ctx->opcode >> 5) & 0x1f;
12534 int rb = 29; /* SP */
12535 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12536
d75c135e 12537 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12538 }
12539 break;
12540 case LW16:
12541 {
12542 int rd = mmreg(uMIPS_RD(ctx->opcode));
12543 int rb = mmreg(uMIPS_RS(ctx->opcode));
12544 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12545
d75c135e 12546 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12547 }
12548 break;
12549 case SB16:
12550 {
12551 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12552 int rb = mmreg(uMIPS_RS(ctx->opcode));
12553 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12554
5c13fdfd 12555 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12556 }
12557 break;
12558 case SH16:
12559 {
12560 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12561 int rb = mmreg(uMIPS_RS(ctx->opcode));
12562 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12563
5c13fdfd 12564 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12565 }
12566 break;
12567 case SWSP16:
12568 {
12569 int rd = (ctx->opcode >> 5) & 0x1f;
12570 int rb = 29; /* SP */
12571 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12572
5c13fdfd 12573 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12574 }
12575 break;
12576 case SW16:
12577 {
12578 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12579 int rb = mmreg(uMIPS_RS(ctx->opcode));
12580 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12581
5c13fdfd 12582 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12583 }
12584 break;
12585 case MOVE16:
12586 {
12587 int rd = uMIPS_RD5(ctx->opcode);
12588 int rs = uMIPS_RS5(ctx->opcode);
12589
d75c135e 12590 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12591 }
12592 break;
12593 case ANDI16:
d75c135e 12594 gen_andi16(ctx);
3c824109
NF
12595 break;
12596 case POOL16D:
12597 switch (ctx->opcode & 0x1) {
12598 case ADDIUS5:
d75c135e 12599 gen_addius5(ctx);
3c824109
NF
12600 break;
12601 case ADDIUSP:
d75c135e 12602 gen_addiusp(ctx);
3c824109
NF
12603 break;
12604 }
12605 break;
12606 case POOL16E:
12607 switch (ctx->opcode & 0x1) {
12608 case ADDIUR2:
d75c135e 12609 gen_addiur2(ctx);
3c824109
NF
12610 break;
12611 case ADDIUR1SP:
d75c135e 12612 gen_addiur1sp(ctx);
3c824109
NF
12613 break;
12614 }
12615 break;
12616 case B16:
12617 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12618 SIMM(ctx->opcode, 0, 10) << 1);
12619 *is_branch = 1;
12620 break;
12621 case BNEZ16:
12622 case BEQZ16:
12623 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12624 mmreg(uMIPS_RD(ctx->opcode)),
12625 0, SIMM(ctx->opcode, 0, 7) << 1);
12626 *is_branch = 1;
12627 break;
12628 case LI16:
12629 {
12630 int reg = mmreg(uMIPS_RD(ctx->opcode));
12631 int imm = ZIMM(ctx->opcode, 0, 7);
12632
12633 imm = (imm == 0x7f ? -1 : imm);
12634 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12635 }
12636 break;
12637 case RES_20:
12638 case RES_28:
12639 case RES_29:
12640 case RES_30:
12641 case RES_31:
12642 case RES_38:
12643 case RES_39:
12644 generate_exception(ctx, EXCP_RI);
12645 break;
12646 default:
12647 decode_micromips32_opc (env, ctx, op, is_branch);
12648 return 4;
12649 }
12650
12651 return 2;
12652}
12653
12654/* SmartMIPS extension to MIPS32 */
12655
12656#if defined(TARGET_MIPS64)
12657
12658/* MDMX extension to MIPS64 */
12659
12660#endif
12661
9b1a1d68 12662/* MIPSDSP functions. */
d75c135e 12663static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12664 int rd, int base, int offset)
12665{
12666 const char *opn = "ldx";
12667 TCGv t0;
12668
9b1a1d68
JL
12669 check_dsp(ctx);
12670 t0 = tcg_temp_new();
12671
12672 if (base == 0) {
12673 gen_load_gpr(t0, offset);
12674 } else if (offset == 0) {
12675 gen_load_gpr(t0, base);
12676 } else {
12677 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12678 }
12679
9b1a1d68
JL
12680 switch (opc) {
12681 case OPC_LBUX:
2910c6cb 12682 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12683 gen_store_gpr(t0, rd);
12684 opn = "lbux";
12685 break;
12686 case OPC_LHX:
2910c6cb 12687 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12688 gen_store_gpr(t0, rd);
12689 opn = "lhx";
12690 break;
12691 case OPC_LWX:
2910c6cb 12692 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12693 gen_store_gpr(t0, rd);
12694 opn = "lwx";
12695 break;
12696#if defined(TARGET_MIPS64)
12697 case OPC_LDX:
2910c6cb 12698 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12699 gen_store_gpr(t0, rd);
12700 opn = "ldx";
12701 break;
12702#endif
12703 }
12704 (void)opn; /* avoid a compiler warning */
12705 MIPS_DEBUG("%s %s, %s(%s)", opn,
12706 regnames[rd], regnames[offset], regnames[base]);
12707 tcg_temp_free(t0);
12708}
12709
461c08df
JL
12710static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12711 int ret, int v1, int v2)
12712{
12713 const char *opn = "mipsdsp arith";
12714 TCGv v1_t;
12715 TCGv v2_t;
12716
12717 if (ret == 0) {
12718 /* Treat as NOP. */
12719 MIPS_DEBUG("NOP");
12720 return;
12721 }
12722
12723 v1_t = tcg_temp_new();
12724 v2_t = tcg_temp_new();
12725
12726 gen_load_gpr(v1_t, v1);
12727 gen_load_gpr(v2_t, v2);
12728
12729 switch (op1) {
12730 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12731 case OPC_MULT_G_2E:
12732 check_dspr2(ctx);
12733 switch (op2) {
12734 case OPC_ADDUH_QB:
12735 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12736 break;
12737 case OPC_ADDUH_R_QB:
12738 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12739 break;
12740 case OPC_ADDQH_PH:
12741 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12742 break;
12743 case OPC_ADDQH_R_PH:
12744 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12745 break;
12746 case OPC_ADDQH_W:
12747 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12748 break;
12749 case OPC_ADDQH_R_W:
12750 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12751 break;
12752 case OPC_SUBUH_QB:
12753 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12754 break;
12755 case OPC_SUBUH_R_QB:
12756 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12757 break;
12758 case OPC_SUBQH_PH:
12759 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12760 break;
12761 case OPC_SUBQH_R_PH:
12762 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12763 break;
12764 case OPC_SUBQH_W:
12765 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12766 break;
12767 case OPC_SUBQH_R_W:
12768 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12769 break;
12770 }
12771 break;
12772 case OPC_ABSQ_S_PH_DSP:
12773 switch (op2) {
12774 case OPC_ABSQ_S_QB:
12775 check_dspr2(ctx);
12776 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12777 break;
12778 case OPC_ABSQ_S_PH:
12779 check_dsp(ctx);
12780 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12781 break;
12782 case OPC_ABSQ_S_W:
12783 check_dsp(ctx);
12784 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12785 break;
12786 case OPC_PRECEQ_W_PHL:
12787 check_dsp(ctx);
12788 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12789 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12790 break;
12791 case OPC_PRECEQ_W_PHR:
12792 check_dsp(ctx);
12793 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12794 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12795 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12796 break;
12797 case OPC_PRECEQU_PH_QBL:
12798 check_dsp(ctx);
12799 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12800 break;
12801 case OPC_PRECEQU_PH_QBR:
12802 check_dsp(ctx);
12803 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12804 break;
12805 case OPC_PRECEQU_PH_QBLA:
12806 check_dsp(ctx);
12807 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12808 break;
12809 case OPC_PRECEQU_PH_QBRA:
12810 check_dsp(ctx);
12811 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12812 break;
12813 case OPC_PRECEU_PH_QBL:
12814 check_dsp(ctx);
12815 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12816 break;
12817 case OPC_PRECEU_PH_QBR:
12818 check_dsp(ctx);
12819 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12820 break;
12821 case OPC_PRECEU_PH_QBLA:
12822 check_dsp(ctx);
12823 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12824 break;
12825 case OPC_PRECEU_PH_QBRA:
12826 check_dsp(ctx);
12827 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12828 break;
12829 }
12830 break;
12831 case OPC_ADDU_QB_DSP:
12832 switch (op2) {
12833 case OPC_ADDQ_PH:
12834 check_dsp(ctx);
12835 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12836 break;
12837 case OPC_ADDQ_S_PH:
12838 check_dsp(ctx);
12839 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12840 break;
12841 case OPC_ADDQ_S_W:
12842 check_dsp(ctx);
12843 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12844 break;
12845 case OPC_ADDU_QB:
12846 check_dsp(ctx);
12847 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12848 break;
12849 case OPC_ADDU_S_QB:
12850 check_dsp(ctx);
12851 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12852 break;
12853 case OPC_ADDU_PH:
12854 check_dspr2(ctx);
12855 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12856 break;
12857 case OPC_ADDU_S_PH:
12858 check_dspr2(ctx);
12859 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12860 break;
12861 case OPC_SUBQ_PH:
12862 check_dsp(ctx);
12863 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12864 break;
12865 case OPC_SUBQ_S_PH:
12866 check_dsp(ctx);
12867 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12868 break;
12869 case OPC_SUBQ_S_W:
12870 check_dsp(ctx);
12871 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12872 break;
12873 case OPC_SUBU_QB:
12874 check_dsp(ctx);
12875 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12876 break;
12877 case OPC_SUBU_S_QB:
12878 check_dsp(ctx);
12879 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12880 break;
12881 case OPC_SUBU_PH:
12882 check_dspr2(ctx);
12883 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12884 break;
12885 case OPC_SUBU_S_PH:
12886 check_dspr2(ctx);
12887 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12888 break;
12889 case OPC_ADDSC:
12890 check_dsp(ctx);
12891 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12892 break;
12893 case OPC_ADDWC:
12894 check_dsp(ctx);
12895 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12896 break;
12897 case OPC_MODSUB:
12898 check_dsp(ctx);
12899 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12900 break;
12901 case OPC_RADDU_W_QB:
12902 check_dsp(ctx);
12903 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12904 break;
12905 }
12906 break;
12907 case OPC_CMPU_EQ_QB_DSP:
12908 switch (op2) {
12909 case OPC_PRECR_QB_PH:
12910 check_dspr2(ctx);
12911 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12912 break;
12913 case OPC_PRECRQ_QB_PH:
12914 check_dsp(ctx);
12915 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12916 break;
12917 case OPC_PRECR_SRA_PH_W:
12918 check_dspr2(ctx);
12919 {
12920 TCGv_i32 sa_t = tcg_const_i32(v2);
12921 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12922 cpu_gpr[ret]);
12923 tcg_temp_free_i32(sa_t);
12924 break;
12925 }
12926 case OPC_PRECR_SRA_R_PH_W:
12927 check_dspr2(ctx);
12928 {
12929 TCGv_i32 sa_t = tcg_const_i32(v2);
12930 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12931 cpu_gpr[ret]);
12932 tcg_temp_free_i32(sa_t);
12933 break;
12934 }
12935 case OPC_PRECRQ_PH_W:
12936 check_dsp(ctx);
12937 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12938 break;
12939 case OPC_PRECRQ_RS_PH_W:
12940 check_dsp(ctx);
12941 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12942 break;
12943 case OPC_PRECRQU_S_QB_PH:
12944 check_dsp(ctx);
12945 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12946 break;
12947 }
12948 break;
12949#ifdef TARGET_MIPS64
12950 case OPC_ABSQ_S_QH_DSP:
12951 switch (op2) {
12952 case OPC_PRECEQ_L_PWL:
12953 check_dsp(ctx);
12954 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12955 break;
12956 case OPC_PRECEQ_L_PWR:
12957 check_dsp(ctx);
12958 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12959 break;
12960 case OPC_PRECEQ_PW_QHL:
12961 check_dsp(ctx);
12962 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12963 break;
12964 case OPC_PRECEQ_PW_QHR:
12965 check_dsp(ctx);
12966 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12967 break;
12968 case OPC_PRECEQ_PW_QHLA:
12969 check_dsp(ctx);
12970 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12971 break;
12972 case OPC_PRECEQ_PW_QHRA:
12973 check_dsp(ctx);
12974 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12975 break;
12976 case OPC_PRECEQU_QH_OBL:
12977 check_dsp(ctx);
12978 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12979 break;
12980 case OPC_PRECEQU_QH_OBR:
12981 check_dsp(ctx);
12982 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12983 break;
12984 case OPC_PRECEQU_QH_OBLA:
12985 check_dsp(ctx);
12986 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12987 break;
12988 case OPC_PRECEQU_QH_OBRA:
12989 check_dsp(ctx);
12990 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12991 break;
12992 case OPC_PRECEU_QH_OBL:
12993 check_dsp(ctx);
12994 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12995 break;
12996 case OPC_PRECEU_QH_OBR:
12997 check_dsp(ctx);
12998 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12999 break;
13000 case OPC_PRECEU_QH_OBLA:
13001 check_dsp(ctx);
13002 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13003 break;
13004 case OPC_PRECEU_QH_OBRA:
13005 check_dsp(ctx);
13006 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13007 break;
13008 case OPC_ABSQ_S_OB:
13009 check_dspr2(ctx);
13010 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13011 break;
13012 case OPC_ABSQ_S_PW:
13013 check_dsp(ctx);
13014 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13015 break;
13016 case OPC_ABSQ_S_QH:
13017 check_dsp(ctx);
13018 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13019 break;
13020 }
13021 break;
13022 case OPC_ADDU_OB_DSP:
13023 switch (op2) {
13024 case OPC_RADDU_L_OB:
13025 check_dsp(ctx);
13026 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13027 break;
13028 case OPC_SUBQ_PW:
13029 check_dsp(ctx);
13030 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13031 break;
13032 case OPC_SUBQ_S_PW:
13033 check_dsp(ctx);
13034 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13035 break;
13036 case OPC_SUBQ_QH:
13037 check_dsp(ctx);
13038 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13039 break;
13040 case OPC_SUBQ_S_QH:
13041 check_dsp(ctx);
13042 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13043 break;
13044 case OPC_SUBU_OB:
13045 check_dsp(ctx);
13046 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13047 break;
13048 case OPC_SUBU_S_OB:
13049 check_dsp(ctx);
13050 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13051 break;
13052 case OPC_SUBU_QH:
13053 check_dspr2(ctx);
13054 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13055 break;
13056 case OPC_SUBU_S_QH:
13057 check_dspr2(ctx);
13058 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13059 break;
13060 case OPC_SUBUH_OB:
13061 check_dspr2(ctx);
13062 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13063 break;
13064 case OPC_SUBUH_R_OB:
13065 check_dspr2(ctx);
13066 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13067 break;
13068 case OPC_ADDQ_PW:
13069 check_dsp(ctx);
13070 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13071 break;
13072 case OPC_ADDQ_S_PW:
13073 check_dsp(ctx);
13074 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13075 break;
13076 case OPC_ADDQ_QH:
13077 check_dsp(ctx);
13078 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13079 break;
13080 case OPC_ADDQ_S_QH:
13081 check_dsp(ctx);
13082 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13083 break;
13084 case OPC_ADDU_OB:
13085 check_dsp(ctx);
13086 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13087 break;
13088 case OPC_ADDU_S_OB:
13089 check_dsp(ctx);
13090 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13091 break;
13092 case OPC_ADDU_QH:
13093 check_dspr2(ctx);
13094 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13095 break;
13096 case OPC_ADDU_S_QH:
13097 check_dspr2(ctx);
13098 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13099 break;
13100 case OPC_ADDUH_OB:
13101 check_dspr2(ctx);
13102 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13103 break;
13104 case OPC_ADDUH_R_OB:
13105 check_dspr2(ctx);
13106 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13107 break;
13108 }
13109 break;
13110 case OPC_CMPU_EQ_OB_DSP:
13111 switch (op2) {
13112 case OPC_PRECR_OB_QH:
13113 check_dspr2(ctx);
13114 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13115 break;
13116 case OPC_PRECR_SRA_QH_PW:
13117 check_dspr2(ctx);
13118 {
13119 TCGv_i32 ret_t = tcg_const_i32(ret);
13120 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13121 tcg_temp_free_i32(ret_t);
13122 break;
13123 }
13124 case OPC_PRECR_SRA_R_QH_PW:
13125 check_dspr2(ctx);
13126 {
13127 TCGv_i32 sa_v = tcg_const_i32(ret);
13128 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13129 tcg_temp_free_i32(sa_v);
13130 break;
13131 }
13132 case OPC_PRECRQ_OB_QH:
13133 check_dsp(ctx);
13134 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13135 break;
13136 case OPC_PRECRQ_PW_L:
13137 check_dsp(ctx);
13138 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13139 break;
13140 case OPC_PRECRQ_QH_PW:
13141 check_dsp(ctx);
13142 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13143 break;
13144 case OPC_PRECRQ_RS_QH_PW:
13145 check_dsp(ctx);
13146 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13147 break;
13148 case OPC_PRECRQU_S_OB_QH:
13149 check_dsp(ctx);
13150 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13151 break;
13152 }
13153 break;
13154#endif
13155 }
13156
13157 tcg_temp_free(v1_t);
13158 tcg_temp_free(v2_t);
13159
13160 (void)opn; /* avoid a compiler warning */
13161 MIPS_DEBUG("%s", opn);
13162}
9b1a1d68 13163
77c5fa8b
JL
13164static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13165 int ret, int v1, int v2)
13166{
13167 uint32_t op2;
13168 const char *opn = "mipsdsp shift";
13169 TCGv t0;
13170 TCGv v1_t;
13171 TCGv v2_t;
13172
13173 if (ret == 0) {
13174 /* Treat as NOP. */
13175 MIPS_DEBUG("NOP");
13176 return;
13177 }
13178
13179 t0 = tcg_temp_new();
13180 v1_t = tcg_temp_new();
13181 v2_t = tcg_temp_new();
13182
13183 tcg_gen_movi_tl(t0, v1);
13184 gen_load_gpr(v1_t, v1);
13185 gen_load_gpr(v2_t, v2);
13186
13187 switch (opc) {
13188 case OPC_SHLL_QB_DSP:
13189 {
13190 op2 = MASK_SHLL_QB(ctx->opcode);
13191 switch (op2) {
13192 case OPC_SHLL_QB:
13193 check_dsp(ctx);
13194 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13195 break;
13196 case OPC_SHLLV_QB:
13197 check_dsp(ctx);
13198 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13199 break;
13200 case OPC_SHLL_PH:
13201 check_dsp(ctx);
13202 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13203 break;
13204 case OPC_SHLLV_PH:
13205 check_dsp(ctx);
13206 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13207 break;
13208 case OPC_SHLL_S_PH:
13209 check_dsp(ctx);
13210 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13211 break;
13212 case OPC_SHLLV_S_PH:
13213 check_dsp(ctx);
13214 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13215 break;
13216 case OPC_SHLL_S_W:
13217 check_dsp(ctx);
13218 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13219 break;
13220 case OPC_SHLLV_S_W:
13221 check_dsp(ctx);
13222 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13223 break;
13224 case OPC_SHRL_QB:
13225 check_dsp(ctx);
13226 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13227 break;
13228 case OPC_SHRLV_QB:
13229 check_dsp(ctx);
13230 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13231 break;
13232 case OPC_SHRL_PH:
13233 check_dspr2(ctx);
13234 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13235 break;
13236 case OPC_SHRLV_PH:
13237 check_dspr2(ctx);
13238 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13239 break;
13240 case OPC_SHRA_QB:
13241 check_dspr2(ctx);
13242 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13243 break;
13244 case OPC_SHRA_R_QB:
13245 check_dspr2(ctx);
13246 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13247 break;
13248 case OPC_SHRAV_QB:
13249 check_dspr2(ctx);
13250 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13251 break;
13252 case OPC_SHRAV_R_QB:
13253 check_dspr2(ctx);
13254 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13255 break;
13256 case OPC_SHRA_PH:
13257 check_dsp(ctx);
13258 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13259 break;
13260 case OPC_SHRA_R_PH:
13261 check_dsp(ctx);
13262 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13263 break;
13264 case OPC_SHRAV_PH:
13265 check_dsp(ctx);
13266 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13267 break;
13268 case OPC_SHRAV_R_PH:
13269 check_dsp(ctx);
13270 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13271 break;
13272 case OPC_SHRA_R_W:
13273 check_dsp(ctx);
13274 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13275 break;
13276 case OPC_SHRAV_R_W:
13277 check_dsp(ctx);
13278 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13279 break;
13280 default: /* Invalid */
13281 MIPS_INVAL("MASK SHLL.QB");
13282 generate_exception(ctx, EXCP_RI);
13283 break;
13284 }
13285 break;
13286 }
13287#ifdef TARGET_MIPS64
13288 case OPC_SHLL_OB_DSP:
13289 op2 = MASK_SHLL_OB(ctx->opcode);
13290 switch (op2) {
13291 case OPC_SHLL_PW:
13292 check_dsp(ctx);
13293 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13294 break;
13295 case OPC_SHLLV_PW:
13296 check_dsp(ctx);
13297 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13298 break;
13299 case OPC_SHLL_S_PW:
13300 check_dsp(ctx);
13301 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13302 break;
13303 case OPC_SHLLV_S_PW:
13304 check_dsp(ctx);
13305 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13306 break;
13307 case OPC_SHLL_OB:
13308 check_dsp(ctx);
13309 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13310 break;
13311 case OPC_SHLLV_OB:
13312 check_dsp(ctx);
13313 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13314 break;
13315 case OPC_SHLL_QH:
13316 check_dsp(ctx);
13317 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13318 break;
13319 case OPC_SHLLV_QH:
13320 check_dsp(ctx);
13321 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13322 break;
13323 case OPC_SHLL_S_QH:
13324 check_dsp(ctx);
13325 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13326 break;
13327 case OPC_SHLLV_S_QH:
13328 check_dsp(ctx);
13329 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13330 break;
13331 case OPC_SHRA_OB:
13332 check_dspr2(ctx);
13333 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13334 break;
13335 case OPC_SHRAV_OB:
13336 check_dspr2(ctx);
13337 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13338 break;
13339 case OPC_SHRA_R_OB:
13340 check_dspr2(ctx);
13341 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13342 break;
13343 case OPC_SHRAV_R_OB:
13344 check_dspr2(ctx);
13345 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13346 break;
13347 case OPC_SHRA_PW:
13348 check_dsp(ctx);
13349 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13350 break;
13351 case OPC_SHRAV_PW:
13352 check_dsp(ctx);
13353 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13354 break;
13355 case OPC_SHRA_R_PW:
13356 check_dsp(ctx);
13357 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13358 break;
13359 case OPC_SHRAV_R_PW:
13360 check_dsp(ctx);
13361 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13362 break;
13363 case OPC_SHRA_QH:
13364 check_dsp(ctx);
13365 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13366 break;
13367 case OPC_SHRAV_QH:
13368 check_dsp(ctx);
13369 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13370 break;
13371 case OPC_SHRA_R_QH:
13372 check_dsp(ctx);
13373 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13374 break;
13375 case OPC_SHRAV_R_QH:
13376 check_dsp(ctx);
13377 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13378 break;
13379 case OPC_SHRL_OB:
13380 check_dsp(ctx);
13381 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13382 break;
13383 case OPC_SHRLV_OB:
13384 check_dsp(ctx);
13385 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13386 break;
13387 case OPC_SHRL_QH:
13388 check_dspr2(ctx);
13389 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13390 break;
13391 case OPC_SHRLV_QH:
13392 check_dspr2(ctx);
13393 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13394 break;
13395 default: /* Invalid */
13396 MIPS_INVAL("MASK SHLL.OB");
13397 generate_exception(ctx, EXCP_RI);
13398 break;
13399 }
13400 break;
13401#endif
13402 }
13403
13404 tcg_temp_free(t0);
13405 tcg_temp_free(v1_t);
13406 tcg_temp_free(v2_t);
13407 (void)opn; /* avoid a compiler warning */
13408 MIPS_DEBUG("%s", opn);
13409}
13410
a22260ae
JL
13411static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13412 int ret, int v1, int v2, int check_ret)
13413{
13414 const char *opn = "mipsdsp multiply";
13415 TCGv_i32 t0;
13416 TCGv v1_t;
13417 TCGv v2_t;
13418
13419 if ((ret == 0) && (check_ret == 1)) {
13420 /* Treat as NOP. */
13421 MIPS_DEBUG("NOP");
13422 return;
13423 }
13424
13425 t0 = tcg_temp_new_i32();
13426 v1_t = tcg_temp_new();
13427 v2_t = tcg_temp_new();
13428
13429 tcg_gen_movi_i32(t0, ret);
13430 gen_load_gpr(v1_t, v1);
13431 gen_load_gpr(v2_t, v2);
13432
13433 switch (op1) {
13434 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13435 * the same mask and op1. */
13436 case OPC_MULT_G_2E:
13437 switch (op2) {
13438 case OPC_MUL_PH:
13439 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13440 break;
13441 case OPC_MUL_S_PH:
13442 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13443 break;
13444 case OPC_MULQ_S_W:
13445 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13446 break;
13447 case OPC_MULQ_RS_W:
13448 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13449 break;
13450 }
13451 break;
13452 case OPC_DPA_W_PH_DSP:
13453 switch (op2) {
13454 case OPC_DPAU_H_QBL:
13455 check_dsp(ctx);
13456 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13457 break;
13458 case OPC_DPAU_H_QBR:
13459 check_dsp(ctx);
13460 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13461 break;
13462 case OPC_DPSU_H_QBL:
13463 check_dsp(ctx);
13464 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13465 break;
13466 case OPC_DPSU_H_QBR:
13467 check_dsp(ctx);
13468 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13469 break;
13470 case OPC_DPA_W_PH:
13471 check_dspr2(ctx);
13472 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13473 break;
13474 case OPC_DPAX_W_PH:
13475 check_dspr2(ctx);
13476 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13477 break;
13478 case OPC_DPAQ_S_W_PH:
13479 check_dsp(ctx);
13480 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13481 break;
13482 case OPC_DPAQX_S_W_PH:
13483 check_dspr2(ctx);
13484 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13485 break;
13486 case OPC_DPAQX_SA_W_PH:
13487 check_dspr2(ctx);
13488 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13489 break;
13490 case OPC_DPS_W_PH:
13491 check_dspr2(ctx);
13492 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13493 break;
13494 case OPC_DPSX_W_PH:
13495 check_dspr2(ctx);
13496 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13497 break;
13498 case OPC_DPSQ_S_W_PH:
13499 check_dsp(ctx);
13500 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13501 break;
13502 case OPC_DPSQX_S_W_PH:
13503 check_dspr2(ctx);
13504 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13505 break;
13506 case OPC_DPSQX_SA_W_PH:
13507 check_dspr2(ctx);
13508 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13509 break;
13510 case OPC_MULSAQ_S_W_PH:
13511 check_dsp(ctx);
13512 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13513 break;
13514 case OPC_DPAQ_SA_L_W:
13515 check_dsp(ctx);
13516 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13517 break;
13518 case OPC_DPSQ_SA_L_W:
13519 check_dsp(ctx);
13520 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13521 break;
13522 case OPC_MAQ_S_W_PHL:
13523 check_dsp(ctx);
13524 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13525 break;
13526 case OPC_MAQ_S_W_PHR:
13527 check_dsp(ctx);
13528 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13529 break;
13530 case OPC_MAQ_SA_W_PHL:
13531 check_dsp(ctx);
13532 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13533 break;
13534 case OPC_MAQ_SA_W_PHR:
13535 check_dsp(ctx);
13536 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13537 break;
13538 case OPC_MULSA_W_PH:
13539 check_dspr2(ctx);
13540 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13541 break;
13542 }
13543 break;
13544#ifdef TARGET_MIPS64
13545 case OPC_DPAQ_W_QH_DSP:
13546 {
13547 int ac = ret & 0x03;
13548 tcg_gen_movi_i32(t0, ac);
13549
13550 switch (op2) {
13551 case OPC_DMADD:
13552 check_dsp(ctx);
13553 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13554 break;
13555 case OPC_DMADDU:
13556 check_dsp(ctx);
13557 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13558 break;
13559 case OPC_DMSUB:
13560 check_dsp(ctx);
13561 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13562 break;
13563 case OPC_DMSUBU:
13564 check_dsp(ctx);
13565 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13566 break;
13567 case OPC_DPA_W_QH:
13568 check_dspr2(ctx);
13569 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13570 break;
13571 case OPC_DPAQ_S_W_QH:
13572 check_dsp(ctx);
13573 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13574 break;
13575 case OPC_DPAQ_SA_L_PW:
13576 check_dsp(ctx);
13577 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13578 break;
13579 case OPC_DPAU_H_OBL:
13580 check_dsp(ctx);
13581 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13582 break;
13583 case OPC_DPAU_H_OBR:
13584 check_dsp(ctx);
13585 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13586 break;
13587 case OPC_DPS_W_QH:
13588 check_dspr2(ctx);
13589 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13590 break;
13591 case OPC_DPSQ_S_W_QH:
13592 check_dsp(ctx);
13593 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13594 break;
13595 case OPC_DPSQ_SA_L_PW:
13596 check_dsp(ctx);
13597 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13598 break;
13599 case OPC_DPSU_H_OBL:
13600 check_dsp(ctx);
13601 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13602 break;
13603 case OPC_DPSU_H_OBR:
13604 check_dsp(ctx);
13605 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13606 break;
13607 case OPC_MAQ_S_L_PWL:
13608 check_dsp(ctx);
13609 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13610 break;
13611 case OPC_MAQ_S_L_PWR:
13612 check_dsp(ctx);
13613 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13614 break;
13615 case OPC_MAQ_S_W_QHLL:
13616 check_dsp(ctx);
13617 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13618 break;
13619 case OPC_MAQ_SA_W_QHLL:
13620 check_dsp(ctx);
13621 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13622 break;
13623 case OPC_MAQ_S_W_QHLR:
13624 check_dsp(ctx);
13625 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13626 break;
13627 case OPC_MAQ_SA_W_QHLR:
13628 check_dsp(ctx);
13629 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13630 break;
13631 case OPC_MAQ_S_W_QHRL:
13632 check_dsp(ctx);
13633 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13634 break;
13635 case OPC_MAQ_SA_W_QHRL:
13636 check_dsp(ctx);
13637 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13638 break;
13639 case OPC_MAQ_S_W_QHRR:
13640 check_dsp(ctx);
13641 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13642 break;
13643 case OPC_MAQ_SA_W_QHRR:
13644 check_dsp(ctx);
13645 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13646 break;
13647 case OPC_MULSAQ_S_L_PW:
13648 check_dsp(ctx);
13649 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13650 break;
13651 case OPC_MULSAQ_S_W_QH:
13652 check_dsp(ctx);
13653 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13654 break;
13655 }
13656 }
13657 break;
13658#endif
13659 case OPC_ADDU_QB_DSP:
13660 switch (op2) {
13661 case OPC_MULEU_S_PH_QBL:
13662 check_dsp(ctx);
13663 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13664 break;
13665 case OPC_MULEU_S_PH_QBR:
13666 check_dsp(ctx);
13667 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 break;
13669 case OPC_MULQ_RS_PH:
13670 check_dsp(ctx);
13671 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 break;
13673 case OPC_MULEQ_S_W_PHL:
13674 check_dsp(ctx);
13675 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 break;
13677 case OPC_MULEQ_S_W_PHR:
13678 check_dsp(ctx);
13679 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13680 break;
13681 case OPC_MULQ_S_PH:
13682 check_dspr2(ctx);
13683 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13684 break;
13685 }
13686 break;
13687#ifdef TARGET_MIPS64
13688 case OPC_ADDU_OB_DSP:
13689 switch (op2) {
13690 case OPC_MULEQ_S_PW_QHL:
13691 check_dsp(ctx);
13692 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13693 break;
13694 case OPC_MULEQ_S_PW_QHR:
13695 check_dsp(ctx);
13696 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13697 break;
13698 case OPC_MULEU_S_QH_OBL:
13699 check_dsp(ctx);
13700 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13701 break;
13702 case OPC_MULEU_S_QH_OBR:
13703 check_dsp(ctx);
13704 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13705 break;
13706 case OPC_MULQ_RS_QH:
13707 check_dsp(ctx);
13708 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13709 break;
13710 }
13711 break;
13712#endif
13713 }
13714
13715 tcg_temp_free_i32(t0);
13716 tcg_temp_free(v1_t);
13717 tcg_temp_free(v2_t);
13718
13719 (void)opn; /* avoid a compiler warning */
13720 MIPS_DEBUG("%s", opn);
13721
13722}
13723
d75c135e 13724static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13725 int ret, int val)
13726{
13727 const char *opn = "mipsdsp Bit/ Manipulation";
13728 int16_t imm;
13729 TCGv t0;
13730 TCGv val_t;
13731
13732 if (ret == 0) {
13733 /* Treat as NOP. */
13734 MIPS_DEBUG("NOP");
13735 return;
13736 }
13737
13738 t0 = tcg_temp_new();
13739 val_t = tcg_temp_new();
13740 gen_load_gpr(val_t, val);
13741
13742 switch (op1) {
13743 case OPC_ABSQ_S_PH_DSP:
13744 switch (op2) {
13745 case OPC_BITREV:
13746 check_dsp(ctx);
13747 gen_helper_bitrev(cpu_gpr[ret], val_t);
13748 break;
13749 case OPC_REPL_QB:
13750 check_dsp(ctx);
13751 {
13752 target_long result;
13753 imm = (ctx->opcode >> 16) & 0xFF;
13754 result = (uint32_t)imm << 24 |
13755 (uint32_t)imm << 16 |
13756 (uint32_t)imm << 8 |
13757 (uint32_t)imm;
13758 result = (int32_t)result;
13759 tcg_gen_movi_tl(cpu_gpr[ret], result);
13760 }
13761 break;
13762 case OPC_REPLV_QB:
13763 check_dsp(ctx);
13764 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13765 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13766 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13767 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13768 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13769 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13770 break;
13771 case OPC_REPL_PH:
13772 check_dsp(ctx);
13773 {
13774 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13775 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13776 tcg_gen_movi_tl(cpu_gpr[ret], \
13777 (target_long)((int32_t)imm << 16 | \
c4aaba92 13778 (uint16_t)imm));
1cb6686c
JL
13779 }
13780 break;
13781 case OPC_REPLV_PH:
13782 check_dsp(ctx);
13783 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13784 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13785 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13786 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13787 break;
13788 }
13789 break;
13790#ifdef TARGET_MIPS64
13791 case OPC_ABSQ_S_QH_DSP:
13792 switch (op2) {
13793 case OPC_REPL_OB:
13794 check_dsp(ctx);
13795 {
13796 target_long temp;
13797
13798 imm = (ctx->opcode >> 16) & 0xFF;
13799 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13800 temp = (temp << 16) | temp;
13801 temp = (temp << 32) | temp;
13802 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13803 break;
13804 }
13805 case OPC_REPL_PW:
13806 check_dsp(ctx);
13807 {
13808 target_long temp;
13809
13810 imm = (ctx->opcode >> 16) & 0x03FF;
13811 imm = (int16_t)(imm << 6) >> 6;
13812 temp = ((target_long)imm << 32) \
13813 | ((target_long)imm & 0xFFFFFFFF);
13814 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13815 break;
13816 }
13817 case OPC_REPL_QH:
13818 check_dsp(ctx);
13819 {
13820 target_long temp;
13821
13822 imm = (ctx->opcode >> 16) & 0x03FF;
13823 imm = (int16_t)(imm << 6) >> 6;
13824
13825 temp = ((uint64_t)(uint16_t)imm << 48) |
13826 ((uint64_t)(uint16_t)imm << 32) |
13827 ((uint64_t)(uint16_t)imm << 16) |
13828 (uint64_t)(uint16_t)imm;
13829 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13830 break;
13831 }
13832 case OPC_REPLV_OB:
13833 check_dsp(ctx);
13834 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13835 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13836 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13837 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13838 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13839 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13840 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13841 break;
13842 case OPC_REPLV_PW:
13843 check_dsp(ctx);
13844 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13845 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13846 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13847 break;
13848 case OPC_REPLV_QH:
13849 check_dsp(ctx);
13850 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13851 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13852 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13853 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13854 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13855 break;
13856 }
13857 break;
13858#endif
13859 }
13860 tcg_temp_free(t0);
13861 tcg_temp_free(val_t);
13862
13863 (void)opn; /* avoid a compiler warning */
13864 MIPS_DEBUG("%s", opn);
13865}
13866
26690560
JL
13867static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13868 uint32_t op1, uint32_t op2,
13869 int ret, int v1, int v2, int check_ret)
13870{
13871 const char *opn = "mipsdsp add compare pick";
26690560
JL
13872 TCGv t1;
13873 TCGv v1_t;
13874 TCGv v2_t;
13875
13876 if ((ret == 0) && (check_ret == 1)) {
13877 /* Treat as NOP. */
13878 MIPS_DEBUG("NOP");
13879 return;
13880 }
13881
26690560
JL
13882 t1 = tcg_temp_new();
13883 v1_t = tcg_temp_new();
13884 v2_t = tcg_temp_new();
13885
13886 gen_load_gpr(v1_t, v1);
13887 gen_load_gpr(v2_t, v2);
13888
13889 switch (op1) {
26690560
JL
13890 case OPC_CMPU_EQ_QB_DSP:
13891 switch (op2) {
13892 case OPC_CMPU_EQ_QB:
13893 check_dsp(ctx);
13894 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13895 break;
13896 case OPC_CMPU_LT_QB:
13897 check_dsp(ctx);
13898 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13899 break;
13900 case OPC_CMPU_LE_QB:
13901 check_dsp(ctx);
13902 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13903 break;
13904 case OPC_CMPGU_EQ_QB:
13905 check_dsp(ctx);
13906 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13907 break;
13908 case OPC_CMPGU_LT_QB:
13909 check_dsp(ctx);
13910 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13911 break;
13912 case OPC_CMPGU_LE_QB:
13913 check_dsp(ctx);
13914 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13915 break;
13916 case OPC_CMPGDU_EQ_QB:
13917 check_dspr2(ctx);
13918 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13919 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13920 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13921 tcg_gen_shli_tl(t1, t1, 24);
13922 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13923 break;
13924 case OPC_CMPGDU_LT_QB:
13925 check_dspr2(ctx);
13926 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13927 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13928 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13929 tcg_gen_shli_tl(t1, t1, 24);
13930 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13931 break;
13932 case OPC_CMPGDU_LE_QB:
13933 check_dspr2(ctx);
13934 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13935 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13936 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13937 tcg_gen_shli_tl(t1, t1, 24);
13938 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13939 break;
13940 case OPC_CMP_EQ_PH:
13941 check_dsp(ctx);
13942 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13943 break;
13944 case OPC_CMP_LT_PH:
13945 check_dsp(ctx);
13946 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13947 break;
13948 case OPC_CMP_LE_PH:
13949 check_dsp(ctx);
13950 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13951 break;
13952 case OPC_PICK_QB:
13953 check_dsp(ctx);
13954 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13955 break;
13956 case OPC_PICK_PH:
13957 check_dsp(ctx);
13958 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13959 break;
13960 case OPC_PACKRL_PH:
13961 check_dsp(ctx);
13962 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13963 break;
13964 }
13965 break;
13966#ifdef TARGET_MIPS64
13967 case OPC_CMPU_EQ_OB_DSP:
13968 switch (op2) {
13969 case OPC_CMP_EQ_PW:
13970 check_dsp(ctx);
13971 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13972 break;
13973 case OPC_CMP_LT_PW:
13974 check_dsp(ctx);
13975 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13976 break;
13977 case OPC_CMP_LE_PW:
13978 check_dsp(ctx);
13979 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13980 break;
13981 case OPC_CMP_EQ_QH:
13982 check_dsp(ctx);
13983 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13984 break;
13985 case OPC_CMP_LT_QH:
13986 check_dsp(ctx);
13987 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13988 break;
13989 case OPC_CMP_LE_QH:
13990 check_dsp(ctx);
13991 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13992 break;
13993 case OPC_CMPGDU_EQ_OB:
13994 check_dspr2(ctx);
13995 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13996 break;
13997 case OPC_CMPGDU_LT_OB:
13998 check_dspr2(ctx);
13999 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14000 break;
14001 case OPC_CMPGDU_LE_OB:
14002 check_dspr2(ctx);
14003 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14004 break;
14005 case OPC_CMPGU_EQ_OB:
14006 check_dsp(ctx);
14007 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14008 break;
14009 case OPC_CMPGU_LT_OB:
14010 check_dsp(ctx);
14011 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14012 break;
14013 case OPC_CMPGU_LE_OB:
14014 check_dsp(ctx);
14015 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14016 break;
14017 case OPC_CMPU_EQ_OB:
14018 check_dsp(ctx);
14019 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14020 break;
14021 case OPC_CMPU_LT_OB:
14022 check_dsp(ctx);
14023 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14024 break;
14025 case OPC_CMPU_LE_OB:
14026 check_dsp(ctx);
14027 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14028 break;
14029 case OPC_PACKRL_PW:
14030 check_dsp(ctx);
14031 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14032 break;
14033 case OPC_PICK_OB:
14034 check_dsp(ctx);
14035 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14036 break;
14037 case OPC_PICK_PW:
14038 check_dsp(ctx);
14039 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14040 break;
14041 case OPC_PICK_QH:
14042 check_dsp(ctx);
14043 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14044 break;
14045 }
14046 break;
df6126a7
AJ
14047#endif
14048 }
14049
14050 tcg_temp_free(t1);
14051 tcg_temp_free(v1_t);
14052 tcg_temp_free(v2_t);
14053
14054 (void)opn; /* avoid a compiler warning */
14055 MIPS_DEBUG("%s", opn);
14056}
14057
14058static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14059 uint32_t op1, int rt, int rs, int sa)
14060{
14061 const char *opn = "mipsdsp append/dappend";
14062 TCGv t0;
14063
14064 check_dspr2(ctx);
14065
14066 if (rt == 0) {
14067 /* Treat as NOP. */
14068 MIPS_DEBUG("NOP");
14069 return;
14070 }
14071
14072 t0 = tcg_temp_new();
14073 gen_load_gpr(t0, rs);
14074
14075 switch (op1) {
14076 case OPC_APPEND_DSP:
14077 switch (MASK_APPEND(ctx->opcode)) {
14078 case OPC_APPEND:
14079 if (sa != 0) {
14080 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14081 }
14082 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14083 break;
14084 case OPC_PREPEND:
14085 if (sa != 0) {
14086 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14087 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14088 tcg_gen_shli_tl(t0, t0, 32 - sa);
14089 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14090 }
14091 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14092 break;
14093 case OPC_BALIGN:
14094 sa &= 3;
14095 if (sa != 0 && sa != 2) {
14096 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14097 tcg_gen_ext32u_tl(t0, t0);
14098 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14099 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14100 }
14101 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14102 break;
14103 default: /* Invalid */
14104 MIPS_INVAL("MASK APPEND");
14105 generate_exception(ctx, EXCP_RI);
14106 break;
14107 }
14108 break;
14109#ifdef TARGET_MIPS64
26690560 14110 case OPC_DAPPEND_DSP:
df6126a7 14111 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 14112 case OPC_DAPPEND:
df6126a7
AJ
14113 if (sa != 0) {
14114 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14115 }
26690560
JL
14116 break;
14117 case OPC_PREPENDD:
df6126a7
AJ
14118 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14119 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14120 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
14121 break;
14122 case OPC_PREPENDW:
df6126a7
AJ
14123 if (sa != 0) {
14124 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14125 tcg_gen_shli_tl(t0, t0, 64 - sa);
14126 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14127 }
26690560
JL
14128 break;
14129 case OPC_DBALIGN:
df6126a7
AJ
14130 sa &= 7;
14131 if (sa != 0 && sa != 2 && sa != 4) {
14132 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14133 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14134 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14135 }
26690560
JL
14136 break;
14137 default: /* Invalid */
14138 MIPS_INVAL("MASK DAPPEND");
14139 generate_exception(ctx, EXCP_RI);
14140 break;
14141 }
14142 break;
14143#endif
14144 }
df6126a7 14145 tcg_temp_free(t0);
26690560
JL
14146 (void)opn; /* avoid a compiler warning */
14147 MIPS_DEBUG("%s", opn);
14148}
14149
b53371ed
JL
14150static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14151 int ret, int v1, int v2, int check_ret)
14152
14153{
14154 const char *opn = "mipsdsp accumulator";
14155 TCGv t0;
14156 TCGv t1;
14157 TCGv v1_t;
14158 TCGv v2_t;
14159 int16_t imm;
14160
14161 if ((ret == 0) && (check_ret == 1)) {
14162 /* Treat as NOP. */
14163 MIPS_DEBUG("NOP");
14164 return;
14165 }
14166
14167 t0 = tcg_temp_new();
14168 t1 = tcg_temp_new();
14169 v1_t = tcg_temp_new();
14170 v2_t = tcg_temp_new();
14171
14172 gen_load_gpr(v1_t, v1);
14173 gen_load_gpr(v2_t, v2);
14174
14175 switch (op1) {
14176 case OPC_EXTR_W_DSP:
14177 check_dsp(ctx);
14178 switch (op2) {
14179 case OPC_EXTR_W:
14180 tcg_gen_movi_tl(t0, v2);
14181 tcg_gen_movi_tl(t1, v1);
14182 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14183 break;
14184 case OPC_EXTR_R_W:
14185 tcg_gen_movi_tl(t0, v2);
14186 tcg_gen_movi_tl(t1, v1);
14187 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14188 break;
14189 case OPC_EXTR_RS_W:
14190 tcg_gen_movi_tl(t0, v2);
14191 tcg_gen_movi_tl(t1, v1);
14192 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14193 break;
14194 case OPC_EXTR_S_H:
14195 tcg_gen_movi_tl(t0, v2);
14196 tcg_gen_movi_tl(t1, v1);
14197 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14198 break;
14199 case OPC_EXTRV_S_H:
14200 tcg_gen_movi_tl(t0, v2);
14201 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14202 break;
14203 case OPC_EXTRV_W:
14204 tcg_gen_movi_tl(t0, v2);
14205 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14206 break;
14207 case OPC_EXTRV_R_W:
14208 tcg_gen_movi_tl(t0, v2);
14209 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14210 break;
14211 case OPC_EXTRV_RS_W:
14212 tcg_gen_movi_tl(t0, v2);
14213 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14214 break;
14215 case OPC_EXTP:
14216 tcg_gen_movi_tl(t0, v2);
14217 tcg_gen_movi_tl(t1, v1);
14218 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14219 break;
14220 case OPC_EXTPV:
14221 tcg_gen_movi_tl(t0, v2);
14222 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14223 break;
14224 case OPC_EXTPDP:
14225 tcg_gen_movi_tl(t0, v2);
14226 tcg_gen_movi_tl(t1, v1);
14227 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14228 break;
14229 case OPC_EXTPDPV:
14230 tcg_gen_movi_tl(t0, v2);
14231 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14232 break;
14233 case OPC_SHILO:
14234 imm = (ctx->opcode >> 20) & 0x3F;
14235 tcg_gen_movi_tl(t0, ret);
14236 tcg_gen_movi_tl(t1, imm);
14237 gen_helper_shilo(t0, t1, cpu_env);
14238 break;
14239 case OPC_SHILOV:
14240 tcg_gen_movi_tl(t0, ret);
14241 gen_helper_shilo(t0, v1_t, cpu_env);
14242 break;
14243 case OPC_MTHLIP:
14244 tcg_gen_movi_tl(t0, ret);
14245 gen_helper_mthlip(t0, v1_t, cpu_env);
14246 break;
14247 case OPC_WRDSP:
14248 imm = (ctx->opcode >> 11) & 0x3FF;
14249 tcg_gen_movi_tl(t0, imm);
14250 gen_helper_wrdsp(v1_t, t0, cpu_env);
14251 break;
14252 case OPC_RDDSP:
14253 imm = (ctx->opcode >> 16) & 0x03FF;
14254 tcg_gen_movi_tl(t0, imm);
14255 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14256 break;
14257 }
14258 break;
14259#ifdef TARGET_MIPS64
14260 case OPC_DEXTR_W_DSP:
14261 check_dsp(ctx);
14262 switch (op2) {
14263 case OPC_DMTHLIP:
14264 tcg_gen_movi_tl(t0, ret);
14265 gen_helper_dmthlip(v1_t, t0, cpu_env);
14266 break;
14267 case OPC_DSHILO:
14268 {
14269 int shift = (ctx->opcode >> 19) & 0x7F;
14270 int ac = (ctx->opcode >> 11) & 0x03;
14271 tcg_gen_movi_tl(t0, shift);
14272 tcg_gen_movi_tl(t1, ac);
14273 gen_helper_dshilo(t0, t1, cpu_env);
14274 break;
14275 }
14276 case OPC_DSHILOV:
14277 {
14278 int ac = (ctx->opcode >> 11) & 0x03;
14279 tcg_gen_movi_tl(t0, ac);
14280 gen_helper_dshilo(v1_t, t0, cpu_env);
14281 break;
14282 }
14283 case OPC_DEXTP:
14284 tcg_gen_movi_tl(t0, v2);
14285 tcg_gen_movi_tl(t1, v1);
14286
14287 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14288 break;
14289 case OPC_DEXTPV:
14290 tcg_gen_movi_tl(t0, v2);
14291 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14292 break;
14293 case OPC_DEXTPDP:
14294 tcg_gen_movi_tl(t0, v2);
14295 tcg_gen_movi_tl(t1, v1);
14296 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14297 break;
14298 case OPC_DEXTPDPV:
14299 tcg_gen_movi_tl(t0, v2);
14300 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14301 break;
14302 case OPC_DEXTR_L:
14303 tcg_gen_movi_tl(t0, v2);
14304 tcg_gen_movi_tl(t1, v1);
14305 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14306 break;
14307 case OPC_DEXTR_R_L:
14308 tcg_gen_movi_tl(t0, v2);
14309 tcg_gen_movi_tl(t1, v1);
14310 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14311 break;
14312 case OPC_DEXTR_RS_L:
14313 tcg_gen_movi_tl(t0, v2);
14314 tcg_gen_movi_tl(t1, v1);
14315 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14316 break;
14317 case OPC_DEXTR_W:
14318 tcg_gen_movi_tl(t0, v2);
14319 tcg_gen_movi_tl(t1, v1);
14320 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14321 break;
14322 case OPC_DEXTR_R_W:
14323 tcg_gen_movi_tl(t0, v2);
14324 tcg_gen_movi_tl(t1, v1);
14325 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14326 break;
14327 case OPC_DEXTR_RS_W:
14328 tcg_gen_movi_tl(t0, v2);
14329 tcg_gen_movi_tl(t1, v1);
14330 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14331 break;
14332 case OPC_DEXTR_S_H:
14333 tcg_gen_movi_tl(t0, v2);
14334 tcg_gen_movi_tl(t1, v1);
14335 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14336 break;
14337 case OPC_DEXTRV_S_H:
14338 tcg_gen_movi_tl(t0, v2);
14339 tcg_gen_movi_tl(t1, v1);
14340 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14341 break;
14342 case OPC_DEXTRV_L:
14343 tcg_gen_movi_tl(t0, v2);
14344 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14345 break;
14346 case OPC_DEXTRV_R_L:
14347 tcg_gen_movi_tl(t0, v2);
14348 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14349 break;
14350 case OPC_DEXTRV_RS_L:
14351 tcg_gen_movi_tl(t0, v2);
14352 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14353 break;
14354 case OPC_DEXTRV_W:
14355 tcg_gen_movi_tl(t0, v2);
14356 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14357 break;
14358 case OPC_DEXTRV_R_W:
14359 tcg_gen_movi_tl(t0, v2);
14360 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14361 break;
14362 case OPC_DEXTRV_RS_W:
14363 tcg_gen_movi_tl(t0, v2);
14364 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14365 break;
14366 }
14367 break;
14368#endif
14369 }
14370
14371 tcg_temp_free(t0);
14372 tcg_temp_free(t1);
14373 tcg_temp_free(v1_t);
14374 tcg_temp_free(v2_t);
14375
14376 (void)opn; /* avoid a compiler warning */
14377 MIPS_DEBUG("%s", opn);
14378}
14379
9b1a1d68
JL
14380/* End MIPSDSP functions. */
14381
7db13fae 14382static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
14383{
14384 int32_t offset;
14385 int rs, rt, rd, sa;
14386 uint32_t op, op1, op2;
14387 int16_t imm;
14388
14389 /* make sure instructions are on a word boundary */
14390 if (ctx->pc & 0x3) {
14391 env->CP0_BadVAddr = ctx->pc;
14392 generate_exception(ctx, EXCP_AdEL);
14393 return;
14394 }
14395
14396 /* Handle blikely not taken case */
14397 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14398 int l1 = gen_new_label();
14399
14400 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14401 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14402 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14403 gen_goto_tb(ctx, 1, ctx->pc + 4);
14404 gen_set_label(l1);
14405 }
14406
fdefe51c 14407 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14408 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14409 }
3c824109
NF
14410
14411 op = MASK_OP_MAJOR(ctx->opcode);
14412 rs = (ctx->opcode >> 21) & 0x1f;
14413 rt = (ctx->opcode >> 16) & 0x1f;
14414 rd = (ctx->opcode >> 11) & 0x1f;
14415 sa = (ctx->opcode >> 6) & 0x1f;
14416 imm = (int16_t)ctx->opcode;
14417 switch (op) {
7a387fff
TS
14418 case OPC_SPECIAL:
14419 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14420 switch (op1) {
324d9e32
AJ
14421 case OPC_SLL: /* Shift with immediate */
14422 case OPC_SRA:
d75c135e 14423 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14424 break;
ea63e2c3
NF
14425 case OPC_SRL:
14426 switch ((ctx->opcode >> 21) & 0x1f) {
14427 case 1:
14428 /* rotr is decoded as srl on non-R2 CPUs */
d75c135e 14429 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14430 op1 = OPC_ROTR;
14431 }
14432 /* Fallthrough */
14433 case 0:
d75c135e 14434 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14435 break;
14436 default:
14437 generate_exception(ctx, EXCP_RI);
14438 break;
14439 }
14440 break;
460f00c4
AJ
14441 case OPC_MOVN: /* Conditional move */
14442 case OPC_MOVZ:
d75c135e 14443 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
aa8f4009 14444 INSN_LOONGSON2E | INSN_LOONGSON2F);
d75c135e 14445 gen_cond_move(ctx, op1, rd, rs, rt);
460f00c4
AJ
14446 break;
14447 case OPC_ADD ... OPC_SUBU:
d75c135e 14448 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14449 break;
460f00c4 14450 case OPC_SLLV: /* Shifts */
460f00c4 14451 case OPC_SRAV:
d75c135e 14452 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14453 break;
ea63e2c3
NF
14454 case OPC_SRLV:
14455 switch ((ctx->opcode >> 6) & 0x1f) {
14456 case 1:
14457 /* rotrv is decoded as srlv on non-R2 CPUs */
d75c135e 14458 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14459 op1 = OPC_ROTRV;
14460 }
14461 /* Fallthrough */
14462 case 0:
d75c135e 14463 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14464 break;
14465 default:
14466 generate_exception(ctx, EXCP_RI);
14467 break;
14468 }
14469 break;
460f00c4
AJ
14470 case OPC_SLT: /* Set on less than */
14471 case OPC_SLTU:
d75c135e 14472 gen_slt(ctx, op1, rd, rs, rt);
460f00c4
AJ
14473 break;
14474 case OPC_AND: /* Logic*/
14475 case OPC_OR:
14476 case OPC_NOR:
14477 case OPC_XOR:
d75c135e 14478 gen_logic(ctx, op1, rd, rs, rt);
460f00c4 14479 break;
7a387fff 14480 case OPC_MULT ... OPC_DIVU:
e9c71dd1 14481 if (sa) {
d75c135e 14482 check_insn(ctx, INSN_VR54XX);
e9c71dd1
TS
14483 op1 = MASK_MUL_VR54XX(ctx->opcode);
14484 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14485 } else
14486 gen_muldiv(ctx, op1, rs, rt);
7a387fff
TS
14487 break;
14488 case OPC_JR ... OPC_JALR:
7dca4ad0 14489 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061
NF
14490 *is_branch = 1;
14491 break;
7a387fff
TS
14492 case OPC_TGE ... OPC_TEQ: /* Traps */
14493 case OPC_TNE:
14494 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14495 break;
7a387fff
TS
14496 case OPC_MFHI: /* Move from HI/LO */
14497 case OPC_MFLO:
14498 gen_HILO(ctx, op1, rd);
6af0bf9c 14499 break;
7a387fff
TS
14500 case OPC_MTHI:
14501 case OPC_MTLO: /* Move to HI/LO */
14502 gen_HILO(ctx, op1, rs);
6af0bf9c 14503 break;
b48cfdff
TS
14504 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14505#ifdef MIPS_STRICT_STANDARD
14506 MIPS_INVAL("PMON / selsl");
14507 generate_exception(ctx, EXCP_RI);
14508#else
895c2d04 14509 gen_helper_0e0i(pmon, sa);
b48cfdff 14510#endif
7a387fff
TS
14511 break;
14512 case OPC_SYSCALL:
6af0bf9c 14513 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14514 ctx->bstate = BS_STOP;
6af0bf9c 14515 break;
7a387fff 14516 case OPC_BREAK:
6af0bf9c
FB
14517 generate_exception(ctx, EXCP_BREAK);
14518 break;
b48cfdff
TS
14519 case OPC_SPIM:
14520#ifdef MIPS_STRICT_STANDARD
14521 MIPS_INVAL("SPIM");
14522 generate_exception(ctx, EXCP_RI);
14523#else
7a387fff
TS
14524 /* Implemented as RI exception for now. */
14525 MIPS_INVAL("spim (unofficial)");
14526 generate_exception(ctx, EXCP_RI);
b48cfdff 14527#endif
6af0bf9c 14528 break;
7a387fff 14529 case OPC_SYNC:
ead9360e 14530 /* Treat as NOP. */
6af0bf9c 14531 break;
4ad40f36 14532
7a387fff 14533 case OPC_MOVCI:
d75c135e 14534 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14535 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14536 check_cp1_enabled(ctx);
36d23958
TS
14537 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14538 (ctx->opcode >> 16) & 1);
14539 } else {
e397ee33 14540 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14541 }
4ad40f36
FB
14542 break;
14543
d26bc211 14544#if defined(TARGET_MIPS64)
7a387fff
TS
14545 /* MIPS64 specific opcodes */
14546 case OPC_DSLL:
324d9e32 14547 case OPC_DSRA:
7a387fff 14548 case OPC_DSLL32:
324d9e32 14549 case OPC_DSRA32:
d75c135e 14550 check_insn(ctx, ISA_MIPS3);
e189e748 14551 check_mips_64(ctx);
d75c135e 14552 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14553 break;
ea63e2c3
NF
14554 case OPC_DSRL:
14555 switch ((ctx->opcode >> 21) & 0x1f) {
14556 case 1:
14557 /* drotr is decoded as dsrl on non-R2 CPUs */
d75c135e 14558 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14559 op1 = OPC_DROTR;
14560 }
14561 /* Fallthrough */
14562 case 0:
d75c135e 14563 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14564 check_mips_64(ctx);
d75c135e 14565 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14566 break;
14567 default:
14568 generate_exception(ctx, EXCP_RI);
14569 break;
14570 }
14571 break;
14572 case OPC_DSRL32:
14573 switch ((ctx->opcode >> 21) & 0x1f) {
14574 case 1:
14575 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
d75c135e 14576 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14577 op1 = OPC_DROTR32;
14578 }
14579 /* Fallthrough */
14580 case 0:
d75c135e 14581 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14582 check_mips_64(ctx);
d75c135e 14583 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3
NF
14584 break;
14585 default:
14586 generate_exception(ctx, EXCP_RI);
14587 break;
14588 }
14589 break;
7a387fff 14590 case OPC_DADD ... OPC_DSUBU:
d75c135e 14591 check_insn(ctx, ISA_MIPS3);
e189e748 14592 check_mips_64(ctx);
d75c135e 14593 gen_arith(ctx, op1, rd, rs, rt);
7a387fff 14594 break;
460f00c4
AJ
14595 case OPC_DSLLV:
14596 case OPC_DSRAV:
d75c135e 14597 check_insn(ctx, ISA_MIPS3);
460f00c4 14598 check_mips_64(ctx);
d75c135e 14599 gen_shift(ctx, op1, rd, rs, rt);
460f00c4 14600 break;
ea63e2c3
NF
14601 case OPC_DSRLV:
14602 switch ((ctx->opcode >> 6) & 0x1f) {
14603 case 1:
14604 /* drotrv is decoded as dsrlv on non-R2 CPUs */
d75c135e 14605 if (ctx->insn_flags & ISA_MIPS32R2) {
ea63e2c3
NF
14606 op1 = OPC_DROTRV;
14607 }
14608 /* Fallthrough */
14609 case 0:
d75c135e 14610 check_insn(ctx, ISA_MIPS3);
ea63e2c3 14611 check_mips_64(ctx);
d75c135e 14612 gen_shift(ctx, op1, rd, rs, rt);
ea63e2c3
NF
14613 break;
14614 default:
14615 generate_exception(ctx, EXCP_RI);
14616 break;
14617 }
14618 break;
7a387fff 14619 case OPC_DMULT ... OPC_DDIVU:
d75c135e 14620 check_insn(ctx, ISA_MIPS3);
e189e748 14621 check_mips_64(ctx);
7a387fff
TS
14622 gen_muldiv(ctx, op1, rs, rt);
14623 break;
6af0bf9c
FB
14624#endif
14625 default: /* Invalid */
14626 MIPS_INVAL("special");
14627 generate_exception(ctx, EXCP_RI);
14628 break;
14629 }
14630 break;
7a387fff
TS
14631 case OPC_SPECIAL2:
14632 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14633 switch (op1) {
7a387fff
TS
14634 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14635 case OPC_MSUB ... OPC_MSUBU:
d75c135e 14636 check_insn(ctx, ISA_MIPS32);
7a387fff 14637 gen_muldiv(ctx, op1, rs, rt);
6af0bf9c 14638 break;
7a387fff 14639 case OPC_MUL:
d75c135e 14640 gen_arith(ctx, op1, rd, rs, rt);
6af0bf9c 14641 break;
20e1fb52
AJ
14642 case OPC_CLO:
14643 case OPC_CLZ:
d75c135e 14644 check_insn(ctx, ISA_MIPS32);
7a387fff 14645 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14646 break;
7a387fff 14647 case OPC_SDBBP:
6af0bf9c
FB
14648 /* XXX: not clear which exception should be raised
14649 * when in debug mode...
14650 */
d75c135e 14651 check_insn(ctx, ISA_MIPS32);
6af0bf9c
FB
14652 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14653 generate_exception(ctx, EXCP_DBp);
14654 } else {
14655 generate_exception(ctx, EXCP_DBp);
14656 }
ead9360e 14657 /* Treat as NOP. */
6af0bf9c 14658 break;
161f85e6
AJ
14659 case OPC_DIV_G_2F:
14660 case OPC_DIVU_G_2F:
14661 case OPC_MULT_G_2F:
14662 case OPC_MULTU_G_2F:
14663 case OPC_MOD_G_2F:
14664 case OPC_MODU_G_2F:
d75c135e 14665 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14666 gen_loongson_integer(ctx, op1, rd, rs, rt);
14667 break;
d26bc211 14668#if defined(TARGET_MIPS64)
20e1fb52
AJ
14669 case OPC_DCLO:
14670 case OPC_DCLZ:
d75c135e 14671 check_insn(ctx, ISA_MIPS64);
e189e748 14672 check_mips_64(ctx);
7a387fff
TS
14673 gen_cl(ctx, op1, rd, rs);
14674 break;
161f85e6
AJ
14675 case OPC_DMULT_G_2F:
14676 case OPC_DMULTU_G_2F:
14677 case OPC_DDIV_G_2F:
14678 case OPC_DDIVU_G_2F:
14679 case OPC_DMOD_G_2F:
14680 case OPC_DMODU_G_2F:
d75c135e 14681 check_insn(ctx, INSN_LOONGSON2F);
161f85e6
AJ
14682 gen_loongson_integer(ctx, op1, rd, rs, rt);
14683 break;
7a387fff 14684#endif
6af0bf9c
FB
14685 default: /* Invalid */
14686 MIPS_INVAL("special2");
14687 generate_exception(ctx, EXCP_RI);
14688 break;
14689 }
14690 break;
7a387fff 14691 case OPC_SPECIAL3:
2b0233ab
TS
14692 op1 = MASK_SPECIAL3(ctx->opcode);
14693 switch (op1) {
14694 case OPC_EXT:
14695 case OPC_INS:
d75c135e 14696 check_insn(ctx, ISA_MIPS32R2);
2b0233ab
TS
14697 gen_bitops(ctx, op1, rt, rs, sa, rd);
14698 break;
14699 case OPC_BSHFL:
d75c135e 14700 check_insn(ctx, ISA_MIPS32R2);
2b0233ab 14701 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14702 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14703 break;
1579a72e 14704 case OPC_RDHWR:
d75c135e 14705 gen_rdhwr(ctx, rt, rd);
1579a72e 14706 break;
ead9360e 14707 case OPC_FORK:
d75c135e 14708 check_insn(ctx, ASE_MT);
6c5c1e20 14709 {
35fbce2c
AJ
14710 TCGv t0 = tcg_temp_new();
14711 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14712
14713 gen_load_gpr(t0, rt);
14714 gen_load_gpr(t1, rs);
a7812ae4 14715 gen_helper_fork(t0, t1);
6c5c1e20
TS
14716 tcg_temp_free(t0);
14717 tcg_temp_free(t1);
14718 }
ead9360e
TS
14719 break;
14720 case OPC_YIELD:
d75c135e 14721 check_insn(ctx, ASE_MT);
6c5c1e20 14722 {
35fbce2c 14723 TCGv t0 = tcg_temp_new();
6c5c1e20 14724
35fbce2c 14725 save_cpu_state(ctx, 1);
6c5c1e20 14726 gen_load_gpr(t0, rs);
895c2d04 14727 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14728 gen_store_gpr(t0, rd);
14729 tcg_temp_free(t0);
14730 }
ead9360e 14731 break;
161f85e6 14732 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14733 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14734 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14735 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14736 * the same mask and op1. */
d75c135e 14737 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
461c08df
JL
14738 op2 = MASK_ADDUH_QB(ctx->opcode);
14739 switch (op2) {
14740 case OPC_ADDUH_QB:
14741 case OPC_ADDUH_R_QB:
14742 case OPC_ADDQH_PH:
14743 case OPC_ADDQH_R_PH:
14744 case OPC_ADDQH_W:
14745 case OPC_ADDQH_R_W:
14746 case OPC_SUBUH_QB:
14747 case OPC_SUBUH_R_QB:
14748 case OPC_SUBQH_PH:
14749 case OPC_SUBQH_R_PH:
14750 case OPC_SUBQH_W:
14751 case OPC_SUBQH_R_W:
14752 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14753 break;
a22260ae
JL
14754 case OPC_MUL_PH:
14755 case OPC_MUL_S_PH:
14756 case OPC_MULQ_S_W:
14757 case OPC_MULQ_RS_W:
14758 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14759 break;
461c08df
JL
14760 default:
14761 MIPS_INVAL("MASK ADDUH.QB");
14762 generate_exception(ctx, EXCP_RI);
14763 break;
14764 }
d75c135e 14765 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
461c08df
JL
14766 gen_loongson_integer(ctx, op1, rd, rs, rt);
14767 } else {
14768 generate_exception(ctx, EXCP_RI);
14769 }
161f85e6 14770 break;
9b1a1d68
JL
14771 case OPC_LX_DSP:
14772 op2 = MASK_LX(ctx->opcode);
14773 switch (op2) {
14774#if defined(TARGET_MIPS64)
14775 case OPC_LDX:
14776#endif
14777 case OPC_LBUX:
14778 case OPC_LHX:
14779 case OPC_LWX:
d75c135e 14780 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
9b1a1d68
JL
14781 break;
14782 default: /* Invalid */
14783 MIPS_INVAL("MASK LX");
14784 generate_exception(ctx, EXCP_RI);
14785 break;
14786 }
14787 break;
461c08df
JL
14788 case OPC_ABSQ_S_PH_DSP:
14789 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14790 switch (op2) {
14791 case OPC_ABSQ_S_QB:
14792 case OPC_ABSQ_S_PH:
14793 case OPC_ABSQ_S_W:
14794 case OPC_PRECEQ_W_PHL:
14795 case OPC_PRECEQ_W_PHR:
14796 case OPC_PRECEQU_PH_QBL:
14797 case OPC_PRECEQU_PH_QBR:
14798 case OPC_PRECEQU_PH_QBLA:
14799 case OPC_PRECEQU_PH_QBRA:
14800 case OPC_PRECEU_PH_QBL:
14801 case OPC_PRECEU_PH_QBR:
14802 case OPC_PRECEU_PH_QBLA:
14803 case OPC_PRECEU_PH_QBRA:
14804 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14805 break;
1cb6686c
JL
14806 case OPC_BITREV:
14807 case OPC_REPL_QB:
14808 case OPC_REPLV_QB:
14809 case OPC_REPL_PH:
14810 case OPC_REPLV_PH:
d75c135e 14811 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 14812 break;
461c08df
JL
14813 default:
14814 MIPS_INVAL("MASK ABSQ_S.PH");
14815 generate_exception(ctx, EXCP_RI);
14816 break;
14817 }
14818 break;
14819 case OPC_ADDU_QB_DSP:
14820 op2 = MASK_ADDU_QB(ctx->opcode);
14821 switch (op2) {
14822 case OPC_ADDQ_PH:
14823 case OPC_ADDQ_S_PH:
14824 case OPC_ADDQ_S_W:
14825 case OPC_ADDU_QB:
14826 case OPC_ADDU_S_QB:
14827 case OPC_ADDU_PH:
14828 case OPC_ADDU_S_PH:
14829 case OPC_SUBQ_PH:
14830 case OPC_SUBQ_S_PH:
14831 case OPC_SUBQ_S_W:
14832 case OPC_SUBU_QB:
14833 case OPC_SUBU_S_QB:
14834 case OPC_SUBU_PH:
14835 case OPC_SUBU_S_PH:
14836 case OPC_ADDSC:
14837 case OPC_ADDWC:
14838 case OPC_MODSUB:
14839 case OPC_RADDU_W_QB:
14840 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14841 break;
a22260ae
JL
14842 case OPC_MULEU_S_PH_QBL:
14843 case OPC_MULEU_S_PH_QBR:
14844 case OPC_MULQ_RS_PH:
14845 case OPC_MULEQ_S_W_PHL:
14846 case OPC_MULEQ_S_W_PHR:
14847 case OPC_MULQ_S_PH:
14848 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14849 break;
461c08df
JL
14850 default: /* Invalid */
14851 MIPS_INVAL("MASK ADDU.QB");
14852 generate_exception(ctx, EXCP_RI);
14853 break;
14854
14855 }
14856 break;
14857 case OPC_CMPU_EQ_QB_DSP:
14858 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14859 switch (op2) {
14860 case OPC_PRECR_SRA_PH_W:
14861 case OPC_PRECR_SRA_R_PH_W:
14862 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14863 break;
14864 case OPC_PRECR_QB_PH:
14865 case OPC_PRECRQ_QB_PH:
14866 case OPC_PRECRQ_PH_W:
14867 case OPC_PRECRQ_RS_PH_W:
14868 case OPC_PRECRQU_S_QB_PH:
14869 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14870 break;
26690560
JL
14871 case OPC_CMPU_EQ_QB:
14872 case OPC_CMPU_LT_QB:
14873 case OPC_CMPU_LE_QB:
14874 case OPC_CMP_EQ_PH:
14875 case OPC_CMP_LT_PH:
14876 case OPC_CMP_LE_PH:
14877 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14878 break;
14879 case OPC_CMPGU_EQ_QB:
14880 case OPC_CMPGU_LT_QB:
14881 case OPC_CMPGU_LE_QB:
14882 case OPC_CMPGDU_EQ_QB:
14883 case OPC_CMPGDU_LT_QB:
14884 case OPC_CMPGDU_LE_QB:
14885 case OPC_PICK_QB:
14886 case OPC_PICK_PH:
14887 case OPC_PACKRL_PH:
14888 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14889 break;
461c08df
JL
14890 default: /* Invalid */
14891 MIPS_INVAL("MASK CMPU.EQ.QB");
14892 generate_exception(ctx, EXCP_RI);
14893 break;
14894 }
14895 break;
77c5fa8b
JL
14896 case OPC_SHLL_QB_DSP:
14897 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14898 break;
a22260ae
JL
14899 case OPC_DPA_W_PH_DSP:
14900 op2 = MASK_DPA_W_PH(ctx->opcode);
14901 switch (op2) {
14902 case OPC_DPAU_H_QBL:
14903 case OPC_DPAU_H_QBR:
14904 case OPC_DPSU_H_QBL:
14905 case OPC_DPSU_H_QBR:
14906 case OPC_DPA_W_PH:
14907 case OPC_DPAX_W_PH:
14908 case OPC_DPAQ_S_W_PH:
14909 case OPC_DPAQX_S_W_PH:
14910 case OPC_DPAQX_SA_W_PH:
14911 case OPC_DPS_W_PH:
14912 case OPC_DPSX_W_PH:
14913 case OPC_DPSQ_S_W_PH:
14914 case OPC_DPSQX_S_W_PH:
14915 case OPC_DPSQX_SA_W_PH:
14916 case OPC_MULSAQ_S_W_PH:
14917 case OPC_DPAQ_SA_L_W:
14918 case OPC_DPSQ_SA_L_W:
14919 case OPC_MAQ_S_W_PHL:
14920 case OPC_MAQ_S_W_PHR:
14921 case OPC_MAQ_SA_W_PHL:
14922 case OPC_MAQ_SA_W_PHR:
14923 case OPC_MULSA_W_PH:
14924 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14925 break;
14926 default: /* Invalid */
14927 MIPS_INVAL("MASK DPAW.PH");
14928 generate_exception(ctx, EXCP_RI);
14929 break;
14930 }
14931 break;
1cb6686c
JL
14932 case OPC_INSV_DSP:
14933 op2 = MASK_INSV(ctx->opcode);
14934 switch (op2) {
14935 case OPC_INSV:
14936 check_dsp(ctx);
14937 {
14938 TCGv t0, t1;
14939
14940 if (rt == 0) {
14941 MIPS_DEBUG("NOP");
14942 break;
14943 }
14944
14945 t0 = tcg_temp_new();
14946 t1 = tcg_temp_new();
14947
14948 gen_load_gpr(t0, rt);
14949 gen_load_gpr(t1, rs);
14950
14951 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14952
14953 tcg_temp_free(t0);
14954 tcg_temp_free(t1);
14955 break;
14956 }
14957 default: /* Invalid */
14958 MIPS_INVAL("MASK INSV");
14959 generate_exception(ctx, EXCP_RI);
14960 break;
14961 }
14962 break;
26690560 14963 case OPC_APPEND_DSP:
df6126a7 14964 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 14965 break;
b53371ed
JL
14966 case OPC_EXTR_W_DSP:
14967 op2 = MASK_EXTR_W(ctx->opcode);
14968 switch (op2) {
14969 case OPC_EXTR_W:
14970 case OPC_EXTR_R_W:
14971 case OPC_EXTR_RS_W:
14972 case OPC_EXTR_S_H:
14973 case OPC_EXTRV_S_H:
14974 case OPC_EXTRV_W:
14975 case OPC_EXTRV_R_W:
14976 case OPC_EXTRV_RS_W:
14977 case OPC_EXTP:
14978 case OPC_EXTPV:
14979 case OPC_EXTPDP:
14980 case OPC_EXTPDPV:
14981 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14982 break;
14983 case OPC_RDDSP:
14984 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14985 break;
14986 case OPC_SHILO:
14987 case OPC_SHILOV:
14988 case OPC_MTHLIP:
14989 case OPC_WRDSP:
14990 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14991 break;
14992 default: /* Invalid */
14993 MIPS_INVAL("MASK EXTR.W");
14994 generate_exception(ctx, EXCP_RI);
14995 break;
14996 }
14997 break;
d26bc211 14998#if defined(TARGET_MIPS64)
1579a72e
TS
14999 case OPC_DEXTM ... OPC_DEXT:
15000 case OPC_DINSM ... OPC_DINS:
d75c135e 15001 check_insn(ctx, ISA_MIPS64R2);
e189e748 15002 check_mips_64(ctx);
1579a72e 15003 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 15004 break;
1579a72e 15005 case OPC_DBSHFL:
d75c135e 15006 check_insn(ctx, ISA_MIPS64R2);
e189e748 15007 check_mips_64(ctx);
1579a72e 15008 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 15009 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 15010 break;
161f85e6
AJ
15011 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15012 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15013 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
d75c135e 15014 check_insn(ctx, INSN_LOONGSON2E);
161f85e6
AJ
15015 gen_loongson_integer(ctx, op1, rd, rs, rt);
15016 break;
461c08df
JL
15017 case OPC_ABSQ_S_QH_DSP:
15018 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15019 switch (op2) {
15020 case OPC_PRECEQ_L_PWL:
15021 case OPC_PRECEQ_L_PWR:
15022 case OPC_PRECEQ_PW_QHL:
15023 case OPC_PRECEQ_PW_QHR:
15024 case OPC_PRECEQ_PW_QHLA:
15025 case OPC_PRECEQ_PW_QHRA:
15026 case OPC_PRECEQU_QH_OBL:
15027 case OPC_PRECEQU_QH_OBR:
15028 case OPC_PRECEQU_QH_OBLA:
15029 case OPC_PRECEQU_QH_OBRA:
15030 case OPC_PRECEU_QH_OBL:
15031 case OPC_PRECEU_QH_OBR:
15032 case OPC_PRECEU_QH_OBLA:
15033 case OPC_PRECEU_QH_OBRA:
15034 case OPC_ABSQ_S_OB:
15035 case OPC_ABSQ_S_PW:
15036 case OPC_ABSQ_S_QH:
15037 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15038 break;
1cb6686c
JL
15039 case OPC_REPL_OB:
15040 case OPC_REPL_PW:
15041 case OPC_REPL_QH:
15042 case OPC_REPLV_OB:
15043 case OPC_REPLV_PW:
15044 case OPC_REPLV_QH:
d75c135e 15045 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
1cb6686c 15046 break;
461c08df
JL
15047 default: /* Invalid */
15048 MIPS_INVAL("MASK ABSQ_S.QH");
15049 generate_exception(ctx, EXCP_RI);
15050 break;
15051 }
15052 break;
15053 case OPC_ADDU_OB_DSP:
15054 op2 = MASK_ADDU_OB(ctx->opcode);
15055 switch (op2) {
15056 case OPC_RADDU_L_OB:
15057 case OPC_SUBQ_PW:
15058 case OPC_SUBQ_S_PW:
15059 case OPC_SUBQ_QH:
15060 case OPC_SUBQ_S_QH:
15061 case OPC_SUBU_OB:
15062 case OPC_SUBU_S_OB:
15063 case OPC_SUBU_QH:
15064 case OPC_SUBU_S_QH:
15065 case OPC_SUBUH_OB:
15066 case OPC_SUBUH_R_OB:
15067 case OPC_ADDQ_PW:
15068 case OPC_ADDQ_S_PW:
15069 case OPC_ADDQ_QH:
15070 case OPC_ADDQ_S_QH:
15071 case OPC_ADDU_OB:
15072 case OPC_ADDU_S_OB:
15073 case OPC_ADDU_QH:
15074 case OPC_ADDU_S_QH:
15075 case OPC_ADDUH_OB:
15076 case OPC_ADDUH_R_OB:
15077 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15078 break;
a22260ae
JL
15079 case OPC_MULEQ_S_PW_QHL:
15080 case OPC_MULEQ_S_PW_QHR:
15081 case OPC_MULEU_S_QH_OBL:
15082 case OPC_MULEU_S_QH_OBR:
15083 case OPC_MULQ_RS_QH:
15084 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15085 break;
461c08df
JL
15086 default: /* Invalid */
15087 MIPS_INVAL("MASK ADDU.OB");
15088 generate_exception(ctx, EXCP_RI);
15089 break;
15090 }
15091 break;
15092 case OPC_CMPU_EQ_OB_DSP:
15093 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15094 switch (op2) {
15095 case OPC_PRECR_SRA_QH_PW:
15096 case OPC_PRECR_SRA_R_QH_PW:
15097 /* Return value is rt. */
15098 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15099 break;
15100 case OPC_PRECR_OB_QH:
15101 case OPC_PRECRQ_OB_QH:
15102 case OPC_PRECRQ_PW_L:
15103 case OPC_PRECRQ_QH_PW:
15104 case OPC_PRECRQ_RS_QH_PW:
15105 case OPC_PRECRQU_S_OB_QH:
15106 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15107 break;
26690560
JL
15108 case OPC_CMPU_EQ_OB:
15109 case OPC_CMPU_LT_OB:
15110 case OPC_CMPU_LE_OB:
15111 case OPC_CMP_EQ_QH:
15112 case OPC_CMP_LT_QH:
15113 case OPC_CMP_LE_QH:
15114 case OPC_CMP_EQ_PW:
15115 case OPC_CMP_LT_PW:
15116 case OPC_CMP_LE_PW:
15117 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15118 break;
15119 case OPC_CMPGDU_EQ_OB:
15120 case OPC_CMPGDU_LT_OB:
15121 case OPC_CMPGDU_LE_OB:
15122 case OPC_CMPGU_EQ_OB:
15123 case OPC_CMPGU_LT_OB:
15124 case OPC_CMPGU_LE_OB:
15125 case OPC_PACKRL_PW:
15126 case OPC_PICK_OB:
15127 case OPC_PICK_PW:
15128 case OPC_PICK_QH:
15129 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15130 break;
461c08df
JL
15131 default: /* Invalid */
15132 MIPS_INVAL("MASK CMPU_EQ.OB");
15133 generate_exception(ctx, EXCP_RI);
15134 break;
15135 }
15136 break;
26690560 15137 case OPC_DAPPEND_DSP:
df6126a7 15138 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26690560 15139 break;
b53371ed
JL
15140 case OPC_DEXTR_W_DSP:
15141 op2 = MASK_DEXTR_W(ctx->opcode);
15142 switch (op2) {
15143 case OPC_DEXTP:
15144 case OPC_DEXTPDP:
15145 case OPC_DEXTPDPV:
15146 case OPC_DEXTPV:
15147 case OPC_DEXTR_L:
15148 case OPC_DEXTR_R_L:
15149 case OPC_DEXTR_RS_L:
15150 case OPC_DEXTR_W:
15151 case OPC_DEXTR_R_W:
15152 case OPC_DEXTR_RS_W:
15153 case OPC_DEXTR_S_H:
15154 case OPC_DEXTRV_L:
15155 case OPC_DEXTRV_R_L:
15156 case OPC_DEXTRV_RS_L:
15157 case OPC_DEXTRV_S_H:
15158 case OPC_DEXTRV_W:
15159 case OPC_DEXTRV_R_W:
15160 case OPC_DEXTRV_RS_W:
15161 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15162 break;
15163 case OPC_DMTHLIP:
15164 case OPC_DSHILO:
15165 case OPC_DSHILOV:
15166 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15167 break;
15168 default: /* Invalid */
15169 MIPS_INVAL("MASK EXTR.W");
15170 generate_exception(ctx, EXCP_RI);
15171 break;
15172 }
15173 break;
a22260ae
JL
15174 case OPC_DPAQ_W_QH_DSP:
15175 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15176 switch (op2) {
15177 case OPC_DPAU_H_OBL:
15178 case OPC_DPAU_H_OBR:
15179 case OPC_DPSU_H_OBL:
15180 case OPC_DPSU_H_OBR:
15181 case OPC_DPA_W_QH:
15182 case OPC_DPAQ_S_W_QH:
15183 case OPC_DPS_W_QH:
15184 case OPC_DPSQ_S_W_QH:
15185 case OPC_MULSAQ_S_W_QH:
15186 case OPC_DPAQ_SA_L_PW:
15187 case OPC_DPSQ_SA_L_PW:
15188 case OPC_MULSAQ_S_L_PW:
15189 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15190 break;
15191 case OPC_MAQ_S_W_QHLL:
15192 case OPC_MAQ_S_W_QHLR:
15193 case OPC_MAQ_S_W_QHRL:
15194 case OPC_MAQ_S_W_QHRR:
15195 case OPC_MAQ_SA_W_QHLL:
15196 case OPC_MAQ_SA_W_QHLR:
15197 case OPC_MAQ_SA_W_QHRL:
15198 case OPC_MAQ_SA_W_QHRR:
15199 case OPC_MAQ_S_L_PWL:
15200 case OPC_MAQ_S_L_PWR:
15201 case OPC_DMADD:
15202 case OPC_DMADDU:
15203 case OPC_DMSUB:
15204 case OPC_DMSUBU:
15205 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15206 break;
15207 default: /* Invalid */
15208 MIPS_INVAL("MASK DPAQ.W.QH");
15209 generate_exception(ctx, EXCP_RI);
15210 break;
15211 }
15212 break;
1cb6686c
JL
15213 case OPC_DINSV_DSP:
15214 op2 = MASK_INSV(ctx->opcode);
15215 switch (op2) {
15216 case OPC_DINSV:
15217 {
15218 TCGv t0, t1;
15219
15220 if (rt == 0) {
15221 MIPS_DEBUG("NOP");
15222 break;
15223 }
15224 check_dsp(ctx);
15225
15226 t0 = tcg_temp_new();
15227 t1 = tcg_temp_new();
15228
15229 gen_load_gpr(t0, rt);
15230 gen_load_gpr(t1, rs);
15231
15232 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15233 break;
15234 }
15235 default: /* Invalid */
15236 MIPS_INVAL("MASK DINSV");
15237 generate_exception(ctx, EXCP_RI);
15238 break;
15239 }
15240 break;
77c5fa8b
JL
15241 case OPC_SHLL_OB_DSP:
15242 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15243 break;
7a387fff
TS
15244#endif
15245 default: /* Invalid */
15246 MIPS_INVAL("special3");
15247 generate_exception(ctx, EXCP_RI);
15248 break;
15249 }
15250 break;
15251 case OPC_REGIMM:
15252 op1 = MASK_REGIMM(ctx->opcode);
15253 switch (op1) {
15254 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15255 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15256 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061
NF
15257 *is_branch = 1;
15258 break;
7a387fff
TS
15259 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15260 case OPC_TNEI:
15261 gen_trap(ctx, op1, rs, -1, imm);
15262 break;
15263 case OPC_SYNCI:
d75c135e 15264 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15265 /* Treat as NOP. */
6af0bf9c 15266 break;
e45a93e2
JL
15267 case OPC_BPOSGE32: /* MIPS DSP branch */
15268#if defined(TARGET_MIPS64)
15269 case OPC_BPOSGE64:
15270#endif
15271 check_dsp(ctx);
15272 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15273 *is_branch = 1;
15274 break;
6af0bf9c 15275 default: /* Invalid */
923617a3 15276 MIPS_INVAL("regimm");
6af0bf9c
FB
15277 generate_exception(ctx, EXCP_RI);
15278 break;
15279 }
15280 break;
7a387fff 15281 case OPC_CP0:
387a8fe5 15282 check_cp0_enabled(ctx);
7a387fff 15283 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15284 switch (op1) {
7a387fff
TS
15285 case OPC_MFC0:
15286 case OPC_MTC0:
ead9360e
TS
15287 case OPC_MFTR:
15288 case OPC_MTTR:
d26bc211 15289#if defined(TARGET_MIPS64)
7a387fff
TS
15290 case OPC_DMFC0:
15291 case OPC_DMTC0:
15292#endif
f1aa6320 15293#ifndef CONFIG_USER_ONLY
932e71cd 15294 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15295#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15296 break;
15297 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15298#ifndef CONFIG_USER_ONLY
932e71cd 15299 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15300#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15301 break;
15302 case OPC_MFMC0:
8706c382 15303#ifndef CONFIG_USER_ONLY
932e71cd 15304 {
35fbce2c 15305 TCGv t0 = tcg_temp_new();
6c5c1e20 15306
0eaef5aa 15307 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15308 switch (op2) {
15309 case OPC_DMT:
d75c135e 15310 check_insn(ctx, ASE_MT);
9ed5726c 15311 gen_helper_dmt(t0);
35fbce2c 15312 gen_store_gpr(t0, rt);
6c5c1e20
TS
15313 break;
15314 case OPC_EMT:
d75c135e 15315 check_insn(ctx, ASE_MT);
9ed5726c 15316 gen_helper_emt(t0);
35fbce2c 15317 gen_store_gpr(t0, rt);
da80682b 15318 break;
6c5c1e20 15319 case OPC_DVPE:
d75c135e 15320 check_insn(ctx, ASE_MT);
895c2d04 15321 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15322 gen_store_gpr(t0, rt);
6c5c1e20
TS
15323 break;
15324 case OPC_EVPE:
d75c135e 15325 check_insn(ctx, ASE_MT);
895c2d04 15326 gen_helper_evpe(t0, cpu_env);
35fbce2c 15327 gen_store_gpr(t0, rt);
6c5c1e20
TS
15328 break;
15329 case OPC_DI:
d75c135e 15330 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15331 save_cpu_state(ctx, 1);
895c2d04 15332 gen_helper_di(t0, cpu_env);
35fbce2c 15333 gen_store_gpr(t0, rt);
6c5c1e20
TS
15334 /* Stop translation as we may have switched the execution mode */
15335 ctx->bstate = BS_STOP;
15336 break;
15337 case OPC_EI:
d75c135e 15338 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15339 save_cpu_state(ctx, 1);
895c2d04 15340 gen_helper_ei(t0, cpu_env);
35fbce2c 15341 gen_store_gpr(t0, rt);
6c5c1e20
TS
15342 /* Stop translation as we may have switched the execution mode */
15343 ctx->bstate = BS_STOP;
15344 break;
15345 default: /* Invalid */
15346 MIPS_INVAL("mfmc0");
15347 generate_exception(ctx, EXCP_RI);
15348 break;
15349 }
6c5c1e20 15350 tcg_temp_free(t0);
7a387fff 15351 }
0eaef5aa 15352#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15353 break;
7a387fff 15354 case OPC_RDPGPR:
d75c135e 15355 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15356 gen_load_srsgpr(rt, rd);
ead9360e 15357 break;
7a387fff 15358 case OPC_WRPGPR:
d75c135e 15359 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15360 gen_store_srsgpr(rt, rd);
38121543 15361 break;
6af0bf9c 15362 default:
923617a3 15363 MIPS_INVAL("cp0");
7a387fff 15364 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15365 break;
15366 }
15367 break;
324d9e32
AJ
15368 case OPC_ADDI: /* Arithmetic with immediate opcode */
15369 case OPC_ADDIU:
d75c135e 15370 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15371 break;
324d9e32
AJ
15372 case OPC_SLTI: /* Set on less than with immediate opcode */
15373 case OPC_SLTIU:
d75c135e 15374 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15375 break;
15376 case OPC_ANDI: /* Arithmetic with immediate opcode */
15377 case OPC_LUI:
15378 case OPC_ORI:
15379 case OPC_XORI:
d75c135e 15380 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15381 break;
7a387fff
TS
15382 case OPC_J ... OPC_JAL: /* Jump */
15383 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15384 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061
NF
15385 *is_branch = 1;
15386 break;
7a387fff
TS
15387 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15388 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15389 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061
NF
15390 *is_branch = 1;
15391 break;
7a387fff 15392 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15393 case OPC_LL:
d75c135e 15394 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15395 break;
7a387fff
TS
15396 case OPC_SB ... OPC_SW:
15397 case OPC_SWR:
5c13fdfd 15398 gen_st(ctx, op, rt, rs, imm);
7a387fff 15399 break;
d66c7132
AJ
15400 case OPC_SC:
15401 gen_st_cond(ctx, op, rt, rs, imm);
15402 break;
7a387fff 15403 case OPC_CACHE:
2e15497c 15404 check_cp0_enabled(ctx);
d75c135e 15405 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15406 /* Treat as NOP. */
34ae7b51 15407 break;
7a387fff 15408 case OPC_PREF:
d75c135e 15409 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15410 /* Treat as NOP. */
6af0bf9c 15411 break;
4ad40f36 15412
923617a3 15413 /* Floating point (COP1). */
7a387fff
TS
15414 case OPC_LWC1:
15415 case OPC_LDC1:
15416 case OPC_SWC1:
15417 case OPC_SDC1:
26ebe468 15418 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15419 break;
15420
7a387fff 15421 case OPC_CP1:
36d23958 15422 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15423 check_cp1_enabled(ctx);
36d23958
TS
15424 op1 = MASK_CP1(ctx->opcode);
15425 switch (op1) {
3a95e3a7
TS
15426 case OPC_MFHC1:
15427 case OPC_MTHC1:
d75c135e 15428 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
15429 case OPC_MFC1:
15430 case OPC_CFC1:
15431 case OPC_MTC1:
15432 case OPC_CTC1:
e189e748
TS
15433 gen_cp1(ctx, op1, rt, rd);
15434 break;
d26bc211 15435#if defined(TARGET_MIPS64)
36d23958
TS
15436 case OPC_DMFC1:
15437 case OPC_DMTC1:
d75c135e 15438 check_insn(ctx, ISA_MIPS3);
36d23958
TS
15439 gen_cp1(ctx, op1, rt, rd);
15440 break;
e189e748 15441#endif
fbcc6828
TS
15442 case OPC_BC1ANY2:
15443 case OPC_BC1ANY4:
b8aa4598 15444 check_cop1x(ctx);
d75c135e 15445 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
15446 /* fall through */
15447 case OPC_BC1:
d75c135e 15448 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15449 (rt >> 2) & 0x7, imm << 2);
c9602061
NF
15450 *is_branch = 1;
15451 break;
36d23958
TS
15452 case OPC_S_FMT:
15453 case OPC_D_FMT:
15454 case OPC_W_FMT:
15455 case OPC_L_FMT:
5a5012ec 15456 case OPC_PS_FMT:
bf4120ad 15457 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15458 (imm >> 8) & 0x7);
36d23958
TS
15459 break;
15460 default:
923617a3 15461 MIPS_INVAL("cp1");
e397ee33 15462 generate_exception (ctx, EXCP_RI);
36d23958
TS
15463 break;
15464 }
15465 } else {
15466 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15467 }
4ad40f36
FB
15468 break;
15469
15470 /* COP2. */
7a387fff
TS
15471 case OPC_LWC2:
15472 case OPC_LDC2:
15473 case OPC_SWC2:
15474 case OPC_SDC2:
7a387fff 15475 /* COP2: Not implemented. */
4ad40f36
FB
15476 generate_exception_err(ctx, EXCP_CpU, 2);
15477 break;
bd277fa1 15478 case OPC_CP2:
d75c135e 15479 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
15480 /* Note that these instructions use different fields. */
15481 gen_loongson_multimedia(ctx, sa, rd, rt);
15482 break;
4ad40f36 15483
7a387fff 15484 case OPC_CP3:
36d23958 15485 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15486 check_cp1_enabled(ctx);
36d23958
TS
15487 op1 = MASK_CP3(ctx->opcode);
15488 switch (op1) {
5a5012ec
TS
15489 case OPC_LWXC1:
15490 case OPC_LDXC1:
15491 case OPC_LUXC1:
15492 case OPC_SWXC1:
15493 case OPC_SDXC1:
15494 case OPC_SUXC1:
93b12ccc 15495 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15496 break;
e0c84da7 15497 case OPC_PREFX:
ead9360e 15498 /* Treat as NOP. */
e0c84da7 15499 break;
5a5012ec
TS
15500 case OPC_ALNV_PS:
15501 case OPC_MADD_S:
15502 case OPC_MADD_D:
15503 case OPC_MADD_PS:
15504 case OPC_MSUB_S:
15505 case OPC_MSUB_D:
15506 case OPC_MSUB_PS:
15507 case OPC_NMADD_S:
15508 case OPC_NMADD_D:
15509 case OPC_NMADD_PS:
15510 case OPC_NMSUB_S:
15511 case OPC_NMSUB_D:
15512 case OPC_NMSUB_PS:
15513 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15514 break;
36d23958 15515 default:
923617a3 15516 MIPS_INVAL("cp3");
e397ee33 15517 generate_exception (ctx, EXCP_RI);
36d23958
TS
15518 break;
15519 }
15520 } else {
e397ee33 15521 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15522 }
4ad40f36
FB
15523 break;
15524
d26bc211 15525#if defined(TARGET_MIPS64)
7a387fff
TS
15526 /* MIPS64 opcodes */
15527 case OPC_LWU:
15528 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15529 case OPC_LLD:
15530 case OPC_LD:
d75c135e 15531 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15532 check_mips_64(ctx);
d75c135e 15533 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
15534 break;
15535 case OPC_SDL ... OPC_SDR:
7a387fff 15536 case OPC_SD:
d75c135e 15537 check_insn(ctx, ISA_MIPS3);
e189e748 15538 check_mips_64(ctx);
5c13fdfd 15539 gen_st(ctx, op, rt, rs, imm);
7a387fff 15540 break;
d66c7132 15541 case OPC_SCD:
d75c135e 15542 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
15543 check_mips_64(ctx);
15544 gen_st_cond(ctx, op, rt, rs, imm);
15545 break;
324d9e32
AJ
15546 case OPC_DADDI:
15547 case OPC_DADDIU:
d75c135e 15548 check_insn(ctx, ISA_MIPS3);
e189e748 15549 check_mips_64(ctx);
d75c135e 15550 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15551 break;
6af0bf9c 15552#endif
7a387fff 15553 case OPC_JALX:
d75c135e 15554 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15555 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15556 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15557 *is_branch = 1;
15558 break;
7a387fff 15559 case OPC_MDMX:
d75c135e 15560 check_insn(ctx, ASE_MDMX);
7a387fff 15561 /* MDMX: Not implemented. */
6af0bf9c 15562 default: /* Invalid */
923617a3 15563 MIPS_INVAL("major opcode");
6af0bf9c
FB
15564 generate_exception(ctx, EXCP_RI);
15565 break;
15566 }
6af0bf9c
FB
15567}
15568
2cfc5f17 15569static inline void
7db13fae 15570gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
820e00f2 15571 int search_pc)
6af0bf9c 15572{
278d0702 15573 DisasContext ctx;
6af0bf9c
FB
15574 target_ulong pc_start;
15575 uint16_t *gen_opc_end;
a1d1bb31 15576 CPUBreakpoint *bp;
6af0bf9c 15577 int j, lj = -1;
2e70f6ef
PB
15578 int num_insns;
15579 int max_insns;
c9602061
NF
15580 int insn_bytes;
15581 int is_branch;
6af0bf9c 15582
93fcfe39
AL
15583 if (search_pc)
15584 qemu_log("search pc %d\n", search_pc);
4ad40f36 15585
6af0bf9c 15586 pc_start = tb->pc;
92414b31 15587 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15588 ctx.pc = pc_start;
4ad40f36 15589 ctx.saved_pc = -1;
7b270ef2 15590 ctx.singlestep_enabled = env->singlestep_enabled;
d75c135e 15591 ctx.insn_flags = env->insn_flags;
6af0bf9c
FB
15592 ctx.tb = tb;
15593 ctx.bstate = BS_NONE;
4ad40f36 15594 /* Restore delay slot state from the tb context. */
c068688b 15595 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
fd4a04eb 15596 restore_cpu_state(env, &ctx);
932e71cd 15597#ifdef CONFIG_USER_ONLY
0eaef5aa 15598 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15599#else
0eaef5aa 15600 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15601#endif
2e70f6ef
PB
15602 num_insns = 0;
15603 max_insns = tb->cflags & CF_COUNT_MASK;
15604 if (max_insns == 0)
15605 max_insns = CF_COUNT_MASK;
d12d51d5 15606 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
2e70f6ef 15607 gen_icount_start();
faf7aaa9 15608 while (ctx.bstate == BS_NONE) {
72cf2d4f
BS
15609 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15610 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 15611 if (bp->pc == ctx.pc) {
278d0702 15612 save_cpu_state(&ctx, 1);
4ad40f36 15613 ctx.bstate = BS_BRANCH;
895c2d04 15614 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15615 /* Include the breakpoint location or the tb won't
15616 * be flushed when it must be. */
15617 ctx.pc += 4;
4ad40f36
FB
15618 goto done_generating;
15619 }
15620 }
15621 }
15622
6af0bf9c 15623 if (search_pc) {
92414b31 15624 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15625 if (lj < j) {
15626 lj++;
15627 while (lj < j)
ab1103de 15628 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 15629 }
25983cad 15630 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 15631 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15632 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 15633 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 15634 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 15635 }
2e70f6ef
PB
15636 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15637 gen_io_start();
c9602061
NF
15638
15639 is_branch = 0;
364d4831 15640 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15641 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061
NF
15642 insn_bytes = 4;
15643 decode_opc(env, &ctx, &is_branch);
d75c135e 15644 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 15645 ctx.opcode = cpu_lduw_code(env, ctx.pc);
3c824109 15646 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
d75c135e 15647 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 15648 ctx.opcode = cpu_lduw_code(env, ctx.pc);
364d4831 15649 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
c9602061
NF
15650 } else {
15651 generate_exception(&ctx, EXCP_RI);
3c824109 15652 ctx.bstate = BS_STOP;
c9602061
NF
15653 break;
15654 }
15655 if (!is_branch) {
d75c135e 15656 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
15657 }
15658 ctx.pc += insn_bytes;
15659
2e70f6ef 15660 num_insns++;
4ad40f36 15661
7b270ef2
NF
15662 /* Execute a branch and its delay slot as a single instruction.
15663 This is what GDB expects and is consistent with what the
15664 hardware does (e.g. if a delay slot instruction faults, the
15665 reported PC is the PC of the branch). */
15666 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
4ad40f36
FB
15667 break;
15668
6af0bf9c
FB
15669 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15670 break;
4ad40f36 15671
efd7f486 15672 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 15673 break;
efd7f486 15674 }
faf7aaa9 15675
2e70f6ef
PB
15676 if (num_insns >= max_insns)
15677 break;
1b530a6d
AJ
15678
15679 if (singlestep)
15680 break;
6af0bf9c 15681 }
2e70f6ef
PB
15682 if (tb->cflags & CF_LAST_IO)
15683 gen_io_end();
7b270ef2 15684 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15685 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15686 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15687 } else {
6958549d 15688 switch (ctx.bstate) {
16c00cb2 15689 case BS_STOP:
df1561e2
TS
15690 gen_goto_tb(&ctx, 0, ctx.pc);
15691 break;
16c00cb2 15692 case BS_NONE:
278d0702 15693 save_cpu_state(&ctx, 0);
16c00cb2
TS
15694 gen_goto_tb(&ctx, 0, ctx.pc);
15695 break;
5a5012ec 15696 case BS_EXCP:
57fec1fe 15697 tcg_gen_exit_tb(0);
16c00cb2 15698 break;
5a5012ec
TS
15699 case BS_BRANCH:
15700 default:
15701 break;
6958549d 15702 }
6af0bf9c 15703 }
4ad40f36 15704done_generating:
2e70f6ef 15705 gen_icount_end(tb, num_insns);
efd7f486 15706 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 15707 if (search_pc) {
92414b31 15708 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15709 lj++;
15710 while (lj <= j)
ab1103de 15711 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15712 } else {
15713 tb->size = ctx.pc - pc_start;
2e70f6ef 15714 tb->icount = num_insns;
6af0bf9c
FB
15715 }
15716#ifdef DEBUG_DISAS
d12d51d5 15717 LOG_DISAS("\n");
8fec2b8c 15718 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 15719 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 15720 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 15721 qemu_log("\n");
6af0bf9c
FB
15722 }
15723#endif
6af0bf9c
FB
15724}
15725
7db13fae 15726void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15727{
2cfc5f17 15728 gen_intermediate_code_internal(env, tb, 0);
6af0bf9c
FB
15729}
15730
7db13fae 15731void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15732{
2cfc5f17 15733 gen_intermediate_code_internal(env, tb, 1);
6af0bf9c
FB
15734}
15735
7db13fae 15736static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15737 int flags)
6ea83fed
FB
15738{
15739 int i;
5e755519 15740 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15741
2a5612e6
SW
15742#define printfpr(fp) \
15743 do { \
15744 if (is_fpu64) \
15745 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15746 " fd:%13g fs:%13g psu: %13g\n", \
15747 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15748 (double)(fp)->fd, \
15749 (double)(fp)->fs[FP_ENDIAN_IDX], \
15750 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15751 else { \
15752 fpr_t tmp; \
15753 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15754 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15755 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15756 " fd:%13g fs:%13g psu:%13g\n", \
15757 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15758 (double)tmp.fd, \
15759 (double)tmp.fs[FP_ENDIAN_IDX], \
15760 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15761 } \
6ea83fed
FB
15762 } while(0)
15763
5a5012ec 15764
9a78eead
SW
15765 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15766 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15767 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15768 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15769 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15770 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15771 }
15772
15773#undef printfpr
15774}
15775
d26bc211 15776#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15777/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15778 sign-extended values on 64bit machines. */
c570fd16
TS
15779
15780#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15781
8706c382 15782static void
7db13fae 15783cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15784 fprintf_function cpu_fprintf,
8706c382 15785 int flags)
c570fd16
TS
15786{
15787 int i;
15788
b5dc7732
TS
15789 if (!SIGN_EXT_P(env->active_tc.PC))
15790 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15791 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15792 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15793 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15794 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15795 if (!SIGN_EXT_P(env->btarget))
3594c774 15796 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15797
15798 for (i = 0; i < 32; i++) {
b5dc7732
TS
15799 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15800 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15801 }
15802
15803 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15804 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15805 if (!SIGN_EXT_P(env->lladdr))
15806 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15807}
15808#endif
15809
7db13fae 15810void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
6af0bf9c
FB
15811 int flags)
15812{
15813 int i;
3b46e624 15814
a7200c9f
SW
15815 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15816 " LO=0x" TARGET_FMT_lx " ds %04x "
15817 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15818 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15819 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15820 for (i = 0; i < 32; i++) {
15821 if ((i & 3) == 0)
15822 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15823 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15824 if ((i & 3) == 3)
15825 cpu_fprintf(f, "\n");
15826 }
568b600d 15827
3594c774 15828 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15829 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15830 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15831 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15832 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15833 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15834#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15835 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15836#endif
6af0bf9c
FB
15837}
15838
78ce64f4 15839void mips_tcg_init(void)
39454628 15840{
f01be154 15841 int i;
39454628
TS
15842 static int inited;
15843
15844 /* Initialize various static tables. */
15845 if (inited)
6958549d 15846 return;
39454628 15847
a7812ae4 15848 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15849 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15850 for (i = 1; i < 32; i++)
a7812ae4 15851 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15852 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15853 regnames[i]);
d73ee8a2
RH
15854
15855 for (i = 0; i < 32; i++) {
15856 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15857 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15858 }
15859
a7812ae4 15860 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15861 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15862 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15863 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15864 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15865 regnames_HI[i]);
a7812ae4 15866 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15867 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15868 regnames_LO[i]);
a7812ae4 15869 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15870 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15871 regnames_ACX[i]);
15872 }
a7812ae4 15873 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15874 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15875 "DSPControl");
1ba74fb8 15876 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15877 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15878 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15879 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15880 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15881 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15882
a7812ae4 15883 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15884 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15885 "fcr0");
15886 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15887 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15888 "fcr31");
39454628 15889
7dd9e556 15890 /* register helpers */
a7812ae4 15891#define GEN_HELPER 2
7dd9e556
TS
15892#include "helper.h"
15893
39454628
TS
15894 inited = 1;
15895}
15896
aaed909a
FB
15897#include "translate_init.c"
15898
30bf942d 15899MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15900{
0f71a709 15901 MIPSCPU *cpu;
6af0bf9c 15902 CPUMIPSState *env;
c227f099 15903 const mips_def_t *def;
6af0bf9c 15904
aaed909a
FB
15905 def = cpu_mips_find_by_name(cpu_model);
15906 if (!def)
15907 return NULL;
0f71a709
AF
15908 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15909 env = &cpu->env;
aaed909a 15910 env->cpu_model = def;
51cc2e78 15911 env->cpu_model_str = cpu_model;
aaed909a 15912
51cc2e78
BS
15913#ifndef CONFIG_USER_ONLY
15914 mmu_init(env, def);
15915#endif
15916 fpu_init(env, def);
15917 mvp_init(env, def);
c1caf1d9
AF
15918
15919 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15920
30bf942d 15921 return cpu;
6ae81775
TS
15922}
15923
1bba0dc9 15924void cpu_state_reset(CPUMIPSState *env)
6ae81775 15925{
55e5c285
AF
15926#ifndef CONFIG_USER_ONLY
15927 MIPSCPU *cpu = mips_env_get_cpu(env);
15928 CPUState *cs = CPU(cpu);
15929#endif
6ae81775 15930
51cc2e78
BS
15931 /* Reset registers to their default values */
15932 env->CP0_PRid = env->cpu_model->CP0_PRid;
15933 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15934#ifdef TARGET_WORDS_BIGENDIAN
15935 env->CP0_Config0 |= (1 << CP0C0_BE);
15936#endif
15937 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15938 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15939 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15940 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15941 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
15942 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15943 << env->cpu_model->CP0_LLAddr_shift;
15944 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
15945 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15946 env->CCRes = env->cpu_model->CCRes;
15947 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15948 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15949 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15950 env->current_tc = 0;
15951 env->SEGBITS = env->cpu_model->SEGBITS;
15952 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15953#if defined(TARGET_MIPS64)
15954 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15955 env->SEGMask |= 3ULL << 62;
15956 }
15957#endif
15958 env->PABITS = env->cpu_model->PABITS;
15959 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15960 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15961 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15962 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15963 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15964 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15965 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15966 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15967 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15968 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15969 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 15970 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
15971 env->insn_flags = env->cpu_model->insn_flags;
15972
0eaef5aa 15973#if defined(CONFIG_USER_ONLY)
03e6e501 15974 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
94159135
MI
15975 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15976 hardware registers. */
15977 env->CP0_HWREna |= 0x0000000F;
91a75935 15978 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 15979 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 15980 }
6f0af304
PJ
15981 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
15982 env->CP0_Status |= (1 << CP0St_MX);
853c3240 15983 }
932e71cd
AJ
15984#else
15985 if (env->hflags & MIPS_HFLAG_BMASK) {
15986 /* If the exception was raised from a delay slot,
15987 come back to the jump. */
15988 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 15989 } else {
932e71cd
AJ
15990 env->CP0_ErrorEPC = env->active_tc.PC;
15991 }
15992 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
15993 env->CP0_Random = env->tlb->nb_tlb - 1;
15994 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 15995 env->CP0_Wired = 0;
55e5c285 15996 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
932e71cd
AJ
15997 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15998 /* vectored interrupts not implemented, timer on int 7,
15999 no performance counters. */
16000 env->CP0_IntCtl = 0xe0000000;
16001 {
16002 int i;
16003
16004 for (i = 0; i < 7; i++) {
16005 env->CP0_WatchLo[i] = 0;
16006 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 16007 }
932e71cd
AJ
16008 env->CP0_WatchLo[7] = 0;
16009 env->CP0_WatchHi[7] = 0;
fd88b6ab 16010 }
932e71cd
AJ
16011 /* Count register increments in debug mode, EJTAG version 1 */
16012 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756
EI
16013
16014 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16015 int i;
16016
16017 /* Only TC0 on VPE 0 starts as active. */
16018 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 16019 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
16020 env->tcs[i].CP0_TCHalt = 1;
16021 }
16022 env->active_tc.CP0_TCHalt = 1;
16023 env->halted = 1;
16024
55e5c285 16025 if (cs->cpu_index == 0) {
9e56e756
EI
16026 /* VPE0 starts up enabled. */
16027 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16028 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16029
16030 /* TC0 starts up unhalted. */
16031 env->halted = 0;
16032 env->active_tc.CP0_TCHalt = 0;
16033 env->tcs[0].CP0_TCHalt = 0;
16034 /* With thread 0 active. */
16035 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16036 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16037 }
16038 }
51cc2e78 16039#endif
03e6e501 16040 compute_hflags(env);
6af0bf9c 16041 env->exception_index = EXCP_NONE;
6af0bf9c 16042}
d2856f1a 16043
7db13fae 16044void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16045{
25983cad 16046 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16047 env->hflags &= ~MIPS_HFLAG_BMASK;
16048 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16049 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16050 case MIPS_HFLAG_BR:
16051 break;
16052 case MIPS_HFLAG_BC:
16053 case MIPS_HFLAG_BL:
16054 case MIPS_HFLAG_B:
16055 env->btarget = gen_opc_btarget[pc_pos];
16056 break;
16057 }
d2856f1a 16058}