]> git.proxmox.com Git - qemu.git/blame - target-mips/translate.c
cpu: Move cpu_index field to CPUState
[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,
26690560
JL
339 /* MIPS DSP Compare-Pick Sub-class */
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 {
546 /* MIPS DSP Compare-Pick Sub-class */
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 {
670 /* DSP Compare-Pick Sub-class */
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;
8e9ade68
TS
1069 /* Routine used to access memory */
1070 int mem_idx;
1071 uint32_t hflags, saved_hflags;
1072 int bstate;
1073 target_ulong btarget;
1074} DisasContext;
1075
1076enum {
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1078 * exception condition */
8e9ade68
TS
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1082};
1083
d73ee8a2
RH
1084static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1089};
6af0bf9c 1090
d73ee8a2
RH
1091static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1093};
4b2eb8d2 1094
d73ee8a2
RH
1095static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1097};
4b2eb8d2 1098
d73ee8a2
RH
1099static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1101};
4b2eb8d2 1102
d73ee8a2
RH
1103static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1108};
958fb4a9 1109
fb7729e2
RH
1110#define MIPS_DEBUG(fmt, ...) \
1111 do { \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1116 } \
1117 } while (0)
1118
1119#define LOG_DISAS(...) \
1120 do { \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1123 } \
1124 } while (0)
958fb4a9 1125
8e9ade68 1126#define MIPS_INVAL(op) \
8e9ade68 1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1129
8e9ade68
TS
1130/* General purpose registers moves. */
1131static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1132{
8e9ade68
TS
1133 if (reg == 0)
1134 tcg_gen_movi_tl(t, 0);
1135 else
4b2eb8d2 1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1137}
1138
8e9ade68 1139static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1140{
8e9ade68 1141 if (reg != 0)
4b2eb8d2 1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1143}
1144
b10fa3c9 1145/* Moves to/from ACX register. */
4b2eb8d2 1146static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1147{
4b2eb8d2 1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1149}
1150
4b2eb8d2 1151static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1152{
4b2eb8d2 1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1154}
1155
8e9ade68 1156/* Moves to/from shadow registers. */
be24bb4f 1157static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1158{
d9bea114 1159 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1160
1161 if (from == 0)
d9bea114 1162 tcg_gen_movi_tl(t0, 0);
8e9ade68 1163 else {
d9bea114 1164 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1165 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1166
7db13fae 1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1172 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1173
d9bea114 1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1175 tcg_temp_free_ptr(addr);
d9bea114 1176 tcg_temp_free_i32(t2);
8e9ade68 1177 }
d9bea114
AJ
1178 gen_store_gpr(t0, to);
1179 tcg_temp_free(t0);
aaa9128a
TS
1180}
1181
be24bb4f 1182static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1183{
be24bb4f 1184 if (to != 0) {
d9bea114
AJ
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1187 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1188
d9bea114 1189 gen_load_gpr(t0, from);
7db13fae 1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1195 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1196
d9bea114 1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1198 tcg_temp_free_ptr(addr);
d9bea114
AJ
1199 tcg_temp_free_i32(t2);
1200 tcg_temp_free(t0);
8e9ade68 1201 }
aaa9128a
TS
1202}
1203
aaa9128a 1204/* Floating point register moves. */
d73ee8a2 1205static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1206{
d73ee8a2 1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1208}
1209
d73ee8a2 1210static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1211{
d73ee8a2
RH
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
6d066274
AJ
1216}
1217
d73ee8a2 1218static void gen_load_fpr32h(TCGv_i32 t, int reg)
6d066274 1219{
d73ee8a2
RH
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
6d066274
AJ
1224}
1225
d73ee8a2 1226static void gen_store_fpr32h(TCGv_i32 t, int reg)
6d066274 1227{
d73ee8a2
RH
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
aa0bf00b 1232}
6ea83fed 1233
d73ee8a2 1234static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1235{
f364515c 1236 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1238 } else {
d73ee8a2 1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1240 }
1241}
6ea83fed 1242
d73ee8a2 1243static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1244{
f364515c 1245 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1246 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1247 } else {
d73ee8a2
RH
1248 TCGv_i64 t0;
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
6d066274 1251 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1253 tcg_temp_free_i64(t0);
aa0bf00b
TS
1254 }
1255}
6ea83fed 1256
d94536f4 1257static inline int get_fp_bit (int cc)
a16336e4 1258{
d94536f4
AJ
1259 if (cc)
1260 return 24 + cc;
1261 else
1262 return 23;
a16336e4
TS
1263}
1264
30898801 1265/* Tests */
8e9ade68
TS
1266static inline void gen_save_pc(target_ulong pc)
1267{
1eb75d4a 1268 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1269}
30898801 1270
356265ae 1271static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1272{
d12d51d5 1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1275 gen_save_pc(ctx->pc);
6af0bf9c
FB
1276 ctx->saved_pc = ctx->pc;
1277 }
1278 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1279 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1280 ctx->saved_hflags = ctx->hflags;
364d4831 1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1282 case MIPS_HFLAG_BR:
5a5012ec
TS
1283 break;
1284 case MIPS_HFLAG_BC:
5a5012ec 1285 case MIPS_HFLAG_BL:
5a5012ec 1286 case MIPS_HFLAG_B:
d077b6f7 1287 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1288 break;
6af0bf9c
FB
1289 }
1290 }
1291}
1292
7db13fae 1293static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1294{
fd4a04eb 1295 ctx->saved_hflags = ctx->hflags;
364d4831 1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1297 case MIPS_HFLAG_BR:
fd4a04eb
TS
1298 break;
1299 case MIPS_HFLAG_BC:
1300 case MIPS_HFLAG_BL:
39454628 1301 case MIPS_HFLAG_B:
fd4a04eb 1302 ctx->btarget = env->btarget;
fd4a04eb 1303 break;
5a5012ec
TS
1304 }
1305}
1306
356265ae 1307static inline void
48d38ca5 1308generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1309{
a7812ae4
PB
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1312 save_cpu_state(ctx, 1);
895c2d04 1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
aaa9128a
TS
1316}
1317
356265ae 1318static inline void
48d38ca5 1319generate_exception (DisasContext *ctx, int excp)
aaa9128a 1320{
6af0bf9c 1321 save_cpu_state(ctx, 1);
895c2d04 1322 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1323}
1324
48d38ca5 1325/* Addresses computation */
941694d0 1326static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1327{
941694d0 1328 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1329
1330#if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1336 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1337 }
1338#endif
4ad40f36
FB
1339}
1340
356265ae 1341static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1342{
fe253235 1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1344 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1345}
1346
356265ae 1347static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1348{
fe253235 1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1351}
1352
b8aa4598
TS
1353/* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1355 opcode tables. */
1356
356265ae 1357static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1358{
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1361}
1362
1363/* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1365
356265ae 1366static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1367{
b8aa4598 1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1369 generate_exception(ctx, EXCP_RI);
1370}
1371
1372/*
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1379 *
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1382 */
356265ae 1383static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1384{
fe253235 1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1386 generate_exception(ctx, EXCP_RI);
1387}
1388
853c3240
JL
1389/* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1391 */
1392
1393static inline void check_dsp(DisasContext *ctx)
1394{
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1397 }
1398}
1399
1400static inline void check_dspr2(DisasContext *ctx)
1401{
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1404 }
1405}
1406
3a95e3a7 1407/* This code generates a "reserved instruction" exception if the
e189e748 1408 CPU does not support the instruction set corresponding to flags. */
7db13fae 1409static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
3a95e3a7 1410{
e189e748 1411 if (unlikely(!(env->insn_flags & flags)))
3a95e3a7
TS
1412 generate_exception(ctx, EXCP_RI);
1413}
1414
e189e748
TS
1415/* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
356265ae 1417static inline void check_mips_64(DisasContext *ctx)
e189e748 1418{
fe253235 1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1420 generate_exception(ctx, EXCP_RI);
1421}
1422
8153667c
NF
1423/* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1426 this one use. */
1427#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1432{ \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1435 switch (ifmt) { \
1436 case FMT_PS: \
1437 check_cp1_64bitmode(ctx); \
1438 break; \
1439 case FMT_D: \
1440 if (abs) { \
1441 check_cop1x(ctx); \
1442 } \
1443 check_cp1_registers(ctx, fs | ft); \
1444 break; \
1445 case FMT_S: \
1446 if (abs) { \
1447 check_cop1x(ctx); \
1448 } \
1449 break; \
1450 } \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1453 switch (n) { \
895c2d04
BS
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1470 default: abort(); \
1471 } \
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1474}
1475
1476FOP_CONDS(, 0, d, FMT_D, 64)
1477FOP_CONDS(abs, 1, d, FMT_D, 64)
1478FOP_CONDS(, 0, s, FMT_S, 32)
1479FOP_CONDS(abs, 1, s, FMT_S, 32)
1480FOP_CONDS(, 0, ps, FMT_PS, 64)
1481FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1482#undef FOP_CONDS
1483#undef gen_ldcmp_fpr32
1484#undef gen_ldcmp_fpr64
1485
958fb4a9 1486/* load/store instructions. */
e7139c44 1487#ifdef CONFIG_USER_ONLY
d9bea114 1488#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1489static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1490{ \
1491 TCGv t0 = tcg_temp_new(); \
1492 tcg_gen_mov_tl(t0, arg1); \
1493 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1494 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1495 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1496 tcg_temp_free(t0); \
aaa9128a 1497}
e7139c44
AJ
1498#else
1499#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1500static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1501{ \
895c2d04 1502 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1503}
1504#endif
aaa9128a
TS
1505OP_LD_ATOMIC(ll,ld32s);
1506#if defined(TARGET_MIPS64)
1507OP_LD_ATOMIC(lld,ld64);
1508#endif
1509#undef OP_LD_ATOMIC
1510
590bc601
PB
1511#ifdef CONFIG_USER_ONLY
1512#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1513static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1514{ \
1515 TCGv t0 = tcg_temp_new(); \
1516 int l1 = gen_new_label(); \
1517 int l2 = gen_new_label(); \
1518 \
1519 tcg_gen_andi_tl(t0, arg2, almask); \
1520 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1521 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1522 generate_exception(ctx, EXCP_AdES); \
1523 gen_set_label(l1); \
7db13fae 1524 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1525 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1526 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1527 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1528 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1529 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1530 gen_set_label(l2); \
1531 tcg_gen_movi_tl(t0, 0); \
1532 gen_store_gpr(t0, rt); \
1533 tcg_temp_free(t0); \
1534}
1535#else
1536#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1537static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1538{ \
1539 TCGv t0 = tcg_temp_new(); \
895c2d04 1540 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1541 gen_store_gpr(t0, rt); \
590bc601
PB
1542 tcg_temp_free(t0); \
1543}
1544#endif
590bc601 1545OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1546#if defined(TARGET_MIPS64)
590bc601 1547OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1548#endif
1549#undef OP_ST_ATOMIC
1550
662d7485
NF
1551static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1552 int base, int16_t offset)
1553{
1554 if (base == 0) {
1555 tcg_gen_movi_tl(addr, offset);
1556 } else if (offset == 0) {
1557 gen_load_gpr(addr, base);
1558 } else {
1559 tcg_gen_movi_tl(addr, offset);
1560 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1561 }
1562}
1563
364d4831
NF
1564static target_ulong pc_relative_pc (DisasContext *ctx)
1565{
1566 target_ulong pc = ctx->pc;
1567
1568 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1569 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1570
1571 pc -= branch_bytes;
1572 }
1573
1574 pc &= ~(target_ulong)3;
1575 return pc;
1576}
1577
5c13fdfd 1578/* Load */
7db13fae 1579static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
afa88c3a 1580 int rt, int base, int16_t offset)
6af0bf9c 1581{
5c13fdfd 1582 const char *opn = "ld";
fc40787a 1583 TCGv t0, t1, t2;
afa88c3a
AJ
1584
1585 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1586 /* Loongson CPU uses a load to zero register for prefetch.
1587 We emulate it as a NOP. On other CPU we must perform the
1588 actual memory access. */
1589 MIPS_DEBUG("NOP");
1590 return;
1591 }
6af0bf9c 1592
afa88c3a 1593 t0 = tcg_temp_new();
662d7485 1594 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1595
6af0bf9c 1596 switch (opc) {
d26bc211 1597#if defined(TARGET_MIPS64)
6e473128 1598 case OPC_LWU:
2910c6cb 1599 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
78723684 1600 gen_store_gpr(t0, rt);
6e473128
TS
1601 opn = "lwu";
1602 break;
6af0bf9c 1603 case OPC_LD:
2910c6cb 1604 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
78723684 1605 gen_store_gpr(t0, rt);
6af0bf9c
FB
1606 opn = "ld";
1607 break;
7a387fff 1608 case OPC_LLD:
b835e919 1609 save_cpu_state(ctx, 1);
5c13fdfd 1610 op_ld_lld(t0, t0, ctx);
78723684 1611 gen_store_gpr(t0, rt);
7a387fff
TS
1612 opn = "lld";
1613 break;
6af0bf9c 1614 case OPC_LDL:
3cee3050 1615 t1 = tcg_temp_new();
fc40787a
AJ
1616 tcg_gen_andi_tl(t1, t0, 7);
1617#ifndef TARGET_WORDS_BIGENDIAN
1618 tcg_gen_xori_tl(t1, t1, 7);
1619#endif
1620 tcg_gen_shli_tl(t1, t1, 3);
1621 tcg_gen_andi_tl(t0, t0, ~7);
1622 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1623 tcg_gen_shl_tl(t0, t0, t1);
1624 tcg_gen_xori_tl(t1, t1, 63);
1625 t2 = tcg_const_tl(0x7fffffffffffffffull);
1626 tcg_gen_shr_tl(t2, t2, t1);
78723684 1627 gen_load_gpr(t1, rt);
fc40787a
AJ
1628 tcg_gen_and_tl(t1, t1, t2);
1629 tcg_temp_free(t2);
1630 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1631 tcg_temp_free(t1);
fc40787a 1632 gen_store_gpr(t0, rt);
6af0bf9c
FB
1633 opn = "ldl";
1634 break;
6af0bf9c 1635 case OPC_LDR:
3cee3050 1636 t1 = tcg_temp_new();
fc40787a
AJ
1637 tcg_gen_andi_tl(t1, t0, 7);
1638#ifdef TARGET_WORDS_BIGENDIAN
1639 tcg_gen_xori_tl(t1, t1, 7);
1640#endif
1641 tcg_gen_shli_tl(t1, t1, 3);
1642 tcg_gen_andi_tl(t0, t0, ~7);
1643 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1644 tcg_gen_shr_tl(t0, t0, t1);
1645 tcg_gen_xori_tl(t1, t1, 63);
1646 t2 = tcg_const_tl(0xfffffffffffffffeull);
1647 tcg_gen_shl_tl(t2, t2, t1);
78723684 1648 gen_load_gpr(t1, rt);
fc40787a
AJ
1649 tcg_gen_and_tl(t1, t1, t2);
1650 tcg_temp_free(t2);
1651 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1652 tcg_temp_free(t1);
fc40787a 1653 gen_store_gpr(t0, rt);
6af0bf9c
FB
1654 opn = "ldr";
1655 break;
364d4831 1656 case OPC_LDPC:
3cee3050 1657 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1658 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1659 tcg_temp_free(t1);
2910c6cb 1660 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
364d4831 1661 gen_store_gpr(t0, rt);
5c13fdfd 1662 opn = "ldpc";
364d4831 1663 break;
6af0bf9c 1664#endif
364d4831 1665 case OPC_LWPC:
3cee3050 1666 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1667 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1668 tcg_temp_free(t1);
2910c6cb 1669 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
364d4831 1670 gen_store_gpr(t0, rt);
5c13fdfd 1671 opn = "lwpc";
364d4831 1672 break;
6af0bf9c 1673 case OPC_LW:
2910c6cb 1674 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
78723684 1675 gen_store_gpr(t0, rt);
6af0bf9c
FB
1676 opn = "lw";
1677 break;
6af0bf9c 1678 case OPC_LH:
2910c6cb 1679 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
78723684 1680 gen_store_gpr(t0, rt);
6af0bf9c
FB
1681 opn = "lh";
1682 break;
6af0bf9c 1683 case OPC_LHU:
2910c6cb 1684 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
78723684 1685 gen_store_gpr(t0, rt);
6af0bf9c
FB
1686 opn = "lhu";
1687 break;
1688 case OPC_LB:
2910c6cb 1689 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
78723684 1690 gen_store_gpr(t0, rt);
6af0bf9c
FB
1691 opn = "lb";
1692 break;
6af0bf9c 1693 case OPC_LBU:
2910c6cb 1694 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
78723684 1695 gen_store_gpr(t0, rt);
6af0bf9c
FB
1696 opn = "lbu";
1697 break;
1698 case OPC_LWL:
3cee3050 1699 t1 = tcg_temp_new();
fc40787a
AJ
1700 tcg_gen_andi_tl(t1, t0, 3);
1701#ifndef TARGET_WORDS_BIGENDIAN
1702 tcg_gen_xori_tl(t1, t1, 3);
1703#endif
1704 tcg_gen_shli_tl(t1, t1, 3);
1705 tcg_gen_andi_tl(t0, t0, ~3);
1706 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1707 tcg_gen_shl_tl(t0, t0, t1);
1708 tcg_gen_xori_tl(t1, t1, 31);
1709 t2 = tcg_const_tl(0x7fffffffull);
1710 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1711 gen_load_gpr(t1, rt);
fc40787a
AJ
1712 tcg_gen_and_tl(t1, t1, t2);
1713 tcg_temp_free(t2);
1714 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1715 tcg_temp_free(t1);
fc40787a
AJ
1716 tcg_gen_ext32s_tl(t0, t0);
1717 gen_store_gpr(t0, rt);
6af0bf9c
FB
1718 opn = "lwl";
1719 break;
6af0bf9c 1720 case OPC_LWR:
3cee3050 1721 t1 = tcg_temp_new();
fc40787a
AJ
1722 tcg_gen_andi_tl(t1, t0, 3);
1723#ifdef TARGET_WORDS_BIGENDIAN
1724 tcg_gen_xori_tl(t1, t1, 3);
1725#endif
1726 tcg_gen_shli_tl(t1, t1, 3);
1727 tcg_gen_andi_tl(t0, t0, ~3);
1728 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1729 tcg_gen_shr_tl(t0, t0, t1);
1730 tcg_gen_xori_tl(t1, t1, 31);
1731 t2 = tcg_const_tl(0xfffffffeull);
1732 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1733 gen_load_gpr(t1, rt);
fc40787a
AJ
1734 tcg_gen_and_tl(t1, t1, t2);
1735 tcg_temp_free(t2);
1736 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1737 tcg_temp_free(t1);
fc40787a 1738 gen_store_gpr(t0, rt);
6af0bf9c
FB
1739 opn = "lwr";
1740 break;
6af0bf9c 1741 case OPC_LL:
e7139c44 1742 save_cpu_state(ctx, 1);
5c13fdfd 1743 op_ld_ll(t0, t0, ctx);
78723684 1744 gen_store_gpr(t0, rt);
6af0bf9c
FB
1745 opn = "ll";
1746 break;
d66c7132 1747 }
2abf314d 1748 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1749 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1750 tcg_temp_free(t0);
d66c7132
AJ
1751}
1752
5c13fdfd
AJ
1753/* Store */
1754static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1755 int base, int16_t offset)
1756{
1757 const char *opn = "st";
1758 TCGv t0 = tcg_temp_new();
1759 TCGv t1 = tcg_temp_new();
1760
1761 gen_base_offset_addr(ctx, t0, base, offset);
1762 gen_load_gpr(t1, rt);
1763 switch (opc) {
1764#if defined(TARGET_MIPS64)
1765 case OPC_SD:
2910c6cb 1766 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1767 opn = "sd";
1768 break;
1769 case OPC_SDL:
1770 save_cpu_state(ctx, 1);
895c2d04 1771 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1772 opn = "sdl";
1773 break;
1774 case OPC_SDR:
1775 save_cpu_state(ctx, 1);
895c2d04 1776 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1777 opn = "sdr";
1778 break;
1779#endif
1780 case OPC_SW:
2910c6cb 1781 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1782 opn = "sw";
1783 break;
1784 case OPC_SH:
2910c6cb 1785 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1786 opn = "sh";
1787 break;
1788 case OPC_SB:
2910c6cb 1789 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1790 opn = "sb";
1791 break;
1792 case OPC_SWL:
1793 save_cpu_state(ctx, 1);
895c2d04 1794 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1795 opn = "swl";
1796 break;
1797 case OPC_SWR:
1798 save_cpu_state(ctx, 1);
895c2d04 1799 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1800 opn = "swr";
1801 break;
1802 }
2abf314d 1803 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1804 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1805 tcg_temp_free(t0);
1806 tcg_temp_free(t1);
1807}
1808
1809
d66c7132
AJ
1810/* Store conditional */
1811static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1812 int base, int16_t offset)
1813{
1814 const char *opn = "st_cond";
1815 TCGv t0, t1;
1816
2d2826b9 1817#ifdef CONFIG_USER_ONLY
d66c7132 1818 t0 = tcg_temp_local_new();
d66c7132 1819 t1 = tcg_temp_local_new();
2d2826b9
AJ
1820#else
1821 t0 = tcg_temp_new();
1822 t1 = tcg_temp_new();
1823#endif
1824 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1825 gen_load_gpr(t1, rt);
1826 switch (opc) {
1827#if defined(TARGET_MIPS64)
1828 case OPC_SCD:
b835e919 1829 save_cpu_state(ctx, 1);
5c13fdfd 1830 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1831 opn = "scd";
1832 break;
1833#endif
6af0bf9c 1834 case OPC_SC:
e7139c44 1835 save_cpu_state(ctx, 1);
5c13fdfd 1836 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1837 opn = "sc";
1838 break;
6af0bf9c 1839 }
2abf314d 1840 (void)opn; /* avoid a compiler warning */
6af0bf9c 1841 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1842 tcg_temp_free(t1);
d66c7132 1843 tcg_temp_free(t0);
6af0bf9c
FB
1844}
1845
6ea83fed 1846/* Load and store */
7a387fff 1847static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1848 int base, int16_t offset)
6ea83fed 1849{
923617a3 1850 const char *opn = "flt_ldst";
4e2474d6 1851 TCGv t0 = tcg_temp_new();
6ea83fed 1852
662d7485 1853 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1854 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1855 memory access. */
6ea83fed
FB
1856 switch (opc) {
1857 case OPC_LWC1:
b6d96bed 1858 {
a7812ae4 1859 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1860
c407df81
AJ
1861 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1862 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 1863 gen_store_fpr32(fp0, ft);
a7812ae4 1864 tcg_temp_free_i32(fp0);
b6d96bed 1865 }
6ea83fed
FB
1866 opn = "lwc1";
1867 break;
1868 case OPC_SWC1:
b6d96bed 1869 {
a7812ae4
PB
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 TCGv t1 = tcg_temp_new();
b6d96bed
TS
1872
1873 gen_load_fpr32(fp0, ft);
a7812ae4
PB
1874 tcg_gen_extu_i32_tl(t1, fp0);
1875 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1876 tcg_temp_free(t1);
1877 tcg_temp_free_i32(fp0);
b6d96bed 1878 }
6ea83fed
FB
1879 opn = "swc1";
1880 break;
1881 case OPC_LDC1:
b6d96bed 1882 {
a7812ae4 1883 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1884
1885 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1886 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1887 tcg_temp_free_i64(fp0);
b6d96bed 1888 }
6ea83fed
FB
1889 opn = "ldc1";
1890 break;
1891 case OPC_SDC1:
b6d96bed 1892 {
a7812ae4 1893 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1894
1895 gen_load_fpr64(ctx, fp0, ft);
1896 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 1897 tcg_temp_free_i64(fp0);
b6d96bed 1898 }
6ea83fed
FB
1899 opn = "sdc1";
1900 break;
1901 default:
923617a3 1902 MIPS_INVAL(opn);
e397ee33 1903 generate_exception(ctx, EXCP_RI);
78723684 1904 goto out;
6ea83fed 1905 }
2abf314d 1906 (void)opn; /* avoid a compiler warning */
6ea83fed 1907 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1908 out:
1909 tcg_temp_free(t0);
6ea83fed 1910}
6ea83fed 1911
7db13fae 1912static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
26ebe468
NF
1913 uint32_t op, int rt, int rs, int16_t imm)
1914{
1915 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1916 check_cp1_enabled(ctx);
1917 gen_flt_ldst(ctx, op, rt, rs, imm);
1918 } else {
1919 generate_exception_err(ctx, EXCP_CpU, 1);
1920 }
1921}
1922
6af0bf9c 1923/* Arithmetic with immediate operand */
7db13fae 1924static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
e189e748 1925 int rt, int rs, int16_t imm)
6af0bf9c 1926{
324d9e32 1927 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1928 const char *opn = "imm arith";
6af0bf9c 1929
7a387fff 1930 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1931 /* If no destination, treat it as a NOP.
1932 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1933 MIPS_DEBUG("NOP");
324d9e32 1934 return;
6af0bf9c
FB
1935 }
1936 switch (opc) {
1937 case OPC_ADDI:
48d38ca5 1938 {
324d9e32
AJ
1939 TCGv t0 = tcg_temp_local_new();
1940 TCGv t1 = tcg_temp_new();
1941 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1942 int l1 = gen_new_label();
1943
324d9e32
AJ
1944 gen_load_gpr(t1, rs);
1945 tcg_gen_addi_tl(t0, t1, uimm);
1946 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1947
324d9e32
AJ
1948 tcg_gen_xori_tl(t1, t1, ~uimm);
1949 tcg_gen_xori_tl(t2, t0, uimm);
1950 tcg_gen_and_tl(t1, t1, t2);
1951 tcg_temp_free(t2);
1952 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1953 tcg_temp_free(t1);
48d38ca5
TS
1954 /* operands of same sign, result different sign */
1955 generate_exception(ctx, EXCP_OVERFLOW);
1956 gen_set_label(l1);
78723684 1957 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1958 gen_store_gpr(t0, rt);
1959 tcg_temp_free(t0);
48d38ca5 1960 }
6af0bf9c
FB
1961 opn = "addi";
1962 break;
1963 case OPC_ADDIU:
324d9e32
AJ
1964 if (rs != 0) {
1965 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1966 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1967 } else {
1968 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1969 }
6af0bf9c
FB
1970 opn = "addiu";
1971 break;
d26bc211 1972#if defined(TARGET_MIPS64)
7a387fff 1973 case OPC_DADDI:
48d38ca5 1974 {
324d9e32
AJ
1975 TCGv t0 = tcg_temp_local_new();
1976 TCGv t1 = tcg_temp_new();
1977 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1978 int l1 = gen_new_label();
1979
324d9e32
AJ
1980 gen_load_gpr(t1, rs);
1981 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1982
324d9e32
AJ
1983 tcg_gen_xori_tl(t1, t1, ~uimm);
1984 tcg_gen_xori_tl(t2, t0, uimm);
1985 tcg_gen_and_tl(t1, t1, t2);
1986 tcg_temp_free(t2);
1987 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1988 tcg_temp_free(t1);
48d38ca5
TS
1989 /* operands of same sign, result different sign */
1990 generate_exception(ctx, EXCP_OVERFLOW);
1991 gen_set_label(l1);
324d9e32
AJ
1992 gen_store_gpr(t0, rt);
1993 tcg_temp_free(t0);
48d38ca5 1994 }
7a387fff
TS
1995 opn = "daddi";
1996 break;
1997 case OPC_DADDIU:
324d9e32
AJ
1998 if (rs != 0) {
1999 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2000 } else {
2001 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2002 }
7a387fff
TS
2003 opn = "daddiu";
2004 break;
2005#endif
324d9e32 2006 }
2abf314d 2007 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2008 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2009}
2010
2011/* Logic with immediate operand */
9fa77488
RH
2012static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2013 int rt, int rs, int16_t imm)
324d9e32
AJ
2014{
2015 target_ulong uimm;
324d9e32
AJ
2016
2017 if (rt == 0) {
2018 /* If no destination, treat it as a NOP. */
2019 MIPS_DEBUG("NOP");
2020 return;
2021 }
2022 uimm = (uint16_t)imm;
2023 switch (opc) {
6af0bf9c 2024 case OPC_ANDI:
324d9e32
AJ
2025 if (likely(rs != 0))
2026 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2027 else
2028 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2029 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2030 regnames[rs], uimm);
6af0bf9c
FB
2031 break;
2032 case OPC_ORI:
324d9e32
AJ
2033 if (rs != 0)
2034 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2035 else
2036 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2037 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2038 regnames[rs], uimm);
6af0bf9c
FB
2039 break;
2040 case OPC_XORI:
324d9e32
AJ
2041 if (likely(rs != 0))
2042 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2043 else
2044 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2045 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2046 regnames[rs], uimm);
6af0bf9c
FB
2047 break;
2048 case OPC_LUI:
324d9e32 2049 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2050 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2051 break;
2052
2053 default:
2054 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2055 break;
324d9e32 2056 }
324d9e32
AJ
2057}
2058
2059/* Set on less than with immediate operand */
9fa77488
RH
2060static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2061 int rt, int rs, int16_t imm)
324d9e32
AJ
2062{
2063 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2064 const char *opn = "imm arith";
2065 TCGv t0;
2066
2067 if (rt == 0) {
2068 /* If no destination, treat it as a NOP. */
2069 MIPS_DEBUG("NOP");
2070 return;
2071 }
2072 t0 = tcg_temp_new();
2073 gen_load_gpr(t0, rs);
2074 switch (opc) {
2075 case OPC_SLTI:
e68dd28f 2076 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2077 opn = "slti";
2078 break;
2079 case OPC_SLTIU:
e68dd28f 2080 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2081 opn = "sltiu";
2082 break;
2083 }
2abf314d 2084 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2085 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2086 tcg_temp_free(t0);
2087}
2088
2089/* Shifts with immediate operand */
7db13fae 2090static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2091 int rt, int rs, int16_t imm)
2092{
2093 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2094 const char *opn = "imm shift";
2095 TCGv t0;
2096
2097 if (rt == 0) {
2098 /* If no destination, treat it as a NOP. */
2099 MIPS_DEBUG("NOP");
2100 return;
2101 }
2102
2103 t0 = tcg_temp_new();
2104 gen_load_gpr(t0, rs);
2105 switch (opc) {
6af0bf9c 2106 case OPC_SLL:
78723684 2107 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2108 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2109 opn = "sll";
2110 break;
2111 case OPC_SRA:
324d9e32 2112 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2113 opn = "sra";
2114 break;
2115 case OPC_SRL:
ea63e2c3
NF
2116 if (uimm != 0) {
2117 tcg_gen_ext32u_tl(t0, t0);
2118 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2119 } else {
2120 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2121 }
ea63e2c3
NF
2122 opn = "srl";
2123 break;
2124 case OPC_ROTR:
2125 if (uimm != 0) {
2126 TCGv_i32 t1 = tcg_temp_new_i32();
2127
2128 tcg_gen_trunc_tl_i32(t1, t0);
2129 tcg_gen_rotri_i32(t1, t1, uimm);
2130 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2131 tcg_temp_free_i32(t1);
3399e30f
NF
2132 } else {
2133 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2134 }
2135 opn = "rotr";
7a387fff 2136 break;
d26bc211 2137#if defined(TARGET_MIPS64)
7a387fff 2138 case OPC_DSLL:
324d9e32 2139 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2140 opn = "dsll";
2141 break;
2142 case OPC_DSRA:
324d9e32 2143 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2144 opn = "dsra";
2145 break;
2146 case OPC_DSRL:
ea63e2c3
NF
2147 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2148 opn = "dsrl";
2149 break;
2150 case OPC_DROTR:
2151 if (uimm != 0) {
2152 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2153 } else {
2154 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2155 }
ea63e2c3 2156 opn = "drotr";
7a387fff
TS
2157 break;
2158 case OPC_DSLL32:
324d9e32 2159 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2160 opn = "dsll32";
2161 break;
2162 case OPC_DSRA32:
324d9e32 2163 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2164 opn = "dsra32";
2165 break;
2166 case OPC_DSRL32:
ea63e2c3
NF
2167 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2168 opn = "dsrl32";
2169 break;
2170 case OPC_DROTR32:
2171 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2172 opn = "drotr32";
6af0bf9c 2173 break;
7a387fff 2174#endif
6af0bf9c 2175 }
2abf314d 2176 (void)opn; /* avoid a compiler warning */
93b12ccc 2177 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2178 tcg_temp_free(t0);
6af0bf9c
FB
2179}
2180
2181/* Arithmetic */
7db13fae 2182static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2183 int rd, int rs, int rt)
2184{
923617a3 2185 const char *opn = "arith";
6af0bf9c 2186
7a387fff
TS
2187 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2188 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2189 /* If no destination, treat it as a NOP.
2190 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2191 MIPS_DEBUG("NOP");
460f00c4 2192 return;
185f0762 2193 }
460f00c4 2194
6af0bf9c
FB
2195 switch (opc) {
2196 case OPC_ADD:
48d38ca5 2197 {
460f00c4
AJ
2198 TCGv t0 = tcg_temp_local_new();
2199 TCGv t1 = tcg_temp_new();
2200 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2201 int l1 = gen_new_label();
2202
460f00c4
AJ
2203 gen_load_gpr(t1, rs);
2204 gen_load_gpr(t2, rt);
2205 tcg_gen_add_tl(t0, t1, t2);
2206 tcg_gen_ext32s_tl(t0, t0);
2207 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2208 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2209 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2210 tcg_temp_free(t2);
2211 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2212 tcg_temp_free(t1);
48d38ca5
TS
2213 /* operands of same sign, result different sign */
2214 generate_exception(ctx, EXCP_OVERFLOW);
2215 gen_set_label(l1);
460f00c4
AJ
2216 gen_store_gpr(t0, rd);
2217 tcg_temp_free(t0);
48d38ca5 2218 }
6af0bf9c
FB
2219 opn = "add";
2220 break;
2221 case OPC_ADDU:
460f00c4
AJ
2222 if (rs != 0 && rt != 0) {
2223 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2224 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2225 } else if (rs == 0 && rt != 0) {
2226 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2227 } else if (rs != 0 && rt == 0) {
2228 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2229 } else {
2230 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2231 }
6af0bf9c
FB
2232 opn = "addu";
2233 break;
2234 case OPC_SUB:
48d38ca5 2235 {
460f00c4
AJ
2236 TCGv t0 = tcg_temp_local_new();
2237 TCGv t1 = tcg_temp_new();
2238 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2239 int l1 = gen_new_label();
2240
460f00c4
AJ
2241 gen_load_gpr(t1, rs);
2242 gen_load_gpr(t2, rt);
2243 tcg_gen_sub_tl(t0, t1, t2);
2244 tcg_gen_ext32s_tl(t0, t0);
2245 tcg_gen_xor_tl(t2, t1, t2);
2246 tcg_gen_xor_tl(t1, t0, t1);
2247 tcg_gen_and_tl(t1, t1, t2);
2248 tcg_temp_free(t2);
2249 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2250 tcg_temp_free(t1);
31e3104f 2251 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2252 generate_exception(ctx, EXCP_OVERFLOW);
2253 gen_set_label(l1);
460f00c4
AJ
2254 gen_store_gpr(t0, rd);
2255 tcg_temp_free(t0);
48d38ca5 2256 }
6af0bf9c
FB
2257 opn = "sub";
2258 break;
2259 case OPC_SUBU:
460f00c4
AJ
2260 if (rs != 0 && rt != 0) {
2261 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2262 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2263 } else if (rs == 0 && rt != 0) {
2264 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2265 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2266 } else if (rs != 0 && rt == 0) {
2267 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2268 } else {
2269 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2270 }
6af0bf9c
FB
2271 opn = "subu";
2272 break;
d26bc211 2273#if defined(TARGET_MIPS64)
7a387fff 2274 case OPC_DADD:
48d38ca5 2275 {
460f00c4
AJ
2276 TCGv t0 = tcg_temp_local_new();
2277 TCGv t1 = tcg_temp_new();
2278 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2279 int l1 = gen_new_label();
2280
460f00c4
AJ
2281 gen_load_gpr(t1, rs);
2282 gen_load_gpr(t2, rt);
2283 tcg_gen_add_tl(t0, t1, t2);
2284 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2285 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2286 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2287 tcg_temp_free(t2);
2288 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2289 tcg_temp_free(t1);
48d38ca5
TS
2290 /* operands of same sign, result different sign */
2291 generate_exception(ctx, EXCP_OVERFLOW);
2292 gen_set_label(l1);
460f00c4
AJ
2293 gen_store_gpr(t0, rd);
2294 tcg_temp_free(t0);
48d38ca5 2295 }
7a387fff
TS
2296 opn = "dadd";
2297 break;
2298 case OPC_DADDU:
460f00c4
AJ
2299 if (rs != 0 && rt != 0) {
2300 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2301 } else if (rs == 0 && rt != 0) {
2302 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2303 } else if (rs != 0 && rt == 0) {
2304 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2305 } else {
2306 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2307 }
7a387fff
TS
2308 opn = "daddu";
2309 break;
2310 case OPC_DSUB:
48d38ca5 2311 {
460f00c4
AJ
2312 TCGv t0 = tcg_temp_local_new();
2313 TCGv t1 = tcg_temp_new();
2314 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2315 int l1 = gen_new_label();
2316
460f00c4
AJ
2317 gen_load_gpr(t1, rs);
2318 gen_load_gpr(t2, rt);
2319 tcg_gen_sub_tl(t0, t1, t2);
2320 tcg_gen_xor_tl(t2, t1, t2);
2321 tcg_gen_xor_tl(t1, t0, t1);
2322 tcg_gen_and_tl(t1, t1, t2);
2323 tcg_temp_free(t2);
2324 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2325 tcg_temp_free(t1);
31e3104f 2326 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2327 generate_exception(ctx, EXCP_OVERFLOW);
2328 gen_set_label(l1);
460f00c4
AJ
2329 gen_store_gpr(t0, rd);
2330 tcg_temp_free(t0);
48d38ca5 2331 }
7a387fff
TS
2332 opn = "dsub";
2333 break;
2334 case OPC_DSUBU:
460f00c4
AJ
2335 if (rs != 0 && rt != 0) {
2336 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2337 } else if (rs == 0 && rt != 0) {
2338 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2339 } else if (rs != 0 && rt == 0) {
2340 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2341 } else {
2342 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2343 }
7a387fff
TS
2344 opn = "dsubu";
2345 break;
2346#endif
460f00c4
AJ
2347 case OPC_MUL:
2348 if (likely(rs != 0 && rt != 0)) {
2349 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2350 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2351 } else {
2352 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2353 }
2354 opn = "mul";
6af0bf9c 2355 break;
460f00c4 2356 }
2abf314d 2357 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2358 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2359}
2360
2361/* Conditional move */
9fa77488
RH
2362static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2363 int rd, int rs, int rt)
460f00c4
AJ
2364{
2365 const char *opn = "cond move";
acf12465 2366 TCGv t0, t1, t2;
460f00c4
AJ
2367
2368 if (rd == 0) {
acf12465 2369 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2370 MIPS_DEBUG("NOP");
2371 return;
2372 }
2373
acf12465
AJ
2374 t0 = tcg_temp_new();
2375 gen_load_gpr(t0, rt);
2376 t1 = tcg_const_tl(0);
2377 t2 = tcg_temp_new();
2378 gen_load_gpr(t2, rs);
460f00c4
AJ
2379 switch (opc) {
2380 case OPC_MOVN:
acf12465 2381 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2382 opn = "movn";
6af0bf9c 2383 break;
460f00c4 2384 case OPC_MOVZ:
acf12465 2385 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2386 opn = "movz";
2387 break;
2388 }
acf12465
AJ
2389 tcg_temp_free(t2);
2390 tcg_temp_free(t1);
2391 tcg_temp_free(t0);
460f00c4 2392
2abf314d 2393 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2394 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2395}
2396
2397/* Logic */
9fa77488
RH
2398static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2399 int rd, int rs, int rt)
460f00c4
AJ
2400{
2401 const char *opn = "logic";
2402
2403 if (rd == 0) {
2404 /* If no destination, treat it as a NOP. */
2405 MIPS_DEBUG("NOP");
2406 return;
2407 }
2408
2409 switch (opc) {
6af0bf9c 2410 case OPC_AND:
460f00c4
AJ
2411 if (likely(rs != 0 && rt != 0)) {
2412 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2413 } else {
2414 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2415 }
6af0bf9c
FB
2416 opn = "and";
2417 break;
2418 case OPC_NOR:
460f00c4
AJ
2419 if (rs != 0 && rt != 0) {
2420 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2421 } else if (rs == 0 && rt != 0) {
2422 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2423 } else if (rs != 0 && rt == 0) {
2424 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2425 } else {
2426 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2427 }
6af0bf9c
FB
2428 opn = "nor";
2429 break;
2430 case OPC_OR:
460f00c4
AJ
2431 if (likely(rs != 0 && rt != 0)) {
2432 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2433 } else if (rs == 0 && rt != 0) {
2434 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2435 } else if (rs != 0 && rt == 0) {
2436 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2437 } else {
2438 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2439 }
6af0bf9c
FB
2440 opn = "or";
2441 break;
2442 case OPC_XOR:
460f00c4
AJ
2443 if (likely(rs != 0 && rt != 0)) {
2444 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2445 } else if (rs == 0 && rt != 0) {
2446 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2447 } else if (rs != 0 && rt == 0) {
2448 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2449 } else {
2450 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2451 }
6af0bf9c
FB
2452 opn = "xor";
2453 break;
460f00c4 2454 }
2abf314d 2455 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2456 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2457}
2458
2459/* Set on lower than */
9fa77488
RH
2460static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2461 int rd, int rs, int rt)
460f00c4
AJ
2462{
2463 const char *opn = "slt";
2464 TCGv t0, t1;
2465
2466 if (rd == 0) {
2467 /* If no destination, treat it as a NOP. */
2468 MIPS_DEBUG("NOP");
2469 return;
2470 }
2471
2472 t0 = tcg_temp_new();
2473 t1 = tcg_temp_new();
2474 gen_load_gpr(t0, rs);
2475 gen_load_gpr(t1, rt);
2476 switch (opc) {
2477 case OPC_SLT:
e68dd28f 2478 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2479 opn = "slt";
6af0bf9c 2480 break;
460f00c4 2481 case OPC_SLTU:
e68dd28f 2482 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2483 opn = "sltu";
2484 break;
2485 }
2abf314d 2486 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2487 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2488 tcg_temp_free(t0);
2489 tcg_temp_free(t1);
2490}
20c4c97c 2491
460f00c4 2492/* Shifts */
7db13fae 2493static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
460f00c4
AJ
2494 int rd, int rs, int rt)
2495{
2496 const char *opn = "shifts";
2497 TCGv t0, t1;
20c4c97c 2498
460f00c4
AJ
2499 if (rd == 0) {
2500 /* If no destination, treat it as a NOP.
2501 For add & sub, we must generate the overflow exception when needed. */
2502 MIPS_DEBUG("NOP");
2503 return;
2504 }
2505
2506 t0 = tcg_temp_new();
2507 t1 = tcg_temp_new();
2508 gen_load_gpr(t0, rs);
2509 gen_load_gpr(t1, rt);
2510 switch (opc) {
6af0bf9c 2511 case OPC_SLLV:
78723684
TS
2512 tcg_gen_andi_tl(t0, t0, 0x1f);
2513 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2514 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2515 opn = "sllv";
2516 break;
2517 case OPC_SRAV:
78723684 2518 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2519 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2520 opn = "srav";
2521 break;
2522 case OPC_SRLV:
ea63e2c3
NF
2523 tcg_gen_ext32u_tl(t1, t1);
2524 tcg_gen_andi_tl(t0, t0, 0x1f);
2525 tcg_gen_shr_tl(t0, t1, t0);
2526 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2527 opn = "srlv";
2528 break;
2529 case OPC_ROTRV:
2530 {
2531 TCGv_i32 t2 = tcg_temp_new_i32();
2532 TCGv_i32 t3 = tcg_temp_new_i32();
2533
2534 tcg_gen_trunc_tl_i32(t2, t0);
2535 tcg_gen_trunc_tl_i32(t3, t1);
2536 tcg_gen_andi_i32(t2, t2, 0x1f);
2537 tcg_gen_rotr_i32(t2, t3, t2);
2538 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2539 tcg_temp_free_i32(t2);
2540 tcg_temp_free_i32(t3);
2541 opn = "rotrv";
5a63bcb2 2542 }
7a387fff 2543 break;
d26bc211 2544#if defined(TARGET_MIPS64)
7a387fff 2545 case OPC_DSLLV:
78723684 2546 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2547 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2548 opn = "dsllv";
2549 break;
2550 case OPC_DSRAV:
78723684 2551 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2552 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2553 opn = "dsrav";
2554 break;
2555 case OPC_DSRLV:
ea63e2c3
NF
2556 tcg_gen_andi_tl(t0, t0, 0x3f);
2557 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2558 opn = "dsrlv";
2559 break;
2560 case OPC_DROTRV:
2561 tcg_gen_andi_tl(t0, t0, 0x3f);
2562 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2563 opn = "drotrv";
6af0bf9c 2564 break;
7a387fff 2565#endif
6af0bf9c 2566 }
2abf314d 2567 (void)opn; /* avoid a compiler warning */
6af0bf9c 2568 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2569 tcg_temp_free(t0);
2570 tcg_temp_free(t1);
6af0bf9c
FB
2571}
2572
2573/* Arithmetic on HI/LO registers */
7a387fff 2574static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
6af0bf9c 2575{
923617a3 2576 const char *opn = "hilo";
4133498f 2577 unsigned int acc;
6af0bf9c
FB
2578
2579 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2580 /* Treat as NOP. */
6af0bf9c 2581 MIPS_DEBUG("NOP");
a1f6684d 2582 return;
6af0bf9c 2583 }
4133498f
JL
2584
2585 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2586 acc = ((ctx->opcode) >> 21) & 0x03;
2587 } else {
2588 acc = ((ctx->opcode) >> 11) & 0x03;
2589 }
2590
2591 if (acc != 0) {
2592 check_dsp(ctx);
2593 }
2594
6af0bf9c
FB
2595 switch (opc) {
2596 case OPC_MFHI:
4133498f
JL
2597#if defined(TARGET_MIPS64)
2598 if (acc != 0) {
2599 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2600 } else
2601#endif
2602 {
2603 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2604 }
6af0bf9c
FB
2605 opn = "mfhi";
2606 break;
2607 case OPC_MFLO:
4133498f
JL
2608#if defined(TARGET_MIPS64)
2609 if (acc != 0) {
2610 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2611 } else
2612#endif
2613 {
2614 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2615 }
6af0bf9c
FB
2616 opn = "mflo";
2617 break;
2618 case OPC_MTHI:
4133498f
JL
2619 if (reg != 0) {
2620#if defined(TARGET_MIPS64)
2621 if (acc != 0) {
2622 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2623 } else
2624#endif
2625 {
2626 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2627 }
2628 } else {
2629 tcg_gen_movi_tl(cpu_HI[acc], 0);
2630 }
6af0bf9c
FB
2631 opn = "mthi";
2632 break;
2633 case OPC_MTLO:
4133498f
JL
2634 if (reg != 0) {
2635#if defined(TARGET_MIPS64)
2636 if (acc != 0) {
2637 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2638 } else
2639#endif
2640 {
2641 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2642 }
2643 } else {
2644 tcg_gen_movi_tl(cpu_LO[acc], 0);
2645 }
6af0bf9c
FB
2646 opn = "mtlo";
2647 break;
6af0bf9c 2648 }
2abf314d 2649 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2650 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2651}
2652
7a387fff 2653static void gen_muldiv (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2654 int rs, int rt)
2655{
923617a3 2656 const char *opn = "mul/div";
d45f89f4 2657 TCGv t0, t1;
4133498f 2658 unsigned int acc;
d45f89f4 2659
51127181
AJ
2660 t0 = tcg_temp_new();
2661 t1 = tcg_temp_new();
6af0bf9c 2662
78723684
TS
2663 gen_load_gpr(t0, rs);
2664 gen_load_gpr(t1, rt);
51127181 2665
6af0bf9c
FB
2666 switch (opc) {
2667 case OPC_DIV:
48d38ca5 2668 {
51127181
AJ
2669 TCGv t2 = tcg_temp_new();
2670 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2671 tcg_gen_ext32s_tl(t0, t0);
2672 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2673 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2674 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2675 tcg_gen_and_tl(t2, t2, t3);
2676 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2677 tcg_gen_or_tl(t2, t2, t3);
2678 tcg_gen_movi_tl(t3, 0);
2679 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
d45f89f4
AJ
2680 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2681 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2682 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2683 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
51127181
AJ
2684 tcg_temp_free(t3);
2685 tcg_temp_free(t2);
48d38ca5 2686 }
6af0bf9c
FB
2687 opn = "div";
2688 break;
2689 case OPC_DIVU:
48d38ca5 2690 {
51127181
AJ
2691 TCGv t2 = tcg_const_tl(0);
2692 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
2693 tcg_gen_ext32u_tl(t0, t0);
2694 tcg_gen_ext32u_tl(t1, t1);
51127181 2695 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
d45f89f4
AJ
2696 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2697 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2698 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2699 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
51127181
AJ
2700 tcg_temp_free(t3);
2701 tcg_temp_free(t2);
48d38ca5 2702 }
6af0bf9c
FB
2703 opn = "divu";
2704 break;
2705 case OPC_MULT:
214c465f 2706 {
d45f89f4
AJ
2707 TCGv_i64 t2 = tcg_temp_new_i64();
2708 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2709 acc = ((ctx->opcode) >> 11) & 0x03;
2710 if (acc != 0) {
2711 check_dsp(ctx);
2712 }
d45f89f4
AJ
2713
2714 tcg_gen_ext_tl_i64(t2, t0);
2715 tcg_gen_ext_tl_i64(t3, t1);
2716 tcg_gen_mul_i64(t2, t2, t3);
2717 tcg_temp_free_i64(t3);
2718 tcg_gen_trunc_i64_tl(t0, t2);
2719 tcg_gen_shri_i64(t2, t2, 32);
2720 tcg_gen_trunc_i64_tl(t1, t2);
2721 tcg_temp_free_i64(t2);
4133498f
JL
2722 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2723 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2724 }
6af0bf9c
FB
2725 opn = "mult";
2726 break;
2727 case OPC_MULTU:
214c465f 2728 {
d45f89f4
AJ
2729 TCGv_i64 t2 = tcg_temp_new_i64();
2730 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2731 acc = ((ctx->opcode) >> 11) & 0x03;
2732 if (acc != 0) {
2733 check_dsp(ctx);
2734 }
214c465f 2735
78723684
TS
2736 tcg_gen_ext32u_tl(t0, t0);
2737 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2738 tcg_gen_extu_tl_i64(t2, t0);
2739 tcg_gen_extu_tl_i64(t3, t1);
2740 tcg_gen_mul_i64(t2, t2, t3);
2741 tcg_temp_free_i64(t3);
2742 tcg_gen_trunc_i64_tl(t0, t2);
2743 tcg_gen_shri_i64(t2, t2, 32);
2744 tcg_gen_trunc_i64_tl(t1, t2);
2745 tcg_temp_free_i64(t2);
4133498f
JL
2746 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2747 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2748 }
6af0bf9c
FB
2749 opn = "multu";
2750 break;
d26bc211 2751#if defined(TARGET_MIPS64)
7a387fff 2752 case OPC_DDIV:
48d38ca5 2753 {
51127181
AJ
2754 TCGv t2 = tcg_temp_new();
2755 TCGv t3 = tcg_temp_new();
2756 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2757 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2758 tcg_gen_and_tl(t2, t2, t3);
2759 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2760 tcg_gen_or_tl(t2, t2, t3);
2761 tcg_gen_movi_tl(t3, 0);
2762 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2763 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2764 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2765 tcg_temp_free(t3);
2766 tcg_temp_free(t2);
48d38ca5 2767 }
7a387fff
TS
2768 opn = "ddiv";
2769 break;
2770 case OPC_DDIVU:
48d38ca5 2771 {
51127181
AJ
2772 TCGv t2 = tcg_const_tl(0);
2773 TCGv t3 = tcg_const_tl(1);
2774 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
b10fa3c9
AJ
2775 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2776 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
51127181
AJ
2777 tcg_temp_free(t3);
2778 tcg_temp_free(t2);
48d38ca5 2779 }
7a387fff
TS
2780 opn = "ddivu";
2781 break;
2782 case OPC_DMULT:
895c2d04 2783 gen_helper_dmult(cpu_env, t0, t1);
7a387fff
TS
2784 opn = "dmult";
2785 break;
2786 case OPC_DMULTU:
895c2d04 2787 gen_helper_dmultu(cpu_env, t0, t1);
7a387fff
TS
2788 opn = "dmultu";
2789 break;
2790#endif
6af0bf9c 2791 case OPC_MADD:
214c465f 2792 {
d45f89f4
AJ
2793 TCGv_i64 t2 = tcg_temp_new_i64();
2794 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2795 acc = ((ctx->opcode) >> 11) & 0x03;
2796 if (acc != 0) {
2797 check_dsp(ctx);
2798 }
d45f89f4
AJ
2799
2800 tcg_gen_ext_tl_i64(t2, t0);
2801 tcg_gen_ext_tl_i64(t3, t1);
2802 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2803 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2804 tcg_gen_add_i64(t2, t2, t3);
2805 tcg_temp_free_i64(t3);
2806 tcg_gen_trunc_i64_tl(t0, t2);
2807 tcg_gen_shri_i64(t2, t2, 32);
2808 tcg_gen_trunc_i64_tl(t1, t2);
2809 tcg_temp_free_i64(t2);
4133498f
JL
2810 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2811 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2812 }
6af0bf9c
FB
2813 opn = "madd";
2814 break;
2815 case OPC_MADDU:
4133498f 2816 {
d45f89f4
AJ
2817 TCGv_i64 t2 = tcg_temp_new_i64();
2818 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2819 acc = ((ctx->opcode) >> 11) & 0x03;
2820 if (acc != 0) {
2821 check_dsp(ctx);
2822 }
214c465f 2823
78723684
TS
2824 tcg_gen_ext32u_tl(t0, t0);
2825 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2826 tcg_gen_extu_tl_i64(t2, t0);
2827 tcg_gen_extu_tl_i64(t3, t1);
2828 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2829 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2830 tcg_gen_add_i64(t2, t2, t3);
2831 tcg_temp_free_i64(t3);
2832 tcg_gen_trunc_i64_tl(t0, t2);
2833 tcg_gen_shri_i64(t2, t2, 32);
2834 tcg_gen_trunc_i64_tl(t1, t2);
2835 tcg_temp_free_i64(t2);
4133498f
JL
2836 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2837 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2838 }
6af0bf9c
FB
2839 opn = "maddu";
2840 break;
2841 case OPC_MSUB:
214c465f 2842 {
d45f89f4
AJ
2843 TCGv_i64 t2 = tcg_temp_new_i64();
2844 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2845 acc = ((ctx->opcode) >> 11) & 0x03;
2846 if (acc != 0) {
2847 check_dsp(ctx);
2848 }
d45f89f4
AJ
2849
2850 tcg_gen_ext_tl_i64(t2, t0);
2851 tcg_gen_ext_tl_i64(t3, t1);
2852 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2853 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2854 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2855 tcg_temp_free_i64(t3);
2856 tcg_gen_trunc_i64_tl(t0, t2);
2857 tcg_gen_shri_i64(t2, t2, 32);
2858 tcg_gen_trunc_i64_tl(t1, t2);
2859 tcg_temp_free_i64(t2);
4133498f
JL
2860 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2861 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2862 }
6af0bf9c
FB
2863 opn = "msub";
2864 break;
2865 case OPC_MSUBU:
214c465f 2866 {
d45f89f4
AJ
2867 TCGv_i64 t2 = tcg_temp_new_i64();
2868 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2869 acc = ((ctx->opcode) >> 11) & 0x03;
2870 if (acc != 0) {
2871 check_dsp(ctx);
2872 }
214c465f 2873
78723684
TS
2874 tcg_gen_ext32u_tl(t0, t0);
2875 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2876 tcg_gen_extu_tl_i64(t2, t0);
2877 tcg_gen_extu_tl_i64(t3, t1);
2878 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2879 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2880 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2881 tcg_temp_free_i64(t3);
2882 tcg_gen_trunc_i64_tl(t0, t2);
2883 tcg_gen_shri_i64(t2, t2, 32);
2884 tcg_gen_trunc_i64_tl(t1, t2);
2885 tcg_temp_free_i64(t2);
4133498f
JL
2886 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2887 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2888 }
6af0bf9c
FB
2889 opn = "msubu";
2890 break;
2891 default:
923617a3 2892 MIPS_INVAL(opn);
6af0bf9c 2893 generate_exception(ctx, EXCP_RI);
78723684 2894 goto out;
6af0bf9c 2895 }
2abf314d 2896 (void)opn; /* avoid a compiler warning */
6af0bf9c 2897 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2898 out:
2899 tcg_temp_free(t0);
2900 tcg_temp_free(t1);
6af0bf9c
FB
2901}
2902
e9c71dd1
TS
2903static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2904 int rd, int rs, int rt)
2905{
2906 const char *opn = "mul vr54xx";
f157bfe1
AJ
2907 TCGv t0 = tcg_temp_new();
2908 TCGv t1 = tcg_temp_new();
e9c71dd1 2909
6c5c1e20
TS
2910 gen_load_gpr(t0, rs);
2911 gen_load_gpr(t1, rt);
e9c71dd1
TS
2912
2913 switch (opc) {
2914 case OPC_VR54XX_MULS:
895c2d04 2915 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2916 opn = "muls";
6958549d 2917 break;
e9c71dd1 2918 case OPC_VR54XX_MULSU:
895c2d04 2919 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2920 opn = "mulsu";
6958549d 2921 break;
e9c71dd1 2922 case OPC_VR54XX_MACC:
895c2d04 2923 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2924 opn = "macc";
6958549d 2925 break;
e9c71dd1 2926 case OPC_VR54XX_MACCU:
895c2d04 2927 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2928 opn = "maccu";
6958549d 2929 break;
e9c71dd1 2930 case OPC_VR54XX_MSAC:
895c2d04 2931 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2932 opn = "msac";
6958549d 2933 break;
e9c71dd1 2934 case OPC_VR54XX_MSACU:
895c2d04 2935 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2936 opn = "msacu";
6958549d 2937 break;
e9c71dd1 2938 case OPC_VR54XX_MULHI:
895c2d04 2939 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2940 opn = "mulhi";
6958549d 2941 break;
e9c71dd1 2942 case OPC_VR54XX_MULHIU:
895c2d04 2943 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2944 opn = "mulhiu";
6958549d 2945 break;
e9c71dd1 2946 case OPC_VR54XX_MULSHI:
895c2d04 2947 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2948 opn = "mulshi";
6958549d 2949 break;
e9c71dd1 2950 case OPC_VR54XX_MULSHIU:
895c2d04 2951 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2952 opn = "mulshiu";
6958549d 2953 break;
e9c71dd1 2954 case OPC_VR54XX_MACCHI:
895c2d04 2955 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2956 opn = "macchi";
6958549d 2957 break;
e9c71dd1 2958 case OPC_VR54XX_MACCHIU:
895c2d04 2959 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2960 opn = "macchiu";
6958549d 2961 break;
e9c71dd1 2962 case OPC_VR54XX_MSACHI:
895c2d04 2963 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2964 opn = "msachi";
6958549d 2965 break;
e9c71dd1 2966 case OPC_VR54XX_MSACHIU:
895c2d04 2967 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2968 opn = "msachiu";
6958549d 2969 break;
e9c71dd1
TS
2970 default:
2971 MIPS_INVAL("mul vr54xx");
2972 generate_exception(ctx, EXCP_RI);
6c5c1e20 2973 goto out;
e9c71dd1 2974 }
6c5c1e20 2975 gen_store_gpr(t0, rd);
2abf314d 2976 (void)opn; /* avoid a compiler warning */
e9c71dd1 2977 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2978
2979 out:
2980 tcg_temp_free(t0);
2981 tcg_temp_free(t1);
e9c71dd1
TS
2982}
2983
7a387fff 2984static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2985 int rd, int rs)
2986{
923617a3 2987 const char *opn = "CLx";
20e1fb52 2988 TCGv t0;
6c5c1e20 2989
6af0bf9c 2990 if (rd == 0) {
ead9360e 2991 /* Treat as NOP. */
6af0bf9c 2992 MIPS_DEBUG("NOP");
20e1fb52 2993 return;
6af0bf9c 2994 }
20e1fb52 2995 t0 = tcg_temp_new();
6c5c1e20 2996 gen_load_gpr(t0, rs);
6af0bf9c
FB
2997 switch (opc) {
2998 case OPC_CLO:
20e1fb52 2999 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3000 opn = "clo";
3001 break;
3002 case OPC_CLZ:
20e1fb52 3003 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3004 opn = "clz";
3005 break;
d26bc211 3006#if defined(TARGET_MIPS64)
7a387fff 3007 case OPC_DCLO:
20e1fb52 3008 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3009 opn = "dclo";
3010 break;
3011 case OPC_DCLZ:
20e1fb52 3012 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3013 opn = "dclz";
3014 break;
3015#endif
6af0bf9c 3016 }
2abf314d 3017 (void)opn; /* avoid a compiler warning */
6af0bf9c 3018 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3019 tcg_temp_free(t0);
6af0bf9c
FB
3020}
3021
161f85e6 3022/* Godson integer instructions */
bd277fa1
RH
3023static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3024 int rd, int rs, int rt)
161f85e6
AJ
3025{
3026 const char *opn = "loongson";
3027 TCGv t0, t1;
3028
3029 if (rd == 0) {
3030 /* Treat as NOP. */
3031 MIPS_DEBUG("NOP");
3032 return;
3033 }
3034
3035 switch (opc) {
3036 case OPC_MULT_G_2E:
3037 case OPC_MULT_G_2F:
3038 case OPC_MULTU_G_2E:
3039 case OPC_MULTU_G_2F:
3040#if defined(TARGET_MIPS64)
3041 case OPC_DMULT_G_2E:
3042 case OPC_DMULT_G_2F:
3043 case OPC_DMULTU_G_2E:
3044 case OPC_DMULTU_G_2F:
3045#endif
3046 t0 = tcg_temp_new();
3047 t1 = tcg_temp_new();
3048 break;
3049 default:
3050 t0 = tcg_temp_local_new();
3051 t1 = tcg_temp_local_new();
3052 break;
3053 }
3054
3055 gen_load_gpr(t0, rs);
3056 gen_load_gpr(t1, rt);
3057
3058 switch (opc) {
3059 case OPC_MULT_G_2E:
3060 case OPC_MULT_G_2F:
3061 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3062 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3063 opn = "mult.g";
3064 break;
3065 case OPC_MULTU_G_2E:
3066 case OPC_MULTU_G_2F:
3067 tcg_gen_ext32u_tl(t0, t0);
3068 tcg_gen_ext32u_tl(t1, t1);
3069 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3070 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3071 opn = "multu.g";
3072 break;
3073 case OPC_DIV_G_2E:
3074 case OPC_DIV_G_2F:
3075 {
3076 int l1 = gen_new_label();
3077 int l2 = gen_new_label();
3078 int l3 = gen_new_label();
3079 tcg_gen_ext32s_tl(t0, t0);
3080 tcg_gen_ext32s_tl(t1, t1);
3081 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3082 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3083 tcg_gen_br(l3);
3084 gen_set_label(l1);
3085 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3086 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3087 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3088 tcg_gen_br(l3);
3089 gen_set_label(l2);
3090 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3091 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3092 gen_set_label(l3);
3093 }
3094 opn = "div.g";
3095 break;
3096 case OPC_DIVU_G_2E:
3097 case OPC_DIVU_G_2F:
3098 {
3099 int l1 = gen_new_label();
3100 int l2 = gen_new_label();
3101 tcg_gen_ext32u_tl(t0, t0);
3102 tcg_gen_ext32u_tl(t1, t1);
3103 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3104 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3105 tcg_gen_br(l2);
3106 gen_set_label(l1);
3107 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3108 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3109 gen_set_label(l2);
3110 }
3111 opn = "divu.g";
3112 break;
3113 case OPC_MOD_G_2E:
3114 case OPC_MOD_G_2F:
3115 {
3116 int l1 = gen_new_label();
3117 int l2 = gen_new_label();
3118 int l3 = gen_new_label();
3119 tcg_gen_ext32u_tl(t0, t0);
3120 tcg_gen_ext32u_tl(t1, t1);
3121 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3122 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3123 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3124 gen_set_label(l1);
3125 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3126 tcg_gen_br(l3);
3127 gen_set_label(l2);
3128 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3129 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3130 gen_set_label(l3);
3131 }
3132 opn = "mod.g";
3133 break;
3134 case OPC_MODU_G_2E:
3135 case OPC_MODU_G_2F:
3136 {
3137 int l1 = gen_new_label();
3138 int l2 = gen_new_label();
3139 tcg_gen_ext32u_tl(t0, t0);
3140 tcg_gen_ext32u_tl(t1, t1);
3141 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3142 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3143 tcg_gen_br(l2);
3144 gen_set_label(l1);
3145 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3146 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3147 gen_set_label(l2);
3148 }
3149 opn = "modu.g";
3150 break;
3151#if defined(TARGET_MIPS64)
3152 case OPC_DMULT_G_2E:
3153 case OPC_DMULT_G_2F:
3154 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3155 opn = "dmult.g";
3156 break;
3157 case OPC_DMULTU_G_2E:
3158 case OPC_DMULTU_G_2F:
3159 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3160 opn = "dmultu.g";
3161 break;
3162 case OPC_DDIV_G_2E:
3163 case OPC_DDIV_G_2F:
3164 {
3165 int l1 = gen_new_label();
3166 int l2 = gen_new_label();
3167 int l3 = gen_new_label();
3168 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3169 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3170 tcg_gen_br(l3);
3171 gen_set_label(l1);
3172 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3173 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3174 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3175 tcg_gen_br(l3);
3176 gen_set_label(l2);
3177 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3178 gen_set_label(l3);
3179 }
3180 opn = "ddiv.g";
3181 break;
3182 case OPC_DDIVU_G_2E:
3183 case OPC_DDIVU_G_2F:
3184 {
3185 int l1 = gen_new_label();
3186 int l2 = gen_new_label();
3187 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3188 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3189 tcg_gen_br(l2);
3190 gen_set_label(l1);
3191 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3192 gen_set_label(l2);
3193 }
3194 opn = "ddivu.g";
3195 break;
3196 case OPC_DMOD_G_2E:
3197 case OPC_DMOD_G_2F:
3198 {
3199 int l1 = gen_new_label();
3200 int l2 = gen_new_label();
3201 int l3 = gen_new_label();
3202 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3203 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3204 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3205 gen_set_label(l1);
3206 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3207 tcg_gen_br(l3);
3208 gen_set_label(l2);
3209 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3210 gen_set_label(l3);
3211 }
3212 opn = "dmod.g";
3213 break;
3214 case OPC_DMODU_G_2E:
3215 case OPC_DMODU_G_2F:
3216 {
3217 int l1 = gen_new_label();
3218 int l2 = gen_new_label();
3219 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3220 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3221 tcg_gen_br(l2);
3222 gen_set_label(l1);
3223 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3224 gen_set_label(l2);
3225 }
3226 opn = "dmodu.g";
3227 break;
3228#endif
3229 }
3230
2abf314d 3231 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3232 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3233 tcg_temp_free(t0);
3234 tcg_temp_free(t1);
3235}
3236
bd277fa1
RH
3237/* Loongson multimedia instructions */
3238static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3239{
3240 const char *opn = "loongson_cp2";
3241 uint32_t opc, shift_max;
3242 TCGv_i64 t0, t1;
3243
3244 opc = MASK_LMI(ctx->opcode);
3245 switch (opc) {
3246 case OPC_ADD_CP2:
3247 case OPC_SUB_CP2:
3248 case OPC_DADD_CP2:
3249 case OPC_DSUB_CP2:
3250 t0 = tcg_temp_local_new_i64();
3251 t1 = tcg_temp_local_new_i64();
3252 break;
3253 default:
3254 t0 = tcg_temp_new_i64();
3255 t1 = tcg_temp_new_i64();
3256 break;
3257 }
3258
3259 gen_load_fpr64(ctx, t0, rs);
3260 gen_load_fpr64(ctx, t1, rt);
3261
3262#define LMI_HELPER(UP, LO) \
3263 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3264#define LMI_HELPER_1(UP, LO) \
3265 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3266#define LMI_DIRECT(UP, LO, OP) \
3267 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3268
3269 switch (opc) {
3270 LMI_HELPER(PADDSH, paddsh);
3271 LMI_HELPER(PADDUSH, paddush);
3272 LMI_HELPER(PADDH, paddh);
3273 LMI_HELPER(PADDW, paddw);
3274 LMI_HELPER(PADDSB, paddsb);
3275 LMI_HELPER(PADDUSB, paddusb);
3276 LMI_HELPER(PADDB, paddb);
3277
3278 LMI_HELPER(PSUBSH, psubsh);
3279 LMI_HELPER(PSUBUSH, psubush);
3280 LMI_HELPER(PSUBH, psubh);
3281 LMI_HELPER(PSUBW, psubw);
3282 LMI_HELPER(PSUBSB, psubsb);
3283 LMI_HELPER(PSUBUSB, psubusb);
3284 LMI_HELPER(PSUBB, psubb);
3285
3286 LMI_HELPER(PSHUFH, pshufh);
3287 LMI_HELPER(PACKSSWH, packsswh);
3288 LMI_HELPER(PACKSSHB, packsshb);
3289 LMI_HELPER(PACKUSHB, packushb);
3290
3291 LMI_HELPER(PUNPCKLHW, punpcklhw);
3292 LMI_HELPER(PUNPCKHHW, punpckhhw);
3293 LMI_HELPER(PUNPCKLBH, punpcklbh);
3294 LMI_HELPER(PUNPCKHBH, punpckhbh);
3295 LMI_HELPER(PUNPCKLWD, punpcklwd);
3296 LMI_HELPER(PUNPCKHWD, punpckhwd);
3297
3298 LMI_HELPER(PAVGH, pavgh);
3299 LMI_HELPER(PAVGB, pavgb);
3300 LMI_HELPER(PMAXSH, pmaxsh);
3301 LMI_HELPER(PMINSH, pminsh);
3302 LMI_HELPER(PMAXUB, pmaxub);
3303 LMI_HELPER(PMINUB, pminub);
3304
3305 LMI_HELPER(PCMPEQW, pcmpeqw);
3306 LMI_HELPER(PCMPGTW, pcmpgtw);
3307 LMI_HELPER(PCMPEQH, pcmpeqh);
3308 LMI_HELPER(PCMPGTH, pcmpgth);
3309 LMI_HELPER(PCMPEQB, pcmpeqb);
3310 LMI_HELPER(PCMPGTB, pcmpgtb);
3311
3312 LMI_HELPER(PSLLW, psllw);
3313 LMI_HELPER(PSLLH, psllh);
3314 LMI_HELPER(PSRLW, psrlw);
3315 LMI_HELPER(PSRLH, psrlh);
3316 LMI_HELPER(PSRAW, psraw);
3317 LMI_HELPER(PSRAH, psrah);
3318
3319 LMI_HELPER(PMULLH, pmullh);
3320 LMI_HELPER(PMULHH, pmulhh);
3321 LMI_HELPER(PMULHUH, pmulhuh);
3322 LMI_HELPER(PMADDHW, pmaddhw);
3323
3324 LMI_HELPER(PASUBUB, pasubub);
3325 LMI_HELPER_1(BIADD, biadd);
3326 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3327
3328 LMI_DIRECT(PADDD, paddd, add);
3329 LMI_DIRECT(PSUBD, psubd, sub);
3330 LMI_DIRECT(XOR_CP2, xor, xor);
3331 LMI_DIRECT(NOR_CP2, nor, nor);
3332 LMI_DIRECT(AND_CP2, and, and);
3333 LMI_DIRECT(PANDN, pandn, andc);
3334 LMI_DIRECT(OR, or, or);
3335
3336 case OPC_PINSRH_0:
3337 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3338 opn = "pinsrh_0";
3339 break;
3340 case OPC_PINSRH_1:
3341 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3342 opn = "pinsrh_1";
3343 break;
3344 case OPC_PINSRH_2:
3345 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3346 opn = "pinsrh_2";
3347 break;
3348 case OPC_PINSRH_3:
3349 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3350 opn = "pinsrh_3";
3351 break;
3352
3353 case OPC_PEXTRH:
3354 tcg_gen_andi_i64(t1, t1, 3);
3355 tcg_gen_shli_i64(t1, t1, 4);
3356 tcg_gen_shr_i64(t0, t0, t1);
3357 tcg_gen_ext16u_i64(t0, t0);
3358 opn = "pextrh";
3359 break;
3360
3361 case OPC_ADDU_CP2:
3362 tcg_gen_add_i64(t0, t0, t1);
3363 tcg_gen_ext32s_i64(t0, t0);
3364 opn = "addu";
3365 break;
3366 case OPC_SUBU_CP2:
3367 tcg_gen_sub_i64(t0, t0, t1);
3368 tcg_gen_ext32s_i64(t0, t0);
3369 opn = "addu";
3370 break;
3371
3372 case OPC_SLL_CP2:
3373 opn = "sll";
3374 shift_max = 32;
3375 goto do_shift;
3376 case OPC_SRL_CP2:
3377 opn = "srl";
3378 shift_max = 32;
3379 goto do_shift;
3380 case OPC_SRA_CP2:
3381 opn = "sra";
3382 shift_max = 32;
3383 goto do_shift;
3384 case OPC_DSLL_CP2:
3385 opn = "dsll";
3386 shift_max = 64;
3387 goto do_shift;
3388 case OPC_DSRL_CP2:
3389 opn = "dsrl";
3390 shift_max = 64;
3391 goto do_shift;
3392 case OPC_DSRA_CP2:
3393 opn = "dsra";
3394 shift_max = 64;
3395 goto do_shift;
3396 do_shift:
3397 /* Make sure shift count isn't TCG undefined behaviour. */
3398 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3399
3400 switch (opc) {
3401 case OPC_SLL_CP2:
3402 case OPC_DSLL_CP2:
3403 tcg_gen_shl_i64(t0, t0, t1);
3404 break;
3405 case OPC_SRA_CP2:
3406 case OPC_DSRA_CP2:
3407 /* Since SRA is UndefinedResult without sign-extended inputs,
3408 we can treat SRA and DSRA the same. */
3409 tcg_gen_sar_i64(t0, t0, t1);
3410 break;
3411 case OPC_SRL_CP2:
3412 /* We want to shift in zeros for SRL; zero-extend first. */
3413 tcg_gen_ext32u_i64(t0, t0);
3414 /* FALLTHRU */
3415 case OPC_DSRL_CP2:
3416 tcg_gen_shr_i64(t0, t0, t1);
3417 break;
3418 }
3419
3420 if (shift_max == 32) {
3421 tcg_gen_ext32s_i64(t0, t0);
3422 }
3423
3424 /* Shifts larger than MAX produce zero. */
3425 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3426 tcg_gen_neg_i64(t1, t1);
3427 tcg_gen_and_i64(t0, t0, t1);
3428 break;
3429
3430 case OPC_ADD_CP2:
3431 case OPC_DADD_CP2:
3432 {
3433 TCGv_i64 t2 = tcg_temp_new_i64();
3434 int lab = gen_new_label();
3435
3436 tcg_gen_mov_i64(t2, t0);
3437 tcg_gen_add_i64(t0, t1, t2);
3438 if (opc == OPC_ADD_CP2) {
3439 tcg_gen_ext32s_i64(t0, t0);
3440 }
3441 tcg_gen_xor_i64(t1, t1, t2);
3442 tcg_gen_xor_i64(t2, t2, t0);
3443 tcg_gen_andc_i64(t1, t2, t1);
3444 tcg_temp_free_i64(t2);
3445 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3446 generate_exception(ctx, EXCP_OVERFLOW);
3447 gen_set_label(lab);
3448
3449 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3450 break;
3451 }
3452
3453 case OPC_SUB_CP2:
3454 case OPC_DSUB_CP2:
3455 {
3456 TCGv_i64 t2 = tcg_temp_new_i64();
3457 int lab = gen_new_label();
3458
3459 tcg_gen_mov_i64(t2, t0);
3460 tcg_gen_sub_i64(t0, t1, t2);
3461 if (opc == OPC_SUB_CP2) {
3462 tcg_gen_ext32s_i64(t0, t0);
3463 }
3464 tcg_gen_xor_i64(t1, t1, t2);
3465 tcg_gen_xor_i64(t2, t2, t0);
3466 tcg_gen_and_i64(t1, t1, t2);
3467 tcg_temp_free_i64(t2);
3468 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3469 generate_exception(ctx, EXCP_OVERFLOW);
3470 gen_set_label(lab);
3471
3472 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3473 break;
3474 }
3475
3476 case OPC_PMULUW:
3477 tcg_gen_ext32u_i64(t0, t0);
3478 tcg_gen_ext32u_i64(t1, t1);
3479 tcg_gen_mul_i64(t0, t0, t1);
3480 opn = "pmuluw";
3481 break;
3482
3483 case OPC_SEQU_CP2:
3484 case OPC_SEQ_CP2:
3485 case OPC_SLTU_CP2:
3486 case OPC_SLT_CP2:
3487 case OPC_SLEU_CP2:
3488 case OPC_SLE_CP2:
3489 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3490 FD field is the CC field? */
3491 default:
3492 MIPS_INVAL(opn);
3493 generate_exception(ctx, EXCP_RI);
3494 return;
3495 }
3496
3497#undef LMI_HELPER
3498#undef LMI_DIRECT
3499
3500 gen_store_fpr64(ctx, t0, rd);
3501
3502 (void)opn; /* avoid a compiler warning */
3503 MIPS_DEBUG("%s %s, %s, %s", opn,
3504 fregnames[rd], fregnames[rs], fregnames[rt]);
3505 tcg_temp_free_i64(t0);
3506 tcg_temp_free_i64(t1);
3507}
3508
6af0bf9c 3509/* Traps */
7a387fff 3510static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3511 int rs, int rt, int16_t imm)
3512{
3513 int cond;
cdc0faa6 3514 TCGv t0 = tcg_temp_new();
1ba74fb8 3515 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3516
3517 cond = 0;
3518 /* Load needed operands */
3519 switch (opc) {
3520 case OPC_TEQ:
3521 case OPC_TGE:
3522 case OPC_TGEU:
3523 case OPC_TLT:
3524 case OPC_TLTU:
3525 case OPC_TNE:
3526 /* Compare two registers */
3527 if (rs != rt) {
be24bb4f
TS
3528 gen_load_gpr(t0, rs);
3529 gen_load_gpr(t1, rt);
6af0bf9c
FB
3530 cond = 1;
3531 }
179e32bb 3532 break;
6af0bf9c
FB
3533 case OPC_TEQI:
3534 case OPC_TGEI:
3535 case OPC_TGEIU:
3536 case OPC_TLTI:
3537 case OPC_TLTIU:
3538 case OPC_TNEI:
3539 /* Compare register to immediate */
3540 if (rs != 0 || imm != 0) {
be24bb4f
TS
3541 gen_load_gpr(t0, rs);
3542 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3543 cond = 1;
3544 }
3545 break;
3546 }
3547 if (cond == 0) {
3548 switch (opc) {
3549 case OPC_TEQ: /* rs == rs */
3550 case OPC_TEQI: /* r0 == 0 */
3551 case OPC_TGE: /* rs >= rs */
3552 case OPC_TGEI: /* r0 >= 0 */
3553 case OPC_TGEU: /* rs >= rs unsigned */
3554 case OPC_TGEIU: /* r0 >= 0 unsigned */
3555 /* Always trap */
cdc0faa6 3556 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3557 break;
3558 case OPC_TLT: /* rs < rs */
3559 case OPC_TLTI: /* r0 < 0 */
3560 case OPC_TLTU: /* rs < rs unsigned */
3561 case OPC_TLTIU: /* r0 < 0 unsigned */
3562 case OPC_TNE: /* rs != rs */
3563 case OPC_TNEI: /* r0 != 0 */
ead9360e 3564 /* Never trap: treat as NOP. */
cdc0faa6 3565 break;
6af0bf9c
FB
3566 }
3567 } else {
cdc0faa6
AJ
3568 int l1 = gen_new_label();
3569
6af0bf9c
FB
3570 switch (opc) {
3571 case OPC_TEQ:
3572 case OPC_TEQI:
cdc0faa6 3573 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3574 break;
3575 case OPC_TGE:
3576 case OPC_TGEI:
cdc0faa6 3577 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3578 break;
3579 case OPC_TGEU:
3580 case OPC_TGEIU:
cdc0faa6 3581 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3582 break;
3583 case OPC_TLT:
3584 case OPC_TLTI:
cdc0faa6 3585 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3586 break;
3587 case OPC_TLTU:
3588 case OPC_TLTIU:
cdc0faa6 3589 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3590 break;
3591 case OPC_TNE:
3592 case OPC_TNEI:
cdc0faa6 3593 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3594 break;
6af0bf9c 3595 }
cdc0faa6 3596 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3597 gen_set_label(l1);
3598 }
be24bb4f
TS
3599 tcg_temp_free(t0);
3600 tcg_temp_free(t1);
6af0bf9c
FB
3601}
3602
356265ae 3603static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3604{
6e256c93
FB
3605 TranslationBlock *tb;
3606 tb = ctx->tb;
7b270ef2
NF
3607 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3608 likely(!ctx->singlestep_enabled)) {
57fec1fe 3609 tcg_gen_goto_tb(n);
9b9e4393 3610 gen_save_pc(dest);
4b4a72e5 3611 tcg_gen_exit_tb((tcg_target_long)tb + n);
6e256c93 3612 } else {
9b9e4393 3613 gen_save_pc(dest);
7b270ef2
NF
3614 if (ctx->singlestep_enabled) {
3615 save_cpu_state(ctx, 0);
895c2d04 3616 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3617 }
57fec1fe 3618 tcg_gen_exit_tb(0);
6e256c93 3619 }
c53be334
FB
3620}
3621
6af0bf9c 3622/* Branches (before delay slot) */
7a387fff 3623static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3624 int insn_bytes,
6af0bf9c
FB
3625 int rs, int rt, int32_t offset)
3626{
d077b6f7 3627 target_ulong btgt = -1;
3ad4bb2d 3628 int blink = 0;
2fdbad25 3629 int bcond_compute = 0;
1ba74fb8
AJ
3630 TCGv t0 = tcg_temp_new();
3631 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3632
3633 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3634#ifdef MIPS_DEBUG_DISAS
d12d51d5 3635 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3636#endif
3ad4bb2d 3637 generate_exception(ctx, EXCP_RI);
6c5c1e20 3638 goto out;
3ad4bb2d 3639 }
6af0bf9c 3640
6af0bf9c
FB
3641 /* Load needed operands */
3642 switch (opc) {
3643 case OPC_BEQ:
3644 case OPC_BEQL:
3645 case OPC_BNE:
3646 case OPC_BNEL:
3647 /* Compare two registers */
3648 if (rs != rt) {
6c5c1e20
TS
3649 gen_load_gpr(t0, rs);
3650 gen_load_gpr(t1, rt);
2fdbad25 3651 bcond_compute = 1;
6af0bf9c 3652 }
7dca4ad0 3653 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3654 break;
3655 case OPC_BGEZ:
3656 case OPC_BGEZAL:
3c824109 3657 case OPC_BGEZALS:
6af0bf9c
FB
3658 case OPC_BGEZALL:
3659 case OPC_BGEZL:
3660 case OPC_BGTZ:
3661 case OPC_BGTZL:
3662 case OPC_BLEZ:
3663 case OPC_BLEZL:
3664 case OPC_BLTZ:
3665 case OPC_BLTZAL:
3c824109 3666 case OPC_BLTZALS:
6af0bf9c
FB
3667 case OPC_BLTZALL:
3668 case OPC_BLTZL:
3669 /* Compare to zero */
3670 if (rs != 0) {
6c5c1e20 3671 gen_load_gpr(t0, rs);
2fdbad25 3672 bcond_compute = 1;
6af0bf9c 3673 }
7dca4ad0 3674 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3675 break;
e45a93e2
JL
3676 case OPC_BPOSGE32:
3677#if defined(TARGET_MIPS64)
3678 case OPC_BPOSGE64:
3679 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3680#else
3681 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3682#endif
3683 bcond_compute = 1;
3684 btgt = ctx->pc + insn_bytes + offset;
3685 break;
6af0bf9c
FB
3686 case OPC_J:
3687 case OPC_JAL:
364d4831 3688 case OPC_JALX:
620e48f6
NF
3689 case OPC_JALS:
3690 case OPC_JALXS:
6af0bf9c 3691 /* Jump to immediate */
7dca4ad0 3692 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3693 break;
3694 case OPC_JR:
3695 case OPC_JALR:
364d4831 3696 case OPC_JALRC:
620e48f6 3697 case OPC_JALRS:
6af0bf9c 3698 /* Jump to register */
7a387fff
TS
3699 if (offset != 0 && offset != 16) {
3700 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3701 others are reserved. */
923617a3 3702 MIPS_INVAL("jump hint");
6af0bf9c 3703 generate_exception(ctx, EXCP_RI);
6c5c1e20 3704 goto out;
6af0bf9c 3705 }
d077b6f7 3706 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3707 break;
3708 default:
3709 MIPS_INVAL("branch/jump");
3710 generate_exception(ctx, EXCP_RI);
6c5c1e20 3711 goto out;
6af0bf9c 3712 }
2fdbad25 3713 if (bcond_compute == 0) {
6af0bf9c
FB
3714 /* No condition to be computed */
3715 switch (opc) {
3716 case OPC_BEQ: /* rx == rx */
3717 case OPC_BEQL: /* rx == rx likely */
3718 case OPC_BGEZ: /* 0 >= 0 */
3719 case OPC_BGEZL: /* 0 >= 0 likely */
3720 case OPC_BLEZ: /* 0 <= 0 */
3721 case OPC_BLEZL: /* 0 <= 0 likely */
3722 /* Always take */
4ad40f36 3723 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3724 MIPS_DEBUG("balways");
3725 break;
3c824109 3726 case OPC_BGEZALS:
6af0bf9c
FB
3727 case OPC_BGEZAL: /* 0 >= 0 */
3728 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3729 ctx->hflags |= (opc == OPC_BGEZALS
3730 ? MIPS_HFLAG_BDS16
3731 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3732 /* Always take and link */
3733 blink = 31;
4ad40f36 3734 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3735 MIPS_DEBUG("balways and link");
3736 break;
3737 case OPC_BNE: /* rx != rx */
3738 case OPC_BGTZ: /* 0 > 0 */
3739 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3740 /* Treat as NOP. */
6af0bf9c 3741 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3742 goto out;
3c824109 3743 case OPC_BLTZALS:
eeef26cd 3744 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3745 ctx->hflags |= (opc == OPC_BLTZALS
3746 ? MIPS_HFLAG_BDS16
3747 : MIPS_HFLAG_BDS32);
3748 /* Handle as an unconditional branch to get correct delay
3749 slot checking. */
3750 blink = 31;
3751 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3752 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3753 MIPS_DEBUG("bnever and link");
3c824109 3754 break;
eeef26cd 3755 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3756 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3757 /* Skip the instruction in the delay slot */
3758 MIPS_DEBUG("bnever, link and skip");
3759 ctx->pc += 4;
6c5c1e20 3760 goto out;
6af0bf9c
FB
3761 case OPC_BNEL: /* rx != rx likely */
3762 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3763 case OPC_BLTZL: /* 0 < 0 likely */
3764 /* Skip the instruction in the delay slot */
3765 MIPS_DEBUG("bnever and skip");
9898128f 3766 ctx->pc += 4;
6c5c1e20 3767 goto out;
6af0bf9c 3768 case OPC_J:
4ad40f36 3769 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3770 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3771 break;
620e48f6 3772 case OPC_JALXS:
364d4831
NF
3773 case OPC_JALX:
3774 ctx->hflags |= MIPS_HFLAG_BX;
3775 /* Fallthrough */
620e48f6 3776 case OPC_JALS:
6af0bf9c
FB
3777 case OPC_JAL:
3778 blink = 31;
4ad40f36 3779 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3780 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3781 ? MIPS_HFLAG_BDS16
3782 : MIPS_HFLAG_BDS32);
d077b6f7 3783 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3784 break;
3785 case OPC_JR:
4ad40f36 3786 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3787 if (insn_bytes == 4)
3788 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3789 MIPS_DEBUG("jr %s", regnames[rs]);
3790 break;
620e48f6 3791 case OPC_JALRS:
6af0bf9c 3792 case OPC_JALR:
364d4831 3793 case OPC_JALRC:
6af0bf9c 3794 blink = rt;
4ad40f36 3795 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3796 ctx->hflags |= (opc == OPC_JALRS
3797 ? MIPS_HFLAG_BDS16
3798 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3799 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3800 break;
3801 default:
3802 MIPS_INVAL("branch/jump");
3803 generate_exception(ctx, EXCP_RI);
6c5c1e20 3804 goto out;
6af0bf9c
FB
3805 }
3806 } else {
3807 switch (opc) {
3808 case OPC_BEQ:
e68dd28f 3809 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3810 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3811 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3812 goto not_likely;
3813 case OPC_BEQL:
e68dd28f 3814 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3815 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3816 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3817 goto likely;
3818 case OPC_BNE:
e68dd28f 3819 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3820 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3821 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3822 goto not_likely;
3823 case OPC_BNEL:
e68dd28f 3824 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3825 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3826 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3827 goto likely;
3828 case OPC_BGEZ:
e68dd28f 3829 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3830 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3831 goto not_likely;
3832 case OPC_BGEZL:
e68dd28f 3833 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3834 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3835 goto likely;
3c824109 3836 case OPC_BGEZALS:
6af0bf9c 3837 case OPC_BGEZAL:
3c824109
NF
3838 ctx->hflags |= (opc == OPC_BGEZALS
3839 ? MIPS_HFLAG_BDS16
3840 : MIPS_HFLAG_BDS32);
e68dd28f 3841 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3842 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3843 blink = 31;
3844 goto not_likely;
3845 case OPC_BGEZALL:
e68dd28f 3846 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3847 blink = 31;
d077b6f7 3848 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3849 goto likely;
3850 case OPC_BGTZ:
e68dd28f 3851 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3852 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3853 goto not_likely;
3854 case OPC_BGTZL:
e68dd28f 3855 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3856 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3857 goto likely;
3858 case OPC_BLEZ:
e68dd28f 3859 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3860 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3861 goto not_likely;
3862 case OPC_BLEZL:
e68dd28f 3863 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3864 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3865 goto likely;
3866 case OPC_BLTZ:
e68dd28f 3867 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3868 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3869 goto not_likely;
3870 case OPC_BLTZL:
e68dd28f 3871 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3872 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3873 goto likely;
e45a93e2
JL
3874 case OPC_BPOSGE32:
3875 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3876 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3877 goto not_likely;
3878#if defined(TARGET_MIPS64)
3879 case OPC_BPOSGE64:
3880 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3881 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3882 goto not_likely;
3883#endif
3c824109 3884 case OPC_BLTZALS:
6af0bf9c 3885 case OPC_BLTZAL:
3c824109
NF
3886 ctx->hflags |= (opc == OPC_BLTZALS
3887 ? MIPS_HFLAG_BDS16
3888 : MIPS_HFLAG_BDS32);
e68dd28f 3889 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3890 blink = 31;
d077b6f7 3891 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3892 not_likely:
4ad40f36 3893 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3894 break;
3895 case OPC_BLTZALL:
e68dd28f 3896 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3897 blink = 31;
d077b6f7 3898 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3899 likely:
4ad40f36 3900 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3901 break;
c53f4a62
TS
3902 default:
3903 MIPS_INVAL("conditional branch/jump");
3904 generate_exception(ctx, EXCP_RI);
6c5c1e20 3905 goto out;
6af0bf9c 3906 }
6af0bf9c 3907 }
923617a3 3908 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3909 blink, ctx->hflags, btgt);
9b9e4393 3910
d077b6f7 3911 ctx->btarget = btgt;
6af0bf9c 3912 if (blink > 0) {
364d4831
NF
3913 int post_delay = insn_bytes;
3914 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3915
3916 if (opc != OPC_JALRC)
3917 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3918
3919 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3920 }
6c5c1e20
TS
3921
3922 out:
364d4831
NF
3923 if (insn_bytes == 2)
3924 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3925 tcg_temp_free(t0);
3926 tcg_temp_free(t1);
6af0bf9c
FB
3927}
3928
7a387fff
TS
3929/* special3 bitfield operations */
3930static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3931 int rs, int lsb, int msb)
7a387fff 3932{
a7812ae4
PB
3933 TCGv t0 = tcg_temp_new();
3934 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
3935
3936 gen_load_gpr(t1, rs);
7a387fff
TS
3937 switch (opc) {
3938 case OPC_EXT:
3939 if (lsb + msb > 31)
3940 goto fail;
505ad7c2
AJ
3941 tcg_gen_shri_tl(t0, t1, lsb);
3942 if (msb != 31) {
3943 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3944 } else {
3945 tcg_gen_ext32s_tl(t0, t0);
3946 }
7a387fff 3947 break;
c6d6dd7c 3948#if defined(TARGET_MIPS64)
7a387fff 3949 case OPC_DEXTM:
505ad7c2
AJ
3950 tcg_gen_shri_tl(t0, t1, lsb);
3951 if (msb != 31) {
3952 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3953 }
7a387fff
TS
3954 break;
3955 case OPC_DEXTU:
505ad7c2
AJ
3956 tcg_gen_shri_tl(t0, t1, lsb + 32);
3957 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3958 break;
3959 case OPC_DEXT:
505ad7c2
AJ
3960 tcg_gen_shri_tl(t0, t1, lsb);
3961 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3962 break;
c6d6dd7c 3963#endif
7a387fff
TS
3964 case OPC_INS:
3965 if (lsb > msb)
3966 goto fail;
6c5c1e20 3967 gen_load_gpr(t0, rt);
e0d002f1 3968 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 3969 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3970 break;
c6d6dd7c 3971#if defined(TARGET_MIPS64)
7a387fff 3972 case OPC_DINSM:
6c5c1e20 3973 gen_load_gpr(t0, rt);
e0d002f1 3974 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
3975 break;
3976 case OPC_DINSU:
6c5c1e20 3977 gen_load_gpr(t0, rt);
e0d002f1 3978 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
3979 break;
3980 case OPC_DINS:
6c5c1e20 3981 gen_load_gpr(t0, rt);
e0d002f1 3982 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 3983 break;
c6d6dd7c 3984#endif
7a387fff
TS
3985 default:
3986fail:
3987 MIPS_INVAL("bitops");
3988 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
3989 tcg_temp_free(t0);
3990 tcg_temp_free(t1);
7a387fff
TS
3991 return;
3992 }
6c5c1e20
TS
3993 gen_store_gpr(t0, rt);
3994 tcg_temp_free(t0);
3995 tcg_temp_free(t1);
7a387fff
TS
3996}
3997
49bcf33c
AJ
3998static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3999{
3a55fa47 4000 TCGv t0;
49bcf33c 4001
3a55fa47
AJ
4002 if (rd == 0) {
4003 /* If no destination, treat it as a NOP. */
4004 MIPS_DEBUG("NOP");
4005 return;
4006 }
4007
4008 t0 = tcg_temp_new();
4009 gen_load_gpr(t0, rt);
49bcf33c
AJ
4010 switch (op2) {
4011 case OPC_WSBH:
3a55fa47
AJ
4012 {
4013 TCGv t1 = tcg_temp_new();
4014
4015 tcg_gen_shri_tl(t1, t0, 8);
4016 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4017 tcg_gen_shli_tl(t0, t0, 8);
4018 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4019 tcg_gen_or_tl(t0, t0, t1);
4020 tcg_temp_free(t1);
4021 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4022 }
49bcf33c
AJ
4023 break;
4024 case OPC_SEB:
3a55fa47 4025 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4026 break;
4027 case OPC_SEH:
3a55fa47 4028 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4029 break;
4030#if defined(TARGET_MIPS64)
4031 case OPC_DSBH:
3a55fa47
AJ
4032 {
4033 TCGv t1 = tcg_temp_new();
4034
4035 tcg_gen_shri_tl(t1, t0, 8);
4036 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4037 tcg_gen_shli_tl(t0, t0, 8);
4038 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4039 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4040 tcg_temp_free(t1);
4041 }
49bcf33c
AJ
4042 break;
4043 case OPC_DSHD:
3a55fa47
AJ
4044 {
4045 TCGv t1 = tcg_temp_new();
4046
4047 tcg_gen_shri_tl(t1, t0, 16);
4048 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4049 tcg_gen_shli_tl(t0, t0, 16);
4050 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4051 tcg_gen_or_tl(t0, t0, t1);
4052 tcg_gen_shri_tl(t1, t0, 32);
4053 tcg_gen_shli_tl(t0, t0, 32);
4054 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4055 tcg_temp_free(t1);
4056 }
49bcf33c
AJ
4057 break;
4058#endif
4059 default:
4060 MIPS_INVAL("bsfhl");
4061 generate_exception(ctx, EXCP_RI);
4062 tcg_temp_free(t0);
49bcf33c
AJ
4063 return;
4064 }
49bcf33c 4065 tcg_temp_free(t0);
49bcf33c
AJ
4066}
4067
f1aa6320 4068#ifndef CONFIG_USER_ONLY
0eaef5aa 4069/* CP0 (MMU and control) */
d9bea114 4070static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4071{
d9bea114 4072 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4073
d9bea114
AJ
4074 tcg_gen_ld_i32(t0, cpu_env, off);
4075 tcg_gen_ext_i32_tl(arg, t0);
4076 tcg_temp_free_i32(t0);
4f57689a
TS
4077}
4078
d9bea114 4079static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4080{
d9bea114
AJ
4081 tcg_gen_ld_tl(arg, cpu_env, off);
4082 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4083}
4084
d9bea114 4085static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4086{
d9bea114 4087 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4088
d9bea114
AJ
4089 tcg_gen_trunc_tl_i32(t0, arg);
4090 tcg_gen_st_i32(t0, cpu_env, off);
4091 tcg_temp_free_i32(t0);
f1aa6320
TS
4092}
4093
d9bea114 4094static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4095{
d9bea114
AJ
4096 tcg_gen_ext32s_tl(arg, arg);
4097 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4098}
4099
7db13fae 4100static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4101{
7a387fff 4102 const char *rn = "invalid";
873eb012 4103
e189e748
TS
4104 if (sel != 0)
4105 check_insn(env, ctx, ISA_MIPS32);
4106
873eb012
TS
4107 switch (reg) {
4108 case 0:
7a387fff
TS
4109 switch (sel) {
4110 case 0:
7db13fae 4111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4112 rn = "Index";
4113 break;
4114 case 1:
7385ac0b 4115 check_insn(env, ctx, ASE_MT);
895c2d04 4116 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4117 rn = "MVPControl";
ead9360e 4118 break;
7a387fff 4119 case 2:
7385ac0b 4120 check_insn(env, ctx, ASE_MT);
895c2d04 4121 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4122 rn = "MVPConf0";
ead9360e 4123 break;
7a387fff 4124 case 3:
7385ac0b 4125 check_insn(env, ctx, ASE_MT);
895c2d04 4126 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4127 rn = "MVPConf1";
ead9360e 4128 break;
7a387fff
TS
4129 default:
4130 goto die;
4131 }
873eb012
TS
4132 break;
4133 case 1:
7a387fff
TS
4134 switch (sel) {
4135 case 0:
895c2d04 4136 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4137 rn = "Random";
2423f660 4138 break;
7a387fff 4139 case 1:
7385ac0b 4140 check_insn(env, ctx, ASE_MT);
7db13fae 4141 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4142 rn = "VPEControl";
ead9360e 4143 break;
7a387fff 4144 case 2:
7385ac0b 4145 check_insn(env, ctx, ASE_MT);
7db13fae 4146 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4147 rn = "VPEConf0";
ead9360e 4148 break;
7a387fff 4149 case 3:
7385ac0b 4150 check_insn(env, ctx, ASE_MT);
7db13fae 4151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4152 rn = "VPEConf1";
ead9360e 4153 break;
7a387fff 4154 case 4:
7385ac0b 4155 check_insn(env, ctx, ASE_MT);
7db13fae 4156 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4157 rn = "YQMask";
ead9360e 4158 break;
7a387fff 4159 case 5:
7385ac0b 4160 check_insn(env, ctx, ASE_MT);
7db13fae 4161 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4162 rn = "VPESchedule";
ead9360e 4163 break;
7a387fff 4164 case 6:
7385ac0b 4165 check_insn(env, ctx, ASE_MT);
7db13fae 4166 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4167 rn = "VPEScheFBack";
ead9360e 4168 break;
7a387fff 4169 case 7:
7385ac0b 4170 check_insn(env, ctx, ASE_MT);
7db13fae 4171 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4172 rn = "VPEOpt";
ead9360e 4173 break;
7a387fff
TS
4174 default:
4175 goto die;
4176 }
873eb012
TS
4177 break;
4178 case 2:
7a387fff
TS
4179 switch (sel) {
4180 case 0:
7db13fae 4181 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4182 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4183 rn = "EntryLo0";
4184 break;
7a387fff 4185 case 1:
7385ac0b 4186 check_insn(env, ctx, ASE_MT);
895c2d04 4187 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4188 rn = "TCStatus";
ead9360e 4189 break;
7a387fff 4190 case 2:
7385ac0b 4191 check_insn(env, ctx, ASE_MT);
895c2d04 4192 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4193 rn = "TCBind";
ead9360e 4194 break;
7a387fff 4195 case 3:
7385ac0b 4196 check_insn(env, ctx, ASE_MT);
895c2d04 4197 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4198 rn = "TCRestart";
ead9360e 4199 break;
7a387fff 4200 case 4:
7385ac0b 4201 check_insn(env, ctx, ASE_MT);
895c2d04 4202 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4203 rn = "TCHalt";
ead9360e 4204 break;
7a387fff 4205 case 5:
7385ac0b 4206 check_insn(env, ctx, ASE_MT);
895c2d04 4207 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4208 rn = "TCContext";
ead9360e 4209 break;
7a387fff 4210 case 6:
7385ac0b 4211 check_insn(env, ctx, ASE_MT);
895c2d04 4212 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4213 rn = "TCSchedule";
ead9360e 4214 break;
7a387fff 4215 case 7:
7385ac0b 4216 check_insn(env, ctx, ASE_MT);
895c2d04 4217 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4218 rn = "TCScheFBack";
ead9360e 4219 break;
7a387fff
TS
4220 default:
4221 goto die;
4222 }
873eb012
TS
4223 break;
4224 case 3:
7a387fff
TS
4225 switch (sel) {
4226 case 0:
7db13fae 4227 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4228 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4229 rn = "EntryLo1";
4230 break;
7a387fff
TS
4231 default:
4232 goto die;
1579a72e 4233 }
873eb012
TS
4234 break;
4235 case 4:
7a387fff
TS
4236 switch (sel) {
4237 case 0:
7db13fae 4238 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4239 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4240 rn = "Context";
4241 break;
7a387fff 4242 case 1:
d9bea114 4243// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
4244 rn = "ContextConfig";
4245// break;
7a387fff
TS
4246 default:
4247 goto die;
1579a72e 4248 }
873eb012
TS
4249 break;
4250 case 5:
7a387fff
TS
4251 switch (sel) {
4252 case 0:
7db13fae 4253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4254 rn = "PageMask";
4255 break;
7a387fff 4256 case 1:
e189e748 4257 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4259 rn = "PageGrain";
4260 break;
7a387fff
TS
4261 default:
4262 goto die;
1579a72e 4263 }
873eb012
TS
4264 break;
4265 case 6:
7a387fff
TS
4266 switch (sel) {
4267 case 0:
7db13fae 4268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4269 rn = "Wired";
4270 break;
7a387fff 4271 case 1:
e189e748 4272 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4274 rn = "SRSConf0";
ead9360e 4275 break;
7a387fff 4276 case 2:
e189e748 4277 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4279 rn = "SRSConf1";
ead9360e 4280 break;
7a387fff 4281 case 3:
e189e748 4282 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4284 rn = "SRSConf2";
ead9360e 4285 break;
7a387fff 4286 case 4:
e189e748 4287 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4289 rn = "SRSConf3";
ead9360e 4290 break;
7a387fff 4291 case 5:
e189e748 4292 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4294 rn = "SRSConf4";
ead9360e 4295 break;
7a387fff
TS
4296 default:
4297 goto die;
1579a72e 4298 }
873eb012 4299 break;
8c0fdd85 4300 case 7:
7a387fff
TS
4301 switch (sel) {
4302 case 0:
e189e748 4303 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4305 rn = "HWREna";
4306 break;
7a387fff
TS
4307 default:
4308 goto die;
1579a72e 4309 }
8c0fdd85 4310 break;
873eb012 4311 case 8:
7a387fff
TS
4312 switch (sel) {
4313 case 0:
7db13fae 4314 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4315 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4316 rn = "BadVAddr";
2423f660 4317 break;
7a387fff
TS
4318 default:
4319 goto die;
4320 }
873eb012
TS
4321 break;
4322 case 9:
7a387fff
TS
4323 switch (sel) {
4324 case 0:
2e70f6ef
PB
4325 /* Mark as an IO operation because we read the time. */
4326 if (use_icount)
4327 gen_io_start();
895c2d04 4328 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4329 if (use_icount) {
4330 gen_io_end();
2e70f6ef 4331 }
55807224
EI
4332 /* Break the TB to be able to take timer interrupts immediately
4333 after reading count. */
4334 ctx->bstate = BS_STOP;
2423f660
TS
4335 rn = "Count";
4336 break;
4337 /* 6,7 are implementation dependent */
7a387fff
TS
4338 default:
4339 goto die;
2423f660 4340 }
873eb012
TS
4341 break;
4342 case 10:
7a387fff
TS
4343 switch (sel) {
4344 case 0:
7db13fae 4345 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4346 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4347 rn = "EntryHi";
4348 break;
7a387fff
TS
4349 default:
4350 goto die;
1579a72e 4351 }
873eb012
TS
4352 break;
4353 case 11:
7a387fff
TS
4354 switch (sel) {
4355 case 0:
7db13fae 4356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4357 rn = "Compare";
4358 break;
4359 /* 6,7 are implementation dependent */
7a387fff
TS
4360 default:
4361 goto die;
2423f660 4362 }
873eb012
TS
4363 break;
4364 case 12:
7a387fff
TS
4365 switch (sel) {
4366 case 0:
7db13fae 4367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4368 rn = "Status";
4369 break;
7a387fff 4370 case 1:
e189e748 4371 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4373 rn = "IntCtl";
4374 break;
7a387fff 4375 case 2:
e189e748 4376 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4378 rn = "SRSCtl";
4379 break;
7a387fff 4380 case 3:
e189e748 4381 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4383 rn = "SRSMap";
fd88b6ab 4384 break;
7a387fff
TS
4385 default:
4386 goto die;
4387 }
873eb012
TS
4388 break;
4389 case 13:
7a387fff
TS
4390 switch (sel) {
4391 case 0:
7db13fae 4392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4393 rn = "Cause";
4394 break;
7a387fff
TS
4395 default:
4396 goto die;
4397 }
873eb012
TS
4398 break;
4399 case 14:
7a387fff
TS
4400 switch (sel) {
4401 case 0:
7db13fae 4402 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4403 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4404 rn = "EPC";
4405 break;
7a387fff
TS
4406 default:
4407 goto die;
1579a72e 4408 }
873eb012
TS
4409 break;
4410 case 15:
7a387fff
TS
4411 switch (sel) {
4412 case 0:
7db13fae 4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4414 rn = "PRid";
4415 break;
7a387fff 4416 case 1:
e189e748 4417 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4419 rn = "EBase";
4420 break;
7a387fff
TS
4421 default:
4422 goto die;
4423 }
873eb012
TS
4424 break;
4425 case 16:
4426 switch (sel) {
4427 case 0:
7db13fae 4428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4429 rn = "Config";
4430 break;
4431 case 1:
7db13fae 4432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4433 rn = "Config1";
4434 break;
7a387fff 4435 case 2:
7db13fae 4436 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4437 rn = "Config2";
4438 break;
4439 case 3:
7db13fae 4440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4441 rn = "Config3";
4442 break;
e397ee33
TS
4443 /* 4,5 are reserved */
4444 /* 6,7 are implementation dependent */
4445 case 6:
7db13fae 4446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4447 rn = "Config6";
4448 break;
4449 case 7:
7db13fae 4450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4451 rn = "Config7";
4452 break;
873eb012 4453 default:
873eb012
TS
4454 goto die;
4455 }
4456 break;
4457 case 17:
7a387fff
TS
4458 switch (sel) {
4459 case 0:
895c2d04 4460 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4461 rn = "LLAddr";
4462 break;
7a387fff
TS
4463 default:
4464 goto die;
4465 }
873eb012
TS
4466 break;
4467 case 18:
7a387fff 4468 switch (sel) {
fd88b6ab 4469 case 0 ... 7:
895c2d04 4470 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4471 rn = "WatchLo";
4472 break;
7a387fff
TS
4473 default:
4474 goto die;
4475 }
873eb012
TS
4476 break;
4477 case 19:
7a387fff 4478 switch (sel) {
fd88b6ab 4479 case 0 ...7:
895c2d04 4480 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4481 rn = "WatchHi";
4482 break;
7a387fff
TS
4483 default:
4484 goto die;
4485 }
873eb012 4486 break;
8c0fdd85 4487 case 20:
7a387fff
TS
4488 switch (sel) {
4489 case 0:
d26bc211 4490#if defined(TARGET_MIPS64)
e189e748 4491 check_insn(env, ctx, ISA_MIPS3);
7db13fae 4492 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4493 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4494 rn = "XContext";
4495 break;
703eaf37 4496#endif
7a387fff
TS
4497 default:
4498 goto die;
4499 }
8c0fdd85
TS
4500 break;
4501 case 21:
7a387fff
TS
4502 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4503 switch (sel) {
4504 case 0:
7db13fae 4505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4506 rn = "Framemask";
4507 break;
7a387fff
TS
4508 default:
4509 goto die;
4510 }
8c0fdd85
TS
4511 break;
4512 case 22:
d9bea114 4513 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4514 rn = "'Diagnostic"; /* implementation dependent */
4515 break;
873eb012 4516 case 23:
7a387fff
TS
4517 switch (sel) {
4518 case 0:
895c2d04 4519 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4520 rn = "Debug";
4521 break;
7a387fff 4522 case 1:
d9bea114 4523// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4524 rn = "TraceControl";
4525// break;
7a387fff 4526 case 2:
d9bea114 4527// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4528 rn = "TraceControl2";
4529// break;
7a387fff 4530 case 3:
d9bea114 4531// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4532 rn = "UserTraceData";
4533// break;
7a387fff 4534 case 4:
d9bea114 4535// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4536 rn = "TraceBPC";
4537// break;
7a387fff
TS
4538 default:
4539 goto die;
4540 }
873eb012
TS
4541 break;
4542 case 24:
7a387fff
TS
4543 switch (sel) {
4544 case 0:
f0b3f3ae 4545 /* EJTAG support */
7db13fae 4546 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4547 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4548 rn = "DEPC";
4549 break;
7a387fff
TS
4550 default:
4551 goto die;
4552 }
873eb012 4553 break;
8c0fdd85 4554 case 25:
7a387fff
TS
4555 switch (sel) {
4556 case 0:
7db13fae 4557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4558 rn = "Performance0";
7a387fff
TS
4559 break;
4560 case 1:
d9bea114 4561// gen_helper_mfc0_performance1(arg);
2423f660
TS
4562 rn = "Performance1";
4563// break;
7a387fff 4564 case 2:
d9bea114 4565// gen_helper_mfc0_performance2(arg);
2423f660
TS
4566 rn = "Performance2";
4567// break;
7a387fff 4568 case 3:
d9bea114 4569// gen_helper_mfc0_performance3(arg);
2423f660
TS
4570 rn = "Performance3";
4571// break;
7a387fff 4572 case 4:
d9bea114 4573// gen_helper_mfc0_performance4(arg);
2423f660
TS
4574 rn = "Performance4";
4575// break;
7a387fff 4576 case 5:
d9bea114 4577// gen_helper_mfc0_performance5(arg);
2423f660
TS
4578 rn = "Performance5";
4579// break;
7a387fff 4580 case 6:
d9bea114 4581// gen_helper_mfc0_performance6(arg);
2423f660
TS
4582 rn = "Performance6";
4583// break;
7a387fff 4584 case 7:
d9bea114 4585// gen_helper_mfc0_performance7(arg);
2423f660
TS
4586 rn = "Performance7";
4587// break;
7a387fff
TS
4588 default:
4589 goto die;
4590 }
8c0fdd85
TS
4591 break;
4592 case 26:
d9bea114 4593 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4594 rn = "ECC";
4595 break;
8c0fdd85 4596 case 27:
7a387fff 4597 switch (sel) {
7a387fff 4598 case 0 ... 3:
d9bea114 4599 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4600 rn = "CacheErr";
4601 break;
7a387fff
TS
4602 default:
4603 goto die;
4604 }
8c0fdd85 4605 break;
873eb012
TS
4606 case 28:
4607 switch (sel) {
4608 case 0:
7a387fff
TS
4609 case 2:
4610 case 4:
4611 case 6:
7db13fae 4612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4613 rn = "TagLo";
4614 break;
4615 case 1:
7a387fff
TS
4616 case 3:
4617 case 5:
4618 case 7:
7db13fae 4619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4620 rn = "DataLo";
4621 break;
4622 default:
873eb012
TS
4623 goto die;
4624 }
4625 break;
8c0fdd85 4626 case 29:
7a387fff
TS
4627 switch (sel) {
4628 case 0:
4629 case 2:
4630 case 4:
4631 case 6:
7db13fae 4632 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4633 rn = "TagHi";
4634 break;
4635 case 1:
4636 case 3:
4637 case 5:
4638 case 7:
7db13fae 4639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4640 rn = "DataHi";
4641 break;
4642 default:
4643 goto die;
4644 }
8c0fdd85 4645 break;
873eb012 4646 case 30:
7a387fff
TS
4647 switch (sel) {
4648 case 0:
7db13fae 4649 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4650 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4651 rn = "ErrorEPC";
4652 break;
7a387fff
TS
4653 default:
4654 goto die;
4655 }
873eb012
TS
4656 break;
4657 case 31:
7a387fff
TS
4658 switch (sel) {
4659 case 0:
f0b3f3ae 4660 /* EJTAG support */
7db13fae 4661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4662 rn = "DESAVE";
4663 break;
7a387fff
TS
4664 default:
4665 goto die;
4666 }
873eb012
TS
4667 break;
4668 default:
873eb012
TS
4669 goto die;
4670 }
2abf314d 4671 (void)rn; /* avoid a compiler warning */
d12d51d5 4672 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4673 return;
4674
4675die:
d12d51d5 4676 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4677 generate_exception(ctx, EXCP_RI);
4678}
4679
7db13fae 4680static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4681{
7a387fff
TS
4682 const char *rn = "invalid";
4683
e189e748
TS
4684 if (sel != 0)
4685 check_insn(env, ctx, ISA_MIPS32);
4686
2e70f6ef
PB
4687 if (use_icount)
4688 gen_io_start();
4689
8c0fdd85
TS
4690 switch (reg) {
4691 case 0:
7a387fff
TS
4692 switch (sel) {
4693 case 0:
895c2d04 4694 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4695 rn = "Index";
4696 break;
4697 case 1:
7385ac0b 4698 check_insn(env, ctx, ASE_MT);
895c2d04 4699 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4700 rn = "MVPControl";
ead9360e 4701 break;
7a387fff 4702 case 2:
7385ac0b 4703 check_insn(env, ctx, ASE_MT);
ead9360e 4704 /* ignored */
7a387fff 4705 rn = "MVPConf0";
ead9360e 4706 break;
7a387fff 4707 case 3:
7385ac0b 4708 check_insn(env, ctx, ASE_MT);
ead9360e 4709 /* ignored */
7a387fff 4710 rn = "MVPConf1";
ead9360e 4711 break;
7a387fff
TS
4712 default:
4713 goto die;
4714 }
8c0fdd85
TS
4715 break;
4716 case 1:
7a387fff
TS
4717 switch (sel) {
4718 case 0:
2423f660 4719 /* ignored */
7a387fff 4720 rn = "Random";
2423f660 4721 break;
7a387fff 4722 case 1:
7385ac0b 4723 check_insn(env, ctx, ASE_MT);
895c2d04 4724 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4725 rn = "VPEControl";
ead9360e 4726 break;
7a387fff 4727 case 2:
7385ac0b 4728 check_insn(env, ctx, ASE_MT);
895c2d04 4729 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4730 rn = "VPEConf0";
ead9360e 4731 break;
7a387fff 4732 case 3:
7385ac0b 4733 check_insn(env, ctx, ASE_MT);
895c2d04 4734 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4735 rn = "VPEConf1";
ead9360e 4736 break;
7a387fff 4737 case 4:
7385ac0b 4738 check_insn(env, ctx, ASE_MT);
895c2d04 4739 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4740 rn = "YQMask";
ead9360e 4741 break;
7a387fff 4742 case 5:
7385ac0b 4743 check_insn(env, ctx, ASE_MT);
7db13fae 4744 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4745 rn = "VPESchedule";
ead9360e 4746 break;
7a387fff 4747 case 6:
7385ac0b 4748 check_insn(env, ctx, ASE_MT);
7db13fae 4749 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4750 rn = "VPEScheFBack";
ead9360e 4751 break;
7a387fff 4752 case 7:
7385ac0b 4753 check_insn(env, ctx, ASE_MT);
895c2d04 4754 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4755 rn = "VPEOpt";
ead9360e 4756 break;
7a387fff
TS
4757 default:
4758 goto die;
4759 }
8c0fdd85
TS
4760 break;
4761 case 2:
7a387fff
TS
4762 switch (sel) {
4763 case 0:
895c2d04 4764 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4765 rn = "EntryLo0";
4766 break;
7a387fff 4767 case 1:
7385ac0b 4768 check_insn(env, ctx, ASE_MT);
895c2d04 4769 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4770 rn = "TCStatus";
ead9360e 4771 break;
7a387fff 4772 case 2:
7385ac0b 4773 check_insn(env, ctx, ASE_MT);
895c2d04 4774 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4775 rn = "TCBind";
ead9360e 4776 break;
7a387fff 4777 case 3:
7385ac0b 4778 check_insn(env, ctx, ASE_MT);
895c2d04 4779 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4780 rn = "TCRestart";
ead9360e 4781 break;
7a387fff 4782 case 4:
7385ac0b 4783 check_insn(env, ctx, ASE_MT);
895c2d04 4784 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4785 rn = "TCHalt";
ead9360e 4786 break;
7a387fff 4787 case 5:
7385ac0b 4788 check_insn(env, ctx, ASE_MT);
895c2d04 4789 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4790 rn = "TCContext";
ead9360e 4791 break;
7a387fff 4792 case 6:
7385ac0b 4793 check_insn(env, ctx, ASE_MT);
895c2d04 4794 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4795 rn = "TCSchedule";
ead9360e 4796 break;
7a387fff 4797 case 7:
7385ac0b 4798 check_insn(env, ctx, ASE_MT);
895c2d04 4799 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4800 rn = "TCScheFBack";
ead9360e 4801 break;
7a387fff
TS
4802 default:
4803 goto die;
4804 }
8c0fdd85
TS
4805 break;
4806 case 3:
7a387fff
TS
4807 switch (sel) {
4808 case 0:
895c2d04 4809 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4810 rn = "EntryLo1";
4811 break;
7a387fff
TS
4812 default:
4813 goto die;
876d4b07 4814 }
8c0fdd85
TS
4815 break;
4816 case 4:
7a387fff
TS
4817 switch (sel) {
4818 case 0:
895c2d04 4819 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4820 rn = "Context";
4821 break;
7a387fff 4822 case 1:
895c2d04 4823// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
4824 rn = "ContextConfig";
4825// break;
7a387fff
TS
4826 default:
4827 goto die;
876d4b07 4828 }
8c0fdd85
TS
4829 break;
4830 case 5:
7a387fff
TS
4831 switch (sel) {
4832 case 0:
895c2d04 4833 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4834 rn = "PageMask";
4835 break;
7a387fff 4836 case 1:
e189e748 4837 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4838 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4839 rn = "PageGrain";
4840 break;
7a387fff
TS
4841 default:
4842 goto die;
876d4b07 4843 }
8c0fdd85
TS
4844 break;
4845 case 6:
7a387fff
TS
4846 switch (sel) {
4847 case 0:
895c2d04 4848 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4849 rn = "Wired";
4850 break;
7a387fff 4851 case 1:
e189e748 4852 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4853 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4854 rn = "SRSConf0";
ead9360e 4855 break;
7a387fff 4856 case 2:
e189e748 4857 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4858 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4859 rn = "SRSConf1";
ead9360e 4860 break;
7a387fff 4861 case 3:
e189e748 4862 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4863 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4864 rn = "SRSConf2";
ead9360e 4865 break;
7a387fff 4866 case 4:
e189e748 4867 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4868 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4869 rn = "SRSConf3";
ead9360e 4870 break;
7a387fff 4871 case 5:
e189e748 4872 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4873 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4874 rn = "SRSConf4";
ead9360e 4875 break;
7a387fff
TS
4876 default:
4877 goto die;
876d4b07 4878 }
8c0fdd85
TS
4879 break;
4880 case 7:
7a387fff
TS
4881 switch (sel) {
4882 case 0:
e189e748 4883 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4884 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
4885 rn = "HWREna";
4886 break;
7a387fff
TS
4887 default:
4888 goto die;
876d4b07 4889 }
8c0fdd85
TS
4890 break;
4891 case 8:
7a387fff 4892 /* ignored */
f0b3f3ae 4893 rn = "BadVAddr";
8c0fdd85
TS
4894 break;
4895 case 9:
7a387fff
TS
4896 switch (sel) {
4897 case 0:
895c2d04 4898 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4899 rn = "Count";
4900 break;
876d4b07 4901 /* 6,7 are implementation dependent */
7a387fff
TS
4902 default:
4903 goto die;
876d4b07 4904 }
8c0fdd85
TS
4905 break;
4906 case 10:
7a387fff
TS
4907 switch (sel) {
4908 case 0:
895c2d04 4909 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4910 rn = "EntryHi";
4911 break;
7a387fff
TS
4912 default:
4913 goto die;
876d4b07 4914 }
8c0fdd85
TS
4915 break;
4916 case 11:
7a387fff
TS
4917 switch (sel) {
4918 case 0:
895c2d04 4919 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4920 rn = "Compare";
4921 break;
4922 /* 6,7 are implementation dependent */
7a387fff
TS
4923 default:
4924 goto die;
876d4b07 4925 }
8c0fdd85
TS
4926 break;
4927 case 12:
7a387fff
TS
4928 switch (sel) {
4929 case 0:
867abc7e 4930 save_cpu_state(ctx, 1);
895c2d04 4931 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4932 /* BS_STOP isn't good enough here, hflags may have changed. */
4933 gen_save_pc(ctx->pc + 4);
4934 ctx->bstate = BS_EXCP;
2423f660
TS
4935 rn = "Status";
4936 break;
7a387fff 4937 case 1:
e189e748 4938 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4939 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4940 /* Stop translation as we may have switched the execution mode */
4941 ctx->bstate = BS_STOP;
2423f660
TS
4942 rn = "IntCtl";
4943 break;
7a387fff 4944 case 2:
e189e748 4945 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4946 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4947 /* Stop translation as we may have switched the execution mode */
4948 ctx->bstate = BS_STOP;
2423f660
TS
4949 rn = "SRSCtl";
4950 break;
7a387fff 4951 case 3:
e189e748 4952 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4953 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4954 /* Stop translation as we may have switched the execution mode */
4955 ctx->bstate = BS_STOP;
2423f660 4956 rn = "SRSMap";
fd88b6ab 4957 break;
7a387fff
TS
4958 default:
4959 goto die;
876d4b07 4960 }
8c0fdd85
TS
4961 break;
4962 case 13:
7a387fff
TS
4963 switch (sel) {
4964 case 0:
867abc7e 4965 save_cpu_state(ctx, 1);
895c2d04 4966 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4967 rn = "Cause";
4968 break;
7a387fff
TS
4969 default:
4970 goto die;
876d4b07 4971 }
8c0fdd85
TS
4972 break;
4973 case 14:
7a387fff
TS
4974 switch (sel) {
4975 case 0:
7db13fae 4976 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4977 rn = "EPC";
4978 break;
7a387fff
TS
4979 default:
4980 goto die;
876d4b07 4981 }
8c0fdd85
TS
4982 break;
4983 case 15:
7a387fff
TS
4984 switch (sel) {
4985 case 0:
2423f660
TS
4986 /* ignored */
4987 rn = "PRid";
4988 break;
7a387fff 4989 case 1:
e189e748 4990 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4991 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
4992 rn = "EBase";
4993 break;
7a387fff
TS
4994 default:
4995 goto die;
1579a72e 4996 }
8c0fdd85
TS
4997 break;
4998 case 16:
4999 switch (sel) {
5000 case 0:
895c2d04 5001 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5002 rn = "Config";
2423f660
TS
5003 /* Stop translation as we may have switched the execution mode */
5004 ctx->bstate = BS_STOP;
7a387fff
TS
5005 break;
5006 case 1:
e397ee33 5007 /* ignored, read only */
7a387fff
TS
5008 rn = "Config1";
5009 break;
5010 case 2:
895c2d04 5011 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5012 rn = "Config2";
2423f660
TS
5013 /* Stop translation as we may have switched the execution mode */
5014 ctx->bstate = BS_STOP;
8c0fdd85 5015 break;
7a387fff 5016 case 3:
e397ee33 5017 /* ignored, read only */
7a387fff
TS
5018 rn = "Config3";
5019 break;
e397ee33
TS
5020 /* 4,5 are reserved */
5021 /* 6,7 are implementation dependent */
5022 case 6:
5023 /* ignored */
5024 rn = "Config6";
5025 break;
5026 case 7:
5027 /* ignored */
5028 rn = "Config7";
5029 break;
8c0fdd85
TS
5030 default:
5031 rn = "Invalid config selector";
5032 goto die;
5033 }
5034 break;
5035 case 17:
7a387fff
TS
5036 switch (sel) {
5037 case 0:
895c2d04 5038 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5039 rn = "LLAddr";
5040 break;
7a387fff
TS
5041 default:
5042 goto die;
5043 }
8c0fdd85
TS
5044 break;
5045 case 18:
7a387fff 5046 switch (sel) {
fd88b6ab 5047 case 0 ... 7:
895c2d04 5048 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5049 rn = "WatchLo";
5050 break;
7a387fff
TS
5051 default:
5052 goto die;
5053 }
8c0fdd85
TS
5054 break;
5055 case 19:
7a387fff 5056 switch (sel) {
fd88b6ab 5057 case 0 ... 7:
895c2d04 5058 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5059 rn = "WatchHi";
5060 break;
7a387fff
TS
5061 default:
5062 goto die;
5063 }
8c0fdd85
TS
5064 break;
5065 case 20:
7a387fff
TS
5066 switch (sel) {
5067 case 0:
d26bc211 5068#if defined(TARGET_MIPS64)
e189e748 5069 check_insn(env, ctx, ISA_MIPS3);
895c2d04 5070 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5071 rn = "XContext";
5072 break;
703eaf37 5073#endif
7a387fff
TS
5074 default:
5075 goto die;
5076 }
8c0fdd85
TS
5077 break;
5078 case 21:
7a387fff
TS
5079 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5080 switch (sel) {
5081 case 0:
895c2d04 5082 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5083 rn = "Framemask";
5084 break;
7a387fff
TS
5085 default:
5086 goto die;
5087 }
5088 break;
8c0fdd85 5089 case 22:
7a387fff
TS
5090 /* ignored */
5091 rn = "Diagnostic"; /* implementation dependent */
2423f660 5092 break;
8c0fdd85 5093 case 23:
7a387fff
TS
5094 switch (sel) {
5095 case 0:
895c2d04 5096 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5097 /* BS_STOP isn't good enough here, hflags may have changed. */
5098 gen_save_pc(ctx->pc + 4);
5099 ctx->bstate = BS_EXCP;
2423f660
TS
5100 rn = "Debug";
5101 break;
7a387fff 5102 case 1:
895c2d04 5103// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5104 rn = "TraceControl";
8487327a
TS
5105 /* Stop translation as we may have switched the execution mode */
5106 ctx->bstate = BS_STOP;
2423f660 5107// break;
7a387fff 5108 case 2:
895c2d04 5109// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5110 rn = "TraceControl2";
8487327a
TS
5111 /* Stop translation as we may have switched the execution mode */
5112 ctx->bstate = BS_STOP;
2423f660 5113// break;
7a387fff 5114 case 3:
8487327a
TS
5115 /* Stop translation as we may have switched the execution mode */
5116 ctx->bstate = BS_STOP;
895c2d04 5117// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5118 rn = "UserTraceData";
8487327a
TS
5119 /* Stop translation as we may have switched the execution mode */
5120 ctx->bstate = BS_STOP;
2423f660 5121// break;
7a387fff 5122 case 4:
895c2d04 5123// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5124 /* Stop translation as we may have switched the execution mode */
5125 ctx->bstate = BS_STOP;
2423f660
TS
5126 rn = "TraceBPC";
5127// break;
7a387fff
TS
5128 default:
5129 goto die;
5130 }
8c0fdd85
TS
5131 break;
5132 case 24:
7a387fff
TS
5133 switch (sel) {
5134 case 0:
f1aa6320 5135 /* EJTAG support */
7db13fae 5136 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5137 rn = "DEPC";
5138 break;
7a387fff
TS
5139 default:
5140 goto die;
5141 }
8c0fdd85
TS
5142 break;
5143 case 25:
7a387fff
TS
5144 switch (sel) {
5145 case 0:
895c2d04 5146 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5147 rn = "Performance0";
5148 break;
7a387fff 5149 case 1:
d9bea114 5150// gen_helper_mtc0_performance1(arg);
2423f660
TS
5151 rn = "Performance1";
5152// break;
7a387fff 5153 case 2:
d9bea114 5154// gen_helper_mtc0_performance2(arg);
2423f660
TS
5155 rn = "Performance2";
5156// break;
7a387fff 5157 case 3:
d9bea114 5158// gen_helper_mtc0_performance3(arg);
2423f660
TS
5159 rn = "Performance3";
5160// break;
7a387fff 5161 case 4:
d9bea114 5162// gen_helper_mtc0_performance4(arg);
2423f660
TS
5163 rn = "Performance4";
5164// break;
7a387fff 5165 case 5:
d9bea114 5166// gen_helper_mtc0_performance5(arg);
2423f660
TS
5167 rn = "Performance5";
5168// break;
7a387fff 5169 case 6:
d9bea114 5170// gen_helper_mtc0_performance6(arg);
2423f660
TS
5171 rn = "Performance6";
5172// break;
7a387fff 5173 case 7:
d9bea114 5174// gen_helper_mtc0_performance7(arg);
2423f660
TS
5175 rn = "Performance7";
5176// break;
7a387fff
TS
5177 default:
5178 goto die;
5179 }
8c0fdd85
TS
5180 break;
5181 case 26:
2423f660 5182 /* ignored */
8c0fdd85 5183 rn = "ECC";
2423f660 5184 break;
8c0fdd85 5185 case 27:
7a387fff
TS
5186 switch (sel) {
5187 case 0 ... 3:
2423f660
TS
5188 /* ignored */
5189 rn = "CacheErr";
5190 break;
7a387fff
TS
5191 default:
5192 goto die;
5193 }
8c0fdd85
TS
5194 break;
5195 case 28:
5196 switch (sel) {
5197 case 0:
7a387fff
TS
5198 case 2:
5199 case 4:
5200 case 6:
895c2d04 5201 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5202 rn = "TagLo";
5203 break;
7a387fff
TS
5204 case 1:
5205 case 3:
5206 case 5:
5207 case 7:
895c2d04 5208 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5209 rn = "DataLo";
5210 break;
8c0fdd85 5211 default:
8c0fdd85
TS
5212 goto die;
5213 }
5214 break;
5215 case 29:
7a387fff
TS
5216 switch (sel) {
5217 case 0:
5218 case 2:
5219 case 4:
5220 case 6:
895c2d04 5221 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5222 rn = "TagHi";
5223 break;
5224 case 1:
5225 case 3:
5226 case 5:
5227 case 7:
895c2d04 5228 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5229 rn = "DataHi";
5230 break;
5231 default:
5232 rn = "invalid sel";
5233 goto die;
5234 }
8c0fdd85
TS
5235 break;
5236 case 30:
7a387fff
TS
5237 switch (sel) {
5238 case 0:
7db13fae 5239 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5240 rn = "ErrorEPC";
5241 break;
7a387fff
TS
5242 default:
5243 goto die;
5244 }
8c0fdd85
TS
5245 break;
5246 case 31:
7a387fff
TS
5247 switch (sel) {
5248 case 0:
f1aa6320 5249 /* EJTAG support */
7db13fae 5250 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5251 rn = "DESAVE";
5252 break;
7a387fff
TS
5253 default:
5254 goto die;
5255 }
2423f660
TS
5256 /* Stop translation as we may have switched the execution mode */
5257 ctx->bstate = BS_STOP;
8c0fdd85
TS
5258 break;
5259 default:
8c0fdd85
TS
5260 goto die;
5261 }
2abf314d 5262 (void)rn; /* avoid a compiler warning */
d12d51d5 5263 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5264 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5265 if (use_icount) {
5266 gen_io_end();
5267 ctx->bstate = BS_STOP;
5268 }
8c0fdd85
TS
5269 return;
5270
5271die:
d12d51d5 5272 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5273 generate_exception(ctx, EXCP_RI);
5274}
5275
d26bc211 5276#if defined(TARGET_MIPS64)
7db13fae 5277static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5278{
5279 const char *rn = "invalid";
5280
e189e748
TS
5281 if (sel != 0)
5282 check_insn(env, ctx, ISA_MIPS64);
5283
9c2149c8
TS
5284 switch (reg) {
5285 case 0:
5286 switch (sel) {
5287 case 0:
7db13fae 5288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5289 rn = "Index";
5290 break;
5291 case 1:
7385ac0b 5292 check_insn(env, ctx, ASE_MT);
895c2d04 5293 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5294 rn = "MVPControl";
ead9360e 5295 break;
9c2149c8 5296 case 2:
7385ac0b 5297 check_insn(env, ctx, ASE_MT);
895c2d04 5298 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5299 rn = "MVPConf0";
ead9360e 5300 break;
9c2149c8 5301 case 3:
7385ac0b 5302 check_insn(env, ctx, ASE_MT);
895c2d04 5303 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5304 rn = "MVPConf1";
ead9360e 5305 break;
9c2149c8
TS
5306 default:
5307 goto die;
5308 }
5309 break;
5310 case 1:
5311 switch (sel) {
5312 case 0:
895c2d04 5313 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5314 rn = "Random";
2423f660 5315 break;
9c2149c8 5316 case 1:
7385ac0b 5317 check_insn(env, ctx, ASE_MT);
7db13fae 5318 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5319 rn = "VPEControl";
ead9360e 5320 break;
9c2149c8 5321 case 2:
7385ac0b 5322 check_insn(env, ctx, ASE_MT);
7db13fae 5323 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5324 rn = "VPEConf0";
ead9360e 5325 break;
9c2149c8 5326 case 3:
7385ac0b 5327 check_insn(env, ctx, ASE_MT);
7db13fae 5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5329 rn = "VPEConf1";
ead9360e 5330 break;
9c2149c8 5331 case 4:
7385ac0b 5332 check_insn(env, ctx, ASE_MT);
7db13fae 5333 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5334 rn = "YQMask";
ead9360e 5335 break;
9c2149c8 5336 case 5:
7385ac0b 5337 check_insn(env, ctx, ASE_MT);
7db13fae 5338 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5339 rn = "VPESchedule";
ead9360e 5340 break;
9c2149c8 5341 case 6:
7385ac0b 5342 check_insn(env, ctx, ASE_MT);
7db13fae 5343 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5344 rn = "VPEScheFBack";
ead9360e 5345 break;
9c2149c8 5346 case 7:
7385ac0b 5347 check_insn(env, ctx, ASE_MT);
7db13fae 5348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5349 rn = "VPEOpt";
ead9360e 5350 break;
9c2149c8
TS
5351 default:
5352 goto die;
5353 }
5354 break;
5355 case 2:
5356 switch (sel) {
5357 case 0:
7db13fae 5358 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5359 rn = "EntryLo0";
5360 break;
9c2149c8 5361 case 1:
7385ac0b 5362 check_insn(env, ctx, ASE_MT);
895c2d04 5363 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5364 rn = "TCStatus";
ead9360e 5365 break;
9c2149c8 5366 case 2:
7385ac0b 5367 check_insn(env, ctx, ASE_MT);
895c2d04 5368 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5369 rn = "TCBind";
ead9360e 5370 break;
9c2149c8 5371 case 3:
7385ac0b 5372 check_insn(env, ctx, ASE_MT);
895c2d04 5373 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5374 rn = "TCRestart";
ead9360e 5375 break;
9c2149c8 5376 case 4:
7385ac0b 5377 check_insn(env, ctx, ASE_MT);
895c2d04 5378 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5379 rn = "TCHalt";
ead9360e 5380 break;
9c2149c8 5381 case 5:
7385ac0b 5382 check_insn(env, ctx, ASE_MT);
895c2d04 5383 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5384 rn = "TCContext";
ead9360e 5385 break;
9c2149c8 5386 case 6:
7385ac0b 5387 check_insn(env, ctx, ASE_MT);
895c2d04 5388 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5389 rn = "TCSchedule";
ead9360e 5390 break;
9c2149c8 5391 case 7:
7385ac0b 5392 check_insn(env, ctx, ASE_MT);
895c2d04 5393 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5394 rn = "TCScheFBack";
ead9360e 5395 break;
9c2149c8
TS
5396 default:
5397 goto die;
5398 }
5399 break;
5400 case 3:
5401 switch (sel) {
5402 case 0:
7db13fae 5403 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5404 rn = "EntryLo1";
5405 break;
9c2149c8
TS
5406 default:
5407 goto die;
1579a72e 5408 }
9c2149c8
TS
5409 break;
5410 case 4:
5411 switch (sel) {
5412 case 0:
7db13fae 5413 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5414 rn = "Context";
5415 break;
9c2149c8 5416 case 1:
d9bea114 5417// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
5418 rn = "ContextConfig";
5419// break;
9c2149c8
TS
5420 default:
5421 goto die;
876d4b07 5422 }
9c2149c8
TS
5423 break;
5424 case 5:
5425 switch (sel) {
5426 case 0:
7db13fae 5427 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5428 rn = "PageMask";
5429 break;
9c2149c8 5430 case 1:
e189e748 5431 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5433 rn = "PageGrain";
5434 break;
9c2149c8
TS
5435 default:
5436 goto die;
876d4b07 5437 }
9c2149c8
TS
5438 break;
5439 case 6:
5440 switch (sel) {
5441 case 0:
7db13fae 5442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5443 rn = "Wired";
5444 break;
9c2149c8 5445 case 1:
e189e748 5446 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5448 rn = "SRSConf0";
ead9360e 5449 break;
9c2149c8 5450 case 2:
e189e748 5451 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5453 rn = "SRSConf1";
ead9360e 5454 break;
9c2149c8 5455 case 3:
e189e748 5456 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5458 rn = "SRSConf2";
ead9360e 5459 break;
9c2149c8 5460 case 4:
e189e748 5461 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5463 rn = "SRSConf3";
ead9360e 5464 break;
9c2149c8 5465 case 5:
e189e748 5466 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5468 rn = "SRSConf4";
ead9360e 5469 break;
9c2149c8
TS
5470 default:
5471 goto die;
876d4b07 5472 }
9c2149c8
TS
5473 break;
5474 case 7:
5475 switch (sel) {
5476 case 0:
e189e748 5477 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5479 rn = "HWREna";
5480 break;
9c2149c8
TS
5481 default:
5482 goto die;
876d4b07 5483 }
9c2149c8
TS
5484 break;
5485 case 8:
5486 switch (sel) {
5487 case 0:
7db13fae 5488 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5489 rn = "BadVAddr";
2423f660 5490 break;
9c2149c8
TS
5491 default:
5492 goto die;
876d4b07 5493 }
9c2149c8
TS
5494 break;
5495 case 9:
5496 switch (sel) {
5497 case 0:
2e70f6ef
PB
5498 /* Mark as an IO operation because we read the time. */
5499 if (use_icount)
5500 gen_io_start();
895c2d04 5501 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5502 if (use_icount) {
5503 gen_io_end();
2e70f6ef 5504 }
55807224
EI
5505 /* Break the TB to be able to take timer interrupts immediately
5506 after reading count. */
5507 ctx->bstate = BS_STOP;
2423f660
TS
5508 rn = "Count";
5509 break;
5510 /* 6,7 are implementation dependent */
9c2149c8
TS
5511 default:
5512 goto die;
876d4b07 5513 }
9c2149c8
TS
5514 break;
5515 case 10:
5516 switch (sel) {
5517 case 0:
7db13fae 5518 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5519 rn = "EntryHi";
5520 break;
9c2149c8
TS
5521 default:
5522 goto die;
876d4b07 5523 }
9c2149c8
TS
5524 break;
5525 case 11:
5526 switch (sel) {
5527 case 0:
7db13fae 5528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5529 rn = "Compare";
5530 break;
876d4b07 5531 /* 6,7 are implementation dependent */
9c2149c8
TS
5532 default:
5533 goto die;
876d4b07 5534 }
9c2149c8
TS
5535 break;
5536 case 12:
5537 switch (sel) {
5538 case 0:
7db13fae 5539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5540 rn = "Status";
5541 break;
9c2149c8 5542 case 1:
e189e748 5543 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5545 rn = "IntCtl";
5546 break;
9c2149c8 5547 case 2:
e189e748 5548 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5550 rn = "SRSCtl";
5551 break;
9c2149c8 5552 case 3:
e189e748 5553 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5555 rn = "SRSMap";
5556 break;
9c2149c8
TS
5557 default:
5558 goto die;
876d4b07 5559 }
9c2149c8
TS
5560 break;
5561 case 13:
5562 switch (sel) {
5563 case 0:
7db13fae 5564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5565 rn = "Cause";
5566 break;
9c2149c8
TS
5567 default:
5568 goto die;
876d4b07 5569 }
9c2149c8
TS
5570 break;
5571 case 14:
5572 switch (sel) {
5573 case 0:
7db13fae 5574 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5575 rn = "EPC";
5576 break;
9c2149c8
TS
5577 default:
5578 goto die;
876d4b07 5579 }
9c2149c8
TS
5580 break;
5581 case 15:
5582 switch (sel) {
5583 case 0:
7db13fae 5584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5585 rn = "PRid";
5586 break;
9c2149c8 5587 case 1:
e189e748 5588 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5590 rn = "EBase";
5591 break;
9c2149c8
TS
5592 default:
5593 goto die;
876d4b07 5594 }
9c2149c8
TS
5595 break;
5596 case 16:
5597 switch (sel) {
5598 case 0:
7db13fae 5599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5600 rn = "Config";
5601 break;
5602 case 1:
7db13fae 5603 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5604 rn = "Config1";
5605 break;
5606 case 2:
7db13fae 5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5608 rn = "Config2";
5609 break;
5610 case 3:
7db13fae 5611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5612 rn = "Config3";
5613 break;
5614 /* 6,7 are implementation dependent */
f0b3f3ae 5615 case 6:
7db13fae 5616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5617 rn = "Config6";
5618 break;
5619 case 7:
7db13fae 5620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5621 rn = "Config7";
5622 break;
9c2149c8
TS
5623 default:
5624 goto die;
5625 }
5626 break;
5627 case 17:
5628 switch (sel) {
5629 case 0:
895c2d04 5630 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5631 rn = "LLAddr";
5632 break;
9c2149c8
TS
5633 default:
5634 goto die;
5635 }
5636 break;
5637 case 18:
5638 switch (sel) {
fd88b6ab 5639 case 0 ... 7:
895c2d04 5640 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5641 rn = "WatchLo";
5642 break;
9c2149c8
TS
5643 default:
5644 goto die;
5645 }
5646 break;
5647 case 19:
5648 switch (sel) {
fd88b6ab 5649 case 0 ... 7:
895c2d04 5650 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5651 rn = "WatchHi";
5652 break;
9c2149c8
TS
5653 default:
5654 goto die;
5655 }
5656 break;
5657 case 20:
5658 switch (sel) {
5659 case 0:
e189e748 5660 check_insn(env, ctx, ISA_MIPS3);
7db13fae 5661 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5662 rn = "XContext";
5663 break;
9c2149c8
TS
5664 default:
5665 goto die;
5666 }
5667 break;
5668 case 21:
5669 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5670 switch (sel) {
5671 case 0:
7db13fae 5672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5673 rn = "Framemask";
5674 break;
9c2149c8
TS
5675 default:
5676 goto die;
5677 }
5678 break;
5679 case 22:
d9bea114 5680 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5681 rn = "'Diagnostic"; /* implementation dependent */
5682 break;
9c2149c8
TS
5683 case 23:
5684 switch (sel) {
5685 case 0:
895c2d04 5686 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5687 rn = "Debug";
5688 break;
9c2149c8 5689 case 1:
895c2d04 5690// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5691 rn = "TraceControl";
5692// break;
9c2149c8 5693 case 2:
895c2d04 5694// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5695 rn = "TraceControl2";
5696// break;
9c2149c8 5697 case 3:
895c2d04 5698// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5699 rn = "UserTraceData";
5700// break;
9c2149c8 5701 case 4:
895c2d04 5702// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5703 rn = "TraceBPC";
5704// break;
9c2149c8
TS
5705 default:
5706 goto die;
5707 }
5708 break;
5709 case 24:
5710 switch (sel) {
5711 case 0:
f0b3f3ae 5712 /* EJTAG support */
7db13fae 5713 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5714 rn = "DEPC";
5715 break;
9c2149c8
TS
5716 default:
5717 goto die;
5718 }
5719 break;
5720 case 25:
5721 switch (sel) {
5722 case 0:
7db13fae 5723 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5724 rn = "Performance0";
9c2149c8
TS
5725 break;
5726 case 1:
d9bea114 5727// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5728 rn = "Performance1";
5729// break;
9c2149c8 5730 case 2:
d9bea114 5731// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5732 rn = "Performance2";
5733// break;
9c2149c8 5734 case 3:
d9bea114 5735// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5736 rn = "Performance3";
5737// break;
9c2149c8 5738 case 4:
d9bea114 5739// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5740 rn = "Performance4";
5741// break;
9c2149c8 5742 case 5:
d9bea114 5743// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5744 rn = "Performance5";
5745// break;
9c2149c8 5746 case 6:
d9bea114 5747// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5748 rn = "Performance6";
5749// break;
9c2149c8 5750 case 7:
d9bea114 5751// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5752 rn = "Performance7";
5753// break;
9c2149c8
TS
5754 default:
5755 goto die;
5756 }
5757 break;
5758 case 26:
d9bea114 5759 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5760 rn = "ECC";
5761 break;
9c2149c8
TS
5762 case 27:
5763 switch (sel) {
5764 /* ignored */
5765 case 0 ... 3:
d9bea114 5766 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5767 rn = "CacheErr";
5768 break;
9c2149c8
TS
5769 default:
5770 goto die;
5771 }
5772 break;
5773 case 28:
5774 switch (sel) {
5775 case 0:
5776 case 2:
5777 case 4:
5778 case 6:
7db13fae 5779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5780 rn = "TagLo";
5781 break;
5782 case 1:
5783 case 3:
5784 case 5:
5785 case 7:
7db13fae 5786 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5787 rn = "DataLo";
5788 break;
5789 default:
5790 goto die;
5791 }
5792 break;
5793 case 29:
5794 switch (sel) {
5795 case 0:
5796 case 2:
5797 case 4:
5798 case 6:
7db13fae 5799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5800 rn = "TagHi";
5801 break;
5802 case 1:
5803 case 3:
5804 case 5:
5805 case 7:
7db13fae 5806 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5807 rn = "DataHi";
5808 break;
5809 default:
5810 goto die;
5811 }
5812 break;
5813 case 30:
5814 switch (sel) {
5815 case 0:
7db13fae 5816 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5817 rn = "ErrorEPC";
5818 break;
9c2149c8
TS
5819 default:
5820 goto die;
5821 }
5822 break;
5823 case 31:
5824 switch (sel) {
5825 case 0:
f0b3f3ae 5826 /* EJTAG support */
7db13fae 5827 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5828 rn = "DESAVE";
5829 break;
9c2149c8
TS
5830 default:
5831 goto die;
5832 }
5833 break;
5834 default:
876d4b07 5835 goto die;
9c2149c8 5836 }
2abf314d 5837 (void)rn; /* avoid a compiler warning */
d12d51d5 5838 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5839 return;
5840
5841die:
d12d51d5 5842 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5843 generate_exception(ctx, EXCP_RI);
5844}
5845
7db13fae 5846static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5847{
5848 const char *rn = "invalid";
5849
e189e748
TS
5850 if (sel != 0)
5851 check_insn(env, ctx, ISA_MIPS64);
5852
2e70f6ef
PB
5853 if (use_icount)
5854 gen_io_start();
5855
9c2149c8
TS
5856 switch (reg) {
5857 case 0:
5858 switch (sel) {
5859 case 0:
895c2d04 5860 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5861 rn = "Index";
5862 break;
5863 case 1:
7385ac0b 5864 check_insn(env, ctx, ASE_MT);
895c2d04 5865 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5866 rn = "MVPControl";
ead9360e 5867 break;
9c2149c8 5868 case 2:
7385ac0b 5869 check_insn(env, ctx, ASE_MT);
ead9360e 5870 /* ignored */
9c2149c8 5871 rn = "MVPConf0";
ead9360e 5872 break;
9c2149c8 5873 case 3:
7385ac0b 5874 check_insn(env, ctx, ASE_MT);
ead9360e 5875 /* ignored */
9c2149c8 5876 rn = "MVPConf1";
ead9360e 5877 break;
9c2149c8
TS
5878 default:
5879 goto die;
5880 }
5881 break;
5882 case 1:
5883 switch (sel) {
5884 case 0:
2423f660 5885 /* ignored */
9c2149c8 5886 rn = "Random";
2423f660 5887 break;
9c2149c8 5888 case 1:
7385ac0b 5889 check_insn(env, ctx, ASE_MT);
895c2d04 5890 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5891 rn = "VPEControl";
ead9360e 5892 break;
9c2149c8 5893 case 2:
7385ac0b 5894 check_insn(env, ctx, ASE_MT);
895c2d04 5895 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5896 rn = "VPEConf0";
ead9360e 5897 break;
9c2149c8 5898 case 3:
7385ac0b 5899 check_insn(env, ctx, ASE_MT);
895c2d04 5900 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5901 rn = "VPEConf1";
ead9360e 5902 break;
9c2149c8 5903 case 4:
7385ac0b 5904 check_insn(env, ctx, ASE_MT);
895c2d04 5905 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5906 rn = "YQMask";
ead9360e 5907 break;
9c2149c8 5908 case 5:
7385ac0b 5909 check_insn(env, ctx, ASE_MT);
7db13fae 5910 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5911 rn = "VPESchedule";
ead9360e 5912 break;
9c2149c8 5913 case 6:
7385ac0b 5914 check_insn(env, ctx, ASE_MT);
7db13fae 5915 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5916 rn = "VPEScheFBack";
ead9360e 5917 break;
9c2149c8 5918 case 7:
7385ac0b 5919 check_insn(env, ctx, ASE_MT);
895c2d04 5920 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5921 rn = "VPEOpt";
ead9360e 5922 break;
9c2149c8
TS
5923 default:
5924 goto die;
5925 }
5926 break;
5927 case 2:
5928 switch (sel) {
5929 case 0:
895c2d04 5930 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5931 rn = "EntryLo0";
5932 break;
9c2149c8 5933 case 1:
7385ac0b 5934 check_insn(env, ctx, ASE_MT);
895c2d04 5935 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5936 rn = "TCStatus";
ead9360e 5937 break;
9c2149c8 5938 case 2:
7385ac0b 5939 check_insn(env, ctx, ASE_MT);
895c2d04 5940 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5941 rn = "TCBind";
ead9360e 5942 break;
9c2149c8 5943 case 3:
7385ac0b 5944 check_insn(env, ctx, ASE_MT);
895c2d04 5945 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5946 rn = "TCRestart";
ead9360e 5947 break;
9c2149c8 5948 case 4:
7385ac0b 5949 check_insn(env, ctx, ASE_MT);
895c2d04 5950 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5951 rn = "TCHalt";
ead9360e 5952 break;
9c2149c8 5953 case 5:
7385ac0b 5954 check_insn(env, ctx, ASE_MT);
895c2d04 5955 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5956 rn = "TCContext";
ead9360e 5957 break;
9c2149c8 5958 case 6:
7385ac0b 5959 check_insn(env, ctx, ASE_MT);
895c2d04 5960 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5961 rn = "TCSchedule";
ead9360e 5962 break;
9c2149c8 5963 case 7:
7385ac0b 5964 check_insn(env, ctx, ASE_MT);
895c2d04 5965 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5966 rn = "TCScheFBack";
ead9360e 5967 break;
9c2149c8
TS
5968 default:
5969 goto die;
5970 }
5971 break;
5972 case 3:
5973 switch (sel) {
5974 case 0:
895c2d04 5975 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5976 rn = "EntryLo1";
5977 break;
9c2149c8
TS
5978 default:
5979 goto die;
876d4b07 5980 }
9c2149c8
TS
5981 break;
5982 case 4:
5983 switch (sel) {
5984 case 0:
895c2d04 5985 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5986 rn = "Context";
5987 break;
9c2149c8 5988 case 1:
895c2d04 5989// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
5990 rn = "ContextConfig";
5991// break;
9c2149c8
TS
5992 default:
5993 goto die;
876d4b07 5994 }
9c2149c8
TS
5995 break;
5996 case 5:
5997 switch (sel) {
5998 case 0:
895c2d04 5999 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6000 rn = "PageMask";
6001 break;
9c2149c8 6002 case 1:
e189e748 6003 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6004 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6005 rn = "PageGrain";
6006 break;
9c2149c8
TS
6007 default:
6008 goto die;
876d4b07 6009 }
9c2149c8
TS
6010 break;
6011 case 6:
6012 switch (sel) {
6013 case 0:
895c2d04 6014 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6015 rn = "Wired";
6016 break;
9c2149c8 6017 case 1:
e189e748 6018 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6019 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6020 rn = "SRSConf0";
ead9360e 6021 break;
9c2149c8 6022 case 2:
e189e748 6023 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6024 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6025 rn = "SRSConf1";
ead9360e 6026 break;
9c2149c8 6027 case 3:
e189e748 6028 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6029 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6030 rn = "SRSConf2";
ead9360e 6031 break;
9c2149c8 6032 case 4:
e189e748 6033 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6034 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6035 rn = "SRSConf3";
ead9360e 6036 break;
9c2149c8 6037 case 5:
e189e748 6038 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6039 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6040 rn = "SRSConf4";
ead9360e 6041 break;
9c2149c8
TS
6042 default:
6043 goto die;
876d4b07 6044 }
9c2149c8
TS
6045 break;
6046 case 7:
6047 switch (sel) {
6048 case 0:
e189e748 6049 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6050 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
6051 rn = "HWREna";
6052 break;
9c2149c8
TS
6053 default:
6054 goto die;
876d4b07 6055 }
9c2149c8
TS
6056 break;
6057 case 8:
6058 /* ignored */
f0b3f3ae 6059 rn = "BadVAddr";
9c2149c8
TS
6060 break;
6061 case 9:
6062 switch (sel) {
6063 case 0:
895c2d04 6064 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6065 rn = "Count";
6066 break;
876d4b07 6067 /* 6,7 are implementation dependent */
9c2149c8
TS
6068 default:
6069 goto die;
876d4b07
TS
6070 }
6071 /* Stop translation as we may have switched the execution mode */
6072 ctx->bstate = BS_STOP;
9c2149c8
TS
6073 break;
6074 case 10:
6075 switch (sel) {
6076 case 0:
895c2d04 6077 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6078 rn = "EntryHi";
6079 break;
9c2149c8
TS
6080 default:
6081 goto die;
876d4b07 6082 }
9c2149c8
TS
6083 break;
6084 case 11:
6085 switch (sel) {
6086 case 0:
895c2d04 6087 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6088 rn = "Compare";
6089 break;
876d4b07 6090 /* 6,7 are implementation dependent */
9c2149c8
TS
6091 default:
6092 goto die;
876d4b07 6093 }
de9a95f0
AJ
6094 /* Stop translation as we may have switched the execution mode */
6095 ctx->bstate = BS_STOP;
9c2149c8
TS
6096 break;
6097 case 12:
6098 switch (sel) {
6099 case 0:
867abc7e 6100 save_cpu_state(ctx, 1);
895c2d04 6101 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6102 /* BS_STOP isn't good enough here, hflags may have changed. */
6103 gen_save_pc(ctx->pc + 4);
6104 ctx->bstate = BS_EXCP;
2423f660
TS
6105 rn = "Status";
6106 break;
9c2149c8 6107 case 1:
e189e748 6108 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6109 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6110 /* Stop translation as we may have switched the execution mode */
6111 ctx->bstate = BS_STOP;
2423f660
TS
6112 rn = "IntCtl";
6113 break;
9c2149c8 6114 case 2:
e189e748 6115 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6116 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6117 /* Stop translation as we may have switched the execution mode */
6118 ctx->bstate = BS_STOP;
2423f660
TS
6119 rn = "SRSCtl";
6120 break;
9c2149c8 6121 case 3:
e189e748 6122 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 6123 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6124 /* Stop translation as we may have switched the execution mode */
6125 ctx->bstate = BS_STOP;
2423f660
TS
6126 rn = "SRSMap";
6127 break;
6128 default:
9c2149c8 6129 goto die;
876d4b07 6130 }
9c2149c8
TS
6131 break;
6132 case 13:
6133 switch (sel) {
6134 case 0:
867abc7e 6135 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6136 /* Mark as an IO operation because we may trigger a software
6137 interrupt. */
6138 if (use_icount) {
6139 gen_io_start();
6140 }
895c2d04 6141 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6142 if (use_icount) {
6143 gen_io_end();
6144 }
6145 /* Stop translation as we may have triggered an intetrupt */
6146 ctx->bstate = BS_STOP;
2423f660
TS
6147 rn = "Cause";
6148 break;
9c2149c8
TS
6149 default:
6150 goto die;
876d4b07 6151 }
9c2149c8
TS
6152 break;
6153 case 14:
6154 switch (sel) {
6155 case 0:
7db13fae 6156 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6157 rn = "EPC";
6158 break;
9c2149c8
TS
6159 default:
6160 goto die;
876d4b07 6161 }
9c2149c8
TS
6162 break;
6163 case 15:
6164 switch (sel) {
6165 case 0:
2423f660
TS
6166 /* ignored */
6167 rn = "PRid";
6168 break;
9c2149c8 6169 case 1:
e189e748 6170 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6171 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6172 rn = "EBase";
6173 break;
9c2149c8
TS
6174 default:
6175 goto die;
876d4b07 6176 }
9c2149c8
TS
6177 break;
6178 case 16:
6179 switch (sel) {
6180 case 0:
895c2d04 6181 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6182 rn = "Config";
2423f660
TS
6183 /* Stop translation as we may have switched the execution mode */
6184 ctx->bstate = BS_STOP;
9c2149c8
TS
6185 break;
6186 case 1:
1fc7bf6e 6187 /* ignored, read only */
9c2149c8
TS
6188 rn = "Config1";
6189 break;
6190 case 2:
895c2d04 6191 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6192 rn = "Config2";
2423f660
TS
6193 /* Stop translation as we may have switched the execution mode */
6194 ctx->bstate = BS_STOP;
9c2149c8
TS
6195 break;
6196 case 3:
2423f660 6197 /* ignored */
9c2149c8
TS
6198 rn = "Config3";
6199 break;
6200 /* 6,7 are implementation dependent */
6201 default:
6202 rn = "Invalid config selector";
6203 goto die;
6204 }
9c2149c8
TS
6205 break;
6206 case 17:
6207 switch (sel) {
6208 case 0:
895c2d04 6209 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6210 rn = "LLAddr";
6211 break;
9c2149c8
TS
6212 default:
6213 goto die;
6214 }
6215 break;
6216 case 18:
6217 switch (sel) {
fd88b6ab 6218 case 0 ... 7:
895c2d04 6219 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6220 rn = "WatchLo";
6221 break;
9c2149c8
TS
6222 default:
6223 goto die;
6224 }
6225 break;
6226 case 19:
6227 switch (sel) {
fd88b6ab 6228 case 0 ... 7:
895c2d04 6229 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6230 rn = "WatchHi";
6231 break;
9c2149c8
TS
6232 default:
6233 goto die;
6234 }
6235 break;
6236 case 20:
6237 switch (sel) {
6238 case 0:
e189e748 6239 check_insn(env, ctx, ISA_MIPS3);
895c2d04 6240 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6241 rn = "XContext";
6242 break;
9c2149c8
TS
6243 default:
6244 goto die;
6245 }
6246 break;
6247 case 21:
6248 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6249 switch (sel) {
6250 case 0:
895c2d04 6251 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6252 rn = "Framemask";
6253 break;
9c2149c8
TS
6254 default:
6255 goto die;
6256 }
6257 break;
6258 case 22:
6259 /* ignored */
6260 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6261 break;
9c2149c8
TS
6262 case 23:
6263 switch (sel) {
6264 case 0:
895c2d04 6265 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6266 /* BS_STOP isn't good enough here, hflags may have changed. */
6267 gen_save_pc(ctx->pc + 4);
6268 ctx->bstate = BS_EXCP;
2423f660
TS
6269 rn = "Debug";
6270 break;
9c2149c8 6271 case 1:
895c2d04 6272// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6273 /* Stop translation as we may have switched the execution mode */
6274 ctx->bstate = BS_STOP;
2423f660
TS
6275 rn = "TraceControl";
6276// break;
9c2149c8 6277 case 2:
895c2d04 6278// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6279 /* Stop translation as we may have switched the execution mode */
6280 ctx->bstate = BS_STOP;
2423f660
TS
6281 rn = "TraceControl2";
6282// break;
9c2149c8 6283 case 3:
895c2d04 6284// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6285 /* Stop translation as we may have switched the execution mode */
6286 ctx->bstate = BS_STOP;
2423f660
TS
6287 rn = "UserTraceData";
6288// break;
9c2149c8 6289 case 4:
895c2d04 6290// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6291 /* Stop translation as we may have switched the execution mode */
6292 ctx->bstate = BS_STOP;
2423f660
TS
6293 rn = "TraceBPC";
6294// break;
9c2149c8
TS
6295 default:
6296 goto die;
6297 }
9c2149c8
TS
6298 break;
6299 case 24:
6300 switch (sel) {
6301 case 0:
f1aa6320 6302 /* EJTAG support */
7db13fae 6303 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6304 rn = "DEPC";
6305 break;
9c2149c8
TS
6306 default:
6307 goto die;
6308 }
6309 break;
6310 case 25:
6311 switch (sel) {
6312 case 0:
895c2d04 6313 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6314 rn = "Performance0";
6315 break;
9c2149c8 6316 case 1:
895c2d04 6317// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6318 rn = "Performance1";
6319// break;
9c2149c8 6320 case 2:
895c2d04 6321// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6322 rn = "Performance2";
6323// break;
9c2149c8 6324 case 3:
895c2d04 6325// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6326 rn = "Performance3";
6327// break;
9c2149c8 6328 case 4:
895c2d04 6329// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6330 rn = "Performance4";
6331// break;
9c2149c8 6332 case 5:
895c2d04 6333// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6334 rn = "Performance5";
6335// break;
9c2149c8 6336 case 6:
895c2d04 6337// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6338 rn = "Performance6";
6339// break;
9c2149c8 6340 case 7:
895c2d04 6341// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6342 rn = "Performance7";
6343// break;
9c2149c8
TS
6344 default:
6345 goto die;
6346 }
876d4b07 6347 break;
9c2149c8 6348 case 26:
876d4b07 6349 /* ignored */
9c2149c8 6350 rn = "ECC";
876d4b07 6351 break;
9c2149c8
TS
6352 case 27:
6353 switch (sel) {
6354 case 0 ... 3:
2423f660
TS
6355 /* ignored */
6356 rn = "CacheErr";
6357 break;
9c2149c8
TS
6358 default:
6359 goto die;
6360 }
876d4b07 6361 break;
9c2149c8
TS
6362 case 28:
6363 switch (sel) {
6364 case 0:
6365 case 2:
6366 case 4:
6367 case 6:
895c2d04 6368 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6369 rn = "TagLo";
6370 break;
6371 case 1:
6372 case 3:
6373 case 5:
6374 case 7:
895c2d04 6375 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6376 rn = "DataLo";
6377 break;
6378 default:
6379 goto die;
6380 }
6381 break;
6382 case 29:
6383 switch (sel) {
6384 case 0:
6385 case 2:
6386 case 4:
6387 case 6:
895c2d04 6388 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6389 rn = "TagHi";
6390 break;
6391 case 1:
6392 case 3:
6393 case 5:
6394 case 7:
895c2d04 6395 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6396 rn = "DataHi";
6397 break;
6398 default:
6399 rn = "invalid sel";
6400 goto die;
6401 }
876d4b07 6402 break;
9c2149c8
TS
6403 case 30:
6404 switch (sel) {
6405 case 0:
7db13fae 6406 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6407 rn = "ErrorEPC";
6408 break;
9c2149c8
TS
6409 default:
6410 goto die;
6411 }
6412 break;
6413 case 31:
6414 switch (sel) {
6415 case 0:
f1aa6320 6416 /* EJTAG support */
7db13fae 6417 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6418 rn = "DESAVE";
6419 break;
9c2149c8
TS
6420 default:
6421 goto die;
6422 }
876d4b07
TS
6423 /* Stop translation as we may have switched the execution mode */
6424 ctx->bstate = BS_STOP;
9c2149c8
TS
6425 break;
6426 default:
876d4b07 6427 goto die;
9c2149c8 6428 }
2abf314d 6429 (void)rn; /* avoid a compiler warning */
d12d51d5 6430 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6431 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6432 if (use_icount) {
6433 gen_io_end();
6434 ctx->bstate = BS_STOP;
6435 }
9c2149c8
TS
6436 return;
6437
6438die:
d12d51d5 6439 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6440 generate_exception(ctx, EXCP_RI);
6441}
d26bc211 6442#endif /* TARGET_MIPS64 */
9c2149c8 6443
7db13fae 6444static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6445 int u, int sel, int h)
6446{
6447 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6448 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6449
6450 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6451 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6452 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6453 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6454 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6455 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6456 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6457 else if (u == 0) {
6458 switch (rt) {
5a25ce94
EI
6459 case 1:
6460 switch (sel) {
6461 case 1:
895c2d04 6462 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6463 break;
6464 case 2:
895c2d04 6465 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6466 break;
6467 default:
6468 goto die;
6469 break;
6470 }
6471 break;
ead9360e
TS
6472 case 2:
6473 switch (sel) {
6474 case 1:
895c2d04 6475 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6476 break;
6477 case 2:
895c2d04 6478 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6479 break;
6480 case 3:
895c2d04 6481 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6482 break;
6483 case 4:
895c2d04 6484 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6485 break;
6486 case 5:
895c2d04 6487 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6488 break;
6489 case 6:
895c2d04 6490 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6491 break;
6492 case 7:
895c2d04 6493 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6494 break;
6495 default:
1a3fd9c3 6496 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6497 break;
6498 }
6499 break;
6500 case 10:
6501 switch (sel) {
6502 case 0:
895c2d04 6503 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6504 break;
6505 default:
1a3fd9c3 6506 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6507 break;
6508 }
6509 case 12:
6510 switch (sel) {
6511 case 0:
895c2d04 6512 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6513 break;
6514 default:
1a3fd9c3 6515 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6516 break;
6517 }
5a25ce94
EI
6518 case 13:
6519 switch (sel) {
6520 case 0:
895c2d04 6521 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6522 break;
6523 default:
6524 goto die;
6525 break;
6526 }
6527 break;
6528 case 14:
6529 switch (sel) {
6530 case 0:
895c2d04 6531 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6532 break;
6533 default:
6534 goto die;
6535 break;
6536 }
6537 break;
6538 case 15:
6539 switch (sel) {
6540 case 1:
895c2d04 6541 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6542 break;
6543 default:
6544 goto die;
6545 break;
6546 }
6547 break;
6548 case 16:
6549 switch (sel) {
6550 case 0 ... 7:
895c2d04 6551 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6552 break;
6553 default:
6554 goto die;
6555 break;
6556 }
6557 break;
ead9360e
TS
6558 case 23:
6559 switch (sel) {
6560 case 0:
895c2d04 6561 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6562 break;
6563 default:
1a3fd9c3 6564 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6565 break;
6566 }
6567 break;
6568 default:
1a3fd9c3 6569 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6570 }
6571 } else switch (sel) {
6572 /* GPR registers. */
6573 case 0:
895c2d04 6574 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6575 break;
6576 /* Auxiliary CPU registers */
6577 case 1:
6578 switch (rt) {
6579 case 0:
895c2d04 6580 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6581 break;
6582 case 1:
895c2d04 6583 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6584 break;
6585 case 2:
895c2d04 6586 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6587 break;
6588 case 4:
895c2d04 6589 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6590 break;
6591 case 5:
895c2d04 6592 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6593 break;
6594 case 6:
895c2d04 6595 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6596 break;
6597 case 8:
895c2d04 6598 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6599 break;
6600 case 9:
895c2d04 6601 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6602 break;
6603 case 10:
895c2d04 6604 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6605 break;
6606 case 12:
895c2d04 6607 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6608 break;
6609 case 13:
895c2d04 6610 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6611 break;
6612 case 14:
895c2d04 6613 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6614 break;
6615 case 16:
895c2d04 6616 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6617 break;
6618 default:
6619 goto die;
6620 }
6621 break;
6622 /* Floating point (COP1). */
6623 case 2:
6624 /* XXX: For now we support only a single FPU context. */
6625 if (h == 0) {
a7812ae4 6626 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6627
6628 gen_load_fpr32(fp0, rt);
6629 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6630 tcg_temp_free_i32(fp0);
ead9360e 6631 } else {
a7812ae4 6632 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6633
6634 gen_load_fpr32h(fp0, rt);
6635 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6636 tcg_temp_free_i32(fp0);
ead9360e
TS
6637 }
6638 break;
6639 case 3:
6640 /* XXX: For now we support only a single FPU context. */
895c2d04 6641 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6642 break;
6643 /* COP2: Not implemented. */
6644 case 4:
6645 case 5:
6646 /* fall through */
6647 default:
6648 goto die;
6649 }
d12d51d5 6650 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6651 gen_store_gpr(t0, rd);
6652 tcg_temp_free(t0);
ead9360e
TS
6653 return;
6654
6655die:
1a3fd9c3 6656 tcg_temp_free(t0);
d12d51d5 6657 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6658 generate_exception(ctx, EXCP_RI);
6659}
6660
7db13fae 6661static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6662 int u, int sel, int h)
6663{
6664 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6665 TCGv t0 = tcg_temp_local_new();
ead9360e 6666
1a3fd9c3 6667 gen_load_gpr(t0, rt);
ead9360e 6668 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6669 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6670 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6671 /* NOP */ ;
6672 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6673 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6674 /* NOP */ ;
6675 else if (u == 0) {
6676 switch (rd) {
5a25ce94
EI
6677 case 1:
6678 switch (sel) {
6679 case 1:
895c2d04 6680 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6681 break;
6682 case 2:
895c2d04 6683 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6684 break;
6685 default:
6686 goto die;
6687 break;
6688 }
6689 break;
ead9360e
TS
6690 case 2:
6691 switch (sel) {
6692 case 1:
895c2d04 6693 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6694 break;
6695 case 2:
895c2d04 6696 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6697 break;
6698 case 3:
895c2d04 6699 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6700 break;
6701 case 4:
895c2d04 6702 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6703 break;
6704 case 5:
895c2d04 6705 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6706 break;
6707 case 6:
895c2d04 6708 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6709 break;
6710 case 7:
895c2d04 6711 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6712 break;
6713 default:
1a3fd9c3 6714 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6715 break;
6716 }
6717 break;
6718 case 10:
6719 switch (sel) {
6720 case 0:
895c2d04 6721 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6722 break;
6723 default:
1a3fd9c3 6724 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6725 break;
6726 }
6727 case 12:
6728 switch (sel) {
6729 case 0:
895c2d04 6730 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6731 break;
6732 default:
1a3fd9c3 6733 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6734 break;
6735 }
5a25ce94
EI
6736 case 13:
6737 switch (sel) {
6738 case 0:
895c2d04 6739 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6740 break;
6741 default:
6742 goto die;
6743 break;
6744 }
6745 break;
6746 case 15:
6747 switch (sel) {
6748 case 1:
895c2d04 6749 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6750 break;
6751 default:
6752 goto die;
6753 break;
6754 }
6755 break;
ead9360e
TS
6756 case 23:
6757 switch (sel) {
6758 case 0:
895c2d04 6759 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6760 break;
6761 default:
1a3fd9c3 6762 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6763 break;
6764 }
6765 break;
6766 default:
1a3fd9c3 6767 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6768 }
6769 } else switch (sel) {
6770 /* GPR registers. */
6771 case 0:
895c2d04 6772 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6773 break;
6774 /* Auxiliary CPU registers */
6775 case 1:
6776 switch (rd) {
6777 case 0:
895c2d04 6778 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6779 break;
6780 case 1:
895c2d04 6781 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6782 break;
6783 case 2:
895c2d04 6784 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6785 break;
6786 case 4:
895c2d04 6787 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6788 break;
6789 case 5:
895c2d04 6790 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6791 break;
6792 case 6:
895c2d04 6793 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6794 break;
6795 case 8:
895c2d04 6796 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6797 break;
6798 case 9:
895c2d04 6799 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6800 break;
6801 case 10:
895c2d04 6802 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6803 break;
6804 case 12:
895c2d04 6805 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6806 break;
6807 case 13:
895c2d04 6808 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6809 break;
6810 case 14:
895c2d04 6811 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6812 break;
6813 case 16:
895c2d04 6814 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6815 break;
6816 default:
6817 goto die;
6818 }
6819 break;
6820 /* Floating point (COP1). */
6821 case 2:
6822 /* XXX: For now we support only a single FPU context. */
6823 if (h == 0) {
a7812ae4 6824 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6825
6826 tcg_gen_trunc_tl_i32(fp0, t0);
6827 gen_store_fpr32(fp0, rd);
a7812ae4 6828 tcg_temp_free_i32(fp0);
ead9360e 6829 } else {
a7812ae4 6830 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6831
6832 tcg_gen_trunc_tl_i32(fp0, t0);
6833 gen_store_fpr32h(fp0, rd);
a7812ae4 6834 tcg_temp_free_i32(fp0);
ead9360e
TS
6835 }
6836 break;
6837 case 3:
6838 /* XXX: For now we support only a single FPU context. */
895c2d04 6839 gen_helper_0e1i(ctc1, t0, rd);
ead9360e
TS
6840 break;
6841 /* COP2: Not implemented. */
6842 case 4:
6843 case 5:
6844 /* fall through */
6845 default:
6846 goto die;
6847 }
d12d51d5 6848 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6849 tcg_temp_free(t0);
ead9360e
TS
6850 return;
6851
6852die:
1a3fd9c3 6853 tcg_temp_free(t0);
d12d51d5 6854 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6855 generate_exception(ctx, EXCP_RI);
6856}
6857
7db13fae 6858static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6859{
287c4b84 6860 const char *opn = "ldst";
6af0bf9c 6861
2e15497c 6862 check_cp0_enabled(ctx);
6af0bf9c
FB
6863 switch (opc) {
6864 case OPC_MFC0:
6865 if (rt == 0) {
ead9360e 6866 /* Treat as NOP. */
6af0bf9c
FB
6867 return;
6868 }
1fc7bf6e 6869 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6870 opn = "mfc0";
6871 break;
6872 case OPC_MTC0:
1a3fd9c3 6873 {
1fc7bf6e 6874 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6875
6876 gen_load_gpr(t0, rt);
1a3fd9c3
TS
6877 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6878 tcg_temp_free(t0);
6879 }
6af0bf9c
FB
6880 opn = "mtc0";
6881 break;
d26bc211 6882#if defined(TARGET_MIPS64)
9c2149c8 6883 case OPC_DMFC0:
e189e748 6884 check_insn(env, ctx, ISA_MIPS3);
9c2149c8 6885 if (rt == 0) {
ead9360e 6886 /* Treat as NOP. */
9c2149c8
TS
6887 return;
6888 }
1fc7bf6e 6889 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6890 opn = "dmfc0";
6891 break;
6892 case OPC_DMTC0:
e189e748 6893 check_insn(env, ctx, ISA_MIPS3);
1a3fd9c3 6894 {
1fc7bf6e 6895 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6896
6897 gen_load_gpr(t0, rt);
1a3fd9c3
TS
6898 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6899 tcg_temp_free(t0);
6900 }
9c2149c8
TS
6901 opn = "dmtc0";
6902 break;
534ce69f 6903#endif
ead9360e 6904 case OPC_MFTR:
7385ac0b 6905 check_insn(env, ctx, ASE_MT);
ead9360e
TS
6906 if (rd == 0) {
6907 /* Treat as NOP. */
6908 return;
6909 }
6c5c1e20 6910 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6911 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6912 opn = "mftr";
6913 break;
6914 case OPC_MTTR:
7385ac0b 6915 check_insn(env, ctx, ASE_MT);
6c5c1e20 6916 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6917 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6918 opn = "mttr";
6919 break;
6af0bf9c 6920 case OPC_TLBWI:
6af0bf9c 6921 opn = "tlbwi";
c01fccd2 6922 if (!env->tlb->helper_tlbwi)
29929e34 6923 goto die;
895c2d04 6924 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6925 break;
6926 case OPC_TLBWR:
6af0bf9c 6927 opn = "tlbwr";
c01fccd2 6928 if (!env->tlb->helper_tlbwr)
29929e34 6929 goto die;
895c2d04 6930 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6931 break;
6932 case OPC_TLBP:
6af0bf9c 6933 opn = "tlbp";
c01fccd2 6934 if (!env->tlb->helper_tlbp)
29929e34 6935 goto die;
895c2d04 6936 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6937 break;
6938 case OPC_TLBR:
6af0bf9c 6939 opn = "tlbr";
c01fccd2 6940 if (!env->tlb->helper_tlbr)
29929e34 6941 goto die;
895c2d04 6942 gen_helper_tlbr(cpu_env);
6af0bf9c 6943 break;
6af0bf9c
FB
6944 case OPC_ERET:
6945 opn = "eret";
e189e748 6946 check_insn(env, ctx, ISA_MIPS2);
895c2d04 6947 gen_helper_eret(cpu_env);
6af0bf9c
FB
6948 ctx->bstate = BS_EXCP;
6949 break;
6950 case OPC_DERET:
6951 opn = "deret";
e189e748 6952 check_insn(env, ctx, ISA_MIPS32);
6af0bf9c 6953 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6954 MIPS_INVAL(opn);
6af0bf9c
FB
6955 generate_exception(ctx, EXCP_RI);
6956 } else {
895c2d04 6957 gen_helper_deret(cpu_env);
6af0bf9c
FB
6958 ctx->bstate = BS_EXCP;
6959 }
6960 break;
4ad40f36
FB
6961 case OPC_WAIT:
6962 opn = "wait";
e189e748 6963 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6964 /* If we get an exception, we want to restart at next instruction */
6965 ctx->pc += 4;
6966 save_cpu_state(ctx, 1);
6967 ctx->pc -= 4;
895c2d04 6968 gen_helper_wait(cpu_env);
4ad40f36
FB
6969 ctx->bstate = BS_EXCP;
6970 break;
6af0bf9c 6971 default:
29929e34 6972 die:
923617a3 6973 MIPS_INVAL(opn);
6af0bf9c
FB
6974 generate_exception(ctx, EXCP_RI);
6975 return;
6976 }
2abf314d 6977 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
6978 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6979}
f1aa6320 6980#endif /* !CONFIG_USER_ONLY */
6af0bf9c 6981
6ea83fed 6982/* CP1 Branches (before delay slot) */
7db13fae 6983static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
5a5012ec 6984 int32_t cc, int32_t offset)
6ea83fed
FB
6985{
6986 target_ulong btarget;
923617a3 6987 const char *opn = "cp1 cond branch";
a7812ae4 6988 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 6989
e189e748
TS
6990 if (cc != 0)
6991 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6992
6ea83fed
FB
6993 btarget = ctx->pc + 4 + offset;
6994
7a387fff
TS
6995 switch (op) {
6996 case OPC_BC1F:
d94536f4
AJ
6997 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6998 tcg_gen_not_i32(t0, t0);
6999 tcg_gen_andi_i32(t0, t0, 1);
7000 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7001 opn = "bc1f";
6ea83fed 7002 goto not_likely;
7a387fff 7003 case OPC_BC1FL:
d94536f4
AJ
7004 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7005 tcg_gen_not_i32(t0, t0);
7006 tcg_gen_andi_i32(t0, t0, 1);
7007 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7008 opn = "bc1fl";
6ea83fed 7009 goto likely;
7a387fff 7010 case OPC_BC1T:
d94536f4
AJ
7011 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7012 tcg_gen_andi_i32(t0, t0, 1);
7013 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7014 opn = "bc1t";
5a5012ec 7015 goto not_likely;
7a387fff 7016 case OPC_BC1TL:
d94536f4
AJ
7017 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7018 tcg_gen_andi_i32(t0, t0, 1);
7019 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7020 opn = "bc1tl";
6ea83fed
FB
7021 likely:
7022 ctx->hflags |= MIPS_HFLAG_BL;
7023 break;
5a5012ec 7024 case OPC_BC1FANY2:
a16336e4 7025 {
d94536f4
AJ
7026 TCGv_i32 t1 = tcg_temp_new_i32();
7027 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7028 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7029 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7030 tcg_temp_free_i32(t1);
d94536f4
AJ
7031 tcg_gen_andi_i32(t0, t0, 1);
7032 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7033 }
fd4a04eb 7034 opn = "bc1any2f";
5a5012ec
TS
7035 goto not_likely;
7036 case OPC_BC1TANY2:
a16336e4 7037 {
d94536f4
AJ
7038 TCGv_i32 t1 = tcg_temp_new_i32();
7039 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7040 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7041 tcg_gen_or_i32(t0, t0, t1);
7042 tcg_temp_free_i32(t1);
7043 tcg_gen_andi_i32(t0, t0, 1);
7044 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7045 }
fd4a04eb 7046 opn = "bc1any2t";
5a5012ec
TS
7047 goto not_likely;
7048 case OPC_BC1FANY4:
a16336e4 7049 {
d94536f4
AJ
7050 TCGv_i32 t1 = tcg_temp_new_i32();
7051 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7052 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7053 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7054 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7055 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7056 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7057 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7058 tcg_temp_free_i32(t1);
d94536f4
AJ
7059 tcg_gen_andi_i32(t0, t0, 1);
7060 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7061 }
fd4a04eb 7062 opn = "bc1any4f";
5a5012ec
TS
7063 goto not_likely;
7064 case OPC_BC1TANY4:
a16336e4 7065 {
d94536f4
AJ
7066 TCGv_i32 t1 = tcg_temp_new_i32();
7067 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7068 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7069 tcg_gen_or_i32(t0, t0, t1);
7070 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7071 tcg_gen_or_i32(t0, t0, t1);
7072 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7073 tcg_gen_or_i32(t0, t0, t1);
7074 tcg_temp_free_i32(t1);
7075 tcg_gen_andi_i32(t0, t0, 1);
7076 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7077 }
fd4a04eb 7078 opn = "bc1any4t";
5a5012ec
TS
7079 not_likely:
7080 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7081 break;
7082 default:
923617a3 7083 MIPS_INVAL(opn);
e397ee33 7084 generate_exception (ctx, EXCP_RI);
6c5c1e20 7085 goto out;
6ea83fed 7086 }
2abf314d 7087 (void)opn; /* avoid a compiler warning */
923617a3 7088 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7089 ctx->hflags, btarget);
7090 ctx->btarget = btarget;
6c5c1e20
TS
7091
7092 out:
a7812ae4 7093 tcg_temp_free_i32(t0);
6ea83fed
FB
7094}
7095
6af0bf9c 7096/* Coprocessor 1 (FPU) */
5a5012ec 7097
5a5012ec
TS
7098#define FOP(func, fmt) (((fmt) << 21) | (func))
7099
bf4120ad
NF
7100enum fopcode {
7101 OPC_ADD_S = FOP(0, FMT_S),
7102 OPC_SUB_S = FOP(1, FMT_S),
7103 OPC_MUL_S = FOP(2, FMT_S),
7104 OPC_DIV_S = FOP(3, FMT_S),
7105 OPC_SQRT_S = FOP(4, FMT_S),
7106 OPC_ABS_S = FOP(5, FMT_S),
7107 OPC_MOV_S = FOP(6, FMT_S),
7108 OPC_NEG_S = FOP(7, FMT_S),
7109 OPC_ROUND_L_S = FOP(8, FMT_S),
7110 OPC_TRUNC_L_S = FOP(9, FMT_S),
7111 OPC_CEIL_L_S = FOP(10, FMT_S),
7112 OPC_FLOOR_L_S = FOP(11, FMT_S),
7113 OPC_ROUND_W_S = FOP(12, FMT_S),
7114 OPC_TRUNC_W_S = FOP(13, FMT_S),
7115 OPC_CEIL_W_S = FOP(14, FMT_S),
7116 OPC_FLOOR_W_S = FOP(15, FMT_S),
7117 OPC_MOVCF_S = FOP(17, FMT_S),
7118 OPC_MOVZ_S = FOP(18, FMT_S),
7119 OPC_MOVN_S = FOP(19, FMT_S),
7120 OPC_RECIP_S = FOP(21, FMT_S),
7121 OPC_RSQRT_S = FOP(22, FMT_S),
7122 OPC_RECIP2_S = FOP(28, FMT_S),
7123 OPC_RECIP1_S = FOP(29, FMT_S),
7124 OPC_RSQRT1_S = FOP(30, FMT_S),
7125 OPC_RSQRT2_S = FOP(31, FMT_S),
7126 OPC_CVT_D_S = FOP(33, FMT_S),
7127 OPC_CVT_W_S = FOP(36, FMT_S),
7128 OPC_CVT_L_S = FOP(37, FMT_S),
7129 OPC_CVT_PS_S = FOP(38, FMT_S),
7130 OPC_CMP_F_S = FOP (48, FMT_S),
7131 OPC_CMP_UN_S = FOP (49, FMT_S),
7132 OPC_CMP_EQ_S = FOP (50, FMT_S),
7133 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7134 OPC_CMP_OLT_S = FOP (52, FMT_S),
7135 OPC_CMP_ULT_S = FOP (53, FMT_S),
7136 OPC_CMP_OLE_S = FOP (54, FMT_S),
7137 OPC_CMP_ULE_S = FOP (55, FMT_S),
7138 OPC_CMP_SF_S = FOP (56, FMT_S),
7139 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7140 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7141 OPC_CMP_NGL_S = FOP (59, FMT_S),
7142 OPC_CMP_LT_S = FOP (60, FMT_S),
7143 OPC_CMP_NGE_S = FOP (61, FMT_S),
7144 OPC_CMP_LE_S = FOP (62, FMT_S),
7145 OPC_CMP_NGT_S = FOP (63, FMT_S),
7146
7147 OPC_ADD_D = FOP(0, FMT_D),
7148 OPC_SUB_D = FOP(1, FMT_D),
7149 OPC_MUL_D = FOP(2, FMT_D),
7150 OPC_DIV_D = FOP(3, FMT_D),
7151 OPC_SQRT_D = FOP(4, FMT_D),
7152 OPC_ABS_D = FOP(5, FMT_D),
7153 OPC_MOV_D = FOP(6, FMT_D),
7154 OPC_NEG_D = FOP(7, FMT_D),
7155 OPC_ROUND_L_D = FOP(8, FMT_D),
7156 OPC_TRUNC_L_D = FOP(9, FMT_D),
7157 OPC_CEIL_L_D = FOP(10, FMT_D),
7158 OPC_FLOOR_L_D = FOP(11, FMT_D),
7159 OPC_ROUND_W_D = FOP(12, FMT_D),
7160 OPC_TRUNC_W_D = FOP(13, FMT_D),
7161 OPC_CEIL_W_D = FOP(14, FMT_D),
7162 OPC_FLOOR_W_D = FOP(15, FMT_D),
7163 OPC_MOVCF_D = FOP(17, FMT_D),
7164 OPC_MOVZ_D = FOP(18, FMT_D),
7165 OPC_MOVN_D = FOP(19, FMT_D),
7166 OPC_RECIP_D = FOP(21, FMT_D),
7167 OPC_RSQRT_D = FOP(22, FMT_D),
7168 OPC_RECIP2_D = FOP(28, FMT_D),
7169 OPC_RECIP1_D = FOP(29, FMT_D),
7170 OPC_RSQRT1_D = FOP(30, FMT_D),
7171 OPC_RSQRT2_D = FOP(31, FMT_D),
7172 OPC_CVT_S_D = FOP(32, FMT_D),
7173 OPC_CVT_W_D = FOP(36, FMT_D),
7174 OPC_CVT_L_D = FOP(37, FMT_D),
7175 OPC_CMP_F_D = FOP (48, FMT_D),
7176 OPC_CMP_UN_D = FOP (49, FMT_D),
7177 OPC_CMP_EQ_D = FOP (50, FMT_D),
7178 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7179 OPC_CMP_OLT_D = FOP (52, FMT_D),
7180 OPC_CMP_ULT_D = FOP (53, FMT_D),
7181 OPC_CMP_OLE_D = FOP (54, FMT_D),
7182 OPC_CMP_ULE_D = FOP (55, FMT_D),
7183 OPC_CMP_SF_D = FOP (56, FMT_D),
7184 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7185 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7186 OPC_CMP_NGL_D = FOP (59, FMT_D),
7187 OPC_CMP_LT_D = FOP (60, FMT_D),
7188 OPC_CMP_NGE_D = FOP (61, FMT_D),
7189 OPC_CMP_LE_D = FOP (62, FMT_D),
7190 OPC_CMP_NGT_D = FOP (63, FMT_D),
7191
7192 OPC_CVT_S_W = FOP(32, FMT_W),
7193 OPC_CVT_D_W = FOP(33, FMT_W),
7194 OPC_CVT_S_L = FOP(32, FMT_L),
7195 OPC_CVT_D_L = FOP(33, FMT_L),
7196 OPC_CVT_PS_PW = FOP(38, FMT_W),
7197
7198 OPC_ADD_PS = FOP(0, FMT_PS),
7199 OPC_SUB_PS = FOP(1, FMT_PS),
7200 OPC_MUL_PS = FOP(2, FMT_PS),
7201 OPC_DIV_PS = FOP(3, FMT_PS),
7202 OPC_ABS_PS = FOP(5, FMT_PS),
7203 OPC_MOV_PS = FOP(6, FMT_PS),
7204 OPC_NEG_PS = FOP(7, FMT_PS),
7205 OPC_MOVCF_PS = FOP(17, FMT_PS),
7206 OPC_MOVZ_PS = FOP(18, FMT_PS),
7207 OPC_MOVN_PS = FOP(19, FMT_PS),
7208 OPC_ADDR_PS = FOP(24, FMT_PS),
7209 OPC_MULR_PS = FOP(26, FMT_PS),
7210 OPC_RECIP2_PS = FOP(28, FMT_PS),
7211 OPC_RECIP1_PS = FOP(29, FMT_PS),
7212 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7213 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7214
7215 OPC_CVT_S_PU = FOP(32, FMT_PS),
7216 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7217 OPC_CVT_S_PL = FOP(40, FMT_PS),
7218 OPC_PLL_PS = FOP(44, FMT_PS),
7219 OPC_PLU_PS = FOP(45, FMT_PS),
7220 OPC_PUL_PS = FOP(46, FMT_PS),
7221 OPC_PUU_PS = FOP(47, FMT_PS),
7222 OPC_CMP_F_PS = FOP (48, FMT_PS),
7223 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7224 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7225 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7226 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7227 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7228 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7229 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7230 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7231 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7232 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7233 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7234 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7235 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7236 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7237 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7238};
7239
7a387fff 7240static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7241{
923617a3 7242 const char *opn = "cp1 move";
72c3a3ee 7243 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7244
7245 switch (opc) {
7246 case OPC_MFC1:
b6d96bed 7247 {
a7812ae4 7248 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7249
7250 gen_load_fpr32(fp0, fs);
7251 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7252 tcg_temp_free_i32(fp0);
6958549d 7253 }
6c5c1e20 7254 gen_store_gpr(t0, rt);
6ea83fed
FB
7255 opn = "mfc1";
7256 break;
7257 case OPC_MTC1:
6c5c1e20 7258 gen_load_gpr(t0, rt);
b6d96bed 7259 {
a7812ae4 7260 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7261
7262 tcg_gen_trunc_tl_i32(fp0, t0);
7263 gen_store_fpr32(fp0, fs);
a7812ae4 7264 tcg_temp_free_i32(fp0);
6958549d 7265 }
6ea83fed
FB
7266 opn = "mtc1";
7267 break;
7268 case OPC_CFC1:
895c2d04 7269 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7270 gen_store_gpr(t0, rt);
6ea83fed
FB
7271 opn = "cfc1";
7272 break;
7273 case OPC_CTC1:
6c5c1e20 7274 gen_load_gpr(t0, rt);
895c2d04 7275 gen_helper_0e1i(ctc1, t0, fs);
6ea83fed
FB
7276 opn = "ctc1";
7277 break;
72c3a3ee 7278#if defined(TARGET_MIPS64)
9c2149c8 7279 case OPC_DMFC1:
72c3a3ee 7280 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7281 gen_store_gpr(t0, rt);
5a5012ec
TS
7282 opn = "dmfc1";
7283 break;
9c2149c8 7284 case OPC_DMTC1:
6c5c1e20 7285 gen_load_gpr(t0, rt);
72c3a3ee 7286 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7287 opn = "dmtc1";
7288 break;
72c3a3ee 7289#endif
5a5012ec 7290 case OPC_MFHC1:
b6d96bed 7291 {
a7812ae4 7292 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7293
7294 gen_load_fpr32h(fp0, fs);
7295 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7296 tcg_temp_free_i32(fp0);
6958549d 7297 }
6c5c1e20 7298 gen_store_gpr(t0, rt);
5a5012ec
TS
7299 opn = "mfhc1";
7300 break;
7301 case OPC_MTHC1:
6c5c1e20 7302 gen_load_gpr(t0, rt);
b6d96bed 7303 {
a7812ae4 7304 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7305
7306 tcg_gen_trunc_tl_i32(fp0, t0);
7307 gen_store_fpr32h(fp0, fs);
a7812ae4 7308 tcg_temp_free_i32(fp0);
6958549d 7309 }
5a5012ec
TS
7310 opn = "mthc1";
7311 break;
6ea83fed 7312 default:
923617a3 7313 MIPS_INVAL(opn);
e397ee33 7314 generate_exception (ctx, EXCP_RI);
6c5c1e20 7315 goto out;
6ea83fed 7316 }
2abf314d 7317 (void)opn; /* avoid a compiler warning */
6ea83fed 7318 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7319
7320 out:
7321 tcg_temp_free(t0);
6ea83fed
FB
7322}
7323
5a5012ec
TS
7324static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7325{
af58f9ca 7326 int l1;
e214b9bb 7327 TCGCond cond;
af58f9ca
AJ
7328 TCGv_i32 t0;
7329
7330 if (rd == 0) {
7331 /* Treat as NOP. */
7332 return;
7333 }
6ea83fed 7334
e214b9bb 7335 if (tf)
e214b9bb 7336 cond = TCG_COND_EQ;
27848470
TS
7337 else
7338 cond = TCG_COND_NE;
7339
af58f9ca
AJ
7340 l1 = gen_new_label();
7341 t0 = tcg_temp_new_i32();
fa31af0e 7342 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7343 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7344 tcg_temp_free_i32(t0);
af58f9ca
AJ
7345 if (rs == 0) {
7346 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7347 } else {
7348 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7349 }
e214b9bb 7350 gen_set_label(l1);
5a5012ec
TS
7351}
7352
b6d96bed 7353static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7354{
a16336e4 7355 int cond;
cbc37b28 7356 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7357 int l1 = gen_new_label();
7358
a16336e4
TS
7359 if (tf)
7360 cond = TCG_COND_EQ;
7361 else
7362 cond = TCG_COND_NE;
7363
fa31af0e 7364 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7365 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7366 gen_load_fpr32(t0, fs);
7367 gen_store_fpr32(t0, fd);
a16336e4 7368 gen_set_label(l1);
cbc37b28 7369 tcg_temp_free_i32(t0);
5a5012ec 7370}
a16336e4 7371
b6d96bed 7372static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7373{
a16336e4 7374 int cond;
cbc37b28
AJ
7375 TCGv_i32 t0 = tcg_temp_new_i32();
7376 TCGv_i64 fp0;
a16336e4
TS
7377 int l1 = gen_new_label();
7378
a16336e4
TS
7379 if (tf)
7380 cond = TCG_COND_EQ;
7381 else
7382 cond = TCG_COND_NE;
7383
fa31af0e 7384 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7385 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7386 tcg_temp_free_i32(t0);
11f94258 7387 fp0 = tcg_temp_new_i64();
9bf3eb2c 7388 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7389 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7390 tcg_temp_free_i64(fp0);
cbc37b28 7391 gen_set_label(l1);
a16336e4
TS
7392}
7393
b6d96bed 7394static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
a16336e4
TS
7395{
7396 int cond;
cbc37b28 7397 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7398 int l1 = gen_new_label();
7399 int l2 = gen_new_label();
7400
7401 if (tf)
7402 cond = TCG_COND_EQ;
7403 else
7404 cond = TCG_COND_NE;
7405
fa31af0e 7406 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7407 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7408 gen_load_fpr32(t0, fs);
7409 gen_store_fpr32(t0, fd);
a16336e4 7410 gen_set_label(l1);
9bf3eb2c 7411
fa31af0e 7412 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28
AJ
7413 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7414 gen_load_fpr32h(t0, fs);
7415 gen_store_fpr32h(t0, fd);
52a0e9eb 7416 tcg_temp_free_i32(t0);
a16336e4 7417 gen_set_label(l2);
a16336e4
TS
7418}
7419
6ea83fed 7420
bf4120ad 7421static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7422 int ft, int fs, int fd, int cc)
6ea83fed 7423{
923617a3 7424 const char *opn = "farith";
6ea83fed
FB
7425 const char *condnames[] = {
7426 "c.f",
7427 "c.un",
7428 "c.eq",
7429 "c.ueq",
7430 "c.olt",
7431 "c.ult",
7432 "c.ole",
7433 "c.ule",
7434 "c.sf",
7435 "c.ngle",
7436 "c.seq",
7437 "c.ngl",
7438 "c.lt",
7439 "c.nge",
7440 "c.le",
7441 "c.ngt",
7442 };
5a1e8ffb
TS
7443 const char *condnames_abs[] = {
7444 "cabs.f",
7445 "cabs.un",
7446 "cabs.eq",
7447 "cabs.ueq",
7448 "cabs.olt",
7449 "cabs.ult",
7450 "cabs.ole",
7451 "cabs.ule",
7452 "cabs.sf",
7453 "cabs.ngle",
7454 "cabs.seq",
7455 "cabs.ngl",
7456 "cabs.lt",
7457 "cabs.nge",
7458 "cabs.le",
7459 "cabs.ngt",
7460 };
7461 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7462 uint32_t func = ctx->opcode & 0x3f;
7463
bf4120ad
NF
7464 switch (op1) {
7465 case OPC_ADD_S:
b6d96bed 7466 {
a7812ae4
PB
7467 TCGv_i32 fp0 = tcg_temp_new_i32();
7468 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7469
7470 gen_load_fpr32(fp0, fs);
7471 gen_load_fpr32(fp1, ft);
895c2d04 7472 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7473 tcg_temp_free_i32(fp1);
b6d96bed 7474 gen_store_fpr32(fp0, fd);
a7812ae4 7475 tcg_temp_free_i32(fp0);
b6d96bed 7476 }
5a5012ec 7477 opn = "add.s";
5a1e8ffb 7478 optype = BINOP;
5a5012ec 7479 break;
bf4120ad 7480 case OPC_SUB_S:
b6d96bed 7481 {
a7812ae4
PB
7482 TCGv_i32 fp0 = tcg_temp_new_i32();
7483 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7484
7485 gen_load_fpr32(fp0, fs);
7486 gen_load_fpr32(fp1, ft);
895c2d04 7487 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7488 tcg_temp_free_i32(fp1);
b6d96bed 7489 gen_store_fpr32(fp0, fd);
a7812ae4 7490 tcg_temp_free_i32(fp0);
b6d96bed 7491 }
5a5012ec 7492 opn = "sub.s";
5a1e8ffb 7493 optype = BINOP;
5a5012ec 7494 break;
bf4120ad 7495 case OPC_MUL_S:
b6d96bed 7496 {
a7812ae4
PB
7497 TCGv_i32 fp0 = tcg_temp_new_i32();
7498 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7499
7500 gen_load_fpr32(fp0, fs);
7501 gen_load_fpr32(fp1, ft);
895c2d04 7502 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7503 tcg_temp_free_i32(fp1);
b6d96bed 7504 gen_store_fpr32(fp0, fd);
a7812ae4 7505 tcg_temp_free_i32(fp0);
b6d96bed 7506 }
5a5012ec 7507 opn = "mul.s";
5a1e8ffb 7508 optype = BINOP;
5a5012ec 7509 break;
bf4120ad 7510 case OPC_DIV_S:
b6d96bed 7511 {
a7812ae4
PB
7512 TCGv_i32 fp0 = tcg_temp_new_i32();
7513 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7514
7515 gen_load_fpr32(fp0, fs);
7516 gen_load_fpr32(fp1, ft);
895c2d04 7517 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7518 tcg_temp_free_i32(fp1);
b6d96bed 7519 gen_store_fpr32(fp0, fd);
a7812ae4 7520 tcg_temp_free_i32(fp0);
b6d96bed 7521 }
5a5012ec 7522 opn = "div.s";
5a1e8ffb 7523 optype = BINOP;
5a5012ec 7524 break;
bf4120ad 7525 case OPC_SQRT_S:
b6d96bed 7526 {
a7812ae4 7527 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7528
7529 gen_load_fpr32(fp0, fs);
895c2d04 7530 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7531 gen_store_fpr32(fp0, fd);
a7812ae4 7532 tcg_temp_free_i32(fp0);
b6d96bed 7533 }
5a5012ec
TS
7534 opn = "sqrt.s";
7535 break;
bf4120ad 7536 case OPC_ABS_S:
b6d96bed 7537 {
a7812ae4 7538 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7539
7540 gen_load_fpr32(fp0, fs);
a7812ae4 7541 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7542 gen_store_fpr32(fp0, fd);
a7812ae4 7543 tcg_temp_free_i32(fp0);
b6d96bed 7544 }
5a5012ec
TS
7545 opn = "abs.s";
7546 break;
bf4120ad 7547 case OPC_MOV_S:
b6d96bed 7548 {
a7812ae4 7549 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7550
7551 gen_load_fpr32(fp0, fs);
7552 gen_store_fpr32(fp0, fd);
a7812ae4 7553 tcg_temp_free_i32(fp0);
b6d96bed 7554 }
5a5012ec
TS
7555 opn = "mov.s";
7556 break;
bf4120ad 7557 case OPC_NEG_S:
b6d96bed 7558 {
a7812ae4 7559 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7560
7561 gen_load_fpr32(fp0, fs);
a7812ae4 7562 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7563 gen_store_fpr32(fp0, fd);
a7812ae4 7564 tcg_temp_free_i32(fp0);
b6d96bed 7565 }
5a5012ec
TS
7566 opn = "neg.s";
7567 break;
bf4120ad 7568 case OPC_ROUND_L_S:
5e755519 7569 check_cp1_64bitmode(ctx);
b6d96bed 7570 {
a7812ae4
PB
7571 TCGv_i32 fp32 = tcg_temp_new_i32();
7572 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7573
7574 gen_load_fpr32(fp32, fs);
895c2d04 7575 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7576 tcg_temp_free_i32(fp32);
b6d96bed 7577 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7578 tcg_temp_free_i64(fp64);
b6d96bed 7579 }
5a5012ec
TS
7580 opn = "round.l.s";
7581 break;
bf4120ad 7582 case OPC_TRUNC_L_S:
5e755519 7583 check_cp1_64bitmode(ctx);
b6d96bed 7584 {
a7812ae4
PB
7585 TCGv_i32 fp32 = tcg_temp_new_i32();
7586 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7587
7588 gen_load_fpr32(fp32, fs);
895c2d04 7589 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7590 tcg_temp_free_i32(fp32);
b6d96bed 7591 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7592 tcg_temp_free_i64(fp64);
b6d96bed 7593 }
5a5012ec
TS
7594 opn = "trunc.l.s";
7595 break;
bf4120ad 7596 case OPC_CEIL_L_S:
5e755519 7597 check_cp1_64bitmode(ctx);
b6d96bed 7598 {
a7812ae4
PB
7599 TCGv_i32 fp32 = tcg_temp_new_i32();
7600 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7601
7602 gen_load_fpr32(fp32, fs);
895c2d04 7603 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7604 tcg_temp_free_i32(fp32);
b6d96bed 7605 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7606 tcg_temp_free_i64(fp64);
b6d96bed 7607 }
5a5012ec
TS
7608 opn = "ceil.l.s";
7609 break;
bf4120ad 7610 case OPC_FLOOR_L_S:
5e755519 7611 check_cp1_64bitmode(ctx);
b6d96bed 7612 {
a7812ae4
PB
7613 TCGv_i32 fp32 = tcg_temp_new_i32();
7614 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7615
7616 gen_load_fpr32(fp32, fs);
895c2d04 7617 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7618 tcg_temp_free_i32(fp32);
b6d96bed 7619 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7620 tcg_temp_free_i64(fp64);
b6d96bed 7621 }
5a5012ec
TS
7622 opn = "floor.l.s";
7623 break;
bf4120ad 7624 case OPC_ROUND_W_S:
b6d96bed 7625 {
a7812ae4 7626 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7627
7628 gen_load_fpr32(fp0, fs);
895c2d04 7629 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7630 gen_store_fpr32(fp0, fd);
a7812ae4 7631 tcg_temp_free_i32(fp0);
b6d96bed 7632 }
5a5012ec
TS
7633 opn = "round.w.s";
7634 break;
bf4120ad 7635 case OPC_TRUNC_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_truncw_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 = "trunc.w.s";
7645 break;
bf4120ad 7646 case OPC_CEIL_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_ceilw_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 = "ceil.w.s";
7656 break;
bf4120ad 7657 case OPC_FLOOR_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_floorw_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 = "floor.w.s";
7667 break;
bf4120ad 7668 case OPC_MOVCF_S:
b6d96bed 7669 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7670 opn = "movcf.s";
7671 break;
bf4120ad 7672 case OPC_MOVZ_S:
a16336e4
TS
7673 {
7674 int l1 = gen_new_label();
c9297f4d 7675 TCGv_i32 fp0;
a16336e4 7676
c9297f4d
AJ
7677 if (ft != 0) {
7678 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7679 }
7680 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7681 gen_load_fpr32(fp0, fs);
7682 gen_store_fpr32(fp0, fd);
a7812ae4 7683 tcg_temp_free_i32(fp0);
a16336e4
TS
7684 gen_set_label(l1);
7685 }
5a5012ec
TS
7686 opn = "movz.s";
7687 break;
bf4120ad 7688 case OPC_MOVN_S:
a16336e4
TS
7689 {
7690 int l1 = gen_new_label();
c9297f4d
AJ
7691 TCGv_i32 fp0;
7692
7693 if (ft != 0) {
7694 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7695 fp0 = tcg_temp_new_i32();
7696 gen_load_fpr32(fp0, fs);
7697 gen_store_fpr32(fp0, fd);
7698 tcg_temp_free_i32(fp0);
7699 gen_set_label(l1);
7700 }
a16336e4 7701 }
5a5012ec
TS
7702 opn = "movn.s";
7703 break;
bf4120ad 7704 case OPC_RECIP_S:
b8aa4598 7705 check_cop1x(ctx);
b6d96bed 7706 {
a7812ae4 7707 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7708
7709 gen_load_fpr32(fp0, fs);
895c2d04 7710 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 7711 gen_store_fpr32(fp0, fd);
a7812ae4 7712 tcg_temp_free_i32(fp0);
b6d96bed 7713 }
57fa1fb3
TS
7714 opn = "recip.s";
7715 break;
bf4120ad 7716 case OPC_RSQRT_S:
b8aa4598 7717 check_cop1x(ctx);
b6d96bed 7718 {
a7812ae4 7719 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7720
7721 gen_load_fpr32(fp0, fs);
895c2d04 7722 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7723 gen_store_fpr32(fp0, fd);
a7812ae4 7724 tcg_temp_free_i32(fp0);
b6d96bed 7725 }
57fa1fb3
TS
7726 opn = "rsqrt.s";
7727 break;
bf4120ad 7728 case OPC_RECIP2_S:
5e755519 7729 check_cp1_64bitmode(ctx);
b6d96bed 7730 {
a7812ae4
PB
7731 TCGv_i32 fp0 = tcg_temp_new_i32();
7732 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7733
7734 gen_load_fpr32(fp0, fs);
d22d7289 7735 gen_load_fpr32(fp1, ft);
895c2d04 7736 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7737 tcg_temp_free_i32(fp1);
b6d96bed 7738 gen_store_fpr32(fp0, fd);
a7812ae4 7739 tcg_temp_free_i32(fp0);
b6d96bed 7740 }
57fa1fb3
TS
7741 opn = "recip2.s";
7742 break;
bf4120ad 7743 case OPC_RECIP1_S:
5e755519 7744 check_cp1_64bitmode(ctx);
b6d96bed 7745 {
a7812ae4 7746 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7747
7748 gen_load_fpr32(fp0, fs);
895c2d04 7749 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7750 gen_store_fpr32(fp0, fd);
a7812ae4 7751 tcg_temp_free_i32(fp0);
b6d96bed 7752 }
57fa1fb3
TS
7753 opn = "recip1.s";
7754 break;
bf4120ad 7755 case OPC_RSQRT1_S:
5e755519 7756 check_cp1_64bitmode(ctx);
b6d96bed 7757 {
a7812ae4 7758 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7759
7760 gen_load_fpr32(fp0, fs);
895c2d04 7761 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7762 gen_store_fpr32(fp0, fd);
a7812ae4 7763 tcg_temp_free_i32(fp0);
b6d96bed 7764 }
57fa1fb3
TS
7765 opn = "rsqrt1.s";
7766 break;
bf4120ad 7767 case OPC_RSQRT2_S:
5e755519 7768 check_cp1_64bitmode(ctx);
b6d96bed 7769 {
a7812ae4
PB
7770 TCGv_i32 fp0 = tcg_temp_new_i32();
7771 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7772
7773 gen_load_fpr32(fp0, fs);
7774 gen_load_fpr32(fp1, ft);
895c2d04 7775 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7776 tcg_temp_free_i32(fp1);
b6d96bed 7777 gen_store_fpr32(fp0, fd);
a7812ae4 7778 tcg_temp_free_i32(fp0);
b6d96bed 7779 }
57fa1fb3
TS
7780 opn = "rsqrt2.s";
7781 break;
bf4120ad 7782 case OPC_CVT_D_S:
5e755519 7783 check_cp1_registers(ctx, fd);
b6d96bed 7784 {
a7812ae4
PB
7785 TCGv_i32 fp32 = tcg_temp_new_i32();
7786 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7787
7788 gen_load_fpr32(fp32, fs);
895c2d04 7789 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7790 tcg_temp_free_i32(fp32);
b6d96bed 7791 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7792 tcg_temp_free_i64(fp64);
b6d96bed 7793 }
5a5012ec
TS
7794 opn = "cvt.d.s";
7795 break;
bf4120ad 7796 case OPC_CVT_W_S:
b6d96bed 7797 {
a7812ae4 7798 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7799
7800 gen_load_fpr32(fp0, fs);
895c2d04 7801 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7802 gen_store_fpr32(fp0, fd);
a7812ae4 7803 tcg_temp_free_i32(fp0);
b6d96bed 7804 }
5a5012ec
TS
7805 opn = "cvt.w.s";
7806 break;
bf4120ad 7807 case OPC_CVT_L_S:
5e755519 7808 check_cp1_64bitmode(ctx);
b6d96bed 7809 {
a7812ae4
PB
7810 TCGv_i32 fp32 = tcg_temp_new_i32();
7811 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7812
7813 gen_load_fpr32(fp32, fs);
895c2d04 7814 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7815 tcg_temp_free_i32(fp32);
b6d96bed 7816 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7817 tcg_temp_free_i64(fp64);
b6d96bed 7818 }
5a5012ec
TS
7819 opn = "cvt.l.s";
7820 break;
bf4120ad 7821 case OPC_CVT_PS_S:
5e755519 7822 check_cp1_64bitmode(ctx);
b6d96bed 7823 {
a7812ae4
PB
7824 TCGv_i64 fp64 = tcg_temp_new_i64();
7825 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7826 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7827
7828 gen_load_fpr32(fp32_0, fs);
7829 gen_load_fpr32(fp32_1, ft);
13d24f49 7830 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7831 tcg_temp_free_i32(fp32_1);
7832 tcg_temp_free_i32(fp32_0);
36aa55dc 7833 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7834 tcg_temp_free_i64(fp64);
b6d96bed 7835 }
5a5012ec
TS
7836 opn = "cvt.ps.s";
7837 break;
bf4120ad
NF
7838 case OPC_CMP_F_S:
7839 case OPC_CMP_UN_S:
7840 case OPC_CMP_EQ_S:
7841 case OPC_CMP_UEQ_S:
7842 case OPC_CMP_OLT_S:
7843 case OPC_CMP_ULT_S:
7844 case OPC_CMP_OLE_S:
7845 case OPC_CMP_ULE_S:
7846 case OPC_CMP_SF_S:
7847 case OPC_CMP_NGLE_S:
7848 case OPC_CMP_SEQ_S:
7849 case OPC_CMP_NGL_S:
7850 case OPC_CMP_LT_S:
7851 case OPC_CMP_NGE_S:
7852 case OPC_CMP_LE_S:
7853 case OPC_CMP_NGT_S:
8153667c
NF
7854 if (ctx->opcode & (1 << 6)) {
7855 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7856 opn = condnames_abs[func-48];
7857 } else {
7858 gen_cmp_s(ctx, func-48, ft, fs, cc);
7859 opn = condnames[func-48];
5a1e8ffb 7860 }
5a5012ec 7861 break;
bf4120ad 7862 case OPC_ADD_D:
5e755519 7863 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7864 {
a7812ae4
PB
7865 TCGv_i64 fp0 = tcg_temp_new_i64();
7866 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7867
7868 gen_load_fpr64(ctx, fp0, fs);
7869 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7870 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7871 tcg_temp_free_i64(fp1);
b6d96bed 7872 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7873 tcg_temp_free_i64(fp0);
b6d96bed 7874 }
6ea83fed 7875 opn = "add.d";
5a1e8ffb 7876 optype = BINOP;
6ea83fed 7877 break;
bf4120ad 7878 case OPC_SUB_D:
5e755519 7879 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7880 {
a7812ae4
PB
7881 TCGv_i64 fp0 = tcg_temp_new_i64();
7882 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7883
7884 gen_load_fpr64(ctx, fp0, fs);
7885 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7886 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7887 tcg_temp_free_i64(fp1);
b6d96bed 7888 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7889 tcg_temp_free_i64(fp0);
b6d96bed 7890 }
6ea83fed 7891 opn = "sub.d";
5a1e8ffb 7892 optype = BINOP;
6ea83fed 7893 break;
bf4120ad 7894 case OPC_MUL_D:
5e755519 7895 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7896 {
a7812ae4
PB
7897 TCGv_i64 fp0 = tcg_temp_new_i64();
7898 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7899
7900 gen_load_fpr64(ctx, fp0, fs);
7901 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7902 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7903 tcg_temp_free_i64(fp1);
b6d96bed 7904 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7905 tcg_temp_free_i64(fp0);
b6d96bed 7906 }
6ea83fed 7907 opn = "mul.d";
5a1e8ffb 7908 optype = BINOP;
6ea83fed 7909 break;
bf4120ad 7910 case OPC_DIV_D:
5e755519 7911 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7912 {
a7812ae4
PB
7913 TCGv_i64 fp0 = tcg_temp_new_i64();
7914 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7915
7916 gen_load_fpr64(ctx, fp0, fs);
7917 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7918 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7919 tcg_temp_free_i64(fp1);
b6d96bed 7920 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7921 tcg_temp_free_i64(fp0);
b6d96bed 7922 }
6ea83fed 7923 opn = "div.d";
5a1e8ffb 7924 optype = BINOP;
6ea83fed 7925 break;
bf4120ad 7926 case OPC_SQRT_D:
5e755519 7927 check_cp1_registers(ctx, fs | fd);
b6d96bed 7928 {
a7812ae4 7929 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7930
7931 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7932 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7933 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7934 tcg_temp_free_i64(fp0);
b6d96bed 7935 }
6ea83fed
FB
7936 opn = "sqrt.d";
7937 break;
bf4120ad 7938 case OPC_ABS_D:
5e755519 7939 check_cp1_registers(ctx, fs | fd);
b6d96bed 7940 {
a7812ae4 7941 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7942
7943 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7944 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7945 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7946 tcg_temp_free_i64(fp0);
b6d96bed 7947 }
6ea83fed
FB
7948 opn = "abs.d";
7949 break;
bf4120ad 7950 case OPC_MOV_D:
5e755519 7951 check_cp1_registers(ctx, fs | fd);
b6d96bed 7952 {
a7812ae4 7953 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7954
7955 gen_load_fpr64(ctx, fp0, fs);
7956 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7957 tcg_temp_free_i64(fp0);
b6d96bed 7958 }
6ea83fed
FB
7959 opn = "mov.d";
7960 break;
bf4120ad 7961 case OPC_NEG_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);
a7812ae4 7967 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 7968 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7969 tcg_temp_free_i64(fp0);
b6d96bed 7970 }
6ea83fed
FB
7971 opn = "neg.d";
7972 break;
bf4120ad 7973 case OPC_ROUND_L_D:
5e755519 7974 check_cp1_64bitmode(ctx);
b6d96bed 7975 {
a7812ae4 7976 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7977
7978 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7979 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 7980 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7981 tcg_temp_free_i64(fp0);
b6d96bed 7982 }
5a5012ec
TS
7983 opn = "round.l.d";
7984 break;
bf4120ad 7985 case OPC_TRUNC_L_D:
5e755519 7986 check_cp1_64bitmode(ctx);
b6d96bed 7987 {
a7812ae4 7988 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7989
7990 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7991 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 7992 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7993 tcg_temp_free_i64(fp0);
b6d96bed 7994 }
5a5012ec
TS
7995 opn = "trunc.l.d";
7996 break;
bf4120ad 7997 case OPC_CEIL_L_D:
5e755519 7998 check_cp1_64bitmode(ctx);
b6d96bed 7999 {
a7812ae4 8000 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8001
8002 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8003 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8004 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8005 tcg_temp_free_i64(fp0);
b6d96bed 8006 }
5a5012ec
TS
8007 opn = "ceil.l.d";
8008 break;
bf4120ad 8009 case OPC_FLOOR_L_D:
5e755519 8010 check_cp1_64bitmode(ctx);
b6d96bed 8011 {
a7812ae4 8012 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8013
8014 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8015 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8016 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8017 tcg_temp_free_i64(fp0);
b6d96bed 8018 }
5a5012ec
TS
8019 opn = "floor.l.d";
8020 break;
bf4120ad 8021 case OPC_ROUND_W_D:
5e755519 8022 check_cp1_registers(ctx, fs);
b6d96bed 8023 {
a7812ae4
PB
8024 TCGv_i32 fp32 = tcg_temp_new_i32();
8025 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8026
8027 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8028 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8029 tcg_temp_free_i64(fp64);
b6d96bed 8030 gen_store_fpr32(fp32, fd);
a7812ae4 8031 tcg_temp_free_i32(fp32);
b6d96bed 8032 }
6ea83fed
FB
8033 opn = "round.w.d";
8034 break;
bf4120ad 8035 case OPC_TRUNC_W_D:
5e755519 8036 check_cp1_registers(ctx, fs);
b6d96bed 8037 {
a7812ae4
PB
8038 TCGv_i32 fp32 = tcg_temp_new_i32();
8039 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8040
8041 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8042 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8043 tcg_temp_free_i64(fp64);
b6d96bed 8044 gen_store_fpr32(fp32, fd);
a7812ae4 8045 tcg_temp_free_i32(fp32);
b6d96bed 8046 }
6ea83fed
FB
8047 opn = "trunc.w.d";
8048 break;
bf4120ad 8049 case OPC_CEIL_W_D:
5e755519 8050 check_cp1_registers(ctx, fs);
b6d96bed 8051 {
a7812ae4
PB
8052 TCGv_i32 fp32 = tcg_temp_new_i32();
8053 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8054
8055 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8056 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8057 tcg_temp_free_i64(fp64);
b6d96bed 8058 gen_store_fpr32(fp32, fd);
a7812ae4 8059 tcg_temp_free_i32(fp32);
b6d96bed 8060 }
6ea83fed
FB
8061 opn = "ceil.w.d";
8062 break;
bf4120ad 8063 case OPC_FLOOR_W_D:
5e755519 8064 check_cp1_registers(ctx, fs);
b6d96bed 8065 {
a7812ae4
PB
8066 TCGv_i32 fp32 = tcg_temp_new_i32();
8067 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8068
8069 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8070 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8071 tcg_temp_free_i64(fp64);
b6d96bed 8072 gen_store_fpr32(fp32, fd);
a7812ae4 8073 tcg_temp_free_i32(fp32);
b6d96bed 8074 }
7a387fff 8075 opn = "floor.w.d";
6ea83fed 8076 break;
bf4120ad 8077 case OPC_MOVCF_D:
b6d96bed 8078 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8079 opn = "movcf.d";
dd016883 8080 break;
bf4120ad 8081 case OPC_MOVZ_D:
a16336e4
TS
8082 {
8083 int l1 = gen_new_label();
c9297f4d 8084 TCGv_i64 fp0;
a16336e4 8085
c9297f4d
AJ
8086 if (ft != 0) {
8087 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8088 }
8089 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8090 gen_load_fpr64(ctx, fp0, fs);
8091 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8092 tcg_temp_free_i64(fp0);
a16336e4
TS
8093 gen_set_label(l1);
8094 }
5a5012ec
TS
8095 opn = "movz.d";
8096 break;
bf4120ad 8097 case OPC_MOVN_D:
a16336e4
TS
8098 {
8099 int l1 = gen_new_label();
c9297f4d
AJ
8100 TCGv_i64 fp0;
8101
8102 if (ft != 0) {
8103 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8104 fp0 = tcg_temp_new_i64();
8105 gen_load_fpr64(ctx, fp0, fs);
8106 gen_store_fpr64(ctx, fp0, fd);
8107 tcg_temp_free_i64(fp0);
8108 gen_set_label(l1);
8109 }
a16336e4 8110 }
5a5012ec 8111 opn = "movn.d";
6ea83fed 8112 break;
bf4120ad 8113 case OPC_RECIP_D:
b8aa4598 8114 check_cp1_64bitmode(ctx);
b6d96bed 8115 {
a7812ae4 8116 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8117
8118 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8119 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8120 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8121 tcg_temp_free_i64(fp0);
b6d96bed 8122 }
57fa1fb3
TS
8123 opn = "recip.d";
8124 break;
bf4120ad 8125 case OPC_RSQRT_D:
b8aa4598 8126 check_cp1_64bitmode(ctx);
b6d96bed 8127 {
a7812ae4 8128 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8129
8130 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8131 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8132 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8133 tcg_temp_free_i64(fp0);
b6d96bed 8134 }
57fa1fb3
TS
8135 opn = "rsqrt.d";
8136 break;
bf4120ad 8137 case OPC_RECIP2_D:
5e755519 8138 check_cp1_64bitmode(ctx);
b6d96bed 8139 {
a7812ae4
PB
8140 TCGv_i64 fp0 = tcg_temp_new_i64();
8141 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8142
8143 gen_load_fpr64(ctx, fp0, fs);
8144 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8145 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8146 tcg_temp_free_i64(fp1);
b6d96bed 8147 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8148 tcg_temp_free_i64(fp0);
b6d96bed 8149 }
57fa1fb3
TS
8150 opn = "recip2.d";
8151 break;
bf4120ad 8152 case OPC_RECIP1_D:
5e755519 8153 check_cp1_64bitmode(ctx);
b6d96bed 8154 {
a7812ae4 8155 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8156
8157 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8158 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8159 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8160 tcg_temp_free_i64(fp0);
b6d96bed 8161 }
57fa1fb3
TS
8162 opn = "recip1.d";
8163 break;
bf4120ad 8164 case OPC_RSQRT1_D:
5e755519 8165 check_cp1_64bitmode(ctx);
b6d96bed 8166 {
a7812ae4 8167 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8168
8169 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8170 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8171 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8172 tcg_temp_free_i64(fp0);
b6d96bed 8173 }
57fa1fb3
TS
8174 opn = "rsqrt1.d";
8175 break;
bf4120ad 8176 case OPC_RSQRT2_D:
5e755519 8177 check_cp1_64bitmode(ctx);
b6d96bed 8178 {
a7812ae4
PB
8179 TCGv_i64 fp0 = tcg_temp_new_i64();
8180 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8181
8182 gen_load_fpr64(ctx, fp0, fs);
8183 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8184 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8185 tcg_temp_free_i64(fp1);
b6d96bed 8186 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8187 tcg_temp_free_i64(fp0);
b6d96bed 8188 }
57fa1fb3
TS
8189 opn = "rsqrt2.d";
8190 break;
bf4120ad
NF
8191 case OPC_CMP_F_D:
8192 case OPC_CMP_UN_D:
8193 case OPC_CMP_EQ_D:
8194 case OPC_CMP_UEQ_D:
8195 case OPC_CMP_OLT_D:
8196 case OPC_CMP_ULT_D:
8197 case OPC_CMP_OLE_D:
8198 case OPC_CMP_ULE_D:
8199 case OPC_CMP_SF_D:
8200 case OPC_CMP_NGLE_D:
8201 case OPC_CMP_SEQ_D:
8202 case OPC_CMP_NGL_D:
8203 case OPC_CMP_LT_D:
8204 case OPC_CMP_NGE_D:
8205 case OPC_CMP_LE_D:
8206 case OPC_CMP_NGT_D:
8153667c
NF
8207 if (ctx->opcode & (1 << 6)) {
8208 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8209 opn = condnames_abs[func-48];
8210 } else {
8211 gen_cmp_d(ctx, func-48, ft, fs, cc);
8212 opn = condnames[func-48];
5a1e8ffb 8213 }
6ea83fed 8214 break;
bf4120ad 8215 case OPC_CVT_S_D:
5e755519 8216 check_cp1_registers(ctx, fs);
b6d96bed 8217 {
a7812ae4
PB
8218 TCGv_i32 fp32 = tcg_temp_new_i32();
8219 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8220
8221 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8222 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8223 tcg_temp_free_i64(fp64);
b6d96bed 8224 gen_store_fpr32(fp32, fd);
a7812ae4 8225 tcg_temp_free_i32(fp32);
b6d96bed 8226 }
5a5012ec
TS
8227 opn = "cvt.s.d";
8228 break;
bf4120ad 8229 case OPC_CVT_W_D:
5e755519 8230 check_cp1_registers(ctx, fs);
b6d96bed 8231 {
a7812ae4
PB
8232 TCGv_i32 fp32 = tcg_temp_new_i32();
8233 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8234
8235 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8236 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8237 tcg_temp_free_i64(fp64);
b6d96bed 8238 gen_store_fpr32(fp32, fd);
a7812ae4 8239 tcg_temp_free_i32(fp32);
b6d96bed 8240 }
5a5012ec
TS
8241 opn = "cvt.w.d";
8242 break;
bf4120ad 8243 case OPC_CVT_L_D:
5e755519 8244 check_cp1_64bitmode(ctx);
b6d96bed 8245 {
a7812ae4 8246 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8247
8248 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8249 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8250 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8251 tcg_temp_free_i64(fp0);
b6d96bed 8252 }
5a5012ec
TS
8253 opn = "cvt.l.d";
8254 break;
bf4120ad 8255 case OPC_CVT_S_W:
b6d96bed 8256 {
a7812ae4 8257 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8258
8259 gen_load_fpr32(fp0, fs);
895c2d04 8260 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8261 gen_store_fpr32(fp0, fd);
a7812ae4 8262 tcg_temp_free_i32(fp0);
b6d96bed 8263 }
5a5012ec 8264 opn = "cvt.s.w";
6ea83fed 8265 break;
bf4120ad 8266 case OPC_CVT_D_W:
5e755519 8267 check_cp1_registers(ctx, fd);
b6d96bed 8268 {
a7812ae4
PB
8269 TCGv_i32 fp32 = tcg_temp_new_i32();
8270 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8271
8272 gen_load_fpr32(fp32, fs);
895c2d04 8273 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8274 tcg_temp_free_i32(fp32);
b6d96bed 8275 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8276 tcg_temp_free_i64(fp64);
b6d96bed 8277 }
5a5012ec
TS
8278 opn = "cvt.d.w";
8279 break;
bf4120ad 8280 case OPC_CVT_S_L:
5e755519 8281 check_cp1_64bitmode(ctx);
b6d96bed 8282 {
a7812ae4
PB
8283 TCGv_i32 fp32 = tcg_temp_new_i32();
8284 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8285
8286 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8287 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8288 tcg_temp_free_i64(fp64);
b6d96bed 8289 gen_store_fpr32(fp32, fd);
a7812ae4 8290 tcg_temp_free_i32(fp32);
b6d96bed 8291 }
5a5012ec
TS
8292 opn = "cvt.s.l";
8293 break;
bf4120ad 8294 case OPC_CVT_D_L:
5e755519 8295 check_cp1_64bitmode(ctx);
b6d96bed 8296 {
a7812ae4 8297 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8298
8299 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8300 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8301 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8302 tcg_temp_free_i64(fp0);
b6d96bed 8303 }
5a5012ec
TS
8304 opn = "cvt.d.l";
8305 break;
bf4120ad 8306 case OPC_CVT_PS_PW:
5e755519 8307 check_cp1_64bitmode(ctx);
b6d96bed 8308 {
a7812ae4 8309 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8310
8311 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8312 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8313 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8314 tcg_temp_free_i64(fp0);
b6d96bed 8315 }
5a5012ec
TS
8316 opn = "cvt.ps.pw";
8317 break;
bf4120ad 8318 case OPC_ADD_PS:
5e755519 8319 check_cp1_64bitmode(ctx);
b6d96bed 8320 {
a7812ae4
PB
8321 TCGv_i64 fp0 = tcg_temp_new_i64();
8322 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8323
8324 gen_load_fpr64(ctx, fp0, fs);
8325 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8326 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8327 tcg_temp_free_i64(fp1);
b6d96bed 8328 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8329 tcg_temp_free_i64(fp0);
b6d96bed 8330 }
5a5012ec 8331 opn = "add.ps";
6ea83fed 8332 break;
bf4120ad 8333 case OPC_SUB_PS:
5e755519 8334 check_cp1_64bitmode(ctx);
b6d96bed 8335 {
a7812ae4
PB
8336 TCGv_i64 fp0 = tcg_temp_new_i64();
8337 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8338
8339 gen_load_fpr64(ctx, fp0, fs);
8340 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8341 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8342 tcg_temp_free_i64(fp1);
b6d96bed 8343 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8344 tcg_temp_free_i64(fp0);
b6d96bed 8345 }
5a5012ec 8346 opn = "sub.ps";
6ea83fed 8347 break;
bf4120ad 8348 case OPC_MUL_PS:
5e755519 8349 check_cp1_64bitmode(ctx);
b6d96bed 8350 {
a7812ae4
PB
8351 TCGv_i64 fp0 = tcg_temp_new_i64();
8352 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8353
8354 gen_load_fpr64(ctx, fp0, fs);
8355 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8356 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8357 tcg_temp_free_i64(fp1);
b6d96bed 8358 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8359 tcg_temp_free_i64(fp0);
b6d96bed 8360 }
5a5012ec 8361 opn = "mul.ps";
6ea83fed 8362 break;
bf4120ad 8363 case OPC_ABS_PS:
5e755519 8364 check_cp1_64bitmode(ctx);
b6d96bed 8365 {
a7812ae4 8366 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8367
8368 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8369 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8370 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8371 tcg_temp_free_i64(fp0);
b6d96bed 8372 }
5a5012ec 8373 opn = "abs.ps";
6ea83fed 8374 break;
bf4120ad 8375 case OPC_MOV_PS:
5e755519 8376 check_cp1_64bitmode(ctx);
b6d96bed 8377 {
a7812ae4 8378 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8379
8380 gen_load_fpr64(ctx, fp0, fs);
8381 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8382 tcg_temp_free_i64(fp0);
b6d96bed 8383 }
5a5012ec 8384 opn = "mov.ps";
6ea83fed 8385 break;
bf4120ad 8386 case OPC_NEG_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);
a7812ae4 8392 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8393 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8394 tcg_temp_free_i64(fp0);
b6d96bed 8395 }
5a5012ec 8396 opn = "neg.ps";
6ea83fed 8397 break;
bf4120ad 8398 case OPC_MOVCF_PS:
5e755519 8399 check_cp1_64bitmode(ctx);
b6d96bed 8400 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8401 opn = "movcf.ps";
6ea83fed 8402 break;
bf4120ad 8403 case OPC_MOVZ_PS:
5e755519 8404 check_cp1_64bitmode(ctx);
a16336e4
TS
8405 {
8406 int l1 = gen_new_label();
30a3848b 8407 TCGv_i64 fp0;
a16336e4 8408
c9297f4d
AJ
8409 if (ft != 0)
8410 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8411 fp0 = tcg_temp_new_i64();
8412 gen_load_fpr64(ctx, fp0, fs);
8413 gen_store_fpr64(ctx, fp0, fd);
8414 tcg_temp_free_i64(fp0);
a16336e4
TS
8415 gen_set_label(l1);
8416 }
5a5012ec 8417 opn = "movz.ps";
6ea83fed 8418 break;
bf4120ad 8419 case OPC_MOVN_PS:
5e755519 8420 check_cp1_64bitmode(ctx);
a16336e4
TS
8421 {
8422 int l1 = gen_new_label();
30a3848b 8423 TCGv_i64 fp0;
c9297f4d
AJ
8424
8425 if (ft != 0) {
8426 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8427 fp0 = tcg_temp_new_i64();
8428 gen_load_fpr64(ctx, fp0, fs);
8429 gen_store_fpr64(ctx, fp0, fd);
8430 tcg_temp_free_i64(fp0);
8431 gen_set_label(l1);
8432 }
a16336e4 8433 }
5a5012ec 8434 opn = "movn.ps";
6ea83fed 8435 break;
bf4120ad 8436 case OPC_ADDR_PS:
5e755519 8437 check_cp1_64bitmode(ctx);
b6d96bed 8438 {
a7812ae4
PB
8439 TCGv_i64 fp0 = tcg_temp_new_i64();
8440 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8441
8442 gen_load_fpr64(ctx, fp0, ft);
8443 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8444 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8445 tcg_temp_free_i64(fp1);
b6d96bed 8446 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8447 tcg_temp_free_i64(fp0);
b6d96bed 8448 }
fbcc6828
TS
8449 opn = "addr.ps";
8450 break;
bf4120ad 8451 case OPC_MULR_PS:
5e755519 8452 check_cp1_64bitmode(ctx);
b6d96bed 8453 {
a7812ae4
PB
8454 TCGv_i64 fp0 = tcg_temp_new_i64();
8455 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8456
8457 gen_load_fpr64(ctx, fp0, ft);
8458 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8459 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8460 tcg_temp_free_i64(fp1);
b6d96bed 8461 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8462 tcg_temp_free_i64(fp0);
b6d96bed 8463 }
57fa1fb3
TS
8464 opn = "mulr.ps";
8465 break;
bf4120ad 8466 case OPC_RECIP2_PS:
5e755519 8467 check_cp1_64bitmode(ctx);
b6d96bed 8468 {
a7812ae4
PB
8469 TCGv_i64 fp0 = tcg_temp_new_i64();
8470 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8471
8472 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8473 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8474 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8475 tcg_temp_free_i64(fp1);
b6d96bed 8476 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8477 tcg_temp_free_i64(fp0);
b6d96bed 8478 }
57fa1fb3
TS
8479 opn = "recip2.ps";
8480 break;
bf4120ad 8481 case OPC_RECIP1_PS:
5e755519 8482 check_cp1_64bitmode(ctx);
b6d96bed 8483 {
a7812ae4 8484 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8485
8486 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8487 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8488 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8489 tcg_temp_free_i64(fp0);
b6d96bed 8490 }
57fa1fb3
TS
8491 opn = "recip1.ps";
8492 break;
bf4120ad 8493 case OPC_RSQRT1_PS:
5e755519 8494 check_cp1_64bitmode(ctx);
b6d96bed 8495 {
a7812ae4 8496 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8497
8498 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8499 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8500 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8501 tcg_temp_free_i64(fp0);
b6d96bed 8502 }
57fa1fb3
TS
8503 opn = "rsqrt1.ps";
8504 break;
bf4120ad 8505 case OPC_RSQRT2_PS:
5e755519 8506 check_cp1_64bitmode(ctx);
b6d96bed 8507 {
a7812ae4
PB
8508 TCGv_i64 fp0 = tcg_temp_new_i64();
8509 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8510
8511 gen_load_fpr64(ctx, fp0, fs);
8512 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8513 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8514 tcg_temp_free_i64(fp1);
b6d96bed 8515 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8516 tcg_temp_free_i64(fp0);
b6d96bed 8517 }
57fa1fb3
TS
8518 opn = "rsqrt2.ps";
8519 break;
bf4120ad 8520 case OPC_CVT_S_PU:
5e755519 8521 check_cp1_64bitmode(ctx);
b6d96bed 8522 {
a7812ae4 8523 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8524
8525 gen_load_fpr32h(fp0, fs);
895c2d04 8526 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8527 gen_store_fpr32(fp0, fd);
a7812ae4 8528 tcg_temp_free_i32(fp0);
b6d96bed 8529 }
5a5012ec 8530 opn = "cvt.s.pu";
dd016883 8531 break;
bf4120ad 8532 case OPC_CVT_PW_PS:
5e755519 8533 check_cp1_64bitmode(ctx);
b6d96bed 8534 {
a7812ae4 8535 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8536
8537 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8538 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8539 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8540 tcg_temp_free_i64(fp0);
b6d96bed 8541 }
5a5012ec 8542 opn = "cvt.pw.ps";
6ea83fed 8543 break;
bf4120ad 8544 case OPC_CVT_S_PL:
5e755519 8545 check_cp1_64bitmode(ctx);
b6d96bed 8546 {
a7812ae4 8547 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8548
8549 gen_load_fpr32(fp0, fs);
895c2d04 8550 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8551 gen_store_fpr32(fp0, fd);
a7812ae4 8552 tcg_temp_free_i32(fp0);
b6d96bed 8553 }
5a5012ec 8554 opn = "cvt.s.pl";
6ea83fed 8555 break;
bf4120ad 8556 case OPC_PLL_PS:
5e755519 8557 check_cp1_64bitmode(ctx);
b6d96bed 8558 {
a7812ae4
PB
8559 TCGv_i32 fp0 = tcg_temp_new_i32();
8560 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8561
8562 gen_load_fpr32(fp0, fs);
8563 gen_load_fpr32(fp1, ft);
8564 gen_store_fpr32h(fp0, fd);
8565 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8566 tcg_temp_free_i32(fp0);
8567 tcg_temp_free_i32(fp1);
b6d96bed 8568 }
5a5012ec 8569 opn = "pll.ps";
6ea83fed 8570 break;
bf4120ad 8571 case OPC_PLU_PS:
5e755519 8572 check_cp1_64bitmode(ctx);
b6d96bed 8573 {
a7812ae4
PB
8574 TCGv_i32 fp0 = tcg_temp_new_i32();
8575 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8576
8577 gen_load_fpr32(fp0, fs);
8578 gen_load_fpr32h(fp1, ft);
8579 gen_store_fpr32(fp1, fd);
8580 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8581 tcg_temp_free_i32(fp0);
8582 tcg_temp_free_i32(fp1);
b6d96bed 8583 }
5a5012ec
TS
8584 opn = "plu.ps";
8585 break;
bf4120ad 8586 case OPC_PUL_PS:
5e755519 8587 check_cp1_64bitmode(ctx);
b6d96bed 8588 {
a7812ae4
PB
8589 TCGv_i32 fp0 = tcg_temp_new_i32();
8590 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8591
8592 gen_load_fpr32h(fp0, fs);
8593 gen_load_fpr32(fp1, ft);
8594 gen_store_fpr32(fp1, fd);
8595 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8596 tcg_temp_free_i32(fp0);
8597 tcg_temp_free_i32(fp1);
b6d96bed 8598 }
5a5012ec
TS
8599 opn = "pul.ps";
8600 break;
bf4120ad 8601 case OPC_PUU_PS:
5e755519 8602 check_cp1_64bitmode(ctx);
b6d96bed 8603 {
a7812ae4
PB
8604 TCGv_i32 fp0 = tcg_temp_new_i32();
8605 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8606
8607 gen_load_fpr32h(fp0, fs);
8608 gen_load_fpr32h(fp1, ft);
8609 gen_store_fpr32(fp1, fd);
8610 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8611 tcg_temp_free_i32(fp0);
8612 tcg_temp_free_i32(fp1);
b6d96bed 8613 }
5a5012ec
TS
8614 opn = "puu.ps";
8615 break;
bf4120ad
NF
8616 case OPC_CMP_F_PS:
8617 case OPC_CMP_UN_PS:
8618 case OPC_CMP_EQ_PS:
8619 case OPC_CMP_UEQ_PS:
8620 case OPC_CMP_OLT_PS:
8621 case OPC_CMP_ULT_PS:
8622 case OPC_CMP_OLE_PS:
8623 case OPC_CMP_ULE_PS:
8624 case OPC_CMP_SF_PS:
8625 case OPC_CMP_NGLE_PS:
8626 case OPC_CMP_SEQ_PS:
8627 case OPC_CMP_NGL_PS:
8628 case OPC_CMP_LT_PS:
8629 case OPC_CMP_NGE_PS:
8630 case OPC_CMP_LE_PS:
8631 case OPC_CMP_NGT_PS:
8153667c
NF
8632 if (ctx->opcode & (1 << 6)) {
8633 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8634 opn = condnames_abs[func-48];
8635 } else {
8636 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8637 opn = condnames[func-48];
5a1e8ffb 8638 }
6ea83fed 8639 break;
5a5012ec 8640 default:
923617a3 8641 MIPS_INVAL(opn);
e397ee33 8642 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8643 return;
8644 }
2abf314d 8645 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8646 switch (optype) {
8647 case BINOP:
6ea83fed 8648 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8649 break;
8650 case CMPOP:
8651 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8652 break;
8653 default:
6ea83fed 8654 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8655 break;
8656 }
6ea83fed 8657}
6af0bf9c 8658
5a5012ec 8659/* Coprocessor 3 (FPU) */
5e755519
TS
8660static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8661 int fd, int fs, int base, int index)
7a387fff 8662{
923617a3 8663 const char *opn = "extended float load/store";
93b12ccc 8664 int store = 0;
4e2474d6 8665 TCGv t0 = tcg_temp_new();
7a387fff 8666
93b12ccc 8667 if (base == 0) {
6c5c1e20 8668 gen_load_gpr(t0, index);
93b12ccc 8669 } else if (index == 0) {
6c5c1e20 8670 gen_load_gpr(t0, base);
93b12ccc 8671 } else {
05168674 8672 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8673 }
5a5012ec 8674 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8675 memory access. */
5a5012ec
TS
8676 switch (opc) {
8677 case OPC_LWXC1:
8c0ab41f 8678 check_cop1x(ctx);
b6d96bed 8679 {
a7812ae4 8680 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8681
585c88d5
AJ
8682 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8683 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8684 gen_store_fpr32(fp0, fd);
a7812ae4 8685 tcg_temp_free_i32(fp0);
b6d96bed 8686 }
5a5012ec
TS
8687 opn = "lwxc1";
8688 break;
8689 case OPC_LDXC1:
8c0ab41f
AJ
8690 check_cop1x(ctx);
8691 check_cp1_registers(ctx, fd);
b6d96bed 8692 {
a7812ae4 8693 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8694
8695 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8696 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8697 tcg_temp_free_i64(fp0);
b6d96bed 8698 }
5a5012ec
TS
8699 opn = "ldxc1";
8700 break;
8701 case OPC_LUXC1:
8c0ab41f 8702 check_cp1_64bitmode(ctx);
6c5c1e20 8703 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8704 {
a7812ae4 8705 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8706
8707 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8708 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8709 tcg_temp_free_i64(fp0);
b6d96bed 8710 }
5a5012ec
TS
8711 opn = "luxc1";
8712 break;
8713 case OPC_SWXC1:
8c0ab41f 8714 check_cop1x(ctx);
b6d96bed 8715 {
a7812ae4 8716 TCGv_i32 fp0 = tcg_temp_new_i32();
585c88d5 8717 TCGv t1 = tcg_temp_new();
b6d96bed
TS
8718
8719 gen_load_fpr32(fp0, fs);
a7812ae4
PB
8720 tcg_gen_extu_i32_tl(t1, fp0);
8721 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8722 tcg_temp_free_i32(fp0);
a6035857 8723 tcg_temp_free(t1);
b6d96bed 8724 }
5a5012ec 8725 opn = "swxc1";
93b12ccc 8726 store = 1;
5a5012ec
TS
8727 break;
8728 case OPC_SDXC1:
8c0ab41f
AJ
8729 check_cop1x(ctx);
8730 check_cp1_registers(ctx, fs);
b6d96bed 8731 {
a7812ae4 8732 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8733
8734 gen_load_fpr64(ctx, fp0, fs);
8735 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8736 tcg_temp_free_i64(fp0);
b6d96bed 8737 }
5a5012ec 8738 opn = "sdxc1";
93b12ccc 8739 store = 1;
5a5012ec
TS
8740 break;
8741 case OPC_SUXC1:
8c0ab41f 8742 check_cp1_64bitmode(ctx);
6c5c1e20 8743 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8744 {
a7812ae4 8745 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8746
8747 gen_load_fpr64(ctx, fp0, fs);
8748 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8749 tcg_temp_free_i64(fp0);
b6d96bed 8750 }
5a5012ec 8751 opn = "suxc1";
93b12ccc 8752 store = 1;
5a5012ec 8753 break;
5a5012ec 8754 }
6c5c1e20 8755 tcg_temp_free(t0);
2abf314d 8756 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8757 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8758 regnames[index], regnames[base]);
5a5012ec
TS
8759}
8760
5e755519
TS
8761static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8762 int fd, int fr, int fs, int ft)
5a5012ec 8763{
923617a3 8764 const char *opn = "flt3_arith";
5a5012ec 8765
5a5012ec
TS
8766 switch (opc) {
8767 case OPC_ALNV_PS:
b8aa4598 8768 check_cp1_64bitmode(ctx);
a16336e4 8769 {
a7812ae4 8770 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8771 TCGv_i32 fp = tcg_temp_new_i32();
8772 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8773 int l1 = gen_new_label();
8774 int l2 = gen_new_label();
8775
6c5c1e20
TS
8776 gen_load_gpr(t0, fr);
8777 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8778
8779 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac
AJ
8780 gen_load_fpr32(fp, fs);
8781 gen_load_fpr32h(fph, fs);
8782 gen_store_fpr32(fp, fd);
8783 gen_store_fpr32h(fph, fd);
a16336e4
TS
8784 tcg_gen_br(l2);
8785 gen_set_label(l1);
6c5c1e20
TS
8786 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8787 tcg_temp_free(t0);
a16336e4 8788#ifdef TARGET_WORDS_BIGENDIAN
c905fdac
AJ
8789 gen_load_fpr32(fp, fs);
8790 gen_load_fpr32h(fph, ft);
8791 gen_store_fpr32h(fp, fd);
8792 gen_store_fpr32(fph, fd);
a16336e4 8793#else
c905fdac
AJ
8794 gen_load_fpr32h(fph, fs);
8795 gen_load_fpr32(fp, ft);
8796 gen_store_fpr32(fph, fd);
8797 gen_store_fpr32h(fp, fd);
a16336e4
TS
8798#endif
8799 gen_set_label(l2);
c905fdac
AJ
8800 tcg_temp_free_i32(fp);
8801 tcg_temp_free_i32(fph);
a16336e4 8802 }
5a5012ec
TS
8803 opn = "alnv.ps";
8804 break;
8805 case OPC_MADD_S:
b8aa4598 8806 check_cop1x(ctx);
b6d96bed 8807 {
a7812ae4
PB
8808 TCGv_i32 fp0 = tcg_temp_new_i32();
8809 TCGv_i32 fp1 = tcg_temp_new_i32();
8810 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8811
8812 gen_load_fpr32(fp0, fs);
8813 gen_load_fpr32(fp1, ft);
8814 gen_load_fpr32(fp2, fr);
b3d6cd44 8815 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8816 tcg_temp_free_i32(fp0);
8817 tcg_temp_free_i32(fp1);
b6d96bed 8818 gen_store_fpr32(fp2, fd);
a7812ae4 8819 tcg_temp_free_i32(fp2);
b6d96bed 8820 }
5a5012ec
TS
8821 opn = "madd.s";
8822 break;
8823 case OPC_MADD_D:
b8aa4598
TS
8824 check_cop1x(ctx);
8825 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8826 {
a7812ae4
PB
8827 TCGv_i64 fp0 = tcg_temp_new_i64();
8828 TCGv_i64 fp1 = tcg_temp_new_i64();
8829 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8830
8831 gen_load_fpr64(ctx, fp0, fs);
8832 gen_load_fpr64(ctx, fp1, ft);
8833 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8834 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8835 tcg_temp_free_i64(fp0);
8836 tcg_temp_free_i64(fp1);
b6d96bed 8837 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8838 tcg_temp_free_i64(fp2);
b6d96bed 8839 }
5a5012ec
TS
8840 opn = "madd.d";
8841 break;
8842 case OPC_MADD_PS:
b8aa4598 8843 check_cp1_64bitmode(ctx);
b6d96bed 8844 {
a7812ae4
PB
8845 TCGv_i64 fp0 = tcg_temp_new_i64();
8846 TCGv_i64 fp1 = tcg_temp_new_i64();
8847 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8848
8849 gen_load_fpr64(ctx, fp0, fs);
8850 gen_load_fpr64(ctx, fp1, ft);
8851 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8852 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8853 tcg_temp_free_i64(fp0);
8854 tcg_temp_free_i64(fp1);
b6d96bed 8855 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8856 tcg_temp_free_i64(fp2);
b6d96bed 8857 }
5a5012ec
TS
8858 opn = "madd.ps";
8859 break;
8860 case OPC_MSUB_S:
b8aa4598 8861 check_cop1x(ctx);
b6d96bed 8862 {
a7812ae4
PB
8863 TCGv_i32 fp0 = tcg_temp_new_i32();
8864 TCGv_i32 fp1 = tcg_temp_new_i32();
8865 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8866
8867 gen_load_fpr32(fp0, fs);
8868 gen_load_fpr32(fp1, ft);
8869 gen_load_fpr32(fp2, fr);
b3d6cd44 8870 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8871 tcg_temp_free_i32(fp0);
8872 tcg_temp_free_i32(fp1);
b6d96bed 8873 gen_store_fpr32(fp2, fd);
a7812ae4 8874 tcg_temp_free_i32(fp2);
b6d96bed 8875 }
5a5012ec
TS
8876 opn = "msub.s";
8877 break;
8878 case OPC_MSUB_D:
b8aa4598
TS
8879 check_cop1x(ctx);
8880 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8881 {
a7812ae4
PB
8882 TCGv_i64 fp0 = tcg_temp_new_i64();
8883 TCGv_i64 fp1 = tcg_temp_new_i64();
8884 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8885
8886 gen_load_fpr64(ctx, fp0, fs);
8887 gen_load_fpr64(ctx, fp1, ft);
8888 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8889 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8890 tcg_temp_free_i64(fp0);
8891 tcg_temp_free_i64(fp1);
b6d96bed 8892 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8893 tcg_temp_free_i64(fp2);
b6d96bed 8894 }
5a5012ec
TS
8895 opn = "msub.d";
8896 break;
8897 case OPC_MSUB_PS:
b8aa4598 8898 check_cp1_64bitmode(ctx);
b6d96bed 8899 {
a7812ae4
PB
8900 TCGv_i64 fp0 = tcg_temp_new_i64();
8901 TCGv_i64 fp1 = tcg_temp_new_i64();
8902 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8903
8904 gen_load_fpr64(ctx, fp0, fs);
8905 gen_load_fpr64(ctx, fp1, ft);
8906 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8907 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8908 tcg_temp_free_i64(fp0);
8909 tcg_temp_free_i64(fp1);
b6d96bed 8910 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8911 tcg_temp_free_i64(fp2);
b6d96bed 8912 }
5a5012ec
TS
8913 opn = "msub.ps";
8914 break;
8915 case OPC_NMADD_S:
b8aa4598 8916 check_cop1x(ctx);
b6d96bed 8917 {
a7812ae4
PB
8918 TCGv_i32 fp0 = tcg_temp_new_i32();
8919 TCGv_i32 fp1 = tcg_temp_new_i32();
8920 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8921
8922 gen_load_fpr32(fp0, fs);
8923 gen_load_fpr32(fp1, ft);
8924 gen_load_fpr32(fp2, fr);
b3d6cd44 8925 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8926 tcg_temp_free_i32(fp0);
8927 tcg_temp_free_i32(fp1);
b6d96bed 8928 gen_store_fpr32(fp2, fd);
a7812ae4 8929 tcg_temp_free_i32(fp2);
b6d96bed 8930 }
5a5012ec
TS
8931 opn = "nmadd.s";
8932 break;
8933 case OPC_NMADD_D:
b8aa4598
TS
8934 check_cop1x(ctx);
8935 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8936 {
a7812ae4
PB
8937 TCGv_i64 fp0 = tcg_temp_new_i64();
8938 TCGv_i64 fp1 = tcg_temp_new_i64();
8939 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8940
8941 gen_load_fpr64(ctx, fp0, fs);
8942 gen_load_fpr64(ctx, fp1, ft);
8943 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8944 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8945 tcg_temp_free_i64(fp0);
8946 tcg_temp_free_i64(fp1);
b6d96bed 8947 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8948 tcg_temp_free_i64(fp2);
b6d96bed 8949 }
5a5012ec
TS
8950 opn = "nmadd.d";
8951 break;
8952 case OPC_NMADD_PS:
b8aa4598 8953 check_cp1_64bitmode(ctx);
b6d96bed 8954 {
a7812ae4
PB
8955 TCGv_i64 fp0 = tcg_temp_new_i64();
8956 TCGv_i64 fp1 = tcg_temp_new_i64();
8957 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8958
8959 gen_load_fpr64(ctx, fp0, fs);
8960 gen_load_fpr64(ctx, fp1, ft);
8961 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8962 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8963 tcg_temp_free_i64(fp0);
8964 tcg_temp_free_i64(fp1);
b6d96bed 8965 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8966 tcg_temp_free_i64(fp2);
b6d96bed 8967 }
5a5012ec
TS
8968 opn = "nmadd.ps";
8969 break;
8970 case OPC_NMSUB_S:
b8aa4598 8971 check_cop1x(ctx);
b6d96bed 8972 {
a7812ae4
PB
8973 TCGv_i32 fp0 = tcg_temp_new_i32();
8974 TCGv_i32 fp1 = tcg_temp_new_i32();
8975 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8976
8977 gen_load_fpr32(fp0, fs);
8978 gen_load_fpr32(fp1, ft);
8979 gen_load_fpr32(fp2, fr);
b3d6cd44 8980 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8981 tcg_temp_free_i32(fp0);
8982 tcg_temp_free_i32(fp1);
b6d96bed 8983 gen_store_fpr32(fp2, fd);
a7812ae4 8984 tcg_temp_free_i32(fp2);
b6d96bed 8985 }
5a5012ec
TS
8986 opn = "nmsub.s";
8987 break;
8988 case OPC_NMSUB_D:
b8aa4598
TS
8989 check_cop1x(ctx);
8990 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8991 {
a7812ae4
PB
8992 TCGv_i64 fp0 = tcg_temp_new_i64();
8993 TCGv_i64 fp1 = tcg_temp_new_i64();
8994 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8995
8996 gen_load_fpr64(ctx, fp0, fs);
8997 gen_load_fpr64(ctx, fp1, ft);
8998 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8999 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9000 tcg_temp_free_i64(fp0);
9001 tcg_temp_free_i64(fp1);
b6d96bed 9002 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9003 tcg_temp_free_i64(fp2);
b6d96bed 9004 }
5a5012ec
TS
9005 opn = "nmsub.d";
9006 break;
9007 case OPC_NMSUB_PS:
b8aa4598 9008 check_cp1_64bitmode(ctx);
b6d96bed 9009 {
a7812ae4
PB
9010 TCGv_i64 fp0 = tcg_temp_new_i64();
9011 TCGv_i64 fp1 = tcg_temp_new_i64();
9012 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9013
9014 gen_load_fpr64(ctx, fp0, fs);
9015 gen_load_fpr64(ctx, fp1, ft);
9016 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9017 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9018 tcg_temp_free_i64(fp0);
9019 tcg_temp_free_i64(fp1);
b6d96bed 9020 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9021 tcg_temp_free_i64(fp2);
b6d96bed 9022 }
5a5012ec
TS
9023 opn = "nmsub.ps";
9024 break;
923617a3
TS
9025 default:
9026 MIPS_INVAL(opn);
5a5012ec
TS
9027 generate_exception (ctx, EXCP_RI);
9028 return;
9029 }
2abf314d 9030 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9031 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9032 fregnames[fs], fregnames[ft]);
7a387fff
TS
9033}
9034
26ebe468 9035static void
7db13fae 9036gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
26ebe468
NF
9037{
9038 TCGv t0;
9039
b3167288
RH
9040#if !defined(CONFIG_USER_ONLY)
9041 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9042 Therefore only check the ISA in system mode. */
26ebe468 9043 check_insn(env, ctx, ISA_MIPS32R2);
b3167288 9044#endif
26ebe468
NF
9045 t0 = tcg_temp_new();
9046
9047 switch (rd) {
9048 case 0:
9049 save_cpu_state(ctx, 1);
895c2d04 9050 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9051 gen_store_gpr(t0, rt);
9052 break;
9053 case 1:
9054 save_cpu_state(ctx, 1);
895c2d04 9055 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9056 gen_store_gpr(t0, rt);
9057 break;
9058 case 2:
9059 save_cpu_state(ctx, 1);
895c2d04 9060 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9061 gen_store_gpr(t0, rt);
9062 break;
9063 case 3:
9064 save_cpu_state(ctx, 1);
895c2d04 9065 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9066 gen_store_gpr(t0, rt);
9067 break;
9068 case 29:
9069#if defined(CONFIG_USER_ONLY)
7db13fae 9070 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
26ebe468
NF
9071 gen_store_gpr(t0, rt);
9072 break;
9073#else
9074 /* XXX: Some CPUs implement this in hardware.
9075 Not supported yet. */
9076#endif
9077 default: /* Invalid */
9078 MIPS_INVAL("rdhwr");
9079 generate_exception(ctx, EXCP_RI);
9080 break;
9081 }
9082 tcg_temp_free(t0);
9083}
9084
7db13fae 9085static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
c9602061
NF
9086 int insn_bytes)
9087{
9088 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9089 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9090 /* Branches completion */
9091 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9092 ctx->bstate = BS_BRANCH;
9093 save_cpu_state(ctx, 0);
9094 /* FIXME: Need to clear can_do_io. */
364d4831 9095 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9096 case MIPS_HFLAG_B:
9097 /* unconditional branch */
9098 MIPS_DEBUG("unconditional branch");
364d4831
NF
9099 if (proc_hflags & MIPS_HFLAG_BX) {
9100 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9101 }
c9602061
NF
9102 gen_goto_tb(ctx, 0, ctx->btarget);
9103 break;
9104 case MIPS_HFLAG_BL:
9105 /* blikely taken case */
9106 MIPS_DEBUG("blikely branch taken");
9107 gen_goto_tb(ctx, 0, ctx->btarget);
9108 break;
9109 case MIPS_HFLAG_BC:
9110 /* Conditional branch */
9111 MIPS_DEBUG("conditional branch");
9112 {
9113 int l1 = gen_new_label();
9114
9115 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9116 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9117 gen_set_label(l1);
9118 gen_goto_tb(ctx, 0, ctx->btarget);
9119 }
9120 break;
9121 case MIPS_HFLAG_BR:
9122 /* unconditional branch to register */
9123 MIPS_DEBUG("branch to register");
3c824109 9124 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9125 TCGv t0 = tcg_temp_new();
9126 TCGv_i32 t1 = tcg_temp_new_i32();
9127
9128 tcg_gen_andi_tl(t0, btarget, 0x1);
9129 tcg_gen_trunc_tl_i32(t1, t0);
9130 tcg_temp_free(t0);
9131 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9132 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9133 tcg_gen_or_i32(hflags, hflags, t1);
9134 tcg_temp_free_i32(t1);
9135
9136 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9137 } else {
9138 tcg_gen_mov_tl(cpu_PC, btarget);
9139 }
c9602061
NF
9140 if (ctx->singlestep_enabled) {
9141 save_cpu_state(ctx, 0);
895c2d04 9142 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9143 }
9144 tcg_gen_exit_tb(0);
9145 break;
9146 default:
9147 MIPS_DEBUG("unknown branch");
9148 break;
9149 }
9150 }
9151}
9152
7a387fff 9153/* ISA extensions (ASEs) */
6af0bf9c 9154/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9155
9156/* MIPS16 major opcodes */
9157enum {
9158 M16_OPC_ADDIUSP = 0x00,
9159 M16_OPC_ADDIUPC = 0x01,
9160 M16_OPC_B = 0x02,
9161 M16_OPC_JAL = 0x03,
9162 M16_OPC_BEQZ = 0x04,
9163 M16_OPC_BNEQZ = 0x05,
9164 M16_OPC_SHIFT = 0x06,
9165 M16_OPC_LD = 0x07,
9166 M16_OPC_RRIA = 0x08,
9167 M16_OPC_ADDIU8 = 0x09,
9168 M16_OPC_SLTI = 0x0a,
9169 M16_OPC_SLTIU = 0x0b,
9170 M16_OPC_I8 = 0x0c,
9171 M16_OPC_LI = 0x0d,
9172 M16_OPC_CMPI = 0x0e,
9173 M16_OPC_SD = 0x0f,
9174 M16_OPC_LB = 0x10,
9175 M16_OPC_LH = 0x11,
9176 M16_OPC_LWSP = 0x12,
9177 M16_OPC_LW = 0x13,
9178 M16_OPC_LBU = 0x14,
9179 M16_OPC_LHU = 0x15,
9180 M16_OPC_LWPC = 0x16,
9181 M16_OPC_LWU = 0x17,
9182 M16_OPC_SB = 0x18,
9183 M16_OPC_SH = 0x19,
9184 M16_OPC_SWSP = 0x1a,
9185 M16_OPC_SW = 0x1b,
9186 M16_OPC_RRR = 0x1c,
9187 M16_OPC_RR = 0x1d,
9188 M16_OPC_EXTEND = 0x1e,
9189 M16_OPC_I64 = 0x1f
9190};
9191
9192/* I8 funct field */
9193enum {
9194 I8_BTEQZ = 0x0,
9195 I8_BTNEZ = 0x1,
9196 I8_SWRASP = 0x2,
9197 I8_ADJSP = 0x3,
9198 I8_SVRS = 0x4,
9199 I8_MOV32R = 0x5,
9200 I8_MOVR32 = 0x7
9201};
9202
9203/* RRR f field */
9204enum {
9205 RRR_DADDU = 0x0,
9206 RRR_ADDU = 0x1,
9207 RRR_DSUBU = 0x2,
9208 RRR_SUBU = 0x3
9209};
9210
9211/* RR funct field */
9212enum {
9213 RR_JR = 0x00,
9214 RR_SDBBP = 0x01,
9215 RR_SLT = 0x02,
9216 RR_SLTU = 0x03,
9217 RR_SLLV = 0x04,
9218 RR_BREAK = 0x05,
9219 RR_SRLV = 0x06,
9220 RR_SRAV = 0x07,
9221 RR_DSRL = 0x08,
9222 RR_CMP = 0x0a,
9223 RR_NEG = 0x0b,
9224 RR_AND = 0x0c,
9225 RR_OR = 0x0d,
9226 RR_XOR = 0x0e,
9227 RR_NOT = 0x0f,
9228 RR_MFHI = 0x10,
9229 RR_CNVT = 0x11,
9230 RR_MFLO = 0x12,
9231 RR_DSRA = 0x13,
9232 RR_DSLLV = 0x14,
9233 RR_DSRLV = 0x16,
9234 RR_DSRAV = 0x17,
9235 RR_MULT = 0x18,
9236 RR_MULTU = 0x19,
9237 RR_DIV = 0x1a,
9238 RR_DIVU = 0x1b,
9239 RR_DMULT = 0x1c,
9240 RR_DMULTU = 0x1d,
9241 RR_DDIV = 0x1e,
9242 RR_DDIVU = 0x1f
9243};
9244
9245/* I64 funct field */
9246enum {
9247 I64_LDSP = 0x0,
9248 I64_SDSP = 0x1,
9249 I64_SDRASP = 0x2,
9250 I64_DADJSP = 0x3,
9251 I64_LDPC = 0x4,
364d4831 9252 I64_DADDIU5 = 0x5,
6ea219d0
NF
9253 I64_DADDIUPC = 0x6,
9254 I64_DADDIUSP = 0x7
9255};
9256
9257/* RR ry field for CNVT */
9258enum {
9259 RR_RY_CNVT_ZEB = 0x0,
9260 RR_RY_CNVT_ZEH = 0x1,
9261 RR_RY_CNVT_ZEW = 0x2,
9262 RR_RY_CNVT_SEB = 0x4,
9263 RR_RY_CNVT_SEH = 0x5,
9264 RR_RY_CNVT_SEW = 0x6,
9265};
9266
364d4831
NF
9267static int xlat (int r)
9268{
9269 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9270
9271 return map[r];
9272}
9273
9274static void gen_mips16_save (DisasContext *ctx,
9275 int xsregs, int aregs,
9276 int do_ra, int do_s0, int do_s1,
9277 int framesize)
9278{
9279 TCGv t0 = tcg_temp_new();
9280 TCGv t1 = tcg_temp_new();
9281 int args, astatic;
9282
9283 switch (aregs) {
9284 case 0:
9285 case 1:
9286 case 2:
9287 case 3:
9288 case 11:
9289 args = 0;
9290 break;
9291 case 4:
9292 case 5:
9293 case 6:
9294 case 7:
9295 args = 1;
9296 break;
9297 case 8:
9298 case 9:
9299 case 10:
9300 args = 2;
9301 break;
9302 case 12:
9303 case 13:
9304 args = 3;
9305 break;
9306 case 14:
9307 args = 4;
9308 break;
9309 default:
9310 generate_exception(ctx, EXCP_RI);
9311 return;
9312 }
9313
9314 switch (args) {
9315 case 4:
9316 gen_base_offset_addr(ctx, t0, 29, 12);
9317 gen_load_gpr(t1, 7);
2910c6cb 9318 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9319 /* Fall through */
9320 case 3:
9321 gen_base_offset_addr(ctx, t0, 29, 8);
9322 gen_load_gpr(t1, 6);
2910c6cb 9323 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9324 /* Fall through */
9325 case 2:
9326 gen_base_offset_addr(ctx, t0, 29, 4);
9327 gen_load_gpr(t1, 5);
2910c6cb 9328 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9329 /* Fall through */
9330 case 1:
9331 gen_base_offset_addr(ctx, t0, 29, 0);
9332 gen_load_gpr(t1, 4);
2910c6cb 9333 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
364d4831
NF
9334 }
9335
9336 gen_load_gpr(t0, 29);
9337
9338#define DECR_AND_STORE(reg) do { \
9339 tcg_gen_subi_tl(t0, t0, 4); \
9340 gen_load_gpr(t1, reg); \
2910c6cb 9341 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
364d4831
NF
9342 } while (0)
9343
9344 if (do_ra) {
9345 DECR_AND_STORE(31);
9346 }
9347
9348 switch (xsregs) {
9349 case 7:
9350 DECR_AND_STORE(30);
9351 /* Fall through */
9352 case 6:
9353 DECR_AND_STORE(23);
9354 /* Fall through */
9355 case 5:
9356 DECR_AND_STORE(22);
9357 /* Fall through */
9358 case 4:
9359 DECR_AND_STORE(21);
9360 /* Fall through */
9361 case 3:
9362 DECR_AND_STORE(20);
9363 /* Fall through */
9364 case 2:
9365 DECR_AND_STORE(19);
9366 /* Fall through */
9367 case 1:
9368 DECR_AND_STORE(18);
9369 }
9370
9371 if (do_s1) {
9372 DECR_AND_STORE(17);
9373 }
9374 if (do_s0) {
9375 DECR_AND_STORE(16);
9376 }
9377
9378 switch (aregs) {
9379 case 0:
9380 case 4:
9381 case 8:
9382 case 12:
9383 case 14:
9384 astatic = 0;
9385 break;
9386 case 1:
9387 case 5:
9388 case 9:
9389 case 13:
9390 astatic = 1;
9391 break;
9392 case 2:
9393 case 6:
9394 case 10:
9395 astatic = 2;
9396 break;
9397 case 3:
9398 case 7:
9399 astatic = 3;
9400 break;
9401 case 11:
9402 astatic = 4;
9403 break;
9404 default:
9405 generate_exception(ctx, EXCP_RI);
9406 return;
9407 }
9408
9409 if (astatic > 0) {
9410 DECR_AND_STORE(7);
9411 if (astatic > 1) {
9412 DECR_AND_STORE(6);
9413 if (astatic > 2) {
9414 DECR_AND_STORE(5);
9415 if (astatic > 3) {
9416 DECR_AND_STORE(4);
9417 }
9418 }
9419 }
9420 }
9421#undef DECR_AND_STORE
9422
9423 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9424 tcg_temp_free(t0);
9425 tcg_temp_free(t1);
9426}
9427
9428static void gen_mips16_restore (DisasContext *ctx,
9429 int xsregs, int aregs,
9430 int do_ra, int do_s0, int do_s1,
9431 int framesize)
9432{
9433 int astatic;
9434 TCGv t0 = tcg_temp_new();
9435 TCGv t1 = tcg_temp_new();
9436
9437 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9438
2910c6cb
AJ
9439#define DECR_AND_LOAD(reg) do { \
9440 tcg_gen_subi_tl(t0, t0, 4); \
9441 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9442 gen_store_gpr(t1, reg); \
364d4831
NF
9443 } while (0)
9444
9445 if (do_ra) {
9446 DECR_AND_LOAD(31);
9447 }
9448
9449 switch (xsregs) {
9450 case 7:
9451 DECR_AND_LOAD(30);
9452 /* Fall through */
9453 case 6:
9454 DECR_AND_LOAD(23);
9455 /* Fall through */
9456 case 5:
9457 DECR_AND_LOAD(22);
9458 /* Fall through */
9459 case 4:
9460 DECR_AND_LOAD(21);
9461 /* Fall through */
9462 case 3:
9463 DECR_AND_LOAD(20);
9464 /* Fall through */
9465 case 2:
9466 DECR_AND_LOAD(19);
9467 /* Fall through */
9468 case 1:
9469 DECR_AND_LOAD(18);
9470 }
9471
9472 if (do_s1) {
9473 DECR_AND_LOAD(17);
9474 }
9475 if (do_s0) {
9476 DECR_AND_LOAD(16);
9477 }
9478
9479 switch (aregs) {
9480 case 0:
9481 case 4:
9482 case 8:
9483 case 12:
9484 case 14:
9485 astatic = 0;
9486 break;
9487 case 1:
9488 case 5:
9489 case 9:
9490 case 13:
9491 astatic = 1;
9492 break;
9493 case 2:
9494 case 6:
9495 case 10:
9496 astatic = 2;
9497 break;
9498 case 3:
9499 case 7:
9500 astatic = 3;
9501 break;
9502 case 11:
9503 astatic = 4;
9504 break;
9505 default:
9506 generate_exception(ctx, EXCP_RI);
9507 return;
9508 }
9509
9510 if (astatic > 0) {
9511 DECR_AND_LOAD(7);
9512 if (astatic > 1) {
9513 DECR_AND_LOAD(6);
9514 if (astatic > 2) {
9515 DECR_AND_LOAD(5);
9516 if (astatic > 3) {
9517 DECR_AND_LOAD(4);
9518 }
9519 }
9520 }
9521 }
9522#undef DECR_AND_LOAD
9523
9524 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9525 tcg_temp_free(t0);
9526 tcg_temp_free(t1);
9527}
9528
9529static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9530 int is_64_bit, int extended)
9531{
9532 TCGv t0;
9533
9534 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9535 generate_exception(ctx, EXCP_RI);
9536 return;
9537 }
9538
9539 t0 = tcg_temp_new();
9540
9541 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9542 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9543 if (!is_64_bit) {
9544 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9545 }
9546
9547 tcg_temp_free(t0);
9548}
9549
9550#if defined(TARGET_MIPS64)
7db13fae 9551static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9552 int ry, int funct, int16_t offset,
9553 int extended)
9554{
9555 switch (funct) {
9556 case I64_LDSP:
9557 check_mips_64(ctx);
9558 offset = extended ? offset : offset << 3;
afa88c3a 9559 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9560 break;
9561 case I64_SDSP:
9562 check_mips_64(ctx);
9563 offset = extended ? offset : offset << 3;
5c13fdfd 9564 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9565 break;
9566 case I64_SDRASP:
9567 check_mips_64(ctx);
9568 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9569 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9570 break;
9571 case I64_DADJSP:
9572 check_mips_64(ctx);
9573 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9574 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9575 break;
9576 case I64_LDPC:
9577 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9578 generate_exception(ctx, EXCP_RI);
9579 } else {
9580 offset = extended ? offset : offset << 3;
afa88c3a 9581 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9582 }
9583 break;
9584 case I64_DADDIU5:
9585 check_mips_64(ctx);
9586 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9587 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9588 break;
9589 case I64_DADDIUPC:
9590 check_mips_64(ctx);
9591 offset = extended ? offset : offset << 2;
9592 gen_addiupc(ctx, ry, offset, 1, extended);
9593 break;
9594 case I64_DADDIUSP:
9595 check_mips_64(ctx);
9596 offset = extended ? offset : offset << 2;
9597 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9598 break;
9599 }
9600}
9601#endif
9602
7db13fae 9603static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9604 int *is_branch)
9605{
895c2d04 9606 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9607 int op, rx, ry, funct, sa;
9608 int16_t imm, offset;
9609
9610 ctx->opcode = (ctx->opcode << 16) | extend;
9611 op = (ctx->opcode >> 11) & 0x1f;
9612 sa = (ctx->opcode >> 22) & 0x1f;
9613 funct = (ctx->opcode >> 8) & 0x7;
9614 rx = xlat((ctx->opcode >> 8) & 0x7);
9615 ry = xlat((ctx->opcode >> 5) & 0x7);
9616 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9617 | ((ctx->opcode >> 21) & 0x3f) << 5
9618 | (ctx->opcode & 0x1f));
9619
9620 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9621 counterparts. */
9622 switch (op) {
9623 case M16_OPC_ADDIUSP:
9624 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9625 break;
9626 case M16_OPC_ADDIUPC:
9627 gen_addiupc(ctx, rx, imm, 0, 1);
9628 break;
9629 case M16_OPC_B:
9630 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9631 /* No delay slot, so just process as a normal instruction */
9632 break;
9633 case M16_OPC_BEQZ:
9634 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9635 /* No delay slot, so just process as a normal instruction */
9636 break;
9637 case M16_OPC_BNEQZ:
9638 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9639 /* No delay slot, so just process as a normal instruction */
9640 break;
9641 case M16_OPC_SHIFT:
9642 switch (ctx->opcode & 0x3) {
9643 case 0x0:
9644 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9645 break;
9646 case 0x1:
9647#if defined(TARGET_MIPS64)
9648 check_mips_64(ctx);
9649 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9650#else
9651 generate_exception(ctx, EXCP_RI);
9652#endif
9653 break;
9654 case 0x2:
9655 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9656 break;
9657 case 0x3:
9658 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9659 break;
9660 }
9661 break;
9662#if defined(TARGET_MIPS64)
9663 case M16_OPC_LD:
9664 check_mips_64(ctx);
afa88c3a 9665 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9666 break;
9667#endif
9668 case M16_OPC_RRIA:
9669 imm = ctx->opcode & 0xf;
9670 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9671 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9672 imm = (int16_t) (imm << 1) >> 1;
9673 if ((ctx->opcode >> 4) & 0x1) {
9674#if defined(TARGET_MIPS64)
9675 check_mips_64(ctx);
9676 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9677#else
9678 generate_exception(ctx, EXCP_RI);
9679#endif
9680 } else {
9681 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9682 }
9683 break;
9684 case M16_OPC_ADDIU8:
9685 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9686 break;
9687 case M16_OPC_SLTI:
9fa77488 9688 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9689 break;
9690 case M16_OPC_SLTIU:
9fa77488 9691 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9692 break;
9693 case M16_OPC_I8:
9694 switch (funct) {
9695 case I8_BTEQZ:
9696 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9697 break;
9698 case I8_BTNEZ:
9699 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9700 break;
9701 case I8_SWRASP:
5c13fdfd 9702 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9703 break;
9704 case I8_ADJSP:
9705 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9706 break;
9707 case I8_SVRS:
9708 {
9709 int xsregs = (ctx->opcode >> 24) & 0x7;
9710 int aregs = (ctx->opcode >> 16) & 0xf;
9711 int do_ra = (ctx->opcode >> 6) & 0x1;
9712 int do_s0 = (ctx->opcode >> 5) & 0x1;
9713 int do_s1 = (ctx->opcode >> 4) & 0x1;
9714 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9715 | (ctx->opcode & 0xf)) << 3;
9716
9717 if (ctx->opcode & (1 << 7)) {
9718 gen_mips16_save(ctx, xsregs, aregs,
9719 do_ra, do_s0, do_s1,
9720 framesize);
9721 } else {
9722 gen_mips16_restore(ctx, xsregs, aregs,
9723 do_ra, do_s0, do_s1,
9724 framesize);
9725 }
9726 }
9727 break;
9728 default:
9729 generate_exception(ctx, EXCP_RI);
9730 break;
9731 }
9732 break;
9733 case M16_OPC_LI:
9734 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9735 break;
9736 case M16_OPC_CMPI:
9737 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9738 break;
9739#if defined(TARGET_MIPS64)
9740 case M16_OPC_SD:
5c13fdfd 9741 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9742 break;
9743#endif
9744 case M16_OPC_LB:
afa88c3a 9745 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9746 break;
9747 case M16_OPC_LH:
afa88c3a 9748 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9749 break;
9750 case M16_OPC_LWSP:
afa88c3a 9751 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9752 break;
9753 case M16_OPC_LW:
afa88c3a 9754 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9755 break;
9756 case M16_OPC_LBU:
afa88c3a 9757 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9758 break;
9759 case M16_OPC_LHU:
afa88c3a 9760 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9761 break;
9762 case M16_OPC_LWPC:
afa88c3a 9763 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9764 break;
9765#if defined(TARGET_MIPS64)
9766 case M16_OPC_LWU:
afa88c3a 9767 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9768 break;
9769#endif
9770 case M16_OPC_SB:
5c13fdfd 9771 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9772 break;
9773 case M16_OPC_SH:
5c13fdfd 9774 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9775 break;
9776 case M16_OPC_SWSP:
5c13fdfd 9777 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9778 break;
9779 case M16_OPC_SW:
5c13fdfd 9780 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9781 break;
9782#if defined(TARGET_MIPS64)
9783 case M16_OPC_I64:
9784 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9785 break;
9786#endif
9787 default:
9788 generate_exception(ctx, EXCP_RI);
9789 break;
9790 }
9791
9792 return 4;
9793}
9794
7db13fae 9795static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9796 int *is_branch)
9797{
9798 int rx, ry;
9799 int sa;
9800 int op, cnvt_op, op1, offset;
9801 int funct;
9802 int n_bytes;
9803
9804 op = (ctx->opcode >> 11) & 0x1f;
9805 sa = (ctx->opcode >> 2) & 0x7;
9806 sa = sa == 0 ? 8 : sa;
9807 rx = xlat((ctx->opcode >> 8) & 0x7);
9808 cnvt_op = (ctx->opcode >> 5) & 0x7;
9809 ry = xlat((ctx->opcode >> 5) & 0x7);
9810 op1 = offset = ctx->opcode & 0x1f;
9811
9812 n_bytes = 2;
9813
9814 switch (op) {
9815 case M16_OPC_ADDIUSP:
9816 {
9817 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9818
9819 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9820 }
9821 break;
9822 case M16_OPC_ADDIUPC:
9823 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9824 break;
9825 case M16_OPC_B:
9826 offset = (ctx->opcode & 0x7ff) << 1;
9827 offset = (int16_t)(offset << 4) >> 4;
9828 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9829 /* No delay slot, so just process as a normal instruction */
9830 break;
9831 case M16_OPC_JAL:
895c2d04 9832 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9833 offset = (((ctx->opcode & 0x1f) << 21)
9834 | ((ctx->opcode >> 5) & 0x1f) << 16
9835 | offset) << 2;
620e48f6 9836 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9837 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9838 n_bytes = 4;
9839 *is_branch = 1;
9840 break;
9841 case M16_OPC_BEQZ:
9842 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9843 /* No delay slot, so just process as a normal instruction */
9844 break;
9845 case M16_OPC_BNEQZ:
9846 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9847 /* No delay slot, so just process as a normal instruction */
9848 break;
9849 case M16_OPC_SHIFT:
9850 switch (ctx->opcode & 0x3) {
9851 case 0x0:
9852 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9853 break;
9854 case 0x1:
9855#if defined(TARGET_MIPS64)
9856 check_mips_64(ctx);
9857 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9858#else
9859 generate_exception(ctx, EXCP_RI);
9860#endif
9861 break;
9862 case 0x2:
9863 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9864 break;
9865 case 0x3:
9866 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9867 break;
9868 }
9869 break;
9870#if defined(TARGET_MIPS64)
9871 case M16_OPC_LD:
9872 check_mips_64(ctx);
afa88c3a 9873 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9874 break;
9875#endif
9876 case M16_OPC_RRIA:
9877 {
9878 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9879
9880 if ((ctx->opcode >> 4) & 1) {
9881#if defined(TARGET_MIPS64)
9882 check_mips_64(ctx);
9883 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9884#else
9885 generate_exception(ctx, EXCP_RI);
9886#endif
9887 } else {
9888 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9889 }
9890 }
9891 break;
9892 case M16_OPC_ADDIU8:
9893 {
9894 int16_t imm = (int8_t) ctx->opcode;
9895
9896 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9897 }
9898 break;
9899 case M16_OPC_SLTI:
9900 {
9901 int16_t imm = (uint8_t) ctx->opcode;
9fa77488 9902 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9903 }
9904 break;
9905 case M16_OPC_SLTIU:
9906 {
9907 int16_t imm = (uint8_t) ctx->opcode;
9fa77488 9908 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9909 }
9910 break;
9911 case M16_OPC_I8:
9912 {
9913 int reg32;
9914
9915 funct = (ctx->opcode >> 8) & 0x7;
9916 switch (funct) {
9917 case I8_BTEQZ:
9918 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9919 ((int8_t)ctx->opcode) << 1);
9920 break;
9921 case I8_BTNEZ:
9922 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9923 ((int8_t)ctx->opcode) << 1);
9924 break;
9925 case I8_SWRASP:
5c13fdfd 9926 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9927 break;
9928 case I8_ADJSP:
9929 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9930 ((int8_t)ctx->opcode) << 3);
9931 break;
9932 case I8_SVRS:
9933 {
9934 int do_ra = ctx->opcode & (1 << 6);
9935 int do_s0 = ctx->opcode & (1 << 5);
9936 int do_s1 = ctx->opcode & (1 << 4);
9937 int framesize = ctx->opcode & 0xf;
9938
9939 if (framesize == 0) {
9940 framesize = 128;
9941 } else {
9942 framesize = framesize << 3;
9943 }
9944
9945 if (ctx->opcode & (1 << 7)) {
9946 gen_mips16_save(ctx, 0, 0,
9947 do_ra, do_s0, do_s1, framesize);
9948 } else {
9949 gen_mips16_restore(ctx, 0, 0,
9950 do_ra, do_s0, do_s1, framesize);
9951 }
9952 }
9953 break;
9954 case I8_MOV32R:
9955 {
9956 int rz = xlat(ctx->opcode & 0x7);
9957
9958 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9959 ((ctx->opcode >> 5) & 0x7);
9960 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9961 }
9962 break;
9963 case I8_MOVR32:
9964 reg32 = ctx->opcode & 0x1f;
9965 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9966 break;
9967 default:
9968 generate_exception(ctx, EXCP_RI);
9969 break;
9970 }
9971 }
9972 break;
9973 case M16_OPC_LI:
9974 {
9975 int16_t imm = (uint8_t) ctx->opcode;
9976
9977 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9978 }
9979 break;
9980 case M16_OPC_CMPI:
9981 {
9982 int16_t imm = (uint8_t) ctx->opcode;
9fa77488 9983 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
9984 }
9985 break;
9986#if defined(TARGET_MIPS64)
9987 case M16_OPC_SD:
9988 check_mips_64(ctx);
5c13fdfd 9989 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
9990 break;
9991#endif
9992 case M16_OPC_LB:
afa88c3a 9993 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9994 break;
9995 case M16_OPC_LH:
afa88c3a 9996 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
9997 break;
9998 case M16_OPC_LWSP:
afa88c3a 9999 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10000 break;
10001 case M16_OPC_LW:
afa88c3a 10002 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10003 break;
10004 case M16_OPC_LBU:
afa88c3a 10005 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10006 break;
10007 case M16_OPC_LHU:
afa88c3a 10008 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10009 break;
10010 case M16_OPC_LWPC:
afa88c3a 10011 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10012 break;
10013#if defined (TARGET_MIPS64)
10014 case M16_OPC_LWU:
10015 check_mips_64(ctx);
afa88c3a 10016 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10017 break;
10018#endif
10019 case M16_OPC_SB:
5c13fdfd 10020 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10021 break;
10022 case M16_OPC_SH:
5c13fdfd 10023 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10024 break;
10025 case M16_OPC_SWSP:
5c13fdfd 10026 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10027 break;
10028 case M16_OPC_SW:
5c13fdfd 10029 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10030 break;
10031 case M16_OPC_RRR:
10032 {
10033 int rz = xlat((ctx->opcode >> 2) & 0x7);
10034 int mips32_op;
10035
10036 switch (ctx->opcode & 0x3) {
10037 case RRR_ADDU:
10038 mips32_op = OPC_ADDU;
10039 break;
10040 case RRR_SUBU:
10041 mips32_op = OPC_SUBU;
10042 break;
10043#if defined(TARGET_MIPS64)
10044 case RRR_DADDU:
10045 mips32_op = OPC_DADDU;
10046 check_mips_64(ctx);
10047 break;
10048 case RRR_DSUBU:
10049 mips32_op = OPC_DSUBU;
10050 check_mips_64(ctx);
10051 break;
10052#endif
10053 default:
10054 generate_exception(ctx, EXCP_RI);
10055 goto done;
10056 }
10057
10058 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10059 done:
10060 ;
10061 }
10062 break;
10063 case M16_OPC_RR:
10064 switch (op1) {
10065 case RR_JR:
10066 {
10067 int nd = (ctx->opcode >> 7) & 0x1;
10068 int link = (ctx->opcode >> 6) & 0x1;
10069 int ra = (ctx->opcode >> 5) & 0x1;
10070
10071 if (link) {
620e48f6 10072 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10073 } else {
10074 op = OPC_JR;
10075 }
10076
10077 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10078 if (!nd) {
10079 *is_branch = 1;
10080 }
10081 }
10082 break;
10083 case RR_SDBBP:
10084 /* XXX: not clear which exception should be raised
10085 * when in debug mode...
10086 */
10087 check_insn(env, ctx, ISA_MIPS32);
10088 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10089 generate_exception(ctx, EXCP_DBp);
10090 } else {
10091 generate_exception(ctx, EXCP_DBp);
10092 }
10093 break;
10094 case RR_SLT:
9fa77488 10095 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10096 break;
10097 case RR_SLTU:
9fa77488 10098 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10099 break;
10100 case RR_BREAK:
10101 generate_exception(ctx, EXCP_BREAK);
10102 break;
10103 case RR_SLLV:
10104 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10105 break;
10106 case RR_SRLV:
10107 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10108 break;
10109 case RR_SRAV:
10110 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10111 break;
10112#if defined (TARGET_MIPS64)
10113 case RR_DSRL:
10114 check_mips_64(ctx);
10115 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10116 break;
10117#endif
10118 case RR_CMP:
9fa77488 10119 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10120 break;
10121 case RR_NEG:
10122 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10123 break;
10124 case RR_AND:
9fa77488 10125 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10126 break;
10127 case RR_OR:
9fa77488 10128 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10129 break;
10130 case RR_XOR:
9fa77488 10131 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10132 break;
10133 case RR_NOT:
9fa77488 10134 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10135 break;
10136 case RR_MFHI:
10137 gen_HILO(ctx, OPC_MFHI, rx);
10138 break;
10139 case RR_CNVT:
10140 switch (cnvt_op) {
10141 case RR_RY_CNVT_ZEB:
10142 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10143 break;
10144 case RR_RY_CNVT_ZEH:
10145 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10146 break;
10147 case RR_RY_CNVT_SEB:
10148 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10149 break;
10150 case RR_RY_CNVT_SEH:
10151 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10152 break;
10153#if defined (TARGET_MIPS64)
10154 case RR_RY_CNVT_ZEW:
10155 check_mips_64(ctx);
10156 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10157 break;
10158 case RR_RY_CNVT_SEW:
10159 check_mips_64(ctx);
10160 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10161 break;
10162#endif
10163 default:
10164 generate_exception(ctx, EXCP_RI);
10165 break;
10166 }
10167 break;
10168 case RR_MFLO:
10169 gen_HILO(ctx, OPC_MFLO, rx);
10170 break;
10171#if defined (TARGET_MIPS64)
10172 case RR_DSRA:
10173 check_mips_64(ctx);
10174 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10175 break;
10176 case RR_DSLLV:
10177 check_mips_64(ctx);
10178 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10179 break;
10180 case RR_DSRLV:
10181 check_mips_64(ctx);
10182 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10183 break;
10184 case RR_DSRAV:
10185 check_mips_64(ctx);
10186 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10187 break;
10188#endif
10189 case RR_MULT:
10190 gen_muldiv(ctx, OPC_MULT, rx, ry);
10191 break;
10192 case RR_MULTU:
10193 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10194 break;
10195 case RR_DIV:
10196 gen_muldiv(ctx, OPC_DIV, rx, ry);
10197 break;
10198 case RR_DIVU:
10199 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10200 break;
10201#if defined (TARGET_MIPS64)
10202 case RR_DMULT:
10203 check_mips_64(ctx);
10204 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10205 break;
10206 case RR_DMULTU:
10207 check_mips_64(ctx);
10208 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10209 break;
10210 case RR_DDIV:
10211 check_mips_64(ctx);
10212 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10213 break;
10214 case RR_DDIVU:
10215 check_mips_64(ctx);
10216 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10217 break;
10218#endif
10219 default:
10220 generate_exception(ctx, EXCP_RI);
10221 break;
10222 }
10223 break;
10224 case M16_OPC_EXTEND:
10225 decode_extended_mips16_opc(env, ctx, is_branch);
10226 n_bytes = 4;
10227 break;
10228#if defined(TARGET_MIPS64)
10229 case M16_OPC_I64:
10230 funct = (ctx->opcode >> 8) & 0x7;
10231 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10232 break;
10233#endif
10234 default:
10235 generate_exception(ctx, EXCP_RI);
10236 break;
10237 }
10238
10239 return n_bytes;
10240}
10241
211da992 10242/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10243
211da992
WRC
10244/*
10245 * microMIPS32/microMIPS64 major opcodes
10246 *
10247 * 1. MIPS Architecture for Programmers Volume II-B:
10248 * The microMIPS32 Instruction Set (Revision 3.05)
10249 *
10250 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10251 *
10252 * 2. MIPS Architecture For Programmers Volume II-A:
10253 * The MIPS64 Instruction Set (Revision 3.51)
10254 */
6af0bf9c 10255
3c824109
NF
10256enum {
10257 POOL32A = 0x00,
10258 POOL16A = 0x01,
10259 LBU16 = 0x02,
10260 MOVE16 = 0x03,
10261 ADDI32 = 0x04,
10262 LBU32 = 0x05,
10263 SB32 = 0x06,
10264 LB32 = 0x07,
10265
10266 POOL32B = 0x08,
10267 POOL16B = 0x09,
10268 LHU16 = 0x0a,
10269 ANDI16 = 0x0b,
10270 ADDIU32 = 0x0c,
10271 LHU32 = 0x0d,
10272 SH32 = 0x0e,
10273 LH32 = 0x0f,
10274
10275 POOL32I = 0x10,
10276 POOL16C = 0x11,
10277 LWSP16 = 0x12,
10278 POOL16D = 0x13,
10279 ORI32 = 0x14,
10280 POOL32F = 0x15,
211da992
WRC
10281 POOL32S = 0x16, /* MIPS64 */
10282 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10283
211da992 10284 /* 0x1f is reserved */
3c824109
NF
10285 POOL32C = 0x18,
10286 LWGP16 = 0x19,
10287 LW16 = 0x1a,
10288 POOL16E = 0x1b,
10289 XORI32 = 0x1c,
10290 JALS32 = 0x1d,
10291 ADDIUPC = 0x1e,
3c824109
NF
10292
10293 /* 0x20 is reserved */
10294 RES_20 = 0x20,
10295 POOL16F = 0x21,
10296 SB16 = 0x22,
10297 BEQZ16 = 0x23,
10298 SLTI32 = 0x24,
10299 BEQ32 = 0x25,
10300 SWC132 = 0x26,
10301 LWC132 = 0x27,
10302
10303 /* 0x28 and 0x29 are reserved */
10304 RES_28 = 0x28,
10305 RES_29 = 0x29,
10306 SH16 = 0x2a,
10307 BNEZ16 = 0x2b,
10308 SLTIU32 = 0x2c,
10309 BNE32 = 0x2d,
10310 SDC132 = 0x2e,
10311 LDC132 = 0x2f,
10312
10313 /* 0x30 and 0x31 are reserved */
10314 RES_30 = 0x30,
10315 RES_31 = 0x31,
10316 SWSP16 = 0x32,
10317 B16 = 0x33,
10318 ANDI32 = 0x34,
10319 J32 = 0x35,
211da992
WRC
10320 SD32 = 0x36, /* MIPS64 */
10321 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10322
10323 /* 0x38 and 0x39 are reserved */
10324 RES_38 = 0x38,
10325 RES_39 = 0x39,
10326 SW16 = 0x3a,
10327 LI16 = 0x3b,
10328 JALX32 = 0x3c,
10329 JAL32 = 0x3d,
10330 SW32 = 0x3e,
10331 LW32 = 0x3f
10332};
10333
10334/* POOL32A encoding of minor opcode field */
10335
10336enum {
10337 /* These opcodes are distinguished only by bits 9..6; those bits are
10338 * what are recorded below. */
10339 SLL32 = 0x0,
10340 SRL32 = 0x1,
10341 SRA = 0x2,
10342 ROTR = 0x3,
10343
10344 SLLV = 0x0,
10345 SRLV = 0x1,
10346 SRAV = 0x2,
10347 ROTRV = 0x3,
10348 ADD = 0x4,
10349 ADDU32 = 0x5,
10350 SUB = 0x6,
10351 SUBU32 = 0x7,
10352 MUL = 0x8,
10353 AND = 0x9,
10354 OR32 = 0xa,
10355 NOR = 0xb,
10356 XOR32 = 0xc,
10357 SLT = 0xd,
10358 SLTU = 0xe,
10359
10360 MOVN = 0x0,
10361 MOVZ = 0x1,
10362 LWXS = 0x4,
10363
10364 /* The following can be distinguished by their lower 6 bits. */
10365 INS = 0x0c,
10366 EXT = 0x2c,
10367 POOL32AXF = 0x3c
10368};
10369
10370/* POOL32AXF encoding of minor opcode field extension */
10371
d132c79f
WRC
10372/*
10373 * 1. MIPS Architecture for Programmers Volume II-B:
10374 * The microMIPS32 Instruction Set (Revision 3.05)
10375 *
10376 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10377 *
10378 * 2. MIPS Architecture for Programmers VolumeIV-e:
10379 * The MIPS DSP Application-Specific Extension
10380 * to the microMIPS32 Architecture (Revision 2.34)
10381 *
10382 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10383 */
10384
3c824109
NF
10385enum {
10386 /* bits 11..6 */
10387 TEQ = 0x00,
10388 TGE = 0x08,
10389 TGEU = 0x10,
10390 TLT = 0x20,
10391 TLTU = 0x28,
10392 TNE = 0x30,
10393
10394 MFC0 = 0x03,
10395 MTC0 = 0x0b,
10396
d132c79f
WRC
10397 /* begin of microMIPS32 DSP */
10398
3c824109
NF
10399 /* bits 13..12 for 0x01 */
10400 MFHI_ACC = 0x0,
10401 MFLO_ACC = 0x1,
10402 MTHI_ACC = 0x2,
10403 MTLO_ACC = 0x3,
10404
10405 /* bits 13..12 for 0x2a */
10406 MADD_ACC = 0x0,
10407 MADDU_ACC = 0x1,
10408 MSUB_ACC = 0x2,
10409 MSUBU_ACC = 0x3,
10410
10411 /* bits 13..12 for 0x32 */
10412 MULT_ACC = 0x0,
6801038b 10413 MULTU_ACC = 0x1,
3c824109 10414
d132c79f
WRC
10415 /* end of microMIPS32 DSP */
10416
3c824109
NF
10417 /* bits 15..12 for 0x2c */
10418 SEB = 0x2,
10419 SEH = 0x3,
10420 CLO = 0x4,
10421 CLZ = 0x5,
10422 RDHWR = 0x6,
10423 WSBH = 0x7,
10424 MULT = 0x8,
10425 MULTU = 0x9,
10426 DIV = 0xa,
10427 DIVU = 0xb,
10428 MADD = 0xc,
10429 MADDU = 0xd,
10430 MSUB = 0xe,
10431 MSUBU = 0xf,
10432
10433 /* bits 15..12 for 0x34 */
10434 MFC2 = 0x4,
10435 MTC2 = 0x5,
10436 MFHC2 = 0x8,
10437 MTHC2 = 0x9,
10438 CFC2 = 0xc,
10439 CTC2 = 0xd,
10440
10441 /* bits 15..12 for 0x3c */
10442 JALR = 0x0,
10443 JR = 0x0, /* alias */
10444 JALR_HB = 0x1,
10445 JALRS = 0x4,
10446 JALRS_HB = 0x5,
10447
10448 /* bits 15..12 for 0x05 */
10449 RDPGPR = 0xe,
10450 WRPGPR = 0xf,
10451
10452 /* bits 15..12 for 0x0d */
10453 TLBP = 0x0,
10454 TLBR = 0x1,
10455 TLBWI = 0x2,
10456 TLBWR = 0x3,
10457 WAIT = 0x9,
10458 IRET = 0xd,
10459 DERET = 0xe,
10460 ERET = 0xf,
10461
10462 /* bits 15..12 for 0x15 */
10463 DMT = 0x0,
10464 DVPE = 0x1,
10465 EMT = 0x2,
10466 EVPE = 0x3,
10467
10468 /* bits 15..12 for 0x1d */
10469 DI = 0x4,
10470 EI = 0x5,
10471
10472 /* bits 15..12 for 0x2d */
10473 SYNC = 0x6,
10474 SYSCALL = 0x8,
10475 SDBBP = 0xd,
10476
10477 /* bits 15..12 for 0x35 */
10478 MFHI32 = 0x0,
10479 MFLO32 = 0x1,
10480 MTHI32 = 0x2,
10481 MTLO32 = 0x3,
10482};
10483
10484/* POOL32B encoding of minor opcode field (bits 15..12) */
10485
10486enum {
10487 LWC2 = 0x0,
10488 LWP = 0x1,
10489 LDP = 0x4,
10490 LWM32 = 0x5,
10491 CACHE = 0x6,
10492 LDM = 0x7,
10493 SWC2 = 0x8,
10494 SWP = 0x9,
10495 SDP = 0xc,
10496 SWM32 = 0xd,
10497 SDM = 0xf
10498};
10499
10500/* POOL32C encoding of minor opcode field (bits 15..12) */
10501
10502enum {
10503 LWL = 0x0,
10504 SWL = 0x8,
10505 LWR = 0x1,
10506 SWR = 0x9,
10507 PREF = 0x2,
10508 /* 0xa is reserved */
10509 LL = 0x3,
10510 SC = 0xb,
10511 LDL = 0x4,
10512 SDL = 0xc,
10513 LDR = 0x5,
10514 SDR = 0xd,
10515 /* 0x6 is reserved */
10516 LWU = 0xe,
10517 LLD = 0x7,
10518 SCD = 0xf
10519};
10520
10521/* POOL32F encoding of minor opcode field (bits 5..0) */
10522
10523enum {
10524 /* These are the bit 7..6 values */
10525 ADD_FMT = 0x0,
10526 MOVN_FMT = 0x0,
10527
10528 SUB_FMT = 0x1,
10529 MOVZ_FMT = 0x1,
10530
10531 MUL_FMT = 0x2,
10532
10533 DIV_FMT = 0x3,
10534
10535 /* These are the bit 8..6 values */
10536 RSQRT2_FMT = 0x0,
10537 MOVF_FMT = 0x0,
10538
10539 LWXC1 = 0x1,
10540 MOVT_FMT = 0x1,
10541
10542 PLL_PS = 0x2,
10543 SWXC1 = 0x2,
10544
10545 PLU_PS = 0x3,
10546 LDXC1 = 0x3,
10547
10548 PUL_PS = 0x4,
10549 SDXC1 = 0x4,
10550 RECIP2_FMT = 0x4,
10551
10552 PUU_PS = 0x5,
10553 LUXC1 = 0x5,
10554
10555 CVT_PS_S = 0x6,
10556 SUXC1 = 0x6,
10557 ADDR_PS = 0x6,
10558 PREFX = 0x6,
10559
10560 MULR_PS = 0x7,
10561
10562 MADD_S = 0x01,
10563 MADD_D = 0x09,
10564 MADD_PS = 0x11,
10565 ALNV_PS = 0x19,
10566 MSUB_S = 0x21,
10567 MSUB_D = 0x29,
10568 MSUB_PS = 0x31,
10569
10570 NMADD_S = 0x02,
10571 NMADD_D = 0x0a,
10572 NMADD_PS = 0x12,
10573 NMSUB_S = 0x22,
10574 NMSUB_D = 0x2a,
10575 NMSUB_PS = 0x32,
10576
10577 POOL32FXF = 0x3b,
10578
10579 CABS_COND_FMT = 0x1c, /* MIPS3D */
10580 C_COND_FMT = 0x3c
10581};
10582
10583/* POOL32Fxf encoding of minor opcode extension field */
10584
10585enum {
10586 CVT_L = 0x04,
10587 RSQRT_FMT = 0x08,
10588 FLOOR_L = 0x0c,
10589 CVT_PW_PS = 0x1c,
10590 CVT_W = 0x24,
10591 SQRT_FMT = 0x28,
10592 FLOOR_W = 0x2c,
10593 CVT_PS_PW = 0x3c,
10594 CFC1 = 0x40,
10595 RECIP_FMT = 0x48,
10596 CEIL_L = 0x4c,
10597 CTC1 = 0x60,
10598 CEIL_W = 0x6c,
10599 MFC1 = 0x80,
10600 CVT_S_PL = 0x84,
10601 TRUNC_L = 0x8c,
10602 MTC1 = 0xa0,
10603 CVT_S_PU = 0xa4,
10604 TRUNC_W = 0xac,
10605 MFHC1 = 0xc0,
10606 ROUND_L = 0xcc,
10607 MTHC1 = 0xe0,
10608 ROUND_W = 0xec,
10609
10610 MOV_FMT = 0x01,
10611 MOVF = 0x05,
10612 ABS_FMT = 0x0d,
10613 RSQRT1_FMT = 0x1d,
10614 MOVT = 0x25,
10615 NEG_FMT = 0x2d,
10616 CVT_D = 0x4d,
10617 RECIP1_FMT = 0x5d,
10618 CVT_S = 0x6d
10619};
10620
10621/* POOL32I encoding of minor opcode field (bits 25..21) */
10622
10623enum {
10624 BLTZ = 0x00,
10625 BLTZAL = 0x01,
10626 BGEZ = 0x02,
10627 BGEZAL = 0x03,
10628 BLEZ = 0x04,
10629 BNEZC = 0x05,
10630 BGTZ = 0x06,
10631 BEQZC = 0x07,
10632 TLTI = 0x08,
10633 TGEI = 0x09,
10634 TLTIU = 0x0a,
10635 TGEIU = 0x0b,
10636 TNEI = 0x0c,
10637 LUI = 0x0d,
10638 TEQI = 0x0e,
10639 SYNCI = 0x10,
10640 BLTZALS = 0x11,
10641 BGEZALS = 0x13,
10642 BC2F = 0x14,
10643 BC2T = 0x15,
10644 BPOSGE64 = 0x1a,
10645 BPOSGE32 = 0x1b,
10646 /* These overlap and are distinguished by bit16 of the instruction */
10647 BC1F = 0x1c,
10648 BC1T = 0x1d,
10649 BC1ANY2F = 0x1c,
10650 BC1ANY2T = 0x1d,
10651 BC1ANY4F = 0x1e,
10652 BC1ANY4T = 0x1f
10653};
10654
10655/* POOL16A encoding of minor opcode field */
10656
10657enum {
10658 ADDU16 = 0x0,
10659 SUBU16 = 0x1
10660};
10661
10662/* POOL16B encoding of minor opcode field */
10663
10664enum {
10665 SLL16 = 0x0,
10666 SRL16 = 0x1
10667};
10668
10669/* POOL16C encoding of minor opcode field */
10670
10671enum {
10672 NOT16 = 0x00,
10673 XOR16 = 0x04,
10674 AND16 = 0x08,
10675 OR16 = 0x0c,
10676 LWM16 = 0x10,
10677 SWM16 = 0x14,
10678 JR16 = 0x18,
10679 JRC16 = 0x1a,
10680 JALR16 = 0x1c,
10681 JALR16S = 0x1e,
10682 MFHI16 = 0x20,
10683 MFLO16 = 0x24,
10684 BREAK16 = 0x28,
10685 SDBBP16 = 0x2c,
10686 JRADDIUSP = 0x30
10687};
10688
10689/* POOL16D encoding of minor opcode field */
10690
10691enum {
10692 ADDIUS5 = 0x0,
10693 ADDIUSP = 0x1
10694};
10695
10696/* POOL16E encoding of minor opcode field */
10697
10698enum {
10699 ADDIUR2 = 0x0,
10700 ADDIUR1SP = 0x1
10701};
10702
10703static int mmreg (int r)
10704{
10705 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10706
10707 return map[r];
10708}
10709
10710/* Used for 16-bit store instructions. */
10711static int mmreg2 (int r)
10712{
10713 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10714
10715 return map[r];
10716}
10717
10718#define uMIPS_RD(op) ((op >> 7) & 0x7)
10719#define uMIPS_RS(op) ((op >> 4) & 0x7)
10720#define uMIPS_RS2(op) uMIPS_RS(op)
10721#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10722#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10723#define uMIPS_RS5(op) (op & 0x1f)
10724
10725/* Signed immediate */
10726#define SIMM(op, start, width) \
10727 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10728 << (32-width)) \
10729 >> (32-width))
10730/* Zero-extended immediate */
10731#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10732
7db13fae 10733static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10734{
10735 int rd = mmreg(uMIPS_RD(ctx->opcode));
10736
10737 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10738}
10739
7db13fae 10740static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10741{
10742 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10743 int rd = mmreg(uMIPS_RD(ctx->opcode));
10744 int rs = mmreg(uMIPS_RS(ctx->opcode));
10745
10746 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10747}
10748
7db13fae 10749static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10750{
10751 int encoded = ZIMM(ctx->opcode, 1, 9);
10752 int decoded;
10753
10754 if (encoded <= 1) {
10755 decoded = 256 + encoded;
10756 } else if (encoded <= 255) {
10757 decoded = encoded;
10758 } else if (encoded <= 509) {
10759 decoded = encoded - 512;
10760 } else {
10761 decoded = encoded - 768;
10762 }
10763
10764 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10765}
10766
7db13fae 10767static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10768{
10769 int imm = SIMM(ctx->opcode, 1, 4);
10770 int rd = (ctx->opcode >> 5) & 0x1f;
10771
10772 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10773}
10774
7db13fae 10775static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10776{
10777 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10778 31, 32, 63, 64, 255, 32768, 65535 };
10779 int rd = mmreg(uMIPS_RD(ctx->opcode));
10780 int rs = mmreg(uMIPS_RS(ctx->opcode));
10781 int encoded = ZIMM(ctx->opcode, 0, 4);
10782
9fa77488 10783 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10784}
10785
10786static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10787 int base, int16_t offset)
10788{
e1050a76 10789 const char *opn = "ldst_multiple";
3c824109
NF
10790 TCGv t0, t1;
10791 TCGv_i32 t2;
10792
10793 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10794 generate_exception(ctx, EXCP_RI);
10795 return;
10796 }
10797
10798 t0 = tcg_temp_new();
10799
10800 gen_base_offset_addr(ctx, t0, base, offset);
10801
10802 t1 = tcg_const_tl(reglist);
10803 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10804
3c824109
NF
10805 save_cpu_state(ctx, 1);
10806 switch (opc) {
10807 case LWM32:
895c2d04 10808 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10809 opn = "lwm";
3c824109
NF
10810 break;
10811 case SWM32:
895c2d04 10812 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10813 opn = "swm";
3c824109
NF
10814 break;
10815#ifdef TARGET_MIPS64
10816 case LDM:
895c2d04 10817 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10818 opn = "ldm";
3c824109
NF
10819 break;
10820 case SDM:
895c2d04 10821 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10822 opn = "sdm";
3c824109 10823 break;
6af0bf9c 10824#endif
3c824109 10825 }
e1050a76 10826 (void)opn;
3c824109
NF
10827 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10828 tcg_temp_free(t0);
33087598 10829 tcg_temp_free(t1);
3c824109
NF
10830 tcg_temp_free_i32(t2);
10831}
6af0bf9c 10832
3c824109 10833
7db13fae 10834static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
6af0bf9c 10835{
3c824109
NF
10836 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10837 int rs = mmreg(ctx->opcode & 0x7);
10838 int opc;
6af0bf9c 10839
3c824109
NF
10840 switch (((ctx->opcode) >> 4) & 0x3f) {
10841 case NOT16 + 0:
10842 case NOT16 + 1:
10843 case NOT16 + 2:
10844 case NOT16 + 3:
9fa77488 10845 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10846 break;
10847 case XOR16 + 0:
10848 case XOR16 + 1:
10849 case XOR16 + 2:
10850 case XOR16 + 3:
9fa77488 10851 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10852 break;
10853 case AND16 + 0:
10854 case AND16 + 1:
10855 case AND16 + 2:
10856 case AND16 + 3:
9fa77488 10857 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10858 break;
10859 case OR16 + 0:
10860 case OR16 + 1:
10861 case OR16 + 2:
10862 case OR16 + 3:
9fa77488 10863 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10864 break;
10865 case LWM16 + 0:
10866 case LWM16 + 1:
10867 case LWM16 + 2:
10868 case LWM16 + 3:
10869 {
10870 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10871 int offset = ZIMM(ctx->opcode, 0, 4);
10872
10873 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10874 29, offset << 2);
10875 }
10876 break;
10877 case SWM16 + 0:
10878 case SWM16 + 1:
10879 case SWM16 + 2:
10880 case SWM16 + 3:
10881 {
10882 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10883 int offset = ZIMM(ctx->opcode, 0, 4);
10884
10885 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10886 29, offset << 2);
10887 }
10888 break;
10889 case JR16 + 0:
10890 case JR16 + 1:
10891 {
10892 int reg = ctx->opcode & 0x1f;
10893
10894 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10895 }
10896 *is_branch = 1;
10897 break;
10898 case JRC16 + 0:
10899 case JRC16 + 1:
10900 {
10901 int reg = ctx->opcode & 0x1f;
10902
10903 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10904 /* Let normal delay slot handling in our caller take us
10905 to the branch target. */
10906 }
10907 break;
10908 case JALR16 + 0:
10909 case JALR16 + 1:
10910 opc = OPC_JALR;
10911 goto do_jalr;
10912 case JALR16S + 0:
10913 case JALR16S + 1:
10914 opc = OPC_JALRS;
10915 do_jalr:
10916 {
10917 int reg = ctx->opcode & 0x1f;
10918
10919 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10920 }
10921 *is_branch = 1;
10922 break;
10923 case MFHI16 + 0:
10924 case MFHI16 + 1:
10925 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10926 break;
10927 case MFLO16 + 0:
10928 case MFLO16 + 1:
10929 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10930 break;
10931 case BREAK16:
10932 generate_exception(ctx, EXCP_BREAK);
10933 break;
10934 case SDBBP16:
10935 /* XXX: not clear which exception should be raised
10936 * when in debug mode...
10937 */
10938 check_insn(env, ctx, ISA_MIPS32);
10939 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10940 generate_exception(ctx, EXCP_DBp);
10941 } else {
10942 generate_exception(ctx, EXCP_DBp);
10943 }
10944 break;
10945 case JRADDIUSP + 0:
10946 case JRADDIUSP + 1:
10947 {
10948 int imm = ZIMM(ctx->opcode, 0, 5);
10949
10950 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10951 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10952 /* Let normal delay slot handling in our caller take us
10953 to the branch target. */
10954 }
10955 break;
10956 default:
10957 generate_exception(ctx, EXCP_RI);
10958 break;
10959 }
10960}
10961
10962static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10963{
10964 TCGv t0 = tcg_temp_new();
10965 TCGv t1 = tcg_temp_new();
10966
10967 gen_load_gpr(t0, base);
10968
10969 if (index != 0) {
10970 gen_load_gpr(t1, index);
10971 tcg_gen_shli_tl(t1, t1, 2);
10972 gen_op_addr_add(ctx, t0, t1, t0);
10973 }
10974
2910c6cb 10975 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
10976 gen_store_gpr(t1, rd);
10977
10978 tcg_temp_free(t0);
10979 tcg_temp_free(t1);
10980}
10981
10982static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10983 int base, int16_t offset)
10984{
10985 const char *opn = "ldst_pair";
10986 TCGv t0, t1;
10987
36c6711b 10988 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 10989 generate_exception(ctx, EXCP_RI);
d796321b
FB
10990 return;
10991 }
10992
3c824109
NF
10993 t0 = tcg_temp_new();
10994 t1 = tcg_temp_new();
8e9ade68 10995
3c824109
NF
10996 gen_base_offset_addr(ctx, t0, base, offset);
10997
10998 switch (opc) {
10999 case LWP:
36c6711b
EJ
11000 if (rd == base) {
11001 generate_exception(ctx, EXCP_RI);
11002 return;
11003 }
2910c6cb 11004 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11005 gen_store_gpr(t1, rd);
11006 tcg_gen_movi_tl(t1, 4);
11007 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11008 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
3c824109
NF
11009 gen_store_gpr(t1, rd+1);
11010 opn = "lwp";
11011 break;
11012 case SWP:
3c824109 11013 gen_load_gpr(t1, rd);
2910c6cb 11014 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11015 tcg_gen_movi_tl(t1, 4);
11016 gen_op_addr_add(ctx, t0, t0, t1);
11017 gen_load_gpr(t1, rd+1);
2910c6cb 11018 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
3c824109
NF
11019 opn = "swp";
11020 break;
11021#ifdef TARGET_MIPS64
11022 case LDP:
36c6711b
EJ
11023 if (rd == base) {
11024 generate_exception(ctx, EXCP_RI);
11025 return;
11026 }
2910c6cb 11027 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11028 gen_store_gpr(t1, rd);
11029 tcg_gen_movi_tl(t1, 8);
11030 gen_op_addr_add(ctx, t0, t0, t1);
2910c6cb 11031 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
3c824109
NF
11032 gen_store_gpr(t1, rd+1);
11033 opn = "ldp";
11034 break;
11035 case SDP:
3c824109 11036 gen_load_gpr(t1, rd);
2910c6cb 11037 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11038 tcg_gen_movi_tl(t1, 8);
11039 gen_op_addr_add(ctx, t0, t0, t1);
11040 gen_load_gpr(t1, rd+1);
2910c6cb 11041 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
3c824109
NF
11042 opn = "sdp";
11043 break;
11044#endif
6af0bf9c 11045 }
2abf314d 11046 (void)opn; /* avoid a compiler warning */
3c824109
NF
11047 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11048 tcg_temp_free(t0);
11049 tcg_temp_free(t1);
11050}
618b0fe9 11051
7db13fae 11052static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
3c824109
NF
11053 int *is_branch)
11054{
11055 int extension = (ctx->opcode >> 6) & 0x3f;
11056 int minor = (ctx->opcode >> 12) & 0xf;
11057 uint32_t mips32_op;
11058
11059 switch (extension) {
11060 case TEQ:
11061 mips32_op = OPC_TEQ;
11062 goto do_trap;
11063 case TGE:
11064 mips32_op = OPC_TGE;
11065 goto do_trap;
11066 case TGEU:
11067 mips32_op = OPC_TGEU;
11068 goto do_trap;
11069 case TLT:
11070 mips32_op = OPC_TLT;
11071 goto do_trap;
11072 case TLTU:
11073 mips32_op = OPC_TLTU;
11074 goto do_trap;
11075 case TNE:
11076 mips32_op = OPC_TNE;
11077 do_trap:
11078 gen_trap(ctx, mips32_op, rs, rt, -1);
11079 break;
11080#ifndef CONFIG_USER_ONLY
11081 case MFC0:
11082 case MFC0 + 32:
2e15497c 11083 check_cp0_enabled(ctx);
3c824109
NF
11084 if (rt == 0) {
11085 /* Treat as NOP. */
11086 break;
11087 }
11088 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11089 break;
11090 case MTC0:
11091 case MTC0 + 32:
2e15497c 11092 check_cp0_enabled(ctx);
3c824109
NF
11093 {
11094 TCGv t0 = tcg_temp_new();
618b0fe9 11095
3c824109
NF
11096 gen_load_gpr(t0, rt);
11097 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11098 tcg_temp_free(t0);
11099 }
11100 break;
11101#endif
11102 case 0x2c:
11103 switch (minor) {
11104 case SEB:
11105 gen_bshfl(ctx, OPC_SEB, rs, rt);
11106 break;
11107 case SEH:
11108 gen_bshfl(ctx, OPC_SEH, rs, rt);
11109 break;
11110 case CLO:
11111 mips32_op = OPC_CLO;
11112 goto do_cl;
11113 case CLZ:
11114 mips32_op = OPC_CLZ;
11115 do_cl:
11116 check_insn(env, ctx, ISA_MIPS32);
11117 gen_cl(ctx, mips32_op, rt, rs);
11118 break;
11119 case RDHWR:
11120 gen_rdhwr(env, ctx, rt, rs);
11121 break;
11122 case WSBH:
11123 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11124 break;
11125 case MULT:
11126 mips32_op = OPC_MULT;
11127 goto do_muldiv;
11128 case MULTU:
11129 mips32_op = OPC_MULTU;
11130 goto do_muldiv;
11131 case DIV:
11132 mips32_op = OPC_DIV;
11133 goto do_muldiv;
11134 case DIVU:
11135 mips32_op = OPC_DIVU;
11136 goto do_muldiv;
11137 case MADD:
11138 mips32_op = OPC_MADD;
11139 goto do_muldiv;
11140 case MADDU:
11141 mips32_op = OPC_MADDU;
11142 goto do_muldiv;
11143 case MSUB:
11144 mips32_op = OPC_MSUB;
11145 goto do_muldiv;
11146 case MSUBU:
11147 mips32_op = OPC_MSUBU;
11148 do_muldiv:
11149 check_insn(env, ctx, ISA_MIPS32);
11150 gen_muldiv(ctx, mips32_op, rs, rt);
11151 break;
11152 default:
11153 goto pool32axf_invalid;
11154 }
11155 break;
11156 case 0x34:
11157 switch (minor) {
11158 case MFC2:
11159 case MTC2:
11160 case MFHC2:
11161 case MTHC2:
11162 case CFC2:
11163 case CTC2:
11164 generate_exception_err(ctx, EXCP_CpU, 2);
11165 break;
11166 default:
11167 goto pool32axf_invalid;
11168 }
11169 break;
11170 case 0x3c:
11171 switch (minor) {
11172 case JALR:
11173 case JALR_HB:
11174 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11175 *is_branch = 1;
11176 break;
11177 case JALRS:
11178 case JALRS_HB:
11179 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11180 *is_branch = 1;
11181 break;
11182 default:
11183 goto pool32axf_invalid;
11184 }
11185 break;
11186 case 0x05:
11187 switch (minor) {
11188 case RDPGPR:
2e15497c 11189 check_cp0_enabled(ctx);
3c824109
NF
11190 check_insn(env, ctx, ISA_MIPS32R2);
11191 gen_load_srsgpr(rt, rs);
11192 break;
11193 case WRPGPR:
2e15497c 11194 check_cp0_enabled(ctx);
3c824109
NF
11195 check_insn(env, ctx, ISA_MIPS32R2);
11196 gen_store_srsgpr(rt, rs);
11197 break;
11198 default:
11199 goto pool32axf_invalid;
11200 }
11201 break;
11202#ifndef CONFIG_USER_ONLY
11203 case 0x0d:
11204 switch (minor) {
11205 case TLBP:
11206 mips32_op = OPC_TLBP;
11207 goto do_cp0;
11208 case TLBR:
11209 mips32_op = OPC_TLBR;
11210 goto do_cp0;
11211 case TLBWI:
11212 mips32_op = OPC_TLBWI;
11213 goto do_cp0;
11214 case TLBWR:
11215 mips32_op = OPC_TLBWR;
11216 goto do_cp0;
11217 case WAIT:
11218 mips32_op = OPC_WAIT;
11219 goto do_cp0;
11220 case DERET:
11221 mips32_op = OPC_DERET;
11222 goto do_cp0;
11223 case ERET:
11224 mips32_op = OPC_ERET;
11225 do_cp0:
11226 gen_cp0(env, ctx, mips32_op, rt, rs);
11227 break;
11228 default:
11229 goto pool32axf_invalid;
11230 }
11231 break;
11232 case 0x1d:
11233 switch (minor) {
11234 case DI:
2e15497c 11235 check_cp0_enabled(ctx);
3c824109
NF
11236 {
11237 TCGv t0 = tcg_temp_new();
11238
11239 save_cpu_state(ctx, 1);
895c2d04 11240 gen_helper_di(t0, cpu_env);
3c824109
NF
11241 gen_store_gpr(t0, rs);
11242 /* Stop translation as we may have switched the execution mode */
11243 ctx->bstate = BS_STOP;
11244 tcg_temp_free(t0);
11245 }
11246 break;
11247 case EI:
2e15497c 11248 check_cp0_enabled(ctx);
3c824109
NF
11249 {
11250 TCGv t0 = tcg_temp_new();
11251
11252 save_cpu_state(ctx, 1);
895c2d04 11253 gen_helper_ei(t0, cpu_env);
3c824109
NF
11254 gen_store_gpr(t0, rs);
11255 /* Stop translation as we may have switched the execution mode */
11256 ctx->bstate = BS_STOP;
11257 tcg_temp_free(t0);
11258 }
11259 break;
11260 default:
11261 goto pool32axf_invalid;
11262 }
11263 break;
11264#endif
11265 case 0x2d:
11266 switch (minor) {
11267 case SYNC:
11268 /* NOP */
11269 break;
11270 case SYSCALL:
11271 generate_exception(ctx, EXCP_SYSCALL);
11272 ctx->bstate = BS_STOP;
11273 break;
11274 case SDBBP:
11275 check_insn(env, ctx, ISA_MIPS32);
11276 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11277 generate_exception(ctx, EXCP_DBp);
11278 } else {
11279 generate_exception(ctx, EXCP_DBp);
11280 }
11281 break;
11282 default:
11283 goto pool32axf_invalid;
11284 }
11285 break;
11286 case 0x35:
11287 switch (minor) {
11288 case MFHI32:
11289 gen_HILO(ctx, OPC_MFHI, rs);
11290 break;
11291 case MFLO32:
11292 gen_HILO(ctx, OPC_MFLO, rs);
11293 break;
11294 case MTHI32:
11295 gen_HILO(ctx, OPC_MTHI, rs);
11296 break;
11297 case MTLO32:
11298 gen_HILO(ctx, OPC_MTLO, rs);
11299 break;
11300 default:
11301 goto pool32axf_invalid;
11302 }
11303 break;
11304 default:
11305 pool32axf_invalid:
11306 MIPS_INVAL("pool32axf");
11307 generate_exception(ctx, EXCP_RI);
11308 break;
11309 }
11310}
11311
11312/* Values for microMIPS fmt field. Variable-width, depending on which
11313 formats the instruction supports. */
11314
11315enum {
11316 FMT_SD_S = 0,
11317 FMT_SD_D = 1,
11318
11319 FMT_SDPS_S = 0,
11320 FMT_SDPS_D = 1,
11321 FMT_SDPS_PS = 2,
11322
11323 FMT_SWL_S = 0,
11324 FMT_SWL_W = 1,
11325 FMT_SWL_L = 2,
11326
11327 FMT_DWL_D = 0,
11328 FMT_DWL_W = 1,
11329 FMT_DWL_L = 2
11330};
11331
7db13fae 11332static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
11333{
11334 int extension = (ctx->opcode >> 6) & 0x3ff;
11335 uint32_t mips32_op;
11336
11337#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11338#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11339#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11340
11341 switch (extension) {
11342 case FLOAT_1BIT_FMT(CFC1, 0):
11343 mips32_op = OPC_CFC1;
11344 goto do_cp1;
11345 case FLOAT_1BIT_FMT(CTC1, 0):
11346 mips32_op = OPC_CTC1;
11347 goto do_cp1;
11348 case FLOAT_1BIT_FMT(MFC1, 0):
11349 mips32_op = OPC_MFC1;
11350 goto do_cp1;
11351 case FLOAT_1BIT_FMT(MTC1, 0):
11352 mips32_op = OPC_MTC1;
11353 goto do_cp1;
11354 case FLOAT_1BIT_FMT(MFHC1, 0):
11355 mips32_op = OPC_MFHC1;
11356 goto do_cp1;
11357 case FLOAT_1BIT_FMT(MTHC1, 0):
11358 mips32_op = OPC_MTHC1;
11359 do_cp1:
11360 gen_cp1(ctx, mips32_op, rt, rs);
11361 break;
11362
11363 /* Reciprocal square root */
11364 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11365 mips32_op = OPC_RSQRT_S;
11366 goto do_unaryfp;
11367 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11368 mips32_op = OPC_RSQRT_D;
11369 goto do_unaryfp;
11370
11371 /* Square root */
11372 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11373 mips32_op = OPC_SQRT_S;
11374 goto do_unaryfp;
11375 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11376 mips32_op = OPC_SQRT_D;
11377 goto do_unaryfp;
11378
11379 /* Reciprocal */
11380 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11381 mips32_op = OPC_RECIP_S;
11382 goto do_unaryfp;
11383 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11384 mips32_op = OPC_RECIP_D;
11385 goto do_unaryfp;
11386
11387 /* Floor */
11388 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11389 mips32_op = OPC_FLOOR_L_S;
11390 goto do_unaryfp;
11391 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11392 mips32_op = OPC_FLOOR_L_D;
11393 goto do_unaryfp;
11394 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11395 mips32_op = OPC_FLOOR_W_S;
11396 goto do_unaryfp;
11397 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11398 mips32_op = OPC_FLOOR_W_D;
11399 goto do_unaryfp;
11400
11401 /* Ceiling */
11402 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11403 mips32_op = OPC_CEIL_L_S;
11404 goto do_unaryfp;
11405 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11406 mips32_op = OPC_CEIL_L_D;
11407 goto do_unaryfp;
11408 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11409 mips32_op = OPC_CEIL_W_S;
11410 goto do_unaryfp;
11411 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11412 mips32_op = OPC_CEIL_W_D;
11413 goto do_unaryfp;
11414
11415 /* Truncation */
11416 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11417 mips32_op = OPC_TRUNC_L_S;
11418 goto do_unaryfp;
11419 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11420 mips32_op = OPC_TRUNC_L_D;
11421 goto do_unaryfp;
11422 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11423 mips32_op = OPC_TRUNC_W_S;
11424 goto do_unaryfp;
11425 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11426 mips32_op = OPC_TRUNC_W_D;
11427 goto do_unaryfp;
11428
11429 /* Round */
11430 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11431 mips32_op = OPC_ROUND_L_S;
11432 goto do_unaryfp;
11433 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11434 mips32_op = OPC_ROUND_L_D;
11435 goto do_unaryfp;
11436 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11437 mips32_op = OPC_ROUND_W_S;
11438 goto do_unaryfp;
11439 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11440 mips32_op = OPC_ROUND_W_D;
11441 goto do_unaryfp;
11442
11443 /* Integer to floating-point conversion */
11444 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11445 mips32_op = OPC_CVT_L_S;
11446 goto do_unaryfp;
11447 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11448 mips32_op = OPC_CVT_L_D;
11449 goto do_unaryfp;
11450 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11451 mips32_op = OPC_CVT_W_S;
11452 goto do_unaryfp;
11453 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11454 mips32_op = OPC_CVT_W_D;
11455 goto do_unaryfp;
11456
11457 /* Paired-foo conversions */
11458 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11459 mips32_op = OPC_CVT_S_PL;
11460 goto do_unaryfp;
11461 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11462 mips32_op = OPC_CVT_S_PU;
11463 goto do_unaryfp;
11464 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11465 mips32_op = OPC_CVT_PW_PS;
11466 goto do_unaryfp;
11467 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11468 mips32_op = OPC_CVT_PS_PW;
11469 goto do_unaryfp;
11470
11471 /* Floating-point moves */
11472 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11473 mips32_op = OPC_MOV_S;
11474 goto do_unaryfp;
11475 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11476 mips32_op = OPC_MOV_D;
11477 goto do_unaryfp;
11478 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11479 mips32_op = OPC_MOV_PS;
11480 goto do_unaryfp;
11481
11482 /* Absolute value */
11483 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11484 mips32_op = OPC_ABS_S;
11485 goto do_unaryfp;
11486 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11487 mips32_op = OPC_ABS_D;
11488 goto do_unaryfp;
11489 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11490 mips32_op = OPC_ABS_PS;
11491 goto do_unaryfp;
11492
11493 /* Negation */
11494 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11495 mips32_op = OPC_NEG_S;
11496 goto do_unaryfp;
11497 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11498 mips32_op = OPC_NEG_D;
11499 goto do_unaryfp;
11500 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11501 mips32_op = OPC_NEG_PS;
11502 goto do_unaryfp;
11503
11504 /* Reciprocal square root step */
11505 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11506 mips32_op = OPC_RSQRT1_S;
11507 goto do_unaryfp;
11508 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11509 mips32_op = OPC_RSQRT1_D;
11510 goto do_unaryfp;
11511 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11512 mips32_op = OPC_RSQRT1_PS;
11513 goto do_unaryfp;
11514
11515 /* Reciprocal step */
11516 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11517 mips32_op = OPC_RECIP1_S;
11518 goto do_unaryfp;
11519 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11520 mips32_op = OPC_RECIP1_S;
11521 goto do_unaryfp;
11522 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11523 mips32_op = OPC_RECIP1_PS;
11524 goto do_unaryfp;
11525
11526 /* Conversions from double */
11527 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11528 mips32_op = OPC_CVT_D_S;
11529 goto do_unaryfp;
11530 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11531 mips32_op = OPC_CVT_D_W;
11532 goto do_unaryfp;
11533 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11534 mips32_op = OPC_CVT_D_L;
11535 goto do_unaryfp;
11536
11537 /* Conversions from single */
11538 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11539 mips32_op = OPC_CVT_S_D;
11540 goto do_unaryfp;
11541 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11542 mips32_op = OPC_CVT_S_W;
11543 goto do_unaryfp;
11544 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11545 mips32_op = OPC_CVT_S_L;
11546 do_unaryfp:
11547 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11548 break;
11549
11550 /* Conditional moves on floating-point codes */
11551 case COND_FLOAT_MOV(MOVT, 0):
11552 case COND_FLOAT_MOV(MOVT, 1):
11553 case COND_FLOAT_MOV(MOVT, 2):
11554 case COND_FLOAT_MOV(MOVT, 3):
11555 case COND_FLOAT_MOV(MOVT, 4):
11556 case COND_FLOAT_MOV(MOVT, 5):
11557 case COND_FLOAT_MOV(MOVT, 6):
11558 case COND_FLOAT_MOV(MOVT, 7):
11559 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11560 break;
11561 case COND_FLOAT_MOV(MOVF, 0):
11562 case COND_FLOAT_MOV(MOVF, 1):
11563 case COND_FLOAT_MOV(MOVF, 2):
11564 case COND_FLOAT_MOV(MOVF, 3):
11565 case COND_FLOAT_MOV(MOVF, 4):
11566 case COND_FLOAT_MOV(MOVF, 5):
11567 case COND_FLOAT_MOV(MOVF, 6):
11568 case COND_FLOAT_MOV(MOVF, 7):
11569 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11570 break;
11571 default:
11572 MIPS_INVAL("pool32fxf");
11573 generate_exception(ctx, EXCP_RI);
11574 break;
11575 }
11576}
11577
7db13fae 11578static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
3c824109
NF
11579 uint16_t insn_hw1, int *is_branch)
11580{
11581 int32_t offset;
11582 uint16_t insn;
11583 int rt, rs, rd, rr;
11584 int16_t imm;
11585 uint32_t op, minor, mips32_op;
11586 uint32_t cond, fmt, cc;
11587
895c2d04 11588 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11589 ctx->opcode = (ctx->opcode << 16) | insn;
11590
11591 rt = (ctx->opcode >> 21) & 0x1f;
11592 rs = (ctx->opcode >> 16) & 0x1f;
11593 rd = (ctx->opcode >> 11) & 0x1f;
11594 rr = (ctx->opcode >> 6) & 0x1f;
11595 imm = (int16_t) ctx->opcode;
11596
11597 op = (ctx->opcode >> 26) & 0x3f;
11598 switch (op) {
11599 case POOL32A:
11600 minor = ctx->opcode & 0x3f;
11601 switch (minor) {
11602 case 0x00:
11603 minor = (ctx->opcode >> 6) & 0xf;
11604 switch (minor) {
11605 case SLL32:
11606 mips32_op = OPC_SLL;
11607 goto do_shifti;
11608 case SRA:
11609 mips32_op = OPC_SRA;
11610 goto do_shifti;
11611 case SRL32:
11612 mips32_op = OPC_SRL;
11613 goto do_shifti;
11614 case ROTR:
11615 mips32_op = OPC_ROTR;
11616 do_shifti:
11617 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11618 break;
11619 default:
11620 goto pool32a_invalid;
11621 }
11622 break;
11623 case 0x10:
11624 minor = (ctx->opcode >> 6) & 0xf;
11625 switch (minor) {
11626 /* Arithmetic */
11627 case ADD:
11628 mips32_op = OPC_ADD;
11629 goto do_arith;
11630 case ADDU32:
11631 mips32_op = OPC_ADDU;
11632 goto do_arith;
11633 case SUB:
11634 mips32_op = OPC_SUB;
11635 goto do_arith;
11636 case SUBU32:
11637 mips32_op = OPC_SUBU;
11638 goto do_arith;
11639 case MUL:
11640 mips32_op = OPC_MUL;
11641 do_arith:
11642 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11643 break;
11644 /* Shifts */
11645 case SLLV:
11646 mips32_op = OPC_SLLV;
11647 goto do_shift;
11648 case SRLV:
11649 mips32_op = OPC_SRLV;
11650 goto do_shift;
11651 case SRAV:
11652 mips32_op = OPC_SRAV;
11653 goto do_shift;
11654 case ROTRV:
11655 mips32_op = OPC_ROTRV;
11656 do_shift:
11657 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11658 break;
11659 /* Logical operations */
11660 case AND:
11661 mips32_op = OPC_AND;
11662 goto do_logic;
11663 case OR32:
11664 mips32_op = OPC_OR;
11665 goto do_logic;
11666 case NOR:
11667 mips32_op = OPC_NOR;
11668 goto do_logic;
11669 case XOR32:
11670 mips32_op = OPC_XOR;
11671 do_logic:
9fa77488 11672 gen_logic(env, ctx, mips32_op, rd, rs, rt);
3c824109
NF
11673 break;
11674 /* Set less than */
11675 case SLT:
11676 mips32_op = OPC_SLT;
11677 goto do_slt;
11678 case SLTU:
11679 mips32_op = OPC_SLTU;
11680 do_slt:
9fa77488 11681 gen_slt(env, ctx, mips32_op, rd, rs, rt);
3c824109
NF
11682 break;
11683 default:
11684 goto pool32a_invalid;
11685 }
11686 break;
11687 case 0x18:
11688 minor = (ctx->opcode >> 6) & 0xf;
11689 switch (minor) {
11690 /* Conditional moves */
11691 case MOVN:
11692 mips32_op = OPC_MOVN;
11693 goto do_cmov;
11694 case MOVZ:
11695 mips32_op = OPC_MOVZ;
11696 do_cmov:
9fa77488 11697 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
3c824109
NF
11698 break;
11699 case LWXS:
11700 gen_ldxs(ctx, rs, rt, rd);
11701 break;
11702 default:
11703 goto pool32a_invalid;
11704 }
11705 break;
11706 case INS:
11707 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11708 return;
11709 case EXT:
11710 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11711 return;
11712 case POOL32AXF:
11713 gen_pool32axf(env, ctx, rt, rs, is_branch);
11714 break;
11715 case 0x07:
11716 generate_exception(ctx, EXCP_BREAK);
11717 break;
11718 default:
11719 pool32a_invalid:
11720 MIPS_INVAL("pool32a");
11721 generate_exception(ctx, EXCP_RI);
11722 break;
11723 }
11724 break;
11725 case POOL32B:
11726 minor = (ctx->opcode >> 12) & 0xf;
11727 switch (minor) {
11728 case CACHE:
2e15497c 11729 check_cp0_enabled(ctx);
3c824109
NF
11730 /* Treat as no-op. */
11731 break;
11732 case LWC2:
11733 case SWC2:
11734 /* COP2: Not implemented. */
11735 generate_exception_err(ctx, EXCP_CpU, 2);
11736 break;
11737 case LWP:
11738 case SWP:
11739#ifdef TARGET_MIPS64
11740 case LDP:
11741 case SDP:
11742#endif
11743 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11744 break;
11745 case LWM32:
11746 case SWM32:
11747#ifdef TARGET_MIPS64
11748 case LDM:
11749 case SDM:
11750#endif
11751 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11752 break;
11753 default:
11754 MIPS_INVAL("pool32b");
11755 generate_exception(ctx, EXCP_RI);
11756 break;
11757 }
11758 break;
11759 case POOL32F:
11760 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11761 minor = ctx->opcode & 0x3f;
11762 check_cp1_enabled(ctx);
11763 switch (minor) {
11764 case ALNV_PS:
11765 mips32_op = OPC_ALNV_PS;
11766 goto do_madd;
11767 case MADD_S:
11768 mips32_op = OPC_MADD_S;
11769 goto do_madd;
11770 case MADD_D:
11771 mips32_op = OPC_MADD_D;
11772 goto do_madd;
11773 case MADD_PS:
11774 mips32_op = OPC_MADD_PS;
11775 goto do_madd;
11776 case MSUB_S:
11777 mips32_op = OPC_MSUB_S;
11778 goto do_madd;
11779 case MSUB_D:
11780 mips32_op = OPC_MSUB_D;
11781 goto do_madd;
11782 case MSUB_PS:
11783 mips32_op = OPC_MSUB_PS;
11784 goto do_madd;
11785 case NMADD_S:
11786 mips32_op = OPC_NMADD_S;
11787 goto do_madd;
11788 case NMADD_D:
11789 mips32_op = OPC_NMADD_D;
11790 goto do_madd;
11791 case NMADD_PS:
11792 mips32_op = OPC_NMADD_PS;
11793 goto do_madd;
11794 case NMSUB_S:
11795 mips32_op = OPC_NMSUB_S;
11796 goto do_madd;
11797 case NMSUB_D:
11798 mips32_op = OPC_NMSUB_D;
11799 goto do_madd;
11800 case NMSUB_PS:
11801 mips32_op = OPC_NMSUB_PS;
11802 do_madd:
11803 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11804 break;
11805 case CABS_COND_FMT:
11806 cond = (ctx->opcode >> 6) & 0xf;
11807 cc = (ctx->opcode >> 13) & 0x7;
11808 fmt = (ctx->opcode >> 10) & 0x3;
11809 switch (fmt) {
11810 case 0x0:
11811 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11812 break;
11813 case 0x1:
11814 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11815 break;
11816 case 0x2:
11817 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11818 break;
11819 default:
11820 goto pool32f_invalid;
11821 }
11822 break;
11823 case C_COND_FMT:
11824 cond = (ctx->opcode >> 6) & 0xf;
11825 cc = (ctx->opcode >> 13) & 0x7;
11826 fmt = (ctx->opcode >> 10) & 0x3;
11827 switch (fmt) {
11828 case 0x0:
11829 gen_cmp_s(ctx, cond, rt, rs, cc);
11830 break;
11831 case 0x1:
11832 gen_cmp_d(ctx, cond, rt, rs, cc);
11833 break;
11834 case 0x2:
11835 gen_cmp_ps(ctx, cond, rt, rs, cc);
11836 break;
11837 default:
11838 goto pool32f_invalid;
11839 }
11840 break;
11841 case POOL32FXF:
11842 gen_pool32fxf(env, ctx, rt, rs);
11843 break;
11844 case 0x00:
11845 /* PLL foo */
11846 switch ((ctx->opcode >> 6) & 0x7) {
11847 case PLL_PS:
11848 mips32_op = OPC_PLL_PS;
11849 goto do_ps;
11850 case PLU_PS:
11851 mips32_op = OPC_PLU_PS;
11852 goto do_ps;
11853 case PUL_PS:
11854 mips32_op = OPC_PUL_PS;
11855 goto do_ps;
11856 case PUU_PS:
11857 mips32_op = OPC_PUU_PS;
11858 goto do_ps;
11859 case CVT_PS_S:
11860 mips32_op = OPC_CVT_PS_S;
11861 do_ps:
11862 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11863 break;
11864 default:
11865 goto pool32f_invalid;
11866 }
11867 break;
11868 case 0x08:
11869 /* [LS][WDU]XC1 */
11870 switch ((ctx->opcode >> 6) & 0x7) {
11871 case LWXC1:
11872 mips32_op = OPC_LWXC1;
11873 goto do_ldst_cp1;
11874 case SWXC1:
11875 mips32_op = OPC_SWXC1;
11876 goto do_ldst_cp1;
11877 case LDXC1:
11878 mips32_op = OPC_LDXC1;
11879 goto do_ldst_cp1;
11880 case SDXC1:
11881 mips32_op = OPC_SDXC1;
11882 goto do_ldst_cp1;
11883 case LUXC1:
11884 mips32_op = OPC_LUXC1;
11885 goto do_ldst_cp1;
11886 case SUXC1:
11887 mips32_op = OPC_SUXC1;
11888 do_ldst_cp1:
11889 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11890 break;
11891 default:
11892 goto pool32f_invalid;
11893 }
11894 break;
11895 case 0x18:
11896 /* 3D insns */
11897 fmt = (ctx->opcode >> 9) & 0x3;
11898 switch ((ctx->opcode >> 6) & 0x7) {
11899 case RSQRT2_FMT:
11900 switch (fmt) {
11901 case FMT_SDPS_S:
11902 mips32_op = OPC_RSQRT2_S;
11903 goto do_3d;
11904 case FMT_SDPS_D:
11905 mips32_op = OPC_RSQRT2_D;
11906 goto do_3d;
11907 case FMT_SDPS_PS:
11908 mips32_op = OPC_RSQRT2_PS;
11909 goto do_3d;
11910 default:
11911 goto pool32f_invalid;
11912 }
11913 break;
11914 case RECIP2_FMT:
11915 switch (fmt) {
11916 case FMT_SDPS_S:
11917 mips32_op = OPC_RECIP2_S;
11918 goto do_3d;
11919 case FMT_SDPS_D:
11920 mips32_op = OPC_RECIP2_D;
11921 goto do_3d;
11922 case FMT_SDPS_PS:
11923 mips32_op = OPC_RECIP2_PS;
11924 goto do_3d;
11925 default:
11926 goto pool32f_invalid;
11927 }
11928 break;
11929 case ADDR_PS:
11930 mips32_op = OPC_ADDR_PS;
11931 goto do_3d;
11932 case MULR_PS:
11933 mips32_op = OPC_MULR_PS;
11934 do_3d:
11935 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11936 break;
11937 default:
11938 goto pool32f_invalid;
11939 }
11940 break;
11941 case 0x20:
11942 /* MOV[FT].fmt and PREFX */
11943 cc = (ctx->opcode >> 13) & 0x7;
11944 fmt = (ctx->opcode >> 9) & 0x3;
11945 switch ((ctx->opcode >> 6) & 0x7) {
11946 case MOVF_FMT:
11947 switch (fmt) {
11948 case FMT_SDPS_S:
11949 gen_movcf_s(rs, rt, cc, 0);
11950 break;
11951 case FMT_SDPS_D:
11952 gen_movcf_d(ctx, rs, rt, cc, 0);
11953 break;
11954 case FMT_SDPS_PS:
11955 gen_movcf_ps(rs, rt, cc, 0);
11956 break;
11957 default:
11958 goto pool32f_invalid;
11959 }
11960 break;
11961 case MOVT_FMT:
11962 switch (fmt) {
11963 case FMT_SDPS_S:
11964 gen_movcf_s(rs, rt, cc, 1);
11965 break;
11966 case FMT_SDPS_D:
11967 gen_movcf_d(ctx, rs, rt, cc, 1);
11968 break;
11969 case FMT_SDPS_PS:
11970 gen_movcf_ps(rs, rt, cc, 1);
11971 break;
11972 default:
11973 goto pool32f_invalid;
11974 }
11975 break;
11976 case PREFX:
11977 break;
11978 default:
11979 goto pool32f_invalid;
11980 }
11981 break;
11982#define FINSN_3ARG_SDPS(prfx) \
11983 switch ((ctx->opcode >> 8) & 0x3) { \
11984 case FMT_SDPS_S: \
11985 mips32_op = OPC_##prfx##_S; \
11986 goto do_fpop; \
11987 case FMT_SDPS_D: \
11988 mips32_op = OPC_##prfx##_D; \
11989 goto do_fpop; \
11990 case FMT_SDPS_PS: \
11991 mips32_op = OPC_##prfx##_PS; \
11992 goto do_fpop; \
11993 default: \
11994 goto pool32f_invalid; \
11995 }
11996 case 0x30:
11997 /* regular FP ops */
11998 switch ((ctx->opcode >> 6) & 0x3) {
11999 case ADD_FMT:
12000 FINSN_3ARG_SDPS(ADD);
12001 break;
12002 case SUB_FMT:
12003 FINSN_3ARG_SDPS(SUB);
12004 break;
12005 case MUL_FMT:
12006 FINSN_3ARG_SDPS(MUL);
12007 break;
12008 case DIV_FMT:
12009 fmt = (ctx->opcode >> 8) & 0x3;
12010 if (fmt == 1) {
12011 mips32_op = OPC_DIV_D;
12012 } else if (fmt == 0) {
12013 mips32_op = OPC_DIV_S;
12014 } else {
12015 goto pool32f_invalid;
12016 }
12017 goto do_fpop;
12018 default:
12019 goto pool32f_invalid;
12020 }
12021 break;
12022 case 0x38:
12023 /* cmovs */
12024 switch ((ctx->opcode >> 6) & 0x3) {
12025 case MOVN_FMT:
12026 FINSN_3ARG_SDPS(MOVN);
12027 break;
12028 case MOVZ_FMT:
12029 FINSN_3ARG_SDPS(MOVZ);
12030 break;
12031 default:
12032 goto pool32f_invalid;
12033 }
12034 break;
12035 do_fpop:
12036 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12037 break;
12038 default:
12039 pool32f_invalid:
12040 MIPS_INVAL("pool32f");
12041 generate_exception(ctx, EXCP_RI);
12042 break;
12043 }
12044 } else {
12045 generate_exception_err(ctx, EXCP_CpU, 1);
12046 }
12047 break;
12048 case POOL32I:
12049 minor = (ctx->opcode >> 21) & 0x1f;
12050 switch (minor) {
12051 case BLTZ:
12052 mips32_op = OPC_BLTZ;
12053 goto do_branch;
12054 case BLTZAL:
12055 mips32_op = OPC_BLTZAL;
12056 goto do_branch;
12057 case BLTZALS:
12058 mips32_op = OPC_BLTZALS;
12059 goto do_branch;
12060 case BGEZ:
12061 mips32_op = OPC_BGEZ;
12062 goto do_branch;
12063 case BGEZAL:
12064 mips32_op = OPC_BGEZAL;
12065 goto do_branch;
12066 case BGEZALS:
12067 mips32_op = OPC_BGEZALS;
12068 goto do_branch;
12069 case BLEZ:
12070 mips32_op = OPC_BLEZ;
12071 goto do_branch;
12072 case BGTZ:
12073 mips32_op = OPC_BGTZ;
12074 do_branch:
12075 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12076 *is_branch = 1;
12077 break;
12078
12079 /* Traps */
12080 case TLTI:
12081 mips32_op = OPC_TLTI;
12082 goto do_trapi;
12083 case TGEI:
12084 mips32_op = OPC_TGEI;
12085 goto do_trapi;
12086 case TLTIU:
12087 mips32_op = OPC_TLTIU;
12088 goto do_trapi;
12089 case TGEIU:
12090 mips32_op = OPC_TGEIU;
12091 goto do_trapi;
12092 case TNEI:
12093 mips32_op = OPC_TNEI;
12094 goto do_trapi;
12095 case TEQI:
12096 mips32_op = OPC_TEQI;
12097 do_trapi:
12098 gen_trap(ctx, mips32_op, rs, -1, imm);
12099 break;
12100
12101 case BNEZC:
12102 case BEQZC:
12103 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12104 4, rs, 0, imm << 1);
12105 /* Compact branches don't have a delay slot, so just let
12106 the normal delay slot handling take us to the branch
12107 target. */
12108 break;
12109 case LUI:
9fa77488 12110 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12111 break;
12112 case SYNCI:
12113 break;
12114 case BC2F:
12115 case BC2T:
12116 /* COP2: Not implemented. */
12117 generate_exception_err(ctx, EXCP_CpU, 2);
12118 break;
12119 case BC1F:
12120 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12121 goto do_cp1branch;
12122 case BC1T:
12123 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12124 goto do_cp1branch;
12125 case BC1ANY4F:
12126 mips32_op = OPC_BC1FANY4;
12127 goto do_cp1mips3d;
12128 case BC1ANY4T:
12129 mips32_op = OPC_BC1TANY4;
12130 do_cp1mips3d:
12131 check_cop1x(ctx);
12132 check_insn(env, ctx, ASE_MIPS3D);
12133 /* Fall through */
12134 do_cp1branch:
12135 gen_compute_branch1(env, ctx, mips32_op,
12136 (ctx->opcode >> 18) & 0x7, imm << 1);
12137 *is_branch = 1;
12138 break;
12139 case BPOSGE64:
12140 case BPOSGE32:
12141 /* MIPS DSP: not implemented */
12142 /* Fall through */
12143 default:
12144 MIPS_INVAL("pool32i");
12145 generate_exception(ctx, EXCP_RI);
12146 break;
12147 }
12148 break;
12149 case POOL32C:
12150 minor = (ctx->opcode >> 12) & 0xf;
12151 switch (minor) {
12152 case LWL:
12153 mips32_op = OPC_LWL;
5c13fdfd 12154 goto do_ld_lr;
3c824109
NF
12155 case SWL:
12156 mips32_op = OPC_SWL;
5c13fdfd 12157 goto do_st_lr;
3c824109
NF
12158 case LWR:
12159 mips32_op = OPC_LWR;
5c13fdfd 12160 goto do_ld_lr;
3c824109
NF
12161 case SWR:
12162 mips32_op = OPC_SWR;
5c13fdfd 12163 goto do_st_lr;
3c824109
NF
12164#if defined(TARGET_MIPS64)
12165 case LDL:
12166 mips32_op = OPC_LDL;
5c13fdfd 12167 goto do_ld_lr;
3c824109
NF
12168 case SDL:
12169 mips32_op = OPC_SDL;
5c13fdfd 12170 goto do_st_lr;
3c824109
NF
12171 case LDR:
12172 mips32_op = OPC_LDR;
5c13fdfd 12173 goto do_ld_lr;
3c824109
NF
12174 case SDR:
12175 mips32_op = OPC_SDR;
5c13fdfd 12176 goto do_st_lr;
3c824109
NF
12177 case LWU:
12178 mips32_op = OPC_LWU;
5c13fdfd 12179 goto do_ld_lr;
3c824109
NF
12180 case LLD:
12181 mips32_op = OPC_LLD;
5c13fdfd 12182 goto do_ld_lr;
3c824109
NF
12183#endif
12184 case LL:
12185 mips32_op = OPC_LL;
5c13fdfd
AJ
12186 goto do_ld_lr;
12187 do_ld_lr:
afa88c3a 12188 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12189 break;
12190 do_st_lr:
12191 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12192 break;
12193 case SC:
12194 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12195 break;
12196#if defined(TARGET_MIPS64)
12197 case SCD:
12198 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12199 break;
12200#endif
12201 case PREF:
12202 /* Treat as no-op */
12203 break;
12204 default:
12205 MIPS_INVAL("pool32c");
12206 generate_exception(ctx, EXCP_RI);
12207 break;
12208 }
12209 break;
12210 case ADDI32:
12211 mips32_op = OPC_ADDI;
12212 goto do_addi;
12213 case ADDIU32:
12214 mips32_op = OPC_ADDIU;
12215 do_addi:
12216 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12217 break;
12218
12219 /* Logical operations */
12220 case ORI32:
12221 mips32_op = OPC_ORI;
12222 goto do_logici;
12223 case XORI32:
12224 mips32_op = OPC_XORI;
12225 goto do_logici;
12226 case ANDI32:
12227 mips32_op = OPC_ANDI;
12228 do_logici:
9fa77488 12229 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
3c824109
NF
12230 break;
12231
12232 /* Set less than immediate */
12233 case SLTI32:
12234 mips32_op = OPC_SLTI;
12235 goto do_slti;
12236 case SLTIU32:
12237 mips32_op = OPC_SLTIU;
12238 do_slti:
9fa77488 12239 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
3c824109
NF
12240 break;
12241 case JALX32:
12242 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12243 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12244 *is_branch = 1;
12245 break;
12246 case JALS32:
12247 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12248 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12249 *is_branch = 1;
12250 break;
12251 case BEQ32:
12252 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12253 *is_branch = 1;
12254 break;
12255 case BNE32:
12256 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12257 *is_branch = 1;
12258 break;
12259 case J32:
12260 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12261 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12262 *is_branch = 1;
12263 break;
12264 case JAL32:
12265 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12266 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12267 *is_branch = 1;
12268 break;
12269 /* Floating point (COP1) */
12270 case LWC132:
12271 mips32_op = OPC_LWC1;
12272 goto do_cop1;
12273 case LDC132:
12274 mips32_op = OPC_LDC1;
12275 goto do_cop1;
12276 case SWC132:
12277 mips32_op = OPC_SWC1;
12278 goto do_cop1;
12279 case SDC132:
12280 mips32_op = OPC_SDC1;
12281 do_cop1:
12282 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12283 break;
12284 case ADDIUPC:
12285 {
12286 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12287 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12288
12289 gen_addiupc(ctx, reg, offset, 0, 0);
12290 }
12291 break;
12292 /* Loads and stores */
12293 case LB32:
12294 mips32_op = OPC_LB;
5c13fdfd 12295 goto do_ld;
3c824109
NF
12296 case LBU32:
12297 mips32_op = OPC_LBU;
5c13fdfd 12298 goto do_ld;
3c824109
NF
12299 case LH32:
12300 mips32_op = OPC_LH;
5c13fdfd 12301 goto do_ld;
3c824109
NF
12302 case LHU32:
12303 mips32_op = OPC_LHU;
5c13fdfd 12304 goto do_ld;
3c824109
NF
12305 case LW32:
12306 mips32_op = OPC_LW;
5c13fdfd 12307 goto do_ld;
3c824109
NF
12308#ifdef TARGET_MIPS64
12309 case LD32:
12310 mips32_op = OPC_LD;
5c13fdfd 12311 goto do_ld;
3c824109
NF
12312 case SD32:
12313 mips32_op = OPC_SD;
5c13fdfd 12314 goto do_st;
3c824109
NF
12315#endif
12316 case SB32:
12317 mips32_op = OPC_SB;
5c13fdfd 12318 goto do_st;
3c824109
NF
12319 case SH32:
12320 mips32_op = OPC_SH;
5c13fdfd 12321 goto do_st;
3c824109
NF
12322 case SW32:
12323 mips32_op = OPC_SW;
5c13fdfd
AJ
12324 goto do_st;
12325 do_ld:
afa88c3a 12326 gen_ld(env, ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12327 break;
12328 do_st:
12329 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12330 break;
12331 default:
12332 generate_exception(ctx, EXCP_RI);
12333 break;
12334 }
12335}
12336
7db13fae 12337static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
12338{
12339 uint32_t op;
12340
12341 /* make sure instructions are on a halfword boundary */
12342 if (ctx->pc & 0x1) {
12343 env->CP0_BadVAddr = ctx->pc;
12344 generate_exception(ctx, EXCP_AdEL);
12345 ctx->bstate = BS_STOP;
12346 return 2;
12347 }
12348
12349 op = (ctx->opcode >> 10) & 0x3f;
12350 /* Enforce properly-sized instructions in a delay slot */
12351 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12352 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12353
12354 switch (op) {
12355 case POOL32A:
12356 case POOL32B:
12357 case POOL32I:
12358 case POOL32C:
12359 case ADDI32:
12360 case ADDIU32:
12361 case ORI32:
12362 case XORI32:
12363 case SLTI32:
12364 case SLTIU32:
12365 case ANDI32:
12366 case JALX32:
12367 case LBU32:
12368 case LHU32:
12369 case POOL32F:
12370 case JALS32:
12371 case BEQ32:
12372 case BNE32:
12373 case J32:
12374 case JAL32:
12375 case SB32:
12376 case SH32:
12377 case POOL32S:
12378 case ADDIUPC:
12379 case SWC132:
12380 case SDC132:
12381 case SD32:
12382 case SW32:
12383 case LB32:
12384 case LH32:
12385 case DADDIU32:
3c824109
NF
12386 case LWC132:
12387 case LDC132:
12388 case LD32:
12389 case LW32:
12390 if (bits & MIPS_HFLAG_BDS16) {
12391 generate_exception(ctx, EXCP_RI);
12392 /* Just stop translation; the user is confused. */
12393 ctx->bstate = BS_STOP;
12394 return 2;
12395 }
12396 break;
12397 case POOL16A:
12398 case POOL16B:
12399 case POOL16C:
12400 case LWGP16:
12401 case POOL16F:
12402 case LBU16:
12403 case LHU16:
12404 case LWSP16:
12405 case LW16:
12406 case SB16:
12407 case SH16:
12408 case SWSP16:
12409 case SW16:
12410 case MOVE16:
12411 case ANDI16:
12412 case POOL16D:
12413 case POOL16E:
12414 case BEQZ16:
12415 case BNEZ16:
12416 case B16:
12417 case LI16:
12418 if (bits & MIPS_HFLAG_BDS32) {
12419 generate_exception(ctx, EXCP_RI);
12420 /* Just stop translation; the user is confused. */
12421 ctx->bstate = BS_STOP;
12422 return 2;
12423 }
12424 break;
12425 default:
12426 break;
12427 }
12428 }
12429 switch (op) {
12430 case POOL16A:
12431 {
12432 int rd = mmreg(uMIPS_RD(ctx->opcode));
12433 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12434 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12435 uint32_t opc = 0;
12436
12437 switch (ctx->opcode & 0x1) {
12438 case ADDU16:
12439 opc = OPC_ADDU;
12440 break;
12441 case SUBU16:
12442 opc = OPC_SUBU;
12443 break;
12444 }
12445
12446 gen_arith(env, ctx, opc, rd, rs1, rs2);
12447 }
12448 break;
12449 case POOL16B:
12450 {
12451 int rd = mmreg(uMIPS_RD(ctx->opcode));
12452 int rs = mmreg(uMIPS_RS(ctx->opcode));
12453 int amount = (ctx->opcode >> 1) & 0x7;
12454 uint32_t opc = 0;
12455 amount = amount == 0 ? 8 : amount;
12456
12457 switch (ctx->opcode & 0x1) {
12458 case SLL16:
12459 opc = OPC_SLL;
12460 break;
12461 case SRL16:
12462 opc = OPC_SRL;
12463 break;
12464 }
12465
12466 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12467 }
12468 break;
12469 case POOL16C:
12470 gen_pool16c_insn(env, ctx, is_branch);
12471 break;
12472 case LWGP16:
12473 {
12474 int rd = mmreg(uMIPS_RD(ctx->opcode));
12475 int rb = 28; /* GP */
12476 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12477
afa88c3a 12478 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12479 }
12480 break;
12481 case POOL16F:
12482 if (ctx->opcode & 1) {
12483 generate_exception(ctx, EXCP_RI);
12484 } else {
12485 /* MOVEP */
12486 int enc_dest = uMIPS_RD(ctx->opcode);
12487 int enc_rt = uMIPS_RS2(ctx->opcode);
12488 int enc_rs = uMIPS_RS1(ctx->opcode);
12489 int rd, rs, re, rt;
12490 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12491 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12492 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12493
12494 rd = rd_enc[enc_dest];
12495 re = re_enc[enc_dest];
12496 rs = rs_rt_enc[enc_rs];
12497 rt = rs_rt_enc[enc_rt];
12498
12499 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12500 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12501 }
12502 break;
12503 case LBU16:
12504 {
12505 int rd = mmreg(uMIPS_RD(ctx->opcode));
12506 int rb = mmreg(uMIPS_RS(ctx->opcode));
12507 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12508 offset = (offset == 0xf ? -1 : offset);
12509
afa88c3a 12510 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12511 }
12512 break;
12513 case LHU16:
12514 {
12515 int rd = mmreg(uMIPS_RD(ctx->opcode));
12516 int rb = mmreg(uMIPS_RS(ctx->opcode));
12517 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12518
afa88c3a 12519 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12520 }
12521 break;
12522 case LWSP16:
12523 {
12524 int rd = (ctx->opcode >> 5) & 0x1f;
12525 int rb = 29; /* SP */
12526 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12527
afa88c3a 12528 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12529 }
12530 break;
12531 case LW16:
12532 {
12533 int rd = mmreg(uMIPS_RD(ctx->opcode));
12534 int rb = mmreg(uMIPS_RS(ctx->opcode));
12535 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12536
afa88c3a 12537 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12538 }
12539 break;
12540 case SB16:
12541 {
12542 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12543 int rb = mmreg(uMIPS_RS(ctx->opcode));
12544 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12545
5c13fdfd 12546 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12547 }
12548 break;
12549 case SH16:
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) << 1;
12554
5c13fdfd 12555 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12556 }
12557 break;
12558 case SWSP16:
12559 {
12560 int rd = (ctx->opcode >> 5) & 0x1f;
12561 int rb = 29; /* SP */
12562 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12563
5c13fdfd 12564 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12565 }
12566 break;
12567 case SW16:
12568 {
12569 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12570 int rb = mmreg(uMIPS_RS(ctx->opcode));
12571 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12572
5c13fdfd 12573 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12574 }
12575 break;
12576 case MOVE16:
12577 {
12578 int rd = uMIPS_RD5(ctx->opcode);
12579 int rs = uMIPS_RS5(ctx->opcode);
12580
12581 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12582 }
12583 break;
12584 case ANDI16:
12585 gen_andi16(env, ctx);
12586 break;
12587 case POOL16D:
12588 switch (ctx->opcode & 0x1) {
12589 case ADDIUS5:
12590 gen_addius5(env, ctx);
12591 break;
12592 case ADDIUSP:
12593 gen_addiusp(env, ctx);
12594 break;
12595 }
12596 break;
12597 case POOL16E:
12598 switch (ctx->opcode & 0x1) {
12599 case ADDIUR2:
12600 gen_addiur2(env, ctx);
12601 break;
12602 case ADDIUR1SP:
12603 gen_addiur1sp(env, ctx);
12604 break;
12605 }
12606 break;
12607 case B16:
12608 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12609 SIMM(ctx->opcode, 0, 10) << 1);
12610 *is_branch = 1;
12611 break;
12612 case BNEZ16:
12613 case BEQZ16:
12614 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12615 mmreg(uMIPS_RD(ctx->opcode)),
12616 0, SIMM(ctx->opcode, 0, 7) << 1);
12617 *is_branch = 1;
12618 break;
12619 case LI16:
12620 {
12621 int reg = mmreg(uMIPS_RD(ctx->opcode));
12622 int imm = ZIMM(ctx->opcode, 0, 7);
12623
12624 imm = (imm == 0x7f ? -1 : imm);
12625 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12626 }
12627 break;
12628 case RES_20:
12629 case RES_28:
12630 case RES_29:
12631 case RES_30:
12632 case RES_31:
12633 case RES_38:
12634 case RES_39:
12635 generate_exception(ctx, EXCP_RI);
12636 break;
12637 default:
12638 decode_micromips32_opc (env, ctx, op, is_branch);
12639 return 4;
12640 }
12641
12642 return 2;
12643}
12644
12645/* SmartMIPS extension to MIPS32 */
12646
12647#if defined(TARGET_MIPS64)
12648
12649/* MDMX extension to MIPS64 */
12650
12651#endif
12652
9b1a1d68
JL
12653/* MIPSDSP functions. */
12654static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12655 int rd, int base, int offset)
12656{
12657 const char *opn = "ldx";
12658 TCGv t0;
12659
12660 if (rd == 0) {
12661 MIPS_DEBUG("NOP");
12662 return;
12663 }
12664
12665 check_dsp(ctx);
12666 t0 = tcg_temp_new();
12667
12668 if (base == 0) {
12669 gen_load_gpr(t0, offset);
12670 } else if (offset == 0) {
12671 gen_load_gpr(t0, base);
12672 } else {
12673 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12674 }
12675
9b1a1d68
JL
12676 switch (opc) {
12677 case OPC_LBUX:
2910c6cb 12678 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12679 gen_store_gpr(t0, rd);
12680 opn = "lbux";
12681 break;
12682 case OPC_LHX:
2910c6cb 12683 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12684 gen_store_gpr(t0, rd);
12685 opn = "lhx";
12686 break;
12687 case OPC_LWX:
2910c6cb 12688 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12689 gen_store_gpr(t0, rd);
12690 opn = "lwx";
12691 break;
12692#if defined(TARGET_MIPS64)
12693 case OPC_LDX:
2910c6cb 12694 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
9b1a1d68
JL
12695 gen_store_gpr(t0, rd);
12696 opn = "ldx";
12697 break;
12698#endif
12699 }
12700 (void)opn; /* avoid a compiler warning */
12701 MIPS_DEBUG("%s %s, %s(%s)", opn,
12702 regnames[rd], regnames[offset], regnames[base]);
12703 tcg_temp_free(t0);
12704}
12705
461c08df
JL
12706static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12707 int ret, int v1, int v2)
12708{
12709 const char *opn = "mipsdsp arith";
12710 TCGv v1_t;
12711 TCGv v2_t;
12712
12713 if (ret == 0) {
12714 /* Treat as NOP. */
12715 MIPS_DEBUG("NOP");
12716 return;
12717 }
12718
12719 v1_t = tcg_temp_new();
12720 v2_t = tcg_temp_new();
12721
12722 gen_load_gpr(v1_t, v1);
12723 gen_load_gpr(v2_t, v2);
12724
12725 switch (op1) {
12726 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12727 case OPC_MULT_G_2E:
12728 check_dspr2(ctx);
12729 switch (op2) {
12730 case OPC_ADDUH_QB:
12731 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12732 break;
12733 case OPC_ADDUH_R_QB:
12734 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12735 break;
12736 case OPC_ADDQH_PH:
12737 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12738 break;
12739 case OPC_ADDQH_R_PH:
12740 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12741 break;
12742 case OPC_ADDQH_W:
12743 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12744 break;
12745 case OPC_ADDQH_R_W:
12746 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12747 break;
12748 case OPC_SUBUH_QB:
12749 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12750 break;
12751 case OPC_SUBUH_R_QB:
12752 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12753 break;
12754 case OPC_SUBQH_PH:
12755 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12756 break;
12757 case OPC_SUBQH_R_PH:
12758 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12759 break;
12760 case OPC_SUBQH_W:
12761 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12762 break;
12763 case OPC_SUBQH_R_W:
12764 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12765 break;
12766 }
12767 break;
12768 case OPC_ABSQ_S_PH_DSP:
12769 switch (op2) {
12770 case OPC_ABSQ_S_QB:
12771 check_dspr2(ctx);
12772 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12773 break;
12774 case OPC_ABSQ_S_PH:
12775 check_dsp(ctx);
12776 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12777 break;
12778 case OPC_ABSQ_S_W:
12779 check_dsp(ctx);
12780 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12781 break;
12782 case OPC_PRECEQ_W_PHL:
12783 check_dsp(ctx);
12784 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12785 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12786 break;
12787 case OPC_PRECEQ_W_PHR:
12788 check_dsp(ctx);
12789 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12790 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12791 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12792 break;
12793 case OPC_PRECEQU_PH_QBL:
12794 check_dsp(ctx);
12795 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12796 break;
12797 case OPC_PRECEQU_PH_QBR:
12798 check_dsp(ctx);
12799 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12800 break;
12801 case OPC_PRECEQU_PH_QBLA:
12802 check_dsp(ctx);
12803 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12804 break;
12805 case OPC_PRECEQU_PH_QBRA:
12806 check_dsp(ctx);
12807 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12808 break;
12809 case OPC_PRECEU_PH_QBL:
12810 check_dsp(ctx);
12811 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12812 break;
12813 case OPC_PRECEU_PH_QBR:
12814 check_dsp(ctx);
12815 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12816 break;
12817 case OPC_PRECEU_PH_QBLA:
12818 check_dsp(ctx);
12819 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12820 break;
12821 case OPC_PRECEU_PH_QBRA:
12822 check_dsp(ctx);
12823 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12824 break;
12825 }
12826 break;
12827 case OPC_ADDU_QB_DSP:
12828 switch (op2) {
12829 case OPC_ADDQ_PH:
12830 check_dsp(ctx);
12831 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12832 break;
12833 case OPC_ADDQ_S_PH:
12834 check_dsp(ctx);
12835 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12836 break;
12837 case OPC_ADDQ_S_W:
12838 check_dsp(ctx);
12839 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12840 break;
12841 case OPC_ADDU_QB:
12842 check_dsp(ctx);
12843 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12844 break;
12845 case OPC_ADDU_S_QB:
12846 check_dsp(ctx);
12847 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12848 break;
12849 case OPC_ADDU_PH:
12850 check_dspr2(ctx);
12851 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12852 break;
12853 case OPC_ADDU_S_PH:
12854 check_dspr2(ctx);
12855 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12856 break;
12857 case OPC_SUBQ_PH:
12858 check_dsp(ctx);
12859 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12860 break;
12861 case OPC_SUBQ_S_PH:
12862 check_dsp(ctx);
12863 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12864 break;
12865 case OPC_SUBQ_S_W:
12866 check_dsp(ctx);
12867 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12868 break;
12869 case OPC_SUBU_QB:
12870 check_dsp(ctx);
12871 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12872 break;
12873 case OPC_SUBU_S_QB:
12874 check_dsp(ctx);
12875 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12876 break;
12877 case OPC_SUBU_PH:
12878 check_dspr2(ctx);
12879 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12880 break;
12881 case OPC_SUBU_S_PH:
12882 check_dspr2(ctx);
12883 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12884 break;
12885 case OPC_ADDSC:
12886 check_dsp(ctx);
12887 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12888 break;
12889 case OPC_ADDWC:
12890 check_dsp(ctx);
12891 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12892 break;
12893 case OPC_MODSUB:
12894 check_dsp(ctx);
12895 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12896 break;
12897 case OPC_RADDU_W_QB:
12898 check_dsp(ctx);
12899 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12900 break;
12901 }
12902 break;
12903 case OPC_CMPU_EQ_QB_DSP:
12904 switch (op2) {
12905 case OPC_PRECR_QB_PH:
12906 check_dspr2(ctx);
12907 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12908 break;
12909 case OPC_PRECRQ_QB_PH:
12910 check_dsp(ctx);
12911 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12912 break;
12913 case OPC_PRECR_SRA_PH_W:
12914 check_dspr2(ctx);
12915 {
12916 TCGv_i32 sa_t = tcg_const_i32(v2);
12917 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12918 cpu_gpr[ret]);
12919 tcg_temp_free_i32(sa_t);
12920 break;
12921 }
12922 case OPC_PRECR_SRA_R_PH_W:
12923 check_dspr2(ctx);
12924 {
12925 TCGv_i32 sa_t = tcg_const_i32(v2);
12926 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12927 cpu_gpr[ret]);
12928 tcg_temp_free_i32(sa_t);
12929 break;
12930 }
12931 case OPC_PRECRQ_PH_W:
12932 check_dsp(ctx);
12933 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12934 break;
12935 case OPC_PRECRQ_RS_PH_W:
12936 check_dsp(ctx);
12937 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12938 break;
12939 case OPC_PRECRQU_S_QB_PH:
12940 check_dsp(ctx);
12941 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12942 break;
12943 }
12944 break;
12945#ifdef TARGET_MIPS64
12946 case OPC_ABSQ_S_QH_DSP:
12947 switch (op2) {
12948 case OPC_PRECEQ_L_PWL:
12949 check_dsp(ctx);
12950 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12951 break;
12952 case OPC_PRECEQ_L_PWR:
12953 check_dsp(ctx);
12954 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12955 break;
12956 case OPC_PRECEQ_PW_QHL:
12957 check_dsp(ctx);
12958 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12959 break;
12960 case OPC_PRECEQ_PW_QHR:
12961 check_dsp(ctx);
12962 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12963 break;
12964 case OPC_PRECEQ_PW_QHLA:
12965 check_dsp(ctx);
12966 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12967 break;
12968 case OPC_PRECEQ_PW_QHRA:
12969 check_dsp(ctx);
12970 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12971 break;
12972 case OPC_PRECEQU_QH_OBL:
12973 check_dsp(ctx);
12974 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12975 break;
12976 case OPC_PRECEQU_QH_OBR:
12977 check_dsp(ctx);
12978 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12979 break;
12980 case OPC_PRECEQU_QH_OBLA:
12981 check_dsp(ctx);
12982 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12983 break;
12984 case OPC_PRECEQU_QH_OBRA:
12985 check_dsp(ctx);
12986 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12987 break;
12988 case OPC_PRECEU_QH_OBL:
12989 check_dsp(ctx);
12990 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12991 break;
12992 case OPC_PRECEU_QH_OBR:
12993 check_dsp(ctx);
12994 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12995 break;
12996 case OPC_PRECEU_QH_OBLA:
12997 check_dsp(ctx);
12998 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12999 break;
13000 case OPC_PRECEU_QH_OBRA:
13001 check_dsp(ctx);
13002 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13003 break;
13004 case OPC_ABSQ_S_OB:
13005 check_dspr2(ctx);
13006 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13007 break;
13008 case OPC_ABSQ_S_PW:
13009 check_dsp(ctx);
13010 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13011 break;
13012 case OPC_ABSQ_S_QH:
13013 check_dsp(ctx);
13014 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13015 break;
13016 }
13017 break;
13018 case OPC_ADDU_OB_DSP:
13019 switch (op2) {
13020 case OPC_RADDU_L_OB:
13021 check_dsp(ctx);
13022 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13023 break;
13024 case OPC_SUBQ_PW:
13025 check_dsp(ctx);
13026 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13027 break;
13028 case OPC_SUBQ_S_PW:
13029 check_dsp(ctx);
13030 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13031 break;
13032 case OPC_SUBQ_QH:
13033 check_dsp(ctx);
13034 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13035 break;
13036 case OPC_SUBQ_S_QH:
13037 check_dsp(ctx);
13038 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13039 break;
13040 case OPC_SUBU_OB:
13041 check_dsp(ctx);
13042 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13043 break;
13044 case OPC_SUBU_S_OB:
13045 check_dsp(ctx);
13046 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13047 break;
13048 case OPC_SUBU_QH:
13049 check_dspr2(ctx);
13050 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13051 break;
13052 case OPC_SUBU_S_QH:
13053 check_dspr2(ctx);
13054 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13055 break;
13056 case OPC_SUBUH_OB:
13057 check_dspr2(ctx);
13058 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13059 break;
13060 case OPC_SUBUH_R_OB:
13061 check_dspr2(ctx);
13062 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13063 break;
13064 case OPC_ADDQ_PW:
13065 check_dsp(ctx);
13066 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13067 break;
13068 case OPC_ADDQ_S_PW:
13069 check_dsp(ctx);
13070 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13071 break;
13072 case OPC_ADDQ_QH:
13073 check_dsp(ctx);
13074 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13075 break;
13076 case OPC_ADDQ_S_QH:
13077 check_dsp(ctx);
13078 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13079 break;
13080 case OPC_ADDU_OB:
13081 check_dsp(ctx);
13082 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13083 break;
13084 case OPC_ADDU_S_OB:
13085 check_dsp(ctx);
13086 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13087 break;
13088 case OPC_ADDU_QH:
13089 check_dspr2(ctx);
13090 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13091 break;
13092 case OPC_ADDU_S_QH:
13093 check_dspr2(ctx);
13094 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13095 break;
13096 case OPC_ADDUH_OB:
13097 check_dspr2(ctx);
13098 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13099 break;
13100 case OPC_ADDUH_R_OB:
13101 check_dspr2(ctx);
13102 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13103 break;
13104 }
13105 break;
13106 case OPC_CMPU_EQ_OB_DSP:
13107 switch (op2) {
13108 case OPC_PRECR_OB_QH:
13109 check_dspr2(ctx);
13110 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13111 break;
13112 case OPC_PRECR_SRA_QH_PW:
13113 check_dspr2(ctx);
13114 {
13115 TCGv_i32 ret_t = tcg_const_i32(ret);
13116 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13117 tcg_temp_free_i32(ret_t);
13118 break;
13119 }
13120 case OPC_PRECR_SRA_R_QH_PW:
13121 check_dspr2(ctx);
13122 {
13123 TCGv_i32 sa_v = tcg_const_i32(ret);
13124 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13125 tcg_temp_free_i32(sa_v);
13126 break;
13127 }
13128 case OPC_PRECRQ_OB_QH:
13129 check_dsp(ctx);
13130 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13131 break;
13132 case OPC_PRECRQ_PW_L:
13133 check_dsp(ctx);
13134 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13135 break;
13136 case OPC_PRECRQ_QH_PW:
13137 check_dsp(ctx);
13138 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13139 break;
13140 case OPC_PRECRQ_RS_QH_PW:
13141 check_dsp(ctx);
13142 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13143 break;
13144 case OPC_PRECRQU_S_OB_QH:
13145 check_dsp(ctx);
13146 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13147 break;
13148 }
13149 break;
13150#endif
13151 }
13152
13153 tcg_temp_free(v1_t);
13154 tcg_temp_free(v2_t);
13155
13156 (void)opn; /* avoid a compiler warning */
13157 MIPS_DEBUG("%s", opn);
13158}
9b1a1d68 13159
77c5fa8b
JL
13160static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13161 int ret, int v1, int v2)
13162{
13163 uint32_t op2;
13164 const char *opn = "mipsdsp shift";
13165 TCGv t0;
13166 TCGv v1_t;
13167 TCGv v2_t;
13168
13169 if (ret == 0) {
13170 /* Treat as NOP. */
13171 MIPS_DEBUG("NOP");
13172 return;
13173 }
13174
13175 t0 = tcg_temp_new();
13176 v1_t = tcg_temp_new();
13177 v2_t = tcg_temp_new();
13178
13179 tcg_gen_movi_tl(t0, v1);
13180 gen_load_gpr(v1_t, v1);
13181 gen_load_gpr(v2_t, v2);
13182
13183 switch (opc) {
13184 case OPC_SHLL_QB_DSP:
13185 {
13186 op2 = MASK_SHLL_QB(ctx->opcode);
13187 switch (op2) {
13188 case OPC_SHLL_QB:
13189 check_dsp(ctx);
13190 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13191 break;
13192 case OPC_SHLLV_QB:
13193 check_dsp(ctx);
13194 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13195 break;
13196 case OPC_SHLL_PH:
13197 check_dsp(ctx);
13198 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13199 break;
13200 case OPC_SHLLV_PH:
13201 check_dsp(ctx);
13202 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13203 break;
13204 case OPC_SHLL_S_PH:
13205 check_dsp(ctx);
13206 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13207 break;
13208 case OPC_SHLLV_S_PH:
13209 check_dsp(ctx);
13210 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13211 break;
13212 case OPC_SHLL_S_W:
13213 check_dsp(ctx);
13214 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13215 break;
13216 case OPC_SHLLV_S_W:
13217 check_dsp(ctx);
13218 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13219 break;
13220 case OPC_SHRL_QB:
13221 check_dsp(ctx);
13222 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13223 break;
13224 case OPC_SHRLV_QB:
13225 check_dsp(ctx);
13226 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13227 break;
13228 case OPC_SHRL_PH:
13229 check_dspr2(ctx);
13230 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13231 break;
13232 case OPC_SHRLV_PH:
13233 check_dspr2(ctx);
13234 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13235 break;
13236 case OPC_SHRA_QB:
13237 check_dspr2(ctx);
13238 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13239 break;
13240 case OPC_SHRA_R_QB:
13241 check_dspr2(ctx);
13242 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13243 break;
13244 case OPC_SHRAV_QB:
13245 check_dspr2(ctx);
13246 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13247 break;
13248 case OPC_SHRAV_R_QB:
13249 check_dspr2(ctx);
13250 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13251 break;
13252 case OPC_SHRA_PH:
13253 check_dsp(ctx);
13254 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13255 break;
13256 case OPC_SHRA_R_PH:
13257 check_dsp(ctx);
13258 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13259 break;
13260 case OPC_SHRAV_PH:
13261 check_dsp(ctx);
13262 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13263 break;
13264 case OPC_SHRAV_R_PH:
13265 check_dsp(ctx);
13266 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13267 break;
13268 case OPC_SHRA_R_W:
13269 check_dsp(ctx);
13270 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13271 break;
13272 case OPC_SHRAV_R_W:
13273 check_dsp(ctx);
13274 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13275 break;
13276 default: /* Invalid */
13277 MIPS_INVAL("MASK SHLL.QB");
13278 generate_exception(ctx, EXCP_RI);
13279 break;
13280 }
13281 break;
13282 }
13283#ifdef TARGET_MIPS64
13284 case OPC_SHLL_OB_DSP:
13285 op2 = MASK_SHLL_OB(ctx->opcode);
13286 switch (op2) {
13287 case OPC_SHLL_PW:
13288 check_dsp(ctx);
13289 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13290 break;
13291 case OPC_SHLLV_PW:
13292 check_dsp(ctx);
13293 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13294 break;
13295 case OPC_SHLL_S_PW:
13296 check_dsp(ctx);
13297 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13298 break;
13299 case OPC_SHLLV_S_PW:
13300 check_dsp(ctx);
13301 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13302 break;
13303 case OPC_SHLL_OB:
13304 check_dsp(ctx);
13305 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13306 break;
13307 case OPC_SHLLV_OB:
13308 check_dsp(ctx);
13309 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13310 break;
13311 case OPC_SHLL_QH:
13312 check_dsp(ctx);
13313 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13314 break;
13315 case OPC_SHLLV_QH:
13316 check_dsp(ctx);
13317 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13318 break;
13319 case OPC_SHLL_S_QH:
13320 check_dsp(ctx);
13321 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13322 break;
13323 case OPC_SHLLV_S_QH:
13324 check_dsp(ctx);
13325 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13326 break;
13327 case OPC_SHRA_OB:
13328 check_dspr2(ctx);
13329 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13330 break;
13331 case OPC_SHRAV_OB:
13332 check_dspr2(ctx);
13333 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13334 break;
13335 case OPC_SHRA_R_OB:
13336 check_dspr2(ctx);
13337 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13338 break;
13339 case OPC_SHRAV_R_OB:
13340 check_dspr2(ctx);
13341 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13342 break;
13343 case OPC_SHRA_PW:
13344 check_dsp(ctx);
13345 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13346 break;
13347 case OPC_SHRAV_PW:
13348 check_dsp(ctx);
13349 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13350 break;
13351 case OPC_SHRA_R_PW:
13352 check_dsp(ctx);
13353 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13354 break;
13355 case OPC_SHRAV_R_PW:
13356 check_dsp(ctx);
13357 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13358 break;
13359 case OPC_SHRA_QH:
13360 check_dsp(ctx);
13361 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13362 break;
13363 case OPC_SHRAV_QH:
13364 check_dsp(ctx);
13365 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13366 break;
13367 case OPC_SHRA_R_QH:
13368 check_dsp(ctx);
13369 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13370 break;
13371 case OPC_SHRAV_R_QH:
13372 check_dsp(ctx);
13373 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13374 break;
13375 case OPC_SHRL_OB:
13376 check_dsp(ctx);
13377 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13378 break;
13379 case OPC_SHRLV_OB:
13380 check_dsp(ctx);
13381 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13382 break;
13383 case OPC_SHRL_QH:
13384 check_dspr2(ctx);
13385 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13386 break;
13387 case OPC_SHRLV_QH:
13388 check_dspr2(ctx);
13389 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13390 break;
13391 default: /* Invalid */
13392 MIPS_INVAL("MASK SHLL.OB");
13393 generate_exception(ctx, EXCP_RI);
13394 break;
13395 }
13396 break;
13397#endif
13398 }
13399
13400 tcg_temp_free(t0);
13401 tcg_temp_free(v1_t);
13402 tcg_temp_free(v2_t);
13403 (void)opn; /* avoid a compiler warning */
13404 MIPS_DEBUG("%s", opn);
13405}
13406
a22260ae
JL
13407static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13408 int ret, int v1, int v2, int check_ret)
13409{
13410 const char *opn = "mipsdsp multiply";
13411 TCGv_i32 t0;
13412 TCGv v1_t;
13413 TCGv v2_t;
13414
13415 if ((ret == 0) && (check_ret == 1)) {
13416 /* Treat as NOP. */
13417 MIPS_DEBUG("NOP");
13418 return;
13419 }
13420
13421 t0 = tcg_temp_new_i32();
13422 v1_t = tcg_temp_new();
13423 v2_t = tcg_temp_new();
13424
13425 tcg_gen_movi_i32(t0, ret);
13426 gen_load_gpr(v1_t, v1);
13427 gen_load_gpr(v2_t, v2);
13428
13429 switch (op1) {
13430 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13431 * the same mask and op1. */
13432 case OPC_MULT_G_2E:
13433 switch (op2) {
13434 case OPC_MUL_PH:
13435 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13436 break;
13437 case OPC_MUL_S_PH:
13438 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13439 break;
13440 case OPC_MULQ_S_W:
13441 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13442 break;
13443 case OPC_MULQ_RS_W:
13444 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13445 break;
13446 }
13447 break;
13448 case OPC_DPA_W_PH_DSP:
13449 switch (op2) {
13450 case OPC_DPAU_H_QBL:
13451 check_dsp(ctx);
13452 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13453 break;
13454 case OPC_DPAU_H_QBR:
13455 check_dsp(ctx);
13456 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13457 break;
13458 case OPC_DPSU_H_QBL:
13459 check_dsp(ctx);
13460 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13461 break;
13462 case OPC_DPSU_H_QBR:
13463 check_dsp(ctx);
13464 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13465 break;
13466 case OPC_DPA_W_PH:
13467 check_dspr2(ctx);
13468 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13469 break;
13470 case OPC_DPAX_W_PH:
13471 check_dspr2(ctx);
13472 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13473 break;
13474 case OPC_DPAQ_S_W_PH:
13475 check_dsp(ctx);
13476 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13477 break;
13478 case OPC_DPAQX_S_W_PH:
13479 check_dspr2(ctx);
13480 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13481 break;
13482 case OPC_DPAQX_SA_W_PH:
13483 check_dspr2(ctx);
13484 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13485 break;
13486 case OPC_DPS_W_PH:
13487 check_dspr2(ctx);
13488 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13489 break;
13490 case OPC_DPSX_W_PH:
13491 check_dspr2(ctx);
13492 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13493 break;
13494 case OPC_DPSQ_S_W_PH:
13495 check_dsp(ctx);
13496 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13497 break;
13498 case OPC_DPSQX_S_W_PH:
13499 check_dspr2(ctx);
13500 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13501 break;
13502 case OPC_DPSQX_SA_W_PH:
13503 check_dspr2(ctx);
13504 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13505 break;
13506 case OPC_MULSAQ_S_W_PH:
13507 check_dsp(ctx);
13508 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13509 break;
13510 case OPC_DPAQ_SA_L_W:
13511 check_dsp(ctx);
13512 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13513 break;
13514 case OPC_DPSQ_SA_L_W:
13515 check_dsp(ctx);
13516 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13517 break;
13518 case OPC_MAQ_S_W_PHL:
13519 check_dsp(ctx);
13520 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13521 break;
13522 case OPC_MAQ_S_W_PHR:
13523 check_dsp(ctx);
13524 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13525 break;
13526 case OPC_MAQ_SA_W_PHL:
13527 check_dsp(ctx);
13528 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13529 break;
13530 case OPC_MAQ_SA_W_PHR:
13531 check_dsp(ctx);
13532 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13533 break;
13534 case OPC_MULSA_W_PH:
13535 check_dspr2(ctx);
13536 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13537 break;
13538 }
13539 break;
13540#ifdef TARGET_MIPS64
13541 case OPC_DPAQ_W_QH_DSP:
13542 {
13543 int ac = ret & 0x03;
13544 tcg_gen_movi_i32(t0, ac);
13545
13546 switch (op2) {
13547 case OPC_DMADD:
13548 check_dsp(ctx);
13549 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13550 break;
13551 case OPC_DMADDU:
13552 check_dsp(ctx);
13553 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13554 break;
13555 case OPC_DMSUB:
13556 check_dsp(ctx);
13557 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13558 break;
13559 case OPC_DMSUBU:
13560 check_dsp(ctx);
13561 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13562 break;
13563 case OPC_DPA_W_QH:
13564 check_dspr2(ctx);
13565 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13566 break;
13567 case OPC_DPAQ_S_W_QH:
13568 check_dsp(ctx);
13569 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13570 break;
13571 case OPC_DPAQ_SA_L_PW:
13572 check_dsp(ctx);
13573 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13574 break;
13575 case OPC_DPAU_H_OBL:
13576 check_dsp(ctx);
13577 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13578 break;
13579 case OPC_DPAU_H_OBR:
13580 check_dsp(ctx);
13581 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13582 break;
13583 case OPC_DPS_W_QH:
13584 check_dspr2(ctx);
13585 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13586 break;
13587 case OPC_DPSQ_S_W_QH:
13588 check_dsp(ctx);
13589 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13590 break;
13591 case OPC_DPSQ_SA_L_PW:
13592 check_dsp(ctx);
13593 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13594 break;
13595 case OPC_DPSU_H_OBL:
13596 check_dsp(ctx);
13597 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13598 break;
13599 case OPC_DPSU_H_OBR:
13600 check_dsp(ctx);
13601 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13602 break;
13603 case OPC_MAQ_S_L_PWL:
13604 check_dsp(ctx);
13605 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13606 break;
13607 case OPC_MAQ_S_L_PWR:
13608 check_dsp(ctx);
13609 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13610 break;
13611 case OPC_MAQ_S_W_QHLL:
13612 check_dsp(ctx);
13613 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13614 break;
13615 case OPC_MAQ_SA_W_QHLL:
13616 check_dsp(ctx);
13617 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13618 break;
13619 case OPC_MAQ_S_W_QHLR:
13620 check_dsp(ctx);
13621 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13622 break;
13623 case OPC_MAQ_SA_W_QHLR:
13624 check_dsp(ctx);
13625 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13626 break;
13627 case OPC_MAQ_S_W_QHRL:
13628 check_dsp(ctx);
13629 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13630 break;
13631 case OPC_MAQ_SA_W_QHRL:
13632 check_dsp(ctx);
13633 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13634 break;
13635 case OPC_MAQ_S_W_QHRR:
13636 check_dsp(ctx);
13637 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13638 break;
13639 case OPC_MAQ_SA_W_QHRR:
13640 check_dsp(ctx);
13641 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13642 break;
13643 case OPC_MULSAQ_S_L_PW:
13644 check_dsp(ctx);
13645 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13646 break;
13647 case OPC_MULSAQ_S_W_QH:
13648 check_dsp(ctx);
13649 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13650 break;
13651 }
13652 }
13653 break;
13654#endif
13655 case OPC_ADDU_QB_DSP:
13656 switch (op2) {
13657 case OPC_MULEU_S_PH_QBL:
13658 check_dsp(ctx);
13659 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13660 break;
13661 case OPC_MULEU_S_PH_QBR:
13662 check_dsp(ctx);
13663 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13664 break;
13665 case OPC_MULQ_RS_PH:
13666 check_dsp(ctx);
13667 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 break;
13669 case OPC_MULEQ_S_W_PHL:
13670 check_dsp(ctx);
13671 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 break;
13673 case OPC_MULEQ_S_W_PHR:
13674 check_dsp(ctx);
13675 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 break;
13677 case OPC_MULQ_S_PH:
13678 check_dspr2(ctx);
13679 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13680 break;
13681 }
13682 break;
13683#ifdef TARGET_MIPS64
13684 case OPC_ADDU_OB_DSP:
13685 switch (op2) {
13686 case OPC_MULEQ_S_PW_QHL:
13687 check_dsp(ctx);
13688 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13689 break;
13690 case OPC_MULEQ_S_PW_QHR:
13691 check_dsp(ctx);
13692 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13693 break;
13694 case OPC_MULEU_S_QH_OBL:
13695 check_dsp(ctx);
13696 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13697 break;
13698 case OPC_MULEU_S_QH_OBR:
13699 check_dsp(ctx);
13700 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13701 break;
13702 case OPC_MULQ_RS_QH:
13703 check_dsp(ctx);
13704 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13705 break;
13706 }
13707 break;
13708#endif
13709 }
13710
13711 tcg_temp_free_i32(t0);
13712 tcg_temp_free(v1_t);
13713 tcg_temp_free(v2_t);
13714
13715 (void)opn; /* avoid a compiler warning */
13716 MIPS_DEBUG("%s", opn);
13717
13718}
13719
1cb6686c
JL
13720static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13721 uint32_t op1, uint32_t op2,
13722 int ret, int val)
13723{
13724 const char *opn = "mipsdsp Bit/ Manipulation";
13725 int16_t imm;
13726 TCGv t0;
13727 TCGv val_t;
13728
13729 if (ret == 0) {
13730 /* Treat as NOP. */
13731 MIPS_DEBUG("NOP");
13732 return;
13733 }
13734
13735 t0 = tcg_temp_new();
13736 val_t = tcg_temp_new();
13737 gen_load_gpr(val_t, val);
13738
13739 switch (op1) {
13740 case OPC_ABSQ_S_PH_DSP:
13741 switch (op2) {
13742 case OPC_BITREV:
13743 check_dsp(ctx);
13744 gen_helper_bitrev(cpu_gpr[ret], val_t);
13745 break;
13746 case OPC_REPL_QB:
13747 check_dsp(ctx);
13748 {
13749 target_long result;
13750 imm = (ctx->opcode >> 16) & 0xFF;
13751 result = (uint32_t)imm << 24 |
13752 (uint32_t)imm << 16 |
13753 (uint32_t)imm << 8 |
13754 (uint32_t)imm;
13755 result = (int32_t)result;
13756 tcg_gen_movi_tl(cpu_gpr[ret], result);
13757 }
13758 break;
13759 case OPC_REPLV_QB:
13760 check_dsp(ctx);
13761 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13762 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13763 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13764 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13765 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13766 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13767 break;
13768 case OPC_REPL_PH:
13769 check_dsp(ctx);
13770 {
13771 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13772 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13773 tcg_gen_movi_tl(cpu_gpr[ret], \
13774 (target_long)((int32_t)imm << 16 | \
c4aaba92 13775 (uint16_t)imm));
1cb6686c
JL
13776 }
13777 break;
13778 case OPC_REPLV_PH:
13779 check_dsp(ctx);
13780 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13781 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13782 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13783 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13784 break;
13785 }
13786 break;
13787#ifdef TARGET_MIPS64
13788 case OPC_ABSQ_S_QH_DSP:
13789 switch (op2) {
13790 case OPC_REPL_OB:
13791 check_dsp(ctx);
13792 {
13793 target_long temp;
13794
13795 imm = (ctx->opcode >> 16) & 0xFF;
13796 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13797 temp = (temp << 16) | temp;
13798 temp = (temp << 32) | temp;
13799 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13800 break;
13801 }
13802 case OPC_REPL_PW:
13803 check_dsp(ctx);
13804 {
13805 target_long temp;
13806
13807 imm = (ctx->opcode >> 16) & 0x03FF;
13808 imm = (int16_t)(imm << 6) >> 6;
13809 temp = ((target_long)imm << 32) \
13810 | ((target_long)imm & 0xFFFFFFFF);
13811 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13812 break;
13813 }
13814 case OPC_REPL_QH:
13815 check_dsp(ctx);
13816 {
13817 target_long temp;
13818
13819 imm = (ctx->opcode >> 16) & 0x03FF;
13820 imm = (int16_t)(imm << 6) >> 6;
13821
13822 temp = ((uint64_t)(uint16_t)imm << 48) |
13823 ((uint64_t)(uint16_t)imm << 32) |
13824 ((uint64_t)(uint16_t)imm << 16) |
13825 (uint64_t)(uint16_t)imm;
13826 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13827 break;
13828 }
13829 case OPC_REPLV_OB:
13830 check_dsp(ctx);
13831 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13832 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13833 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13834 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13835 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13836 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13837 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13838 break;
13839 case OPC_REPLV_PW:
13840 check_dsp(ctx);
13841 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13842 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13843 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13844 break;
13845 case OPC_REPLV_QH:
13846 check_dsp(ctx);
13847 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13848 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13849 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13850 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13851 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13852 break;
13853 }
13854 break;
13855#endif
13856 }
13857 tcg_temp_free(t0);
13858 tcg_temp_free(val_t);
13859
13860 (void)opn; /* avoid a compiler warning */
13861 MIPS_DEBUG("%s", opn);
13862}
13863
26690560
JL
13864static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13865 uint32_t op1, uint32_t op2,
13866 int ret, int v1, int v2, int check_ret)
13867{
13868 const char *opn = "mipsdsp add compare pick";
13869 TCGv_i32 t0;
13870 TCGv t1;
13871 TCGv v1_t;
13872 TCGv v2_t;
13873
13874 if ((ret == 0) && (check_ret == 1)) {
13875 /* Treat as NOP. */
13876 MIPS_DEBUG("NOP");
13877 return;
13878 }
13879
13880 t0 = tcg_temp_new_i32();
13881 t1 = tcg_temp_new();
13882 v1_t = tcg_temp_new();
13883 v2_t = tcg_temp_new();
13884
13885 gen_load_gpr(v1_t, v1);
13886 gen_load_gpr(v2_t, v2);
13887
13888 switch (op1) {
13889 case OPC_APPEND_DSP:
13890 switch (op2) {
13891 case OPC_APPEND:
13892 tcg_gen_movi_i32(t0, v2);
13893 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13894 break;
13895 case OPC_PREPEND:
13896 tcg_gen_movi_i32(t0, v2);
13897 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13898 break;
13899 case OPC_BALIGN:
13900 tcg_gen_movi_i32(t0, v2);
13901 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13902 break;
13903 default: /* Invid */
13904 MIPS_INVAL("MASK APPEND");
13905 generate_exception(ctx, EXCP_RI);
13906 break;
13907 }
13908 break;
13909 case OPC_CMPU_EQ_QB_DSP:
13910 switch (op2) {
13911 case OPC_CMPU_EQ_QB:
13912 check_dsp(ctx);
13913 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13914 break;
13915 case OPC_CMPU_LT_QB:
13916 check_dsp(ctx);
13917 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13918 break;
13919 case OPC_CMPU_LE_QB:
13920 check_dsp(ctx);
13921 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13922 break;
13923 case OPC_CMPGU_EQ_QB:
13924 check_dsp(ctx);
13925 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13926 break;
13927 case OPC_CMPGU_LT_QB:
13928 check_dsp(ctx);
13929 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13930 break;
13931 case OPC_CMPGU_LE_QB:
13932 check_dsp(ctx);
13933 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13934 break;
13935 case OPC_CMPGDU_EQ_QB:
13936 check_dspr2(ctx);
13937 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13938 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13939 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13940 tcg_gen_shli_tl(t1, t1, 24);
13941 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13942 break;
13943 case OPC_CMPGDU_LT_QB:
13944 check_dspr2(ctx);
13945 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13946 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13947 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13948 tcg_gen_shli_tl(t1, t1, 24);
13949 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13950 break;
13951 case OPC_CMPGDU_LE_QB:
13952 check_dspr2(ctx);
13953 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13954 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13955 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13956 tcg_gen_shli_tl(t1, t1, 24);
13957 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13958 break;
13959 case OPC_CMP_EQ_PH:
13960 check_dsp(ctx);
13961 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13962 break;
13963 case OPC_CMP_LT_PH:
13964 check_dsp(ctx);
13965 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13966 break;
13967 case OPC_CMP_LE_PH:
13968 check_dsp(ctx);
13969 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13970 break;
13971 case OPC_PICK_QB:
13972 check_dsp(ctx);
13973 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13974 break;
13975 case OPC_PICK_PH:
13976 check_dsp(ctx);
13977 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13978 break;
13979 case OPC_PACKRL_PH:
13980 check_dsp(ctx);
13981 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13982 break;
13983 }
13984 break;
13985#ifdef TARGET_MIPS64
13986 case OPC_CMPU_EQ_OB_DSP:
13987 switch (op2) {
13988 case OPC_CMP_EQ_PW:
13989 check_dsp(ctx);
13990 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13991 break;
13992 case OPC_CMP_LT_PW:
13993 check_dsp(ctx);
13994 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13995 break;
13996 case OPC_CMP_LE_PW:
13997 check_dsp(ctx);
13998 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13999 break;
14000 case OPC_CMP_EQ_QH:
14001 check_dsp(ctx);
14002 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14003 break;
14004 case OPC_CMP_LT_QH:
14005 check_dsp(ctx);
14006 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14007 break;
14008 case OPC_CMP_LE_QH:
14009 check_dsp(ctx);
14010 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14011 break;
14012 case OPC_CMPGDU_EQ_OB:
14013 check_dspr2(ctx);
14014 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14015 break;
14016 case OPC_CMPGDU_LT_OB:
14017 check_dspr2(ctx);
14018 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14019 break;
14020 case OPC_CMPGDU_LE_OB:
14021 check_dspr2(ctx);
14022 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14023 break;
14024 case OPC_CMPGU_EQ_OB:
14025 check_dsp(ctx);
14026 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14027 break;
14028 case OPC_CMPGU_LT_OB:
14029 check_dsp(ctx);
14030 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14031 break;
14032 case OPC_CMPGU_LE_OB:
14033 check_dsp(ctx);
14034 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14035 break;
14036 case OPC_CMPU_EQ_OB:
14037 check_dsp(ctx);
14038 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14039 break;
14040 case OPC_CMPU_LT_OB:
14041 check_dsp(ctx);
14042 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14043 break;
14044 case OPC_CMPU_LE_OB:
14045 check_dsp(ctx);
14046 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14047 break;
14048 case OPC_PACKRL_PW:
14049 check_dsp(ctx);
14050 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14051 break;
14052 case OPC_PICK_OB:
14053 check_dsp(ctx);
14054 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14055 break;
14056 case OPC_PICK_PW:
14057 check_dsp(ctx);
14058 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14059 break;
14060 case OPC_PICK_QH:
14061 check_dsp(ctx);
14062 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14063 break;
14064 }
14065 break;
14066 case OPC_DAPPEND_DSP:
14067 switch (op2) {
14068 case OPC_DAPPEND:
14069 tcg_gen_movi_i32(t0, v2);
14070 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14071 break;
14072 case OPC_PREPENDD:
14073 tcg_gen_movi_i32(t0, v2);
14074 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14075 break;
14076 case OPC_PREPENDW:
14077 tcg_gen_movi_i32(t0, v2);
14078 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14079 break;
14080 case OPC_DBALIGN:
14081 tcg_gen_movi_i32(t0, v2);
14082 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14083 break;
14084 default: /* Invalid */
14085 MIPS_INVAL("MASK DAPPEND");
14086 generate_exception(ctx, EXCP_RI);
14087 break;
14088 }
14089 break;
14090#endif
14091 }
14092
14093 tcg_temp_free_i32(t0);
14094 tcg_temp_free(t1);
14095 tcg_temp_free(v1_t);
14096 tcg_temp_free(v2_t);
14097
14098 (void)opn; /* avoid a compiler warning */
14099 MIPS_DEBUG("%s", opn);
14100}
14101
b53371ed
JL
14102static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14103 int ret, int v1, int v2, int check_ret)
14104
14105{
14106 const char *opn = "mipsdsp accumulator";
14107 TCGv t0;
14108 TCGv t1;
14109 TCGv v1_t;
14110 TCGv v2_t;
14111 int16_t imm;
14112
14113 if ((ret == 0) && (check_ret == 1)) {
14114 /* Treat as NOP. */
14115 MIPS_DEBUG("NOP");
14116 return;
14117 }
14118
14119 t0 = tcg_temp_new();
14120 t1 = tcg_temp_new();
14121 v1_t = tcg_temp_new();
14122 v2_t = tcg_temp_new();
14123
14124 gen_load_gpr(v1_t, v1);
14125 gen_load_gpr(v2_t, v2);
14126
14127 switch (op1) {
14128 case OPC_EXTR_W_DSP:
14129 check_dsp(ctx);
14130 switch (op2) {
14131 case OPC_EXTR_W:
14132 tcg_gen_movi_tl(t0, v2);
14133 tcg_gen_movi_tl(t1, v1);
14134 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14135 break;
14136 case OPC_EXTR_R_W:
14137 tcg_gen_movi_tl(t0, v2);
14138 tcg_gen_movi_tl(t1, v1);
14139 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14140 break;
14141 case OPC_EXTR_RS_W:
14142 tcg_gen_movi_tl(t0, v2);
14143 tcg_gen_movi_tl(t1, v1);
14144 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14145 break;
14146 case OPC_EXTR_S_H:
14147 tcg_gen_movi_tl(t0, v2);
14148 tcg_gen_movi_tl(t1, v1);
14149 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14150 break;
14151 case OPC_EXTRV_S_H:
14152 tcg_gen_movi_tl(t0, v2);
14153 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14154 break;
14155 case OPC_EXTRV_W:
14156 tcg_gen_movi_tl(t0, v2);
14157 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14158 break;
14159 case OPC_EXTRV_R_W:
14160 tcg_gen_movi_tl(t0, v2);
14161 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14162 break;
14163 case OPC_EXTRV_RS_W:
14164 tcg_gen_movi_tl(t0, v2);
14165 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14166 break;
14167 case OPC_EXTP:
14168 tcg_gen_movi_tl(t0, v2);
14169 tcg_gen_movi_tl(t1, v1);
14170 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14171 break;
14172 case OPC_EXTPV:
14173 tcg_gen_movi_tl(t0, v2);
14174 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14175 break;
14176 case OPC_EXTPDP:
14177 tcg_gen_movi_tl(t0, v2);
14178 tcg_gen_movi_tl(t1, v1);
14179 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14180 break;
14181 case OPC_EXTPDPV:
14182 tcg_gen_movi_tl(t0, v2);
14183 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14184 break;
14185 case OPC_SHILO:
14186 imm = (ctx->opcode >> 20) & 0x3F;
14187 tcg_gen_movi_tl(t0, ret);
14188 tcg_gen_movi_tl(t1, imm);
14189 gen_helper_shilo(t0, t1, cpu_env);
14190 break;
14191 case OPC_SHILOV:
14192 tcg_gen_movi_tl(t0, ret);
14193 gen_helper_shilo(t0, v1_t, cpu_env);
14194 break;
14195 case OPC_MTHLIP:
14196 tcg_gen_movi_tl(t0, ret);
14197 gen_helper_mthlip(t0, v1_t, cpu_env);
14198 break;
14199 case OPC_WRDSP:
14200 imm = (ctx->opcode >> 11) & 0x3FF;
14201 tcg_gen_movi_tl(t0, imm);
14202 gen_helper_wrdsp(v1_t, t0, cpu_env);
14203 break;
14204 case OPC_RDDSP:
14205 imm = (ctx->opcode >> 16) & 0x03FF;
14206 tcg_gen_movi_tl(t0, imm);
14207 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14208 break;
14209 }
14210 break;
14211#ifdef TARGET_MIPS64
14212 case OPC_DEXTR_W_DSP:
14213 check_dsp(ctx);
14214 switch (op2) {
14215 case OPC_DMTHLIP:
14216 tcg_gen_movi_tl(t0, ret);
14217 gen_helper_dmthlip(v1_t, t0, cpu_env);
14218 break;
14219 case OPC_DSHILO:
14220 {
14221 int shift = (ctx->opcode >> 19) & 0x7F;
14222 int ac = (ctx->opcode >> 11) & 0x03;
14223 tcg_gen_movi_tl(t0, shift);
14224 tcg_gen_movi_tl(t1, ac);
14225 gen_helper_dshilo(t0, t1, cpu_env);
14226 break;
14227 }
14228 case OPC_DSHILOV:
14229 {
14230 int ac = (ctx->opcode >> 11) & 0x03;
14231 tcg_gen_movi_tl(t0, ac);
14232 gen_helper_dshilo(v1_t, t0, cpu_env);
14233 break;
14234 }
14235 case OPC_DEXTP:
14236 tcg_gen_movi_tl(t0, v2);
14237 tcg_gen_movi_tl(t1, v1);
14238
14239 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14240 break;
14241 case OPC_DEXTPV:
14242 tcg_gen_movi_tl(t0, v2);
14243 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14244 break;
14245 case OPC_DEXTPDP:
14246 tcg_gen_movi_tl(t0, v2);
14247 tcg_gen_movi_tl(t1, v1);
14248 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14249 break;
14250 case OPC_DEXTPDPV:
14251 tcg_gen_movi_tl(t0, v2);
14252 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14253 break;
14254 case OPC_DEXTR_L:
14255 tcg_gen_movi_tl(t0, v2);
14256 tcg_gen_movi_tl(t1, v1);
14257 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14258 break;
14259 case OPC_DEXTR_R_L:
14260 tcg_gen_movi_tl(t0, v2);
14261 tcg_gen_movi_tl(t1, v1);
14262 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14263 break;
14264 case OPC_DEXTR_RS_L:
14265 tcg_gen_movi_tl(t0, v2);
14266 tcg_gen_movi_tl(t1, v1);
14267 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14268 break;
14269 case OPC_DEXTR_W:
14270 tcg_gen_movi_tl(t0, v2);
14271 tcg_gen_movi_tl(t1, v1);
14272 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14273 break;
14274 case OPC_DEXTR_R_W:
14275 tcg_gen_movi_tl(t0, v2);
14276 tcg_gen_movi_tl(t1, v1);
14277 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14278 break;
14279 case OPC_DEXTR_RS_W:
14280 tcg_gen_movi_tl(t0, v2);
14281 tcg_gen_movi_tl(t1, v1);
14282 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14283 break;
14284 case OPC_DEXTR_S_H:
14285 tcg_gen_movi_tl(t0, v2);
14286 tcg_gen_movi_tl(t1, v1);
14287 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14288 break;
14289 case OPC_DEXTRV_S_H:
14290 tcg_gen_movi_tl(t0, v2);
14291 tcg_gen_movi_tl(t1, v1);
14292 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14293 break;
14294 case OPC_DEXTRV_L:
14295 tcg_gen_movi_tl(t0, v2);
14296 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14297 break;
14298 case OPC_DEXTRV_R_L:
14299 tcg_gen_movi_tl(t0, v2);
14300 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14301 break;
14302 case OPC_DEXTRV_RS_L:
14303 tcg_gen_movi_tl(t0, v2);
14304 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14305 break;
14306 case OPC_DEXTRV_W:
14307 tcg_gen_movi_tl(t0, v2);
14308 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14309 break;
14310 case OPC_DEXTRV_R_W:
14311 tcg_gen_movi_tl(t0, v2);
14312 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14313 break;
14314 case OPC_DEXTRV_RS_W:
14315 tcg_gen_movi_tl(t0, v2);
14316 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14317 break;
14318 }
14319 break;
14320#endif
14321 }
14322
14323 tcg_temp_free(t0);
14324 tcg_temp_free(t1);
14325 tcg_temp_free(v1_t);
14326 tcg_temp_free(v2_t);
14327
14328 (void)opn; /* avoid a compiler warning */
14329 MIPS_DEBUG("%s", opn);
14330}
14331
9b1a1d68
JL
14332/* End MIPSDSP functions. */
14333
7db13fae 14334static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
14335{
14336 int32_t offset;
14337 int rs, rt, rd, sa;
14338 uint32_t op, op1, op2;
14339 int16_t imm;
14340
14341 /* make sure instructions are on a word boundary */
14342 if (ctx->pc & 0x3) {
14343 env->CP0_BadVAddr = ctx->pc;
14344 generate_exception(ctx, EXCP_AdEL);
14345 return;
14346 }
14347
14348 /* Handle blikely not taken case */
14349 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14350 int l1 = gen_new_label();
14351
14352 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14353 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14354 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14355 gen_goto_tb(ctx, 1, ctx->pc + 4);
14356 gen_set_label(l1);
14357 }
14358
fdefe51c 14359 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14360 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14361 }
3c824109
NF
14362
14363 op = MASK_OP_MAJOR(ctx->opcode);
14364 rs = (ctx->opcode >> 21) & 0x1f;
14365 rt = (ctx->opcode >> 16) & 0x1f;
14366 rd = (ctx->opcode >> 11) & 0x1f;
14367 sa = (ctx->opcode >> 6) & 0x1f;
14368 imm = (int16_t)ctx->opcode;
14369 switch (op) {
7a387fff
TS
14370 case OPC_SPECIAL:
14371 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14372 switch (op1) {
324d9e32
AJ
14373 case OPC_SLL: /* Shift with immediate */
14374 case OPC_SRA:
324d9e32 14375 gen_shift_imm(env, ctx, op1, rd, rt, sa);
7a387fff 14376 break;
ea63e2c3
NF
14377 case OPC_SRL:
14378 switch ((ctx->opcode >> 21) & 0x1f) {
14379 case 1:
14380 /* rotr is decoded as srl on non-R2 CPUs */
14381 if (env->insn_flags & ISA_MIPS32R2) {
14382 op1 = OPC_ROTR;
14383 }
14384 /* Fallthrough */
14385 case 0:
14386 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14387 break;
14388 default:
14389 generate_exception(ctx, EXCP_RI);
14390 break;
14391 }
14392 break;
460f00c4
AJ
14393 case OPC_MOVN: /* Conditional move */
14394 case OPC_MOVZ:
aa8f4009
AJ
14395 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14396 INSN_LOONGSON2E | INSN_LOONGSON2F);
9fa77488 14397 gen_cond_move(env, ctx, op1, rd, rs, rt);
460f00c4
AJ
14398 break;
14399 case OPC_ADD ... OPC_SUBU:
e189e748 14400 gen_arith(env, ctx, op1, rd, rs, rt);
7a387fff 14401 break;
460f00c4 14402 case OPC_SLLV: /* Shifts */
460f00c4
AJ
14403 case OPC_SRAV:
14404 gen_shift(env, ctx, op1, rd, rs, rt);
14405 break;
ea63e2c3
NF
14406 case OPC_SRLV:
14407 switch ((ctx->opcode >> 6) & 0x1f) {
14408 case 1:
14409 /* rotrv is decoded as srlv on non-R2 CPUs */
14410 if (env->insn_flags & ISA_MIPS32R2) {
14411 op1 = OPC_ROTRV;
14412 }
14413 /* Fallthrough */
14414 case 0:
14415 gen_shift(env, ctx, op1, rd, rs, rt);
14416 break;
14417 default:
14418 generate_exception(ctx, EXCP_RI);
14419 break;
14420 }
14421 break;
460f00c4
AJ
14422 case OPC_SLT: /* Set on less than */
14423 case OPC_SLTU:
9fa77488 14424 gen_slt(env, ctx, op1, rd, rs, rt);
460f00c4
AJ
14425 break;
14426 case OPC_AND: /* Logic*/
14427 case OPC_OR:
14428 case OPC_NOR:
14429 case OPC_XOR:
9fa77488 14430 gen_logic(env, ctx, op1, rd, rs, rt);
460f00c4 14431 break;
7a387fff 14432 case OPC_MULT ... OPC_DIVU:
e9c71dd1
TS
14433 if (sa) {
14434 check_insn(env, ctx, INSN_VR54XX);
14435 op1 = MASK_MUL_VR54XX(ctx->opcode);
14436 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14437 } else
14438 gen_muldiv(ctx, op1, rs, rt);
7a387fff
TS
14439 break;
14440 case OPC_JR ... OPC_JALR:
7dca4ad0 14441 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061
NF
14442 *is_branch = 1;
14443 break;
7a387fff
TS
14444 case OPC_TGE ... OPC_TEQ: /* Traps */
14445 case OPC_TNE:
14446 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14447 break;
7a387fff
TS
14448 case OPC_MFHI: /* Move from HI/LO */
14449 case OPC_MFLO:
14450 gen_HILO(ctx, op1, rd);
6af0bf9c 14451 break;
7a387fff
TS
14452 case OPC_MTHI:
14453 case OPC_MTLO: /* Move to HI/LO */
14454 gen_HILO(ctx, op1, rs);
6af0bf9c 14455 break;
b48cfdff
TS
14456 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14457#ifdef MIPS_STRICT_STANDARD
14458 MIPS_INVAL("PMON / selsl");
14459 generate_exception(ctx, EXCP_RI);
14460#else
895c2d04 14461 gen_helper_0e0i(pmon, sa);
b48cfdff 14462#endif
7a387fff
TS
14463 break;
14464 case OPC_SYSCALL:
6af0bf9c 14465 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14466 ctx->bstate = BS_STOP;
6af0bf9c 14467 break;
7a387fff 14468 case OPC_BREAK:
6af0bf9c
FB
14469 generate_exception(ctx, EXCP_BREAK);
14470 break;
b48cfdff
TS
14471 case OPC_SPIM:
14472#ifdef MIPS_STRICT_STANDARD
14473 MIPS_INVAL("SPIM");
14474 generate_exception(ctx, EXCP_RI);
14475#else
7a387fff
TS
14476 /* Implemented as RI exception for now. */
14477 MIPS_INVAL("spim (unofficial)");
14478 generate_exception(ctx, EXCP_RI);
b48cfdff 14479#endif
6af0bf9c 14480 break;
7a387fff 14481 case OPC_SYNC:
ead9360e 14482 /* Treat as NOP. */
6af0bf9c 14483 break;
4ad40f36 14484
7a387fff 14485 case OPC_MOVCI:
e189e748 14486 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14487 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14488 check_cp1_enabled(ctx);
36d23958
TS
14489 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14490 (ctx->opcode >> 16) & 1);
14491 } else {
e397ee33 14492 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14493 }
4ad40f36
FB
14494 break;
14495
d26bc211 14496#if defined(TARGET_MIPS64)
7a387fff
TS
14497 /* MIPS64 specific opcodes */
14498 case OPC_DSLL:
324d9e32 14499 case OPC_DSRA:
7a387fff 14500 case OPC_DSLL32:
324d9e32 14501 case OPC_DSRA32:
e189e748
TS
14502 check_insn(env, ctx, ISA_MIPS3);
14503 check_mips_64(ctx);
324d9e32 14504 gen_shift_imm(env, ctx, op1, rd, rt, sa);
7a387fff 14505 break;
ea63e2c3
NF
14506 case OPC_DSRL:
14507 switch ((ctx->opcode >> 21) & 0x1f) {
14508 case 1:
14509 /* drotr is decoded as dsrl on non-R2 CPUs */
14510 if (env->insn_flags & ISA_MIPS32R2) {
14511 op1 = OPC_DROTR;
14512 }
14513 /* Fallthrough */
14514 case 0:
14515 check_insn(env, ctx, ISA_MIPS3);
14516 check_mips_64(ctx);
14517 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14518 break;
14519 default:
14520 generate_exception(ctx, EXCP_RI);
14521 break;
14522 }
14523 break;
14524 case OPC_DSRL32:
14525 switch ((ctx->opcode >> 21) & 0x1f) {
14526 case 1:
14527 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14528 if (env->insn_flags & ISA_MIPS32R2) {
14529 op1 = OPC_DROTR32;
14530 }
14531 /* Fallthrough */
14532 case 0:
14533 check_insn(env, ctx, ISA_MIPS3);
14534 check_mips_64(ctx);
14535 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14536 break;
14537 default:
14538 generate_exception(ctx, EXCP_RI);
14539 break;
14540 }
14541 break;
7a387fff 14542 case OPC_DADD ... OPC_DSUBU:
e189e748
TS
14543 check_insn(env, ctx, ISA_MIPS3);
14544 check_mips_64(ctx);
14545 gen_arith(env, ctx, op1, rd, rs, rt);
7a387fff 14546 break;
460f00c4
AJ
14547 case OPC_DSLLV:
14548 case OPC_DSRAV:
460f00c4
AJ
14549 check_insn(env, ctx, ISA_MIPS3);
14550 check_mips_64(ctx);
14551 gen_shift(env, ctx, op1, rd, rs, rt);
14552 break;
ea63e2c3
NF
14553 case OPC_DSRLV:
14554 switch ((ctx->opcode >> 6) & 0x1f) {
14555 case 1:
14556 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14557 if (env->insn_flags & ISA_MIPS32R2) {
14558 op1 = OPC_DROTRV;
14559 }
14560 /* Fallthrough */
14561 case 0:
14562 check_insn(env, ctx, ISA_MIPS3);
14563 check_mips_64(ctx);
14564 gen_shift(env, ctx, op1, rd, rs, rt);
14565 break;
14566 default:
14567 generate_exception(ctx, EXCP_RI);
14568 break;
14569 }
14570 break;
7a387fff 14571 case OPC_DMULT ... OPC_DDIVU:
e189e748
TS
14572 check_insn(env, ctx, ISA_MIPS3);
14573 check_mips_64(ctx);
7a387fff
TS
14574 gen_muldiv(ctx, op1, rs, rt);
14575 break;
6af0bf9c
FB
14576#endif
14577 default: /* Invalid */
14578 MIPS_INVAL("special");
14579 generate_exception(ctx, EXCP_RI);
14580 break;
14581 }
14582 break;
7a387fff
TS
14583 case OPC_SPECIAL2:
14584 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14585 switch (op1) {
7a387fff
TS
14586 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14587 case OPC_MSUB ... OPC_MSUBU:
e189e748 14588 check_insn(env, ctx, ISA_MIPS32);
7a387fff 14589 gen_muldiv(ctx, op1, rs, rt);
6af0bf9c 14590 break;
7a387fff 14591 case OPC_MUL:
e189e748 14592 gen_arith(env, ctx, op1, rd, rs, rt);
6af0bf9c 14593 break;
20e1fb52
AJ
14594 case OPC_CLO:
14595 case OPC_CLZ:
e189e748 14596 check_insn(env, ctx, ISA_MIPS32);
7a387fff 14597 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14598 break;
7a387fff 14599 case OPC_SDBBP:
6af0bf9c
FB
14600 /* XXX: not clear which exception should be raised
14601 * when in debug mode...
14602 */
e189e748 14603 check_insn(env, ctx, ISA_MIPS32);
6af0bf9c
FB
14604 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14605 generate_exception(ctx, EXCP_DBp);
14606 } else {
14607 generate_exception(ctx, EXCP_DBp);
14608 }
ead9360e 14609 /* Treat as NOP. */
6af0bf9c 14610 break;
161f85e6
AJ
14611 case OPC_DIV_G_2F:
14612 case OPC_DIVU_G_2F:
14613 case OPC_MULT_G_2F:
14614 case OPC_MULTU_G_2F:
14615 case OPC_MOD_G_2F:
14616 case OPC_MODU_G_2F:
14617 check_insn(env, ctx, INSN_LOONGSON2F);
14618 gen_loongson_integer(ctx, op1, rd, rs, rt);
14619 break;
d26bc211 14620#if defined(TARGET_MIPS64)
20e1fb52
AJ
14621 case OPC_DCLO:
14622 case OPC_DCLZ:
e189e748
TS
14623 check_insn(env, ctx, ISA_MIPS64);
14624 check_mips_64(ctx);
7a387fff
TS
14625 gen_cl(ctx, op1, rd, rs);
14626 break;
161f85e6
AJ
14627 case OPC_DMULT_G_2F:
14628 case OPC_DMULTU_G_2F:
14629 case OPC_DDIV_G_2F:
14630 case OPC_DDIVU_G_2F:
14631 case OPC_DMOD_G_2F:
14632 case OPC_DMODU_G_2F:
14633 check_insn(env, ctx, INSN_LOONGSON2F);
14634 gen_loongson_integer(ctx, op1, rd, rs, rt);
14635 break;
7a387fff 14636#endif
6af0bf9c
FB
14637 default: /* Invalid */
14638 MIPS_INVAL("special2");
14639 generate_exception(ctx, EXCP_RI);
14640 break;
14641 }
14642 break;
7a387fff 14643 case OPC_SPECIAL3:
2b0233ab
TS
14644 op1 = MASK_SPECIAL3(ctx->opcode);
14645 switch (op1) {
14646 case OPC_EXT:
14647 case OPC_INS:
14648 check_insn(env, ctx, ISA_MIPS32R2);
14649 gen_bitops(ctx, op1, rt, rs, sa, rd);
14650 break;
14651 case OPC_BSHFL:
14652 check_insn(env, ctx, ISA_MIPS32R2);
14653 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14654 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14655 break;
1579a72e 14656 case OPC_RDHWR:
26ebe468 14657 gen_rdhwr(env, ctx, rt, rd);
1579a72e 14658 break;
ead9360e 14659 case OPC_FORK:
7385ac0b 14660 check_insn(env, ctx, ASE_MT);
6c5c1e20 14661 {
35fbce2c
AJ
14662 TCGv t0 = tcg_temp_new();
14663 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14664
14665 gen_load_gpr(t0, rt);
14666 gen_load_gpr(t1, rs);
a7812ae4 14667 gen_helper_fork(t0, t1);
6c5c1e20
TS
14668 tcg_temp_free(t0);
14669 tcg_temp_free(t1);
14670 }
ead9360e
TS
14671 break;
14672 case OPC_YIELD:
7385ac0b 14673 check_insn(env, ctx, ASE_MT);
6c5c1e20 14674 {
35fbce2c 14675 TCGv t0 = tcg_temp_new();
6c5c1e20 14676
35fbce2c 14677 save_cpu_state(ctx, 1);
6c5c1e20 14678 gen_load_gpr(t0, rs);
895c2d04 14679 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14680 gen_store_gpr(t0, rd);
14681 tcg_temp_free(t0);
14682 }
ead9360e 14683 break;
161f85e6 14684 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14685 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14686 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14687 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14688 * the same mask and op1. */
14689 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14690 op2 = MASK_ADDUH_QB(ctx->opcode);
14691 switch (op2) {
14692 case OPC_ADDUH_QB:
14693 case OPC_ADDUH_R_QB:
14694 case OPC_ADDQH_PH:
14695 case OPC_ADDQH_R_PH:
14696 case OPC_ADDQH_W:
14697 case OPC_ADDQH_R_W:
14698 case OPC_SUBUH_QB:
14699 case OPC_SUBUH_R_QB:
14700 case OPC_SUBQH_PH:
14701 case OPC_SUBQH_R_PH:
14702 case OPC_SUBQH_W:
14703 case OPC_SUBQH_R_W:
14704 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14705 break;
a22260ae
JL
14706 case OPC_MUL_PH:
14707 case OPC_MUL_S_PH:
14708 case OPC_MULQ_S_W:
14709 case OPC_MULQ_RS_W:
14710 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14711 break;
461c08df
JL
14712 default:
14713 MIPS_INVAL("MASK ADDUH.QB");
14714 generate_exception(ctx, EXCP_RI);
14715 break;
14716 }
14717 } else if (env->insn_flags & INSN_LOONGSON2E) {
14718 gen_loongson_integer(ctx, op1, rd, rs, rt);
14719 } else {
14720 generate_exception(ctx, EXCP_RI);
14721 }
161f85e6 14722 break;
9b1a1d68
JL
14723 case OPC_LX_DSP:
14724 op2 = MASK_LX(ctx->opcode);
14725 switch (op2) {
14726#if defined(TARGET_MIPS64)
14727 case OPC_LDX:
14728#endif
14729 case OPC_LBUX:
14730 case OPC_LHX:
14731 case OPC_LWX:
14732 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14733 break;
14734 default: /* Invalid */
14735 MIPS_INVAL("MASK LX");
14736 generate_exception(ctx, EXCP_RI);
14737 break;
14738 }
14739 break;
461c08df
JL
14740 case OPC_ABSQ_S_PH_DSP:
14741 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14742 switch (op2) {
14743 case OPC_ABSQ_S_QB:
14744 case OPC_ABSQ_S_PH:
14745 case OPC_ABSQ_S_W:
14746 case OPC_PRECEQ_W_PHL:
14747 case OPC_PRECEQ_W_PHR:
14748 case OPC_PRECEQU_PH_QBL:
14749 case OPC_PRECEQU_PH_QBR:
14750 case OPC_PRECEQU_PH_QBLA:
14751 case OPC_PRECEQU_PH_QBRA:
14752 case OPC_PRECEU_PH_QBL:
14753 case OPC_PRECEU_PH_QBR:
14754 case OPC_PRECEU_PH_QBLA:
14755 case OPC_PRECEU_PH_QBRA:
14756 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14757 break;
1cb6686c
JL
14758 case OPC_BITREV:
14759 case OPC_REPL_QB:
14760 case OPC_REPLV_QB:
14761 case OPC_REPL_PH:
14762 case OPC_REPLV_PH:
14763 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14764 break;
461c08df
JL
14765 default:
14766 MIPS_INVAL("MASK ABSQ_S.PH");
14767 generate_exception(ctx, EXCP_RI);
14768 break;
14769 }
14770 break;
14771 case OPC_ADDU_QB_DSP:
14772 op2 = MASK_ADDU_QB(ctx->opcode);
14773 switch (op2) {
14774 case OPC_ADDQ_PH:
14775 case OPC_ADDQ_S_PH:
14776 case OPC_ADDQ_S_W:
14777 case OPC_ADDU_QB:
14778 case OPC_ADDU_S_QB:
14779 case OPC_ADDU_PH:
14780 case OPC_ADDU_S_PH:
14781 case OPC_SUBQ_PH:
14782 case OPC_SUBQ_S_PH:
14783 case OPC_SUBQ_S_W:
14784 case OPC_SUBU_QB:
14785 case OPC_SUBU_S_QB:
14786 case OPC_SUBU_PH:
14787 case OPC_SUBU_S_PH:
14788 case OPC_ADDSC:
14789 case OPC_ADDWC:
14790 case OPC_MODSUB:
14791 case OPC_RADDU_W_QB:
14792 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14793 break;
a22260ae
JL
14794 case OPC_MULEU_S_PH_QBL:
14795 case OPC_MULEU_S_PH_QBR:
14796 case OPC_MULQ_RS_PH:
14797 case OPC_MULEQ_S_W_PHL:
14798 case OPC_MULEQ_S_W_PHR:
14799 case OPC_MULQ_S_PH:
14800 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14801 break;
461c08df
JL
14802 default: /* Invalid */
14803 MIPS_INVAL("MASK ADDU.QB");
14804 generate_exception(ctx, EXCP_RI);
14805 break;
14806
14807 }
14808 break;
14809 case OPC_CMPU_EQ_QB_DSP:
14810 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14811 switch (op2) {
14812 case OPC_PRECR_SRA_PH_W:
14813 case OPC_PRECR_SRA_R_PH_W:
14814 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14815 break;
14816 case OPC_PRECR_QB_PH:
14817 case OPC_PRECRQ_QB_PH:
14818 case OPC_PRECRQ_PH_W:
14819 case OPC_PRECRQ_RS_PH_W:
14820 case OPC_PRECRQU_S_QB_PH:
14821 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14822 break;
26690560
JL
14823 case OPC_CMPU_EQ_QB:
14824 case OPC_CMPU_LT_QB:
14825 case OPC_CMPU_LE_QB:
14826 case OPC_CMP_EQ_PH:
14827 case OPC_CMP_LT_PH:
14828 case OPC_CMP_LE_PH:
14829 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14830 break;
14831 case OPC_CMPGU_EQ_QB:
14832 case OPC_CMPGU_LT_QB:
14833 case OPC_CMPGU_LE_QB:
14834 case OPC_CMPGDU_EQ_QB:
14835 case OPC_CMPGDU_LT_QB:
14836 case OPC_CMPGDU_LE_QB:
14837 case OPC_PICK_QB:
14838 case OPC_PICK_PH:
14839 case OPC_PACKRL_PH:
14840 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14841 break;
461c08df
JL
14842 default: /* Invalid */
14843 MIPS_INVAL("MASK CMPU.EQ.QB");
14844 generate_exception(ctx, EXCP_RI);
14845 break;
14846 }
14847 break;
77c5fa8b
JL
14848 case OPC_SHLL_QB_DSP:
14849 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14850 break;
a22260ae
JL
14851 case OPC_DPA_W_PH_DSP:
14852 op2 = MASK_DPA_W_PH(ctx->opcode);
14853 switch (op2) {
14854 case OPC_DPAU_H_QBL:
14855 case OPC_DPAU_H_QBR:
14856 case OPC_DPSU_H_QBL:
14857 case OPC_DPSU_H_QBR:
14858 case OPC_DPA_W_PH:
14859 case OPC_DPAX_W_PH:
14860 case OPC_DPAQ_S_W_PH:
14861 case OPC_DPAQX_S_W_PH:
14862 case OPC_DPAQX_SA_W_PH:
14863 case OPC_DPS_W_PH:
14864 case OPC_DPSX_W_PH:
14865 case OPC_DPSQ_S_W_PH:
14866 case OPC_DPSQX_S_W_PH:
14867 case OPC_DPSQX_SA_W_PH:
14868 case OPC_MULSAQ_S_W_PH:
14869 case OPC_DPAQ_SA_L_W:
14870 case OPC_DPSQ_SA_L_W:
14871 case OPC_MAQ_S_W_PHL:
14872 case OPC_MAQ_S_W_PHR:
14873 case OPC_MAQ_SA_W_PHL:
14874 case OPC_MAQ_SA_W_PHR:
14875 case OPC_MULSA_W_PH:
14876 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14877 break;
14878 default: /* Invalid */
14879 MIPS_INVAL("MASK DPAW.PH");
14880 generate_exception(ctx, EXCP_RI);
14881 break;
14882 }
14883 break;
1cb6686c
JL
14884 case OPC_INSV_DSP:
14885 op2 = MASK_INSV(ctx->opcode);
14886 switch (op2) {
14887 case OPC_INSV:
14888 check_dsp(ctx);
14889 {
14890 TCGv t0, t1;
14891
14892 if (rt == 0) {
14893 MIPS_DEBUG("NOP");
14894 break;
14895 }
14896
14897 t0 = tcg_temp_new();
14898 t1 = tcg_temp_new();
14899
14900 gen_load_gpr(t0, rt);
14901 gen_load_gpr(t1, rs);
14902
14903 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14904
14905 tcg_temp_free(t0);
14906 tcg_temp_free(t1);
14907 break;
14908 }
14909 default: /* Invalid */
14910 MIPS_INVAL("MASK INSV");
14911 generate_exception(ctx, EXCP_RI);
14912 break;
14913 }
14914 break;
26690560
JL
14915 case OPC_APPEND_DSP:
14916 check_dspr2(ctx);
14917 op2 = MASK_APPEND(ctx->opcode);
14918 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14919 break;
b53371ed
JL
14920 case OPC_EXTR_W_DSP:
14921 op2 = MASK_EXTR_W(ctx->opcode);
14922 switch (op2) {
14923 case OPC_EXTR_W:
14924 case OPC_EXTR_R_W:
14925 case OPC_EXTR_RS_W:
14926 case OPC_EXTR_S_H:
14927 case OPC_EXTRV_S_H:
14928 case OPC_EXTRV_W:
14929 case OPC_EXTRV_R_W:
14930 case OPC_EXTRV_RS_W:
14931 case OPC_EXTP:
14932 case OPC_EXTPV:
14933 case OPC_EXTPDP:
14934 case OPC_EXTPDPV:
14935 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14936 break;
14937 case OPC_RDDSP:
14938 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14939 break;
14940 case OPC_SHILO:
14941 case OPC_SHILOV:
14942 case OPC_MTHLIP:
14943 case OPC_WRDSP:
14944 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14945 break;
14946 default: /* Invalid */
14947 MIPS_INVAL("MASK EXTR.W");
14948 generate_exception(ctx, EXCP_RI);
14949 break;
14950 }
14951 break;
d26bc211 14952#if defined(TARGET_MIPS64)
1579a72e
TS
14953 case OPC_DEXTM ... OPC_DEXT:
14954 case OPC_DINSM ... OPC_DINS:
e189e748
TS
14955 check_insn(env, ctx, ISA_MIPS64R2);
14956 check_mips_64(ctx);
1579a72e 14957 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 14958 break;
1579a72e 14959 case OPC_DBSHFL:
e189e748
TS
14960 check_insn(env, ctx, ISA_MIPS64R2);
14961 check_mips_64(ctx);
1579a72e 14962 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 14963 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 14964 break;
161f85e6
AJ
14965 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14966 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14967 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14968 check_insn(env, ctx, INSN_LOONGSON2E);
14969 gen_loongson_integer(ctx, op1, rd, rs, rt);
14970 break;
461c08df
JL
14971 case OPC_ABSQ_S_QH_DSP:
14972 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14973 switch (op2) {
14974 case OPC_PRECEQ_L_PWL:
14975 case OPC_PRECEQ_L_PWR:
14976 case OPC_PRECEQ_PW_QHL:
14977 case OPC_PRECEQ_PW_QHR:
14978 case OPC_PRECEQ_PW_QHLA:
14979 case OPC_PRECEQ_PW_QHRA:
14980 case OPC_PRECEQU_QH_OBL:
14981 case OPC_PRECEQU_QH_OBR:
14982 case OPC_PRECEQU_QH_OBLA:
14983 case OPC_PRECEQU_QH_OBRA:
14984 case OPC_PRECEU_QH_OBL:
14985 case OPC_PRECEU_QH_OBR:
14986 case OPC_PRECEU_QH_OBLA:
14987 case OPC_PRECEU_QH_OBRA:
14988 case OPC_ABSQ_S_OB:
14989 case OPC_ABSQ_S_PW:
14990 case OPC_ABSQ_S_QH:
14991 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14992 break;
1cb6686c
JL
14993 case OPC_REPL_OB:
14994 case OPC_REPL_PW:
14995 case OPC_REPL_QH:
14996 case OPC_REPLV_OB:
14997 case OPC_REPLV_PW:
14998 case OPC_REPLV_QH:
14999 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
15000 break;
461c08df
JL
15001 default: /* Invalid */
15002 MIPS_INVAL("MASK ABSQ_S.QH");
15003 generate_exception(ctx, EXCP_RI);
15004 break;
15005 }
15006 break;
15007 case OPC_ADDU_OB_DSP:
15008 op2 = MASK_ADDU_OB(ctx->opcode);
15009 switch (op2) {
15010 case OPC_RADDU_L_OB:
15011 case OPC_SUBQ_PW:
15012 case OPC_SUBQ_S_PW:
15013 case OPC_SUBQ_QH:
15014 case OPC_SUBQ_S_QH:
15015 case OPC_SUBU_OB:
15016 case OPC_SUBU_S_OB:
15017 case OPC_SUBU_QH:
15018 case OPC_SUBU_S_QH:
15019 case OPC_SUBUH_OB:
15020 case OPC_SUBUH_R_OB:
15021 case OPC_ADDQ_PW:
15022 case OPC_ADDQ_S_PW:
15023 case OPC_ADDQ_QH:
15024 case OPC_ADDQ_S_QH:
15025 case OPC_ADDU_OB:
15026 case OPC_ADDU_S_OB:
15027 case OPC_ADDU_QH:
15028 case OPC_ADDU_S_QH:
15029 case OPC_ADDUH_OB:
15030 case OPC_ADDUH_R_OB:
15031 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15032 break;
a22260ae
JL
15033 case OPC_MULEQ_S_PW_QHL:
15034 case OPC_MULEQ_S_PW_QHR:
15035 case OPC_MULEU_S_QH_OBL:
15036 case OPC_MULEU_S_QH_OBR:
15037 case OPC_MULQ_RS_QH:
15038 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15039 break;
461c08df
JL
15040 default: /* Invalid */
15041 MIPS_INVAL("MASK ADDU.OB");
15042 generate_exception(ctx, EXCP_RI);
15043 break;
15044 }
15045 break;
15046 case OPC_CMPU_EQ_OB_DSP:
15047 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15048 switch (op2) {
15049 case OPC_PRECR_SRA_QH_PW:
15050 case OPC_PRECR_SRA_R_QH_PW:
15051 /* Return value is rt. */
15052 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15053 break;
15054 case OPC_PRECR_OB_QH:
15055 case OPC_PRECRQ_OB_QH:
15056 case OPC_PRECRQ_PW_L:
15057 case OPC_PRECRQ_QH_PW:
15058 case OPC_PRECRQ_RS_QH_PW:
15059 case OPC_PRECRQU_S_OB_QH:
15060 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15061 break;
26690560
JL
15062 case OPC_CMPU_EQ_OB:
15063 case OPC_CMPU_LT_OB:
15064 case OPC_CMPU_LE_OB:
15065 case OPC_CMP_EQ_QH:
15066 case OPC_CMP_LT_QH:
15067 case OPC_CMP_LE_QH:
15068 case OPC_CMP_EQ_PW:
15069 case OPC_CMP_LT_PW:
15070 case OPC_CMP_LE_PW:
15071 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15072 break;
15073 case OPC_CMPGDU_EQ_OB:
15074 case OPC_CMPGDU_LT_OB:
15075 case OPC_CMPGDU_LE_OB:
15076 case OPC_CMPGU_EQ_OB:
15077 case OPC_CMPGU_LT_OB:
15078 case OPC_CMPGU_LE_OB:
15079 case OPC_PACKRL_PW:
15080 case OPC_PICK_OB:
15081 case OPC_PICK_PW:
15082 case OPC_PICK_QH:
15083 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15084 break;
461c08df
JL
15085 default: /* Invalid */
15086 MIPS_INVAL("MASK CMPU_EQ.OB");
15087 generate_exception(ctx, EXCP_RI);
15088 break;
15089 }
15090 break;
26690560
JL
15091 case OPC_DAPPEND_DSP:
15092 check_dspr2(ctx);
15093 op2 = MASK_DAPPEND(ctx->opcode);
15094 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15095 break;
b53371ed
JL
15096 case OPC_DEXTR_W_DSP:
15097 op2 = MASK_DEXTR_W(ctx->opcode);
15098 switch (op2) {
15099 case OPC_DEXTP:
15100 case OPC_DEXTPDP:
15101 case OPC_DEXTPDPV:
15102 case OPC_DEXTPV:
15103 case OPC_DEXTR_L:
15104 case OPC_DEXTR_R_L:
15105 case OPC_DEXTR_RS_L:
15106 case OPC_DEXTR_W:
15107 case OPC_DEXTR_R_W:
15108 case OPC_DEXTR_RS_W:
15109 case OPC_DEXTR_S_H:
15110 case OPC_DEXTRV_L:
15111 case OPC_DEXTRV_R_L:
15112 case OPC_DEXTRV_RS_L:
15113 case OPC_DEXTRV_S_H:
15114 case OPC_DEXTRV_W:
15115 case OPC_DEXTRV_R_W:
15116 case OPC_DEXTRV_RS_W:
15117 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15118 break;
15119 case OPC_DMTHLIP:
15120 case OPC_DSHILO:
15121 case OPC_DSHILOV:
15122 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15123 break;
15124 default: /* Invalid */
15125 MIPS_INVAL("MASK EXTR.W");
15126 generate_exception(ctx, EXCP_RI);
15127 break;
15128 }
15129 break;
a22260ae
JL
15130 case OPC_DPAQ_W_QH_DSP:
15131 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15132 switch (op2) {
15133 case OPC_DPAU_H_OBL:
15134 case OPC_DPAU_H_OBR:
15135 case OPC_DPSU_H_OBL:
15136 case OPC_DPSU_H_OBR:
15137 case OPC_DPA_W_QH:
15138 case OPC_DPAQ_S_W_QH:
15139 case OPC_DPS_W_QH:
15140 case OPC_DPSQ_S_W_QH:
15141 case OPC_MULSAQ_S_W_QH:
15142 case OPC_DPAQ_SA_L_PW:
15143 case OPC_DPSQ_SA_L_PW:
15144 case OPC_MULSAQ_S_L_PW:
15145 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15146 break;
15147 case OPC_MAQ_S_W_QHLL:
15148 case OPC_MAQ_S_W_QHLR:
15149 case OPC_MAQ_S_W_QHRL:
15150 case OPC_MAQ_S_W_QHRR:
15151 case OPC_MAQ_SA_W_QHLL:
15152 case OPC_MAQ_SA_W_QHLR:
15153 case OPC_MAQ_SA_W_QHRL:
15154 case OPC_MAQ_SA_W_QHRR:
15155 case OPC_MAQ_S_L_PWL:
15156 case OPC_MAQ_S_L_PWR:
15157 case OPC_DMADD:
15158 case OPC_DMADDU:
15159 case OPC_DMSUB:
15160 case OPC_DMSUBU:
15161 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15162 break;
15163 default: /* Invalid */
15164 MIPS_INVAL("MASK DPAQ.W.QH");
15165 generate_exception(ctx, EXCP_RI);
15166 break;
15167 }
15168 break;
1cb6686c
JL
15169 case OPC_DINSV_DSP:
15170 op2 = MASK_INSV(ctx->opcode);
15171 switch (op2) {
15172 case OPC_DINSV:
15173 {
15174 TCGv t0, t1;
15175
15176 if (rt == 0) {
15177 MIPS_DEBUG("NOP");
15178 break;
15179 }
15180 check_dsp(ctx);
15181
15182 t0 = tcg_temp_new();
15183 t1 = tcg_temp_new();
15184
15185 gen_load_gpr(t0, rt);
15186 gen_load_gpr(t1, rs);
15187
15188 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15189 break;
15190 }
15191 default: /* Invalid */
15192 MIPS_INVAL("MASK DINSV");
15193 generate_exception(ctx, EXCP_RI);
15194 break;
15195 }
15196 break;
77c5fa8b
JL
15197 case OPC_SHLL_OB_DSP:
15198 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15199 break;
7a387fff
TS
15200#endif
15201 default: /* Invalid */
15202 MIPS_INVAL("special3");
15203 generate_exception(ctx, EXCP_RI);
15204 break;
15205 }
15206 break;
15207 case OPC_REGIMM:
15208 op1 = MASK_REGIMM(ctx->opcode);
15209 switch (op1) {
15210 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15211 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15212 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061
NF
15213 *is_branch = 1;
15214 break;
7a387fff
TS
15215 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15216 case OPC_TNEI:
15217 gen_trap(ctx, op1, rs, -1, imm);
15218 break;
15219 case OPC_SYNCI:
e189e748 15220 check_insn(env, ctx, ISA_MIPS32R2);
ead9360e 15221 /* Treat as NOP. */
6af0bf9c 15222 break;
e45a93e2
JL
15223 case OPC_BPOSGE32: /* MIPS DSP branch */
15224#if defined(TARGET_MIPS64)
15225 case OPC_BPOSGE64:
15226#endif
15227 check_dsp(ctx);
15228 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15229 *is_branch = 1;
15230 break;
6af0bf9c 15231 default: /* Invalid */
923617a3 15232 MIPS_INVAL("regimm");
6af0bf9c
FB
15233 generate_exception(ctx, EXCP_RI);
15234 break;
15235 }
15236 break;
7a387fff 15237 case OPC_CP0:
387a8fe5 15238 check_cp0_enabled(ctx);
7a387fff 15239 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15240 switch (op1) {
7a387fff
TS
15241 case OPC_MFC0:
15242 case OPC_MTC0:
ead9360e
TS
15243 case OPC_MFTR:
15244 case OPC_MTTR:
d26bc211 15245#if defined(TARGET_MIPS64)
7a387fff
TS
15246 case OPC_DMFC0:
15247 case OPC_DMTC0:
15248#endif
f1aa6320 15249#ifndef CONFIG_USER_ONLY
932e71cd 15250 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15251#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15252 break;
15253 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15254#ifndef CONFIG_USER_ONLY
932e71cd 15255 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15256#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15257 break;
15258 case OPC_MFMC0:
8706c382 15259#ifndef CONFIG_USER_ONLY
932e71cd 15260 {
35fbce2c 15261 TCGv t0 = tcg_temp_new();
6c5c1e20 15262
0eaef5aa 15263 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15264 switch (op2) {
15265 case OPC_DMT:
15266 check_insn(env, ctx, ASE_MT);
9ed5726c 15267 gen_helper_dmt(t0);
35fbce2c 15268 gen_store_gpr(t0, rt);
6c5c1e20
TS
15269 break;
15270 case OPC_EMT:
15271 check_insn(env, ctx, ASE_MT);
9ed5726c 15272 gen_helper_emt(t0);
35fbce2c 15273 gen_store_gpr(t0, rt);
da80682b 15274 break;
6c5c1e20
TS
15275 case OPC_DVPE:
15276 check_insn(env, ctx, ASE_MT);
895c2d04 15277 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15278 gen_store_gpr(t0, rt);
6c5c1e20
TS
15279 break;
15280 case OPC_EVPE:
15281 check_insn(env, ctx, ASE_MT);
895c2d04 15282 gen_helper_evpe(t0, cpu_env);
35fbce2c 15283 gen_store_gpr(t0, rt);
6c5c1e20
TS
15284 break;
15285 case OPC_DI:
15286 check_insn(env, ctx, ISA_MIPS32R2);
867abc7e 15287 save_cpu_state(ctx, 1);
895c2d04 15288 gen_helper_di(t0, cpu_env);
35fbce2c 15289 gen_store_gpr(t0, rt);
6c5c1e20
TS
15290 /* Stop translation as we may have switched the execution mode */
15291 ctx->bstate = BS_STOP;
15292 break;
15293 case OPC_EI:
15294 check_insn(env, ctx, ISA_MIPS32R2);
867abc7e 15295 save_cpu_state(ctx, 1);
895c2d04 15296 gen_helper_ei(t0, cpu_env);
35fbce2c 15297 gen_store_gpr(t0, rt);
6c5c1e20
TS
15298 /* Stop translation as we may have switched the execution mode */
15299 ctx->bstate = BS_STOP;
15300 break;
15301 default: /* Invalid */
15302 MIPS_INVAL("mfmc0");
15303 generate_exception(ctx, EXCP_RI);
15304 break;
15305 }
6c5c1e20 15306 tcg_temp_free(t0);
7a387fff 15307 }
0eaef5aa 15308#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15309 break;
7a387fff 15310 case OPC_RDPGPR:
e189e748 15311 check_insn(env, ctx, ISA_MIPS32R2);
be24bb4f 15312 gen_load_srsgpr(rt, rd);
ead9360e 15313 break;
7a387fff 15314 case OPC_WRPGPR:
e189e748 15315 check_insn(env, ctx, ISA_MIPS32R2);
be24bb4f 15316 gen_store_srsgpr(rt, rd);
38121543 15317 break;
6af0bf9c 15318 default:
923617a3 15319 MIPS_INVAL("cp0");
7a387fff 15320 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15321 break;
15322 }
15323 break;
324d9e32
AJ
15324 case OPC_ADDI: /* Arithmetic with immediate opcode */
15325 case OPC_ADDIU:
e189e748 15326 gen_arith_imm(env, ctx, op, rt, rs, imm);
7a387fff 15327 break;
324d9e32
AJ
15328 case OPC_SLTI: /* Set on less than with immediate opcode */
15329 case OPC_SLTIU:
9fa77488 15330 gen_slt_imm(env, ctx, op, rt, rs, imm);
324d9e32
AJ
15331 break;
15332 case OPC_ANDI: /* Arithmetic with immediate opcode */
15333 case OPC_LUI:
15334 case OPC_ORI:
15335 case OPC_XORI:
9fa77488 15336 gen_logic_imm(env, ctx, op, rt, rs, imm);
324d9e32 15337 break;
7a387fff
TS
15338 case OPC_J ... OPC_JAL: /* Jump */
15339 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15340 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061
NF
15341 *is_branch = 1;
15342 break;
7a387fff
TS
15343 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15344 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15345 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061
NF
15346 *is_branch = 1;
15347 break;
7a387fff 15348 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15349 case OPC_LL:
afa88c3a 15350 gen_ld(env, ctx, op, rt, rs, imm);
5c13fdfd 15351 break;
7a387fff
TS
15352 case OPC_SB ... OPC_SW:
15353 case OPC_SWR:
5c13fdfd 15354 gen_st(ctx, op, rt, rs, imm);
7a387fff 15355 break;
d66c7132
AJ
15356 case OPC_SC:
15357 gen_st_cond(ctx, op, rt, rs, imm);
15358 break;
7a387fff 15359 case OPC_CACHE:
2e15497c 15360 check_cp0_enabled(ctx);
e189e748 15361 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15362 /* Treat as NOP. */
34ae7b51 15363 break;
7a387fff 15364 case OPC_PREF:
e189e748 15365 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15366 /* Treat as NOP. */
6af0bf9c 15367 break;
4ad40f36 15368
923617a3 15369 /* Floating point (COP1). */
7a387fff
TS
15370 case OPC_LWC1:
15371 case OPC_LDC1:
15372 case OPC_SWC1:
15373 case OPC_SDC1:
26ebe468 15374 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15375 break;
15376
7a387fff 15377 case OPC_CP1:
36d23958 15378 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15379 check_cp1_enabled(ctx);
36d23958
TS
15380 op1 = MASK_CP1(ctx->opcode);
15381 switch (op1) {
3a95e3a7
TS
15382 case OPC_MFHC1:
15383 case OPC_MTHC1:
e189e748 15384 check_insn(env, ctx, ISA_MIPS32R2);
36d23958
TS
15385 case OPC_MFC1:
15386 case OPC_CFC1:
15387 case OPC_MTC1:
15388 case OPC_CTC1:
e189e748
TS
15389 gen_cp1(ctx, op1, rt, rd);
15390 break;
d26bc211 15391#if defined(TARGET_MIPS64)
36d23958
TS
15392 case OPC_DMFC1:
15393 case OPC_DMTC1:
e189e748 15394 check_insn(env, ctx, ISA_MIPS3);
36d23958
TS
15395 gen_cp1(ctx, op1, rt, rd);
15396 break;
e189e748 15397#endif
fbcc6828
TS
15398 case OPC_BC1ANY2:
15399 case OPC_BC1ANY4:
b8aa4598 15400 check_cop1x(ctx);
7385ac0b 15401 check_insn(env, ctx, ASE_MIPS3D);
d8a5950a
TS
15402 /* fall through */
15403 case OPC_BC1:
e189e748 15404 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
5a5012ec 15405 (rt >> 2) & 0x7, imm << 2);
c9602061
NF
15406 *is_branch = 1;
15407 break;
36d23958
TS
15408 case OPC_S_FMT:
15409 case OPC_D_FMT:
15410 case OPC_W_FMT:
15411 case OPC_L_FMT:
5a5012ec 15412 case OPC_PS_FMT:
bf4120ad 15413 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15414 (imm >> 8) & 0x7);
36d23958
TS
15415 break;
15416 default:
923617a3 15417 MIPS_INVAL("cp1");
e397ee33 15418 generate_exception (ctx, EXCP_RI);
36d23958
TS
15419 break;
15420 }
15421 } else {
15422 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15423 }
4ad40f36
FB
15424 break;
15425
15426 /* COP2. */
7a387fff
TS
15427 case OPC_LWC2:
15428 case OPC_LDC2:
15429 case OPC_SWC2:
15430 case OPC_SDC2:
7a387fff 15431 /* COP2: Not implemented. */
4ad40f36
FB
15432 generate_exception_err(ctx, EXCP_CpU, 2);
15433 break;
bd277fa1
RH
15434 case OPC_CP2:
15435 check_insn(env, ctx, INSN_LOONGSON2F);
15436 /* Note that these instructions use different fields. */
15437 gen_loongson_multimedia(ctx, sa, rd, rt);
15438 break;
4ad40f36 15439
7a387fff 15440 case OPC_CP3:
36d23958 15441 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15442 check_cp1_enabled(ctx);
36d23958
TS
15443 op1 = MASK_CP3(ctx->opcode);
15444 switch (op1) {
5a5012ec
TS
15445 case OPC_LWXC1:
15446 case OPC_LDXC1:
15447 case OPC_LUXC1:
15448 case OPC_SWXC1:
15449 case OPC_SDXC1:
15450 case OPC_SUXC1:
93b12ccc 15451 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15452 break;
e0c84da7 15453 case OPC_PREFX:
ead9360e 15454 /* Treat as NOP. */
e0c84da7 15455 break;
5a5012ec
TS
15456 case OPC_ALNV_PS:
15457 case OPC_MADD_S:
15458 case OPC_MADD_D:
15459 case OPC_MADD_PS:
15460 case OPC_MSUB_S:
15461 case OPC_MSUB_D:
15462 case OPC_MSUB_PS:
15463 case OPC_NMADD_S:
15464 case OPC_NMADD_D:
15465 case OPC_NMADD_PS:
15466 case OPC_NMSUB_S:
15467 case OPC_NMSUB_D:
15468 case OPC_NMSUB_PS:
15469 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15470 break;
36d23958 15471 default:
923617a3 15472 MIPS_INVAL("cp3");
e397ee33 15473 generate_exception (ctx, EXCP_RI);
36d23958
TS
15474 break;
15475 }
15476 } else {
e397ee33 15477 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15478 }
4ad40f36
FB
15479 break;
15480
d26bc211 15481#if defined(TARGET_MIPS64)
7a387fff
TS
15482 /* MIPS64 opcodes */
15483 case OPC_LWU:
15484 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15485 case OPC_LLD:
15486 case OPC_LD:
5c13fdfd
AJ
15487 check_insn(env, ctx, ISA_MIPS3);
15488 check_mips_64(ctx);
afa88c3a 15489 gen_ld(env, ctx, op, rt, rs, imm);
5c13fdfd
AJ
15490 break;
15491 case OPC_SDL ... OPC_SDR:
7a387fff 15492 case OPC_SD:
e189e748
TS
15493 check_insn(env, ctx, ISA_MIPS3);
15494 check_mips_64(ctx);
5c13fdfd 15495 gen_st(ctx, op, rt, rs, imm);
7a387fff 15496 break;
d66c7132
AJ
15497 case OPC_SCD:
15498 check_insn(env, ctx, ISA_MIPS3);
15499 check_mips_64(ctx);
15500 gen_st_cond(ctx, op, rt, rs, imm);
15501 break;
324d9e32
AJ
15502 case OPC_DADDI:
15503 case OPC_DADDIU:
e189e748
TS
15504 check_insn(env, ctx, ISA_MIPS3);
15505 check_mips_64(ctx);
15506 gen_arith_imm(env, ctx, op, rt, rs, imm);
7a387fff 15507 break;
6af0bf9c 15508#endif
7a387fff 15509 case OPC_JALX:
3c824109 15510 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15511 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15512 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15513 *is_branch = 1;
15514 break;
7a387fff 15515 case OPC_MDMX:
e189e748 15516 check_insn(env, ctx, ASE_MDMX);
7a387fff 15517 /* MDMX: Not implemented. */
6af0bf9c 15518 default: /* Invalid */
923617a3 15519 MIPS_INVAL("major opcode");
6af0bf9c
FB
15520 generate_exception(ctx, EXCP_RI);
15521 break;
15522 }
6af0bf9c
FB
15523}
15524
2cfc5f17 15525static inline void
7db13fae 15526gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
820e00f2 15527 int search_pc)
6af0bf9c 15528{
278d0702 15529 DisasContext ctx;
6af0bf9c
FB
15530 target_ulong pc_start;
15531 uint16_t *gen_opc_end;
a1d1bb31 15532 CPUBreakpoint *bp;
6af0bf9c 15533 int j, lj = -1;
2e70f6ef
PB
15534 int num_insns;
15535 int max_insns;
c9602061
NF
15536 int insn_bytes;
15537 int is_branch;
6af0bf9c 15538
93fcfe39
AL
15539 if (search_pc)
15540 qemu_log("search pc %d\n", search_pc);
4ad40f36 15541
6af0bf9c 15542 pc_start = tb->pc;
92414b31 15543 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15544 ctx.pc = pc_start;
4ad40f36 15545 ctx.saved_pc = -1;
7b270ef2 15546 ctx.singlestep_enabled = env->singlestep_enabled;
6af0bf9c
FB
15547 ctx.tb = tb;
15548 ctx.bstate = BS_NONE;
4ad40f36 15549 /* Restore delay slot state from the tb context. */
c068688b 15550 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
fd4a04eb 15551 restore_cpu_state(env, &ctx);
932e71cd 15552#ifdef CONFIG_USER_ONLY
0eaef5aa 15553 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15554#else
0eaef5aa 15555 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15556#endif
2e70f6ef
PB
15557 num_insns = 0;
15558 max_insns = tb->cflags & CF_COUNT_MASK;
15559 if (max_insns == 0)
15560 max_insns = CF_COUNT_MASK;
d12d51d5 15561 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
2e70f6ef 15562 gen_icount_start();
faf7aaa9 15563 while (ctx.bstate == BS_NONE) {
72cf2d4f
BS
15564 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15565 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 15566 if (bp->pc == ctx.pc) {
278d0702 15567 save_cpu_state(&ctx, 1);
4ad40f36 15568 ctx.bstate = BS_BRANCH;
895c2d04 15569 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15570 /* Include the breakpoint location or the tb won't
15571 * be flushed when it must be. */
15572 ctx.pc += 4;
4ad40f36
FB
15573 goto done_generating;
15574 }
15575 }
15576 }
15577
6af0bf9c 15578 if (search_pc) {
92414b31 15579 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15580 if (lj < j) {
15581 lj++;
15582 while (lj < j)
ab1103de 15583 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 15584 }
25983cad 15585 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 15586 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15587 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 15588 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 15589 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 15590 }
2e70f6ef
PB
15591 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15592 gen_io_start();
c9602061
NF
15593
15594 is_branch = 0;
364d4831 15595 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15596 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061
NF
15597 insn_bytes = 4;
15598 decode_opc(env, &ctx, &is_branch);
3c824109 15599 } else if (env->insn_flags & ASE_MICROMIPS) {
895c2d04 15600 ctx.opcode = cpu_lduw_code(env, ctx.pc);
3c824109 15601 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
364d4831 15602 } else if (env->insn_flags & ASE_MIPS16) {
895c2d04 15603 ctx.opcode = cpu_lduw_code(env, ctx.pc);
364d4831 15604 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
c9602061
NF
15605 } else {
15606 generate_exception(&ctx, EXCP_RI);
3c824109 15607 ctx.bstate = BS_STOP;
c9602061
NF
15608 break;
15609 }
15610 if (!is_branch) {
15611 handle_delay_slot(env, &ctx, insn_bytes);
15612 }
15613 ctx.pc += insn_bytes;
15614
2e70f6ef 15615 num_insns++;
4ad40f36 15616
7b270ef2
NF
15617 /* Execute a branch and its delay slot as a single instruction.
15618 This is what GDB expects and is consistent with what the
15619 hardware does (e.g. if a delay slot instruction faults, the
15620 reported PC is the PC of the branch). */
15621 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
4ad40f36
FB
15622 break;
15623
6af0bf9c
FB
15624 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15625 break;
4ad40f36 15626
efd7f486 15627 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 15628 break;
efd7f486 15629 }
faf7aaa9 15630
2e70f6ef
PB
15631 if (num_insns >= max_insns)
15632 break;
1b530a6d
AJ
15633
15634 if (singlestep)
15635 break;
6af0bf9c 15636 }
2e70f6ef
PB
15637 if (tb->cflags & CF_LAST_IO)
15638 gen_io_end();
7b270ef2 15639 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15640 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15641 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15642 } else {
6958549d 15643 switch (ctx.bstate) {
16c00cb2 15644 case BS_STOP:
df1561e2
TS
15645 gen_goto_tb(&ctx, 0, ctx.pc);
15646 break;
16c00cb2 15647 case BS_NONE:
278d0702 15648 save_cpu_state(&ctx, 0);
16c00cb2
TS
15649 gen_goto_tb(&ctx, 0, ctx.pc);
15650 break;
5a5012ec 15651 case BS_EXCP:
57fec1fe 15652 tcg_gen_exit_tb(0);
16c00cb2 15653 break;
5a5012ec
TS
15654 case BS_BRANCH:
15655 default:
15656 break;
6958549d 15657 }
6af0bf9c 15658 }
4ad40f36 15659done_generating:
2e70f6ef 15660 gen_icount_end(tb, num_insns);
efd7f486 15661 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 15662 if (search_pc) {
92414b31 15663 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
15664 lj++;
15665 while (lj <= j)
ab1103de 15666 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15667 } else {
15668 tb->size = ctx.pc - pc_start;
2e70f6ef 15669 tb->icount = num_insns;
6af0bf9c
FB
15670 }
15671#ifdef DEBUG_DISAS
d12d51d5 15672 LOG_DISAS("\n");
8fec2b8c 15673 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 15674 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 15675 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 15676 qemu_log("\n");
6af0bf9c
FB
15677 }
15678#endif
6af0bf9c
FB
15679}
15680
7db13fae 15681void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15682{
2cfc5f17 15683 gen_intermediate_code_internal(env, tb, 0);
6af0bf9c
FB
15684}
15685
7db13fae 15686void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15687{
2cfc5f17 15688 gen_intermediate_code_internal(env, tb, 1);
6af0bf9c
FB
15689}
15690
7db13fae 15691static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15692 int flags)
6ea83fed
FB
15693{
15694 int i;
5e755519 15695 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15696
2a5612e6
SW
15697#define printfpr(fp) \
15698 do { \
15699 if (is_fpu64) \
15700 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15701 " fd:%13g fs:%13g psu: %13g\n", \
15702 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15703 (double)(fp)->fd, \
15704 (double)(fp)->fs[FP_ENDIAN_IDX], \
15705 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15706 else { \
15707 fpr_t tmp; \
15708 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15709 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15710 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15711 " fd:%13g fs:%13g psu:%13g\n", \
15712 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15713 (double)tmp.fd, \
15714 (double)tmp.fs[FP_ENDIAN_IDX], \
15715 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15716 } \
6ea83fed
FB
15717 } while(0)
15718
5a5012ec 15719
9a78eead
SW
15720 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15721 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15722 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15723 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15724 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15725 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15726 }
15727
15728#undef printfpr
15729}
15730
d26bc211 15731#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15732/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15733 sign-extended values on 64bit machines. */
c570fd16
TS
15734
15735#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15736
8706c382 15737static void
7db13fae 15738cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15739 fprintf_function cpu_fprintf,
8706c382 15740 int flags)
c570fd16
TS
15741{
15742 int i;
15743
b5dc7732
TS
15744 if (!SIGN_EXT_P(env->active_tc.PC))
15745 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15746 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15747 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15748 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15749 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15750 if (!SIGN_EXT_P(env->btarget))
3594c774 15751 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15752
15753 for (i = 0; i < 32; i++) {
b5dc7732
TS
15754 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15755 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15756 }
15757
15758 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15759 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15760 if (!SIGN_EXT_P(env->lladdr))
15761 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15762}
15763#endif
15764
7db13fae 15765void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
6af0bf9c
FB
15766 int flags)
15767{
15768 int i;
3b46e624 15769
a7200c9f
SW
15770 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15771 " LO=0x" TARGET_FMT_lx " ds %04x "
15772 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15773 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15774 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15775 for (i = 0; i < 32; i++) {
15776 if ((i & 3) == 0)
15777 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15778 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15779 if ((i & 3) == 3)
15780 cpu_fprintf(f, "\n");
15781 }
568b600d 15782
3594c774 15783 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15784 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15785 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15786 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15787 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15788 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15789#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15790 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15791#endif
6af0bf9c
FB
15792}
15793
39454628
TS
15794static void mips_tcg_init(void)
15795{
f01be154 15796 int i;
39454628
TS
15797 static int inited;
15798
15799 /* Initialize various static tables. */
15800 if (inited)
6958549d 15801 return;
39454628 15802
a7812ae4 15803 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15804 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15805 for (i = 1; i < 32; i++)
a7812ae4 15806 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15807 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15808 regnames[i]);
d73ee8a2
RH
15809
15810 for (i = 0; i < 32; i++) {
15811 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15812 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15813 }
15814
a7812ae4 15815 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15816 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15817 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15818 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15819 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15820 regnames_HI[i]);
a7812ae4 15821 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15822 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15823 regnames_LO[i]);
a7812ae4 15824 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15825 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15826 regnames_ACX[i]);
15827 }
a7812ae4 15828 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15829 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15830 "DSPControl");
1ba74fb8 15831 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15832 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15833 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15834 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15835 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15836 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15837
a7812ae4 15838 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15839 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15840 "fcr0");
15841 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15842 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15843 "fcr31");
39454628 15844
7dd9e556 15845 /* register helpers */
a7812ae4 15846#define GEN_HELPER 2
7dd9e556
TS
15847#include "helper.h"
15848
39454628
TS
15849 inited = 1;
15850}
15851
aaed909a
FB
15852#include "translate_init.c"
15853
30bf942d 15854MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15855{
0f71a709 15856 MIPSCPU *cpu;
6af0bf9c 15857 CPUMIPSState *env;
c227f099 15858 const mips_def_t *def;
6af0bf9c 15859
aaed909a
FB
15860 def = cpu_mips_find_by_name(cpu_model);
15861 if (!def)
15862 return NULL;
0f71a709
AF
15863 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15864 env = &cpu->env;
aaed909a 15865 env->cpu_model = def;
51cc2e78 15866 env->cpu_model_str = cpu_model;
aaed909a 15867
51cc2e78
BS
15868#ifndef CONFIG_USER_ONLY
15869 mmu_init(env, def);
15870#endif
15871 fpu_init(env, def);
15872 mvp_init(env, def);
39454628 15873 mips_tcg_init();
3bd4122e 15874 cpu_reset(CPU(cpu));
0bf46a40 15875 qemu_init_vcpu(env);
30bf942d 15876 return cpu;
6ae81775
TS
15877}
15878
1bba0dc9 15879void cpu_state_reset(CPUMIPSState *env)
6ae81775 15880{
55e5c285
AF
15881#ifndef CONFIG_USER_ONLY
15882 MIPSCPU *cpu = mips_env_get_cpu(env);
15883 CPUState *cs = CPU(cpu);
15884#endif
6ae81775 15885
51cc2e78
BS
15886 /* Reset registers to their default values */
15887 env->CP0_PRid = env->cpu_model->CP0_PRid;
15888 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15889#ifdef TARGET_WORDS_BIGENDIAN
15890 env->CP0_Config0 |= (1 << CP0C0_BE);
15891#endif
15892 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15893 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15894 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15895 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15896 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
15897 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15898 << env->cpu_model->CP0_LLAddr_shift;
15899 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
15900 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15901 env->CCRes = env->cpu_model->CCRes;
15902 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15903 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15904 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15905 env->current_tc = 0;
15906 env->SEGBITS = env->cpu_model->SEGBITS;
15907 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15908#if defined(TARGET_MIPS64)
15909 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15910 env->SEGMask |= 3ULL << 62;
15911 }
15912#endif
15913 env->PABITS = env->cpu_model->PABITS;
15914 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15915 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15916 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15917 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15918 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15919 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15920 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15921 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15922 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15923 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15924 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 15925 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
15926 env->insn_flags = env->cpu_model->insn_flags;
15927
0eaef5aa 15928#if defined(CONFIG_USER_ONLY)
03e6e501 15929 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
94159135
MI
15930 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15931 hardware registers. */
15932 env->CP0_HWREna |= 0x0000000F;
91a75935 15933 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 15934 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 15935 }
853c3240
JL
15936 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15937 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15938 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15939 env->hflags |= MIPS_HFLAG_DSP;
15940 }
932e71cd
AJ
15941#else
15942 if (env->hflags & MIPS_HFLAG_BMASK) {
15943 /* If the exception was raised from a delay slot,
15944 come back to the jump. */
15945 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 15946 } else {
932e71cd
AJ
15947 env->CP0_ErrorEPC = env->active_tc.PC;
15948 }
15949 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
15950 env->CP0_Random = env->tlb->nb_tlb - 1;
15951 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 15952 env->CP0_Wired = 0;
55e5c285 15953 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
932e71cd
AJ
15954 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15955 /* vectored interrupts not implemented, timer on int 7,
15956 no performance counters. */
15957 env->CP0_IntCtl = 0xe0000000;
15958 {
15959 int i;
15960
15961 for (i = 0; i < 7; i++) {
15962 env->CP0_WatchLo[i] = 0;
15963 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 15964 }
932e71cd
AJ
15965 env->CP0_WatchLo[7] = 0;
15966 env->CP0_WatchHi[7] = 0;
fd88b6ab 15967 }
932e71cd
AJ
15968 /* Count register increments in debug mode, EJTAG version 1 */
15969 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756
EI
15970
15971 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15972 int i;
15973
15974 /* Only TC0 on VPE 0 starts as active. */
15975 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 15976 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
15977 env->tcs[i].CP0_TCHalt = 1;
15978 }
15979 env->active_tc.CP0_TCHalt = 1;
15980 env->halted = 1;
15981
55e5c285 15982 if (cs->cpu_index == 0) {
9e56e756
EI
15983 /* VPE0 starts up enabled. */
15984 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15985 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15986
15987 /* TC0 starts up unhalted. */
15988 env->halted = 0;
15989 env->active_tc.CP0_TCHalt = 0;
15990 env->tcs[0].CP0_TCHalt = 0;
15991 /* With thread 0 active. */
15992 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15993 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15994 }
15995 }
51cc2e78 15996#endif
03e6e501 15997 compute_hflags(env);
6af0bf9c 15998 env->exception_index = EXCP_NONE;
6af0bf9c 15999}
d2856f1a 16000
7db13fae 16001void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16002{
25983cad 16003 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16004 env->hflags &= ~MIPS_HFLAG_BMASK;
16005 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16006 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16007 case MIPS_HFLAG_BR:
16008 break;
16009 case MIPS_HFLAG_BC:
16010 case MIPS_HFLAG_BL:
16011 case MIPS_HFLAG_B:
16012 env->btarget = gen_opc_btarget[pc_pos];
16013 break;
16014 }
d2856f1a 16015}