]> git.proxmox.com Git - mirror_qemu.git/blob - target/mips/translate.c
mips: Add KVM T&E segment support for TCG
[mirror_qemu.git] / target / mips / translate.c
1 /*
2 * MIPS32 emulation for qemu: main translation routines.
3 *
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
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
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "qemu/osdep.h"
25 #include "cpu.h"
26 #include "disas/disas.h"
27 #include "exec/exec-all.h"
28 #include "tcg-op.h"
29 #include "exec/cpu_ldst.h"
30 #include "hw/mips/cpudevs.h"
31
32 #include "exec/helper-proto.h"
33 #include "exec/helper-gen.h"
34 #include "exec/semihost.h"
35
36 #include "target/mips/trace.h"
37 #include "trace-tcg.h"
38 #include "exec/log.h"
39
40 #define MIPS_DEBUG_DISAS 0
41
42 /* MIPS major opcodes */
43 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
44
45 enum {
46 /* indirect opcode tables */
47 OPC_SPECIAL = (0x00 << 26),
48 OPC_REGIMM = (0x01 << 26),
49 OPC_CP0 = (0x10 << 26),
50 OPC_CP1 = (0x11 << 26),
51 OPC_CP2 = (0x12 << 26),
52 OPC_CP3 = (0x13 << 26),
53 OPC_SPECIAL2 = (0x1C << 26),
54 OPC_SPECIAL3 = (0x1F << 26),
55 /* arithmetic with immediate */
56 OPC_ADDI = (0x08 << 26),
57 OPC_ADDIU = (0x09 << 26),
58 OPC_SLTI = (0x0A << 26),
59 OPC_SLTIU = (0x0B << 26),
60 /* logic with immediate */
61 OPC_ANDI = (0x0C << 26),
62 OPC_ORI = (0x0D << 26),
63 OPC_XORI = (0x0E << 26),
64 OPC_LUI = (0x0F << 26),
65 /* arithmetic with immediate */
66 OPC_DADDI = (0x18 << 26),
67 OPC_DADDIU = (0x19 << 26),
68 /* Jump and branches */
69 OPC_J = (0x02 << 26),
70 OPC_JAL = (0x03 << 26),
71 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
72 OPC_BEQL = (0x14 << 26),
73 OPC_BNE = (0x05 << 26),
74 OPC_BNEL = (0x15 << 26),
75 OPC_BLEZ = (0x06 << 26),
76 OPC_BLEZL = (0x16 << 26),
77 OPC_BGTZ = (0x07 << 26),
78 OPC_BGTZL = (0x17 << 26),
79 OPC_JALX = (0x1D << 26),
80 OPC_DAUI = (0x1D << 26),
81 /* Load and stores */
82 OPC_LDL = (0x1A << 26),
83 OPC_LDR = (0x1B << 26),
84 OPC_LB = (0x20 << 26),
85 OPC_LH = (0x21 << 26),
86 OPC_LWL = (0x22 << 26),
87 OPC_LW = (0x23 << 26),
88 OPC_LWPC = OPC_LW | 0x5,
89 OPC_LBU = (0x24 << 26),
90 OPC_LHU = (0x25 << 26),
91 OPC_LWR = (0x26 << 26),
92 OPC_LWU = (0x27 << 26),
93 OPC_SB = (0x28 << 26),
94 OPC_SH = (0x29 << 26),
95 OPC_SWL = (0x2A << 26),
96 OPC_SW = (0x2B << 26),
97 OPC_SDL = (0x2C << 26),
98 OPC_SDR = (0x2D << 26),
99 OPC_SWR = (0x2E << 26),
100 OPC_LL = (0x30 << 26),
101 OPC_LLD = (0x34 << 26),
102 OPC_LD = (0x37 << 26),
103 OPC_LDPC = OPC_LD | 0x5,
104 OPC_SC = (0x38 << 26),
105 OPC_SCD = (0x3C << 26),
106 OPC_SD = (0x3F << 26),
107 /* Floating point load/store */
108 OPC_LWC1 = (0x31 << 26),
109 OPC_LWC2 = (0x32 << 26),
110 OPC_LDC1 = (0x35 << 26),
111 OPC_LDC2 = (0x36 << 26),
112 OPC_SWC1 = (0x39 << 26),
113 OPC_SWC2 = (0x3A << 26),
114 OPC_SDC1 = (0x3D << 26),
115 OPC_SDC2 = (0x3E << 26),
116 /* Compact Branches */
117 OPC_BLEZALC = (0x06 << 26),
118 OPC_BGEZALC = (0x06 << 26),
119 OPC_BGEUC = (0x06 << 26),
120 OPC_BGTZALC = (0x07 << 26),
121 OPC_BLTZALC = (0x07 << 26),
122 OPC_BLTUC = (0x07 << 26),
123 OPC_BOVC = (0x08 << 26),
124 OPC_BEQZALC = (0x08 << 26),
125 OPC_BEQC = (0x08 << 26),
126 OPC_BLEZC = (0x16 << 26),
127 OPC_BGEZC = (0x16 << 26),
128 OPC_BGEC = (0x16 << 26),
129 OPC_BGTZC = (0x17 << 26),
130 OPC_BLTZC = (0x17 << 26),
131 OPC_BLTC = (0x17 << 26),
132 OPC_BNVC = (0x18 << 26),
133 OPC_BNEZALC = (0x18 << 26),
134 OPC_BNEC = (0x18 << 26),
135 OPC_BC = (0x32 << 26),
136 OPC_BEQZC = (0x36 << 26),
137 OPC_JIC = (0x36 << 26),
138 OPC_BALC = (0x3A << 26),
139 OPC_BNEZC = (0x3E << 26),
140 OPC_JIALC = (0x3E << 26),
141 /* MDMX ASE specific */
142 OPC_MDMX = (0x1E << 26),
143 /* MSA ASE, same as MDMX */
144 OPC_MSA = OPC_MDMX,
145 /* Cache and prefetch */
146 OPC_CACHE = (0x2F << 26),
147 OPC_PREF = (0x33 << 26),
148 /* PC-relative address computation / loads */
149 OPC_PCREL = (0x3B << 26),
150 };
151
152 /* PC-relative address computation / loads */
153 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
154 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
155 enum {
156 /* Instructions determined by bits 19 and 20 */
157 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
158 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
159 OPC_LWUPC = OPC_PCREL | (2 << 19),
160
161 /* Instructions determined by bits 16 ... 20 */
162 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
163 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
164
165 /* Other */
166 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
167 };
168
169 /* MIPS special opcodes */
170 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
171
172 enum {
173 /* Shifts */
174 OPC_SLL = 0x00 | OPC_SPECIAL,
175 /* NOP is SLL r0, r0, 0 */
176 /* SSNOP is SLL r0, r0, 1 */
177 /* EHB is SLL r0, r0, 3 */
178 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
179 OPC_ROTR = OPC_SRL | (1 << 21),
180 OPC_SRA = 0x03 | OPC_SPECIAL,
181 OPC_SLLV = 0x04 | OPC_SPECIAL,
182 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
183 OPC_ROTRV = OPC_SRLV | (1 << 6),
184 OPC_SRAV = 0x07 | OPC_SPECIAL,
185 OPC_DSLLV = 0x14 | OPC_SPECIAL,
186 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
187 OPC_DROTRV = OPC_DSRLV | (1 << 6),
188 OPC_DSRAV = 0x17 | OPC_SPECIAL,
189 OPC_DSLL = 0x38 | OPC_SPECIAL,
190 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
191 OPC_DROTR = OPC_DSRL | (1 << 21),
192 OPC_DSRA = 0x3B | OPC_SPECIAL,
193 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
194 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
195 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
196 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
197 /* Multiplication / division */
198 OPC_MULT = 0x18 | OPC_SPECIAL,
199 OPC_MULTU = 0x19 | OPC_SPECIAL,
200 OPC_DIV = 0x1A | OPC_SPECIAL,
201 OPC_DIVU = 0x1B | OPC_SPECIAL,
202 OPC_DMULT = 0x1C | OPC_SPECIAL,
203 OPC_DMULTU = 0x1D | OPC_SPECIAL,
204 OPC_DDIV = 0x1E | OPC_SPECIAL,
205 OPC_DDIVU = 0x1F | OPC_SPECIAL,
206
207 /* 2 registers arithmetic / logic */
208 OPC_ADD = 0x20 | OPC_SPECIAL,
209 OPC_ADDU = 0x21 | OPC_SPECIAL,
210 OPC_SUB = 0x22 | OPC_SPECIAL,
211 OPC_SUBU = 0x23 | OPC_SPECIAL,
212 OPC_AND = 0x24 | OPC_SPECIAL,
213 OPC_OR = 0x25 | OPC_SPECIAL,
214 OPC_XOR = 0x26 | OPC_SPECIAL,
215 OPC_NOR = 0x27 | OPC_SPECIAL,
216 OPC_SLT = 0x2A | OPC_SPECIAL,
217 OPC_SLTU = 0x2B | OPC_SPECIAL,
218 OPC_DADD = 0x2C | OPC_SPECIAL,
219 OPC_DADDU = 0x2D | OPC_SPECIAL,
220 OPC_DSUB = 0x2E | OPC_SPECIAL,
221 OPC_DSUBU = 0x2F | OPC_SPECIAL,
222 /* Jumps */
223 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
224 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
225 /* Traps */
226 OPC_TGE = 0x30 | OPC_SPECIAL,
227 OPC_TGEU = 0x31 | OPC_SPECIAL,
228 OPC_TLT = 0x32 | OPC_SPECIAL,
229 OPC_TLTU = 0x33 | OPC_SPECIAL,
230 OPC_TEQ = 0x34 | OPC_SPECIAL,
231 OPC_TNE = 0x36 | OPC_SPECIAL,
232 /* HI / LO registers load & stores */
233 OPC_MFHI = 0x10 | OPC_SPECIAL,
234 OPC_MTHI = 0x11 | OPC_SPECIAL,
235 OPC_MFLO = 0x12 | OPC_SPECIAL,
236 OPC_MTLO = 0x13 | OPC_SPECIAL,
237 /* Conditional moves */
238 OPC_MOVZ = 0x0A | OPC_SPECIAL,
239 OPC_MOVN = 0x0B | OPC_SPECIAL,
240
241 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
242 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
243
244 OPC_MOVCI = 0x01 | OPC_SPECIAL,
245
246 /* Special */
247 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
248 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
249 OPC_BREAK = 0x0D | OPC_SPECIAL,
250 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
251 OPC_SYNC = 0x0F | OPC_SPECIAL,
252
253 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
254 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
255 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
256 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
257 };
258
259 /* R6 Multiply and Divide instructions have the same Opcode
260 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
261 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
262
263 enum {
264 R6_OPC_MUL = OPC_MULT | (2 << 6),
265 R6_OPC_MUH = OPC_MULT | (3 << 6),
266 R6_OPC_MULU = OPC_MULTU | (2 << 6),
267 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
268 R6_OPC_DIV = OPC_DIV | (2 << 6),
269 R6_OPC_MOD = OPC_DIV | (3 << 6),
270 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
271 R6_OPC_MODU = OPC_DIVU | (3 << 6),
272
273 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
274 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
275 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
276 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
277 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
278 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
279 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
280 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
281
282 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
283 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
284 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
285 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
286 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
287
288 OPC_LSA = 0x05 | OPC_SPECIAL,
289 OPC_DLSA = 0x15 | OPC_SPECIAL,
290 };
291
292 /* Multiplication variants of the vr54xx. */
293 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
294
295 enum {
296 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
297 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
298 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
299 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
300 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
301 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
302 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
303 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
304 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
305 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
306 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
307 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
308 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
309 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
310 };
311
312 /* REGIMM (rt field) opcodes */
313 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
314
315 enum {
316 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
317 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
318 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
319 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
320 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
321 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
322 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
323 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
324 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
325 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
326 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
327 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
328 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
329 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
330 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
331 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
332
333 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
334 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
335 };
336
337 /* Special2 opcodes */
338 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
339
340 enum {
341 /* Multiply & xxx operations */
342 OPC_MADD = 0x00 | OPC_SPECIAL2,
343 OPC_MADDU = 0x01 | OPC_SPECIAL2,
344 OPC_MUL = 0x02 | OPC_SPECIAL2,
345 OPC_MSUB = 0x04 | OPC_SPECIAL2,
346 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
347 /* Loongson 2F */
348 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
349 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
350 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
351 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
352 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
353 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
354 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
355 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
356 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
357 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
358 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
359 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
360 /* Misc */
361 OPC_CLZ = 0x20 | OPC_SPECIAL2,
362 OPC_CLO = 0x21 | OPC_SPECIAL2,
363 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
364 OPC_DCLO = 0x25 | OPC_SPECIAL2,
365 /* Special */
366 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
367 };
368
369 /* Special3 opcodes */
370 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
371
372 enum {
373 OPC_EXT = 0x00 | OPC_SPECIAL3,
374 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
375 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
376 OPC_DEXT = 0x03 | OPC_SPECIAL3,
377 OPC_INS = 0x04 | OPC_SPECIAL3,
378 OPC_DINSM = 0x05 | OPC_SPECIAL3,
379 OPC_DINSU = 0x06 | OPC_SPECIAL3,
380 OPC_DINS = 0x07 | OPC_SPECIAL3,
381 OPC_FORK = 0x08 | OPC_SPECIAL3,
382 OPC_YIELD = 0x09 | OPC_SPECIAL3,
383 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
384 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
385 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
386
387 /* Loongson 2E */
388 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
389 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
390 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
391 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
392 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
393 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
394 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
395 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
396 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
397 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
398 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
399 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
400
401 /* MIPS DSP Load */
402 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
403 /* MIPS DSP Arithmetic */
404 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
405 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
406 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
407 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
408 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
409 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
410 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
411 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
412 /* MIPS DSP GPR-Based Shift Sub-class */
413 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
414 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
415 /* MIPS DSP Multiply Sub-class insns */
416 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
417 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
418 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
419 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
420 /* DSP Bit/Manipulation Sub-class */
421 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
422 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
423 /* MIPS DSP Append Sub-class */
424 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
425 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
426 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
427 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
428 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
429
430 /* EVA */
431 OPC_LWLE = 0x19 | OPC_SPECIAL3,
432 OPC_LWRE = 0x1A | OPC_SPECIAL3,
433 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
434 OPC_SBE = 0x1C | OPC_SPECIAL3,
435 OPC_SHE = 0x1D | OPC_SPECIAL3,
436 OPC_SCE = 0x1E | OPC_SPECIAL3,
437 OPC_SWE = 0x1F | OPC_SPECIAL3,
438 OPC_SWLE = 0x21 | OPC_SPECIAL3,
439 OPC_SWRE = 0x22 | OPC_SPECIAL3,
440 OPC_PREFE = 0x23 | OPC_SPECIAL3,
441 OPC_LBUE = 0x28 | OPC_SPECIAL3,
442 OPC_LHUE = 0x29 | OPC_SPECIAL3,
443 OPC_LBE = 0x2C | OPC_SPECIAL3,
444 OPC_LHE = 0x2D | OPC_SPECIAL3,
445 OPC_LLE = 0x2E | OPC_SPECIAL3,
446 OPC_LWE = 0x2F | OPC_SPECIAL3,
447
448 /* R6 */
449 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
450 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
451 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
452 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
453 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
454 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
455 };
456
457 /* BSHFL opcodes */
458 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
459
460 enum {
461 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
462 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
463 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
464 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
465 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
466 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
467 };
468
469 /* DBSHFL opcodes */
470 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
471
472 enum {
473 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
474 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
475 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
476 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
477 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
478 };
479
480 /* MIPS DSP REGIMM opcodes */
481 enum {
482 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
483 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
484 };
485
486 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
487 /* MIPS DSP Load */
488 enum {
489 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
490 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
491 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
492 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
493 };
494
495 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
496 enum {
497 /* MIPS DSP Arithmetic Sub-class */
498 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
499 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
500 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
501 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
502 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
503 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
504 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
505 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
506 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
507 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
508 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
509 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
510 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
511 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
512 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
513 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
514 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
515 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
516 /* MIPS DSP Multiply Sub-class insns */
517 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
518 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
519 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
520 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
521 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
522 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
523 };
524
525 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
526 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
527 enum {
528 /* MIPS DSP Arithmetic Sub-class */
529 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
530 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
531 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
532 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
533 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
534 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
535 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
536 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
537 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
538 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
539 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
541 /* MIPS DSP Multiply Sub-class insns */
542 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
543 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
544 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
545 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
546 };
547
548 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
549 enum {
550 /* MIPS DSP Arithmetic Sub-class */
551 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
552 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
553 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
554 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
555 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
556 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
557 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
558 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
559 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
560 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
561 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
564 /* DSP Bit/Manipulation Sub-class */
565 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
566 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
567 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
570 };
571
572 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
573 enum {
574 /* MIPS DSP Arithmetic Sub-class */
575 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
579 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
580 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
581 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
582 /* DSP Compare-Pick Sub-class */
583 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
584 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
585 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
592 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
593 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
598 };
599
600 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
601 enum {
602 /* MIPS DSP GPR-Based Shift Sub-class */
603 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
605 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
606 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
607 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
608 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
609 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
610 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
611 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
612 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
613 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
625 };
626
627 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
628 enum {
629 /* MIPS DSP Multiply Sub-class insns */
630 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
632 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
633 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
634 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
635 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
636 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
637 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
638 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
639 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
640 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
644 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
646 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
647 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
648 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
649 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
652 };
653
654 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
655 enum {
656 /* DSP Bit/Manipulation Sub-class */
657 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
658 };
659
660 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
661 enum {
662 /* MIPS DSP Append Sub-class */
663 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
664 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
665 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
666 };
667
668 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669 enum {
670 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
671 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
672 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
673 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
674 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
675 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
676 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
677 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
678 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
679 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
680 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
681 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
683 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
684 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
685 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
686 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
687 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
688 };
689
690 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
691 enum {
692 /* MIPS DSP Arithmetic Sub-class */
693 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
698 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
699 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
700 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
701 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
702 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
703 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
710 /* DSP Bit/Manipulation Sub-class */
711 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
712 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
713 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
717 };
718
719 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
720 enum {
721 /* MIPS DSP Multiply Sub-class insns */
722 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
723 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
724 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
725 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
726 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
727 /* MIPS DSP Arithmetic Sub-class */
728 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
729 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
730 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
731 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
732 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
733 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
734 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
735 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
736 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
737 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
738 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
739 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
740 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
741 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
742 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
743 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
744 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
745 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
746 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
747 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
748 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
749 };
750
751 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
752 enum {
753 /* DSP Compare-Pick Sub-class */
754 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
763 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
764 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
773 /* MIPS DSP Arithmetic Sub-class */
774 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
775 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
776 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
782 };
783
784 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
785 enum {
786 /* DSP Append Sub-class */
787 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
788 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
789 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
790 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
791 };
792
793 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
794 enum {
795 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
796 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
797 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
798 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
799 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
800 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
801 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
802 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
803 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
804 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
805 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
806 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
807 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
817 };
818
819 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
820 enum {
821 /* DSP Bit/Manipulation Sub-class */
822 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
823 };
824
825 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
826 enum {
827 /* MIPS DSP Multiply Sub-class insns */
828 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
835 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
836 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
837 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
838 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
854 };
855
856 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
857 enum {
858 /* MIPS DSP GPR-Based Shift Sub-class */
859 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
866 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
867 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
868 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
869 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
885 };
886
887 /* Coprocessor 0 (rs field) */
888 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
889
890 enum {
891 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
892 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
893 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
894 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
895 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
896 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
897 OPC_MFTR = (0x08 << 21) | OPC_CP0,
898 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
899 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
900 OPC_MTTR = (0x0C << 21) | OPC_CP0,
901 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
902 OPC_C0 = (0x10 << 21) | OPC_CP0,
903 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
904 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
905 };
906
907 /* MFMC0 opcodes */
908 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
909
910 enum {
911 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
912 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
913 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
914 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
915 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
916 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
917 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
918 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
919 };
920
921 /* Coprocessor 0 (with rs == C0) */
922 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
923
924 enum {
925 OPC_TLBR = 0x01 | OPC_C0,
926 OPC_TLBWI = 0x02 | OPC_C0,
927 OPC_TLBINV = 0x03 | OPC_C0,
928 OPC_TLBINVF = 0x04 | OPC_C0,
929 OPC_TLBWR = 0x06 | OPC_C0,
930 OPC_TLBP = 0x08 | OPC_C0,
931 OPC_RFE = 0x10 | OPC_C0,
932 OPC_ERET = 0x18 | OPC_C0,
933 OPC_DERET = 0x1F | OPC_C0,
934 OPC_WAIT = 0x20 | OPC_C0,
935 };
936
937 /* Coprocessor 1 (rs field) */
938 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
939
940 /* Values for the fmt field in FP instructions */
941 enum {
942 /* 0 - 15 are reserved */
943 FMT_S = 16, /* single fp */
944 FMT_D = 17, /* double fp */
945 FMT_E = 18, /* extended fp */
946 FMT_Q = 19, /* quad fp */
947 FMT_W = 20, /* 32-bit fixed */
948 FMT_L = 21, /* 64-bit fixed */
949 FMT_PS = 22, /* paired single fp */
950 /* 23 - 31 are reserved */
951 };
952
953 enum {
954 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
955 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
956 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
957 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
958 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
959 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
960 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
961 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
962 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
963 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
964 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
965 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
966 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
967 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
968 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
969 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
970 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
971 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
972 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
973 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
974 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
975 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
976 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
977 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
978 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
979 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
980 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
981 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
982 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
983 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
984 };
985
986 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
987 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
988
989 enum {
990 OPC_BC1F = (0x00 << 16) | OPC_BC1,
991 OPC_BC1T = (0x01 << 16) | OPC_BC1,
992 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
993 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
994 };
995
996 enum {
997 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
998 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
999 };
1000
1001 enum {
1002 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1003 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1004 };
1005
1006 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1007
1008 enum {
1009 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1010 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1011 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1012 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1013 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1014 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1015 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1016 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1017 OPC_BC2 = (0x08 << 21) | OPC_CP2,
1018 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1019 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1020 };
1021
1022 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1023
1024 enum {
1025 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1026 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1027 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1028 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1029 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1030 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1031 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1032 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1033
1034 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1035 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1036 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1037 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1038 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1039 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1040 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1041 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1042
1043 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1044 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1045 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1046 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1047 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1048 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1049 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1050 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1051
1052 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1053 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1054 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1055 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1056 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1057 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1058 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1059 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1060
1061 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1062 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1063 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1064 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1065 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1066 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1067
1068 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1069 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1070 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1071 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1072 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1073 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1074
1075 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1076 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1077 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1078 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1079 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1080 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1081
1082 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1083 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1084 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1085 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1086 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1087 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1088
1089 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1090 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1091 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1092 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1093 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1094 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1095
1096 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1097 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1098 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1099 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1100 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1101 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1102
1103 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1104 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1105 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1106 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1107 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1108 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1109
1110 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1111 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1112 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1113 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1114 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1115 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1116 };
1117
1118
1119 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1120
1121 enum {
1122 OPC_LWXC1 = 0x00 | OPC_CP3,
1123 OPC_LDXC1 = 0x01 | OPC_CP3,
1124 OPC_LUXC1 = 0x05 | OPC_CP3,
1125 OPC_SWXC1 = 0x08 | OPC_CP3,
1126 OPC_SDXC1 = 0x09 | OPC_CP3,
1127 OPC_SUXC1 = 0x0D | OPC_CP3,
1128 OPC_PREFX = 0x0F | OPC_CP3,
1129 OPC_ALNV_PS = 0x1E | OPC_CP3,
1130 OPC_MADD_S = 0x20 | OPC_CP3,
1131 OPC_MADD_D = 0x21 | OPC_CP3,
1132 OPC_MADD_PS = 0x26 | OPC_CP3,
1133 OPC_MSUB_S = 0x28 | OPC_CP3,
1134 OPC_MSUB_D = 0x29 | OPC_CP3,
1135 OPC_MSUB_PS = 0x2E | OPC_CP3,
1136 OPC_NMADD_S = 0x30 | OPC_CP3,
1137 OPC_NMADD_D = 0x31 | OPC_CP3,
1138 OPC_NMADD_PS= 0x36 | OPC_CP3,
1139 OPC_NMSUB_S = 0x38 | OPC_CP3,
1140 OPC_NMSUB_D = 0x39 | OPC_CP3,
1141 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1142 };
1143
1144 /* MSA Opcodes */
1145 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1146 enum {
1147 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1148 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1149 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1150 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1151 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1152 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1153 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1154 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1155 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1156 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1157 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1158 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1159 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1160 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1161 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1162 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1163 OPC_MSA_ELM = 0x19 | OPC_MSA,
1164 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1165 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1166 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1167 OPC_MSA_VEC = 0x1E | OPC_MSA,
1168
1169 /* MI10 instruction */
1170 OPC_LD_B = (0x20) | OPC_MSA,
1171 OPC_LD_H = (0x21) | OPC_MSA,
1172 OPC_LD_W = (0x22) | OPC_MSA,
1173 OPC_LD_D = (0x23) | OPC_MSA,
1174 OPC_ST_B = (0x24) | OPC_MSA,
1175 OPC_ST_H = (0x25) | OPC_MSA,
1176 OPC_ST_W = (0x26) | OPC_MSA,
1177 OPC_ST_D = (0x27) | OPC_MSA,
1178 };
1179
1180 enum {
1181 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1182 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1183 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1184 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1185 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1186 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1187 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1188 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1189 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1190 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1191 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1192 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1193 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1194
1195 /* I8 instruction */
1196 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1197 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1198 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1199 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1200 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1201 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1202 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1203 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1204 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1205 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1206
1207 /* VEC/2R/2RF instruction */
1208 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1209 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1210 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1211 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1212 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1213 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1214 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1215
1216 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1217 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1218
1219 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1220 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1221 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1222 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1223 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1224
1225 /* 2RF instruction df(bit 16) = _w, _d */
1226 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1227 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1228 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1229 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1230 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1231 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1232 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1233 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1234 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1235 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1236 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1237 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1238 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1239 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1240 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1241 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1242
1243 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1244 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1245 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1246 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1247 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1248 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1249 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1250 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1251 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1252 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1253 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1254 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1255 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1256 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1257 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1258 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1259 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1260 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1261 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1262 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1263 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1264 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1265 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1266 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1267 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1268 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1269 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1270 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1271 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1272 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1273 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1274 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1275 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1276 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1277 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1278 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1279 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1280 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1281 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1282 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1283 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1284 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1285 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1286 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1287 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1288 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1289 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1290 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1291 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1292 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1293 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1294 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1295 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1296 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1297 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1298 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1299 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1300 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1301 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1302 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1303 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1304 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1305 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1306 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1307
1308 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1309 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1310 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1311 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1312 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1313 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1314 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1315 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1316 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1317 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1318
1319 /* 3RF instruction _df(bit 21) = _w, _d */
1320 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1321 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1322 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1323 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1324 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1325 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1326 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1327 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1328 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1329 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1330 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1331 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1332 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1333 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1334 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1335 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1336 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1337 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1338 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1339 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1340 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1341 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1342 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1343 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1345 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1346 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1347 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1348 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1349 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1350 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1351 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1352 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1353 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1354 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1355 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1356 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1357 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1358 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1359 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1360 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1361
1362 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1363 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1364 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1365 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1366 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1367 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1368 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1369 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1370 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1371 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1372 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1373 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1374 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1375 };
1376
1377 /* global register indices */
1378 static TCGv_env cpu_env;
1379 static TCGv cpu_gpr[32], cpu_PC;
1380 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1381 static TCGv cpu_dspctrl, btarget, bcond;
1382 static TCGv_i32 hflags;
1383 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1384 static TCGv_i64 fpu_f64[32];
1385 static TCGv_i64 msa_wr_d[64];
1386
1387 #include "exec/gen-icount.h"
1388
1389 #define gen_helper_0e0i(name, arg) do { \
1390 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1391 gen_helper_##name(cpu_env, helper_tmp); \
1392 tcg_temp_free_i32(helper_tmp); \
1393 } while(0)
1394
1395 #define gen_helper_0e1i(name, arg1, arg2) do { \
1396 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1397 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1398 tcg_temp_free_i32(helper_tmp); \
1399 } while(0)
1400
1401 #define gen_helper_1e0i(name, ret, arg1) do { \
1402 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1403 gen_helper_##name(ret, cpu_env, helper_tmp); \
1404 tcg_temp_free_i32(helper_tmp); \
1405 } while(0)
1406
1407 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1408 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1409 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1410 tcg_temp_free_i32(helper_tmp); \
1411 } while(0)
1412
1413 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1414 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1415 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1416 tcg_temp_free_i32(helper_tmp); \
1417 } while(0)
1418
1419 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1420 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1421 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1422 tcg_temp_free_i32(helper_tmp); \
1423 } while(0)
1424
1425 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1426 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1427 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1428 tcg_temp_free_i32(helper_tmp); \
1429 } while(0)
1430
1431 typedef struct DisasContext {
1432 struct TranslationBlock *tb;
1433 target_ulong pc, saved_pc;
1434 uint32_t opcode;
1435 int singlestep_enabled;
1436 int insn_flags;
1437 int32_t CP0_Config1;
1438 /* Routine used to access memory */
1439 int mem_idx;
1440 TCGMemOp default_tcg_memop_mask;
1441 uint32_t hflags, saved_hflags;
1442 int bstate;
1443 target_ulong btarget;
1444 bool ulri;
1445 int kscrexist;
1446 bool rxi;
1447 int ie;
1448 bool bi;
1449 bool bp;
1450 uint64_t PAMask;
1451 bool mvh;
1452 bool eva;
1453 bool sc;
1454 int CP0_LLAddr_shift;
1455 bool ps;
1456 bool vp;
1457 bool cmgcr;
1458 bool mrp;
1459 bool nan2008;
1460 bool abs2008;
1461 } DisasContext;
1462
1463 enum {
1464 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1465 * exception condition */
1466 BS_STOP = 1, /* We want to stop translation for any reason */
1467 BS_BRANCH = 2, /* We reached a branch condition */
1468 BS_EXCP = 3, /* We reached an exception condition */
1469 };
1470
1471 static const char * const regnames[] = {
1472 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1473 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1474 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1475 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1476 };
1477
1478 static const char * const regnames_HI[] = {
1479 "HI0", "HI1", "HI2", "HI3",
1480 };
1481
1482 static const char * const regnames_LO[] = {
1483 "LO0", "LO1", "LO2", "LO3",
1484 };
1485
1486 static const char * const fregnames[] = {
1487 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1488 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1489 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1490 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1491 };
1492
1493 static const char * const msaregnames[] = {
1494 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1495 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1496 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1497 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1498 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1499 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1500 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1501 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1502 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1503 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1504 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1505 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1506 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1507 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1508 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1509 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1510 };
1511
1512 #define LOG_DISAS(...) \
1513 do { \
1514 if (MIPS_DEBUG_DISAS) { \
1515 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1516 } \
1517 } while (0)
1518
1519 #define MIPS_INVAL(op) \
1520 do { \
1521 if (MIPS_DEBUG_DISAS) { \
1522 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1523 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1524 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1525 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
1526 } \
1527 } while (0)
1528
1529 /* General purpose registers moves. */
1530 static inline void gen_load_gpr (TCGv t, int reg)
1531 {
1532 if (reg == 0)
1533 tcg_gen_movi_tl(t, 0);
1534 else
1535 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1536 }
1537
1538 static inline void gen_store_gpr (TCGv t, int reg)
1539 {
1540 if (reg != 0)
1541 tcg_gen_mov_tl(cpu_gpr[reg], t);
1542 }
1543
1544 /* Moves to/from shadow registers. */
1545 static inline void gen_load_srsgpr (int from, int to)
1546 {
1547 TCGv t0 = tcg_temp_new();
1548
1549 if (from == 0)
1550 tcg_gen_movi_tl(t0, 0);
1551 else {
1552 TCGv_i32 t2 = tcg_temp_new_i32();
1553 TCGv_ptr addr = tcg_temp_new_ptr();
1554
1555 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1556 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1557 tcg_gen_andi_i32(t2, t2, 0xf);
1558 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1559 tcg_gen_ext_i32_ptr(addr, t2);
1560 tcg_gen_add_ptr(addr, cpu_env, addr);
1561
1562 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1563 tcg_temp_free_ptr(addr);
1564 tcg_temp_free_i32(t2);
1565 }
1566 gen_store_gpr(t0, to);
1567 tcg_temp_free(t0);
1568 }
1569
1570 static inline void gen_store_srsgpr (int from, int to)
1571 {
1572 if (to != 0) {
1573 TCGv t0 = tcg_temp_new();
1574 TCGv_i32 t2 = tcg_temp_new_i32();
1575 TCGv_ptr addr = tcg_temp_new_ptr();
1576
1577 gen_load_gpr(t0, from);
1578 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1579 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1580 tcg_gen_andi_i32(t2, t2, 0xf);
1581 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1582 tcg_gen_ext_i32_ptr(addr, t2);
1583 tcg_gen_add_ptr(addr, cpu_env, addr);
1584
1585 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1586 tcg_temp_free_ptr(addr);
1587 tcg_temp_free_i32(t2);
1588 tcg_temp_free(t0);
1589 }
1590 }
1591
1592 /* Tests */
1593 static inline void gen_save_pc(target_ulong pc)
1594 {
1595 tcg_gen_movi_tl(cpu_PC, pc);
1596 }
1597
1598 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1599 {
1600 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1601 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1602 gen_save_pc(ctx->pc);
1603 ctx->saved_pc = ctx->pc;
1604 }
1605 if (ctx->hflags != ctx->saved_hflags) {
1606 tcg_gen_movi_i32(hflags, ctx->hflags);
1607 ctx->saved_hflags = ctx->hflags;
1608 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1609 case MIPS_HFLAG_BR:
1610 break;
1611 case MIPS_HFLAG_BC:
1612 case MIPS_HFLAG_BL:
1613 case MIPS_HFLAG_B:
1614 tcg_gen_movi_tl(btarget, ctx->btarget);
1615 break;
1616 }
1617 }
1618 }
1619
1620 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1621 {
1622 ctx->saved_hflags = ctx->hflags;
1623 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1624 case MIPS_HFLAG_BR:
1625 break;
1626 case MIPS_HFLAG_BC:
1627 case MIPS_HFLAG_BL:
1628 case MIPS_HFLAG_B:
1629 ctx->btarget = env->btarget;
1630 break;
1631 }
1632 }
1633
1634 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1635 {
1636 TCGv_i32 texcp = tcg_const_i32(excp);
1637 TCGv_i32 terr = tcg_const_i32(err);
1638 save_cpu_state(ctx, 1);
1639 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1640 tcg_temp_free_i32(terr);
1641 tcg_temp_free_i32(texcp);
1642 ctx->bstate = BS_EXCP;
1643 }
1644
1645 static inline void generate_exception(DisasContext *ctx, int excp)
1646 {
1647 gen_helper_0e0i(raise_exception, excp);
1648 }
1649
1650 static inline void generate_exception_end(DisasContext *ctx, int excp)
1651 {
1652 generate_exception_err(ctx, excp, 0);
1653 }
1654
1655 /* Floating point register moves. */
1656 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1657 {
1658 if (ctx->hflags & MIPS_HFLAG_FRE) {
1659 generate_exception(ctx, EXCP_RI);
1660 }
1661 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1662 }
1663
1664 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1665 {
1666 TCGv_i64 t64;
1667 if (ctx->hflags & MIPS_HFLAG_FRE) {
1668 generate_exception(ctx, EXCP_RI);
1669 }
1670 t64 = tcg_temp_new_i64();
1671 tcg_gen_extu_i32_i64(t64, t);
1672 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1673 tcg_temp_free_i64(t64);
1674 }
1675
1676 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1677 {
1678 if (ctx->hflags & MIPS_HFLAG_F64) {
1679 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1680 } else {
1681 gen_load_fpr32(ctx, t, reg | 1);
1682 }
1683 }
1684
1685 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1686 {
1687 if (ctx->hflags & MIPS_HFLAG_F64) {
1688 TCGv_i64 t64 = tcg_temp_new_i64();
1689 tcg_gen_extu_i32_i64(t64, t);
1690 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1691 tcg_temp_free_i64(t64);
1692 } else {
1693 gen_store_fpr32(ctx, t, reg | 1);
1694 }
1695 }
1696
1697 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1698 {
1699 if (ctx->hflags & MIPS_HFLAG_F64) {
1700 tcg_gen_mov_i64(t, fpu_f64[reg]);
1701 } else {
1702 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1703 }
1704 }
1705
1706 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1707 {
1708 if (ctx->hflags & MIPS_HFLAG_F64) {
1709 tcg_gen_mov_i64(fpu_f64[reg], t);
1710 } else {
1711 TCGv_i64 t0;
1712 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1713 t0 = tcg_temp_new_i64();
1714 tcg_gen_shri_i64(t0, t, 32);
1715 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1716 tcg_temp_free_i64(t0);
1717 }
1718 }
1719
1720 static inline int get_fp_bit (int cc)
1721 {
1722 if (cc)
1723 return 24 + cc;
1724 else
1725 return 23;
1726 }
1727
1728 /* Addresses computation */
1729 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1730 {
1731 tcg_gen_add_tl(ret, arg0, arg1);
1732
1733 #if defined(TARGET_MIPS64)
1734 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1735 tcg_gen_ext32s_i64(ret, ret);
1736 }
1737 #endif
1738 }
1739
1740 /* Addresses computation (translation time) */
1741 static target_long addr_add(DisasContext *ctx, target_long base,
1742 target_long offset)
1743 {
1744 target_long sum = base + offset;
1745
1746 #if defined(TARGET_MIPS64)
1747 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1748 sum = (int32_t)sum;
1749 }
1750 #endif
1751 return sum;
1752 }
1753
1754 /* Sign-extract the low 32-bits to a target_long. */
1755 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1756 {
1757 #if defined(TARGET_MIPS64)
1758 tcg_gen_ext32s_i64(ret, arg);
1759 #else
1760 tcg_gen_extrl_i64_i32(ret, arg);
1761 #endif
1762 }
1763
1764 /* Sign-extract the high 32-bits to a target_long. */
1765 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1766 {
1767 #if defined(TARGET_MIPS64)
1768 tcg_gen_sari_i64(ret, arg, 32);
1769 #else
1770 tcg_gen_extrh_i64_i32(ret, arg);
1771 #endif
1772 }
1773
1774 static inline void check_cp0_enabled(DisasContext *ctx)
1775 {
1776 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1777 generate_exception_err(ctx, EXCP_CpU, 0);
1778 }
1779
1780 static inline void check_cp1_enabled(DisasContext *ctx)
1781 {
1782 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1783 generate_exception_err(ctx, EXCP_CpU, 1);
1784 }
1785
1786 /* Verify that the processor is running with COP1X instructions enabled.
1787 This is associated with the nabla symbol in the MIPS32 and MIPS64
1788 opcode tables. */
1789
1790 static inline void check_cop1x(DisasContext *ctx)
1791 {
1792 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1793 generate_exception_end(ctx, EXCP_RI);
1794 }
1795
1796 /* Verify that the processor is running with 64-bit floating-point
1797 operations enabled. */
1798
1799 static inline void check_cp1_64bitmode(DisasContext *ctx)
1800 {
1801 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1802 generate_exception_end(ctx, EXCP_RI);
1803 }
1804
1805 /*
1806 * Verify if floating point register is valid; an operation is not defined
1807 * if bit 0 of any register specification is set and the FR bit in the
1808 * Status register equals zero, since the register numbers specify an
1809 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1810 * in the Status register equals one, both even and odd register numbers
1811 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1812 *
1813 * Multiple 64 bit wide registers can be checked by calling
1814 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1815 */
1816 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1817 {
1818 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1819 generate_exception_end(ctx, EXCP_RI);
1820 }
1821
1822 /* Verify that the processor is running with DSP instructions enabled.
1823 This is enabled by CP0 Status register MX(24) bit.
1824 */
1825
1826 static inline void check_dsp(DisasContext *ctx)
1827 {
1828 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1829 if (ctx->insn_flags & ASE_DSP) {
1830 generate_exception_end(ctx, EXCP_DSPDIS);
1831 } else {
1832 generate_exception_end(ctx, EXCP_RI);
1833 }
1834 }
1835 }
1836
1837 static inline void check_dspr2(DisasContext *ctx)
1838 {
1839 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1840 if (ctx->insn_flags & ASE_DSP) {
1841 generate_exception_end(ctx, EXCP_DSPDIS);
1842 } else {
1843 generate_exception_end(ctx, EXCP_RI);
1844 }
1845 }
1846 }
1847
1848 /* This code generates a "reserved instruction" exception if the
1849 CPU does not support the instruction set corresponding to flags. */
1850 static inline void check_insn(DisasContext *ctx, int flags)
1851 {
1852 if (unlikely(!(ctx->insn_flags & flags))) {
1853 generate_exception_end(ctx, EXCP_RI);
1854 }
1855 }
1856
1857 /* This code generates a "reserved instruction" exception if the
1858 CPU has corresponding flag set which indicates that the instruction
1859 has been removed. */
1860 static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1861 {
1862 if (unlikely(ctx->insn_flags & flags)) {
1863 generate_exception_end(ctx, EXCP_RI);
1864 }
1865 }
1866
1867 /* This code generates a "reserved instruction" exception if the
1868 CPU does not support 64-bit paired-single (PS) floating point data type */
1869 static inline void check_ps(DisasContext *ctx)
1870 {
1871 if (unlikely(!ctx->ps)) {
1872 generate_exception(ctx, EXCP_RI);
1873 }
1874 check_cp1_64bitmode(ctx);
1875 }
1876
1877 #ifdef TARGET_MIPS64
1878 /* This code generates a "reserved instruction" exception if 64-bit
1879 instructions are not enabled. */
1880 static inline void check_mips_64(DisasContext *ctx)
1881 {
1882 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1883 generate_exception_end(ctx, EXCP_RI);
1884 }
1885 #endif
1886
1887 #ifndef CONFIG_USER_ONLY
1888 static inline void check_mvh(DisasContext *ctx)
1889 {
1890 if (unlikely(!ctx->mvh)) {
1891 generate_exception(ctx, EXCP_RI);
1892 }
1893 }
1894 #endif
1895
1896 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1897 calling interface for 32 and 64-bit FPRs. No sense in changing
1898 all callers for gen_load_fpr32 when we need the CTX parameter for
1899 this one use. */
1900 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1901 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1902 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1903 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1904 int ft, int fs, int cc) \
1905 { \
1906 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1907 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1908 switch (ifmt) { \
1909 case FMT_PS: \
1910 check_ps(ctx); \
1911 break; \
1912 case FMT_D: \
1913 if (abs) { \
1914 check_cop1x(ctx); \
1915 } \
1916 check_cp1_registers(ctx, fs | ft); \
1917 break; \
1918 case FMT_S: \
1919 if (abs) { \
1920 check_cop1x(ctx); \
1921 } \
1922 break; \
1923 } \
1924 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1925 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1926 switch (n) { \
1927 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1928 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1929 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1930 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1931 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1932 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1933 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1934 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1935 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1936 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1937 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1938 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1939 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1940 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1941 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1942 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1943 default: abort(); \
1944 } \
1945 tcg_temp_free_i##bits (fp0); \
1946 tcg_temp_free_i##bits (fp1); \
1947 }
1948
1949 FOP_CONDS(, 0, d, FMT_D, 64)
1950 FOP_CONDS(abs, 1, d, FMT_D, 64)
1951 FOP_CONDS(, 0, s, FMT_S, 32)
1952 FOP_CONDS(abs, 1, s, FMT_S, 32)
1953 FOP_CONDS(, 0, ps, FMT_PS, 64)
1954 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1955 #undef FOP_CONDS
1956
1957 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1958 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1959 int ft, int fs, int fd) \
1960 { \
1961 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1962 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1963 if (ifmt == FMT_D) { \
1964 check_cp1_registers(ctx, fs | ft | fd); \
1965 } \
1966 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1967 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1968 switch (n) { \
1969 case 0: \
1970 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1971 break; \
1972 case 1: \
1973 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1974 break; \
1975 case 2: \
1976 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1977 break; \
1978 case 3: \
1979 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1980 break; \
1981 case 4: \
1982 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1983 break; \
1984 case 5: \
1985 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1986 break; \
1987 case 6: \
1988 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1989 break; \
1990 case 7: \
1991 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1992 break; \
1993 case 8: \
1994 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1995 break; \
1996 case 9: \
1997 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1998 break; \
1999 case 10: \
2000 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2001 break; \
2002 case 11: \
2003 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2004 break; \
2005 case 12: \
2006 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2007 break; \
2008 case 13: \
2009 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2010 break; \
2011 case 14: \
2012 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2013 break; \
2014 case 15: \
2015 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2016 break; \
2017 case 17: \
2018 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2019 break; \
2020 case 18: \
2021 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2022 break; \
2023 case 19: \
2024 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2025 break; \
2026 case 25: \
2027 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2028 break; \
2029 case 26: \
2030 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2031 break; \
2032 case 27: \
2033 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2034 break; \
2035 default: \
2036 abort(); \
2037 } \
2038 STORE; \
2039 tcg_temp_free_i ## bits (fp0); \
2040 tcg_temp_free_i ## bits (fp1); \
2041 }
2042
2043 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2044 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2045 #undef FOP_CONDNS
2046 #undef gen_ldcmp_fpr32
2047 #undef gen_ldcmp_fpr64
2048
2049 /* load/store instructions. */
2050 #ifdef CONFIG_USER_ONLY
2051 #define OP_LD_ATOMIC(insn,fname) \
2052 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2053 DisasContext *ctx) \
2054 { \
2055 TCGv t0 = tcg_temp_new(); \
2056 tcg_gen_mov_tl(t0, arg1); \
2057 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2058 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2059 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2060 tcg_temp_free(t0); \
2061 }
2062 #else
2063 #define OP_LD_ATOMIC(insn,fname) \
2064 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2065 DisasContext *ctx) \
2066 { \
2067 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2068 }
2069 #endif
2070 OP_LD_ATOMIC(ll,ld32s);
2071 #if defined(TARGET_MIPS64)
2072 OP_LD_ATOMIC(lld,ld64);
2073 #endif
2074 #undef OP_LD_ATOMIC
2075
2076 #ifdef CONFIG_USER_ONLY
2077 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2078 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2079 DisasContext *ctx) \
2080 { \
2081 TCGv t0 = tcg_temp_new(); \
2082 TCGLabel *l1 = gen_new_label(); \
2083 TCGLabel *l2 = gen_new_label(); \
2084 \
2085 tcg_gen_andi_tl(t0, arg2, almask); \
2086 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2087 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2088 generate_exception(ctx, EXCP_AdES); \
2089 gen_set_label(l1); \
2090 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2091 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2092 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2093 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2094 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2095 generate_exception_end(ctx, EXCP_SC); \
2096 gen_set_label(l2); \
2097 tcg_gen_movi_tl(t0, 0); \
2098 gen_store_gpr(t0, rt); \
2099 tcg_temp_free(t0); \
2100 }
2101 #else
2102 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2103 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2104 DisasContext *ctx) \
2105 { \
2106 TCGv t0 = tcg_temp_new(); \
2107 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
2108 gen_store_gpr(t0, rt); \
2109 tcg_temp_free(t0); \
2110 }
2111 #endif
2112 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2113 #if defined(TARGET_MIPS64)
2114 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2115 #endif
2116 #undef OP_ST_ATOMIC
2117
2118 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2119 int base, int16_t offset)
2120 {
2121 if (base == 0) {
2122 tcg_gen_movi_tl(addr, offset);
2123 } else if (offset == 0) {
2124 gen_load_gpr(addr, base);
2125 } else {
2126 tcg_gen_movi_tl(addr, offset);
2127 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2128 }
2129 }
2130
2131 static target_ulong pc_relative_pc (DisasContext *ctx)
2132 {
2133 target_ulong pc = ctx->pc;
2134
2135 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2136 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2137
2138 pc -= branch_bytes;
2139 }
2140
2141 pc &= ~(target_ulong)3;
2142 return pc;
2143 }
2144
2145 /* Load */
2146 static void gen_ld(DisasContext *ctx, uint32_t opc,
2147 int rt, int base, int16_t offset)
2148 {
2149 TCGv t0, t1, t2;
2150 int mem_idx = ctx->mem_idx;
2151
2152 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2153 /* Loongson CPU uses a load to zero register for prefetch.
2154 We emulate it as a NOP. On other CPU we must perform the
2155 actual memory access. */
2156 return;
2157 }
2158
2159 t0 = tcg_temp_new();
2160 gen_base_offset_addr(ctx, t0, base, offset);
2161
2162 switch (opc) {
2163 #if defined(TARGET_MIPS64)
2164 case OPC_LWU:
2165 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2166 ctx->default_tcg_memop_mask);
2167 gen_store_gpr(t0, rt);
2168 break;
2169 case OPC_LD:
2170 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2171 ctx->default_tcg_memop_mask);
2172 gen_store_gpr(t0, rt);
2173 break;
2174 case OPC_LLD:
2175 case R6_OPC_LLD:
2176 op_ld_lld(t0, t0, mem_idx, ctx);
2177 gen_store_gpr(t0, rt);
2178 break;
2179 case OPC_LDL:
2180 t1 = tcg_temp_new();
2181 /* Do a byte access to possibly trigger a page
2182 fault with the unaligned address. */
2183 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2184 tcg_gen_andi_tl(t1, t0, 7);
2185 #ifndef TARGET_WORDS_BIGENDIAN
2186 tcg_gen_xori_tl(t1, t1, 7);
2187 #endif
2188 tcg_gen_shli_tl(t1, t1, 3);
2189 tcg_gen_andi_tl(t0, t0, ~7);
2190 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2191 tcg_gen_shl_tl(t0, t0, t1);
2192 t2 = tcg_const_tl(-1);
2193 tcg_gen_shl_tl(t2, t2, t1);
2194 gen_load_gpr(t1, rt);
2195 tcg_gen_andc_tl(t1, t1, t2);
2196 tcg_temp_free(t2);
2197 tcg_gen_or_tl(t0, t0, t1);
2198 tcg_temp_free(t1);
2199 gen_store_gpr(t0, rt);
2200 break;
2201 case OPC_LDR:
2202 t1 = tcg_temp_new();
2203 /* Do a byte access to possibly trigger a page
2204 fault with the unaligned address. */
2205 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2206 tcg_gen_andi_tl(t1, t0, 7);
2207 #ifdef TARGET_WORDS_BIGENDIAN
2208 tcg_gen_xori_tl(t1, t1, 7);
2209 #endif
2210 tcg_gen_shli_tl(t1, t1, 3);
2211 tcg_gen_andi_tl(t0, t0, ~7);
2212 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2213 tcg_gen_shr_tl(t0, t0, t1);
2214 tcg_gen_xori_tl(t1, t1, 63);
2215 t2 = tcg_const_tl(0xfffffffffffffffeull);
2216 tcg_gen_shl_tl(t2, t2, t1);
2217 gen_load_gpr(t1, rt);
2218 tcg_gen_and_tl(t1, t1, t2);
2219 tcg_temp_free(t2);
2220 tcg_gen_or_tl(t0, t0, t1);
2221 tcg_temp_free(t1);
2222 gen_store_gpr(t0, rt);
2223 break;
2224 case OPC_LDPC:
2225 t1 = tcg_const_tl(pc_relative_pc(ctx));
2226 gen_op_addr_add(ctx, t0, t0, t1);
2227 tcg_temp_free(t1);
2228 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2229 gen_store_gpr(t0, rt);
2230 break;
2231 #endif
2232 case OPC_LWPC:
2233 t1 = tcg_const_tl(pc_relative_pc(ctx));
2234 gen_op_addr_add(ctx, t0, t0, t1);
2235 tcg_temp_free(t1);
2236 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2237 gen_store_gpr(t0, rt);
2238 break;
2239 case OPC_LWE:
2240 mem_idx = MIPS_HFLAG_UM;
2241 /* fall through */
2242 case OPC_LW:
2243 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2244 ctx->default_tcg_memop_mask);
2245 gen_store_gpr(t0, rt);
2246 break;
2247 case OPC_LHE:
2248 mem_idx = MIPS_HFLAG_UM;
2249 /* fall through */
2250 case OPC_LH:
2251 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2252 ctx->default_tcg_memop_mask);
2253 gen_store_gpr(t0, rt);
2254 break;
2255 case OPC_LHUE:
2256 mem_idx = MIPS_HFLAG_UM;
2257 /* fall through */
2258 case OPC_LHU:
2259 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2260 ctx->default_tcg_memop_mask);
2261 gen_store_gpr(t0, rt);
2262 break;
2263 case OPC_LBE:
2264 mem_idx = MIPS_HFLAG_UM;
2265 /* fall through */
2266 case OPC_LB:
2267 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2268 gen_store_gpr(t0, rt);
2269 break;
2270 case OPC_LBUE:
2271 mem_idx = MIPS_HFLAG_UM;
2272 /* fall through */
2273 case OPC_LBU:
2274 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2275 gen_store_gpr(t0, rt);
2276 break;
2277 case OPC_LWLE:
2278 mem_idx = MIPS_HFLAG_UM;
2279 /* fall through */
2280 case OPC_LWL:
2281 t1 = tcg_temp_new();
2282 /* Do a byte access to possibly trigger a page
2283 fault with the unaligned address. */
2284 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2285 tcg_gen_andi_tl(t1, t0, 3);
2286 #ifndef TARGET_WORDS_BIGENDIAN
2287 tcg_gen_xori_tl(t1, t1, 3);
2288 #endif
2289 tcg_gen_shli_tl(t1, t1, 3);
2290 tcg_gen_andi_tl(t0, t0, ~3);
2291 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2292 tcg_gen_shl_tl(t0, t0, t1);
2293 t2 = tcg_const_tl(-1);
2294 tcg_gen_shl_tl(t2, t2, t1);
2295 gen_load_gpr(t1, rt);
2296 tcg_gen_andc_tl(t1, t1, t2);
2297 tcg_temp_free(t2);
2298 tcg_gen_or_tl(t0, t0, t1);
2299 tcg_temp_free(t1);
2300 tcg_gen_ext32s_tl(t0, t0);
2301 gen_store_gpr(t0, rt);
2302 break;
2303 case OPC_LWRE:
2304 mem_idx = MIPS_HFLAG_UM;
2305 /* fall through */
2306 case OPC_LWR:
2307 t1 = tcg_temp_new();
2308 /* Do a byte access to possibly trigger a page
2309 fault with the unaligned address. */
2310 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2311 tcg_gen_andi_tl(t1, t0, 3);
2312 #ifdef TARGET_WORDS_BIGENDIAN
2313 tcg_gen_xori_tl(t1, t1, 3);
2314 #endif
2315 tcg_gen_shli_tl(t1, t1, 3);
2316 tcg_gen_andi_tl(t0, t0, ~3);
2317 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2318 tcg_gen_shr_tl(t0, t0, t1);
2319 tcg_gen_xori_tl(t1, t1, 31);
2320 t2 = tcg_const_tl(0xfffffffeull);
2321 tcg_gen_shl_tl(t2, t2, t1);
2322 gen_load_gpr(t1, rt);
2323 tcg_gen_and_tl(t1, t1, t2);
2324 tcg_temp_free(t2);
2325 tcg_gen_or_tl(t0, t0, t1);
2326 tcg_temp_free(t1);
2327 tcg_gen_ext32s_tl(t0, t0);
2328 gen_store_gpr(t0, rt);
2329 break;
2330 case OPC_LLE:
2331 mem_idx = MIPS_HFLAG_UM;
2332 /* fall through */
2333 case OPC_LL:
2334 case R6_OPC_LL:
2335 op_ld_ll(t0, t0, mem_idx, ctx);
2336 gen_store_gpr(t0, rt);
2337 break;
2338 }
2339 tcg_temp_free(t0);
2340 }
2341
2342 /* Store */
2343 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2344 int base, int16_t offset)
2345 {
2346 TCGv t0 = tcg_temp_new();
2347 TCGv t1 = tcg_temp_new();
2348 int mem_idx = ctx->mem_idx;
2349
2350 gen_base_offset_addr(ctx, t0, base, offset);
2351 gen_load_gpr(t1, rt);
2352 switch (opc) {
2353 #if defined(TARGET_MIPS64)
2354 case OPC_SD:
2355 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
2356 ctx->default_tcg_memop_mask);
2357 break;
2358 case OPC_SDL:
2359 gen_helper_0e2i(sdl, t1, t0, mem_idx);
2360 break;
2361 case OPC_SDR:
2362 gen_helper_0e2i(sdr, t1, t0, mem_idx);
2363 break;
2364 #endif
2365 case OPC_SWE:
2366 mem_idx = MIPS_HFLAG_UM;
2367 /* fall through */
2368 case OPC_SW:
2369 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2370 ctx->default_tcg_memop_mask);
2371 break;
2372 case OPC_SHE:
2373 mem_idx = MIPS_HFLAG_UM;
2374 /* fall through */
2375 case OPC_SH:
2376 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2377 ctx->default_tcg_memop_mask);
2378 break;
2379 case OPC_SBE:
2380 mem_idx = MIPS_HFLAG_UM;
2381 /* fall through */
2382 case OPC_SB:
2383 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2384 break;
2385 case OPC_SWLE:
2386 mem_idx = MIPS_HFLAG_UM;
2387 /* fall through */
2388 case OPC_SWL:
2389 gen_helper_0e2i(swl, t1, t0, mem_idx);
2390 break;
2391 case OPC_SWRE:
2392 mem_idx = MIPS_HFLAG_UM;
2393 /* fall through */
2394 case OPC_SWR:
2395 gen_helper_0e2i(swr, t1, t0, mem_idx);
2396 break;
2397 }
2398 tcg_temp_free(t0);
2399 tcg_temp_free(t1);
2400 }
2401
2402
2403 /* Store conditional */
2404 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2405 int base, int16_t offset)
2406 {
2407 TCGv t0, t1;
2408 int mem_idx = ctx->mem_idx;
2409
2410 #ifdef CONFIG_USER_ONLY
2411 t0 = tcg_temp_local_new();
2412 t1 = tcg_temp_local_new();
2413 #else
2414 t0 = tcg_temp_new();
2415 t1 = tcg_temp_new();
2416 #endif
2417 gen_base_offset_addr(ctx, t0, base, offset);
2418 gen_load_gpr(t1, rt);
2419 switch (opc) {
2420 #if defined(TARGET_MIPS64)
2421 case OPC_SCD:
2422 case R6_OPC_SCD:
2423 op_st_scd(t1, t0, rt, mem_idx, ctx);
2424 break;
2425 #endif
2426 case OPC_SCE:
2427 mem_idx = MIPS_HFLAG_UM;
2428 /* fall through */
2429 case OPC_SC:
2430 case R6_OPC_SC:
2431 op_st_sc(t1, t0, rt, mem_idx, ctx);
2432 break;
2433 }
2434 tcg_temp_free(t1);
2435 tcg_temp_free(t0);
2436 }
2437
2438 /* Load and store */
2439 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2440 int base, int16_t offset)
2441 {
2442 TCGv t0 = tcg_temp_new();
2443
2444 gen_base_offset_addr(ctx, t0, base, offset);
2445 /* Don't do NOP if destination is zero: we must perform the actual
2446 memory access. */
2447 switch (opc) {
2448 case OPC_LWC1:
2449 {
2450 TCGv_i32 fp0 = tcg_temp_new_i32();
2451 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2452 ctx->default_tcg_memop_mask);
2453 gen_store_fpr32(ctx, fp0, ft);
2454 tcg_temp_free_i32(fp0);
2455 }
2456 break;
2457 case OPC_SWC1:
2458 {
2459 TCGv_i32 fp0 = tcg_temp_new_i32();
2460 gen_load_fpr32(ctx, fp0, ft);
2461 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2462 ctx->default_tcg_memop_mask);
2463 tcg_temp_free_i32(fp0);
2464 }
2465 break;
2466 case OPC_LDC1:
2467 {
2468 TCGv_i64 fp0 = tcg_temp_new_i64();
2469 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2470 ctx->default_tcg_memop_mask);
2471 gen_store_fpr64(ctx, fp0, ft);
2472 tcg_temp_free_i64(fp0);
2473 }
2474 break;
2475 case OPC_SDC1:
2476 {
2477 TCGv_i64 fp0 = tcg_temp_new_i64();
2478 gen_load_fpr64(ctx, fp0, ft);
2479 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2480 ctx->default_tcg_memop_mask);
2481 tcg_temp_free_i64(fp0);
2482 }
2483 break;
2484 default:
2485 MIPS_INVAL("flt_ldst");
2486 generate_exception_end(ctx, EXCP_RI);
2487 goto out;
2488 }
2489 out:
2490 tcg_temp_free(t0);
2491 }
2492
2493 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2494 int rs, int16_t imm)
2495 {
2496 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2497 check_cp1_enabled(ctx);
2498 switch (op) {
2499 case OPC_LDC1:
2500 case OPC_SDC1:
2501 check_insn(ctx, ISA_MIPS2);
2502 /* Fallthrough */
2503 default:
2504 gen_flt_ldst(ctx, op, rt, rs, imm);
2505 }
2506 } else {
2507 generate_exception_err(ctx, EXCP_CpU, 1);
2508 }
2509 }
2510
2511 /* Arithmetic with immediate operand */
2512 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2513 int rt, int rs, int16_t imm)
2514 {
2515 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2516
2517 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2518 /* If no destination, treat it as a NOP.
2519 For addi, we must generate the overflow exception when needed. */
2520 return;
2521 }
2522 switch (opc) {
2523 case OPC_ADDI:
2524 {
2525 TCGv t0 = tcg_temp_local_new();
2526 TCGv t1 = tcg_temp_new();
2527 TCGv t2 = tcg_temp_new();
2528 TCGLabel *l1 = gen_new_label();
2529
2530 gen_load_gpr(t1, rs);
2531 tcg_gen_addi_tl(t0, t1, uimm);
2532 tcg_gen_ext32s_tl(t0, t0);
2533
2534 tcg_gen_xori_tl(t1, t1, ~uimm);
2535 tcg_gen_xori_tl(t2, t0, uimm);
2536 tcg_gen_and_tl(t1, t1, t2);
2537 tcg_temp_free(t2);
2538 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2539 tcg_temp_free(t1);
2540 /* operands of same sign, result different sign */
2541 generate_exception(ctx, EXCP_OVERFLOW);
2542 gen_set_label(l1);
2543 tcg_gen_ext32s_tl(t0, t0);
2544 gen_store_gpr(t0, rt);
2545 tcg_temp_free(t0);
2546 }
2547 break;
2548 case OPC_ADDIU:
2549 if (rs != 0) {
2550 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2551 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2552 } else {
2553 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2554 }
2555 break;
2556 #if defined(TARGET_MIPS64)
2557 case OPC_DADDI:
2558 {
2559 TCGv t0 = tcg_temp_local_new();
2560 TCGv t1 = tcg_temp_new();
2561 TCGv t2 = tcg_temp_new();
2562 TCGLabel *l1 = gen_new_label();
2563
2564 gen_load_gpr(t1, rs);
2565 tcg_gen_addi_tl(t0, t1, uimm);
2566
2567 tcg_gen_xori_tl(t1, t1, ~uimm);
2568 tcg_gen_xori_tl(t2, t0, uimm);
2569 tcg_gen_and_tl(t1, t1, t2);
2570 tcg_temp_free(t2);
2571 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2572 tcg_temp_free(t1);
2573 /* operands of same sign, result different sign */
2574 generate_exception(ctx, EXCP_OVERFLOW);
2575 gen_set_label(l1);
2576 gen_store_gpr(t0, rt);
2577 tcg_temp_free(t0);
2578 }
2579 break;
2580 case OPC_DADDIU:
2581 if (rs != 0) {
2582 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2583 } else {
2584 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2585 }
2586 break;
2587 #endif
2588 }
2589 }
2590
2591 /* Logic with immediate operand */
2592 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2593 int rt, int rs, int16_t imm)
2594 {
2595 target_ulong uimm;
2596
2597 if (rt == 0) {
2598 /* If no destination, treat it as a NOP. */
2599 return;
2600 }
2601 uimm = (uint16_t)imm;
2602 switch (opc) {
2603 case OPC_ANDI:
2604 if (likely(rs != 0))
2605 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2606 else
2607 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2608 break;
2609 case OPC_ORI:
2610 if (rs != 0)
2611 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2612 else
2613 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2614 break;
2615 case OPC_XORI:
2616 if (likely(rs != 0))
2617 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2618 else
2619 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2620 break;
2621 case OPC_LUI:
2622 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2623 /* OPC_AUI */
2624 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2625 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2626 } else {
2627 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2628 }
2629 break;
2630
2631 default:
2632 break;
2633 }
2634 }
2635
2636 /* Set on less than with immediate operand */
2637 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2638 int rt, int rs, int16_t imm)
2639 {
2640 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2641 TCGv t0;
2642
2643 if (rt == 0) {
2644 /* If no destination, treat it as a NOP. */
2645 return;
2646 }
2647 t0 = tcg_temp_new();
2648 gen_load_gpr(t0, rs);
2649 switch (opc) {
2650 case OPC_SLTI:
2651 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2652 break;
2653 case OPC_SLTIU:
2654 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2655 break;
2656 }
2657 tcg_temp_free(t0);
2658 }
2659
2660 /* Shifts with immediate operand */
2661 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2662 int rt, int rs, int16_t imm)
2663 {
2664 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2665 TCGv t0;
2666
2667 if (rt == 0) {
2668 /* If no destination, treat it as a NOP. */
2669 return;
2670 }
2671
2672 t0 = tcg_temp_new();
2673 gen_load_gpr(t0, rs);
2674 switch (opc) {
2675 case OPC_SLL:
2676 tcg_gen_shli_tl(t0, t0, uimm);
2677 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2678 break;
2679 case OPC_SRA:
2680 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2681 break;
2682 case OPC_SRL:
2683 if (uimm != 0) {
2684 tcg_gen_ext32u_tl(t0, t0);
2685 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2686 } else {
2687 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2688 }
2689 break;
2690 case OPC_ROTR:
2691 if (uimm != 0) {
2692 TCGv_i32 t1 = tcg_temp_new_i32();
2693
2694 tcg_gen_trunc_tl_i32(t1, t0);
2695 tcg_gen_rotri_i32(t1, t1, uimm);
2696 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2697 tcg_temp_free_i32(t1);
2698 } else {
2699 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2700 }
2701 break;
2702 #if defined(TARGET_MIPS64)
2703 case OPC_DSLL:
2704 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2705 break;
2706 case OPC_DSRA:
2707 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2708 break;
2709 case OPC_DSRL:
2710 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2711 break;
2712 case OPC_DROTR:
2713 if (uimm != 0) {
2714 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2715 } else {
2716 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2717 }
2718 break;
2719 case OPC_DSLL32:
2720 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2721 break;
2722 case OPC_DSRA32:
2723 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2724 break;
2725 case OPC_DSRL32:
2726 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2727 break;
2728 case OPC_DROTR32:
2729 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2730 break;
2731 #endif
2732 }
2733 tcg_temp_free(t0);
2734 }
2735
2736 /* Arithmetic */
2737 static void gen_arith(DisasContext *ctx, uint32_t opc,
2738 int rd, int rs, int rt)
2739 {
2740 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2741 && opc != OPC_DADD && opc != OPC_DSUB) {
2742 /* If no destination, treat it as a NOP.
2743 For add & sub, we must generate the overflow exception when needed. */
2744 return;
2745 }
2746
2747 switch (opc) {
2748 case OPC_ADD:
2749 {
2750 TCGv t0 = tcg_temp_local_new();
2751 TCGv t1 = tcg_temp_new();
2752 TCGv t2 = tcg_temp_new();
2753 TCGLabel *l1 = gen_new_label();
2754
2755 gen_load_gpr(t1, rs);
2756 gen_load_gpr(t2, rt);
2757 tcg_gen_add_tl(t0, t1, t2);
2758 tcg_gen_ext32s_tl(t0, t0);
2759 tcg_gen_xor_tl(t1, t1, t2);
2760 tcg_gen_xor_tl(t2, t0, t2);
2761 tcg_gen_andc_tl(t1, t2, t1);
2762 tcg_temp_free(t2);
2763 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2764 tcg_temp_free(t1);
2765 /* operands of same sign, result different sign */
2766 generate_exception(ctx, EXCP_OVERFLOW);
2767 gen_set_label(l1);
2768 gen_store_gpr(t0, rd);
2769 tcg_temp_free(t0);
2770 }
2771 break;
2772 case OPC_ADDU:
2773 if (rs != 0 && rt != 0) {
2774 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2775 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2776 } else if (rs == 0 && rt != 0) {
2777 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2778 } else if (rs != 0 && rt == 0) {
2779 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2780 } else {
2781 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2782 }
2783 break;
2784 case OPC_SUB:
2785 {
2786 TCGv t0 = tcg_temp_local_new();
2787 TCGv t1 = tcg_temp_new();
2788 TCGv t2 = tcg_temp_new();
2789 TCGLabel *l1 = gen_new_label();
2790
2791 gen_load_gpr(t1, rs);
2792 gen_load_gpr(t2, rt);
2793 tcg_gen_sub_tl(t0, t1, t2);
2794 tcg_gen_ext32s_tl(t0, t0);
2795 tcg_gen_xor_tl(t2, t1, t2);
2796 tcg_gen_xor_tl(t1, t0, t1);
2797 tcg_gen_and_tl(t1, t1, t2);
2798 tcg_temp_free(t2);
2799 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2800 tcg_temp_free(t1);
2801 /* operands of different sign, first operand and result different sign */
2802 generate_exception(ctx, EXCP_OVERFLOW);
2803 gen_set_label(l1);
2804 gen_store_gpr(t0, rd);
2805 tcg_temp_free(t0);
2806 }
2807 break;
2808 case OPC_SUBU:
2809 if (rs != 0 && rt != 0) {
2810 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2811 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2812 } else if (rs == 0 && rt != 0) {
2813 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2814 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2815 } else if (rs != 0 && rt == 0) {
2816 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2817 } else {
2818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2819 }
2820 break;
2821 #if defined(TARGET_MIPS64)
2822 case OPC_DADD:
2823 {
2824 TCGv t0 = tcg_temp_local_new();
2825 TCGv t1 = tcg_temp_new();
2826 TCGv t2 = tcg_temp_new();
2827 TCGLabel *l1 = gen_new_label();
2828
2829 gen_load_gpr(t1, rs);
2830 gen_load_gpr(t2, rt);
2831 tcg_gen_add_tl(t0, t1, t2);
2832 tcg_gen_xor_tl(t1, t1, t2);
2833 tcg_gen_xor_tl(t2, t0, t2);
2834 tcg_gen_andc_tl(t1, t2, t1);
2835 tcg_temp_free(t2);
2836 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2837 tcg_temp_free(t1);
2838 /* operands of same sign, result different sign */
2839 generate_exception(ctx, EXCP_OVERFLOW);
2840 gen_set_label(l1);
2841 gen_store_gpr(t0, rd);
2842 tcg_temp_free(t0);
2843 }
2844 break;
2845 case OPC_DADDU:
2846 if (rs != 0 && rt != 0) {
2847 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2848 } else if (rs == 0 && rt != 0) {
2849 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2850 } else if (rs != 0 && rt == 0) {
2851 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2852 } else {
2853 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2854 }
2855 break;
2856 case OPC_DSUB:
2857 {
2858 TCGv t0 = tcg_temp_local_new();
2859 TCGv t1 = tcg_temp_new();
2860 TCGv t2 = tcg_temp_new();
2861 TCGLabel *l1 = gen_new_label();
2862
2863 gen_load_gpr(t1, rs);
2864 gen_load_gpr(t2, rt);
2865 tcg_gen_sub_tl(t0, t1, t2);
2866 tcg_gen_xor_tl(t2, t1, t2);
2867 tcg_gen_xor_tl(t1, t0, t1);
2868 tcg_gen_and_tl(t1, t1, t2);
2869 tcg_temp_free(t2);
2870 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2871 tcg_temp_free(t1);
2872 /* operands of different sign, first operand and result different sign */
2873 generate_exception(ctx, EXCP_OVERFLOW);
2874 gen_set_label(l1);
2875 gen_store_gpr(t0, rd);
2876 tcg_temp_free(t0);
2877 }
2878 break;
2879 case OPC_DSUBU:
2880 if (rs != 0 && rt != 0) {
2881 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2882 } else if (rs == 0 && rt != 0) {
2883 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2884 } else if (rs != 0 && rt == 0) {
2885 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2886 } else {
2887 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2888 }
2889 break;
2890 #endif
2891 case OPC_MUL:
2892 if (likely(rs != 0 && rt != 0)) {
2893 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2894 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2895 } else {
2896 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2897 }
2898 break;
2899 }
2900 }
2901
2902 /* Conditional move */
2903 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2904 int rd, int rs, int rt)
2905 {
2906 TCGv t0, t1, t2;
2907
2908 if (rd == 0) {
2909 /* If no destination, treat it as a NOP. */
2910 return;
2911 }
2912
2913 t0 = tcg_temp_new();
2914 gen_load_gpr(t0, rt);
2915 t1 = tcg_const_tl(0);
2916 t2 = tcg_temp_new();
2917 gen_load_gpr(t2, rs);
2918 switch (opc) {
2919 case OPC_MOVN:
2920 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2921 break;
2922 case OPC_MOVZ:
2923 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2924 break;
2925 case OPC_SELNEZ:
2926 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2927 break;
2928 case OPC_SELEQZ:
2929 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2930 break;
2931 }
2932 tcg_temp_free(t2);
2933 tcg_temp_free(t1);
2934 tcg_temp_free(t0);
2935 }
2936
2937 /* Logic */
2938 static void gen_logic(DisasContext *ctx, uint32_t opc,
2939 int rd, int rs, int rt)
2940 {
2941 if (rd == 0) {
2942 /* If no destination, treat it as a NOP. */
2943 return;
2944 }
2945
2946 switch (opc) {
2947 case OPC_AND:
2948 if (likely(rs != 0 && rt != 0)) {
2949 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2950 } else {
2951 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2952 }
2953 break;
2954 case OPC_NOR:
2955 if (rs != 0 && rt != 0) {
2956 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2957 } else if (rs == 0 && rt != 0) {
2958 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2959 } else if (rs != 0 && rt == 0) {
2960 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2961 } else {
2962 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2963 }
2964 break;
2965 case OPC_OR:
2966 if (likely(rs != 0 && rt != 0)) {
2967 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2968 } else if (rs == 0 && rt != 0) {
2969 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2970 } else if (rs != 0 && rt == 0) {
2971 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2972 } else {
2973 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2974 }
2975 break;
2976 case OPC_XOR:
2977 if (likely(rs != 0 && rt != 0)) {
2978 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2979 } else if (rs == 0 && rt != 0) {
2980 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2981 } else if (rs != 0 && rt == 0) {
2982 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2983 } else {
2984 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2985 }
2986 break;
2987 }
2988 }
2989
2990 /* Set on lower than */
2991 static void gen_slt(DisasContext *ctx, uint32_t opc,
2992 int rd, int rs, int rt)
2993 {
2994 TCGv t0, t1;
2995
2996 if (rd == 0) {
2997 /* If no destination, treat it as a NOP. */
2998 return;
2999 }
3000
3001 t0 = tcg_temp_new();
3002 t1 = tcg_temp_new();
3003 gen_load_gpr(t0, rs);
3004 gen_load_gpr(t1, rt);
3005 switch (opc) {
3006 case OPC_SLT:
3007 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
3008 break;
3009 case OPC_SLTU:
3010 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
3011 break;
3012 }
3013 tcg_temp_free(t0);
3014 tcg_temp_free(t1);
3015 }
3016
3017 /* Shifts */
3018 static void gen_shift(DisasContext *ctx, uint32_t opc,
3019 int rd, int rs, int rt)
3020 {
3021 TCGv t0, t1;
3022
3023 if (rd == 0) {
3024 /* If no destination, treat it as a NOP.
3025 For add & sub, we must generate the overflow exception when needed. */
3026 return;
3027 }
3028
3029 t0 = tcg_temp_new();
3030 t1 = tcg_temp_new();
3031 gen_load_gpr(t0, rs);
3032 gen_load_gpr(t1, rt);
3033 switch (opc) {
3034 case OPC_SLLV:
3035 tcg_gen_andi_tl(t0, t0, 0x1f);
3036 tcg_gen_shl_tl(t0, t1, t0);
3037 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3038 break;
3039 case OPC_SRAV:
3040 tcg_gen_andi_tl(t0, t0, 0x1f);
3041 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3042 break;
3043 case OPC_SRLV:
3044 tcg_gen_ext32u_tl(t1, t1);
3045 tcg_gen_andi_tl(t0, t0, 0x1f);
3046 tcg_gen_shr_tl(t0, t1, t0);
3047 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3048 break;
3049 case OPC_ROTRV:
3050 {
3051 TCGv_i32 t2 = tcg_temp_new_i32();
3052 TCGv_i32 t3 = tcg_temp_new_i32();
3053
3054 tcg_gen_trunc_tl_i32(t2, t0);
3055 tcg_gen_trunc_tl_i32(t3, t1);
3056 tcg_gen_andi_i32(t2, t2, 0x1f);
3057 tcg_gen_rotr_i32(t2, t3, t2);
3058 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3059 tcg_temp_free_i32(t2);
3060 tcg_temp_free_i32(t3);
3061 }
3062 break;
3063 #if defined(TARGET_MIPS64)
3064 case OPC_DSLLV:
3065 tcg_gen_andi_tl(t0, t0, 0x3f);
3066 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
3067 break;
3068 case OPC_DSRAV:
3069 tcg_gen_andi_tl(t0, t0, 0x3f);
3070 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3071 break;
3072 case OPC_DSRLV:
3073 tcg_gen_andi_tl(t0, t0, 0x3f);
3074 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3075 break;
3076 case OPC_DROTRV:
3077 tcg_gen_andi_tl(t0, t0, 0x3f);
3078 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3079 break;
3080 #endif
3081 }
3082 tcg_temp_free(t0);
3083 tcg_temp_free(t1);
3084 }
3085
3086 /* Arithmetic on HI/LO registers */
3087 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3088 {
3089 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3090 /* Treat as NOP. */
3091 return;
3092 }
3093
3094 if (acc != 0) {
3095 check_dsp(ctx);
3096 }
3097
3098 switch (opc) {
3099 case OPC_MFHI:
3100 #if defined(TARGET_MIPS64)
3101 if (acc != 0) {
3102 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3103 } else
3104 #endif
3105 {
3106 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3107 }
3108 break;
3109 case OPC_MFLO:
3110 #if defined(TARGET_MIPS64)
3111 if (acc != 0) {
3112 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3113 } else
3114 #endif
3115 {
3116 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3117 }
3118 break;
3119 case OPC_MTHI:
3120 if (reg != 0) {
3121 #if defined(TARGET_MIPS64)
3122 if (acc != 0) {
3123 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3124 } else
3125 #endif
3126 {
3127 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3128 }
3129 } else {
3130 tcg_gen_movi_tl(cpu_HI[acc], 0);
3131 }
3132 break;
3133 case OPC_MTLO:
3134 if (reg != 0) {
3135 #if defined(TARGET_MIPS64)
3136 if (acc != 0) {
3137 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3138 } else
3139 #endif
3140 {
3141 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3142 }
3143 } else {
3144 tcg_gen_movi_tl(cpu_LO[acc], 0);
3145 }
3146 break;
3147 }
3148 }
3149
3150 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3151 TCGMemOp memop)
3152 {
3153 TCGv t0 = tcg_const_tl(addr);
3154 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3155 gen_store_gpr(t0, reg);
3156 tcg_temp_free(t0);
3157 }
3158
3159 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3160 int rs)
3161 {
3162 target_long offset;
3163 target_long addr;
3164
3165 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3166 case OPC_ADDIUPC:
3167 if (rs != 0) {
3168 offset = sextract32(ctx->opcode << 2, 0, 21);
3169 addr = addr_add(ctx, pc, offset);
3170 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3171 }
3172 break;
3173 case R6_OPC_LWPC:
3174 offset = sextract32(ctx->opcode << 2, 0, 21);
3175 addr = addr_add(ctx, pc, offset);
3176 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3177 break;
3178 #if defined(TARGET_MIPS64)
3179 case OPC_LWUPC:
3180 check_mips_64(ctx);
3181 offset = sextract32(ctx->opcode << 2, 0, 21);
3182 addr = addr_add(ctx, pc, offset);
3183 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3184 break;
3185 #endif
3186 default:
3187 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3188 case OPC_AUIPC:
3189 if (rs != 0) {
3190 offset = sextract32(ctx->opcode, 0, 16) << 16;
3191 addr = addr_add(ctx, pc, offset);
3192 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3193 }
3194 break;
3195 case OPC_ALUIPC:
3196 if (rs != 0) {
3197 offset = sextract32(ctx->opcode, 0, 16) << 16;
3198 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3199 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3200 }
3201 break;
3202 #if defined(TARGET_MIPS64)
3203 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3204 case R6_OPC_LDPC + (1 << 16):
3205 case R6_OPC_LDPC + (2 << 16):
3206 case R6_OPC_LDPC + (3 << 16):
3207 check_mips_64(ctx);
3208 offset = sextract32(ctx->opcode << 3, 0, 21);
3209 addr = addr_add(ctx, (pc & ~0x7), offset);
3210 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3211 break;
3212 #endif
3213 default:
3214 MIPS_INVAL("OPC_PCREL");
3215 generate_exception_end(ctx, EXCP_RI);
3216 break;
3217 }
3218 break;
3219 }
3220 }
3221
3222 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3223 {
3224 TCGv t0, t1;
3225
3226 if (rd == 0) {
3227 /* Treat as NOP. */
3228 return;
3229 }
3230
3231 t0 = tcg_temp_new();
3232 t1 = tcg_temp_new();
3233
3234 gen_load_gpr(t0, rs);
3235 gen_load_gpr(t1, rt);
3236
3237 switch (opc) {
3238 case R6_OPC_DIV:
3239 {
3240 TCGv t2 = tcg_temp_new();
3241 TCGv t3 = tcg_temp_new();
3242 tcg_gen_ext32s_tl(t0, t0);
3243 tcg_gen_ext32s_tl(t1, t1);
3244 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3245 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3246 tcg_gen_and_tl(t2, t2, t3);
3247 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3248 tcg_gen_or_tl(t2, t2, t3);
3249 tcg_gen_movi_tl(t3, 0);
3250 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3251 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3252 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3253 tcg_temp_free(t3);
3254 tcg_temp_free(t2);
3255 }
3256 break;
3257 case R6_OPC_MOD:
3258 {
3259 TCGv t2 = tcg_temp_new();
3260 TCGv t3 = tcg_temp_new();
3261 tcg_gen_ext32s_tl(t0, t0);
3262 tcg_gen_ext32s_tl(t1, t1);
3263 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3264 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3265 tcg_gen_and_tl(t2, t2, t3);
3266 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3267 tcg_gen_or_tl(t2, t2, t3);
3268 tcg_gen_movi_tl(t3, 0);
3269 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3270 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3271 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3272 tcg_temp_free(t3);
3273 tcg_temp_free(t2);
3274 }
3275 break;
3276 case R6_OPC_DIVU:
3277 {
3278 TCGv t2 = tcg_const_tl(0);
3279 TCGv t3 = tcg_const_tl(1);
3280 tcg_gen_ext32u_tl(t0, t0);
3281 tcg_gen_ext32u_tl(t1, t1);
3282 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3283 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3284 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3285 tcg_temp_free(t3);
3286 tcg_temp_free(t2);
3287 }
3288 break;
3289 case R6_OPC_MODU:
3290 {
3291 TCGv t2 = tcg_const_tl(0);
3292 TCGv t3 = tcg_const_tl(1);
3293 tcg_gen_ext32u_tl(t0, t0);
3294 tcg_gen_ext32u_tl(t1, t1);
3295 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3296 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3297 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3298 tcg_temp_free(t3);
3299 tcg_temp_free(t2);
3300 }
3301 break;
3302 case R6_OPC_MUL:
3303 {
3304 TCGv_i32 t2 = tcg_temp_new_i32();
3305 TCGv_i32 t3 = tcg_temp_new_i32();
3306 tcg_gen_trunc_tl_i32(t2, t0);
3307 tcg_gen_trunc_tl_i32(t3, t1);
3308 tcg_gen_mul_i32(t2, t2, t3);
3309 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3310 tcg_temp_free_i32(t2);
3311 tcg_temp_free_i32(t3);
3312 }
3313 break;
3314 case R6_OPC_MUH:
3315 {
3316 TCGv_i32 t2 = tcg_temp_new_i32();
3317 TCGv_i32 t3 = tcg_temp_new_i32();
3318 tcg_gen_trunc_tl_i32(t2, t0);
3319 tcg_gen_trunc_tl_i32(t3, t1);
3320 tcg_gen_muls2_i32(t2, t3, t2, t3);
3321 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3322 tcg_temp_free_i32(t2);
3323 tcg_temp_free_i32(t3);
3324 }
3325 break;
3326 case R6_OPC_MULU:
3327 {
3328 TCGv_i32 t2 = tcg_temp_new_i32();
3329 TCGv_i32 t3 = tcg_temp_new_i32();
3330 tcg_gen_trunc_tl_i32(t2, t0);
3331 tcg_gen_trunc_tl_i32(t3, t1);
3332 tcg_gen_mul_i32(t2, t2, t3);
3333 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3334 tcg_temp_free_i32(t2);
3335 tcg_temp_free_i32(t3);
3336 }
3337 break;
3338 case R6_OPC_MUHU:
3339 {
3340 TCGv_i32 t2 = tcg_temp_new_i32();
3341 TCGv_i32 t3 = tcg_temp_new_i32();
3342 tcg_gen_trunc_tl_i32(t2, t0);
3343 tcg_gen_trunc_tl_i32(t3, t1);
3344 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3345 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3346 tcg_temp_free_i32(t2);
3347 tcg_temp_free_i32(t3);
3348 }
3349 break;
3350 #if defined(TARGET_MIPS64)
3351 case R6_OPC_DDIV:
3352 {
3353 TCGv t2 = tcg_temp_new();
3354 TCGv t3 = tcg_temp_new();
3355 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3356 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3357 tcg_gen_and_tl(t2, t2, t3);
3358 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3359 tcg_gen_or_tl(t2, t2, t3);
3360 tcg_gen_movi_tl(t3, 0);
3361 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3362 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3363 tcg_temp_free(t3);
3364 tcg_temp_free(t2);
3365 }
3366 break;
3367 case R6_OPC_DMOD:
3368 {
3369 TCGv t2 = tcg_temp_new();
3370 TCGv t3 = tcg_temp_new();
3371 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3372 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3373 tcg_gen_and_tl(t2, t2, t3);
3374 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3375 tcg_gen_or_tl(t2, t2, t3);
3376 tcg_gen_movi_tl(t3, 0);
3377 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3378 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3379 tcg_temp_free(t3);
3380 tcg_temp_free(t2);
3381 }
3382 break;
3383 case R6_OPC_DDIVU:
3384 {
3385 TCGv t2 = tcg_const_tl(0);
3386 TCGv t3 = tcg_const_tl(1);
3387 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3388 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3389 tcg_temp_free(t3);
3390 tcg_temp_free(t2);
3391 }
3392 break;
3393 case R6_OPC_DMODU:
3394 {
3395 TCGv t2 = tcg_const_tl(0);
3396 TCGv t3 = tcg_const_tl(1);
3397 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3398 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3399 tcg_temp_free(t3);
3400 tcg_temp_free(t2);
3401 }
3402 break;
3403 case R6_OPC_DMUL:
3404 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3405 break;
3406 case R6_OPC_DMUH:
3407 {
3408 TCGv t2 = tcg_temp_new();
3409 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3410 tcg_temp_free(t2);
3411 }
3412 break;
3413 case R6_OPC_DMULU:
3414 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3415 break;
3416 case R6_OPC_DMUHU:
3417 {
3418 TCGv t2 = tcg_temp_new();
3419 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3420 tcg_temp_free(t2);
3421 }
3422 break;
3423 #endif
3424 default:
3425 MIPS_INVAL("r6 mul/div");
3426 generate_exception_end(ctx, EXCP_RI);
3427 goto out;
3428 }
3429 out:
3430 tcg_temp_free(t0);
3431 tcg_temp_free(t1);
3432 }
3433
3434 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3435 int acc, int rs, int rt)
3436 {
3437 TCGv t0, t1;
3438
3439 t0 = tcg_temp_new();
3440 t1 = tcg_temp_new();
3441
3442 gen_load_gpr(t0, rs);
3443 gen_load_gpr(t1, rt);
3444
3445 if (acc != 0) {
3446 check_dsp(ctx);
3447 }
3448
3449 switch (opc) {
3450 case OPC_DIV:
3451 {
3452 TCGv t2 = tcg_temp_new();
3453 TCGv t3 = tcg_temp_new();
3454 tcg_gen_ext32s_tl(t0, t0);
3455 tcg_gen_ext32s_tl(t1, t1);
3456 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3457 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3458 tcg_gen_and_tl(t2, t2, t3);
3459 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3460 tcg_gen_or_tl(t2, t2, t3);
3461 tcg_gen_movi_tl(t3, 0);
3462 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3463 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3464 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3465 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3466 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3467 tcg_temp_free(t3);
3468 tcg_temp_free(t2);
3469 }
3470 break;
3471 case OPC_DIVU:
3472 {
3473 TCGv t2 = tcg_const_tl(0);
3474 TCGv t3 = tcg_const_tl(1);
3475 tcg_gen_ext32u_tl(t0, t0);
3476 tcg_gen_ext32u_tl(t1, t1);
3477 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3478 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3479 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3480 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3481 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3482 tcg_temp_free(t3);
3483 tcg_temp_free(t2);
3484 }
3485 break;
3486 case OPC_MULT:
3487 {
3488 TCGv_i32 t2 = tcg_temp_new_i32();
3489 TCGv_i32 t3 = tcg_temp_new_i32();
3490 tcg_gen_trunc_tl_i32(t2, t0);
3491 tcg_gen_trunc_tl_i32(t3, t1);
3492 tcg_gen_muls2_i32(t2, t3, t2, t3);
3493 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3494 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3495 tcg_temp_free_i32(t2);
3496 tcg_temp_free_i32(t3);
3497 }
3498 break;
3499 case OPC_MULTU:
3500 {
3501 TCGv_i32 t2 = tcg_temp_new_i32();
3502 TCGv_i32 t3 = tcg_temp_new_i32();
3503 tcg_gen_trunc_tl_i32(t2, t0);
3504 tcg_gen_trunc_tl_i32(t3, t1);
3505 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3506 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3507 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3508 tcg_temp_free_i32(t2);
3509 tcg_temp_free_i32(t3);
3510 }
3511 break;
3512 #if defined(TARGET_MIPS64)
3513 case OPC_DDIV:
3514 {
3515 TCGv t2 = tcg_temp_new();
3516 TCGv t3 = tcg_temp_new();
3517 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3518 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3519 tcg_gen_and_tl(t2, t2, t3);
3520 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3521 tcg_gen_or_tl(t2, t2, t3);
3522 tcg_gen_movi_tl(t3, 0);
3523 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3524 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3525 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3526 tcg_temp_free(t3);
3527 tcg_temp_free(t2);
3528 }
3529 break;
3530 case OPC_DDIVU:
3531 {
3532 TCGv t2 = tcg_const_tl(0);
3533 TCGv t3 = tcg_const_tl(1);
3534 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3535 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3536 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3537 tcg_temp_free(t3);
3538 tcg_temp_free(t2);
3539 }
3540 break;
3541 case OPC_DMULT:
3542 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3543 break;
3544 case OPC_DMULTU:
3545 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3546 break;
3547 #endif
3548 case OPC_MADD:
3549 {
3550 TCGv_i64 t2 = tcg_temp_new_i64();
3551 TCGv_i64 t3 = tcg_temp_new_i64();
3552
3553 tcg_gen_ext_tl_i64(t2, t0);
3554 tcg_gen_ext_tl_i64(t3, t1);
3555 tcg_gen_mul_i64(t2, t2, t3);
3556 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3557 tcg_gen_add_i64(t2, t2, t3);
3558 tcg_temp_free_i64(t3);
3559 gen_move_low32(cpu_LO[acc], t2);
3560 gen_move_high32(cpu_HI[acc], t2);
3561 tcg_temp_free_i64(t2);
3562 }
3563 break;
3564 case OPC_MADDU:
3565 {
3566 TCGv_i64 t2 = tcg_temp_new_i64();
3567 TCGv_i64 t3 = tcg_temp_new_i64();
3568
3569 tcg_gen_ext32u_tl(t0, t0);
3570 tcg_gen_ext32u_tl(t1, t1);
3571 tcg_gen_extu_tl_i64(t2, t0);
3572 tcg_gen_extu_tl_i64(t3, t1);
3573 tcg_gen_mul_i64(t2, t2, t3);
3574 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3575 tcg_gen_add_i64(t2, t2, t3);
3576 tcg_temp_free_i64(t3);
3577 gen_move_low32(cpu_LO[acc], t2);
3578 gen_move_high32(cpu_HI[acc], t2);
3579 tcg_temp_free_i64(t2);
3580 }
3581 break;
3582 case OPC_MSUB:
3583 {
3584 TCGv_i64 t2 = tcg_temp_new_i64();
3585 TCGv_i64 t3 = tcg_temp_new_i64();
3586
3587 tcg_gen_ext_tl_i64(t2, t0);
3588 tcg_gen_ext_tl_i64(t3, t1);
3589 tcg_gen_mul_i64(t2, t2, t3);
3590 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3591 tcg_gen_sub_i64(t2, t3, t2);
3592 tcg_temp_free_i64(t3);
3593 gen_move_low32(cpu_LO[acc], t2);
3594 gen_move_high32(cpu_HI[acc], t2);
3595 tcg_temp_free_i64(t2);
3596 }
3597 break;
3598 case OPC_MSUBU:
3599 {
3600 TCGv_i64 t2 = tcg_temp_new_i64();
3601 TCGv_i64 t3 = tcg_temp_new_i64();
3602
3603 tcg_gen_ext32u_tl(t0, t0);
3604 tcg_gen_ext32u_tl(t1, t1);
3605 tcg_gen_extu_tl_i64(t2, t0);
3606 tcg_gen_extu_tl_i64(t3, t1);
3607 tcg_gen_mul_i64(t2, t2, t3);
3608 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3609 tcg_gen_sub_i64(t2, t3, t2);
3610 tcg_temp_free_i64(t3);
3611 gen_move_low32(cpu_LO[acc], t2);
3612 gen_move_high32(cpu_HI[acc], t2);
3613 tcg_temp_free_i64(t2);
3614 }
3615 break;
3616 default:
3617 MIPS_INVAL("mul/div");
3618 generate_exception_end(ctx, EXCP_RI);
3619 goto out;
3620 }
3621 out:
3622 tcg_temp_free(t0);
3623 tcg_temp_free(t1);
3624 }
3625
3626 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3627 int rd, int rs, int rt)
3628 {
3629 TCGv t0 = tcg_temp_new();
3630 TCGv t1 = tcg_temp_new();
3631
3632 gen_load_gpr(t0, rs);
3633 gen_load_gpr(t1, rt);
3634
3635 switch (opc) {
3636 case OPC_VR54XX_MULS:
3637 gen_helper_muls(t0, cpu_env, t0, t1);
3638 break;
3639 case OPC_VR54XX_MULSU:
3640 gen_helper_mulsu(t0, cpu_env, t0, t1);
3641 break;
3642 case OPC_VR54XX_MACC:
3643 gen_helper_macc(t0, cpu_env, t0, t1);
3644 break;
3645 case OPC_VR54XX_MACCU:
3646 gen_helper_maccu(t0, cpu_env, t0, t1);
3647 break;
3648 case OPC_VR54XX_MSAC:
3649 gen_helper_msac(t0, cpu_env, t0, t1);
3650 break;
3651 case OPC_VR54XX_MSACU:
3652 gen_helper_msacu(t0, cpu_env, t0, t1);
3653 break;
3654 case OPC_VR54XX_MULHI:
3655 gen_helper_mulhi(t0, cpu_env, t0, t1);
3656 break;
3657 case OPC_VR54XX_MULHIU:
3658 gen_helper_mulhiu(t0, cpu_env, t0, t1);
3659 break;
3660 case OPC_VR54XX_MULSHI:
3661 gen_helper_mulshi(t0, cpu_env, t0, t1);
3662 break;
3663 case OPC_VR54XX_MULSHIU:
3664 gen_helper_mulshiu(t0, cpu_env, t0, t1);
3665 break;
3666 case OPC_VR54XX_MACCHI:
3667 gen_helper_macchi(t0, cpu_env, t0, t1);
3668 break;
3669 case OPC_VR54XX_MACCHIU:
3670 gen_helper_macchiu(t0, cpu_env, t0, t1);
3671 break;
3672 case OPC_VR54XX_MSACHI:
3673 gen_helper_msachi(t0, cpu_env, t0, t1);
3674 break;
3675 case OPC_VR54XX_MSACHIU:
3676 gen_helper_msachiu(t0, cpu_env, t0, t1);
3677 break;
3678 default:
3679 MIPS_INVAL("mul vr54xx");
3680 generate_exception_end(ctx, EXCP_RI);
3681 goto out;
3682 }
3683 gen_store_gpr(t0, rd);
3684
3685 out:
3686 tcg_temp_free(t0);
3687 tcg_temp_free(t1);
3688 }
3689
3690 static void gen_cl (DisasContext *ctx, uint32_t opc,
3691 int rd, int rs)
3692 {
3693 TCGv t0;
3694
3695 if (rd == 0) {
3696 /* Treat as NOP. */
3697 return;
3698 }
3699 t0 = cpu_gpr[rd];
3700 gen_load_gpr(t0, rs);
3701
3702 switch (opc) {
3703 case OPC_CLO:
3704 case R6_OPC_CLO:
3705 #if defined(TARGET_MIPS64)
3706 case OPC_DCLO:
3707 case R6_OPC_DCLO:
3708 #endif
3709 tcg_gen_not_tl(t0, t0);
3710 break;
3711 }
3712
3713 switch (opc) {
3714 case OPC_CLO:
3715 case R6_OPC_CLO:
3716 case OPC_CLZ:
3717 case R6_OPC_CLZ:
3718 tcg_gen_ext32u_tl(t0, t0);
3719 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3720 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3721 break;
3722 #if defined(TARGET_MIPS64)
3723 case OPC_DCLO:
3724 case R6_OPC_DCLO:
3725 case OPC_DCLZ:
3726 case R6_OPC_DCLZ:
3727 tcg_gen_clzi_i64(t0, t0, 64);
3728 break;
3729 #endif
3730 }
3731 }
3732
3733 /* Godson integer instructions */
3734 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3735 int rd, int rs, int rt)
3736 {
3737 TCGv t0, t1;
3738
3739 if (rd == 0) {
3740 /* Treat as NOP. */
3741 return;
3742 }
3743
3744 switch (opc) {
3745 case OPC_MULT_G_2E:
3746 case OPC_MULT_G_2F:
3747 case OPC_MULTU_G_2E:
3748 case OPC_MULTU_G_2F:
3749 #if defined(TARGET_MIPS64)
3750 case OPC_DMULT_G_2E:
3751 case OPC_DMULT_G_2F:
3752 case OPC_DMULTU_G_2E:
3753 case OPC_DMULTU_G_2F:
3754 #endif
3755 t0 = tcg_temp_new();
3756 t1 = tcg_temp_new();
3757 break;
3758 default:
3759 t0 = tcg_temp_local_new();
3760 t1 = tcg_temp_local_new();
3761 break;
3762 }
3763
3764 gen_load_gpr(t0, rs);
3765 gen_load_gpr(t1, rt);
3766
3767 switch (opc) {
3768 case OPC_MULT_G_2E:
3769 case OPC_MULT_G_2F:
3770 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3771 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3772 break;
3773 case OPC_MULTU_G_2E:
3774 case OPC_MULTU_G_2F:
3775 tcg_gen_ext32u_tl(t0, t0);
3776 tcg_gen_ext32u_tl(t1, t1);
3777 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3778 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3779 break;
3780 case OPC_DIV_G_2E:
3781 case OPC_DIV_G_2F:
3782 {
3783 TCGLabel *l1 = gen_new_label();
3784 TCGLabel *l2 = gen_new_label();
3785 TCGLabel *l3 = gen_new_label();
3786 tcg_gen_ext32s_tl(t0, t0);
3787 tcg_gen_ext32s_tl(t1, t1);
3788 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3789 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3790 tcg_gen_br(l3);
3791 gen_set_label(l1);
3792 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3793 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3794 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3795 tcg_gen_br(l3);
3796 gen_set_label(l2);
3797 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3798 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3799 gen_set_label(l3);
3800 }
3801 break;
3802 case OPC_DIVU_G_2E:
3803 case OPC_DIVU_G_2F:
3804 {
3805 TCGLabel *l1 = gen_new_label();
3806 TCGLabel *l2 = gen_new_label();
3807 tcg_gen_ext32u_tl(t0, t0);
3808 tcg_gen_ext32u_tl(t1, t1);
3809 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3810 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3811 tcg_gen_br(l2);
3812 gen_set_label(l1);
3813 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3814 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3815 gen_set_label(l2);
3816 }
3817 break;
3818 case OPC_MOD_G_2E:
3819 case OPC_MOD_G_2F:
3820 {
3821 TCGLabel *l1 = gen_new_label();
3822 TCGLabel *l2 = gen_new_label();
3823 TCGLabel *l3 = gen_new_label();
3824 tcg_gen_ext32u_tl(t0, t0);
3825 tcg_gen_ext32u_tl(t1, t1);
3826 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3827 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3828 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3829 gen_set_label(l1);
3830 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3831 tcg_gen_br(l3);
3832 gen_set_label(l2);
3833 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3834 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3835 gen_set_label(l3);
3836 }
3837 break;
3838 case OPC_MODU_G_2E:
3839 case OPC_MODU_G_2F:
3840 {
3841 TCGLabel *l1 = gen_new_label();
3842 TCGLabel *l2 = gen_new_label();
3843 tcg_gen_ext32u_tl(t0, t0);
3844 tcg_gen_ext32u_tl(t1, t1);
3845 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3846 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3847 tcg_gen_br(l2);
3848 gen_set_label(l1);
3849 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3850 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3851 gen_set_label(l2);
3852 }
3853 break;
3854 #if defined(TARGET_MIPS64)
3855 case OPC_DMULT_G_2E:
3856 case OPC_DMULT_G_2F:
3857 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3858 break;
3859 case OPC_DMULTU_G_2E:
3860 case OPC_DMULTU_G_2F:
3861 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3862 break;
3863 case OPC_DDIV_G_2E:
3864 case OPC_DDIV_G_2F:
3865 {
3866 TCGLabel *l1 = gen_new_label();
3867 TCGLabel *l2 = gen_new_label();
3868 TCGLabel *l3 = gen_new_label();
3869 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3870 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3871 tcg_gen_br(l3);
3872 gen_set_label(l1);
3873 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3874 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3875 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3876 tcg_gen_br(l3);
3877 gen_set_label(l2);
3878 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3879 gen_set_label(l3);
3880 }
3881 break;
3882 case OPC_DDIVU_G_2E:
3883 case OPC_DDIVU_G_2F:
3884 {
3885 TCGLabel *l1 = gen_new_label();
3886 TCGLabel *l2 = gen_new_label();
3887 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3888 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3889 tcg_gen_br(l2);
3890 gen_set_label(l1);
3891 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3892 gen_set_label(l2);
3893 }
3894 break;
3895 case OPC_DMOD_G_2E:
3896 case OPC_DMOD_G_2F:
3897 {
3898 TCGLabel *l1 = gen_new_label();
3899 TCGLabel *l2 = gen_new_label();
3900 TCGLabel *l3 = gen_new_label();
3901 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3902 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3903 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3904 gen_set_label(l1);
3905 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3906 tcg_gen_br(l3);
3907 gen_set_label(l2);
3908 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3909 gen_set_label(l3);
3910 }
3911 break;
3912 case OPC_DMODU_G_2E:
3913 case OPC_DMODU_G_2F:
3914 {
3915 TCGLabel *l1 = gen_new_label();
3916 TCGLabel *l2 = gen_new_label();
3917 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3918 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3919 tcg_gen_br(l2);
3920 gen_set_label(l1);
3921 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3922 gen_set_label(l2);
3923 }
3924 break;
3925 #endif
3926 }
3927
3928 tcg_temp_free(t0);
3929 tcg_temp_free(t1);
3930 }
3931
3932 /* Loongson multimedia instructions */
3933 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3934 {
3935 uint32_t opc, shift_max;
3936 TCGv_i64 t0, t1;
3937
3938 opc = MASK_LMI(ctx->opcode);
3939 switch (opc) {
3940 case OPC_ADD_CP2:
3941 case OPC_SUB_CP2:
3942 case OPC_DADD_CP2:
3943 case OPC_DSUB_CP2:
3944 t0 = tcg_temp_local_new_i64();
3945 t1 = tcg_temp_local_new_i64();
3946 break;
3947 default:
3948 t0 = tcg_temp_new_i64();
3949 t1 = tcg_temp_new_i64();
3950 break;
3951 }
3952
3953 check_cp1_enabled(ctx);
3954 gen_load_fpr64(ctx, t0, rs);
3955 gen_load_fpr64(ctx, t1, rt);
3956
3957 #define LMI_HELPER(UP, LO) \
3958 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3959 #define LMI_HELPER_1(UP, LO) \
3960 case OPC_##UP: gen_helper_##LO(t0, t0); break
3961 #define LMI_DIRECT(UP, LO, OP) \
3962 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3963
3964 switch (opc) {
3965 LMI_HELPER(PADDSH, paddsh);
3966 LMI_HELPER(PADDUSH, paddush);
3967 LMI_HELPER(PADDH, paddh);
3968 LMI_HELPER(PADDW, paddw);
3969 LMI_HELPER(PADDSB, paddsb);
3970 LMI_HELPER(PADDUSB, paddusb);
3971 LMI_HELPER(PADDB, paddb);
3972
3973 LMI_HELPER(PSUBSH, psubsh);
3974 LMI_HELPER(PSUBUSH, psubush);
3975 LMI_HELPER(PSUBH, psubh);
3976 LMI_HELPER(PSUBW, psubw);
3977 LMI_HELPER(PSUBSB, psubsb);
3978 LMI_HELPER(PSUBUSB, psubusb);
3979 LMI_HELPER(PSUBB, psubb);
3980
3981 LMI_HELPER(PSHUFH, pshufh);
3982 LMI_HELPER(PACKSSWH, packsswh);
3983 LMI_HELPER(PACKSSHB, packsshb);
3984 LMI_HELPER(PACKUSHB, packushb);
3985
3986 LMI_HELPER(PUNPCKLHW, punpcklhw);
3987 LMI_HELPER(PUNPCKHHW, punpckhhw);
3988 LMI_HELPER(PUNPCKLBH, punpcklbh);
3989 LMI_HELPER(PUNPCKHBH, punpckhbh);
3990 LMI_HELPER(PUNPCKLWD, punpcklwd);
3991 LMI_HELPER(PUNPCKHWD, punpckhwd);
3992
3993 LMI_HELPER(PAVGH, pavgh);
3994 LMI_HELPER(PAVGB, pavgb);
3995 LMI_HELPER(PMAXSH, pmaxsh);
3996 LMI_HELPER(PMINSH, pminsh);
3997 LMI_HELPER(PMAXUB, pmaxub);
3998 LMI_HELPER(PMINUB, pminub);
3999
4000 LMI_HELPER(PCMPEQW, pcmpeqw);
4001 LMI_HELPER(PCMPGTW, pcmpgtw);
4002 LMI_HELPER(PCMPEQH, pcmpeqh);
4003 LMI_HELPER(PCMPGTH, pcmpgth);
4004 LMI_HELPER(PCMPEQB, pcmpeqb);
4005 LMI_HELPER(PCMPGTB, pcmpgtb);
4006
4007 LMI_HELPER(PSLLW, psllw);
4008 LMI_HELPER(PSLLH, psllh);
4009 LMI_HELPER(PSRLW, psrlw);
4010 LMI_HELPER(PSRLH, psrlh);
4011 LMI_HELPER(PSRAW, psraw);
4012 LMI_HELPER(PSRAH, psrah);
4013
4014 LMI_HELPER(PMULLH, pmullh);
4015 LMI_HELPER(PMULHH, pmulhh);
4016 LMI_HELPER(PMULHUH, pmulhuh);
4017 LMI_HELPER(PMADDHW, pmaddhw);
4018
4019 LMI_HELPER(PASUBUB, pasubub);
4020 LMI_HELPER_1(BIADD, biadd);
4021 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4022
4023 LMI_DIRECT(PADDD, paddd, add);
4024 LMI_DIRECT(PSUBD, psubd, sub);
4025 LMI_DIRECT(XOR_CP2, xor, xor);
4026 LMI_DIRECT(NOR_CP2, nor, nor);
4027 LMI_DIRECT(AND_CP2, and, and);
4028 LMI_DIRECT(OR_CP2, or, or);
4029
4030 case OPC_PANDN:
4031 tcg_gen_andc_i64(t0, t1, t0);
4032 break;
4033
4034 case OPC_PINSRH_0:
4035 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4036 break;
4037 case OPC_PINSRH_1:
4038 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4039 break;
4040 case OPC_PINSRH_2:
4041 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4042 break;
4043 case OPC_PINSRH_3:
4044 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4045 break;
4046
4047 case OPC_PEXTRH:
4048 tcg_gen_andi_i64(t1, t1, 3);
4049 tcg_gen_shli_i64(t1, t1, 4);
4050 tcg_gen_shr_i64(t0, t0, t1);
4051 tcg_gen_ext16u_i64(t0, t0);
4052 break;
4053
4054 case OPC_ADDU_CP2:
4055 tcg_gen_add_i64(t0, t0, t1);
4056 tcg_gen_ext32s_i64(t0, t0);
4057 break;
4058 case OPC_SUBU_CP2:
4059 tcg_gen_sub_i64(t0, t0, t1);
4060 tcg_gen_ext32s_i64(t0, t0);
4061 break;
4062
4063 case OPC_SLL_CP2:
4064 shift_max = 32;
4065 goto do_shift;
4066 case OPC_SRL_CP2:
4067 shift_max = 32;
4068 goto do_shift;
4069 case OPC_SRA_CP2:
4070 shift_max = 32;
4071 goto do_shift;
4072 case OPC_DSLL_CP2:
4073 shift_max = 64;
4074 goto do_shift;
4075 case OPC_DSRL_CP2:
4076 shift_max = 64;
4077 goto do_shift;
4078 case OPC_DSRA_CP2:
4079 shift_max = 64;
4080 goto do_shift;
4081 do_shift:
4082 /* Make sure shift count isn't TCG undefined behaviour. */
4083 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4084
4085 switch (opc) {
4086 case OPC_SLL_CP2:
4087 case OPC_DSLL_CP2:
4088 tcg_gen_shl_i64(t0, t0, t1);
4089 break;
4090 case OPC_SRA_CP2:
4091 case OPC_DSRA_CP2:
4092 /* Since SRA is UndefinedResult without sign-extended inputs,
4093 we can treat SRA and DSRA the same. */
4094 tcg_gen_sar_i64(t0, t0, t1);
4095 break;
4096 case OPC_SRL_CP2:
4097 /* We want to shift in zeros for SRL; zero-extend first. */
4098 tcg_gen_ext32u_i64(t0, t0);
4099 /* FALLTHRU */
4100 case OPC_DSRL_CP2:
4101 tcg_gen_shr_i64(t0, t0, t1);
4102 break;
4103 }
4104
4105 if (shift_max == 32) {
4106 tcg_gen_ext32s_i64(t0, t0);
4107 }
4108
4109 /* Shifts larger than MAX produce zero. */
4110 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4111 tcg_gen_neg_i64(t1, t1);
4112 tcg_gen_and_i64(t0, t0, t1);
4113 break;
4114
4115 case OPC_ADD_CP2:
4116 case OPC_DADD_CP2:
4117 {
4118 TCGv_i64 t2 = tcg_temp_new_i64();
4119 TCGLabel *lab = gen_new_label();
4120
4121 tcg_gen_mov_i64(t2, t0);
4122 tcg_gen_add_i64(t0, t1, t2);
4123 if (opc == OPC_ADD_CP2) {
4124 tcg_gen_ext32s_i64(t0, t0);
4125 }
4126 tcg_gen_xor_i64(t1, t1, t2);
4127 tcg_gen_xor_i64(t2, t2, t0);
4128 tcg_gen_andc_i64(t1, t2, t1);
4129 tcg_temp_free_i64(t2);
4130 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4131 generate_exception(ctx, EXCP_OVERFLOW);
4132 gen_set_label(lab);
4133 break;
4134 }
4135
4136 case OPC_SUB_CP2:
4137 case OPC_DSUB_CP2:
4138 {
4139 TCGv_i64 t2 = tcg_temp_new_i64();
4140 TCGLabel *lab = gen_new_label();
4141
4142 tcg_gen_mov_i64(t2, t0);
4143 tcg_gen_sub_i64(t0, t1, t2);
4144 if (opc == OPC_SUB_CP2) {
4145 tcg_gen_ext32s_i64(t0, t0);
4146 }
4147 tcg_gen_xor_i64(t1, t1, t2);
4148 tcg_gen_xor_i64(t2, t2, t0);
4149 tcg_gen_and_i64(t1, t1, t2);
4150 tcg_temp_free_i64(t2);
4151 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4152 generate_exception(ctx, EXCP_OVERFLOW);
4153 gen_set_label(lab);
4154 break;
4155 }
4156
4157 case OPC_PMULUW:
4158 tcg_gen_ext32u_i64(t0, t0);
4159 tcg_gen_ext32u_i64(t1, t1);
4160 tcg_gen_mul_i64(t0, t0, t1);
4161 break;
4162
4163 case OPC_SEQU_CP2:
4164 case OPC_SEQ_CP2:
4165 case OPC_SLTU_CP2:
4166 case OPC_SLT_CP2:
4167 case OPC_SLEU_CP2:
4168 case OPC_SLE_CP2:
4169 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4170 FD field is the CC field? */
4171 default:
4172 MIPS_INVAL("loongson_cp2");
4173 generate_exception_end(ctx, EXCP_RI);
4174 return;
4175 }
4176
4177 #undef LMI_HELPER
4178 #undef LMI_DIRECT
4179
4180 gen_store_fpr64(ctx, t0, rd);
4181
4182 tcg_temp_free_i64(t0);
4183 tcg_temp_free_i64(t1);
4184 }
4185
4186 /* Traps */
4187 static void gen_trap (DisasContext *ctx, uint32_t opc,
4188 int rs, int rt, int16_t imm)
4189 {
4190 int cond;
4191 TCGv t0 = tcg_temp_new();
4192 TCGv t1 = tcg_temp_new();
4193
4194 cond = 0;
4195 /* Load needed operands */
4196 switch (opc) {
4197 case OPC_TEQ:
4198 case OPC_TGE:
4199 case OPC_TGEU:
4200 case OPC_TLT:
4201 case OPC_TLTU:
4202 case OPC_TNE:
4203 /* Compare two registers */
4204 if (rs != rt) {
4205 gen_load_gpr(t0, rs);
4206 gen_load_gpr(t1, rt);
4207 cond = 1;
4208 }
4209 break;
4210 case OPC_TEQI:
4211 case OPC_TGEI:
4212 case OPC_TGEIU:
4213 case OPC_TLTI:
4214 case OPC_TLTIU:
4215 case OPC_TNEI:
4216 /* Compare register to immediate */
4217 if (rs != 0 || imm != 0) {
4218 gen_load_gpr(t0, rs);
4219 tcg_gen_movi_tl(t1, (int32_t)imm);
4220 cond = 1;
4221 }
4222 break;
4223 }
4224 if (cond == 0) {
4225 switch (opc) {
4226 case OPC_TEQ: /* rs == rs */
4227 case OPC_TEQI: /* r0 == 0 */
4228 case OPC_TGE: /* rs >= rs */
4229 case OPC_TGEI: /* r0 >= 0 */
4230 case OPC_TGEU: /* rs >= rs unsigned */
4231 case OPC_TGEIU: /* r0 >= 0 unsigned */
4232 /* Always trap */
4233 generate_exception_end(ctx, EXCP_TRAP);
4234 break;
4235 case OPC_TLT: /* rs < rs */
4236 case OPC_TLTI: /* r0 < 0 */
4237 case OPC_TLTU: /* rs < rs unsigned */
4238 case OPC_TLTIU: /* r0 < 0 unsigned */
4239 case OPC_TNE: /* rs != rs */
4240 case OPC_TNEI: /* r0 != 0 */
4241 /* Never trap: treat as NOP. */
4242 break;
4243 }
4244 } else {
4245 TCGLabel *l1 = gen_new_label();
4246
4247 switch (opc) {
4248 case OPC_TEQ:
4249 case OPC_TEQI:
4250 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4251 break;
4252 case OPC_TGE:
4253 case OPC_TGEI:
4254 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4255 break;
4256 case OPC_TGEU:
4257 case OPC_TGEIU:
4258 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4259 break;
4260 case OPC_TLT:
4261 case OPC_TLTI:
4262 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4263 break;
4264 case OPC_TLTU:
4265 case OPC_TLTIU:
4266 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4267 break;
4268 case OPC_TNE:
4269 case OPC_TNEI:
4270 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4271 break;
4272 }
4273 generate_exception(ctx, EXCP_TRAP);
4274 gen_set_label(l1);
4275 }
4276 tcg_temp_free(t0);
4277 tcg_temp_free(t1);
4278 }
4279
4280 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4281 {
4282 if (unlikely(ctx->singlestep_enabled)) {
4283 return false;
4284 }
4285
4286 #ifndef CONFIG_USER_ONLY
4287 return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4288 #else
4289 return true;
4290 #endif
4291 }
4292
4293 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4294 {
4295 if (use_goto_tb(ctx, dest)) {
4296 tcg_gen_goto_tb(n);
4297 gen_save_pc(dest);
4298 tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
4299 } else {
4300 gen_save_pc(dest);
4301 if (ctx->singlestep_enabled) {
4302 save_cpu_state(ctx, 0);
4303 gen_helper_raise_exception_debug(cpu_env);
4304 }
4305 tcg_gen_lookup_and_goto_ptr(cpu_PC);
4306 }
4307 }
4308
4309 /* Branches (before delay slot) */
4310 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4311 int insn_bytes,
4312 int rs, int rt, int32_t offset,
4313 int delayslot_size)
4314 {
4315 target_ulong btgt = -1;
4316 int blink = 0;
4317 int bcond_compute = 0;
4318 TCGv t0 = tcg_temp_new();
4319 TCGv t1 = tcg_temp_new();
4320
4321 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4322 #ifdef MIPS_DEBUG_DISAS
4323 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4324 TARGET_FMT_lx "\n", ctx->pc);
4325 #endif
4326 generate_exception_end(ctx, EXCP_RI);
4327 goto out;
4328 }
4329
4330 /* Load needed operands */
4331 switch (opc) {
4332 case OPC_BEQ:
4333 case OPC_BEQL:
4334 case OPC_BNE:
4335 case OPC_BNEL:
4336 /* Compare two registers */
4337 if (rs != rt) {
4338 gen_load_gpr(t0, rs);
4339 gen_load_gpr(t1, rt);
4340 bcond_compute = 1;
4341 }
4342 btgt = ctx->pc + insn_bytes + offset;
4343 break;
4344 case OPC_BGEZ:
4345 case OPC_BGEZAL:
4346 case OPC_BGEZALL:
4347 case OPC_BGEZL:
4348 case OPC_BGTZ:
4349 case OPC_BGTZL:
4350 case OPC_BLEZ:
4351 case OPC_BLEZL:
4352 case OPC_BLTZ:
4353 case OPC_BLTZAL:
4354 case OPC_BLTZALL:
4355 case OPC_BLTZL:
4356 /* Compare to zero */
4357 if (rs != 0) {
4358 gen_load_gpr(t0, rs);
4359 bcond_compute = 1;
4360 }
4361 btgt = ctx->pc + insn_bytes + offset;
4362 break;
4363 case OPC_BPOSGE32:
4364 #if defined(TARGET_MIPS64)
4365 case OPC_BPOSGE64:
4366 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4367 #else
4368 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4369 #endif
4370 bcond_compute = 1;
4371 btgt = ctx->pc + insn_bytes + offset;
4372 break;
4373 case OPC_J:
4374 case OPC_JAL:
4375 case OPC_JALX:
4376 /* Jump to immediate */
4377 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4378 break;
4379 case OPC_JR:
4380 case OPC_JALR:
4381 /* Jump to register */
4382 if (offset != 0 && offset != 16) {
4383 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4384 others are reserved. */
4385 MIPS_INVAL("jump hint");
4386 generate_exception_end(ctx, EXCP_RI);
4387 goto out;
4388 }
4389 gen_load_gpr(btarget, rs);
4390 break;
4391 default:
4392 MIPS_INVAL("branch/jump");
4393 generate_exception_end(ctx, EXCP_RI);
4394 goto out;
4395 }
4396 if (bcond_compute == 0) {
4397 /* No condition to be computed */
4398 switch (opc) {
4399 case OPC_BEQ: /* rx == rx */
4400 case OPC_BEQL: /* rx == rx likely */
4401 case OPC_BGEZ: /* 0 >= 0 */
4402 case OPC_BGEZL: /* 0 >= 0 likely */
4403 case OPC_BLEZ: /* 0 <= 0 */
4404 case OPC_BLEZL: /* 0 <= 0 likely */
4405 /* Always take */
4406 ctx->hflags |= MIPS_HFLAG_B;
4407 break;
4408 case OPC_BGEZAL: /* 0 >= 0 */
4409 case OPC_BGEZALL: /* 0 >= 0 likely */
4410 /* Always take and link */
4411 blink = 31;
4412 ctx->hflags |= MIPS_HFLAG_B;
4413 break;
4414 case OPC_BNE: /* rx != rx */
4415 case OPC_BGTZ: /* 0 > 0 */
4416 case OPC_BLTZ: /* 0 < 0 */
4417 /* Treat as NOP. */
4418 goto out;
4419 case OPC_BLTZAL: /* 0 < 0 */
4420 /* Handle as an unconditional branch to get correct delay
4421 slot checking. */
4422 blink = 31;
4423 btgt = ctx->pc + insn_bytes + delayslot_size;
4424 ctx->hflags |= MIPS_HFLAG_B;
4425 break;
4426 case OPC_BLTZALL: /* 0 < 0 likely */
4427 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4428 /* Skip the instruction in the delay slot */
4429 ctx->pc += 4;
4430 goto out;
4431 case OPC_BNEL: /* rx != rx likely */
4432 case OPC_BGTZL: /* 0 > 0 likely */
4433 case OPC_BLTZL: /* 0 < 0 likely */
4434 /* Skip the instruction in the delay slot */
4435 ctx->pc += 4;
4436 goto out;
4437 case OPC_J:
4438 ctx->hflags |= MIPS_HFLAG_B;
4439 break;
4440 case OPC_JALX:
4441 ctx->hflags |= MIPS_HFLAG_BX;
4442 /* Fallthrough */
4443 case OPC_JAL:
4444 blink = 31;
4445 ctx->hflags |= MIPS_HFLAG_B;
4446 break;
4447 case OPC_JR:
4448 ctx->hflags |= MIPS_HFLAG_BR;
4449 break;
4450 case OPC_JALR:
4451 blink = rt;
4452 ctx->hflags |= MIPS_HFLAG_BR;
4453 break;
4454 default:
4455 MIPS_INVAL("branch/jump");
4456 generate_exception_end(ctx, EXCP_RI);
4457 goto out;
4458 }
4459 } else {
4460 switch (opc) {
4461 case OPC_BEQ:
4462 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4463 goto not_likely;
4464 case OPC_BEQL:
4465 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4466 goto likely;
4467 case OPC_BNE:
4468 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4469 goto not_likely;
4470 case OPC_BNEL:
4471 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4472 goto likely;
4473 case OPC_BGEZ:
4474 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4475 goto not_likely;
4476 case OPC_BGEZL:
4477 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4478 goto likely;
4479 case OPC_BGEZAL:
4480 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4481 blink = 31;
4482 goto not_likely;
4483 case OPC_BGEZALL:
4484 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4485 blink = 31;
4486 goto likely;
4487 case OPC_BGTZ:
4488 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4489 goto not_likely;
4490 case OPC_BGTZL:
4491 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4492 goto likely;
4493 case OPC_BLEZ:
4494 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4495 goto not_likely;
4496 case OPC_BLEZL:
4497 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4498 goto likely;
4499 case OPC_BLTZ:
4500 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4501 goto not_likely;
4502 case OPC_BLTZL:
4503 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4504 goto likely;
4505 case OPC_BPOSGE32:
4506 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4507 goto not_likely;
4508 #if defined(TARGET_MIPS64)
4509 case OPC_BPOSGE64:
4510 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4511 goto not_likely;
4512 #endif
4513 case OPC_BLTZAL:
4514 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4515 blink = 31;
4516 not_likely:
4517 ctx->hflags |= MIPS_HFLAG_BC;
4518 break;
4519 case OPC_BLTZALL:
4520 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4521 blink = 31;
4522 likely:
4523 ctx->hflags |= MIPS_HFLAG_BL;
4524 break;
4525 default:
4526 MIPS_INVAL("conditional branch/jump");
4527 generate_exception_end(ctx, EXCP_RI);
4528 goto out;
4529 }
4530 }
4531
4532 ctx->btarget = btgt;
4533
4534 switch (delayslot_size) {
4535 case 2:
4536 ctx->hflags |= MIPS_HFLAG_BDS16;
4537 break;
4538 case 4:
4539 ctx->hflags |= MIPS_HFLAG_BDS32;
4540 break;
4541 }
4542
4543 if (blink > 0) {
4544 int post_delay = insn_bytes + delayslot_size;
4545 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4546
4547 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4548 }
4549
4550 out:
4551 if (insn_bytes == 2)
4552 ctx->hflags |= MIPS_HFLAG_B16;
4553 tcg_temp_free(t0);
4554 tcg_temp_free(t1);
4555 }
4556
4557 /* special3 bitfield operations */
4558 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4559 int rs, int lsb, int msb)
4560 {
4561 TCGv t0 = tcg_temp_new();
4562 TCGv t1 = tcg_temp_new();
4563
4564 gen_load_gpr(t1, rs);
4565 switch (opc) {
4566 case OPC_EXT:
4567 if (lsb + msb > 31) {
4568 goto fail;
4569 }
4570 if (msb != 31) {
4571 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4572 } else {
4573 /* The two checks together imply that lsb == 0,
4574 so this is a simple sign-extension. */
4575 tcg_gen_ext32s_tl(t0, t1);
4576 }
4577 break;
4578 #if defined(TARGET_MIPS64)
4579 case OPC_DEXTU:
4580 lsb += 32;
4581 goto do_dext;
4582 case OPC_DEXTM:
4583 msb += 32;
4584 goto do_dext;
4585 case OPC_DEXT:
4586 do_dext:
4587 if (lsb + msb > 63) {
4588 goto fail;
4589 }
4590 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4591 break;
4592 #endif
4593 case OPC_INS:
4594 if (lsb > msb) {
4595 goto fail;
4596 }
4597 gen_load_gpr(t0, rt);
4598 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4599 tcg_gen_ext32s_tl(t0, t0);
4600 break;
4601 #if defined(TARGET_MIPS64)
4602 case OPC_DINSU:
4603 lsb += 32;
4604 /* FALLTHRU */
4605 case OPC_DINSM:
4606 msb += 32;
4607 /* FALLTHRU */
4608 case OPC_DINS:
4609 if (lsb > msb) {
4610 goto fail;
4611 }
4612 gen_load_gpr(t0, rt);
4613 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4614 break;
4615 #endif
4616 default:
4617 fail:
4618 MIPS_INVAL("bitops");
4619 generate_exception_end(ctx, EXCP_RI);
4620 tcg_temp_free(t0);
4621 tcg_temp_free(t1);
4622 return;
4623 }
4624 gen_store_gpr(t0, rt);
4625 tcg_temp_free(t0);
4626 tcg_temp_free(t1);
4627 }
4628
4629 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4630 {
4631 TCGv t0;
4632
4633 if (rd == 0) {
4634 /* If no destination, treat it as a NOP. */
4635 return;
4636 }
4637
4638 t0 = tcg_temp_new();
4639 gen_load_gpr(t0, rt);
4640 switch (op2) {
4641 case OPC_WSBH:
4642 {
4643 TCGv t1 = tcg_temp_new();
4644 TCGv t2 = tcg_const_tl(0x00FF00FF);
4645
4646 tcg_gen_shri_tl(t1, t0, 8);
4647 tcg_gen_and_tl(t1, t1, t2);
4648 tcg_gen_and_tl(t0, t0, t2);
4649 tcg_gen_shli_tl(t0, t0, 8);
4650 tcg_gen_or_tl(t0, t0, t1);
4651 tcg_temp_free(t2);
4652 tcg_temp_free(t1);
4653 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4654 }
4655 break;
4656 case OPC_SEB:
4657 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4658 break;
4659 case OPC_SEH:
4660 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4661 break;
4662 #if defined(TARGET_MIPS64)
4663 case OPC_DSBH:
4664 {
4665 TCGv t1 = tcg_temp_new();
4666 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
4667
4668 tcg_gen_shri_tl(t1, t0, 8);
4669 tcg_gen_and_tl(t1, t1, t2);
4670 tcg_gen_and_tl(t0, t0, t2);
4671 tcg_gen_shli_tl(t0, t0, 8);
4672 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4673 tcg_temp_free(t2);
4674 tcg_temp_free(t1);
4675 }
4676 break;
4677 case OPC_DSHD:
4678 {
4679 TCGv t1 = tcg_temp_new();
4680 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
4681
4682 tcg_gen_shri_tl(t1, t0, 16);
4683 tcg_gen_and_tl(t1, t1, t2);
4684 tcg_gen_and_tl(t0, t0, t2);
4685 tcg_gen_shli_tl(t0, t0, 16);
4686 tcg_gen_or_tl(t0, t0, t1);
4687 tcg_gen_shri_tl(t1, t0, 32);
4688 tcg_gen_shli_tl(t0, t0, 32);
4689 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4690 tcg_temp_free(t2);
4691 tcg_temp_free(t1);
4692 }
4693 break;
4694 #endif
4695 default:
4696 MIPS_INVAL("bsfhl");
4697 generate_exception_end(ctx, EXCP_RI);
4698 tcg_temp_free(t0);
4699 return;
4700 }
4701 tcg_temp_free(t0);
4702 }
4703
4704 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4705 int imm2)
4706 {
4707 TCGv t0;
4708 TCGv t1;
4709 if (rd == 0) {
4710 /* Treat as NOP. */
4711 return;
4712 }
4713 t0 = tcg_temp_new();
4714 t1 = tcg_temp_new();
4715 gen_load_gpr(t0, rs);
4716 gen_load_gpr(t1, rt);
4717 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4718 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4719 if (opc == OPC_LSA) {
4720 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4721 }
4722
4723 tcg_temp_free(t1);
4724 tcg_temp_free(t0);
4725
4726 return;
4727 }
4728
4729 static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4730 int bp)
4731 {
4732 TCGv t0;
4733 if (rd == 0) {
4734 /* Treat as NOP. */
4735 return;
4736 }
4737 t0 = tcg_temp_new();
4738 gen_load_gpr(t0, rt);
4739 if (bp == 0) {
4740 switch (opc) {
4741 case OPC_ALIGN:
4742 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4743 break;
4744 #if defined(TARGET_MIPS64)
4745 case OPC_DALIGN:
4746 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4747 break;
4748 #endif
4749 }
4750 } else {
4751 TCGv t1 = tcg_temp_new();
4752 gen_load_gpr(t1, rs);
4753 switch (opc) {
4754 case OPC_ALIGN:
4755 {
4756 TCGv_i64 t2 = tcg_temp_new_i64();
4757 tcg_gen_concat_tl_i64(t2, t1, t0);
4758 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4759 gen_move_low32(cpu_gpr[rd], t2);
4760 tcg_temp_free_i64(t2);
4761 }
4762 break;
4763 #if defined(TARGET_MIPS64)
4764 case OPC_DALIGN:
4765 tcg_gen_shli_tl(t0, t0, 8 * bp);
4766 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4767 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4768 break;
4769 #endif
4770 }
4771 tcg_temp_free(t1);
4772 }
4773
4774 tcg_temp_free(t0);
4775 }
4776
4777 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4778 {
4779 TCGv t0;
4780 if (rd == 0) {
4781 /* Treat as NOP. */
4782 return;
4783 }
4784 t0 = tcg_temp_new();
4785 gen_load_gpr(t0, rt);
4786 switch (opc) {
4787 case OPC_BITSWAP:
4788 gen_helper_bitswap(cpu_gpr[rd], t0);
4789 break;
4790 #if defined(TARGET_MIPS64)
4791 case OPC_DBITSWAP:
4792 gen_helper_dbitswap(cpu_gpr[rd], t0);
4793 break;
4794 #endif
4795 }
4796 tcg_temp_free(t0);
4797 }
4798
4799 #ifndef CONFIG_USER_ONLY
4800 /* CP0 (MMU and control) */
4801 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4802 {
4803 TCGv_i64 t0 = tcg_temp_new_i64();
4804 TCGv_i64 t1 = tcg_temp_new_i64();
4805
4806 tcg_gen_ext_tl_i64(t0, arg);
4807 tcg_gen_ld_i64(t1, cpu_env, off);
4808 #if defined(TARGET_MIPS64)
4809 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4810 #else
4811 tcg_gen_concat32_i64(t1, t1, t0);
4812 #endif
4813 tcg_gen_st_i64(t1, cpu_env, off);
4814 tcg_temp_free_i64(t1);
4815 tcg_temp_free_i64(t0);
4816 }
4817
4818 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4819 {
4820 TCGv_i64 t0 = tcg_temp_new_i64();
4821 TCGv_i64 t1 = tcg_temp_new_i64();
4822
4823 tcg_gen_ext_tl_i64(t0, arg);
4824 tcg_gen_ld_i64(t1, cpu_env, off);
4825 tcg_gen_concat32_i64(t1, t1, t0);
4826 tcg_gen_st_i64(t1, cpu_env, off);
4827 tcg_temp_free_i64(t1);
4828 tcg_temp_free_i64(t0);
4829 }
4830
4831 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4832 {
4833 TCGv_i64 t0 = tcg_temp_new_i64();
4834
4835 tcg_gen_ld_i64(t0, cpu_env, off);
4836 #if defined(TARGET_MIPS64)
4837 tcg_gen_shri_i64(t0, t0, 30);
4838 #else
4839 tcg_gen_shri_i64(t0, t0, 32);
4840 #endif
4841 gen_move_low32(arg, t0);
4842 tcg_temp_free_i64(t0);
4843 }
4844
4845 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4846 {
4847 TCGv_i64 t0 = tcg_temp_new_i64();
4848
4849 tcg_gen_ld_i64(t0, cpu_env, off);
4850 tcg_gen_shri_i64(t0, t0, 32 + shift);
4851 gen_move_low32(arg, t0);
4852 tcg_temp_free_i64(t0);
4853 }
4854
4855 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4856 {
4857 TCGv_i32 t0 = tcg_temp_new_i32();
4858
4859 tcg_gen_ld_i32(t0, cpu_env, off);
4860 tcg_gen_ext_i32_tl(arg, t0);
4861 tcg_temp_free_i32(t0);
4862 }
4863
4864 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4865 {
4866 tcg_gen_ld_tl(arg, cpu_env, off);
4867 tcg_gen_ext32s_tl(arg, arg);
4868 }
4869
4870 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4871 {
4872 TCGv_i32 t0 = tcg_temp_new_i32();
4873
4874 tcg_gen_trunc_tl_i32(t0, arg);
4875 tcg_gen_st_i32(t0, cpu_env, off);
4876 tcg_temp_free_i32(t0);
4877 }
4878
4879 #define CP0_CHECK(c) \
4880 do { \
4881 if (!(c)) { \
4882 goto cp0_unimplemented; \
4883 } \
4884 } while (0)
4885
4886 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4887 {
4888 const char *rn = "invalid";
4889
4890 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4891
4892 switch (reg) {
4893 case 2:
4894 switch (sel) {
4895 case 0:
4896 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4897 rn = "EntryLo0";
4898 break;
4899 default:
4900 goto cp0_unimplemented;
4901 }
4902 break;
4903 case 3:
4904 switch (sel) {
4905 case 0:
4906 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4907 rn = "EntryLo1";
4908 break;
4909 default:
4910 goto cp0_unimplemented;
4911 }
4912 break;
4913 case 17:
4914 switch (sel) {
4915 case 0:
4916 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4917 ctx->CP0_LLAddr_shift);
4918 rn = "LLAddr";
4919 break;
4920 case 1:
4921 CP0_CHECK(ctx->mrp);
4922 gen_helper_mfhc0_maar(arg, cpu_env);
4923 rn = "MAAR";
4924 break;
4925 default:
4926 goto cp0_unimplemented;
4927 }
4928 break;
4929 case 28:
4930 switch (sel) {
4931 case 0:
4932 case 2:
4933 case 4:
4934 case 6:
4935 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4936 rn = "TagLo";
4937 break;
4938 default:
4939 goto cp0_unimplemented;
4940 }
4941 break;
4942 default:
4943 goto cp0_unimplemented;
4944 }
4945 trace_mips_translate_c0("mfhc0", rn, reg, sel);
4946 return;
4947
4948 cp0_unimplemented:
4949 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4950 tcg_gen_movi_tl(arg, 0);
4951 }
4952
4953 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4954 {
4955 const char *rn = "invalid";
4956 uint64_t mask = ctx->PAMask >> 36;
4957
4958 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4959
4960 switch (reg) {
4961 case 2:
4962 switch (sel) {
4963 case 0:
4964 tcg_gen_andi_tl(arg, arg, mask);
4965 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4966 rn = "EntryLo0";
4967 break;
4968 default:
4969 goto cp0_unimplemented;
4970 }
4971 break;
4972 case 3:
4973 switch (sel) {
4974 case 0:
4975 tcg_gen_andi_tl(arg, arg, mask);
4976 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4977 rn = "EntryLo1";
4978 break;
4979 default:
4980 goto cp0_unimplemented;
4981 }
4982 break;
4983 case 17:
4984 switch (sel) {
4985 case 0:
4986 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4987 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4988 relevant for modern MIPS cores supporting MTHC0, therefore
4989 treating MTHC0 to LLAddr as NOP. */
4990 rn = "LLAddr";
4991 break;
4992 case 1:
4993 CP0_CHECK(ctx->mrp);
4994 gen_helper_mthc0_maar(cpu_env, arg);
4995 rn = "MAAR";
4996 break;
4997 default:
4998 goto cp0_unimplemented;
4999 }
5000 break;
5001 case 28:
5002 switch (sel) {
5003 case 0:
5004 case 2:
5005 case 4:
5006 case 6:
5007 tcg_gen_andi_tl(arg, arg, mask);
5008 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5009 rn = "TagLo";
5010 break;
5011 default:
5012 goto cp0_unimplemented;
5013 }
5014 break;
5015 default:
5016 goto cp0_unimplemented;
5017 }
5018 trace_mips_translate_c0("mthc0", rn, reg, sel);
5019
5020 cp0_unimplemented:
5021 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5022 }
5023
5024 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5025 {
5026 if (ctx->insn_flags & ISA_MIPS32R6) {
5027 tcg_gen_movi_tl(arg, 0);
5028 } else {
5029 tcg_gen_movi_tl(arg, ~0);
5030 }
5031 }
5032
5033 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5034 {
5035 const char *rn = "invalid";
5036
5037 if (sel != 0)
5038 check_insn(ctx, ISA_MIPS32);
5039
5040 switch (reg) {
5041 case 0:
5042 switch (sel) {
5043 case 0:
5044 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5045 rn = "Index";
5046 break;
5047 case 1:
5048 CP0_CHECK(ctx->insn_flags & ASE_MT);
5049 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5050 rn = "MVPControl";
5051 break;
5052 case 2:
5053 CP0_CHECK(ctx->insn_flags & ASE_MT);
5054 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5055 rn = "MVPConf0";
5056 break;
5057 case 3:
5058 CP0_CHECK(ctx->insn_flags & ASE_MT);
5059 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5060 rn = "MVPConf1";
5061 break;
5062 case 4:
5063 CP0_CHECK(ctx->vp);
5064 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5065 rn = "VPControl";
5066 break;
5067 default:
5068 goto cp0_unimplemented;
5069 }
5070 break;
5071 case 1:
5072 switch (sel) {
5073 case 0:
5074 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5075 gen_helper_mfc0_random(arg, cpu_env);
5076 rn = "Random";
5077 break;
5078 case 1:
5079 CP0_CHECK(ctx->insn_flags & ASE_MT);
5080 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5081 rn = "VPEControl";
5082 break;
5083 case 2:
5084 CP0_CHECK(ctx->insn_flags & ASE_MT);
5085 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5086 rn = "VPEConf0";
5087 break;
5088 case 3:
5089 CP0_CHECK(ctx->insn_flags & ASE_MT);
5090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5091 rn = "VPEConf1";
5092 break;
5093 case 4:
5094 CP0_CHECK(ctx->insn_flags & ASE_MT);
5095 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5096 rn = "YQMask";
5097 break;
5098 case 5:
5099 CP0_CHECK(ctx->insn_flags & ASE_MT);
5100 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5101 rn = "VPESchedule";
5102 break;
5103 case 6:
5104 CP0_CHECK(ctx->insn_flags & ASE_MT);
5105 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5106 rn = "VPEScheFBack";
5107 break;
5108 case 7:
5109 CP0_CHECK(ctx->insn_flags & ASE_MT);
5110 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5111 rn = "VPEOpt";
5112 break;
5113 default:
5114 goto cp0_unimplemented;
5115 }
5116 break;
5117 case 2:
5118 switch (sel) {
5119 case 0:
5120 {
5121 TCGv_i64 tmp = tcg_temp_new_i64();
5122 tcg_gen_ld_i64(tmp, cpu_env,
5123 offsetof(CPUMIPSState, CP0_EntryLo0));
5124 #if defined(TARGET_MIPS64)
5125 if (ctx->rxi) {
5126 /* Move RI/XI fields to bits 31:30 */
5127 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5128 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5129 }
5130 #endif
5131 gen_move_low32(arg, tmp);
5132 tcg_temp_free_i64(tmp);
5133 }
5134 rn = "EntryLo0";
5135 break;
5136 case 1:
5137 CP0_CHECK(ctx->insn_flags & ASE_MT);
5138 gen_helper_mfc0_tcstatus(arg, cpu_env);
5139 rn = "TCStatus";
5140 break;
5141 case 2:
5142 CP0_CHECK(ctx->insn_flags & ASE_MT);
5143 gen_helper_mfc0_tcbind(arg, cpu_env);
5144 rn = "TCBind";
5145 break;
5146 case 3:
5147 CP0_CHECK(ctx->insn_flags & ASE_MT);
5148 gen_helper_mfc0_tcrestart(arg, cpu_env);
5149 rn = "TCRestart";
5150 break;
5151 case 4:
5152 CP0_CHECK(ctx->insn_flags & ASE_MT);
5153 gen_helper_mfc0_tchalt(arg, cpu_env);
5154 rn = "TCHalt";
5155 break;
5156 case 5:
5157 CP0_CHECK(ctx->insn_flags & ASE_MT);
5158 gen_helper_mfc0_tccontext(arg, cpu_env);
5159 rn = "TCContext";
5160 break;
5161 case 6:
5162 CP0_CHECK(ctx->insn_flags & ASE_MT);
5163 gen_helper_mfc0_tcschedule(arg, cpu_env);
5164 rn = "TCSchedule";
5165 break;
5166 case 7:
5167 CP0_CHECK(ctx->insn_flags & ASE_MT);
5168 gen_helper_mfc0_tcschefback(arg, cpu_env);
5169 rn = "TCScheFBack";
5170 break;
5171 default:
5172 goto cp0_unimplemented;
5173 }
5174 break;
5175 case 3:
5176 switch (sel) {
5177 case 0:
5178 {
5179 TCGv_i64 tmp = tcg_temp_new_i64();
5180 tcg_gen_ld_i64(tmp, cpu_env,
5181 offsetof(CPUMIPSState, CP0_EntryLo1));
5182 #if defined(TARGET_MIPS64)
5183 if (ctx->rxi) {
5184 /* Move RI/XI fields to bits 31:30 */
5185 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5186 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5187 }
5188 #endif
5189 gen_move_low32(arg, tmp);
5190 tcg_temp_free_i64(tmp);
5191 }
5192 rn = "EntryLo1";
5193 break;
5194 case 1:
5195 CP0_CHECK(ctx->vp);
5196 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5197 rn = "GlobalNumber";
5198 break;
5199 default:
5200 goto cp0_unimplemented;
5201 }
5202 break;
5203 case 4:
5204 switch (sel) {
5205 case 0:
5206 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5207 tcg_gen_ext32s_tl(arg, arg);
5208 rn = "Context";
5209 break;
5210 case 1:
5211 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5212 rn = "ContextConfig";
5213 goto cp0_unimplemented;
5214 case 2:
5215 CP0_CHECK(ctx->ulri);
5216 tcg_gen_ld_tl(arg, cpu_env,
5217 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5218 tcg_gen_ext32s_tl(arg, arg);
5219 rn = "UserLocal";
5220 break;
5221 default:
5222 goto cp0_unimplemented;
5223 }
5224 break;
5225 case 5:
5226 switch (sel) {
5227 case 0:
5228 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5229 rn = "PageMask";
5230 break;
5231 case 1:
5232 check_insn(ctx, ISA_MIPS32R2);
5233 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5234 rn = "PageGrain";
5235 break;
5236 case 2:
5237 CP0_CHECK(ctx->sc);
5238 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5239 tcg_gen_ext32s_tl(arg, arg);
5240 rn = "SegCtl0";
5241 break;
5242 case 3:
5243 CP0_CHECK(ctx->sc);
5244 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5245 tcg_gen_ext32s_tl(arg, arg);
5246 rn = "SegCtl1";
5247 break;
5248 case 4:
5249 CP0_CHECK(ctx->sc);
5250 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5251 tcg_gen_ext32s_tl(arg, arg);
5252 rn = "SegCtl2";
5253 break;
5254 default:
5255 goto cp0_unimplemented;
5256 }
5257 break;
5258 case 6:
5259 switch (sel) {
5260 case 0:
5261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5262 rn = "Wired";
5263 break;
5264 case 1:
5265 check_insn(ctx, ISA_MIPS32R2);
5266 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5267 rn = "SRSConf0";
5268 break;
5269 case 2:
5270 check_insn(ctx, ISA_MIPS32R2);
5271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5272 rn = "SRSConf1";
5273 break;
5274 case 3:
5275 check_insn(ctx, ISA_MIPS32R2);
5276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5277 rn = "SRSConf2";
5278 break;
5279 case 4:
5280 check_insn(ctx, ISA_MIPS32R2);
5281 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5282 rn = "SRSConf3";
5283 break;
5284 case 5:
5285 check_insn(ctx, ISA_MIPS32R2);
5286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5287 rn = "SRSConf4";
5288 break;
5289 default:
5290 goto cp0_unimplemented;
5291 }
5292 break;
5293 case 7:
5294 switch (sel) {
5295 case 0:
5296 check_insn(ctx, ISA_MIPS32R2);
5297 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5298 rn = "HWREna";
5299 break;
5300 default:
5301 goto cp0_unimplemented;
5302 }
5303 break;
5304 case 8:
5305 switch (sel) {
5306 case 0:
5307 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5308 tcg_gen_ext32s_tl(arg, arg);
5309 rn = "BadVAddr";
5310 break;
5311 case 1:
5312 CP0_CHECK(ctx->bi);
5313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5314 rn = "BadInstr";
5315 break;
5316 case 2:
5317 CP0_CHECK(ctx->bp);
5318 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5319 rn = "BadInstrP";
5320 break;
5321 default:
5322 goto cp0_unimplemented;
5323 }
5324 break;
5325 case 9:
5326 switch (sel) {
5327 case 0:
5328 /* Mark as an IO operation because we read the time. */
5329 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5330 gen_io_start();
5331 }
5332 gen_helper_mfc0_count(arg, cpu_env);
5333 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5334 gen_io_end();
5335 }
5336 /* Break the TB to be able to take timer interrupts immediately
5337 after reading count. */
5338 ctx->bstate = BS_STOP;
5339 rn = "Count";
5340 break;
5341 /* 6,7 are implementation dependent */
5342 default:
5343 goto cp0_unimplemented;
5344 }
5345 break;
5346 case 10:
5347 switch (sel) {
5348 case 0:
5349 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5350 tcg_gen_ext32s_tl(arg, arg);
5351 rn = "EntryHi";
5352 break;
5353 default:
5354 goto cp0_unimplemented;
5355 }
5356 break;
5357 case 11:
5358 switch (sel) {
5359 case 0:
5360 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5361 rn = "Compare";
5362 break;
5363 /* 6,7 are implementation dependent */
5364 default:
5365 goto cp0_unimplemented;
5366 }
5367 break;
5368 case 12:
5369 switch (sel) {
5370 case 0:
5371 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5372 rn = "Status";
5373 break;
5374 case 1:
5375 check_insn(ctx, ISA_MIPS32R2);
5376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5377 rn = "IntCtl";
5378 break;
5379 case 2:
5380 check_insn(ctx, ISA_MIPS32R2);
5381 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5382 rn = "SRSCtl";
5383 break;
5384 case 3:
5385 check_insn(ctx, ISA_MIPS32R2);
5386 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5387 rn = "SRSMap";
5388 break;
5389 default:
5390 goto cp0_unimplemented;
5391 }
5392 break;
5393 case 13:
5394 switch (sel) {
5395 case 0:
5396 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5397 rn = "Cause";
5398 break;
5399 default:
5400 goto cp0_unimplemented;
5401 }
5402 break;
5403 case 14:
5404 switch (sel) {
5405 case 0:
5406 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5407 tcg_gen_ext32s_tl(arg, arg);
5408 rn = "EPC";
5409 break;
5410 default:
5411 goto cp0_unimplemented;
5412 }
5413 break;
5414 case 15:
5415 switch (sel) {
5416 case 0:
5417 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5418 rn = "PRid";
5419 break;
5420 case 1:
5421 check_insn(ctx, ISA_MIPS32R2);
5422 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
5423 tcg_gen_ext32s_tl(arg, arg);
5424 rn = "EBase";
5425 break;
5426 case 3:
5427 check_insn(ctx, ISA_MIPS32R2);
5428 CP0_CHECK(ctx->cmgcr);
5429 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5430 tcg_gen_ext32s_tl(arg, arg);
5431 rn = "CMGCRBase";
5432 break;
5433 default:
5434 goto cp0_unimplemented;
5435 }
5436 break;
5437 case 16:
5438 switch (sel) {
5439 case 0:
5440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5441 rn = "Config";
5442 break;
5443 case 1:
5444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5445 rn = "Config1";
5446 break;
5447 case 2:
5448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5449 rn = "Config2";
5450 break;
5451 case 3:
5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5453 rn = "Config3";
5454 break;
5455 case 4:
5456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5457 rn = "Config4";
5458 break;
5459 case 5:
5460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5461 rn = "Config5";
5462 break;
5463 /* 6,7 are implementation dependent */
5464 case 6:
5465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5466 rn = "Config6";
5467 break;
5468 case 7:
5469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5470 rn = "Config7";
5471 break;
5472 default:
5473 goto cp0_unimplemented;
5474 }
5475 break;
5476 case 17:
5477 switch (sel) {
5478 case 0:
5479 gen_helper_mfc0_lladdr(arg, cpu_env);
5480 rn = "LLAddr";
5481 break;
5482 case 1:
5483 CP0_CHECK(ctx->mrp);
5484 gen_helper_mfc0_maar(arg, cpu_env);
5485 rn = "MAAR";
5486 break;
5487 case 2:
5488 CP0_CHECK(ctx->mrp);
5489 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5490 rn = "MAARI";
5491 break;
5492 default:
5493 goto cp0_unimplemented;
5494 }
5495 break;
5496 case 18:
5497 switch (sel) {
5498 case 0 ... 7:
5499 gen_helper_1e0i(mfc0_watchlo, arg, sel);
5500 rn = "WatchLo";
5501 break;
5502 default:
5503 goto cp0_unimplemented;
5504 }
5505 break;
5506 case 19:
5507 switch (sel) {
5508 case 0 ...7:
5509 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5510 rn = "WatchHi";
5511 break;
5512 default:
5513 goto cp0_unimplemented;
5514 }
5515 break;
5516 case 20:
5517 switch (sel) {
5518 case 0:
5519 #if defined(TARGET_MIPS64)
5520 check_insn(ctx, ISA_MIPS3);
5521 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5522 tcg_gen_ext32s_tl(arg, arg);
5523 rn = "XContext";
5524 break;
5525 #endif
5526 default:
5527 goto cp0_unimplemented;
5528 }
5529 break;
5530 case 21:
5531 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5532 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5533 switch (sel) {
5534 case 0:
5535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5536 rn = "Framemask";
5537 break;
5538 default:
5539 goto cp0_unimplemented;
5540 }
5541 break;
5542 case 22:
5543 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5544 rn = "'Diagnostic"; /* implementation dependent */
5545 break;
5546 case 23:
5547 switch (sel) {
5548 case 0:
5549 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5550 rn = "Debug";
5551 break;
5552 case 1:
5553 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5554 rn = "TraceControl";
5555 goto cp0_unimplemented;
5556 case 2:
5557 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5558 rn = "TraceControl2";
5559 goto cp0_unimplemented;
5560 case 3:
5561 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5562 rn = "UserTraceData";
5563 goto cp0_unimplemented;
5564 case 4:
5565 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5566 rn = "TraceBPC";
5567 goto cp0_unimplemented;
5568 default:
5569 goto cp0_unimplemented;
5570 }
5571 break;
5572 case 24:
5573 switch (sel) {
5574 case 0:
5575 /* EJTAG support */
5576 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5577 tcg_gen_ext32s_tl(arg, arg);
5578 rn = "DEPC";
5579 break;
5580 default:
5581 goto cp0_unimplemented;
5582 }
5583 break;
5584 case 25:
5585 switch (sel) {
5586 case 0:
5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5588 rn = "Performance0";
5589 break;
5590 case 1:
5591 // gen_helper_mfc0_performance1(arg);
5592 rn = "Performance1";
5593 goto cp0_unimplemented;
5594 case 2:
5595 // gen_helper_mfc0_performance2(arg);
5596 rn = "Performance2";
5597 goto cp0_unimplemented;
5598 case 3:
5599 // gen_helper_mfc0_performance3(arg);
5600 rn = "Performance3";
5601 goto cp0_unimplemented;
5602 case 4:
5603 // gen_helper_mfc0_performance4(arg);
5604 rn = "Performance4";
5605 goto cp0_unimplemented;
5606 case 5:
5607 // gen_helper_mfc0_performance5(arg);
5608 rn = "Performance5";
5609 goto cp0_unimplemented;
5610 case 6:
5611 // gen_helper_mfc0_performance6(arg);
5612 rn = "Performance6";
5613 goto cp0_unimplemented;
5614 case 7:
5615 // gen_helper_mfc0_performance7(arg);
5616 rn = "Performance7";
5617 goto cp0_unimplemented;
5618 default:
5619 goto cp0_unimplemented;
5620 }
5621 break;
5622 case 26:
5623 switch (sel) {
5624 case 0:
5625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5626 rn = "ErrCtl";
5627 break;
5628 default:
5629 goto cp0_unimplemented;
5630 }
5631 break;
5632 case 27:
5633 switch (sel) {
5634 case 0 ... 3:
5635 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5636 rn = "CacheErr";
5637 break;
5638 default:
5639 goto cp0_unimplemented;
5640 }
5641 break;
5642 case 28:
5643 switch (sel) {
5644 case 0:
5645 case 2:
5646 case 4:
5647 case 6:
5648 {
5649 TCGv_i64 tmp = tcg_temp_new_i64();
5650 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5651 gen_move_low32(arg, tmp);
5652 tcg_temp_free_i64(tmp);
5653 }
5654 rn = "TagLo";
5655 break;
5656 case 1:
5657 case 3:
5658 case 5:
5659 case 7:
5660 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5661 rn = "DataLo";
5662 break;
5663 default:
5664 goto cp0_unimplemented;
5665 }
5666 break;
5667 case 29:
5668 switch (sel) {
5669 case 0:
5670 case 2:
5671 case 4:
5672 case 6:
5673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5674 rn = "TagHi";
5675 break;
5676 case 1:
5677 case 3:
5678 case 5:
5679 case 7:
5680 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5681 rn = "DataHi";
5682 break;
5683 default:
5684 goto cp0_unimplemented;
5685 }
5686 break;
5687 case 30:
5688 switch (sel) {
5689 case 0:
5690 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5691 tcg_gen_ext32s_tl(arg, arg);
5692 rn = "ErrorEPC";
5693 break;
5694 default:
5695 goto cp0_unimplemented;
5696 }
5697 break;
5698 case 31:
5699 switch (sel) {
5700 case 0:
5701 /* EJTAG support */
5702 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5703 rn = "DESAVE";
5704 break;
5705 case 2 ... 7:
5706 CP0_CHECK(ctx->kscrexist & (1 << sel));
5707 tcg_gen_ld_tl(arg, cpu_env,
5708 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5709 tcg_gen_ext32s_tl(arg, arg);
5710 rn = "KScratch";
5711 break;
5712 default:
5713 goto cp0_unimplemented;
5714 }
5715 break;
5716 default:
5717 goto cp0_unimplemented;
5718 }
5719 trace_mips_translate_c0("mfc0", rn, reg, sel);
5720 return;
5721
5722 cp0_unimplemented:
5723 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5724 gen_mfc0_unimplemented(ctx, arg);
5725 }
5726
5727 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5728 {
5729 const char *rn = "invalid";
5730
5731 if (sel != 0)
5732 check_insn(ctx, ISA_MIPS32);
5733
5734 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5735 gen_io_start();
5736 }
5737
5738 switch (reg) {
5739 case 0:
5740 switch (sel) {
5741 case 0:
5742 gen_helper_mtc0_index(cpu_env, arg);
5743 rn = "Index";
5744 break;
5745 case 1:
5746 CP0_CHECK(ctx->insn_flags & ASE_MT);
5747 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5748 rn = "MVPControl";
5749 break;
5750 case 2:
5751 CP0_CHECK(ctx->insn_flags & ASE_MT);
5752 /* ignored */
5753 rn = "MVPConf0";
5754 break;
5755 case 3:
5756 CP0_CHECK(ctx->insn_flags & ASE_MT);
5757 /* ignored */
5758 rn = "MVPConf1";
5759 break;
5760 case 4:
5761 CP0_CHECK(ctx->vp);
5762 /* ignored */
5763 rn = "VPControl";
5764 break;
5765 default:
5766 goto cp0_unimplemented;
5767 }
5768 break;
5769 case 1:
5770 switch (sel) {
5771 case 0:
5772 /* ignored */
5773 rn = "Random";
5774 break;
5775 case 1:
5776 CP0_CHECK(ctx->insn_flags & ASE_MT);
5777 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5778 rn = "VPEControl";
5779 break;
5780 case 2:
5781 CP0_CHECK(ctx->insn_flags & ASE_MT);
5782 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5783 rn = "VPEConf0";
5784 break;
5785 case 3:
5786 CP0_CHECK(ctx->insn_flags & ASE_MT);
5787 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5788 rn = "VPEConf1";
5789 break;
5790 case 4:
5791 CP0_CHECK(ctx->insn_flags & ASE_MT);
5792 gen_helper_mtc0_yqmask(cpu_env, arg);
5793 rn = "YQMask";
5794 break;
5795 case 5:
5796 CP0_CHECK(ctx->insn_flags & ASE_MT);
5797 tcg_gen_st_tl(arg, cpu_env,
5798 offsetof(CPUMIPSState, CP0_VPESchedule));
5799 rn = "VPESchedule";
5800 break;
5801 case 6:
5802 CP0_CHECK(ctx->insn_flags & ASE_MT);
5803 tcg_gen_st_tl(arg, cpu_env,
5804 offsetof(CPUMIPSState, CP0_VPEScheFBack));
5805 rn = "VPEScheFBack";
5806 break;
5807 case 7:
5808 CP0_CHECK(ctx->insn_flags & ASE_MT);
5809 gen_helper_mtc0_vpeopt(cpu_env, arg);
5810 rn = "VPEOpt";
5811 break;
5812 default:
5813 goto cp0_unimplemented;
5814 }
5815 break;
5816 case 2:
5817 switch (sel) {
5818 case 0:
5819 gen_helper_mtc0_entrylo0(cpu_env, arg);
5820 rn = "EntryLo0";
5821 break;
5822 case 1:
5823 CP0_CHECK(ctx->insn_flags & ASE_MT);
5824 gen_helper_mtc0_tcstatus(cpu_env, arg);
5825 rn = "TCStatus";
5826 break;
5827 case 2:
5828 CP0_CHECK(ctx->insn_flags & ASE_MT);
5829 gen_helper_mtc0_tcbind(cpu_env, arg);
5830 rn = "TCBind";
5831 break;
5832 case 3:
5833 CP0_CHECK(ctx->insn_flags & ASE_MT);
5834 gen_helper_mtc0_tcrestart(cpu_env, arg);
5835 rn = "TCRestart";
5836 break;
5837 case 4:
5838 CP0_CHECK(ctx->insn_flags & ASE_MT);
5839 gen_helper_mtc0_tchalt(cpu_env, arg);
5840 rn = "TCHalt";
5841 break;
5842 case 5:
5843 CP0_CHECK(ctx->insn_flags & ASE_MT);
5844 gen_helper_mtc0_tccontext(cpu_env, arg);
5845 rn = "TCContext";
5846 break;
5847 case 6:
5848 CP0_CHECK(ctx->insn_flags & ASE_MT);
5849 gen_helper_mtc0_tcschedule(cpu_env, arg);
5850 rn = "TCSchedule";
5851 break;
5852 case 7:
5853 CP0_CHECK(ctx->insn_flags & ASE_MT);
5854 gen_helper_mtc0_tcschefback(cpu_env, arg);
5855 rn = "TCScheFBack";
5856 break;
5857 default:
5858 goto cp0_unimplemented;
5859 }
5860 break;
5861 case 3:
5862 switch (sel) {
5863 case 0:
5864 gen_helper_mtc0_entrylo1(cpu_env, arg);
5865 rn = "EntryLo1";
5866 break;
5867 case 1:
5868 CP0_CHECK(ctx->vp);
5869 /* ignored */
5870 rn = "GlobalNumber";
5871 break;
5872 default:
5873 goto cp0_unimplemented;
5874 }
5875 break;
5876 case 4:
5877 switch (sel) {
5878 case 0:
5879 gen_helper_mtc0_context(cpu_env, arg);
5880 rn = "Context";
5881 break;
5882 case 1:
5883 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5884 rn = "ContextConfig";
5885 goto cp0_unimplemented;
5886 case 2:
5887 CP0_CHECK(ctx->ulri);
5888 tcg_gen_st_tl(arg, cpu_env,
5889 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5890 rn = "UserLocal";
5891 break;
5892 default:
5893 goto cp0_unimplemented;
5894 }
5895 break;
5896 case 5:
5897 switch (sel) {
5898 case 0:
5899 gen_helper_mtc0_pagemask(cpu_env, arg);
5900 rn = "PageMask";
5901 break;
5902 case 1:
5903 check_insn(ctx, ISA_MIPS32R2);
5904 gen_helper_mtc0_pagegrain(cpu_env, arg);
5905 rn = "PageGrain";
5906 ctx->bstate = BS_STOP;
5907 break;
5908 case 2:
5909 CP0_CHECK(ctx->sc);
5910 gen_helper_mtc0_segctl0(cpu_env, arg);
5911 rn = "SegCtl0";
5912 break;
5913 case 3:
5914 CP0_CHECK(ctx->sc);
5915 gen_helper_mtc0_segctl1(cpu_env, arg);
5916 rn = "SegCtl1";
5917 break;
5918 case 4:
5919 CP0_CHECK(ctx->sc);
5920 gen_helper_mtc0_segctl2(cpu_env, arg);
5921 rn = "SegCtl2";
5922 break;
5923 default:
5924 goto cp0_unimplemented;
5925 }
5926 break;
5927 case 6:
5928 switch (sel) {
5929 case 0:
5930 gen_helper_mtc0_wired(cpu_env, arg);
5931 rn = "Wired";
5932 break;
5933 case 1:
5934 check_insn(ctx, ISA_MIPS32R2);
5935 gen_helper_mtc0_srsconf0(cpu_env, arg);
5936 rn = "SRSConf0";
5937 break;
5938 case 2:
5939 check_insn(ctx, ISA_MIPS32R2);
5940 gen_helper_mtc0_srsconf1(cpu_env, arg);
5941 rn = "SRSConf1";
5942 break;
5943 case 3:
5944 check_insn(ctx, ISA_MIPS32R2);
5945 gen_helper_mtc0_srsconf2(cpu_env, arg);
5946 rn = "SRSConf2";
5947 break;
5948 case 4:
5949 check_insn(ctx, ISA_MIPS32R2);
5950 gen_helper_mtc0_srsconf3(cpu_env, arg);
5951 rn = "SRSConf3";
5952 break;
5953 case 5:
5954 check_insn(ctx, ISA_MIPS32R2);
5955 gen_helper_mtc0_srsconf4(cpu_env, arg);
5956 rn = "SRSConf4";
5957 break;
5958 default:
5959 goto cp0_unimplemented;
5960 }
5961 break;
5962 case 7:
5963 switch (sel) {
5964 case 0:
5965 check_insn(ctx, ISA_MIPS32R2);
5966 gen_helper_mtc0_hwrena(cpu_env, arg);
5967 ctx->bstate = BS_STOP;
5968 rn = "HWREna";
5969 break;
5970 default:
5971 goto cp0_unimplemented;
5972 }
5973 break;
5974 case 8:
5975 switch (sel) {
5976 case 0:
5977 /* ignored */
5978 rn = "BadVAddr";
5979 break;
5980 case 1:
5981 /* ignored */
5982 rn = "BadInstr";
5983 break;
5984 case 2:
5985 /* ignored */
5986 rn = "BadInstrP";
5987 break;
5988 default:
5989 goto cp0_unimplemented;
5990 }
5991 break;
5992 case 9:
5993 switch (sel) {
5994 case 0:
5995 gen_helper_mtc0_count(cpu_env, arg);
5996 rn = "Count";
5997 break;
5998 /* 6,7 are implementation dependent */
5999 default:
6000 goto cp0_unimplemented;
6001 }
6002 break;
6003 case 10:
6004 switch (sel) {
6005 case 0:
6006 gen_helper_mtc0_entryhi(cpu_env, arg);
6007 rn = "EntryHi";
6008 break;
6009 default:
6010 goto cp0_unimplemented;
6011 }
6012 break;
6013 case 11:
6014 switch (sel) {
6015 case 0:
6016 gen_helper_mtc0_compare(cpu_env, arg);
6017 rn = "Compare";
6018 break;
6019 /* 6,7 are implementation dependent */
6020 default:
6021 goto cp0_unimplemented;
6022 }
6023 break;
6024 case 12:
6025 switch (sel) {
6026 case 0:
6027 save_cpu_state(ctx, 1);
6028 gen_helper_mtc0_status(cpu_env, arg);
6029 /* BS_STOP isn't good enough here, hflags may have changed. */
6030 gen_save_pc(ctx->pc + 4);
6031 ctx->bstate = BS_EXCP;
6032 rn = "Status";
6033 break;
6034 case 1:
6035 check_insn(ctx, ISA_MIPS32R2);
6036 gen_helper_mtc0_intctl(cpu_env, arg);
6037 /* Stop translation as we may have switched the execution mode */
6038 ctx->bstate = BS_STOP;
6039 rn = "IntCtl";
6040 break;
6041 case 2:
6042 check_insn(ctx, ISA_MIPS32R2);
6043 gen_helper_mtc0_srsctl(cpu_env, arg);
6044 /* Stop translation as we may have switched the execution mode */
6045 ctx->bstate = BS_STOP;
6046 rn = "SRSCtl";
6047 break;
6048 case 3:
6049 check_insn(ctx, ISA_MIPS32R2);
6050 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6051 /* Stop translation as we may have switched the execution mode */
6052 ctx->bstate = BS_STOP;
6053 rn = "SRSMap";
6054 break;
6055 default:
6056 goto cp0_unimplemented;
6057 }
6058 break;
6059 case 13:
6060 switch (sel) {
6061 case 0:
6062 save_cpu_state(ctx, 1);
6063 gen_helper_mtc0_cause(cpu_env, arg);
6064 rn = "Cause";
6065 break;
6066 default:
6067 goto cp0_unimplemented;
6068 }
6069 break;
6070 case 14:
6071 switch (sel) {
6072 case 0:
6073 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6074 rn = "EPC";
6075 break;
6076 default:
6077 goto cp0_unimplemented;
6078 }
6079 break;
6080 case 15:
6081 switch (sel) {
6082 case 0:
6083 /* ignored */
6084 rn = "PRid";
6085 break;
6086 case 1:
6087 check_insn(ctx, ISA_MIPS32R2);
6088 gen_helper_mtc0_ebase(cpu_env, arg);
6089 rn = "EBase";
6090 break;
6091 default:
6092 goto cp0_unimplemented;
6093 }
6094 break;
6095 case 16:
6096 switch (sel) {
6097 case 0:
6098 gen_helper_mtc0_config0(cpu_env, arg);
6099 rn = "Config";
6100 /* Stop translation as we may have switched the execution mode */
6101 ctx->bstate = BS_STOP;
6102 break;
6103 case 1:
6104 /* ignored, read only */
6105 rn = "Config1";
6106 break;
6107 case 2:
6108 gen_helper_mtc0_config2(cpu_env, arg);
6109 rn = "Config2";
6110 /* Stop translation as we may have switched the execution mode */
6111 ctx->bstate = BS_STOP;
6112 break;
6113 case 3:
6114 gen_helper_mtc0_config3(cpu_env, arg);
6115 rn = "Config3";
6116 /* Stop translation as we may have switched the execution mode */
6117 ctx->bstate = BS_STOP;
6118 break;
6119 case 4:
6120 gen_helper_mtc0_config4(cpu_env, arg);
6121 rn = "Config4";
6122 ctx->bstate = BS_STOP;
6123 break;
6124 case 5:
6125 gen_helper_mtc0_config5(cpu_env, arg);
6126 rn = "Config5";
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx->bstate = BS_STOP;
6129 break;
6130 /* 6,7 are implementation dependent */
6131 case 6:
6132 /* ignored */
6133 rn = "Config6";
6134 break;
6135 case 7:
6136 /* ignored */
6137 rn = "Config7";
6138 break;
6139 default:
6140 rn = "Invalid config selector";
6141 goto cp0_unimplemented;
6142 }
6143 break;
6144 case 17:
6145 switch (sel) {
6146 case 0:
6147 gen_helper_mtc0_lladdr(cpu_env, arg);
6148 rn = "LLAddr";
6149 break;
6150 case 1:
6151 CP0_CHECK(ctx->mrp);
6152 gen_helper_mtc0_maar(cpu_env, arg);
6153 rn = "MAAR";
6154 break;
6155 case 2:
6156 CP0_CHECK(ctx->mrp);
6157 gen_helper_mtc0_maari(cpu_env, arg);
6158 rn = "MAARI";
6159 break;
6160 default:
6161 goto cp0_unimplemented;
6162 }
6163 break;
6164 case 18:
6165 switch (sel) {
6166 case 0 ... 7:
6167 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6168 rn = "WatchLo";
6169 break;
6170 default:
6171 goto cp0_unimplemented;
6172 }
6173 break;
6174 case 19:
6175 switch (sel) {
6176 case 0 ... 7:
6177 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6178 rn = "WatchHi";
6179 break;
6180 default:
6181 goto cp0_unimplemented;
6182 }
6183 break;
6184 case 20:
6185 switch (sel) {
6186 case 0:
6187 #if defined(TARGET_MIPS64)
6188 check_insn(ctx, ISA_MIPS3);
6189 gen_helper_mtc0_xcontext(cpu_env, arg);
6190 rn = "XContext";
6191 break;
6192 #endif
6193 default:
6194 goto cp0_unimplemented;
6195 }
6196 break;
6197 case 21:
6198 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6199 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6200 switch (sel) {
6201 case 0:
6202 gen_helper_mtc0_framemask(cpu_env, arg);
6203 rn = "Framemask";
6204 break;
6205 default:
6206 goto cp0_unimplemented;
6207 }
6208 break;
6209 case 22:
6210 /* ignored */
6211 rn = "Diagnostic"; /* implementation dependent */
6212 break;
6213 case 23:
6214 switch (sel) {
6215 case 0:
6216 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6217 /* BS_STOP isn't good enough here, hflags may have changed. */
6218 gen_save_pc(ctx->pc + 4);
6219 ctx->bstate = BS_EXCP;
6220 rn = "Debug";
6221 break;
6222 case 1:
6223 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6224 rn = "TraceControl";
6225 /* Stop translation as we may have switched the execution mode */
6226 ctx->bstate = BS_STOP;
6227 goto cp0_unimplemented;
6228 case 2:
6229 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6230 rn = "TraceControl2";
6231 /* Stop translation as we may have switched the execution mode */
6232 ctx->bstate = BS_STOP;
6233 goto cp0_unimplemented;
6234 case 3:
6235 /* Stop translation as we may have switched the execution mode */
6236 ctx->bstate = BS_STOP;
6237 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6238 rn = "UserTraceData";
6239 /* Stop translation as we may have switched the execution mode */
6240 ctx->bstate = BS_STOP;
6241 goto cp0_unimplemented;
6242 case 4:
6243 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6244 /* Stop translation as we may have switched the execution mode */
6245 ctx->bstate = BS_STOP;
6246 rn = "TraceBPC";
6247 goto cp0_unimplemented;
6248 default:
6249 goto cp0_unimplemented;
6250 }
6251 break;
6252 case 24:
6253 switch (sel) {
6254 case 0:
6255 /* EJTAG support */
6256 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6257 rn = "DEPC";
6258 break;
6259 default:
6260 goto cp0_unimplemented;
6261 }
6262 break;
6263 case 25:
6264 switch (sel) {
6265 case 0:
6266 gen_helper_mtc0_performance0(cpu_env, arg);
6267 rn = "Performance0";
6268 break;
6269 case 1:
6270 // gen_helper_mtc0_performance1(arg);
6271 rn = "Performance1";
6272 goto cp0_unimplemented;
6273 case 2:
6274 // gen_helper_mtc0_performance2(arg);
6275 rn = "Performance2";
6276 goto cp0_unimplemented;
6277 case 3:
6278 // gen_helper_mtc0_performance3(arg);
6279 rn = "Performance3";
6280 goto cp0_unimplemented;
6281 case 4:
6282 // gen_helper_mtc0_performance4(arg);
6283 rn = "Performance4";
6284 goto cp0_unimplemented;
6285 case 5:
6286 // gen_helper_mtc0_performance5(arg);
6287 rn = "Performance5";
6288 goto cp0_unimplemented;
6289 case 6:
6290 // gen_helper_mtc0_performance6(arg);
6291 rn = "Performance6";
6292 goto cp0_unimplemented;
6293 case 7:
6294 // gen_helper_mtc0_performance7(arg);
6295 rn = "Performance7";
6296 goto cp0_unimplemented;
6297 default:
6298 goto cp0_unimplemented;
6299 }
6300 break;
6301 case 26:
6302 switch (sel) {
6303 case 0:
6304 gen_helper_mtc0_errctl(cpu_env, arg);
6305 ctx->bstate = BS_STOP;
6306 rn = "ErrCtl";
6307 break;
6308 default:
6309 goto cp0_unimplemented;
6310 }
6311 break;
6312 case 27:
6313 switch (sel) {
6314 case 0 ... 3:
6315 /* ignored */
6316 rn = "CacheErr";
6317 break;
6318 default:
6319 goto cp0_unimplemented;
6320 }
6321 break;
6322 case 28:
6323 switch (sel) {
6324 case 0:
6325 case 2:
6326 case 4:
6327 case 6:
6328 gen_helper_mtc0_taglo(cpu_env, arg);
6329 rn = "TagLo";
6330 break;
6331 case 1:
6332 case 3:
6333 case 5:
6334 case 7:
6335 gen_helper_mtc0_datalo(cpu_env, arg);
6336 rn = "DataLo";
6337 break;
6338 default:
6339 goto cp0_unimplemented;
6340 }
6341 break;
6342 case 29:
6343 switch (sel) {
6344 case 0:
6345 case 2:
6346 case 4:
6347 case 6:
6348 gen_helper_mtc0_taghi(cpu_env, arg);
6349 rn = "TagHi";
6350 break;
6351 case 1:
6352 case 3:
6353 case 5:
6354 case 7:
6355 gen_helper_mtc0_datahi(cpu_env, arg);
6356 rn = "DataHi";
6357 break;
6358 default:
6359 rn = "invalid sel";
6360 goto cp0_unimplemented;
6361 }
6362 break;
6363 case 30:
6364 switch (sel) {
6365 case 0:
6366 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6367 rn = "ErrorEPC";
6368 break;
6369 default:
6370 goto cp0_unimplemented;
6371 }
6372 break;
6373 case 31:
6374 switch (sel) {
6375 case 0:
6376 /* EJTAG support */
6377 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6378 rn = "DESAVE";
6379 break;
6380 case 2 ... 7:
6381 CP0_CHECK(ctx->kscrexist & (1 << sel));
6382 tcg_gen_st_tl(arg, cpu_env,
6383 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6384 rn = "KScratch";
6385 break;
6386 default:
6387 goto cp0_unimplemented;
6388 }
6389 break;
6390 default:
6391 goto cp0_unimplemented;
6392 }
6393 trace_mips_translate_c0("mtc0", rn, reg, sel);
6394
6395 /* For simplicity assume that all writes can cause interrupts. */
6396 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6397 gen_io_end();
6398 ctx->bstate = BS_STOP;
6399 }
6400 return;
6401
6402 cp0_unimplemented:
6403 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6404 }
6405
6406 #if defined(TARGET_MIPS64)
6407 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6408 {
6409 const char *rn = "invalid";
6410
6411 if (sel != 0)
6412 check_insn(ctx, ISA_MIPS64);
6413
6414 switch (reg) {
6415 case 0:
6416 switch (sel) {
6417 case 0:
6418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6419 rn = "Index";
6420 break;
6421 case 1:
6422 CP0_CHECK(ctx->insn_flags & ASE_MT);
6423 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6424 rn = "MVPControl";
6425 break;
6426 case 2:
6427 CP0_CHECK(ctx->insn_flags & ASE_MT);
6428 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6429 rn = "MVPConf0";
6430 break;
6431 case 3:
6432 CP0_CHECK(ctx->insn_flags & ASE_MT);
6433 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6434 rn = "MVPConf1";
6435 break;
6436 case 4:
6437 CP0_CHECK(ctx->vp);
6438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6439 rn = "VPControl";
6440 break;
6441 default:
6442 goto cp0_unimplemented;
6443 }
6444 break;
6445 case 1:
6446 switch (sel) {
6447 case 0:
6448 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6449 gen_helper_mfc0_random(arg, cpu_env);
6450 rn = "Random";
6451 break;
6452 case 1:
6453 CP0_CHECK(ctx->insn_flags & ASE_MT);
6454 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6455 rn = "VPEControl";
6456 break;
6457 case 2:
6458 CP0_CHECK(ctx->insn_flags & ASE_MT);
6459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6460 rn = "VPEConf0";
6461 break;
6462 case 3:
6463 CP0_CHECK(ctx->insn_flags & ASE_MT);
6464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6465 rn = "VPEConf1";
6466 break;
6467 case 4:
6468 CP0_CHECK(ctx->insn_flags & ASE_MT);
6469 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6470 rn = "YQMask";
6471 break;
6472 case 5:
6473 CP0_CHECK(ctx->insn_flags & ASE_MT);
6474 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6475 rn = "VPESchedule";
6476 break;
6477 case 6:
6478 CP0_CHECK(ctx->insn_flags & ASE_MT);
6479 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6480 rn = "VPEScheFBack";
6481 break;
6482 case 7:
6483 CP0_CHECK(ctx->insn_flags & ASE_MT);
6484 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6485 rn = "VPEOpt";
6486 break;
6487 default:
6488 goto cp0_unimplemented;
6489 }
6490 break;
6491 case 2:
6492 switch (sel) {
6493 case 0:
6494 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6495 rn = "EntryLo0";
6496 break;
6497 case 1:
6498 CP0_CHECK(ctx->insn_flags & ASE_MT);
6499 gen_helper_mfc0_tcstatus(arg, cpu_env);
6500 rn = "TCStatus";
6501 break;
6502 case 2:
6503 CP0_CHECK(ctx->insn_flags & ASE_MT);
6504 gen_helper_mfc0_tcbind(arg, cpu_env);
6505 rn = "TCBind";
6506 break;
6507 case 3:
6508 CP0_CHECK(ctx->insn_flags & ASE_MT);
6509 gen_helper_dmfc0_tcrestart(arg, cpu_env);
6510 rn = "TCRestart";
6511 break;
6512 case 4:
6513 CP0_CHECK(ctx->insn_flags & ASE_MT);
6514 gen_helper_dmfc0_tchalt(arg, cpu_env);
6515 rn = "TCHalt";
6516 break;
6517 case 5:
6518 CP0_CHECK(ctx->insn_flags & ASE_MT);
6519 gen_helper_dmfc0_tccontext(arg, cpu_env);
6520 rn = "TCContext";
6521 break;
6522 case 6:
6523 CP0_CHECK(ctx->insn_flags & ASE_MT);
6524 gen_helper_dmfc0_tcschedule(arg, cpu_env);
6525 rn = "TCSchedule";
6526 break;
6527 case 7:
6528 CP0_CHECK(ctx->insn_flags & ASE_MT);
6529 gen_helper_dmfc0_tcschefback(arg, cpu_env);
6530 rn = "TCScheFBack";
6531 break;
6532 default:
6533 goto cp0_unimplemented;
6534 }
6535 break;
6536 case 3:
6537 switch (sel) {
6538 case 0:
6539 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6540 rn = "EntryLo1";
6541 break;
6542 case 1:
6543 CP0_CHECK(ctx->vp);
6544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6545 rn = "GlobalNumber";
6546 break;
6547 default:
6548 goto cp0_unimplemented;
6549 }
6550 break;
6551 case 4:
6552 switch (sel) {
6553 case 0:
6554 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6555 rn = "Context";
6556 break;
6557 case 1:
6558 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6559 rn = "ContextConfig";
6560 goto cp0_unimplemented;
6561 case 2:
6562 CP0_CHECK(ctx->ulri);
6563 tcg_gen_ld_tl(arg, cpu_env,
6564 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6565 rn = "UserLocal";
6566 break;
6567 default:
6568 goto cp0_unimplemented;
6569 }
6570 break;
6571 case 5:
6572 switch (sel) {
6573 case 0:
6574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6575 rn = "PageMask";
6576 break;
6577 case 1:
6578 check_insn(ctx, ISA_MIPS32R2);
6579 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6580 rn = "PageGrain";
6581 break;
6582 case 2:
6583 CP0_CHECK(ctx->sc);
6584 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6585 rn = "SegCtl0";
6586 break;
6587 case 3:
6588 CP0_CHECK(ctx->sc);
6589 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6590 rn = "SegCtl1";
6591 break;
6592 case 4:
6593 CP0_CHECK(ctx->sc);
6594 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6595 rn = "SegCtl2";
6596 break;
6597 default:
6598 goto cp0_unimplemented;
6599 }
6600 break;
6601 case 6:
6602 switch (sel) {
6603 case 0:
6604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6605 rn = "Wired";
6606 break;
6607 case 1:
6608 check_insn(ctx, ISA_MIPS32R2);
6609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6610 rn = "SRSConf0";
6611 break;
6612 case 2:
6613 check_insn(ctx, ISA_MIPS32R2);
6614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6615 rn = "SRSConf1";
6616 break;
6617 case 3:
6618 check_insn(ctx, ISA_MIPS32R2);
6619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6620 rn = "SRSConf2";
6621 break;
6622 case 4:
6623 check_insn(ctx, ISA_MIPS32R2);
6624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6625 rn = "SRSConf3";
6626 break;
6627 case 5:
6628 check_insn(ctx, ISA_MIPS32R2);
6629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6630 rn = "SRSConf4";
6631 break;
6632 default:
6633 goto cp0_unimplemented;
6634 }
6635 break;
6636 case 7:
6637 switch (sel) {
6638 case 0:
6639 check_insn(ctx, ISA_MIPS32R2);
6640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6641 rn = "HWREna";
6642 break;
6643 default:
6644 goto cp0_unimplemented;
6645 }
6646 break;
6647 case 8:
6648 switch (sel) {
6649 case 0:
6650 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6651 rn = "BadVAddr";
6652 break;
6653 case 1:
6654 CP0_CHECK(ctx->bi);
6655 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6656 rn = "BadInstr";
6657 break;
6658 case 2:
6659 CP0_CHECK(ctx->bp);
6660 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6661 rn = "BadInstrP";
6662 break;
6663 default:
6664 goto cp0_unimplemented;
6665 }
6666 break;
6667 case 9:
6668 switch (sel) {
6669 case 0:
6670 /* Mark as an IO operation because we read the time. */
6671 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6672 gen_io_start();
6673 }
6674 gen_helper_mfc0_count(arg, cpu_env);
6675 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6676 gen_io_end();
6677 }
6678 /* Break the TB to be able to take timer interrupts immediately
6679 after reading count. */
6680 ctx->bstate = BS_STOP;
6681 rn = "Count";
6682 break;
6683 /* 6,7 are implementation dependent */
6684 default:
6685 goto cp0_unimplemented;
6686 }
6687 break;
6688 case 10:
6689 switch (sel) {
6690 case 0:
6691 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6692 rn = "EntryHi";
6693 break;
6694 default:
6695 goto cp0_unimplemented;
6696 }
6697 break;
6698 case 11:
6699 switch (sel) {
6700 case 0:
6701 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6702 rn = "Compare";
6703 break;
6704 /* 6,7 are implementation dependent */
6705 default:
6706 goto cp0_unimplemented;
6707 }
6708 break;
6709 case 12:
6710 switch (sel) {
6711 case 0:
6712 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6713 rn = "Status";
6714 break;
6715 case 1:
6716 check_insn(ctx, ISA_MIPS32R2);
6717 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6718 rn = "IntCtl";
6719 break;
6720 case 2:
6721 check_insn(ctx, ISA_MIPS32R2);
6722 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6723 rn = "SRSCtl";
6724 break;
6725 case 3:
6726 check_insn(ctx, ISA_MIPS32R2);
6727 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6728 rn = "SRSMap";
6729 break;
6730 default:
6731 goto cp0_unimplemented;
6732 }
6733 break;
6734 case 13:
6735 switch (sel) {
6736 case 0:
6737 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6738 rn = "Cause";
6739 break;
6740 default:
6741 goto cp0_unimplemented;
6742 }
6743 break;
6744 case 14:
6745 switch (sel) {
6746 case 0:
6747 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6748 rn = "EPC";
6749 break;
6750 default:
6751 goto cp0_unimplemented;
6752 }
6753 break;
6754 case 15:
6755 switch (sel) {
6756 case 0:
6757 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6758 rn = "PRid";
6759 break;
6760 case 1:
6761 check_insn(ctx, ISA_MIPS32R2);
6762 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6763 rn = "EBase";
6764 break;
6765 case 3:
6766 check_insn(ctx, ISA_MIPS32R2);
6767 CP0_CHECK(ctx->cmgcr);
6768 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6769 rn = "CMGCRBase";
6770 break;
6771 default:
6772 goto cp0_unimplemented;
6773 }
6774 break;
6775 case 16:
6776 switch (sel) {
6777 case 0:
6778 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6779 rn = "Config";
6780 break;
6781 case 1:
6782 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6783 rn = "Config1";
6784 break;
6785 case 2:
6786 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6787 rn = "Config2";
6788 break;
6789 case 3:
6790 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6791 rn = "Config3";
6792 break;
6793 case 4:
6794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6795 rn = "Config4";
6796 break;
6797 case 5:
6798 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6799 rn = "Config5";
6800 break;
6801 /* 6,7 are implementation dependent */
6802 case 6:
6803 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6804 rn = "Config6";
6805 break;
6806 case 7:
6807 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6808 rn = "Config7";
6809 break;
6810 default:
6811 goto cp0_unimplemented;
6812 }
6813 break;
6814 case 17:
6815 switch (sel) {
6816 case 0:
6817 gen_helper_dmfc0_lladdr(arg, cpu_env);
6818 rn = "LLAddr";
6819 break;
6820 case 1:
6821 CP0_CHECK(ctx->mrp);
6822 gen_helper_dmfc0_maar(arg, cpu_env);
6823 rn = "MAAR";
6824 break;
6825 case 2:
6826 CP0_CHECK(ctx->mrp);
6827 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6828 rn = "MAARI";
6829 break;
6830 default:
6831 goto cp0_unimplemented;
6832 }
6833 break;
6834 case 18:
6835 switch (sel) {
6836 case 0 ... 7:
6837 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6838 rn = "WatchLo";
6839 break;
6840 default:
6841 goto cp0_unimplemented;
6842 }
6843 break;
6844 case 19:
6845 switch (sel) {
6846 case 0 ... 7:
6847 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6848 rn = "WatchHi";
6849 break;
6850 default:
6851 goto cp0_unimplemented;
6852 }
6853 break;
6854 case 20:
6855 switch (sel) {
6856 case 0:
6857 check_insn(ctx, ISA_MIPS3);
6858 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6859 rn = "XContext";
6860 break;
6861 default:
6862 goto cp0_unimplemented;
6863 }
6864 break;
6865 case 21:
6866 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6867 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6868 switch (sel) {
6869 case 0:
6870 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6871 rn = "Framemask";
6872 break;
6873 default:
6874 goto cp0_unimplemented;
6875 }
6876 break;
6877 case 22:
6878 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6879 rn = "'Diagnostic"; /* implementation dependent */
6880 break;
6881 case 23:
6882 switch (sel) {
6883 case 0:
6884 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6885 rn = "Debug";
6886 break;
6887 case 1:
6888 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6889 rn = "TraceControl";
6890 goto cp0_unimplemented;
6891 case 2:
6892 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6893 rn = "TraceControl2";
6894 goto cp0_unimplemented;
6895 case 3:
6896 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6897 rn = "UserTraceData";
6898 goto cp0_unimplemented;
6899 case 4:
6900 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6901 rn = "TraceBPC";
6902 goto cp0_unimplemented;
6903 default:
6904 goto cp0_unimplemented;
6905 }
6906 break;
6907 case 24:
6908 switch (sel) {
6909 case 0:
6910 /* EJTAG support */
6911 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6912 rn = "DEPC";
6913 break;
6914 default:
6915 goto cp0_unimplemented;
6916 }
6917 break;
6918 case 25:
6919 switch (sel) {
6920 case 0:
6921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6922 rn = "Performance0";
6923 break;
6924 case 1:
6925 // gen_helper_dmfc0_performance1(arg);
6926 rn = "Performance1";
6927 goto cp0_unimplemented;
6928 case 2:
6929 // gen_helper_dmfc0_performance2(arg);
6930 rn = "Performance2";
6931 goto cp0_unimplemented;
6932 case 3:
6933 // gen_helper_dmfc0_performance3(arg);
6934 rn = "Performance3";
6935 goto cp0_unimplemented;
6936 case 4:
6937 // gen_helper_dmfc0_performance4(arg);
6938 rn = "Performance4";
6939 goto cp0_unimplemented;
6940 case 5:
6941 // gen_helper_dmfc0_performance5(arg);
6942 rn = "Performance5";
6943 goto cp0_unimplemented;
6944 case 6:
6945 // gen_helper_dmfc0_performance6(arg);
6946 rn = "Performance6";
6947 goto cp0_unimplemented;
6948 case 7:
6949 // gen_helper_dmfc0_performance7(arg);
6950 rn = "Performance7";
6951 goto cp0_unimplemented;
6952 default:
6953 goto cp0_unimplemented;
6954 }
6955 break;
6956 case 26:
6957 switch (sel) {
6958 case 0:
6959 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6960 rn = "ErrCtl";
6961 break;
6962 default:
6963 goto cp0_unimplemented;
6964 }
6965 break;
6966 case 27:
6967 switch (sel) {
6968 /* ignored */
6969 case 0 ... 3:
6970 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6971 rn = "CacheErr";
6972 break;
6973 default:
6974 goto cp0_unimplemented;
6975 }
6976 break;
6977 case 28:
6978 switch (sel) {
6979 case 0:
6980 case 2:
6981 case 4:
6982 case 6:
6983 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6984 rn = "TagLo";
6985 break;
6986 case 1:
6987 case 3:
6988 case 5:
6989 case 7:
6990 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6991 rn = "DataLo";
6992 break;
6993 default:
6994 goto cp0_unimplemented;
6995 }
6996 break;
6997 case 29:
6998 switch (sel) {
6999 case 0:
7000 case 2:
7001 case 4:
7002 case 6:
7003 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7004 rn = "TagHi";
7005 break;
7006 case 1:
7007 case 3:
7008 case 5:
7009 case 7:
7010 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7011 rn = "DataHi";
7012 break;
7013 default:
7014 goto cp0_unimplemented;
7015 }
7016 break;
7017 case 30:
7018 switch (sel) {
7019 case 0:
7020 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7021 rn = "ErrorEPC";
7022 break;
7023 default:
7024 goto cp0_unimplemented;
7025 }
7026 break;
7027 case 31:
7028 switch (sel) {
7029 case 0:
7030 /* EJTAG support */
7031 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7032 rn = "DESAVE";
7033 break;
7034 case 2 ... 7:
7035 CP0_CHECK(ctx->kscrexist & (1 << sel));
7036 tcg_gen_ld_tl(arg, cpu_env,
7037 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7038 rn = "KScratch";
7039 break;
7040 default:
7041 goto cp0_unimplemented;
7042 }
7043 break;
7044 default:
7045 goto cp0_unimplemented;
7046 }
7047 trace_mips_translate_c0("dmfc0", rn, reg, sel);
7048 return;
7049
7050 cp0_unimplemented:
7051 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
7052 gen_mfc0_unimplemented(ctx, arg);
7053 }
7054
7055 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7056 {
7057 const char *rn = "invalid";
7058
7059 if (sel != 0)
7060 check_insn(ctx, ISA_MIPS64);
7061
7062 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7063 gen_io_start();
7064 }
7065
7066 switch (reg) {
7067 case 0:
7068 switch (sel) {
7069 case 0:
7070 gen_helper_mtc0_index(cpu_env, arg);
7071 rn = "Index";
7072 break;
7073 case 1:
7074 CP0_CHECK(ctx->insn_flags & ASE_MT);
7075 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7076 rn = "MVPControl";
7077 break;
7078 case 2:
7079 CP0_CHECK(ctx->insn_flags & ASE_MT);
7080 /* ignored */
7081 rn = "MVPConf0";
7082 break;
7083 case 3:
7084 CP0_CHECK(ctx->insn_flags & ASE_MT);
7085 /* ignored */
7086 rn = "MVPConf1";
7087 break;
7088 case 4:
7089 CP0_CHECK(ctx->vp);
7090 /* ignored */
7091 rn = "VPControl";
7092 break;
7093 default:
7094 goto cp0_unimplemented;
7095 }
7096 break;
7097 case 1:
7098 switch (sel) {
7099 case 0:
7100 /* ignored */
7101 rn = "Random";
7102 break;
7103 case 1:
7104 CP0_CHECK(ctx->insn_flags & ASE_MT);
7105 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7106 rn = "VPEControl";
7107 break;
7108 case 2:
7109 CP0_CHECK(ctx->insn_flags & ASE_MT);
7110 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7111 rn = "VPEConf0";
7112 break;
7113 case 3:
7114 CP0_CHECK(ctx->insn_flags & ASE_MT);
7115 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7116 rn = "VPEConf1";
7117 break;
7118 case 4:
7119 CP0_CHECK(ctx->insn_flags & ASE_MT);
7120 gen_helper_mtc0_yqmask(cpu_env, arg);
7121 rn = "YQMask";
7122 break;
7123 case 5:
7124 CP0_CHECK(ctx->insn_flags & ASE_MT);
7125 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7126 rn = "VPESchedule";
7127 break;
7128 case 6:
7129 CP0_CHECK(ctx->insn_flags & ASE_MT);
7130 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7131 rn = "VPEScheFBack";
7132 break;
7133 case 7:
7134 CP0_CHECK(ctx->insn_flags & ASE_MT);
7135 gen_helper_mtc0_vpeopt(cpu_env, arg);
7136 rn = "VPEOpt";
7137 break;
7138 default:
7139 goto cp0_unimplemented;
7140 }
7141 break;
7142 case 2:
7143 switch (sel) {
7144 case 0:
7145 gen_helper_dmtc0_entrylo0(cpu_env, arg);
7146 rn = "EntryLo0";
7147 break;
7148 case 1:
7149 CP0_CHECK(ctx->insn_flags & ASE_MT);
7150 gen_helper_mtc0_tcstatus(cpu_env, arg);
7151 rn = "TCStatus";
7152 break;
7153 case 2:
7154 CP0_CHECK(ctx->insn_flags & ASE_MT);
7155 gen_helper_mtc0_tcbind(cpu_env, arg);
7156 rn = "TCBind";
7157 break;
7158 case 3:
7159 CP0_CHECK(ctx->insn_flags & ASE_MT);
7160 gen_helper_mtc0_tcrestart(cpu_env, arg);
7161 rn = "TCRestart";
7162 break;
7163 case 4:
7164 CP0_CHECK(ctx->insn_flags & ASE_MT);
7165 gen_helper_mtc0_tchalt(cpu_env, arg);
7166 rn = "TCHalt";
7167 break;
7168 case 5:
7169 CP0_CHECK(ctx->insn_flags & ASE_MT);
7170 gen_helper_mtc0_tccontext(cpu_env, arg);
7171 rn = "TCContext";
7172 break;
7173 case 6:
7174 CP0_CHECK(ctx->insn_flags & ASE_MT);
7175 gen_helper_mtc0_tcschedule(cpu_env, arg);
7176 rn = "TCSchedule";
7177 break;
7178 case 7:
7179 CP0_CHECK(ctx->insn_flags & ASE_MT);
7180 gen_helper_mtc0_tcschefback(cpu_env, arg);
7181 rn = "TCScheFBack";
7182 break;
7183 default:
7184 goto cp0_unimplemented;
7185 }
7186 break;
7187 case 3:
7188 switch (sel) {
7189 case 0:
7190 gen_helper_dmtc0_entrylo1(cpu_env, arg);
7191 rn = "EntryLo1";
7192 break;
7193 case 1:
7194 CP0_CHECK(ctx->vp);
7195 /* ignored */
7196 rn = "GlobalNumber";
7197 break;
7198 default:
7199 goto cp0_unimplemented;
7200 }
7201 break;
7202 case 4:
7203 switch (sel) {
7204 case 0:
7205 gen_helper_mtc0_context(cpu_env, arg);
7206 rn = "Context";
7207 break;
7208 case 1:
7209 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7210 rn = "ContextConfig";
7211 goto cp0_unimplemented;
7212 case 2:
7213 CP0_CHECK(ctx->ulri);
7214 tcg_gen_st_tl(arg, cpu_env,
7215 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7216 rn = "UserLocal";
7217 break;
7218 default:
7219 goto cp0_unimplemented;
7220 }
7221 break;
7222 case 5:
7223 switch (sel) {
7224 case 0:
7225 gen_helper_mtc0_pagemask(cpu_env, arg);
7226 rn = "PageMask";
7227 break;
7228 case 1:
7229 check_insn(ctx, ISA_MIPS32R2);
7230 gen_helper_mtc0_pagegrain(cpu_env, arg);
7231 rn = "PageGrain";
7232 break;
7233 case 2:
7234 CP0_CHECK(ctx->sc);
7235 gen_helper_mtc0_segctl0(cpu_env, arg);
7236 rn = "SegCtl0";
7237 break;
7238 case 3:
7239 CP0_CHECK(ctx->sc);
7240 gen_helper_mtc0_segctl1(cpu_env, arg);
7241 rn = "SegCtl1";
7242 break;
7243 case 4:
7244 CP0_CHECK(ctx->sc);
7245 gen_helper_mtc0_segctl2(cpu_env, arg);
7246 rn = "SegCtl2";
7247 break;
7248 default:
7249 goto cp0_unimplemented;
7250 }
7251 break;
7252 case 6:
7253 switch (sel) {
7254 case 0:
7255 gen_helper_mtc0_wired(cpu_env, arg);
7256 rn = "Wired";
7257 break;
7258 case 1:
7259 check_insn(ctx, ISA_MIPS32R2);
7260 gen_helper_mtc0_srsconf0(cpu_env, arg);
7261 rn = "SRSConf0";
7262 break;
7263 case 2:
7264 check_insn(ctx, ISA_MIPS32R2);
7265 gen_helper_mtc0_srsconf1(cpu_env, arg);
7266 rn = "SRSConf1";
7267 break;
7268 case 3:
7269 check_insn(ctx, ISA_MIPS32R2);
7270 gen_helper_mtc0_srsconf2(cpu_env, arg);
7271 rn = "SRSConf2";
7272 break;
7273 case 4:
7274 check_insn(ctx, ISA_MIPS32R2);
7275 gen_helper_mtc0_srsconf3(cpu_env, arg);
7276 rn = "SRSConf3";
7277 break;
7278 case 5:
7279 check_insn(ctx, ISA_MIPS32R2);
7280 gen_helper_mtc0_srsconf4(cpu_env, arg);
7281 rn = "SRSConf4";
7282 break;
7283 default:
7284 goto cp0_unimplemented;
7285 }
7286 break;
7287 case 7:
7288 switch (sel) {
7289 case 0:
7290 check_insn(ctx, ISA_MIPS32R2);
7291 gen_helper_mtc0_hwrena(cpu_env, arg);
7292 ctx->bstate = BS_STOP;
7293 rn = "HWREna";
7294 break;
7295 default:
7296 goto cp0_unimplemented;
7297 }
7298 break;
7299 case 8:
7300 switch (sel) {
7301 case 0:
7302 /* ignored */
7303 rn = "BadVAddr";
7304 break;
7305 case 1:
7306 /* ignored */
7307 rn = "BadInstr";
7308 break;
7309 case 2:
7310 /* ignored */
7311 rn = "BadInstrP";
7312 break;
7313 default:
7314 goto cp0_unimplemented;
7315 }
7316 break;
7317 case 9:
7318 switch (sel) {
7319 case 0:
7320 gen_helper_mtc0_count(cpu_env, arg);
7321 rn = "Count";
7322 break;
7323 /* 6,7 are implementation dependent */
7324 default:
7325 goto cp0_unimplemented;
7326 }
7327 /* Stop translation as we may have switched the execution mode */
7328 ctx->bstate = BS_STOP;
7329 break;
7330 case 10:
7331 switch (sel) {
7332 case 0:
7333 gen_helper_mtc0_entryhi(cpu_env, arg);
7334 rn = "EntryHi";
7335 break;
7336 default:
7337 goto cp0_unimplemented;
7338 }
7339 break;
7340 case 11:
7341 switch (sel) {
7342 case 0:
7343 gen_helper_mtc0_compare(cpu_env, arg);
7344 rn = "Compare";
7345 break;
7346 /* 6,7 are implementation dependent */
7347 default:
7348 goto cp0_unimplemented;
7349 }
7350 /* Stop translation as we may have switched the execution mode */
7351 ctx->bstate = BS_STOP;
7352 break;
7353 case 12:
7354 switch (sel) {
7355 case 0:
7356 save_cpu_state(ctx, 1);
7357 gen_helper_mtc0_status(cpu_env, arg);
7358 /* BS_STOP isn't good enough here, hflags may have changed. */
7359 gen_save_pc(ctx->pc + 4);
7360 ctx->bstate = BS_EXCP;
7361 rn = "Status";
7362 break;
7363 case 1:
7364 check_insn(ctx, ISA_MIPS32R2);
7365 gen_helper_mtc0_intctl(cpu_env, arg);
7366 /* Stop translation as we may have switched the execution mode */
7367 ctx->bstate = BS_STOP;
7368 rn = "IntCtl";
7369 break;
7370 case 2:
7371 check_insn(ctx, ISA_MIPS32R2);
7372 gen_helper_mtc0_srsctl(cpu_env, arg);
7373 /* Stop translation as we may have switched the execution mode */
7374 ctx->bstate = BS_STOP;
7375 rn = "SRSCtl";
7376 break;
7377 case 3:
7378 check_insn(ctx, ISA_MIPS32R2);
7379 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7380 /* Stop translation as we may have switched the execution mode */
7381 ctx->bstate = BS_STOP;
7382 rn = "SRSMap";
7383 break;
7384 default:
7385 goto cp0_unimplemented;
7386 }
7387 break;
7388 case 13:
7389 switch (sel) {
7390 case 0:
7391 save_cpu_state(ctx, 1);
7392 /* Mark as an IO operation because we may trigger a software
7393 interrupt. */
7394 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7395 gen_io_start();
7396 }
7397 gen_helper_mtc0_cause(cpu_env, arg);
7398 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7399 gen_io_end();
7400 }
7401 /* Stop translation as we may have triggered an intetrupt */
7402 ctx->bstate = BS_STOP;
7403 rn = "Cause";
7404 break;
7405 default:
7406 goto cp0_unimplemented;
7407 }
7408 break;
7409 case 14:
7410 switch (sel) {
7411 case 0:
7412 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7413 rn = "EPC";
7414 break;
7415 default:
7416 goto cp0_unimplemented;
7417 }
7418 break;
7419 case 15:
7420 switch (sel) {
7421 case 0:
7422 /* ignored */
7423 rn = "PRid";
7424 break;
7425 case 1:
7426 check_insn(ctx, ISA_MIPS32R2);
7427 gen_helper_mtc0_ebase(cpu_env, arg);
7428 rn = "EBase";
7429 break;
7430 default:
7431 goto cp0_unimplemented;
7432 }
7433 break;
7434 case 16:
7435 switch (sel) {
7436 case 0:
7437 gen_helper_mtc0_config0(cpu_env, arg);
7438 rn = "Config";
7439 /* Stop translation as we may have switched the execution mode */
7440 ctx->bstate = BS_STOP;
7441 break;
7442 case 1:
7443 /* ignored, read only */
7444 rn = "Config1";
7445 break;
7446 case 2:
7447 gen_helper_mtc0_config2(cpu_env, arg);
7448 rn = "Config2";
7449 /* Stop translation as we may have switched the execution mode */
7450 ctx->bstate = BS_STOP;
7451 break;
7452 case 3:
7453 gen_helper_mtc0_config3(cpu_env, arg);
7454 rn = "Config3";
7455 /* Stop translation as we may have switched the execution mode */
7456 ctx->bstate = BS_STOP;
7457 break;
7458 case 4:
7459 /* currently ignored */
7460 rn = "Config4";
7461 break;
7462 case 5:
7463 gen_helper_mtc0_config5(cpu_env, arg);
7464 rn = "Config5";
7465 /* Stop translation as we may have switched the execution mode */
7466 ctx->bstate = BS_STOP;
7467 break;
7468 /* 6,7 are implementation dependent */
7469 default:
7470 rn = "Invalid config selector";
7471 goto cp0_unimplemented;
7472 }
7473 break;
7474 case 17:
7475 switch (sel) {
7476 case 0:
7477 gen_helper_mtc0_lladdr(cpu_env, arg);
7478 rn = "LLAddr";
7479 break;
7480 case 1:
7481 CP0_CHECK(ctx->mrp);
7482 gen_helper_mtc0_maar(cpu_env, arg);
7483 rn = "MAAR";
7484 break;
7485 case 2:
7486 CP0_CHECK(ctx->mrp);
7487 gen_helper_mtc0_maari(cpu_env, arg);
7488 rn = "MAARI";
7489 break;
7490 default:
7491 goto cp0_unimplemented;
7492 }
7493 break;
7494 case 18:
7495 switch (sel) {
7496 case 0 ... 7:
7497 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7498 rn = "WatchLo";
7499 break;
7500 default:
7501 goto cp0_unimplemented;
7502 }
7503 break;
7504 case 19:
7505 switch (sel) {
7506 case 0 ... 7:
7507 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7508 rn = "WatchHi";
7509 break;
7510 default:
7511 goto cp0_unimplemented;
7512 }
7513 break;
7514 case 20:
7515 switch (sel) {
7516 case 0:
7517 check_insn(ctx, ISA_MIPS3);
7518 gen_helper_mtc0_xcontext(cpu_env, arg);
7519 rn = "XContext";
7520 break;
7521 default:
7522 goto cp0_unimplemented;
7523 }
7524 break;
7525 case 21:
7526 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7527 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7528 switch (sel) {
7529 case 0:
7530 gen_helper_mtc0_framemask(cpu_env, arg);
7531 rn = "Framemask";
7532 break;
7533 default:
7534 goto cp0_unimplemented;
7535 }
7536 break;
7537 case 22:
7538 /* ignored */
7539 rn = "Diagnostic"; /* implementation dependent */
7540 break;
7541 case 23:
7542 switch (sel) {
7543 case 0:
7544 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7545 /* BS_STOP isn't good enough here, hflags may have changed. */
7546 gen_save_pc(ctx->pc + 4);
7547 ctx->bstate = BS_EXCP;
7548 rn = "Debug";
7549 break;
7550 case 1:
7551 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7552 /* Stop translation as we may have switched the execution mode */
7553 ctx->bstate = BS_STOP;
7554 rn = "TraceControl";
7555 goto cp0_unimplemented;
7556 case 2:
7557 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7558 /* Stop translation as we may have switched the execution mode */
7559 ctx->bstate = BS_STOP;
7560 rn = "TraceControl2";
7561 goto cp0_unimplemented;
7562 case 3:
7563 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7564 /* Stop translation as we may have switched the execution mode */
7565 ctx->bstate = BS_STOP;
7566 rn = "UserTraceData";
7567 goto cp0_unimplemented;
7568 case 4:
7569 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7570 /* Stop translation as we may have switched the execution mode */
7571 ctx->bstate = BS_STOP;
7572 rn = "TraceBPC";
7573 goto cp0_unimplemented;
7574 default:
7575 goto cp0_unimplemented;
7576 }
7577 break;
7578 case 24:
7579 switch (sel) {
7580 case 0:
7581 /* EJTAG support */
7582 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7583 rn = "DEPC";
7584 break;
7585 default:
7586 goto cp0_unimplemented;
7587 }
7588 break;
7589 case 25:
7590 switch (sel) {
7591 case 0:
7592 gen_helper_mtc0_performance0(cpu_env, arg);
7593 rn = "Performance0";
7594 break;
7595 case 1:
7596 // gen_helper_mtc0_performance1(cpu_env, arg);
7597 rn = "Performance1";
7598 goto cp0_unimplemented;
7599 case 2:
7600 // gen_helper_mtc0_performance2(cpu_env, arg);
7601 rn = "Performance2";
7602 goto cp0_unimplemented;
7603 case 3:
7604 // gen_helper_mtc0_performance3(cpu_env, arg);
7605 rn = "Performance3";
7606 goto cp0_unimplemented;
7607 case 4:
7608 // gen_helper_mtc0_performance4(cpu_env, arg);
7609 rn = "Performance4";
7610 goto cp0_unimplemented;
7611 case 5:
7612 // gen_helper_mtc0_performance5(cpu_env, arg);
7613 rn = "Performance5";
7614 goto cp0_unimplemented;
7615 case 6:
7616 // gen_helper_mtc0_performance6(cpu_env, arg);
7617 rn = "Performance6";
7618 goto cp0_unimplemented;
7619 case 7:
7620 // gen_helper_mtc0_performance7(cpu_env, arg);
7621 rn = "Performance7";
7622 goto cp0_unimplemented;
7623 default:
7624 goto cp0_unimplemented;
7625 }
7626 break;
7627 case 26:
7628 switch (sel) {
7629 case 0:
7630 gen_helper_mtc0_errctl(cpu_env, arg);
7631 ctx->bstate = BS_STOP;
7632 rn = "ErrCtl";
7633 break;
7634 default:
7635 goto cp0_unimplemented;
7636 }
7637 break;
7638 case 27:
7639 switch (sel) {
7640 case 0 ... 3:
7641 /* ignored */
7642 rn = "CacheErr";
7643 break;
7644 default:
7645 goto cp0_unimplemented;
7646 }
7647 break;
7648 case 28:
7649 switch (sel) {
7650 case 0:
7651 case 2:
7652 case 4:
7653 case 6:
7654 gen_helper_mtc0_taglo(cpu_env, arg);
7655 rn = "TagLo";
7656 break;
7657 case 1:
7658 case 3:
7659 case 5:
7660 case 7:
7661 gen_helper_mtc0_datalo(cpu_env, arg);
7662 rn = "DataLo";
7663 break;
7664 default:
7665 goto cp0_unimplemented;
7666 }
7667 break;
7668 case 29:
7669 switch (sel) {
7670 case 0:
7671 case 2:
7672 case 4:
7673 case 6:
7674 gen_helper_mtc0_taghi(cpu_env, arg);
7675 rn = "TagHi";
7676 break;
7677 case 1:
7678 case 3:
7679 case 5:
7680 case 7:
7681 gen_helper_mtc0_datahi(cpu_env, arg);
7682 rn = "DataHi";
7683 break;
7684 default:
7685 rn = "invalid sel";
7686 goto cp0_unimplemented;
7687 }
7688 break;
7689 case 30:
7690 switch (sel) {
7691 case 0:
7692 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7693 rn = "ErrorEPC";
7694 break;
7695 default:
7696 goto cp0_unimplemented;
7697 }
7698 break;
7699 case 31:
7700 switch (sel) {
7701 case 0:
7702 /* EJTAG support */
7703 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7704 rn = "DESAVE";
7705 break;
7706 case 2 ... 7:
7707 CP0_CHECK(ctx->kscrexist & (1 << sel));
7708 tcg_gen_st_tl(arg, cpu_env,
7709 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7710 rn = "KScratch";
7711 break;
7712 default:
7713 goto cp0_unimplemented;
7714 }
7715 break;
7716 default:
7717 goto cp0_unimplemented;
7718 }
7719 trace_mips_translate_c0("dmtc0", rn, reg, sel);
7720
7721 /* For simplicity assume that all writes can cause interrupts. */
7722 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7723 gen_io_end();
7724 ctx->bstate = BS_STOP;
7725 }
7726 return;
7727
7728 cp0_unimplemented:
7729 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7730 }
7731 #endif /* TARGET_MIPS64 */
7732
7733 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7734 int u, int sel, int h)
7735 {
7736 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7737 TCGv t0 = tcg_temp_local_new();
7738
7739 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7740 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7741 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7742 tcg_gen_movi_tl(t0, -1);
7743 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7744 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7745 tcg_gen_movi_tl(t0, -1);
7746 else if (u == 0) {
7747 switch (rt) {
7748 case 1:
7749 switch (sel) {
7750 case 1:
7751 gen_helper_mftc0_vpecontrol(t0, cpu_env);
7752 break;
7753 case 2:
7754 gen_helper_mftc0_vpeconf0(t0, cpu_env);
7755 break;
7756 default:
7757 goto die;
7758 break;
7759 }
7760 break;
7761 case 2:
7762 switch (sel) {
7763 case 1:
7764 gen_helper_mftc0_tcstatus(t0, cpu_env);
7765 break;
7766 case 2:
7767 gen_helper_mftc0_tcbind(t0, cpu_env);
7768 break;
7769 case 3:
7770 gen_helper_mftc0_tcrestart(t0, cpu_env);
7771 break;
7772 case 4:
7773 gen_helper_mftc0_tchalt(t0, cpu_env);
7774 break;
7775 case 5:
7776 gen_helper_mftc0_tccontext(t0, cpu_env);
7777 break;
7778 case 6:
7779 gen_helper_mftc0_tcschedule(t0, cpu_env);
7780 break;
7781 case 7:
7782 gen_helper_mftc0_tcschefback(t0, cpu_env);
7783 break;
7784 default:
7785 gen_mfc0(ctx, t0, rt, sel);
7786 break;
7787 }
7788 break;
7789 case 10:
7790 switch (sel) {
7791 case 0:
7792 gen_helper_mftc0_entryhi(t0, cpu_env);
7793 break;
7794 default:
7795 gen_mfc0(ctx, t0, rt, sel);
7796 break;
7797 }
7798 case 12:
7799 switch (sel) {
7800 case 0:
7801 gen_helper_mftc0_status(t0, cpu_env);
7802 break;
7803 default:
7804 gen_mfc0(ctx, t0, rt, sel);
7805 break;
7806 }
7807 case 13:
7808 switch (sel) {
7809 case 0:
7810 gen_helper_mftc0_cause(t0, cpu_env);
7811 break;
7812 default:
7813 goto die;
7814 break;
7815 }
7816 break;
7817 case 14:
7818 switch (sel) {
7819 case 0:
7820 gen_helper_mftc0_epc(t0, cpu_env);
7821 break;
7822 default:
7823 goto die;
7824 break;
7825 }
7826 break;
7827 case 15:
7828 switch (sel) {
7829 case 1:
7830 gen_helper_mftc0_ebase(t0, cpu_env);
7831 break;
7832 default:
7833 goto die;
7834 break;
7835 }
7836 break;
7837 case 16:
7838 switch (sel) {
7839 case 0 ... 7:
7840 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7841 break;
7842 default:
7843 goto die;
7844 break;
7845 }
7846 break;
7847 case 23:
7848 switch (sel) {
7849 case 0:
7850 gen_helper_mftc0_debug(t0, cpu_env);
7851 break;
7852 default:
7853 gen_mfc0(ctx, t0, rt, sel);
7854 break;
7855 }
7856 break;
7857 default:
7858 gen_mfc0(ctx, t0, rt, sel);
7859 }
7860 } else switch (sel) {
7861 /* GPR registers. */
7862 case 0:
7863 gen_helper_1e0i(mftgpr, t0, rt);
7864 break;
7865 /* Auxiliary CPU registers */
7866 case 1:
7867 switch (rt) {
7868 case 0:
7869 gen_helper_1e0i(mftlo, t0, 0);
7870 break;
7871 case 1:
7872 gen_helper_1e0i(mfthi, t0, 0);
7873 break;
7874 case 2:
7875 gen_helper_1e0i(mftacx, t0, 0);
7876 break;
7877 case 4:
7878 gen_helper_1e0i(mftlo, t0, 1);
7879 break;
7880 case 5:
7881 gen_helper_1e0i(mfthi, t0, 1);
7882 break;
7883 case 6:
7884 gen_helper_1e0i(mftacx, t0, 1);
7885 break;
7886 case 8:
7887 gen_helper_1e0i(mftlo, t0, 2);
7888 break;
7889 case 9:
7890 gen_helper_1e0i(mfthi, t0, 2);
7891 break;
7892 case 10:
7893 gen_helper_1e0i(mftacx, t0, 2);
7894 break;
7895 case 12:
7896 gen_helper_1e0i(mftlo, t0, 3);
7897 break;
7898 case 13:
7899 gen_helper_1e0i(mfthi, t0, 3);
7900 break;
7901 case 14:
7902 gen_helper_1e0i(mftacx, t0, 3);
7903 break;
7904 case 16:
7905 gen_helper_mftdsp(t0, cpu_env);
7906 break;
7907 default:
7908 goto die;
7909 }
7910 break;
7911 /* Floating point (COP1). */
7912 case 2:
7913 /* XXX: For now we support only a single FPU context. */
7914 if (h == 0) {
7915 TCGv_i32 fp0 = tcg_temp_new_i32();
7916
7917 gen_load_fpr32(ctx, fp0, rt);
7918 tcg_gen_ext_i32_tl(t0, fp0);
7919 tcg_temp_free_i32(fp0);
7920 } else {
7921 TCGv_i32 fp0 = tcg_temp_new_i32();
7922
7923 gen_load_fpr32h(ctx, fp0, rt);
7924 tcg_gen_ext_i32_tl(t0, fp0);
7925 tcg_temp_free_i32(fp0);
7926 }
7927 break;
7928 case 3:
7929 /* XXX: For now we support only a single FPU context. */
7930 gen_helper_1e0i(cfc1, t0, rt);
7931 break;
7932 /* COP2: Not implemented. */
7933 case 4:
7934 case 5:
7935 /* fall through */
7936 default:
7937 goto die;
7938 }
7939 trace_mips_translate_tr("mftr", rt, u, sel, h);
7940 gen_store_gpr(t0, rd);
7941 tcg_temp_free(t0);
7942 return;
7943
7944 die:
7945 tcg_temp_free(t0);
7946 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7947 generate_exception_end(ctx, EXCP_RI);
7948 }
7949
7950 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7951 int u, int sel, int h)
7952 {
7953 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7954 TCGv t0 = tcg_temp_local_new();
7955
7956 gen_load_gpr(t0, rt);
7957 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7958 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7959 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7960 /* NOP */ ;
7961 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7962 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7963 /* NOP */ ;
7964 else if (u == 0) {
7965 switch (rd) {
7966 case 1:
7967 switch (sel) {
7968 case 1:
7969 gen_helper_mttc0_vpecontrol(cpu_env, t0);
7970 break;
7971 case 2:
7972 gen_helper_mttc0_vpeconf0(cpu_env, t0);
7973 break;
7974 default:
7975 goto die;
7976 break;
7977 }
7978 break;
7979 case 2:
7980 switch (sel) {
7981 case 1:
7982 gen_helper_mttc0_tcstatus(cpu_env, t0);
7983 break;
7984 case 2:
7985 gen_helper_mttc0_tcbind(cpu_env, t0);
7986 break;
7987 case 3:
7988 gen_helper_mttc0_tcrestart(cpu_env, t0);
7989 break;
7990 case 4:
7991 gen_helper_mttc0_tchalt(cpu_env, t0);
7992 break;
7993 case 5:
7994 gen_helper_mttc0_tccontext(cpu_env, t0);
7995 break;
7996 case 6:
7997 gen_helper_mttc0_tcschedule(cpu_env, t0);
7998 break;
7999 case 7:
8000 gen_helper_mttc0_tcschefback(cpu_env, t0);
8001 break;
8002 default:
8003 gen_mtc0(ctx, t0, rd, sel);
8004 break;
8005 }
8006 break;
8007 case 10:
8008 switch (sel) {
8009 case 0:
8010 gen_helper_mttc0_entryhi(cpu_env, t0);
8011 break;
8012 default:
8013 gen_mtc0(ctx, t0, rd, sel);
8014 break;
8015 }
8016 case 12:
8017 switch (sel) {
8018 case 0:
8019 gen_helper_mttc0_status(cpu_env, t0);
8020 break;
8021 default:
8022 gen_mtc0(ctx, t0, rd, sel);
8023 break;
8024 }
8025 case 13:
8026 switch (sel) {
8027 case 0:
8028 gen_helper_mttc0_cause(cpu_env, t0);
8029 break;
8030 default:
8031 goto die;
8032 break;
8033 }
8034 break;
8035 case 15:
8036 switch (sel) {
8037 case 1:
8038 gen_helper_mttc0_ebase(cpu_env, t0);
8039 break;
8040 default:
8041 goto die;
8042 break;
8043 }
8044 break;
8045 case 23:
8046 switch (sel) {
8047 case 0:
8048 gen_helper_mttc0_debug(cpu_env, t0);
8049 break;
8050 default:
8051 gen_mtc0(ctx, t0, rd, sel);
8052 break;
8053 }
8054 break;
8055 default:
8056 gen_mtc0(ctx, t0, rd, sel);
8057 }
8058 } else switch (sel) {
8059 /* GPR registers. */
8060 case 0:
8061 gen_helper_0e1i(mttgpr, t0, rd);
8062 break;
8063 /* Auxiliary CPU registers */
8064 case 1:
8065 switch (rd) {
8066 case 0:
8067 gen_helper_0e1i(mttlo, t0, 0);
8068 break;
8069 case 1:
8070 gen_helper_0e1i(mtthi, t0, 0);
8071 break;
8072 case 2:
8073 gen_helper_0e1i(mttacx, t0, 0);
8074 break;
8075 case 4:
8076 gen_helper_0e1i(mttlo, t0, 1);
8077 break;
8078 case 5:
8079 gen_helper_0e1i(mtthi, t0, 1);
8080 break;
8081 case 6:
8082 gen_helper_0e1i(mttacx, t0, 1);
8083 break;
8084 case 8:
8085 gen_helper_0e1i(mttlo, t0, 2);
8086 break;
8087 case 9:
8088 gen_helper_0e1i(mtthi, t0, 2);
8089 break;
8090 case 10:
8091 gen_helper_0e1i(mttacx, t0, 2);
8092 break;
8093 case 12:
8094 gen_helper_0e1i(mttlo, t0, 3);
8095 break;
8096 case 13:
8097 gen_helper_0e1i(mtthi, t0, 3);
8098 break;
8099 case 14:
8100 gen_helper_0e1i(mttacx, t0, 3);
8101 break;
8102 case 16:
8103 gen_helper_mttdsp(cpu_env, t0);
8104 break;
8105 default:
8106 goto die;
8107 }
8108 break;
8109 /* Floating point (COP1). */
8110 case 2:
8111 /* XXX: For now we support only a single FPU context. */
8112 if (h == 0) {
8113 TCGv_i32 fp0 = tcg_temp_new_i32();
8114
8115 tcg_gen_trunc_tl_i32(fp0, t0);
8116 gen_store_fpr32(ctx, fp0, rd);
8117 tcg_temp_free_i32(fp0);
8118 } else {
8119 TCGv_i32 fp0 = tcg_temp_new_i32();
8120
8121 tcg_gen_trunc_tl_i32(fp0, t0);
8122 gen_store_fpr32h(ctx, fp0, rd);
8123 tcg_temp_free_i32(fp0);
8124 }
8125 break;
8126 case 3:
8127 /* XXX: For now we support only a single FPU context. */
8128 {
8129 TCGv_i32 fs_tmp = tcg_const_i32(rd);
8130
8131 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8132 tcg_temp_free_i32(fs_tmp);
8133 }
8134 /* Stop translation as we may have changed hflags */
8135 ctx->bstate = BS_STOP;
8136 break;
8137 /* COP2: Not implemented. */
8138 case 4:
8139 case 5:
8140 /* fall through */
8141 default:
8142 goto die;
8143 }
8144 trace_mips_translate_tr("mttr", rd, u, sel, h);
8145 tcg_temp_free(t0);
8146 return;
8147
8148 die:
8149 tcg_temp_free(t0);
8150 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8151 generate_exception_end(ctx, EXCP_RI);
8152 }
8153
8154 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
8155 {
8156 const char *opn = "ldst";
8157
8158 check_cp0_enabled(ctx);
8159 switch (opc) {
8160 case OPC_MFC0:
8161 if (rt == 0) {
8162 /* Treat as NOP. */
8163 return;
8164 }
8165 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8166 opn = "mfc0";
8167 break;
8168 case OPC_MTC0:
8169 {
8170 TCGv t0 = tcg_temp_new();
8171
8172 gen_load_gpr(t0, rt);
8173 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8174 tcg_temp_free(t0);
8175 }
8176 opn = "mtc0";
8177 break;
8178 #if defined(TARGET_MIPS64)
8179 case OPC_DMFC0:
8180 check_insn(ctx, ISA_MIPS3);
8181 if (rt == 0) {
8182 /* Treat as NOP. */
8183 return;
8184 }
8185 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8186 opn = "dmfc0";
8187 break;
8188 case OPC_DMTC0:
8189 check_insn(ctx, ISA_MIPS3);
8190 {
8191 TCGv t0 = tcg_temp_new();
8192
8193 gen_load_gpr(t0, rt);
8194 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8195 tcg_temp_free(t0);
8196 }
8197 opn = "dmtc0";
8198 break;
8199 #endif
8200 case OPC_MFHC0:
8201 check_mvh(ctx);
8202 if (rt == 0) {
8203 /* Treat as NOP. */
8204 return;
8205 }
8206 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8207 opn = "mfhc0";
8208 break;
8209 case OPC_MTHC0:
8210 check_mvh(ctx);
8211 {
8212 TCGv t0 = tcg_temp_new();
8213 gen_load_gpr(t0, rt);
8214 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8215 tcg_temp_free(t0);
8216 }
8217 opn = "mthc0";
8218 break;
8219 case OPC_MFTR:
8220 check_insn(ctx, ASE_MT);
8221 if (rd == 0) {
8222 /* Treat as NOP. */
8223 return;
8224 }
8225 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8226 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8227 opn = "mftr";
8228 break;
8229 case OPC_MTTR:
8230 check_insn(ctx, ASE_MT);
8231 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8232 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8233 opn = "mttr";
8234 break;
8235 case OPC_TLBWI:
8236 opn = "tlbwi";
8237 if (!env->tlb->helper_tlbwi)
8238 goto die;
8239 gen_helper_tlbwi(cpu_env);
8240 break;
8241 case OPC_TLBINV:
8242 opn = "tlbinv";
8243 if (ctx->ie >= 2) {
8244 if (!env->tlb->helper_tlbinv) {
8245 goto die;
8246 }
8247 gen_helper_tlbinv(cpu_env);
8248 } /* treat as nop if TLBINV not supported */
8249 break;
8250 case OPC_TLBINVF:
8251 opn = "tlbinvf";
8252 if (ctx->ie >= 2) {
8253 if (!env->tlb->helper_tlbinvf) {
8254 goto die;
8255 }
8256 gen_helper_tlbinvf(cpu_env);
8257 } /* treat as nop if TLBINV not supported */
8258 break;
8259 case OPC_TLBWR:
8260 opn = "tlbwr";
8261 if (!env->tlb->helper_tlbwr)
8262 goto die;
8263 gen_helper_tlbwr(cpu_env);
8264 break;
8265 case OPC_TLBP:
8266 opn = "tlbp";
8267 if (!env->tlb->helper_tlbp)
8268 goto die;
8269 gen_helper_tlbp(cpu_env);
8270 break;
8271 case OPC_TLBR:
8272 opn = "tlbr";
8273 if (!env->tlb->helper_tlbr)
8274 goto die;
8275 gen_helper_tlbr(cpu_env);
8276 break;
8277 case OPC_ERET: /* OPC_ERETNC */
8278 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8279 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8280 goto die;
8281 } else {
8282 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8283 if (ctx->opcode & (1 << bit_shift)) {
8284 /* OPC_ERETNC */
8285 opn = "eretnc";
8286 check_insn(ctx, ISA_MIPS32R5);
8287 gen_helper_eretnc(cpu_env);
8288 } else {
8289 /* OPC_ERET */
8290 opn = "eret";
8291 check_insn(ctx, ISA_MIPS2);
8292 gen_helper_eret(cpu_env);
8293 }
8294 ctx->bstate = BS_EXCP;
8295 }
8296 break;
8297 case OPC_DERET:
8298 opn = "deret";
8299 check_insn(ctx, ISA_MIPS32);
8300 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8301 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8302 goto die;
8303 }
8304 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8305 MIPS_INVAL(opn);
8306 generate_exception_end(ctx, EXCP_RI);
8307 } else {
8308 gen_helper_deret(cpu_env);
8309 ctx->bstate = BS_EXCP;
8310 }
8311 break;
8312 case OPC_WAIT:
8313 opn = "wait";
8314 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8315 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8316 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8317 goto die;
8318 }
8319 /* If we get an exception, we want to restart at next instruction */
8320 ctx->pc += 4;
8321 save_cpu_state(ctx, 1);
8322 ctx->pc -= 4;
8323 gen_helper_wait(cpu_env);
8324 ctx->bstate = BS_EXCP;
8325 break;
8326 default:
8327 die:
8328 MIPS_INVAL(opn);
8329 generate_exception_end(ctx, EXCP_RI);
8330 return;
8331 }
8332 (void)opn; /* avoid a compiler warning */
8333 }
8334 #endif /* !CONFIG_USER_ONLY */
8335
8336 /* CP1 Branches (before delay slot) */
8337 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8338 int32_t cc, int32_t offset)
8339 {
8340 target_ulong btarget;
8341 TCGv_i32 t0 = tcg_temp_new_i32();
8342
8343 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8344 generate_exception_end(ctx, EXCP_RI);
8345 goto out;
8346 }
8347
8348 if (cc != 0)
8349 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8350
8351 btarget = ctx->pc + 4 + offset;
8352
8353 switch (op) {
8354 case OPC_BC1F:
8355 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8356 tcg_gen_not_i32(t0, t0);
8357 tcg_gen_andi_i32(t0, t0, 1);
8358 tcg_gen_extu_i32_tl(bcond, t0);
8359 goto not_likely;
8360 case OPC_BC1FL:
8361 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8362 tcg_gen_not_i32(t0, t0);
8363 tcg_gen_andi_i32(t0, t0, 1);
8364 tcg_gen_extu_i32_tl(bcond, t0);
8365 goto likely;
8366 case OPC_BC1T:
8367 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8368 tcg_gen_andi_i32(t0, t0, 1);
8369 tcg_gen_extu_i32_tl(bcond, t0);
8370 goto not_likely;
8371 case OPC_BC1TL:
8372 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8373 tcg_gen_andi_i32(t0, t0, 1);
8374 tcg_gen_extu_i32_tl(bcond, t0);
8375 likely:
8376 ctx->hflags |= MIPS_HFLAG_BL;
8377 break;
8378 case OPC_BC1FANY2:
8379 {
8380 TCGv_i32 t1 = tcg_temp_new_i32();
8381 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8382 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8383 tcg_gen_nand_i32(t0, t0, t1);
8384 tcg_temp_free_i32(t1);
8385 tcg_gen_andi_i32(t0, t0, 1);
8386 tcg_gen_extu_i32_tl(bcond, t0);
8387 }
8388 goto not_likely;
8389 case OPC_BC1TANY2:
8390 {
8391 TCGv_i32 t1 = tcg_temp_new_i32();
8392 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8393 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8394 tcg_gen_or_i32(t0, t0, t1);
8395 tcg_temp_free_i32(t1);
8396 tcg_gen_andi_i32(t0, t0, 1);
8397 tcg_gen_extu_i32_tl(bcond, t0);
8398 }
8399 goto not_likely;
8400 case OPC_BC1FANY4:
8401 {
8402 TCGv_i32 t1 = tcg_temp_new_i32();
8403 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8404 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8405 tcg_gen_and_i32(t0, t0, t1);
8406 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8407 tcg_gen_and_i32(t0, t0, t1);
8408 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8409 tcg_gen_nand_i32(t0, t0, t1);
8410 tcg_temp_free_i32(t1);
8411 tcg_gen_andi_i32(t0, t0, 1);
8412 tcg_gen_extu_i32_tl(bcond, t0);
8413 }
8414 goto not_likely;
8415 case OPC_BC1TANY4:
8416 {
8417 TCGv_i32 t1 = tcg_temp_new_i32();
8418 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8419 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8420 tcg_gen_or_i32(t0, t0, t1);
8421 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8422 tcg_gen_or_i32(t0, t0, t1);
8423 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8424 tcg_gen_or_i32(t0, t0, t1);
8425 tcg_temp_free_i32(t1);
8426 tcg_gen_andi_i32(t0, t0, 1);
8427 tcg_gen_extu_i32_tl(bcond, t0);
8428 }
8429 not_likely:
8430 ctx->hflags |= MIPS_HFLAG_BC;
8431 break;
8432 default:
8433 MIPS_INVAL("cp1 cond branch");
8434 generate_exception_end(ctx, EXCP_RI);
8435 goto out;
8436 }
8437 ctx->btarget = btarget;
8438 ctx->hflags |= MIPS_HFLAG_BDS32;
8439 out:
8440 tcg_temp_free_i32(t0);
8441 }
8442
8443 /* R6 CP1 Branches */
8444 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8445 int32_t ft, int32_t offset,
8446 int delayslot_size)
8447 {
8448 target_ulong btarget;
8449 TCGv_i64 t0 = tcg_temp_new_i64();
8450
8451 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8452 #ifdef MIPS_DEBUG_DISAS
8453 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8454 "\n", ctx->pc);
8455 #endif
8456 generate_exception_end(ctx, EXCP_RI);
8457 goto out;
8458 }
8459
8460 gen_load_fpr64(ctx, t0, ft);
8461 tcg_gen_andi_i64(t0, t0, 1);
8462
8463 btarget = addr_add(ctx, ctx->pc + 4, offset);
8464
8465 switch (op) {
8466 case OPC_BC1EQZ:
8467 tcg_gen_xori_i64(t0, t0, 1);
8468 ctx->hflags |= MIPS_HFLAG_BC;
8469 break;
8470 case OPC_BC1NEZ:
8471 /* t0 already set */
8472 ctx->hflags |= MIPS_HFLAG_BC;
8473 break;
8474 default:
8475 MIPS_INVAL("cp1 cond branch");
8476 generate_exception_end(ctx, EXCP_RI);
8477 goto out;
8478 }
8479
8480 tcg_gen_trunc_i64_tl(bcond, t0);
8481
8482 ctx->btarget = btarget;
8483
8484 switch (delayslot_size) {
8485 case 2:
8486 ctx->hflags |= MIPS_HFLAG_BDS16;
8487 break;
8488 case 4:
8489 ctx->hflags |= MIPS_HFLAG_BDS32;
8490 break;
8491 }
8492
8493 out:
8494 tcg_temp_free_i64(t0);
8495 }
8496
8497 /* Coprocessor 1 (FPU) */
8498
8499 #define FOP(func, fmt) (((fmt) << 21) | (func))
8500
8501 enum fopcode {
8502 OPC_ADD_S = FOP(0, FMT_S),
8503 OPC_SUB_S = FOP(1, FMT_S),
8504 OPC_MUL_S = FOP(2, FMT_S),
8505 OPC_DIV_S = FOP(3, FMT_S),
8506 OPC_SQRT_S = FOP(4, FMT_S),
8507 OPC_ABS_S = FOP(5, FMT_S),
8508 OPC_MOV_S = FOP(6, FMT_S),
8509 OPC_NEG_S = FOP(7, FMT_S),
8510 OPC_ROUND_L_S = FOP(8, FMT_S),
8511 OPC_TRUNC_L_S = FOP(9, FMT_S),
8512 OPC_CEIL_L_S = FOP(10, FMT_S),
8513 OPC_FLOOR_L_S = FOP(11, FMT_S),
8514 OPC_ROUND_W_S = FOP(12, FMT_S),
8515 OPC_TRUNC_W_S = FOP(13, FMT_S),
8516 OPC_CEIL_W_S = FOP(14, FMT_S),
8517 OPC_FLOOR_W_S = FOP(15, FMT_S),
8518 OPC_SEL_S = FOP(16, FMT_S),
8519 OPC_MOVCF_S = FOP(17, FMT_S),
8520 OPC_MOVZ_S = FOP(18, FMT_S),
8521 OPC_MOVN_S = FOP(19, FMT_S),
8522 OPC_SELEQZ_S = FOP(20, FMT_S),
8523 OPC_RECIP_S = FOP(21, FMT_S),
8524 OPC_RSQRT_S = FOP(22, FMT_S),
8525 OPC_SELNEZ_S = FOP(23, FMT_S),
8526 OPC_MADDF_S = FOP(24, FMT_S),
8527 OPC_MSUBF_S = FOP(25, FMT_S),
8528 OPC_RINT_S = FOP(26, FMT_S),
8529 OPC_CLASS_S = FOP(27, FMT_S),
8530 OPC_MIN_S = FOP(28, FMT_S),
8531 OPC_RECIP2_S = FOP(28, FMT_S),
8532 OPC_MINA_S = FOP(29, FMT_S),
8533 OPC_RECIP1_S = FOP(29, FMT_S),
8534 OPC_MAX_S = FOP(30, FMT_S),
8535 OPC_RSQRT1_S = FOP(30, FMT_S),
8536 OPC_MAXA_S = FOP(31, FMT_S),
8537 OPC_RSQRT2_S = FOP(31, FMT_S),
8538 OPC_CVT_D_S = FOP(33, FMT_S),
8539 OPC_CVT_W_S = FOP(36, FMT_S),
8540 OPC_CVT_L_S = FOP(37, FMT_S),
8541 OPC_CVT_PS_S = FOP(38, FMT_S),
8542 OPC_CMP_F_S = FOP (48, FMT_S),
8543 OPC_CMP_UN_S = FOP (49, FMT_S),
8544 OPC_CMP_EQ_S = FOP (50, FMT_S),
8545 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8546 OPC_CMP_OLT_S = FOP (52, FMT_S),
8547 OPC_CMP_ULT_S = FOP (53, FMT_S),
8548 OPC_CMP_OLE_S = FOP (54, FMT_S),
8549 OPC_CMP_ULE_S = FOP (55, FMT_S),
8550 OPC_CMP_SF_S = FOP (56, FMT_S),
8551 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8552 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8553 OPC_CMP_NGL_S = FOP (59, FMT_S),
8554 OPC_CMP_LT_S = FOP (60, FMT_S),
8555 OPC_CMP_NGE_S = FOP (61, FMT_S),
8556 OPC_CMP_LE_S = FOP (62, FMT_S),
8557 OPC_CMP_NGT_S = FOP (63, FMT_S),
8558
8559 OPC_ADD_D = FOP(0, FMT_D),
8560 OPC_SUB_D = FOP(1, FMT_D),
8561 OPC_MUL_D = FOP(2, FMT_D),
8562 OPC_DIV_D = FOP(3, FMT_D),
8563 OPC_SQRT_D = FOP(4, FMT_D),
8564 OPC_ABS_D = FOP(5, FMT_D),
8565 OPC_MOV_D = FOP(6, FMT_D),
8566 OPC_NEG_D = FOP(7, FMT_D),
8567 OPC_ROUND_L_D = FOP(8, FMT_D),
8568 OPC_TRUNC_L_D = FOP(9, FMT_D),
8569 OPC_CEIL_L_D = FOP(10, FMT_D),
8570 OPC_FLOOR_L_D = FOP(11, FMT_D),
8571 OPC_ROUND_W_D = FOP(12, FMT_D),
8572 OPC_TRUNC_W_D = FOP(13, FMT_D),
8573 OPC_CEIL_W_D = FOP(14, FMT_D),
8574 OPC_FLOOR_W_D = FOP(15, FMT_D),
8575 OPC_SEL_D = FOP(16, FMT_D),
8576 OPC_MOVCF_D = FOP(17, FMT_D),
8577 OPC_MOVZ_D = FOP(18, FMT_D),
8578 OPC_MOVN_D = FOP(19, FMT_D),
8579 OPC_SELEQZ_D = FOP(20, FMT_D),
8580 OPC_RECIP_D = FOP(21, FMT_D),
8581 OPC_RSQRT_D = FOP(22, FMT_D),
8582 OPC_SELNEZ_D = FOP(23, FMT_D),
8583 OPC_MADDF_D = FOP(24, FMT_D),
8584 OPC_MSUBF_D = FOP(25, FMT_D),
8585 OPC_RINT_D = FOP(26, FMT_D),
8586 OPC_CLASS_D = FOP(27, FMT_D),
8587 OPC_MIN_D = FOP(28, FMT_D),
8588 OPC_RECIP2_D = FOP(28, FMT_D),
8589 OPC_MINA_D = FOP(29, FMT_D),
8590 OPC_RECIP1_D = FOP(29, FMT_D),
8591 OPC_MAX_D = FOP(30, FMT_D),
8592 OPC_RSQRT1_D = FOP(30, FMT_D),
8593 OPC_MAXA_D = FOP(31, FMT_D),
8594 OPC_RSQRT2_D = FOP(31, FMT_D),
8595 OPC_CVT_S_D = FOP(32, FMT_D),
8596 OPC_CVT_W_D = FOP(36, FMT_D),
8597 OPC_CVT_L_D = FOP(37, FMT_D),
8598 OPC_CMP_F_D = FOP (48, FMT_D),
8599 OPC_CMP_UN_D = FOP (49, FMT_D),
8600 OPC_CMP_EQ_D = FOP (50, FMT_D),
8601 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8602 OPC_CMP_OLT_D = FOP (52, FMT_D),
8603 OPC_CMP_ULT_D = FOP (53, FMT_D),
8604 OPC_CMP_OLE_D = FOP (54, FMT_D),
8605 OPC_CMP_ULE_D = FOP (55, FMT_D),
8606 OPC_CMP_SF_D = FOP (56, FMT_D),
8607 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8608 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8609 OPC_CMP_NGL_D = FOP (59, FMT_D),
8610 OPC_CMP_LT_D = FOP (60, FMT_D),
8611 OPC_CMP_NGE_D = FOP (61, FMT_D),
8612 OPC_CMP_LE_D = FOP (62, FMT_D),
8613 OPC_CMP_NGT_D = FOP (63, FMT_D),
8614
8615 OPC_CVT_S_W = FOP(32, FMT_W),
8616 OPC_CVT_D_W = FOP(33, FMT_W),
8617 OPC_CVT_S_L = FOP(32, FMT_L),
8618 OPC_CVT_D_L = FOP(33, FMT_L),
8619 OPC_CVT_PS_PW = FOP(38, FMT_W),
8620
8621 OPC_ADD_PS = FOP(0, FMT_PS),
8622 OPC_SUB_PS = FOP(1, FMT_PS),
8623 OPC_MUL_PS = FOP(2, FMT_PS),
8624 OPC_DIV_PS = FOP(3, FMT_PS),
8625 OPC_ABS_PS = FOP(5, FMT_PS),
8626 OPC_MOV_PS = FOP(6, FMT_PS),
8627 OPC_NEG_PS = FOP(7, FMT_PS),
8628 OPC_MOVCF_PS = FOP(17, FMT_PS),
8629 OPC_MOVZ_PS = FOP(18, FMT_PS),
8630 OPC_MOVN_PS = FOP(19, FMT_PS),
8631 OPC_ADDR_PS = FOP(24, FMT_PS),
8632 OPC_MULR_PS = FOP(26, FMT_PS),
8633 OPC_RECIP2_PS = FOP(28, FMT_PS),
8634 OPC_RECIP1_PS = FOP(29, FMT_PS),
8635 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8636 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8637
8638 OPC_CVT_S_PU = FOP(32, FMT_PS),
8639 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8640 OPC_CVT_S_PL = FOP(40, FMT_PS),
8641 OPC_PLL_PS = FOP(44, FMT_PS),
8642 OPC_PLU_PS = FOP(45, FMT_PS),
8643 OPC_PUL_PS = FOP(46, FMT_PS),
8644 OPC_PUU_PS = FOP(47, FMT_PS),
8645 OPC_CMP_F_PS = FOP (48, FMT_PS),
8646 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8647 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8648 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8649 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8650 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8651 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8652 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8653 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8654 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8655 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8656 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8657 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8658 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8659 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8660 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8661 };
8662
8663 enum r6_f_cmp_op {
8664 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8665 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8666 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8667 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8668 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8669 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8670 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8671 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8672 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8673 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8674 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8675 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8676 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8677 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8678 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8679 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8680 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8681 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8682 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8683 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8684 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8685 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8686
8687 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8688 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8689 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8690 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8691 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8692 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8693 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8694 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8695 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8696 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8697 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8698 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8699 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8700 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8701 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8702 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8703 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8704 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8705 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8706 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8707 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8708 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8709 };
8710 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8711 {
8712 TCGv t0 = tcg_temp_new();
8713
8714 switch (opc) {
8715 case OPC_MFC1:
8716 {
8717 TCGv_i32 fp0 = tcg_temp_new_i32();
8718
8719 gen_load_fpr32(ctx, fp0, fs);
8720 tcg_gen_ext_i32_tl(t0, fp0);
8721 tcg_temp_free_i32(fp0);
8722 }
8723 gen_store_gpr(t0, rt);
8724 break;
8725 case OPC_MTC1:
8726 gen_load_gpr(t0, rt);
8727 {
8728 TCGv_i32 fp0 = tcg_temp_new_i32();
8729
8730 tcg_gen_trunc_tl_i32(fp0, t0);
8731 gen_store_fpr32(ctx, fp0, fs);
8732 tcg_temp_free_i32(fp0);
8733 }
8734 break;
8735 case OPC_CFC1:
8736 gen_helper_1e0i(cfc1, t0, fs);
8737 gen_store_gpr(t0, rt);
8738 break;
8739 case OPC_CTC1:
8740 gen_load_gpr(t0, rt);
8741 save_cpu_state(ctx, 0);
8742 {
8743 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8744
8745 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8746 tcg_temp_free_i32(fs_tmp);
8747 }
8748 /* Stop translation as we may have changed hflags */
8749 ctx->bstate = BS_STOP;
8750 break;
8751 #if defined(TARGET_MIPS64)
8752 case OPC_DMFC1:
8753 gen_load_fpr64(ctx, t0, fs);
8754 gen_store_gpr(t0, rt);
8755 break;
8756 case OPC_DMTC1:
8757 gen_load_gpr(t0, rt);
8758 gen_store_fpr64(ctx, t0, fs);
8759 break;
8760 #endif
8761 case OPC_MFHC1:
8762 {
8763 TCGv_i32 fp0 = tcg_temp_new_i32();
8764
8765 gen_load_fpr32h(ctx, fp0, fs);
8766 tcg_gen_ext_i32_tl(t0, fp0);
8767 tcg_temp_free_i32(fp0);
8768 }
8769 gen_store_gpr(t0, rt);
8770 break;
8771 case OPC_MTHC1:
8772 gen_load_gpr(t0, rt);
8773 {
8774 TCGv_i32 fp0 = tcg_temp_new_i32();
8775
8776 tcg_gen_trunc_tl_i32(fp0, t0);
8777 gen_store_fpr32h(ctx, fp0, fs);
8778 tcg_temp_free_i32(fp0);
8779 }
8780 break;
8781 default:
8782 MIPS_INVAL("cp1 move");
8783 generate_exception_end(ctx, EXCP_RI);
8784 goto out;
8785 }
8786
8787 out:
8788 tcg_temp_free(t0);
8789 }
8790
8791 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8792 {
8793 TCGLabel *l1;
8794 TCGCond cond;
8795 TCGv_i32 t0;
8796
8797 if (rd == 0) {
8798 /* Treat as NOP. */
8799 return;
8800 }
8801
8802 if (tf)
8803 cond = TCG_COND_EQ;
8804 else
8805 cond = TCG_COND_NE;
8806
8807 l1 = gen_new_label();
8808 t0 = tcg_temp_new_i32();
8809 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8810 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8811 tcg_temp_free_i32(t0);
8812 if (rs == 0) {
8813 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8814 } else {
8815 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8816 }
8817 gen_set_label(l1);
8818 }
8819
8820 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8821 int tf)
8822 {
8823 int cond;
8824 TCGv_i32 t0 = tcg_temp_new_i32();
8825 TCGLabel *l1 = gen_new_label();
8826
8827 if (tf)
8828 cond = TCG_COND_EQ;
8829 else
8830 cond = TCG_COND_NE;
8831
8832 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8833 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8834 gen_load_fpr32(ctx, t0, fs);
8835 gen_store_fpr32(ctx, t0, fd);
8836 gen_set_label(l1);
8837 tcg_temp_free_i32(t0);
8838 }
8839
8840 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8841 {
8842 int cond;
8843 TCGv_i32 t0 = tcg_temp_new_i32();
8844 TCGv_i64 fp0;
8845 TCGLabel *l1 = gen_new_label();
8846
8847 if (tf)
8848 cond = TCG_COND_EQ;
8849 else
8850 cond = TCG_COND_NE;
8851
8852 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8853 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8854 tcg_temp_free_i32(t0);
8855 fp0 = tcg_temp_new_i64();
8856 gen_load_fpr64(ctx, fp0, fs);
8857 gen_store_fpr64(ctx, fp0, fd);
8858 tcg_temp_free_i64(fp0);
8859 gen_set_label(l1);
8860 }
8861
8862 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8863 int cc, int tf)
8864 {
8865 int cond;
8866 TCGv_i32 t0 = tcg_temp_new_i32();
8867 TCGLabel *l1 = gen_new_label();
8868 TCGLabel *l2 = gen_new_label();
8869
8870 if (tf)
8871 cond = TCG_COND_EQ;
8872 else
8873 cond = TCG_COND_NE;
8874
8875 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8876 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8877 gen_load_fpr32(ctx, t0, fs);
8878 gen_store_fpr32(ctx, t0, fd);
8879 gen_set_label(l1);
8880
8881 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8882 tcg_gen_brcondi_i32(cond, t0, 0, l2);
8883 gen_load_fpr32h(ctx, t0, fs);
8884 gen_store_fpr32h(ctx, t0, fd);
8885 tcg_temp_free_i32(t0);
8886 gen_set_label(l2);
8887 }
8888
8889 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8890 int fs)
8891 {
8892 TCGv_i32 t1 = tcg_const_i32(0);
8893 TCGv_i32 fp0 = tcg_temp_new_i32();
8894 TCGv_i32 fp1 = tcg_temp_new_i32();
8895 TCGv_i32 fp2 = tcg_temp_new_i32();
8896 gen_load_fpr32(ctx, fp0, fd);
8897 gen_load_fpr32(ctx, fp1, ft);
8898 gen_load_fpr32(ctx, fp2, fs);
8899
8900 switch (op1) {
8901 case OPC_SEL_S:
8902 tcg_gen_andi_i32(fp0, fp0, 1);
8903 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8904 break;
8905 case OPC_SELEQZ_S:
8906 tcg_gen_andi_i32(fp1, fp1, 1);
8907 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8908 break;
8909 case OPC_SELNEZ_S:
8910 tcg_gen_andi_i32(fp1, fp1, 1);
8911 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8912 break;
8913 default:
8914 MIPS_INVAL("gen_sel_s");
8915 generate_exception_end(ctx, EXCP_RI);
8916 break;
8917 }
8918
8919 gen_store_fpr32(ctx, fp0, fd);
8920 tcg_temp_free_i32(fp2);
8921 tcg_temp_free_i32(fp1);
8922 tcg_temp_free_i32(fp0);
8923 tcg_temp_free_i32(t1);
8924 }
8925
8926 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8927 int fs)
8928 {
8929 TCGv_i64 t1 = tcg_const_i64(0);
8930 TCGv_i64 fp0 = tcg_temp_new_i64();
8931 TCGv_i64 fp1 = tcg_temp_new_i64();
8932 TCGv_i64 fp2 = tcg_temp_new_i64();
8933 gen_load_fpr64(ctx, fp0, fd);
8934 gen_load_fpr64(ctx, fp1, ft);
8935 gen_load_fpr64(ctx, fp2, fs);
8936
8937 switch (op1) {
8938 case OPC_SEL_D:
8939 tcg_gen_andi_i64(fp0, fp0, 1);
8940 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8941 break;
8942 case OPC_SELEQZ_D:
8943 tcg_gen_andi_i64(fp1, fp1, 1);
8944 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8945 break;
8946 case OPC_SELNEZ_D:
8947 tcg_gen_andi_i64(fp1, fp1, 1);
8948 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8949 break;
8950 default:
8951 MIPS_INVAL("gen_sel_d");
8952 generate_exception_end(ctx, EXCP_RI);
8953 break;
8954 }
8955
8956 gen_store_fpr64(ctx, fp0, fd);
8957 tcg_temp_free_i64(fp2);
8958 tcg_temp_free_i64(fp1);
8959 tcg_temp_free_i64(fp0);
8960 tcg_temp_free_i64(t1);
8961 }
8962
8963 static void gen_farith (DisasContext *ctx, enum fopcode op1,
8964 int ft, int fs, int fd, int cc)
8965 {
8966 uint32_t func = ctx->opcode & 0x3f;
8967 switch (op1) {
8968 case OPC_ADD_S:
8969 {
8970 TCGv_i32 fp0 = tcg_temp_new_i32();
8971 TCGv_i32 fp1 = tcg_temp_new_i32();
8972
8973 gen_load_fpr32(ctx, fp0, fs);
8974 gen_load_fpr32(ctx, fp1, ft);
8975 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8976 tcg_temp_free_i32(fp1);
8977 gen_store_fpr32(ctx, fp0, fd);
8978 tcg_temp_free_i32(fp0);
8979 }
8980 break;
8981 case OPC_SUB_S:
8982 {
8983 TCGv_i32 fp0 = tcg_temp_new_i32();
8984 TCGv_i32 fp1 = tcg_temp_new_i32();
8985
8986 gen_load_fpr32(ctx, fp0, fs);
8987 gen_load_fpr32(ctx, fp1, ft);
8988 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8989 tcg_temp_free_i32(fp1);
8990 gen_store_fpr32(ctx, fp0, fd);
8991 tcg_temp_free_i32(fp0);
8992 }
8993 break;
8994 case OPC_MUL_S:
8995 {
8996 TCGv_i32 fp0 = tcg_temp_new_i32();
8997 TCGv_i32 fp1 = tcg_temp_new_i32();
8998
8999 gen_load_fpr32(ctx, fp0, fs);
9000 gen_load_fpr32(ctx, fp1, ft);
9001 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9002 tcg_temp_free_i32(fp1);
9003 gen_store_fpr32(ctx, fp0, fd);
9004 tcg_temp_free_i32(fp0);
9005 }
9006 break;
9007 case OPC_DIV_S:
9008 {
9009 TCGv_i32 fp0 = tcg_temp_new_i32();
9010 TCGv_i32 fp1 = tcg_temp_new_i32();
9011
9012 gen_load_fpr32(ctx, fp0, fs);
9013 gen_load_fpr32(ctx, fp1, ft);
9014 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9015 tcg_temp_free_i32(fp1);
9016 gen_store_fpr32(ctx, fp0, fd);
9017 tcg_temp_free_i32(fp0);
9018 }
9019 break;
9020 case OPC_SQRT_S:
9021 {
9022 TCGv_i32 fp0 = tcg_temp_new_i32();
9023
9024 gen_load_fpr32(ctx, fp0, fs);
9025 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9026 gen_store_fpr32(ctx, fp0, fd);
9027 tcg_temp_free_i32(fp0);
9028 }
9029 break;
9030 case OPC_ABS_S:
9031 {
9032 TCGv_i32 fp0 = tcg_temp_new_i32();
9033
9034 gen_load_fpr32(ctx, fp0, fs);
9035 if (ctx->abs2008) {
9036 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9037 } else {
9038 gen_helper_float_abs_s(fp0, fp0);
9039 }
9040 gen_store_fpr32(ctx, fp0, fd);
9041 tcg_temp_free_i32(fp0);
9042 }
9043 break;
9044 case OPC_MOV_S:
9045 {
9046 TCGv_i32 fp0 = tcg_temp_new_i32();
9047
9048 gen_load_fpr32(ctx, fp0, fs);
9049 gen_store_fpr32(ctx, fp0, fd);
9050 tcg_temp_free_i32(fp0);
9051 }
9052 break;
9053 case OPC_NEG_S:
9054 {
9055 TCGv_i32 fp0 = tcg_temp_new_i32();
9056
9057 gen_load_fpr32(ctx, fp0, fs);
9058 if (ctx->abs2008) {
9059 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9060 } else {
9061 gen_helper_float_chs_s(fp0, fp0);
9062 }
9063 gen_store_fpr32(ctx, fp0, fd);
9064 tcg_temp_free_i32(fp0);
9065 }
9066 break;
9067 case OPC_ROUND_L_S:
9068 check_cp1_64bitmode(ctx);
9069 {
9070 TCGv_i32 fp32 = tcg_temp_new_i32();
9071 TCGv_i64 fp64 = tcg_temp_new_i64();
9072
9073 gen_load_fpr32(ctx, fp32, fs);
9074 if (ctx->nan2008) {
9075 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9076 } else {
9077 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9078 }
9079 tcg_temp_free_i32(fp32);
9080 gen_store_fpr64(ctx, fp64, fd);
9081 tcg_temp_free_i64(fp64);
9082 }
9083 break;
9084 case OPC_TRUNC_L_S:
9085 check_cp1_64bitmode(ctx);
9086 {
9087 TCGv_i32 fp32 = tcg_temp_new_i32();
9088 TCGv_i64 fp64 = tcg_temp_new_i64();
9089
9090 gen_load_fpr32(ctx, fp32, fs);
9091 if (ctx->nan2008) {
9092 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
9093 } else {
9094 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
9095 }
9096 tcg_temp_free_i32(fp32);
9097 gen_store_fpr64(ctx, fp64, fd);
9098 tcg_temp_free_i64(fp64);
9099 }
9100 break;
9101 case OPC_CEIL_L_S:
9102 check_cp1_64bitmode(ctx);
9103 {
9104 TCGv_i32 fp32 = tcg_temp_new_i32();
9105 TCGv_i64 fp64 = tcg_temp_new_i64();
9106
9107 gen_load_fpr32(ctx, fp32, fs);
9108 if (ctx->nan2008) {
9109 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
9110 } else {
9111 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
9112 }
9113 tcg_temp_free_i32(fp32);
9114 gen_store_fpr64(ctx, fp64, fd);
9115 tcg_temp_free_i64(fp64);
9116 }
9117 break;
9118 case OPC_FLOOR_L_S:
9119 check_cp1_64bitmode(ctx);
9120 {
9121 TCGv_i32 fp32 = tcg_temp_new_i32();
9122 TCGv_i64 fp64 = tcg_temp_new_i64();
9123
9124 gen_load_fpr32(ctx, fp32, fs);
9125 if (ctx->nan2008) {
9126 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
9127 } else {
9128 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
9129 }
9130 tcg_temp_free_i32(fp32);
9131 gen_store_fpr64(ctx, fp64, fd);
9132 tcg_temp_free_i64(fp64);
9133 }
9134 break;
9135 case OPC_ROUND_W_S:
9136 {
9137 TCGv_i32 fp0 = tcg_temp_new_i32();
9138
9139 gen_load_fpr32(ctx, fp0, fs);
9140 if (ctx->nan2008) {
9141 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9142 } else {
9143 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9144 }
9145 gen_store_fpr32(ctx, fp0, fd);
9146 tcg_temp_free_i32(fp0);
9147 }
9148 break;
9149 case OPC_TRUNC_W_S:
9150 {
9151 TCGv_i32 fp0 = tcg_temp_new_i32();
9152
9153 gen_load_fpr32(ctx, fp0, fs);
9154 if (ctx->nan2008) {
9155 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9156 } else {
9157 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9158 }
9159 gen_store_fpr32(ctx, fp0, fd);
9160 tcg_temp_free_i32(fp0);
9161 }
9162 break;
9163 case OPC_CEIL_W_S:
9164 {
9165 TCGv_i32 fp0 = tcg_temp_new_i32();
9166
9167 gen_load_fpr32(ctx, fp0, fs);
9168 if (ctx->nan2008) {
9169 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9170 } else {
9171 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9172 }
9173 gen_store_fpr32(ctx, fp0, fd);
9174 tcg_temp_free_i32(fp0);
9175 }
9176 break;
9177 case OPC_FLOOR_W_S:
9178 {
9179 TCGv_i32 fp0 = tcg_temp_new_i32();
9180
9181 gen_load_fpr32(ctx, fp0, fs);
9182 if (ctx->nan2008) {
9183 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9184 } else {
9185 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9186 }
9187 gen_store_fpr32(ctx, fp0, fd);
9188 tcg_temp_free_i32(fp0);
9189 }
9190 break;
9191 case OPC_SEL_S:
9192 check_insn(ctx, ISA_MIPS32R6);
9193 gen_sel_s(ctx, op1, fd, ft, fs);
9194 break;
9195 case OPC_SELEQZ_S:
9196 check_insn(ctx, ISA_MIPS32R6);
9197 gen_sel_s(ctx, op1, fd, ft, fs);
9198 break;
9199 case OPC_SELNEZ_S:
9200 check_insn(ctx, ISA_MIPS32R6);
9201 gen_sel_s(ctx, op1, fd, ft, fs);
9202 break;
9203 case OPC_MOVCF_S:
9204 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9205 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9206 break;
9207 case OPC_MOVZ_S:
9208 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9209 {
9210 TCGLabel *l1 = gen_new_label();
9211 TCGv_i32 fp0;
9212
9213 if (ft != 0) {
9214 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9215 }
9216 fp0 = tcg_temp_new_i32();
9217 gen_load_fpr32(ctx, fp0, fs);
9218 gen_store_fpr32(ctx, fp0, fd);
9219 tcg_temp_free_i32(fp0);
9220 gen_set_label(l1);
9221 }
9222 break;
9223 case OPC_MOVN_S:
9224 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9225 {
9226 TCGLabel *l1 = gen_new_label();
9227 TCGv_i32 fp0;
9228
9229 if (ft != 0) {
9230 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9231 fp0 = tcg_temp_new_i32();
9232 gen_load_fpr32(ctx, fp0, fs);
9233 gen_store_fpr32(ctx, fp0, fd);
9234 tcg_temp_free_i32(fp0);
9235 gen_set_label(l1);
9236 }
9237 }
9238 break;
9239 case OPC_RECIP_S:
9240 {
9241 TCGv_i32 fp0 = tcg_temp_new_i32();
9242
9243 gen_load_fpr32(ctx, fp0, fs);
9244 gen_helper_float_recip_s(fp0, cpu_env, fp0);
9245 gen_store_fpr32(ctx, fp0, fd);
9246 tcg_temp_free_i32(fp0);
9247 }
9248 break;
9249 case OPC_RSQRT_S:
9250 {
9251 TCGv_i32 fp0 = tcg_temp_new_i32();
9252
9253 gen_load_fpr32(ctx, fp0, fs);
9254 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
9255 gen_store_fpr32(ctx, fp0, fd);
9256 tcg_temp_free_i32(fp0);
9257 }
9258 break;
9259 case OPC_MADDF_S:
9260 check_insn(ctx, ISA_MIPS32R6);
9261 {
9262 TCGv_i32 fp0 = tcg_temp_new_i32();
9263 TCGv_i32 fp1 = tcg_temp_new_i32();
9264 TCGv_i32 fp2 = tcg_temp_new_i32();
9265 gen_load_fpr32(ctx, fp0, fs);
9266 gen_load_fpr32(ctx, fp1, ft);
9267 gen_load_fpr32(ctx, fp2, fd);
9268 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
9269 gen_store_fpr32(ctx, fp2, fd);
9270 tcg_temp_free_i32(fp2);
9271 tcg_temp_free_i32(fp1);
9272 tcg_temp_free_i32(fp0);
9273 }
9274 break;
9275 case OPC_MSUBF_S:
9276 check_insn(ctx, ISA_MIPS32R6);
9277 {
9278 TCGv_i32 fp0 = tcg_temp_new_i32();
9279 TCGv_i32 fp1 = tcg_temp_new_i32();
9280 TCGv_i32 fp2 = tcg_temp_new_i32();
9281 gen_load_fpr32(ctx, fp0, fs);
9282 gen_load_fpr32(ctx, fp1, ft);
9283 gen_load_fpr32(ctx, fp2, fd);
9284 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9285 gen_store_fpr32(ctx, fp2, fd);
9286 tcg_temp_free_i32(fp2);
9287 tcg_temp_free_i32(fp1);
9288 tcg_temp_free_i32(fp0);
9289 }
9290 break;
9291 case OPC_RINT_S:
9292 check_insn(ctx, ISA_MIPS32R6);
9293 {
9294 TCGv_i32 fp0 = tcg_temp_new_i32();
9295 gen_load_fpr32(ctx, fp0, fs);
9296 gen_helper_float_rint_s(fp0, cpu_env, fp0);
9297 gen_store_fpr32(ctx, fp0, fd);
9298 tcg_temp_free_i32(fp0);
9299 }
9300 break;
9301 case OPC_CLASS_S:
9302 check_insn(ctx, ISA_MIPS32R6);
9303 {
9304 TCGv_i32 fp0 = tcg_temp_new_i32();
9305 gen_load_fpr32(ctx, fp0, fs);
9306 gen_helper_float_class_s(fp0, cpu_env, fp0);
9307 gen_store_fpr32(ctx, fp0, fd);
9308 tcg_temp_free_i32(fp0);
9309 }
9310 break;
9311 case OPC_MIN_S: /* OPC_RECIP2_S */
9312 if (ctx->insn_flags & ISA_MIPS32R6) {
9313 /* OPC_MIN_S */
9314 TCGv_i32 fp0 = tcg_temp_new_i32();
9315 TCGv_i32 fp1 = tcg_temp_new_i32();
9316 TCGv_i32 fp2 = tcg_temp_new_i32();
9317 gen_load_fpr32(ctx, fp0, fs);
9318 gen_load_fpr32(ctx, fp1, ft);
9319 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9320 gen_store_fpr32(ctx, fp2, fd);
9321 tcg_temp_free_i32(fp2);
9322 tcg_temp_free_i32(fp1);
9323 tcg_temp_free_i32(fp0);
9324 } else {
9325 /* OPC_RECIP2_S */
9326 check_cp1_64bitmode(ctx);
9327 {
9328 TCGv_i32 fp0 = tcg_temp_new_i32();
9329 TCGv_i32 fp1 = tcg_temp_new_i32();
9330
9331 gen_load_fpr32(ctx, fp0, fs);
9332 gen_load_fpr32(ctx, fp1, ft);
9333 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9334 tcg_temp_free_i32(fp1);
9335 gen_store_fpr32(ctx, fp0, fd);
9336 tcg_temp_free_i32(fp0);
9337 }
9338 }
9339 break;
9340 case OPC_MINA_S: /* OPC_RECIP1_S */
9341 if (ctx->insn_flags & ISA_MIPS32R6) {
9342 /* OPC_MINA_S */
9343 TCGv_i32 fp0 = tcg_temp_new_i32();
9344 TCGv_i32 fp1 = tcg_temp_new_i32();
9345 TCGv_i32 fp2 = tcg_temp_new_i32();
9346 gen_load_fpr32(ctx, fp0, fs);
9347 gen_load_fpr32(ctx, fp1, ft);
9348 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9349 gen_store_fpr32(ctx, fp2, fd);
9350 tcg_temp_free_i32(fp2);
9351 tcg_temp_free_i32(fp1);
9352 tcg_temp_free_i32(fp0);
9353 } else {
9354 /* OPC_RECIP1_S */
9355 check_cp1_64bitmode(ctx);
9356 {
9357 TCGv_i32 fp0 = tcg_temp_new_i32();
9358
9359 gen_load_fpr32(ctx, fp0, fs);
9360 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9361 gen_store_fpr32(ctx, fp0, fd);
9362 tcg_temp_free_i32(fp0);
9363 }
9364 }
9365 break;
9366 case OPC_MAX_S: /* OPC_RSQRT1_S */
9367 if (ctx->insn_flags & ISA_MIPS32R6) {
9368 /* OPC_MAX_S */
9369 TCGv_i32 fp0 = tcg_temp_new_i32();
9370 TCGv_i32 fp1 = tcg_temp_new_i32();
9371 gen_load_fpr32(ctx, fp0, fs);
9372 gen_load_fpr32(ctx, fp1, ft);
9373 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9374 gen_store_fpr32(ctx, fp1, fd);
9375 tcg_temp_free_i32(fp1);
9376 tcg_temp_free_i32(fp0);
9377 } else {
9378 /* OPC_RSQRT1_S */
9379 check_cp1_64bitmode(ctx);
9380 {
9381 TCGv_i32 fp0 = tcg_temp_new_i32();
9382
9383 gen_load_fpr32(ctx, fp0, fs);
9384 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9385 gen_store_fpr32(ctx, fp0, fd);
9386 tcg_temp_free_i32(fp0);
9387 }
9388 }
9389 break;
9390 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9391 if (ctx->insn_flags & ISA_MIPS32R6) {
9392 /* OPC_MAXA_S */
9393 TCGv_i32 fp0 = tcg_temp_new_i32();
9394 TCGv_i32 fp1 = tcg_temp_new_i32();
9395 gen_load_fpr32(ctx, fp0, fs);
9396 gen_load_fpr32(ctx, fp1, ft);
9397 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9398 gen_store_fpr32(ctx, fp1, fd);
9399 tcg_temp_free_i32(fp1);
9400 tcg_temp_free_i32(fp0);
9401 } else {
9402 /* OPC_RSQRT2_S */
9403 check_cp1_64bitmode(ctx);
9404 {
9405 TCGv_i32 fp0 = tcg_temp_new_i32();
9406 TCGv_i32 fp1 = tcg_temp_new_i32();
9407
9408 gen_load_fpr32(ctx, fp0, fs);
9409 gen_load_fpr32(ctx, fp1, ft);
9410 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9411 tcg_temp_free_i32(fp1);
9412 gen_store_fpr32(ctx, fp0, fd);
9413 tcg_temp_free_i32(fp0);
9414 }
9415 }
9416 break;
9417 case OPC_CVT_D_S:
9418 check_cp1_registers(ctx, fd);
9419 {
9420 TCGv_i32 fp32 = tcg_temp_new_i32();
9421 TCGv_i64 fp64 = tcg_temp_new_i64();
9422
9423 gen_load_fpr32(ctx, fp32, fs);
9424 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9425 tcg_temp_free_i32(fp32);
9426 gen_store_fpr64(ctx, fp64, fd);
9427 tcg_temp_free_i64(fp64);
9428 }
9429 break;
9430 case OPC_CVT_W_S:
9431 {
9432 TCGv_i32 fp0 = tcg_temp_new_i32();
9433
9434 gen_load_fpr32(ctx, fp0, fs);
9435 if (ctx->nan2008) {
9436 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9437 } else {
9438 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9439 }
9440 gen_store_fpr32(ctx, fp0, fd);
9441 tcg_temp_free_i32(fp0);
9442 }
9443 break;
9444 case OPC_CVT_L_S:
9445 check_cp1_64bitmode(ctx);
9446 {
9447 TCGv_i32 fp32 = tcg_temp_new_i32();
9448 TCGv_i64 fp64 = tcg_temp_new_i64();
9449
9450 gen_load_fpr32(ctx, fp32, fs);
9451 if (ctx->nan2008) {
9452 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9453 } else {
9454 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9455 }
9456 tcg_temp_free_i32(fp32);
9457 gen_store_fpr64(ctx, fp64, fd);
9458 tcg_temp_free_i64(fp64);
9459 }
9460 break;
9461 case OPC_CVT_PS_S:
9462 check_ps(ctx);
9463 {
9464 TCGv_i64 fp64 = tcg_temp_new_i64();
9465 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9466 TCGv_i32 fp32_1 = tcg_temp_new_i32();
9467
9468 gen_load_fpr32(ctx, fp32_0, fs);
9469 gen_load_fpr32(ctx, fp32_1, ft);
9470 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9471 tcg_temp_free_i32(fp32_1);
9472 tcg_temp_free_i32(fp32_0);
9473 gen_store_fpr64(ctx, fp64, fd);
9474 tcg_temp_free_i64(fp64);
9475 }
9476 break;
9477 case OPC_CMP_F_S:
9478 case OPC_CMP_UN_S:
9479 case OPC_CMP_EQ_S:
9480 case OPC_CMP_UEQ_S:
9481 case OPC_CMP_OLT_S:
9482 case OPC_CMP_ULT_S:
9483 case OPC_CMP_OLE_S:
9484 case OPC_CMP_ULE_S:
9485 case OPC_CMP_SF_S:
9486 case OPC_CMP_NGLE_S:
9487 case OPC_CMP_SEQ_S:
9488 case OPC_CMP_NGL_S:
9489 case OPC_CMP_LT_S:
9490 case OPC_CMP_NGE_S:
9491 case OPC_CMP_LE_S:
9492 case OPC_CMP_NGT_S:
9493 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9494 if (ctx->opcode & (1 << 6)) {
9495 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9496 } else {
9497 gen_cmp_s(ctx, func-48, ft, fs, cc);
9498 }
9499 break;
9500 case OPC_ADD_D:
9501 check_cp1_registers(ctx, fs | ft | fd);
9502 {
9503 TCGv_i64 fp0 = tcg_temp_new_i64();
9504 TCGv_i64 fp1 = tcg_temp_new_i64();
9505
9506 gen_load_fpr64(ctx, fp0, fs);
9507 gen_load_fpr64(ctx, fp1, ft);
9508 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9509 tcg_temp_free_i64(fp1);
9510 gen_store_fpr64(ctx, fp0, fd);
9511 tcg_temp_free_i64(fp0);
9512 }
9513 break;
9514 case OPC_SUB_D:
9515 check_cp1_registers(ctx, fs | ft | fd);
9516 {
9517 TCGv_i64 fp0 = tcg_temp_new_i64();
9518 TCGv_i64 fp1 = tcg_temp_new_i64();
9519
9520 gen_load_fpr64(ctx, fp0, fs);
9521 gen_load_fpr64(ctx, fp1, ft);
9522 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9523 tcg_temp_free_i64(fp1);
9524 gen_store_fpr64(ctx, fp0, fd);
9525 tcg_temp_free_i64(fp0);
9526 }
9527 break;
9528 case OPC_MUL_D:
9529 check_cp1_registers(ctx, fs | ft | fd);
9530 {
9531 TCGv_i64 fp0 = tcg_temp_new_i64();
9532 TCGv_i64 fp1 = tcg_temp_new_i64();
9533
9534 gen_load_fpr64(ctx, fp0, fs);
9535 gen_load_fpr64(ctx, fp1, ft);
9536 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9537 tcg_temp_free_i64(fp1);
9538 gen_store_fpr64(ctx, fp0, fd);
9539 tcg_temp_free_i64(fp0);
9540 }
9541 break;
9542 case OPC_DIV_D:
9543 check_cp1_registers(ctx, fs | ft | fd);
9544 {
9545 TCGv_i64 fp0 = tcg_temp_new_i64();
9546 TCGv_i64 fp1 = tcg_temp_new_i64();
9547
9548 gen_load_fpr64(ctx, fp0, fs);
9549 gen_load_fpr64(ctx, fp1, ft);
9550 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9551 tcg_temp_free_i64(fp1);
9552 gen_store_fpr64(ctx, fp0, fd);
9553 tcg_temp_free_i64(fp0);
9554 }
9555 break;
9556 case OPC_SQRT_D:
9557 check_cp1_registers(ctx, fs | fd);
9558 {
9559 TCGv_i64 fp0 = tcg_temp_new_i64();
9560
9561 gen_load_fpr64(ctx, fp0, fs);
9562 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9563 gen_store_fpr64(ctx, fp0, fd);
9564 tcg_temp_free_i64(fp0);
9565 }
9566 break;
9567 case OPC_ABS_D:
9568 check_cp1_registers(ctx, fs | fd);
9569 {
9570 TCGv_i64 fp0 = tcg_temp_new_i64();
9571
9572 gen_load_fpr64(ctx, fp0, fs);
9573 if (ctx->abs2008) {
9574 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9575 } else {
9576 gen_helper_float_abs_d(fp0, fp0);
9577 }
9578 gen_store_fpr64(ctx, fp0, fd);
9579 tcg_temp_free_i64(fp0);
9580 }
9581 break;
9582 case OPC_MOV_D:
9583 check_cp1_registers(ctx, fs | fd);
9584 {
9585 TCGv_i64 fp0 = tcg_temp_new_i64();
9586
9587 gen_load_fpr64(ctx, fp0, fs);
9588 gen_store_fpr64(ctx, fp0, fd);
9589 tcg_temp_free_i64(fp0);
9590 }
9591 break;
9592 case OPC_NEG_D:
9593 check_cp1_registers(ctx, fs | fd);
9594 {
9595 TCGv_i64 fp0 = tcg_temp_new_i64();
9596
9597 gen_load_fpr64(ctx, fp0, fs);
9598 if (ctx->abs2008) {
9599 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9600 } else {
9601 gen_helper_float_chs_d(fp0, fp0);
9602 }
9603 gen_store_fpr64(ctx, fp0, fd);
9604 tcg_temp_free_i64(fp0);
9605 }
9606 break;
9607 case OPC_ROUND_L_D:
9608 check_cp1_64bitmode(ctx);
9609 {
9610 TCGv_i64 fp0 = tcg_temp_new_i64();
9611
9612 gen_load_fpr64(ctx, fp0, fs);
9613 if (ctx->nan2008) {
9614 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9615 } else {
9616 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9617 }
9618 gen_store_fpr64(ctx, fp0, fd);
9619 tcg_temp_free_i64(fp0);
9620 }
9621 break;
9622 case OPC_TRUNC_L_D:
9623 check_cp1_64bitmode(ctx);
9624 {
9625 TCGv_i64 fp0 = tcg_temp_new_i64();
9626
9627 gen_load_fpr64(ctx, fp0, fs);
9628 if (ctx->nan2008) {
9629 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9630 } else {
9631 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9632 }
9633 gen_store_fpr64(ctx, fp0, fd);
9634 tcg_temp_free_i64(fp0);
9635 }
9636 break;
9637 case OPC_CEIL_L_D:
9638 check_cp1_64bitmode(ctx);
9639 {
9640 TCGv_i64 fp0 = tcg_temp_new_i64();
9641
9642 gen_load_fpr64(ctx, fp0, fs);
9643 if (ctx->nan2008) {
9644 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9645 } else {
9646 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9647 }
9648 gen_store_fpr64(ctx, fp0, fd);
9649 tcg_temp_free_i64(fp0);
9650 }
9651 break;
9652 case OPC_FLOOR_L_D:
9653 check_cp1_64bitmode(ctx);
9654 {
9655 TCGv_i64 fp0 = tcg_temp_new_i64();
9656
9657 gen_load_fpr64(ctx, fp0, fs);
9658 if (ctx->nan2008) {
9659 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9660 } else {
9661 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9662 }
9663 gen_store_fpr64(ctx, fp0, fd);
9664 tcg_temp_free_i64(fp0);
9665 }
9666 break;
9667 case OPC_ROUND_W_D:
9668 check_cp1_registers(ctx, fs);
9669 {
9670 TCGv_i32 fp32 = tcg_temp_new_i32();
9671 TCGv_i64 fp64 = tcg_temp_new_i64();
9672
9673 gen_load_fpr64(ctx, fp64, fs);
9674 if (ctx->nan2008) {
9675 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9676 } else {
9677 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9678 }
9679 tcg_temp_free_i64(fp64);
9680 gen_store_fpr32(ctx, fp32, fd);
9681 tcg_temp_free_i32(fp32);
9682 }
9683 break;
9684 case OPC_TRUNC_W_D:
9685 check_cp1_registers(ctx, fs);
9686 {
9687 TCGv_i32 fp32 = tcg_temp_new_i32();
9688 TCGv_i64 fp64 = tcg_temp_new_i64();
9689
9690 gen_load_fpr64(ctx, fp64, fs);
9691 if (ctx->nan2008) {
9692 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9693 } else {
9694 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9695 }
9696 tcg_temp_free_i64(fp64);
9697 gen_store_fpr32(ctx, fp32, fd);
9698 tcg_temp_free_i32(fp32);
9699 }
9700 break;
9701 case OPC_CEIL_W_D:
9702 check_cp1_registers(ctx, fs);
9703 {
9704 TCGv_i32 fp32 = tcg_temp_new_i32();
9705 TCGv_i64 fp64 = tcg_temp_new_i64();
9706
9707 gen_load_fpr64(ctx, fp64, fs);
9708 if (ctx->nan2008) {
9709 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9710 } else {
9711 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9712 }
9713 tcg_temp_free_i64(fp64);
9714 gen_store_fpr32(ctx, fp32, fd);
9715 tcg_temp_free_i32(fp32);
9716 }
9717 break;
9718 case OPC_FLOOR_W_D:
9719 check_cp1_registers(ctx, fs);
9720 {
9721 TCGv_i32 fp32 = tcg_temp_new_i32();
9722 TCGv_i64 fp64 = tcg_temp_new_i64();
9723
9724 gen_load_fpr64(ctx, fp64, fs);
9725 if (ctx->nan2008) {
9726 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9727 } else {
9728 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9729 }
9730 tcg_temp_free_i64(fp64);
9731 gen_store_fpr32(ctx, fp32, fd);
9732 tcg_temp_free_i32(fp32);
9733 }
9734 break;
9735 case OPC_SEL_D:
9736 check_insn(ctx, ISA_MIPS32R6);
9737 gen_sel_d(ctx, op1, fd, ft, fs);
9738 break;
9739 case OPC_SELEQZ_D:
9740 check_insn(ctx, ISA_MIPS32R6);
9741 gen_sel_d(ctx, op1, fd, ft, fs);
9742 break;
9743 case OPC_SELNEZ_D:
9744 check_insn(ctx, ISA_MIPS32R6);
9745 gen_sel_d(ctx, op1, fd, ft, fs);
9746 break;
9747 case OPC_MOVCF_D:
9748 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9749 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9750 break;
9751 case OPC_MOVZ_D:
9752 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9753 {
9754 TCGLabel *l1 = gen_new_label();
9755 TCGv_i64 fp0;
9756
9757 if (ft != 0) {
9758 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9759 }
9760 fp0 = tcg_temp_new_i64();
9761 gen_load_fpr64(ctx, fp0, fs);
9762 gen_store_fpr64(ctx, fp0, fd);
9763 tcg_temp_free_i64(fp0);
9764 gen_set_label(l1);
9765 }
9766 break;
9767 case OPC_MOVN_D:
9768 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9769 {
9770 TCGLabel *l1 = gen_new_label();
9771 TCGv_i64 fp0;
9772
9773 if (ft != 0) {
9774 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9775 fp0 = tcg_temp_new_i64();
9776 gen_load_fpr64(ctx, fp0, fs);
9777 gen_store_fpr64(ctx, fp0, fd);
9778 tcg_temp_free_i64(fp0);
9779 gen_set_label(l1);
9780 }
9781 }
9782 break;
9783 case OPC_RECIP_D:
9784 check_cp1_registers(ctx, fs | fd);
9785 {
9786 TCGv_i64 fp0 = tcg_temp_new_i64();
9787
9788 gen_load_fpr64(ctx, fp0, fs);
9789 gen_helper_float_recip_d(fp0, cpu_env, fp0);
9790 gen_store_fpr64(ctx, fp0, fd);
9791 tcg_temp_free_i64(fp0);
9792 }
9793 break;
9794 case OPC_RSQRT_D:
9795 check_cp1_registers(ctx, fs | fd);
9796 {
9797 TCGv_i64 fp0 = tcg_temp_new_i64();
9798
9799 gen_load_fpr64(ctx, fp0, fs);
9800 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9801 gen_store_fpr64(ctx, fp0, fd);
9802 tcg_temp_free_i64(fp0);
9803 }
9804 break;
9805 case OPC_MADDF_D:
9806 check_insn(ctx, ISA_MIPS32R6);
9807 {
9808 TCGv_i64 fp0 = tcg_temp_new_i64();
9809 TCGv_i64 fp1 = tcg_temp_new_i64();
9810 TCGv_i64 fp2 = tcg_temp_new_i64();
9811 gen_load_fpr64(ctx, fp0, fs);
9812 gen_load_fpr64(ctx, fp1, ft);
9813 gen_load_fpr64(ctx, fp2, fd);
9814 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9815 gen_store_fpr64(ctx, fp2, fd);
9816 tcg_temp_free_i64(fp2);
9817 tcg_temp_free_i64(fp1);
9818 tcg_temp_free_i64(fp0);
9819 }
9820 break;
9821 case OPC_MSUBF_D:
9822 check_insn(ctx, ISA_MIPS32R6);
9823 {
9824 TCGv_i64 fp0 = tcg_temp_new_i64();
9825 TCGv_i64 fp1 = tcg_temp_new_i64();
9826 TCGv_i64 fp2 = tcg_temp_new_i64();
9827 gen_load_fpr64(ctx, fp0, fs);
9828 gen_load_fpr64(ctx, fp1, ft);
9829 gen_load_fpr64(ctx, fp2, fd);
9830 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9831 gen_store_fpr64(ctx, fp2, fd);
9832 tcg_temp_free_i64(fp2);
9833 tcg_temp_free_i64(fp1);
9834 tcg_temp_free_i64(fp0);
9835 }
9836 break;
9837 case OPC_RINT_D:
9838 check_insn(ctx, ISA_MIPS32R6);
9839 {
9840 TCGv_i64 fp0 = tcg_temp_new_i64();
9841 gen_load_fpr64(ctx, fp0, fs);
9842 gen_helper_float_rint_d(fp0, cpu_env, fp0);
9843 gen_store_fpr64(ctx, fp0, fd);
9844 tcg_temp_free_i64(fp0);
9845 }
9846 break;
9847 case OPC_CLASS_D:
9848 check_insn(ctx, ISA_MIPS32R6);
9849 {
9850 TCGv_i64 fp0 = tcg_temp_new_i64();
9851 gen_load_fpr64(ctx, fp0, fs);
9852 gen_helper_float_class_d(fp0, cpu_env, fp0);
9853 gen_store_fpr64(ctx, fp0, fd);
9854 tcg_temp_free_i64(fp0);
9855 }
9856 break;
9857 case OPC_MIN_D: /* OPC_RECIP2_D */
9858 if (ctx->insn_flags & ISA_MIPS32R6) {
9859 /* OPC_MIN_D */
9860 TCGv_i64 fp0 = tcg_temp_new_i64();
9861 TCGv_i64 fp1 = tcg_temp_new_i64();
9862 gen_load_fpr64(ctx, fp0, fs);
9863 gen_load_fpr64(ctx, fp1, ft);
9864 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9865 gen_store_fpr64(ctx, fp1, fd);
9866 tcg_temp_free_i64(fp1);
9867 tcg_temp_free_i64(fp0);
9868 } else {
9869 /* OPC_RECIP2_D */
9870 check_cp1_64bitmode(ctx);
9871 {
9872 TCGv_i64 fp0 = tcg_temp_new_i64();
9873 TCGv_i64 fp1 = tcg_temp_new_i64();
9874
9875 gen_load_fpr64(ctx, fp0, fs);
9876 gen_load_fpr64(ctx, fp1, ft);
9877 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9878 tcg_temp_free_i64(fp1);
9879 gen_store_fpr64(ctx, fp0, fd);
9880 tcg_temp_free_i64(fp0);
9881 }
9882 }
9883 break;
9884 case OPC_MINA_D: /* OPC_RECIP1_D */
9885 if (ctx->insn_flags & ISA_MIPS32R6) {
9886 /* OPC_MINA_D */
9887 TCGv_i64 fp0 = tcg_temp_new_i64();
9888 TCGv_i64 fp1 = tcg_temp_new_i64();
9889 gen_load_fpr64(ctx, fp0, fs);
9890 gen_load_fpr64(ctx, fp1, ft);
9891 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9892 gen_store_fpr64(ctx, fp1, fd);
9893 tcg_temp_free_i64(fp1);
9894 tcg_temp_free_i64(fp0);
9895 } else {
9896 /* OPC_RECIP1_D */
9897 check_cp1_64bitmode(ctx);
9898 {
9899 TCGv_i64 fp0 = tcg_temp_new_i64();
9900
9901 gen_load_fpr64(ctx, fp0, fs);
9902 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9903 gen_store_fpr64(ctx, fp0, fd);
9904 tcg_temp_free_i64(fp0);
9905 }
9906 }
9907 break;
9908 case OPC_MAX_D: /* OPC_RSQRT1_D */
9909 if (ctx->insn_flags & ISA_MIPS32R6) {
9910 /* OPC_MAX_D */
9911 TCGv_i64 fp0 = tcg_temp_new_i64();
9912 TCGv_i64 fp1 = tcg_temp_new_i64();
9913 gen_load_fpr64(ctx, fp0, fs);
9914 gen_load_fpr64(ctx, fp1, ft);
9915 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9916 gen_store_fpr64(ctx, fp1, fd);
9917 tcg_temp_free_i64(fp1);
9918 tcg_temp_free_i64(fp0);
9919 } else {
9920 /* OPC_RSQRT1_D */
9921 check_cp1_64bitmode(ctx);
9922 {
9923 TCGv_i64 fp0 = tcg_temp_new_i64();
9924
9925 gen_load_fpr64(ctx, fp0, fs);
9926 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9927 gen_store_fpr64(ctx, fp0, fd);
9928 tcg_temp_free_i64(fp0);
9929 }
9930 }
9931 break;
9932 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9933 if (ctx->insn_flags & ISA_MIPS32R6) {
9934 /* OPC_MAXA_D */
9935 TCGv_i64 fp0 = tcg_temp_new_i64();
9936 TCGv_i64 fp1 = tcg_temp_new_i64();
9937 gen_load_fpr64(ctx, fp0, fs);
9938 gen_load_fpr64(ctx, fp1, ft);
9939 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9940 gen_store_fpr64(ctx, fp1, fd);
9941 tcg_temp_free_i64(fp1);
9942 tcg_temp_free_i64(fp0);
9943 } else {
9944 /* OPC_RSQRT2_D */
9945 check_cp1_64bitmode(ctx);
9946 {
9947 TCGv_i64 fp0 = tcg_temp_new_i64();
9948 TCGv_i64 fp1 = tcg_temp_new_i64();
9949
9950 gen_load_fpr64(ctx, fp0, fs);
9951 gen_load_fpr64(ctx, fp1, ft);
9952 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9953 tcg_temp_free_i64(fp1);
9954 gen_store_fpr64(ctx, fp0, fd);
9955 tcg_temp_free_i64(fp0);
9956 }
9957 }
9958 break;
9959 case OPC_CMP_F_D:
9960 case OPC_CMP_UN_D:
9961 case OPC_CMP_EQ_D:
9962 case OPC_CMP_UEQ_D:
9963 case OPC_CMP_OLT_D:
9964 case OPC_CMP_ULT_D:
9965 case OPC_CMP_OLE_D:
9966 case OPC_CMP_ULE_D:
9967 case OPC_CMP_SF_D:
9968 case OPC_CMP_NGLE_D:
9969 case OPC_CMP_SEQ_D:
9970 case OPC_CMP_NGL_D:
9971 case OPC_CMP_LT_D:
9972 case OPC_CMP_NGE_D:
9973 case OPC_CMP_LE_D:
9974 case OPC_CMP_NGT_D:
9975 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9976 if (ctx->opcode & (1 << 6)) {
9977 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9978 } else {
9979 gen_cmp_d(ctx, func-48, ft, fs, cc);
9980 }
9981 break;
9982 case OPC_CVT_S_D:
9983 check_cp1_registers(ctx, fs);
9984 {
9985 TCGv_i32 fp32 = tcg_temp_new_i32();
9986 TCGv_i64 fp64 = tcg_temp_new_i64();
9987
9988 gen_load_fpr64(ctx, fp64, fs);
9989 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9990 tcg_temp_free_i64(fp64);
9991 gen_store_fpr32(ctx, fp32, fd);
9992 tcg_temp_free_i32(fp32);
9993 }
9994 break;
9995 case OPC_CVT_W_D:
9996 check_cp1_registers(ctx, fs);
9997 {
9998 TCGv_i32 fp32 = tcg_temp_new_i32();
9999 TCGv_i64 fp64 = tcg_temp_new_i64();
10000
10001 gen_load_fpr64(ctx, fp64, fs);
10002 if (ctx->nan2008) {
10003 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10004 } else {
10005 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10006 }
10007 tcg_temp_free_i64(fp64);
10008 gen_store_fpr32(ctx, fp32, fd);
10009 tcg_temp_free_i32(fp32);
10010 }
10011 break;
10012 case OPC_CVT_L_D:
10013 check_cp1_64bitmode(ctx);
10014 {
10015 TCGv_i64 fp0 = tcg_temp_new_i64();
10016
10017 gen_load_fpr64(ctx, fp0, fs);
10018 if (ctx->nan2008) {
10019 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10020 } else {
10021 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10022 }
10023 gen_store_fpr64(ctx, fp0, fd);
10024 tcg_temp_free_i64(fp0);
10025 }
10026 break;
10027 case OPC_CVT_S_W:
10028 {
10029 TCGv_i32 fp0 = tcg_temp_new_i32();
10030
10031 gen_load_fpr32(ctx, fp0, fs);
10032 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
10033 gen_store_fpr32(ctx, fp0, fd);
10034 tcg_temp_free_i32(fp0);
10035 }
10036 break;
10037 case OPC_CVT_D_W:
10038 check_cp1_registers(ctx, fd);
10039 {
10040 TCGv_i32 fp32 = tcg_temp_new_i32();
10041 TCGv_i64 fp64 = tcg_temp_new_i64();
10042
10043 gen_load_fpr32(ctx, fp32, fs);
10044 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
10045 tcg_temp_free_i32(fp32);
10046 gen_store_fpr64(ctx, fp64, fd);
10047 tcg_temp_free_i64(fp64);
10048 }
10049 break;
10050 case OPC_CVT_S_L:
10051 check_cp1_64bitmode(ctx);
10052 {
10053 TCGv_i32 fp32 = tcg_temp_new_i32();
10054 TCGv_i64 fp64 = tcg_temp_new_i64();
10055
10056 gen_load_fpr64(ctx, fp64, fs);
10057 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
10058 tcg_temp_free_i64(fp64);
10059 gen_store_fpr32(ctx, fp32, fd);
10060 tcg_temp_free_i32(fp32);
10061 }
10062 break;
10063 case OPC_CVT_D_L:
10064 check_cp1_64bitmode(ctx);
10065 {
10066 TCGv_i64 fp0 = tcg_temp_new_i64();
10067
10068 gen_load_fpr64(ctx, fp0, fs);
10069 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
10070 gen_store_fpr64(ctx, fp0, fd);
10071 tcg_temp_free_i64(fp0);
10072 }
10073 break;
10074 case OPC_CVT_PS_PW:
10075 check_ps(ctx);
10076 {
10077 TCGv_i64 fp0 = tcg_temp_new_i64();
10078
10079 gen_load_fpr64(ctx, fp0, fs);
10080 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
10081 gen_store_fpr64(ctx, fp0, fd);
10082 tcg_temp_free_i64(fp0);
10083 }
10084 break;
10085 case OPC_ADD_PS:
10086 check_ps(ctx);
10087 {
10088 TCGv_i64 fp0 = tcg_temp_new_i64();
10089 TCGv_i64 fp1 = tcg_temp_new_i64();
10090
10091 gen_load_fpr64(ctx, fp0, fs);
10092 gen_load_fpr64(ctx, fp1, ft);
10093 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
10094 tcg_temp_free_i64(fp1);
10095 gen_store_fpr64(ctx, fp0, fd);
10096 tcg_temp_free_i64(fp0);
10097 }
10098 break;
10099 case OPC_SUB_PS:
10100 check_ps(ctx);
10101 {
10102 TCGv_i64 fp0 = tcg_temp_new_i64();
10103 TCGv_i64 fp1 = tcg_temp_new_i64();
10104
10105 gen_load_fpr64(ctx, fp0, fs);
10106 gen_load_fpr64(ctx, fp1, ft);
10107 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
10108 tcg_temp_free_i64(fp1);
10109 gen_store_fpr64(ctx, fp0, fd);
10110 tcg_temp_free_i64(fp0);
10111 }
10112 break;
10113 case OPC_MUL_PS:
10114 check_ps(ctx);
10115 {
10116 TCGv_i64 fp0 = tcg_temp_new_i64();
10117 TCGv_i64 fp1 = tcg_temp_new_i64();
10118
10119 gen_load_fpr64(ctx, fp0, fs);
10120 gen_load_fpr64(ctx, fp1, ft);
10121 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
10122 tcg_temp_free_i64(fp1);
10123 gen_store_fpr64(ctx, fp0, fd);
10124 tcg_temp_free_i64(fp0);
10125 }
10126 break;
10127 case OPC_ABS_PS:
10128 check_ps(ctx);
10129 {
10130 TCGv_i64 fp0 = tcg_temp_new_i64();
10131
10132 gen_load_fpr64(ctx, fp0, fs);
10133 gen_helper_float_abs_ps(fp0, fp0);
10134 gen_store_fpr64(ctx, fp0, fd);
10135 tcg_temp_free_i64(fp0);
10136 }
10137 break;
10138 case OPC_MOV_PS:
10139 check_ps(ctx);
10140 {
10141 TCGv_i64 fp0 = tcg_temp_new_i64();
10142
10143 gen_load_fpr64(ctx, fp0, fs);
10144 gen_store_fpr64(ctx, fp0, fd);
10145 tcg_temp_free_i64(fp0);
10146 }
10147 break;
10148 case OPC_NEG_PS:
10149 check_ps(ctx);
10150 {
10151 TCGv_i64 fp0 = tcg_temp_new_i64();
10152
10153 gen_load_fpr64(ctx, fp0, fs);
10154 gen_helper_float_chs_ps(fp0, fp0);
10155 gen_store_fpr64(ctx, fp0, fd);
10156 tcg_temp_free_i64(fp0);
10157 }
10158 break;
10159 case OPC_MOVCF_PS:
10160 check_ps(ctx);
10161 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10162 break;
10163 case OPC_MOVZ_PS:
10164 check_ps(ctx);
10165 {
10166 TCGLabel *l1 = gen_new_label();
10167 TCGv_i64 fp0;
10168
10169 if (ft != 0)
10170 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10171 fp0 = tcg_temp_new_i64();
10172 gen_load_fpr64(ctx, fp0, fs);
10173 gen_store_fpr64(ctx, fp0, fd);
10174 tcg_temp_free_i64(fp0);
10175 gen_set_label(l1);
10176 }
10177 break;
10178 case OPC_MOVN_PS:
10179 check_ps(ctx);
10180 {
10181 TCGLabel *l1 = gen_new_label();
10182 TCGv_i64 fp0;
10183
10184 if (ft != 0) {
10185 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10186 fp0 = tcg_temp_new_i64();
10187 gen_load_fpr64(ctx, fp0, fs);
10188 gen_store_fpr64(ctx, fp0, fd);
10189 tcg_temp_free_i64(fp0);
10190 gen_set_label(l1);
10191 }
10192 }
10193 break;
10194 case OPC_ADDR_PS:
10195 check_ps(ctx);
10196 {
10197 TCGv_i64 fp0 = tcg_temp_new_i64();
10198 TCGv_i64 fp1 = tcg_temp_new_i64();
10199
10200 gen_load_fpr64(ctx, fp0, ft);
10201 gen_load_fpr64(ctx, fp1, fs);
10202 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
10203 tcg_temp_free_i64(fp1);
10204 gen_store_fpr64(ctx, fp0, fd);
10205 tcg_temp_free_i64(fp0);
10206 }
10207 break;
10208 case OPC_MULR_PS:
10209 check_ps(ctx);
10210 {
10211 TCGv_i64 fp0 = tcg_temp_new_i64();
10212 TCGv_i64 fp1 = tcg_temp_new_i64();
10213
10214 gen_load_fpr64(ctx, fp0, ft);
10215 gen_load_fpr64(ctx, fp1, fs);
10216 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
10217 tcg_temp_free_i64(fp1);
10218 gen_store_fpr64(ctx, fp0, fd);
10219 tcg_temp_free_i64(fp0);
10220 }
10221 break;
10222 case OPC_RECIP2_PS:
10223 check_ps(ctx);
10224 {
10225 TCGv_i64 fp0 = tcg_temp_new_i64();
10226 TCGv_i64 fp1 = tcg_temp_new_i64();
10227
10228 gen_load_fpr64(ctx, fp0, fs);
10229 gen_load_fpr64(ctx, fp1, ft);
10230 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
10231 tcg_temp_free_i64(fp1);
10232 gen_store_fpr64(ctx, fp0, fd);
10233 tcg_temp_free_i64(fp0);
10234 }
10235 break;
10236 case OPC_RECIP1_PS:
10237 check_ps(ctx);
10238 {
10239 TCGv_i64 fp0 = tcg_temp_new_i64();
10240
10241 gen_load_fpr64(ctx, fp0, fs);
10242 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
10243 gen_store_fpr64(ctx, fp0, fd);
10244 tcg_temp_free_i64(fp0);
10245 }
10246 break;
10247 case OPC_RSQRT1_PS:
10248 check_ps(ctx);
10249 {
10250 TCGv_i64 fp0 = tcg_temp_new_i64();
10251
10252 gen_load_fpr64(ctx, fp0, fs);
10253 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
10254 gen_store_fpr64(ctx, fp0, fd);
10255 tcg_temp_free_i64(fp0);
10256 }
10257 break;
10258 case OPC_RSQRT2_PS:
10259 check_ps(ctx);
10260 {
10261 TCGv_i64 fp0 = tcg_temp_new_i64();
10262 TCGv_i64 fp1 = tcg_temp_new_i64();
10263
10264 gen_load_fpr64(ctx, fp0, fs);
10265 gen_load_fpr64(ctx, fp1, ft);
10266 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
10267 tcg_temp_free_i64(fp1);
10268 gen_store_fpr64(ctx, fp0, fd);
10269 tcg_temp_free_i64(fp0);
10270 }
10271 break;
10272 case OPC_CVT_S_PU:
10273 check_cp1_64bitmode(ctx);
10274 {
10275 TCGv_i32 fp0 = tcg_temp_new_i32();
10276
10277 gen_load_fpr32h(ctx, fp0, fs);
10278 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
10279 gen_store_fpr32(ctx, fp0, fd);
10280 tcg_temp_free_i32(fp0);
10281 }
10282 break;
10283 case OPC_CVT_PW_PS:
10284 check_ps(ctx);
10285 {
10286 TCGv_i64 fp0 = tcg_temp_new_i64();
10287
10288 gen_load_fpr64(ctx, fp0, fs);
10289 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
10290 gen_store_fpr64(ctx, fp0, fd);
10291 tcg_temp_free_i64(fp0);
10292 }
10293 break;
10294 case OPC_CVT_S_PL:
10295 check_cp1_64bitmode(ctx);
10296 {
10297 TCGv_i32 fp0 = tcg_temp_new_i32();
10298
10299 gen_load_fpr32(ctx, fp0, fs);
10300 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
10301 gen_store_fpr32(ctx, fp0, fd);
10302 tcg_temp_free_i32(fp0);
10303 }
10304 break;
10305 case OPC_PLL_PS:
10306 check_ps(ctx);
10307 {
10308 TCGv_i32 fp0 = tcg_temp_new_i32();
10309 TCGv_i32 fp1 = tcg_temp_new_i32();
10310
10311 gen_load_fpr32(ctx, fp0, fs);
10312 gen_load_fpr32(ctx, fp1, ft);
10313 gen_store_fpr32h(ctx, fp0, fd);
10314 gen_store_fpr32(ctx, fp1, fd);
10315 tcg_temp_free_i32(fp0);
10316 tcg_temp_free_i32(fp1);
10317 }
10318 break;
10319 case OPC_PLU_PS:
10320 check_ps(ctx);
10321 {
10322 TCGv_i32 fp0 = tcg_temp_new_i32();
10323 TCGv_i32 fp1 = tcg_temp_new_i32();
10324
10325 gen_load_fpr32(ctx, fp0, fs);
10326 gen_load_fpr32h(ctx, fp1, ft);
10327 gen_store_fpr32(ctx, fp1, fd);
10328 gen_store_fpr32h(ctx, fp0, fd);
10329 tcg_temp_free_i32(fp0);
10330 tcg_temp_free_i32(fp1);
10331 }
10332 break;
10333 case OPC_PUL_PS:
10334 check_ps(ctx);
10335 {
10336 TCGv_i32 fp0 = tcg_temp_new_i32();
10337 TCGv_i32 fp1 = tcg_temp_new_i32();
10338
10339 gen_load_fpr32h(ctx, fp0, fs);
10340 gen_load_fpr32(ctx, fp1, ft);
10341 gen_store_fpr32(ctx, fp1, fd);
10342 gen_store_fpr32h(ctx, fp0, fd);
10343 tcg_temp_free_i32(fp0);
10344 tcg_temp_free_i32(fp1);
10345 }
10346 break;
10347 case OPC_PUU_PS:
10348 check_ps(ctx);
10349 {
10350 TCGv_i32 fp0 = tcg_temp_new_i32();
10351 TCGv_i32 fp1 = tcg_temp_new_i32();
10352
10353 gen_load_fpr32h(ctx, fp0, fs);
10354 gen_load_fpr32h(ctx, fp1, ft);
10355 gen_store_fpr32(ctx, fp1, fd);
10356 gen_store_fpr32h(ctx, fp0, fd);
10357 tcg_temp_free_i32(fp0);
10358 tcg_temp_free_i32(fp1);
10359 }
10360 break;
10361 case OPC_CMP_F_PS:
10362 case OPC_CMP_UN_PS:
10363 case OPC_CMP_EQ_PS:
10364 case OPC_CMP_UEQ_PS:
10365 case OPC_CMP_OLT_PS:
10366 case OPC_CMP_ULT_PS:
10367 case OPC_CMP_OLE_PS:
10368 case OPC_CMP_ULE_PS:
10369 case OPC_CMP_SF_PS:
10370 case OPC_CMP_NGLE_PS:
10371 case OPC_CMP_SEQ_PS:
10372 case OPC_CMP_NGL_PS:
10373 case OPC_CMP_LT_PS:
10374 case OPC_CMP_NGE_PS:
10375 case OPC_CMP_LE_PS:
10376 case OPC_CMP_NGT_PS:
10377 if (ctx->opcode & (1 << 6)) {
10378 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10379 } else {
10380 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10381 }
10382 break;
10383 default:
10384 MIPS_INVAL("farith");
10385 generate_exception_end(ctx, EXCP_RI);
10386 return;
10387 }
10388 }
10389
10390 /* Coprocessor 3 (FPU) */
10391 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10392 int fd, int fs, int base, int index)
10393 {
10394 TCGv t0 = tcg_temp_new();
10395
10396 if (base == 0) {
10397 gen_load_gpr(t0, index);
10398 } else if (index == 0) {
10399 gen_load_gpr(t0, base);
10400 } else {
10401 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10402 }
10403 /* Don't do NOP if destination is zero: we must perform the actual
10404 memory access. */
10405 switch (opc) {
10406 case OPC_LWXC1:
10407 check_cop1x(ctx);
10408 {
10409 TCGv_i32 fp0 = tcg_temp_new_i32();
10410
10411 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10412 tcg_gen_trunc_tl_i32(fp0, t0);
10413 gen_store_fpr32(ctx, fp0, fd);
10414 tcg_temp_free_i32(fp0);
10415 }
10416 break;
10417 case OPC_LDXC1:
10418 check_cop1x(ctx);
10419 check_cp1_registers(ctx, fd);
10420 {
10421 TCGv_i64 fp0 = tcg_temp_new_i64();
10422 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10423 gen_store_fpr64(ctx, fp0, fd);
10424 tcg_temp_free_i64(fp0);
10425 }
10426 break;
10427 case OPC_LUXC1:
10428 check_cp1_64bitmode(ctx);
10429 tcg_gen_andi_tl(t0, t0, ~0x7);
10430 {
10431 TCGv_i64 fp0 = tcg_temp_new_i64();
10432
10433 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10434 gen_store_fpr64(ctx, fp0, fd);
10435 tcg_temp_free_i64(fp0);
10436 }
10437 break;
10438 case OPC_SWXC1:
10439 check_cop1x(ctx);
10440 {
10441 TCGv_i32 fp0 = tcg_temp_new_i32();
10442 gen_load_fpr32(ctx, fp0, fs);
10443 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10444 tcg_temp_free_i32(fp0);
10445 }
10446 break;
10447 case OPC_SDXC1:
10448 check_cop1x(ctx);
10449 check_cp1_registers(ctx, fs);
10450 {
10451 TCGv_i64 fp0 = tcg_temp_new_i64();
10452 gen_load_fpr64(ctx, fp0, fs);
10453 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10454 tcg_temp_free_i64(fp0);
10455 }
10456 break;
10457 case OPC_SUXC1:
10458 check_cp1_64bitmode(ctx);
10459 tcg_gen_andi_tl(t0, t0, ~0x7);
10460 {
10461 TCGv_i64 fp0 = tcg_temp_new_i64();
10462 gen_load_fpr64(ctx, fp0, fs);
10463 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10464 tcg_temp_free_i64(fp0);
10465 }
10466 break;
10467 }
10468 tcg_temp_free(t0);
10469 }
10470
10471 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10472 int fd, int fr, int fs, int ft)
10473 {
10474 switch (opc) {
10475 case OPC_ALNV_PS:
10476 check_ps(ctx);
10477 {
10478 TCGv t0 = tcg_temp_local_new();
10479 TCGv_i32 fp = tcg_temp_new_i32();
10480 TCGv_i32 fph = tcg_temp_new_i32();
10481 TCGLabel *l1 = gen_new_label();
10482 TCGLabel *l2 = gen_new_label();
10483
10484 gen_load_gpr(t0, fr);
10485 tcg_gen_andi_tl(t0, t0, 0x7);
10486
10487 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10488 gen_load_fpr32(ctx, fp, fs);
10489 gen_load_fpr32h(ctx, fph, fs);
10490 gen_store_fpr32(ctx, fp, fd);
10491 gen_store_fpr32h(ctx, fph, fd);
10492 tcg_gen_br(l2);
10493 gen_set_label(l1);
10494 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10495 tcg_temp_free(t0);
10496 #ifdef TARGET_WORDS_BIGENDIAN
10497 gen_load_fpr32(ctx, fp, fs);
10498 gen_load_fpr32h(ctx, fph, ft);
10499 gen_store_fpr32h(ctx, fp, fd);
10500 gen_store_fpr32(ctx, fph, fd);
10501 #else
10502 gen_load_fpr32h(ctx, fph, fs);
10503 gen_load_fpr32(ctx, fp, ft);
10504 gen_store_fpr32(ctx, fph, fd);
10505 gen_store_fpr32h(ctx, fp, fd);
10506 #endif
10507 gen_set_label(l2);
10508 tcg_temp_free_i32(fp);
10509 tcg_temp_free_i32(fph);
10510 }
10511 break;
10512 case OPC_MADD_S:
10513 check_cop1x(ctx);
10514 {
10515 TCGv_i32 fp0 = tcg_temp_new_i32();
10516 TCGv_i32 fp1 = tcg_temp_new_i32();
10517 TCGv_i32 fp2 = tcg_temp_new_i32();
10518
10519 gen_load_fpr32(ctx, fp0, fs);
10520 gen_load_fpr32(ctx, fp1, ft);
10521 gen_load_fpr32(ctx, fp2, fr);
10522 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10523 tcg_temp_free_i32(fp0);
10524 tcg_temp_free_i32(fp1);
10525 gen_store_fpr32(ctx, fp2, fd);
10526 tcg_temp_free_i32(fp2);
10527 }
10528 break;
10529 case OPC_MADD_D:
10530 check_cop1x(ctx);
10531 check_cp1_registers(ctx, fd | fs | ft | fr);
10532 {
10533 TCGv_i64 fp0 = tcg_temp_new_i64();
10534 TCGv_i64 fp1 = tcg_temp_new_i64();
10535 TCGv_i64 fp2 = tcg_temp_new_i64();
10536
10537 gen_load_fpr64(ctx, fp0, fs);
10538 gen_load_fpr64(ctx, fp1, ft);
10539 gen_load_fpr64(ctx, fp2, fr);
10540 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10541 tcg_temp_free_i64(fp0);
10542 tcg_temp_free_i64(fp1);
10543 gen_store_fpr64(ctx, fp2, fd);
10544 tcg_temp_free_i64(fp2);
10545 }
10546 break;
10547 case OPC_MADD_PS:
10548 check_ps(ctx);
10549 {
10550 TCGv_i64 fp0 = tcg_temp_new_i64();
10551 TCGv_i64 fp1 = tcg_temp_new_i64();
10552 TCGv_i64 fp2 = tcg_temp_new_i64();
10553
10554 gen_load_fpr64(ctx, fp0, fs);
10555 gen_load_fpr64(ctx, fp1, ft);
10556 gen_load_fpr64(ctx, fp2, fr);
10557 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10558 tcg_temp_free_i64(fp0);
10559 tcg_temp_free_i64(fp1);
10560 gen_store_fpr64(ctx, fp2, fd);
10561 tcg_temp_free_i64(fp2);
10562 }
10563 break;
10564 case OPC_MSUB_S:
10565 check_cop1x(ctx);
10566 {
10567 TCGv_i32 fp0 = tcg_temp_new_i32();
10568 TCGv_i32 fp1 = tcg_temp_new_i32();
10569 TCGv_i32 fp2 = tcg_temp_new_i32();
10570
10571 gen_load_fpr32(ctx, fp0, fs);
10572 gen_load_fpr32(ctx, fp1, ft);
10573 gen_load_fpr32(ctx, fp2, fr);
10574 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10575 tcg_temp_free_i32(fp0);
10576 tcg_temp_free_i32(fp1);
10577 gen_store_fpr32(ctx, fp2, fd);
10578 tcg_temp_free_i32(fp2);
10579 }
10580 break;
10581 case OPC_MSUB_D:
10582 check_cop1x(ctx);
10583 check_cp1_registers(ctx, fd | fs | ft | fr);
10584 {
10585 TCGv_i64 fp0 = tcg_temp_new_i64();
10586 TCGv_i64 fp1 = tcg_temp_new_i64();
10587 TCGv_i64 fp2 = tcg_temp_new_i64();
10588
10589 gen_load_fpr64(ctx, fp0, fs);
10590 gen_load_fpr64(ctx, fp1, ft);
10591 gen_load_fpr64(ctx, fp2, fr);
10592 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10593 tcg_temp_free_i64(fp0);
10594 tcg_temp_free_i64(fp1);
10595 gen_store_fpr64(ctx, fp2, fd);
10596 tcg_temp_free_i64(fp2);
10597 }
10598 break;
10599 case OPC_MSUB_PS:
10600 check_ps(ctx);
10601 {
10602 TCGv_i64 fp0 = tcg_temp_new_i64();
10603 TCGv_i64 fp1 = tcg_temp_new_i64();
10604 TCGv_i64 fp2 = tcg_temp_new_i64();
10605
10606 gen_load_fpr64(ctx, fp0, fs);
10607 gen_load_fpr64(ctx, fp1, ft);
10608 gen_load_fpr64(ctx, fp2, fr);
10609 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10610 tcg_temp_free_i64(fp0);
10611 tcg_temp_free_i64(fp1);
10612 gen_store_fpr64(ctx, fp2, fd);
10613 tcg_temp_free_i64(fp2);
10614 }
10615 break;
10616 case OPC_NMADD_S:
10617 check_cop1x(ctx);
10618 {
10619 TCGv_i32 fp0 = tcg_temp_new_i32();
10620 TCGv_i32 fp1 = tcg_temp_new_i32();
10621 TCGv_i32 fp2 = tcg_temp_new_i32();
10622
10623 gen_load_fpr32(ctx, fp0, fs);
10624 gen_load_fpr32(ctx, fp1, ft);
10625 gen_load_fpr32(ctx, fp2, fr);
10626 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10627 tcg_temp_free_i32(fp0);
10628 tcg_temp_free_i32(fp1);
10629 gen_store_fpr32(ctx, fp2, fd);
10630 tcg_temp_free_i32(fp2);
10631 }
10632 break;
10633 case OPC_NMADD_D:
10634 check_cop1x(ctx);
10635 check_cp1_registers(ctx, fd | fs | ft | fr);
10636 {
10637 TCGv_i64 fp0 = tcg_temp_new_i64();
10638 TCGv_i64 fp1 = tcg_temp_new_i64();
10639 TCGv_i64 fp2 = tcg_temp_new_i64();
10640
10641 gen_load_fpr64(ctx, fp0, fs);
10642 gen_load_fpr64(ctx, fp1, ft);
10643 gen_load_fpr64(ctx, fp2, fr);
10644 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10645 tcg_temp_free_i64(fp0);
10646 tcg_temp_free_i64(fp1);
10647 gen_store_fpr64(ctx, fp2, fd);
10648 tcg_temp_free_i64(fp2);
10649 }
10650 break;
10651 case OPC_NMADD_PS:
10652 check_ps(ctx);
10653 {
10654 TCGv_i64 fp0 = tcg_temp_new_i64();
10655 TCGv_i64 fp1 = tcg_temp_new_i64();
10656 TCGv_i64 fp2 = tcg_temp_new_i64();
10657
10658 gen_load_fpr64(ctx, fp0, fs);
10659 gen_load_fpr64(ctx, fp1, ft);
10660 gen_load_fpr64(ctx, fp2, fr);
10661 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10662 tcg_temp_free_i64(fp0);
10663 tcg_temp_free_i64(fp1);
10664 gen_store_fpr64(ctx, fp2, fd);
10665 tcg_temp_free_i64(fp2);
10666 }
10667 break;
10668 case OPC_NMSUB_S:
10669 check_cop1x(ctx);
10670 {
10671 TCGv_i32 fp0 = tcg_temp_new_i32();
10672 TCGv_i32 fp1 = tcg_temp_new_i32();
10673 TCGv_i32 fp2 = tcg_temp_new_i32();
10674
10675 gen_load_fpr32(ctx, fp0, fs);
10676 gen_load_fpr32(ctx, fp1, ft);
10677 gen_load_fpr32(ctx, fp2, fr);
10678 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10679 tcg_temp_free_i32(fp0);
10680 tcg_temp_free_i32(fp1);
10681 gen_store_fpr32(ctx, fp2, fd);
10682 tcg_temp_free_i32(fp2);
10683 }
10684 break;
10685 case OPC_NMSUB_D:
10686 check_cop1x(ctx);
10687 check_cp1_registers(ctx, fd | fs | ft | fr);
10688 {
10689 TCGv_i64 fp0 = tcg_temp_new_i64();
10690 TCGv_i64 fp1 = tcg_temp_new_i64();
10691 TCGv_i64 fp2 = tcg_temp_new_i64();
10692
10693 gen_load_fpr64(ctx, fp0, fs);
10694 gen_load_fpr64(ctx, fp1, ft);
10695 gen_load_fpr64(ctx, fp2, fr);
10696 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10697 tcg_temp_free_i64(fp0);
10698 tcg_temp_free_i64(fp1);
10699 gen_store_fpr64(ctx, fp2, fd);
10700 tcg_temp_free_i64(fp2);
10701 }
10702 break;
10703 case OPC_NMSUB_PS:
10704 check_ps(ctx);
10705 {
10706 TCGv_i64 fp0 = tcg_temp_new_i64();
10707 TCGv_i64 fp1 = tcg_temp_new_i64();
10708 TCGv_i64 fp2 = tcg_temp_new_i64();
10709
10710 gen_load_fpr64(ctx, fp0, fs);
10711 gen_load_fpr64(ctx, fp1, ft);
10712 gen_load_fpr64(ctx, fp2, fr);
10713 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10714 tcg_temp_free_i64(fp0);
10715 tcg_temp_free_i64(fp1);
10716 gen_store_fpr64(ctx, fp2, fd);
10717 tcg_temp_free_i64(fp2);
10718 }
10719 break;
10720 default:
10721 MIPS_INVAL("flt3_arith");
10722 generate_exception_end(ctx, EXCP_RI);
10723 return;
10724 }
10725 }
10726
10727 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10728 {
10729 TCGv t0;
10730
10731 #if !defined(CONFIG_USER_ONLY)
10732 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10733 Therefore only check the ISA in system mode. */
10734 check_insn(ctx, ISA_MIPS32R2);
10735 #endif
10736 t0 = tcg_temp_new();
10737
10738 switch (rd) {
10739 case 0:
10740 gen_helper_rdhwr_cpunum(t0, cpu_env);
10741 gen_store_gpr(t0, rt);
10742 break;
10743 case 1:
10744 gen_helper_rdhwr_synci_step(t0, cpu_env);
10745 gen_store_gpr(t0, rt);
10746 break;
10747 case 2:
10748 gen_helper_rdhwr_cc(t0, cpu_env);
10749 gen_store_gpr(t0, rt);
10750 break;
10751 case 3:
10752 gen_helper_rdhwr_ccres(t0, cpu_env);
10753 gen_store_gpr(t0, rt);
10754 break;
10755 case 4:
10756 check_insn(ctx, ISA_MIPS32R6);
10757 if (sel != 0) {
10758 /* Performance counter registers are not implemented other than
10759 * control register 0.
10760 */
10761 generate_exception(ctx, EXCP_RI);
10762 }
10763 gen_helper_rdhwr_performance(t0, cpu_env);
10764 gen_store_gpr(t0, rt);
10765 break;
10766 case 5:
10767 check_insn(ctx, ISA_MIPS32R6);
10768 gen_helper_rdhwr_xnp(t0, cpu_env);
10769 gen_store_gpr(t0, rt);
10770 break;
10771 case 29:
10772 #if defined(CONFIG_USER_ONLY)
10773 tcg_gen_ld_tl(t0, cpu_env,
10774 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10775 gen_store_gpr(t0, rt);
10776 break;
10777 #else
10778 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10779 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10780 tcg_gen_ld_tl(t0, cpu_env,
10781 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10782 gen_store_gpr(t0, rt);
10783 } else {
10784 generate_exception_end(ctx, EXCP_RI);
10785 }
10786 break;
10787 #endif
10788 default: /* Invalid */
10789 MIPS_INVAL("rdhwr");
10790 generate_exception_end(ctx, EXCP_RI);
10791 break;
10792 }
10793 tcg_temp_free(t0);
10794 }
10795
10796 static inline void clear_branch_hflags(DisasContext *ctx)
10797 {
10798 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10799 if (ctx->bstate == BS_NONE) {
10800 save_cpu_state(ctx, 0);
10801 } else {
10802 /* it is not safe to save ctx->hflags as hflags may be changed
10803 in execution time by the instruction in delay / forbidden slot. */
10804 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10805 }
10806 }
10807
10808 static void gen_branch(DisasContext *ctx, int insn_bytes)
10809 {
10810 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10811 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10812 /* Branches completion */
10813 clear_branch_hflags(ctx);
10814 ctx->bstate = BS_BRANCH;
10815 /* FIXME: Need to clear can_do_io. */
10816 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10817 case MIPS_HFLAG_FBNSLOT:
10818 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10819 break;
10820 case MIPS_HFLAG_B:
10821 /* unconditional branch */
10822 if (proc_hflags & MIPS_HFLAG_BX) {
10823 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10824 }
10825 gen_goto_tb(ctx, 0, ctx->btarget);
10826 break;
10827 case MIPS_HFLAG_BL:
10828 /* blikely taken case */
10829 gen_goto_tb(ctx, 0, ctx->btarget);
10830 break;
10831 case MIPS_HFLAG_BC:
10832 /* Conditional branch */
10833 {
10834 TCGLabel *l1 = gen_new_label();
10835
10836 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10837 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10838 gen_set_label(l1);
10839 gen_goto_tb(ctx, 0, ctx->btarget);
10840 }
10841 break;
10842 case MIPS_HFLAG_BR:
10843 /* unconditional branch to register */
10844 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10845 TCGv t0 = tcg_temp_new();
10846 TCGv_i32 t1 = tcg_temp_new_i32();
10847
10848 tcg_gen_andi_tl(t0, btarget, 0x1);
10849 tcg_gen_trunc_tl_i32(t1, t0);
10850 tcg_temp_free(t0);
10851 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10852 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10853 tcg_gen_or_i32(hflags, hflags, t1);
10854 tcg_temp_free_i32(t1);
10855
10856 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10857 } else {
10858 tcg_gen_mov_tl(cpu_PC, btarget);
10859 }
10860 if (ctx->singlestep_enabled) {
10861 save_cpu_state(ctx, 0);
10862 gen_helper_raise_exception_debug(cpu_env);
10863 }
10864 tcg_gen_lookup_and_goto_ptr(cpu_PC);
10865 break;
10866 default:
10867 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10868 abort();
10869 }
10870 }
10871 }
10872
10873 /* Compact Branches */
10874 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10875 int rs, int rt, int32_t offset)
10876 {
10877 int bcond_compute = 0;
10878 TCGv t0 = tcg_temp_new();
10879 TCGv t1 = tcg_temp_new();
10880 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10881
10882 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10883 #ifdef MIPS_DEBUG_DISAS
10884 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10885 "\n", ctx->pc);
10886 #endif
10887 generate_exception_end(ctx, EXCP_RI);
10888 goto out;
10889 }
10890
10891 /* Load needed operands and calculate btarget */
10892 switch (opc) {
10893 /* compact branch */
10894 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10895 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10896 gen_load_gpr(t0, rs);
10897 gen_load_gpr(t1, rt);
10898 bcond_compute = 1;
10899 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10900 if (rs <= rt && rs == 0) {
10901 /* OPC_BEQZALC, OPC_BNEZALC */
10902 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10903 }
10904 break;
10905 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10906 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10907 gen_load_gpr(t0, rs);
10908 gen_load_gpr(t1, rt);
10909 bcond_compute = 1;
10910 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10911 break;
10912 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10913 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10914 if (rs == 0 || rs == rt) {
10915 /* OPC_BLEZALC, OPC_BGEZALC */
10916 /* OPC_BGTZALC, OPC_BLTZALC */
10917 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10918 }
10919 gen_load_gpr(t0, rs);
10920 gen_load_gpr(t1, rt);
10921 bcond_compute = 1;
10922 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10923 break;
10924 case OPC_BC:
10925 case OPC_BALC:
10926 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10927 break;
10928 case OPC_BEQZC:
10929 case OPC_BNEZC:
10930 if (rs != 0) {
10931 /* OPC_BEQZC, OPC_BNEZC */
10932 gen_load_gpr(t0, rs);
10933 bcond_compute = 1;
10934 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10935 } else {
10936 /* OPC_JIC, OPC_JIALC */
10937 TCGv tbase = tcg_temp_new();
10938 TCGv toffset = tcg_temp_new();
10939
10940 gen_load_gpr(tbase, rt);
10941 tcg_gen_movi_tl(toffset, offset);
10942 gen_op_addr_add(ctx, btarget, tbase, toffset);
10943 tcg_temp_free(tbase);
10944 tcg_temp_free(toffset);
10945 }
10946 break;
10947 default:
10948 MIPS_INVAL("Compact branch/jump");
10949 generate_exception_end(ctx, EXCP_RI);
10950 goto out;
10951 }
10952
10953 if (bcond_compute == 0) {
10954 /* Uncoditional compact branch */
10955 switch (opc) {
10956 case OPC_JIALC:
10957 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10958 /* Fallthrough */
10959 case OPC_JIC:
10960 ctx->hflags |= MIPS_HFLAG_BR;
10961 break;
10962 case OPC_BALC:
10963 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10964 /* Fallthrough */
10965 case OPC_BC:
10966 ctx->hflags |= MIPS_HFLAG_B;
10967 break;
10968 default:
10969 MIPS_INVAL("Compact branch/jump");
10970 generate_exception_end(ctx, EXCP_RI);
10971 goto out;
10972 }
10973
10974 /* Generating branch here as compact branches don't have delay slot */
10975 gen_branch(ctx, 4);
10976 } else {
10977 /* Conditional compact branch */
10978 TCGLabel *fs = gen_new_label();
10979 save_cpu_state(ctx, 0);
10980
10981 switch (opc) {
10982 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10983 if (rs == 0 && rt != 0) {
10984 /* OPC_BLEZALC */
10985 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10986 } else if (rs != 0 && rt != 0 && rs == rt) {
10987 /* OPC_BGEZALC */
10988 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10989 } else {
10990 /* OPC_BGEUC */
10991 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10992 }
10993 break;
10994 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10995 if (rs == 0 && rt != 0) {
10996 /* OPC_BGTZALC */
10997 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10998 } else if (rs != 0 && rt != 0 && rs == rt) {
10999 /* OPC_BLTZALC */
11000 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11001 } else {
11002 /* OPC_BLTUC */
11003 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11004 }
11005 break;
11006 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11007 if (rs == 0 && rt != 0) {
11008 /* OPC_BLEZC */
11009 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11010 } else if (rs != 0 && rt != 0 && rs == rt) {
11011 /* OPC_BGEZC */
11012 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11013 } else {
11014 /* OPC_BGEC */
11015 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11016 }
11017 break;
11018 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11019 if (rs == 0 && rt != 0) {
11020 /* OPC_BGTZC */
11021 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11022 } else if (rs != 0 && rt != 0 && rs == rt) {
11023 /* OPC_BLTZC */
11024 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11025 } else {
11026 /* OPC_BLTC */
11027 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11028 }
11029 break;
11030 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11031 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11032 if (rs >= rt) {
11033 /* OPC_BOVC, OPC_BNVC */
11034 TCGv t2 = tcg_temp_new();
11035 TCGv t3 = tcg_temp_new();
11036 TCGv t4 = tcg_temp_new();
11037 TCGv input_overflow = tcg_temp_new();
11038
11039 gen_load_gpr(t0, rs);
11040 gen_load_gpr(t1, rt);
11041 tcg_gen_ext32s_tl(t2, t0);
11042 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11043 tcg_gen_ext32s_tl(t3, t1);
11044 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11045 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11046
11047 tcg_gen_add_tl(t4, t2, t3);
11048 tcg_gen_ext32s_tl(t4, t4);
11049 tcg_gen_xor_tl(t2, t2, t3);
11050 tcg_gen_xor_tl(t3, t4, t3);
11051 tcg_gen_andc_tl(t2, t3, t2);
11052 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11053 tcg_gen_or_tl(t4, t4, input_overflow);
11054 if (opc == OPC_BOVC) {
11055 /* OPC_BOVC */
11056 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11057 } else {
11058 /* OPC_BNVC */
11059 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11060 }
11061 tcg_temp_free(input_overflow);
11062 tcg_temp_free(t4);
11063 tcg_temp_free(t3);
11064 tcg_temp_free(t2);
11065 } else if (rs < rt && rs == 0) {
11066 /* OPC_BEQZALC, OPC_BNEZALC */
11067 if (opc == OPC_BEQZALC) {
11068 /* OPC_BEQZALC */
11069 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11070 } else {
11071 /* OPC_BNEZALC */
11072 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11073 }
11074 } else {
11075 /* OPC_BEQC, OPC_BNEC */
11076 if (opc == OPC_BEQC) {
11077 /* OPC_BEQC */
11078 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11079 } else {
11080 /* OPC_BNEC */
11081 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11082 }
11083 }
11084 break;
11085 case OPC_BEQZC:
11086 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11087 break;
11088 case OPC_BNEZC:
11089 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11090 break;
11091 default:
11092 MIPS_INVAL("Compact conditional branch/jump");
11093 generate_exception_end(ctx, EXCP_RI);
11094 goto out;
11095 }
11096
11097 /* Generating branch here as compact branches don't have delay slot */
11098 gen_goto_tb(ctx, 1, ctx->btarget);
11099 gen_set_label(fs);
11100
11101 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
11102 }
11103
11104 out:
11105 tcg_temp_free(t0);
11106 tcg_temp_free(t1);
11107 }
11108
11109 /* ISA extensions (ASEs) */
11110 /* MIPS16 extension to MIPS32 */
11111
11112 /* MIPS16 major opcodes */
11113 enum {
11114 M16_OPC_ADDIUSP = 0x00,
11115 M16_OPC_ADDIUPC = 0x01,
11116 M16_OPC_B = 0x02,
11117 M16_OPC_JAL = 0x03,
11118 M16_OPC_BEQZ = 0x04,
11119 M16_OPC_BNEQZ = 0x05,
11120 M16_OPC_SHIFT = 0x06,
11121 M16_OPC_LD = 0x07,
11122 M16_OPC_RRIA = 0x08,
11123 M16_OPC_ADDIU8 = 0x09,
11124 M16_OPC_SLTI = 0x0a,
11125 M16_OPC_SLTIU = 0x0b,
11126 M16_OPC_I8 = 0x0c,
11127 M16_OPC_LI = 0x0d,
11128 M16_OPC_CMPI = 0x0e,
11129 M16_OPC_SD = 0x0f,
11130 M16_OPC_LB = 0x10,
11131 M16_OPC_LH = 0x11,
11132 M16_OPC_LWSP = 0x12,
11133 M16_OPC_LW = 0x13,
11134 M16_OPC_LBU = 0x14,
11135 M16_OPC_LHU = 0x15,
11136 M16_OPC_LWPC = 0x16,
11137 M16_OPC_LWU = 0x17,
11138 M16_OPC_SB = 0x18,
11139 M16_OPC_SH = 0x19,
11140 M16_OPC_SWSP = 0x1a,
11141 M16_OPC_SW = 0x1b,
11142 M16_OPC_RRR = 0x1c,
11143 M16_OPC_RR = 0x1d,
11144 M16_OPC_EXTEND = 0x1e,
11145 M16_OPC_I64 = 0x1f
11146 };
11147
11148 /* I8 funct field */
11149 enum {
11150 I8_BTEQZ = 0x0,
11151 I8_BTNEZ = 0x1,
11152 I8_SWRASP = 0x2,
11153 I8_ADJSP = 0x3,
11154 I8_SVRS = 0x4,
11155 I8_MOV32R = 0x5,
11156 I8_MOVR32 = 0x7
11157 };
11158
11159 /* RRR f field */
11160 enum {
11161 RRR_DADDU = 0x0,
11162 RRR_ADDU = 0x1,
11163 RRR_DSUBU = 0x2,
11164 RRR_SUBU = 0x3
11165 };
11166
11167 /* RR funct field */
11168 enum {
11169 RR_JR = 0x00,
11170 RR_SDBBP = 0x01,
11171 RR_SLT = 0x02,
11172 RR_SLTU = 0x03,
11173 RR_SLLV = 0x04,
11174 RR_BREAK = 0x05,
11175 RR_SRLV = 0x06,
11176 RR_SRAV = 0x07,
11177 RR_DSRL = 0x08,
11178 RR_CMP = 0x0a,
11179 RR_NEG = 0x0b,
11180 RR_AND = 0x0c,
11181 RR_OR = 0x0d,
11182 RR_XOR = 0x0e,
11183 RR_NOT = 0x0f,
11184 RR_MFHI = 0x10,
11185 RR_CNVT = 0x11,
11186 RR_MFLO = 0x12,
11187 RR_DSRA = 0x13,
11188 RR_DSLLV = 0x14,
11189 RR_DSRLV = 0x16,
11190 RR_DSRAV = 0x17,
11191 RR_MULT = 0x18,
11192 RR_MULTU = 0x19,
11193 RR_DIV = 0x1a,
11194 RR_DIVU = 0x1b,
11195 RR_DMULT = 0x1c,
11196 RR_DMULTU = 0x1d,
11197 RR_DDIV = 0x1e,
11198 RR_DDIVU = 0x1f
11199 };
11200
11201 /* I64 funct field */
11202 enum {
11203 I64_LDSP = 0x0,
11204 I64_SDSP = 0x1,
11205 I64_SDRASP = 0x2,
11206 I64_DADJSP = 0x3,
11207 I64_LDPC = 0x4,
11208 I64_DADDIU5 = 0x5,
11209 I64_DADDIUPC = 0x6,
11210 I64_DADDIUSP = 0x7
11211 };
11212
11213 /* RR ry field for CNVT */
11214 enum {
11215 RR_RY_CNVT_ZEB = 0x0,
11216 RR_RY_CNVT_ZEH = 0x1,
11217 RR_RY_CNVT_ZEW = 0x2,
11218 RR_RY_CNVT_SEB = 0x4,
11219 RR_RY_CNVT_SEH = 0x5,
11220 RR_RY_CNVT_SEW = 0x6,
11221 };
11222
11223 static int xlat (int r)
11224 {
11225 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11226
11227 return map[r];
11228 }
11229
11230 static void gen_mips16_save (DisasContext *ctx,
11231 int xsregs, int aregs,
11232 int do_ra, int do_s0, int do_s1,
11233 int framesize)
11234 {
11235 TCGv t0 = tcg_temp_new();
11236 TCGv t1 = tcg_temp_new();
11237 TCGv t2 = tcg_temp_new();
11238 int args, astatic;
11239
11240 switch (aregs) {
11241 case 0:
11242 case 1:
11243 case 2:
11244 case 3:
11245 case 11:
11246 args = 0;
11247 break;
11248 case 4:
11249 case 5:
11250 case 6:
11251 case 7:
11252 args = 1;
11253 break;
11254 case 8:
11255 case 9:
11256 case 10:
11257 args = 2;
11258 break;
11259 case 12:
11260 case 13:
11261 args = 3;
11262 break;
11263 case 14:
11264 args = 4;
11265 break;
11266 default:
11267 generate_exception_end(ctx, EXCP_RI);
11268 return;
11269 }
11270
11271 switch (args) {
11272 case 4:
11273 gen_base_offset_addr(ctx, t0, 29, 12);
11274 gen_load_gpr(t1, 7);
11275 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11276 /* Fall through */
11277 case 3:
11278 gen_base_offset_addr(ctx, t0, 29, 8);
11279 gen_load_gpr(t1, 6);
11280 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11281 /* Fall through */
11282 case 2:
11283 gen_base_offset_addr(ctx, t0, 29, 4);
11284 gen_load_gpr(t1, 5);
11285 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11286 /* Fall through */
11287 case 1:
11288 gen_base_offset_addr(ctx, t0, 29, 0);
11289 gen_load_gpr(t1, 4);
11290 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11291 }
11292
11293 gen_load_gpr(t0, 29);
11294
11295 #define DECR_AND_STORE(reg) do { \
11296 tcg_gen_movi_tl(t2, -4); \
11297 gen_op_addr_add(ctx, t0, t0, t2); \
11298 gen_load_gpr(t1, reg); \
11299 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11300 } while (0)
11301
11302 if (do_ra) {
11303 DECR_AND_STORE(31);
11304 }
11305
11306 switch (xsregs) {
11307 case 7:
11308 DECR_AND_STORE(30);
11309 /* Fall through */
11310 case 6:
11311 DECR_AND_STORE(23);
11312 /* Fall through */
11313 case 5:
11314 DECR_AND_STORE(22);
11315 /* Fall through */
11316 case 4:
11317 DECR_AND_STORE(21);
11318 /* Fall through */
11319 case 3:
11320 DECR_AND_STORE(20);
11321 /* Fall through */
11322 case 2:
11323 DECR_AND_STORE(19);
11324 /* Fall through */
11325 case 1:
11326 DECR_AND_STORE(18);
11327 }
11328
11329 if (do_s1) {
11330 DECR_AND_STORE(17);
11331 }
11332 if (do_s0) {
11333 DECR_AND_STORE(16);
11334 }
11335
11336 switch (aregs) {
11337 case 0:
11338 case 4:
11339 case 8:
11340 case 12:
11341 case 14:
11342 astatic = 0;
11343 break;
11344 case 1:
11345 case 5:
11346 case 9:
11347 case 13:
11348 astatic = 1;
11349 break;
11350 case 2:
11351 case 6:
11352 case 10:
11353 astatic = 2;
11354 break;
11355 case 3:
11356 case 7:
11357 astatic = 3;
11358 break;
11359 case 11:
11360 astatic = 4;
11361 break;
11362 default:
11363 generate_exception_end(ctx, EXCP_RI);
11364 return;
11365 }
11366
11367 if (astatic > 0) {
11368 DECR_AND_STORE(7);
11369 if (astatic > 1) {
11370 DECR_AND_STORE(6);
11371 if (astatic > 2) {
11372 DECR_AND_STORE(5);
11373 if (astatic > 3) {
11374 DECR_AND_STORE(4);
11375 }
11376 }
11377 }
11378 }
11379 #undef DECR_AND_STORE
11380
11381 tcg_gen_movi_tl(t2, -framesize);
11382 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11383 tcg_temp_free(t0);
11384 tcg_temp_free(t1);
11385 tcg_temp_free(t2);
11386 }
11387
11388 static void gen_mips16_restore (DisasContext *ctx,
11389 int xsregs, int aregs,
11390 int do_ra, int do_s0, int do_s1,
11391 int framesize)
11392 {
11393 int astatic;
11394 TCGv t0 = tcg_temp_new();
11395 TCGv t1 = tcg_temp_new();
11396 TCGv t2 = tcg_temp_new();
11397
11398 tcg_gen_movi_tl(t2, framesize);
11399 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
11400
11401 #define DECR_AND_LOAD(reg) do { \
11402 tcg_gen_movi_tl(t2, -4); \
11403 gen_op_addr_add(ctx, t0, t0, t2); \
11404 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11405 gen_store_gpr(t1, reg); \
11406 } while (0)
11407
11408 if (do_ra) {
11409 DECR_AND_LOAD(31);
11410 }
11411
11412 switch (xsregs) {
11413 case 7:
11414 DECR_AND_LOAD(30);
11415 /* Fall through */
11416 case 6:
11417 DECR_AND_LOAD(23);
11418 /* Fall through */
11419 case 5:
11420 DECR_AND_LOAD(22);
11421 /* Fall through */
11422 case 4:
11423 DECR_AND_LOAD(21);
11424 /* Fall through */
11425 case 3:
11426 DECR_AND_LOAD(20);
11427 /* Fall through */
11428 case 2:
11429 DECR_AND_LOAD(19);
11430 /* Fall through */
11431 case 1:
11432 DECR_AND_LOAD(18);
11433 }
11434
11435 if (do_s1) {
11436 DECR_AND_LOAD(17);
11437 }
11438 if (do_s0) {
11439 DECR_AND_LOAD(16);
11440 }
11441
11442 switch (aregs) {
11443 case 0:
11444 case 4:
11445 case 8:
11446 case 12:
11447 case 14:
11448 astatic = 0;
11449 break;
11450 case 1:
11451 case 5:
11452 case 9:
11453 case 13:
11454 astatic = 1;
11455 break;
11456 case 2:
11457 case 6:
11458 case 10:
11459 astatic = 2;
11460 break;
11461 case 3:
11462 case 7:
11463 astatic = 3;
11464 break;
11465 case 11:
11466 astatic = 4;
11467 break;
11468 default:
11469 generate_exception_end(ctx, EXCP_RI);
11470 return;
11471 }
11472
11473 if (astatic > 0) {
11474 DECR_AND_LOAD(7);
11475 if (astatic > 1) {
11476 DECR_AND_LOAD(6);
11477 if (astatic > 2) {
11478 DECR_AND_LOAD(5);
11479 if (astatic > 3) {
11480 DECR_AND_LOAD(4);
11481 }
11482 }
11483 }
11484 }
11485 #undef DECR_AND_LOAD
11486
11487 tcg_gen_movi_tl(t2, framesize);
11488 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11489 tcg_temp_free(t0);
11490 tcg_temp_free(t1);
11491 tcg_temp_free(t2);
11492 }
11493
11494 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11495 int is_64_bit, int extended)
11496 {
11497 TCGv t0;
11498
11499 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11500 generate_exception_end(ctx, EXCP_RI);
11501 return;
11502 }
11503
11504 t0 = tcg_temp_new();
11505
11506 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11507 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11508 if (!is_64_bit) {
11509 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11510 }
11511
11512 tcg_temp_free(t0);
11513 }
11514
11515 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11516 int16_t offset)
11517 {
11518 TCGv_i32 t0 = tcg_const_i32(op);
11519 TCGv t1 = tcg_temp_new();
11520 gen_base_offset_addr(ctx, t1, base, offset);
11521 gen_helper_cache(cpu_env, t1, t0);
11522 }
11523
11524 #if defined(TARGET_MIPS64)
11525 static void decode_i64_mips16 (DisasContext *ctx,
11526 int ry, int funct, int16_t offset,
11527 int extended)
11528 {
11529 switch (funct) {
11530 case I64_LDSP:
11531 check_insn(ctx, ISA_MIPS3);
11532 check_mips_64(ctx);
11533 offset = extended ? offset : offset << 3;
11534 gen_ld(ctx, OPC_LD, ry, 29, offset);
11535 break;
11536 case I64_SDSP:
11537 check_insn(ctx, ISA_MIPS3);
11538 check_mips_64(ctx);
11539 offset = extended ? offset : offset << 3;
11540 gen_st(ctx, OPC_SD, ry, 29, offset);
11541 break;
11542 case I64_SDRASP:
11543 check_insn(ctx, ISA_MIPS3);
11544 check_mips_64(ctx);
11545 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11546 gen_st(ctx, OPC_SD, 31, 29, offset);
11547 break;
11548 case I64_DADJSP:
11549 check_insn(ctx, ISA_MIPS3);
11550 check_mips_64(ctx);
11551 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11552 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11553 break;
11554 case I64_LDPC:
11555 check_insn(ctx, ISA_MIPS3);
11556 check_mips_64(ctx);
11557 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11558 generate_exception_end(ctx, EXCP_RI);
11559 } else {
11560 offset = extended ? offset : offset << 3;
11561 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11562 }
11563 break;
11564 case I64_DADDIU5:
11565 check_insn(ctx, ISA_MIPS3);
11566 check_mips_64(ctx);
11567 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11568 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11569 break;
11570 case I64_DADDIUPC:
11571 check_insn(ctx, ISA_MIPS3);
11572 check_mips_64(ctx);
11573 offset = extended ? offset : offset << 2;
11574 gen_addiupc(ctx, ry, offset, 1, extended);
11575 break;
11576 case I64_DADDIUSP:
11577 check_insn(ctx, ISA_MIPS3);
11578 check_mips_64(ctx);
11579 offset = extended ? offset : offset << 2;
11580 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11581 break;
11582 }
11583 }
11584 #endif
11585
11586 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11587 {
11588 int extend = cpu_lduw_code(env, ctx->pc + 2);
11589 int op, rx, ry, funct, sa;
11590 int16_t imm, offset;
11591
11592 ctx->opcode = (ctx->opcode << 16) | extend;
11593 op = (ctx->opcode >> 11) & 0x1f;
11594 sa = (ctx->opcode >> 22) & 0x1f;
11595 funct = (ctx->opcode >> 8) & 0x7;
11596 rx = xlat((ctx->opcode >> 8) & 0x7);
11597 ry = xlat((ctx->opcode >> 5) & 0x7);
11598 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11599 | ((ctx->opcode >> 21) & 0x3f) << 5
11600 | (ctx->opcode & 0x1f));
11601
11602 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11603 counterparts. */
11604 switch (op) {
11605 case M16_OPC_ADDIUSP:
11606 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11607 break;
11608 case M16_OPC_ADDIUPC:
11609 gen_addiupc(ctx, rx, imm, 0, 1);
11610 break;
11611 case M16_OPC_B:
11612 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11613 /* No delay slot, so just process as a normal instruction */
11614 break;
11615 case M16_OPC_BEQZ:
11616 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11617 /* No delay slot, so just process as a normal instruction */
11618 break;
11619 case M16_OPC_BNEQZ:
11620 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11621 /* No delay slot, so just process as a normal instruction */
11622 break;
11623 case M16_OPC_SHIFT:
11624 switch (ctx->opcode & 0x3) {
11625 case 0x0:
11626 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11627 break;
11628 case 0x1:
11629 #if defined(TARGET_MIPS64)
11630 check_mips_64(ctx);
11631 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11632 #else
11633 generate_exception_end(ctx, EXCP_RI);
11634 #endif
11635 break;
11636 case 0x2:
11637 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11638 break;
11639 case 0x3:
11640 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11641 break;
11642 }
11643 break;
11644 #if defined(TARGET_MIPS64)
11645 case M16_OPC_LD:
11646 check_insn(ctx, ISA_MIPS3);
11647 check_mips_64(ctx);
11648 gen_ld(ctx, OPC_LD, ry, rx, offset);
11649 break;
11650 #endif
11651 case M16_OPC_RRIA:
11652 imm = ctx->opcode & 0xf;
11653 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11654 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11655 imm = (int16_t) (imm << 1) >> 1;
11656 if ((ctx->opcode >> 4) & 0x1) {
11657 #if defined(TARGET_MIPS64)
11658 check_mips_64(ctx);
11659 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11660 #else
11661 generate_exception_end(ctx, EXCP_RI);
11662 #endif
11663 } else {
11664 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11665 }
11666 break;
11667 case M16_OPC_ADDIU8:
11668 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11669 break;
11670 case M16_OPC_SLTI:
11671 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11672 break;
11673 case M16_OPC_SLTIU:
11674 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11675 break;
11676 case M16_OPC_I8:
11677 switch (funct) {
11678 case I8_BTEQZ:
11679 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11680 break;
11681 case I8_BTNEZ:
11682 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11683 break;
11684 case I8_SWRASP:
11685 gen_st(ctx, OPC_SW, 31, 29, imm);
11686 break;
11687 case I8_ADJSP:
11688 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11689 break;
11690 case I8_SVRS:
11691 check_insn(ctx, ISA_MIPS32);
11692 {
11693 int xsregs = (ctx->opcode >> 24) & 0x7;
11694 int aregs = (ctx->opcode >> 16) & 0xf;
11695 int do_ra = (ctx->opcode >> 6) & 0x1;
11696 int do_s0 = (ctx->opcode >> 5) & 0x1;
11697 int do_s1 = (ctx->opcode >> 4) & 0x1;
11698 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11699 | (ctx->opcode & 0xf)) << 3;
11700
11701 if (ctx->opcode & (1 << 7)) {
11702 gen_mips16_save(ctx, xsregs, aregs,
11703 do_ra, do_s0, do_s1,
11704 framesize);
11705 } else {
11706 gen_mips16_restore(ctx, xsregs, aregs,
11707 do_ra, do_s0, do_s1,
11708 framesize);
11709 }
11710 }
11711 break;
11712 default:
11713 generate_exception_end(ctx, EXCP_RI);
11714 break;
11715 }
11716 break;
11717 case M16_OPC_LI:
11718 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11719 break;
11720 case M16_OPC_CMPI:
11721 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11722 break;
11723 #if defined(TARGET_MIPS64)
11724 case M16_OPC_SD:
11725 check_insn(ctx, ISA_MIPS3);
11726 check_mips_64(ctx);
11727 gen_st(ctx, OPC_SD, ry, rx, offset);
11728 break;
11729 #endif
11730 case M16_OPC_LB:
11731 gen_ld(ctx, OPC_LB, ry, rx, offset);
11732 break;
11733 case M16_OPC_LH:
11734 gen_ld(ctx, OPC_LH, ry, rx, offset);
11735 break;
11736 case M16_OPC_LWSP:
11737 gen_ld(ctx, OPC_LW, rx, 29, offset);
11738 break;
11739 case M16_OPC_LW:
11740 gen_ld(ctx, OPC_LW, ry, rx, offset);
11741 break;
11742 case M16_OPC_LBU:
11743 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11744 break;
11745 case M16_OPC_LHU:
11746 gen_ld(ctx, OPC_LHU, ry, rx, offset);
11747 break;
11748 case M16_OPC_LWPC:
11749 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11750 break;
11751 #if defined(TARGET_MIPS64)
11752 case M16_OPC_LWU:
11753 check_insn(ctx, ISA_MIPS3);
11754 check_mips_64(ctx);
11755 gen_ld(ctx, OPC_LWU, ry, rx, offset);
11756 break;
11757 #endif
11758 case M16_OPC_SB:
11759 gen_st(ctx, OPC_SB, ry, rx, offset);
11760 break;
11761 case M16_OPC_SH:
11762 gen_st(ctx, OPC_SH, ry, rx, offset);
11763 break;
11764 case M16_OPC_SWSP:
11765 gen_st(ctx, OPC_SW, rx, 29, offset);
11766 break;
11767 case M16_OPC_SW:
11768 gen_st(ctx, OPC_SW, ry, rx, offset);
11769 break;
11770 #if defined(TARGET_MIPS64)
11771 case M16_OPC_I64:
11772 decode_i64_mips16(ctx, ry, funct, offset, 1);
11773 break;
11774 #endif
11775 default:
11776 generate_exception_end(ctx, EXCP_RI);
11777 break;
11778 }
11779
11780 return 4;
11781 }
11782
11783 static inline bool is_uhi(int sdbbp_code)
11784 {
11785 #ifdef CONFIG_USER_ONLY
11786 return false;
11787 #else
11788 return semihosting_enabled() && sdbbp_code == 1;
11789 #endif
11790 }
11791
11792 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11793 {
11794 int rx, ry;
11795 int sa;
11796 int op, cnvt_op, op1, offset;
11797 int funct;
11798 int n_bytes;
11799
11800 op = (ctx->opcode >> 11) & 0x1f;
11801 sa = (ctx->opcode >> 2) & 0x7;
11802 sa = sa == 0 ? 8 : sa;
11803 rx = xlat((ctx->opcode >> 8) & 0x7);
11804 cnvt_op = (ctx->opcode >> 5) & 0x7;
11805 ry = xlat((ctx->opcode >> 5) & 0x7);
11806 op1 = offset = ctx->opcode & 0x1f;
11807
11808 n_bytes = 2;
11809
11810 switch (op) {
11811 case M16_OPC_ADDIUSP:
11812 {
11813 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11814
11815 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11816 }
11817 break;
11818 case M16_OPC_ADDIUPC:
11819 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11820 break;
11821 case M16_OPC_B:
11822 offset = (ctx->opcode & 0x7ff) << 1;
11823 offset = (int16_t)(offset << 4) >> 4;
11824 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11825 /* No delay slot, so just process as a normal instruction */
11826 break;
11827 case M16_OPC_JAL:
11828 offset = cpu_lduw_code(env, ctx->pc + 2);
11829 offset = (((ctx->opcode & 0x1f) << 21)
11830 | ((ctx->opcode >> 5) & 0x1f) << 16
11831 | offset) << 2;
11832 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11833 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11834 n_bytes = 4;
11835 break;
11836 case M16_OPC_BEQZ:
11837 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11838 ((int8_t)ctx->opcode) << 1, 0);
11839 /* No delay slot, so just process as a normal instruction */
11840 break;
11841 case M16_OPC_BNEQZ:
11842 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11843 ((int8_t)ctx->opcode) << 1, 0);
11844 /* No delay slot, so just process as a normal instruction */
11845 break;
11846 case M16_OPC_SHIFT:
11847 switch (ctx->opcode & 0x3) {
11848 case 0x0:
11849 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11850 break;
11851 case 0x1:
11852 #if defined(TARGET_MIPS64)
11853 check_insn(ctx, ISA_MIPS3);
11854 check_mips_64(ctx);
11855 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11856 #else
11857 generate_exception_end(ctx, EXCP_RI);
11858 #endif
11859 break;
11860 case 0x2:
11861 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11862 break;
11863 case 0x3:
11864 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11865 break;
11866 }
11867 break;
11868 #if defined(TARGET_MIPS64)
11869 case M16_OPC_LD:
11870 check_insn(ctx, ISA_MIPS3);
11871 check_mips_64(ctx);
11872 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11873 break;
11874 #endif
11875 case M16_OPC_RRIA:
11876 {
11877 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11878
11879 if ((ctx->opcode >> 4) & 1) {
11880 #if defined(TARGET_MIPS64)
11881 check_insn(ctx, ISA_MIPS3);
11882 check_mips_64(ctx);
11883 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11884 #else
11885 generate_exception_end(ctx, EXCP_RI);
11886 #endif
11887 } else {
11888 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11889 }
11890 }
11891 break;
11892 case M16_OPC_ADDIU8:
11893 {
11894 int16_t imm = (int8_t) ctx->opcode;
11895
11896 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11897 }
11898 break;
11899 case M16_OPC_SLTI:
11900 {
11901 int16_t imm = (uint8_t) ctx->opcode;
11902 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11903 }
11904 break;
11905 case M16_OPC_SLTIU:
11906 {
11907 int16_t imm = (uint8_t) ctx->opcode;
11908 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11909 }
11910 break;
11911 case M16_OPC_I8:
11912 {
11913 int reg32;
11914
11915 funct = (ctx->opcode >> 8) & 0x7;
11916 switch (funct) {
11917 case I8_BTEQZ:
11918 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11919 ((int8_t)ctx->opcode) << 1, 0);
11920 break;
11921 case I8_BTNEZ:
11922 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11923 ((int8_t)ctx->opcode) << 1, 0);
11924 break;
11925 case I8_SWRASP:
11926 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11927 break;
11928 case I8_ADJSP:
11929 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11930 ((int8_t)ctx->opcode) << 3);
11931 break;
11932 case I8_SVRS:
11933 check_insn(ctx, ISA_MIPS32);
11934 {
11935 int do_ra = ctx->opcode & (1 << 6);
11936 int do_s0 = ctx->opcode & (1 << 5);
11937 int do_s1 = ctx->opcode & (1 << 4);
11938 int framesize = ctx->opcode & 0xf;
11939
11940 if (framesize == 0) {
11941 framesize = 128;
11942 } else {
11943 framesize = framesize << 3;
11944 }
11945
11946 if (ctx->opcode & (1 << 7)) {
11947 gen_mips16_save(ctx, 0, 0,
11948 do_ra, do_s0, do_s1, framesize);
11949 } else {
11950 gen_mips16_restore(ctx, 0, 0,
11951 do_ra, do_s0, do_s1, framesize);
11952 }
11953 }
11954 break;
11955 case I8_MOV32R:
11956 {
11957 int rz = xlat(ctx->opcode & 0x7);
11958
11959 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11960 ((ctx->opcode >> 5) & 0x7);
11961 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11962 }
11963 break;
11964 case I8_MOVR32:
11965 reg32 = ctx->opcode & 0x1f;
11966 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11967 break;
11968 default:
11969 generate_exception_end(ctx, EXCP_RI);
11970 break;
11971 }
11972 }
11973 break;
11974 case M16_OPC_LI:
11975 {
11976 int16_t imm = (uint8_t) ctx->opcode;
11977
11978 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11979 }
11980 break;
11981 case M16_OPC_CMPI:
11982 {
11983 int16_t imm = (uint8_t) ctx->opcode;
11984 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11985 }
11986 break;
11987 #if defined(TARGET_MIPS64)
11988 case M16_OPC_SD:
11989 check_insn(ctx, ISA_MIPS3);
11990 check_mips_64(ctx);
11991 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11992 break;
11993 #endif
11994 case M16_OPC_LB:
11995 gen_ld(ctx, OPC_LB, ry, rx, offset);
11996 break;
11997 case M16_OPC_LH:
11998 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11999 break;
12000 case M16_OPC_LWSP:
12001 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
12002 break;
12003 case M16_OPC_LW:
12004 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
12005 break;
12006 case M16_OPC_LBU:
12007 gen_ld(ctx, OPC_LBU, ry, rx, offset);
12008 break;
12009 case M16_OPC_LHU:
12010 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
12011 break;
12012 case M16_OPC_LWPC:
12013 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
12014 break;
12015 #if defined (TARGET_MIPS64)
12016 case M16_OPC_LWU:
12017 check_insn(ctx, ISA_MIPS3);
12018 check_mips_64(ctx);
12019 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
12020 break;
12021 #endif
12022 case M16_OPC_SB:
12023 gen_st(ctx, OPC_SB, ry, rx, offset);
12024 break;
12025 case M16_OPC_SH:
12026 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
12027 break;
12028 case M16_OPC_SWSP:
12029 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
12030 break;
12031 case M16_OPC_SW:
12032 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
12033 break;
12034 case M16_OPC_RRR:
12035 {
12036 int rz = xlat((ctx->opcode >> 2) & 0x7);
12037 int mips32_op;
12038
12039 switch (ctx->opcode & 0x3) {
12040 case RRR_ADDU:
12041 mips32_op = OPC_ADDU;
12042 break;
12043 case RRR_SUBU:
12044 mips32_op = OPC_SUBU;
12045 break;
12046 #if defined(TARGET_MIPS64)
12047 case RRR_DADDU:
12048 mips32_op = OPC_DADDU;
12049 check_insn(ctx, ISA_MIPS3);
12050 check_mips_64(ctx);
12051 break;
12052 case RRR_DSUBU:
12053 mips32_op = OPC_DSUBU;
12054 check_insn(ctx, ISA_MIPS3);
12055 check_mips_64(ctx);
12056 break;
12057 #endif
12058 default:
12059 generate_exception_end(ctx, EXCP_RI);
12060 goto done;
12061 }
12062
12063 gen_arith(ctx, mips32_op, rz, rx, ry);
12064 done:
12065 ;
12066 }
12067 break;
12068 case M16_OPC_RR:
12069 switch (op1) {
12070 case RR_JR:
12071 {
12072 int nd = (ctx->opcode >> 7) & 0x1;
12073 int link = (ctx->opcode >> 6) & 0x1;
12074 int ra = (ctx->opcode >> 5) & 0x1;
12075
12076 if (nd) {
12077 check_insn(ctx, ISA_MIPS32);
12078 }
12079
12080 if (link) {
12081 op = OPC_JALR;
12082 } else {
12083 op = OPC_JR;
12084 }
12085
12086 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
12087 (nd ? 0 : 2));
12088 }
12089 break;
12090 case RR_SDBBP:
12091 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
12092 gen_helper_do_semihosting(cpu_env);
12093 } else {
12094 /* XXX: not clear which exception should be raised
12095 * when in debug mode...
12096 */
12097 check_insn(ctx, ISA_MIPS32);
12098 generate_exception_end(ctx, EXCP_DBp);
12099 }
12100 break;
12101 case RR_SLT:
12102 gen_slt(ctx, OPC_SLT, 24, rx, ry);
12103 break;
12104 case RR_SLTU:
12105 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
12106 break;
12107 case RR_BREAK:
12108 generate_exception_end(ctx, EXCP_BREAK);
12109 break;
12110 case RR_SLLV:
12111 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
12112 break;
12113 case RR_SRLV:
12114 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
12115 break;
12116 case RR_SRAV:
12117 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
12118 break;
12119 #if defined (TARGET_MIPS64)
12120 case RR_DSRL:
12121 check_insn(ctx, ISA_MIPS3);
12122 check_mips_64(ctx);
12123 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
12124 break;
12125 #endif
12126 case RR_CMP:
12127 gen_logic(ctx, OPC_XOR, 24, rx, ry);
12128 break;
12129 case RR_NEG:
12130 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
12131 break;
12132 case RR_AND:
12133 gen_logic(ctx, OPC_AND, rx, rx, ry);
12134 break;
12135 case RR_OR:
12136 gen_logic(ctx, OPC_OR, rx, rx, ry);
12137 break;
12138 case RR_XOR:
12139 gen_logic(ctx, OPC_XOR, rx, rx, ry);
12140 break;
12141 case RR_NOT:
12142 gen_logic(ctx, OPC_NOR, rx, ry, 0);
12143 break;
12144 case RR_MFHI:
12145 gen_HILO(ctx, OPC_MFHI, 0, rx);
12146 break;
12147 case RR_CNVT:
12148 check_insn(ctx, ISA_MIPS32);
12149 switch (cnvt_op) {
12150 case RR_RY_CNVT_ZEB:
12151 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12152 break;
12153 case RR_RY_CNVT_ZEH:
12154 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12155 break;
12156 case RR_RY_CNVT_SEB:
12157 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12158 break;
12159 case RR_RY_CNVT_SEH:
12160 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12161 break;
12162 #if defined (TARGET_MIPS64)
12163 case RR_RY_CNVT_ZEW:
12164 check_insn(ctx, ISA_MIPS64);
12165 check_mips_64(ctx);
12166 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12167 break;
12168 case RR_RY_CNVT_SEW:
12169 check_insn(ctx, ISA_MIPS64);
12170 check_mips_64(ctx);
12171 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12172 break;
12173 #endif
12174 default:
12175 generate_exception_end(ctx, EXCP_RI);
12176 break;
12177 }
12178 break;
12179 case RR_MFLO:
12180 gen_HILO(ctx, OPC_MFLO, 0, rx);
12181 break;
12182 #if defined (TARGET_MIPS64)
12183 case RR_DSRA:
12184 check_insn(ctx, ISA_MIPS3);
12185 check_mips_64(ctx);
12186 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
12187 break;
12188 case RR_DSLLV:
12189 check_insn(ctx, ISA_MIPS3);
12190 check_mips_64(ctx);
12191 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
12192 break;
12193 case RR_DSRLV:
12194 check_insn(ctx, ISA_MIPS3);
12195 check_mips_64(ctx);
12196 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
12197 break;
12198 case RR_DSRAV:
12199 check_insn(ctx, ISA_MIPS3);
12200 check_mips_64(ctx);
12201 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
12202 break;
12203 #endif
12204 case RR_MULT:
12205 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
12206 break;
12207 case RR_MULTU:
12208 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
12209 break;
12210 case RR_DIV:
12211 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
12212 break;
12213 case RR_DIVU:
12214 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
12215 break;
12216 #if defined (TARGET_MIPS64)
12217 case RR_DMULT:
12218 check_insn(ctx, ISA_MIPS3);
12219 check_mips_64(ctx);
12220 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
12221 break;
12222 case RR_DMULTU:
12223 check_insn(ctx, ISA_MIPS3);
12224 check_mips_64(ctx);
12225 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
12226 break;
12227 case RR_DDIV:
12228 check_insn(ctx, ISA_MIPS3);
12229 check_mips_64(ctx);
12230 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
12231 break;
12232 case RR_DDIVU:
12233 check_insn(ctx, ISA_MIPS3);
12234 check_mips_64(ctx);
12235 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
12236 break;
12237 #endif
12238 default:
12239 generate_exception_end(ctx, EXCP_RI);
12240 break;
12241 }
12242 break;
12243 case M16_OPC_EXTEND:
12244 decode_extended_mips16_opc(env, ctx);
12245 n_bytes = 4;
12246 break;
12247 #if defined(TARGET_MIPS64)
12248 case M16_OPC_I64:
12249 funct = (ctx->opcode >> 8) & 0x7;
12250 decode_i64_mips16(ctx, ry, funct, offset, 0);
12251 break;
12252 #endif
12253 default:
12254 generate_exception_end(ctx, EXCP_RI);
12255 break;
12256 }
12257
12258 return n_bytes;
12259 }
12260
12261 /* microMIPS extension to MIPS32/MIPS64 */
12262
12263 /*
12264 * microMIPS32/microMIPS64 major opcodes
12265 *
12266 * 1. MIPS Architecture for Programmers Volume II-B:
12267 * The microMIPS32 Instruction Set (Revision 3.05)
12268 *
12269 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12270 *
12271 * 2. MIPS Architecture For Programmers Volume II-A:
12272 * The MIPS64 Instruction Set (Revision 3.51)
12273 */
12274
12275 enum {
12276 POOL32A = 0x00,
12277 POOL16A = 0x01,
12278 LBU16 = 0x02,
12279 MOVE16 = 0x03,
12280 ADDI32 = 0x04,
12281 R6_LUI = 0x04,
12282 AUI = 0x04,
12283 LBU32 = 0x05,
12284 SB32 = 0x06,
12285 LB32 = 0x07,
12286
12287 POOL32B = 0x08,
12288 POOL16B = 0x09,
12289 LHU16 = 0x0a,
12290 ANDI16 = 0x0b,
12291 ADDIU32 = 0x0c,
12292 LHU32 = 0x0d,
12293 SH32 = 0x0e,
12294 LH32 = 0x0f,
12295
12296 POOL32I = 0x10,
12297 POOL16C = 0x11,
12298 LWSP16 = 0x12,
12299 POOL16D = 0x13,
12300 ORI32 = 0x14,
12301 POOL32F = 0x15,
12302 POOL32S = 0x16, /* MIPS64 */
12303 DADDIU32 = 0x17, /* MIPS64 */
12304
12305 POOL32C = 0x18,
12306 LWGP16 = 0x19,
12307 LW16 = 0x1a,
12308 POOL16E = 0x1b,
12309 XORI32 = 0x1c,
12310 JALS32 = 0x1d,
12311 BOVC = 0x1d,
12312 BEQC = 0x1d,
12313 BEQZALC = 0x1d,
12314 ADDIUPC = 0x1e,
12315 PCREL = 0x1e,
12316 BNVC = 0x1f,
12317 BNEC = 0x1f,
12318 BNEZALC = 0x1f,
12319
12320 R6_BEQZC = 0x20,
12321 JIC = 0x20,
12322 POOL16F = 0x21,
12323 SB16 = 0x22,
12324 BEQZ16 = 0x23,
12325 BEQZC16 = 0x23,
12326 SLTI32 = 0x24,
12327 BEQ32 = 0x25,
12328 BC = 0x25,
12329 SWC132 = 0x26,
12330 LWC132 = 0x27,
12331
12332 /* 0x29 is reserved */
12333 RES_29 = 0x29,
12334 R6_BNEZC = 0x28,
12335 JIALC = 0x28,
12336 SH16 = 0x2a,
12337 BNEZ16 = 0x2b,
12338 BNEZC16 = 0x2b,
12339 SLTIU32 = 0x2c,
12340 BNE32 = 0x2d,
12341 BALC = 0x2d,
12342 SDC132 = 0x2e,
12343 LDC132 = 0x2f,
12344
12345 /* 0x31 is reserved */
12346 RES_31 = 0x31,
12347 BLEZALC = 0x30,
12348 BGEZALC = 0x30,
12349 BGEUC = 0x30,
12350 SWSP16 = 0x32,
12351 B16 = 0x33,
12352 BC16 = 0x33,
12353 ANDI32 = 0x34,
12354 J32 = 0x35,
12355 BGTZC = 0x35,
12356 BLTZC = 0x35,
12357 BLTC = 0x35,
12358 SD32 = 0x36, /* MIPS64 */
12359 LD32 = 0x37, /* MIPS64 */
12360
12361 /* 0x39 is reserved */
12362 RES_39 = 0x39,
12363 BGTZALC = 0x38,
12364 BLTZALC = 0x38,
12365 BLTUC = 0x38,
12366 SW16 = 0x3a,
12367 LI16 = 0x3b,
12368 JALX32 = 0x3c,
12369 JAL32 = 0x3d,
12370 BLEZC = 0x3d,
12371 BGEZC = 0x3d,
12372 BGEC = 0x3d,
12373 SW32 = 0x3e,
12374 LW32 = 0x3f
12375 };
12376
12377 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12378 enum {
12379 ADDIUPC_00 = 0x00,
12380 ADDIUPC_07 = 0x07,
12381 AUIPC = 0x1e,
12382 ALUIPC = 0x1f,
12383 LWPC_08 = 0x08,
12384 LWPC_0F = 0x0F,
12385 };
12386
12387 /* POOL32A encoding of minor opcode field */
12388
12389 enum {
12390 /* These opcodes are distinguished only by bits 9..6; those bits are
12391 * what are recorded below. */
12392 SLL32 = 0x0,
12393 SRL32 = 0x1,
12394 SRA = 0x2,
12395 ROTR = 0x3,
12396 SELEQZ = 0x5,
12397 SELNEZ = 0x6,
12398 R6_RDHWR = 0x7,
12399
12400 SLLV = 0x0,
12401 SRLV = 0x1,
12402 SRAV = 0x2,
12403 ROTRV = 0x3,
12404 ADD = 0x4,
12405 ADDU32 = 0x5,
12406 SUB = 0x6,
12407 SUBU32 = 0x7,
12408 MUL = 0x8,
12409 AND = 0x9,
12410 OR32 = 0xa,
12411 NOR = 0xb,
12412 XOR32 = 0xc,
12413 SLT = 0xd,
12414 SLTU = 0xe,
12415
12416 MOVN = 0x0,
12417 R6_MUL = 0x0,
12418 MOVZ = 0x1,
12419 MUH = 0x1,
12420 MULU = 0x2,
12421 MUHU = 0x3,
12422 LWXS = 0x4,
12423 R6_DIV = 0x4,
12424 MOD = 0x5,
12425 R6_DIVU = 0x6,
12426 MODU = 0x7,
12427
12428 /* The following can be distinguished by their lower 6 bits. */
12429 BREAK32 = 0x07,
12430 INS = 0x0c,
12431 LSA = 0x0f,
12432 ALIGN = 0x1f,
12433 EXT = 0x2c,
12434 POOL32AXF = 0x3c,
12435 SIGRIE = 0x3f
12436 };
12437
12438 /* POOL32AXF encoding of minor opcode field extension */
12439
12440 /*
12441 * 1. MIPS Architecture for Programmers Volume II-B:
12442 * The microMIPS32 Instruction Set (Revision 3.05)
12443 *
12444 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12445 *
12446 * 2. MIPS Architecture for Programmers VolumeIV-e:
12447 * The MIPS DSP Application-Specific Extension
12448 * to the microMIPS32 Architecture (Revision 2.34)
12449 *
12450 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12451 */
12452
12453 enum {
12454 /* bits 11..6 */
12455 TEQ = 0x00,
12456 TGE = 0x08,
12457 TGEU = 0x10,
12458 TLT = 0x20,
12459 TLTU = 0x28,
12460 TNE = 0x30,
12461
12462 MFC0 = 0x03,
12463 MTC0 = 0x0b,
12464
12465 /* begin of microMIPS32 DSP */
12466
12467 /* bits 13..12 for 0x01 */
12468 MFHI_ACC = 0x0,
12469 MFLO_ACC = 0x1,
12470 MTHI_ACC = 0x2,
12471 MTLO_ACC = 0x3,
12472
12473 /* bits 13..12 for 0x2a */
12474 MADD_ACC = 0x0,
12475 MADDU_ACC = 0x1,
12476 MSUB_ACC = 0x2,
12477 MSUBU_ACC = 0x3,
12478
12479 /* bits 13..12 for 0x32 */
12480 MULT_ACC = 0x0,
12481 MULTU_ACC = 0x1,
12482
12483 /* end of microMIPS32 DSP */
12484
12485 /* bits 15..12 for 0x2c */
12486 BITSWAP = 0x0,
12487 SEB = 0x2,
12488 SEH = 0x3,
12489 CLO = 0x4,
12490 CLZ = 0x5,
12491 RDHWR = 0x6,
12492 WSBH = 0x7,
12493 MULT = 0x8,
12494 MULTU = 0x9,
12495 DIV = 0xa,
12496 DIVU = 0xb,
12497 MADD = 0xc,
12498 MADDU = 0xd,
12499 MSUB = 0xe,
12500 MSUBU = 0xf,
12501
12502 /* bits 15..12 for 0x34 */
12503 MFC2 = 0x4,
12504 MTC2 = 0x5,
12505 MFHC2 = 0x8,
12506 MTHC2 = 0x9,
12507 CFC2 = 0xc,
12508 CTC2 = 0xd,
12509
12510 /* bits 15..12 for 0x3c */
12511 JALR = 0x0,
12512 JR = 0x0, /* alias */
12513 JALRC = 0x0,
12514 JRC = 0x0,
12515 JALR_HB = 0x1,
12516 JALRC_HB = 0x1,
12517 JALRS = 0x4,
12518 JALRS_HB = 0x5,
12519
12520 /* bits 15..12 for 0x05 */
12521 RDPGPR = 0xe,
12522 WRPGPR = 0xf,
12523
12524 /* bits 15..12 for 0x0d */
12525 TLBP = 0x0,
12526 TLBR = 0x1,
12527 TLBWI = 0x2,
12528 TLBWR = 0x3,
12529 TLBINV = 0x4,
12530 TLBINVF = 0x5,
12531 WAIT = 0x9,
12532 IRET = 0xd,
12533 DERET = 0xe,
12534 ERET = 0xf,
12535
12536 /* bits 15..12 for 0x15 */
12537 DMT = 0x0,
12538 DVPE = 0x1,
12539 EMT = 0x2,
12540 EVPE = 0x3,
12541
12542 /* bits 15..12 for 0x1d */
12543 DI = 0x4,
12544 EI = 0x5,
12545
12546 /* bits 15..12 for 0x2d */
12547 SYNC = 0x6,
12548 SYSCALL = 0x8,
12549 SDBBP = 0xd,
12550
12551 /* bits 15..12 for 0x35 */
12552 MFHI32 = 0x0,
12553 MFLO32 = 0x1,
12554 MTHI32 = 0x2,
12555 MTLO32 = 0x3,
12556 };
12557
12558 /* POOL32B encoding of minor opcode field (bits 15..12) */
12559
12560 enum {
12561 LWC2 = 0x0,
12562 LWP = 0x1,
12563 LDP = 0x4,
12564 LWM32 = 0x5,
12565 CACHE = 0x6,
12566 LDM = 0x7,
12567 SWC2 = 0x8,
12568 SWP = 0x9,
12569 SDP = 0xc,
12570 SWM32 = 0xd,
12571 SDM = 0xf
12572 };
12573
12574 /* POOL32C encoding of minor opcode field (bits 15..12) */
12575
12576 enum {
12577 LWL = 0x0,
12578 SWL = 0x8,
12579 LWR = 0x1,
12580 SWR = 0x9,
12581 PREF = 0x2,
12582 ST_EVA = 0xa,
12583 LL = 0x3,
12584 SC = 0xb,
12585 LDL = 0x4,
12586 SDL = 0xc,
12587 LDR = 0x5,
12588 SDR = 0xd,
12589 LD_EVA = 0x6,
12590 LWU = 0xe,
12591 LLD = 0x7,
12592 SCD = 0xf
12593 };
12594
12595 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
12596
12597 enum {
12598 LBUE = 0x0,
12599 LHUE = 0x1,
12600 LWLE = 0x2,
12601 LWRE = 0x3,
12602 LBE = 0x4,
12603 LHE = 0x5,
12604 LLE = 0x6,
12605 LWE = 0x7,
12606 };
12607
12608 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
12609
12610 enum {
12611 SWLE = 0x0,
12612 SWRE = 0x1,
12613 PREFE = 0x2,
12614 CACHEE = 0x3,
12615 SBE = 0x4,
12616 SHE = 0x5,
12617 SCE = 0x6,
12618 SWE = 0x7,
12619 };
12620
12621 /* POOL32F encoding of minor opcode field (bits 5..0) */
12622
12623 enum {
12624 /* These are the bit 7..6 values */
12625 ADD_FMT = 0x0,
12626
12627 SUB_FMT = 0x1,
12628
12629 MUL_FMT = 0x2,
12630
12631 DIV_FMT = 0x3,
12632
12633 /* These are the bit 8..6 values */
12634 MOVN_FMT = 0x0,
12635 RSQRT2_FMT = 0x0,
12636 MOVF_FMT = 0x0,
12637 RINT_FMT = 0x0,
12638 SELNEZ_FMT = 0x0,
12639
12640 MOVZ_FMT = 0x1,
12641 LWXC1 = 0x1,
12642 MOVT_FMT = 0x1,
12643 CLASS_FMT = 0x1,
12644 SELEQZ_FMT = 0x1,
12645
12646 PLL_PS = 0x2,
12647 SWXC1 = 0x2,
12648 SEL_FMT = 0x2,
12649
12650 PLU_PS = 0x3,
12651 LDXC1 = 0x3,
12652
12653 MOVN_FMT_04 = 0x4,
12654 PUL_PS = 0x4,
12655 SDXC1 = 0x4,
12656 RECIP2_FMT = 0x4,
12657
12658 MOVZ_FMT_05 = 0x05,
12659 PUU_PS = 0x5,
12660 LUXC1 = 0x5,
12661
12662 CVT_PS_S = 0x6,
12663 SUXC1 = 0x6,
12664 ADDR_PS = 0x6,
12665 PREFX = 0x6,
12666 MADDF_FMT = 0x6,
12667
12668 MULR_PS = 0x7,
12669 MSUBF_FMT = 0x7,
12670
12671 MADD_S = 0x01,
12672 MADD_D = 0x09,
12673 MADD_PS = 0x11,
12674 ALNV_PS = 0x19,
12675 MSUB_S = 0x21,
12676 MSUB_D = 0x29,
12677 MSUB_PS = 0x31,
12678
12679 NMADD_S = 0x02,
12680 NMADD_D = 0x0a,
12681 NMADD_PS = 0x12,
12682 NMSUB_S = 0x22,
12683 NMSUB_D = 0x2a,
12684 NMSUB_PS = 0x32,
12685
12686 MIN_FMT = 0x3,
12687 MAX_FMT = 0xb,
12688 MINA_FMT = 0x23,
12689 MAXA_FMT = 0x2b,
12690 POOL32FXF = 0x3b,
12691
12692 CABS_COND_FMT = 0x1c, /* MIPS3D */
12693 C_COND_FMT = 0x3c,
12694
12695 CMP_CONDN_S = 0x5,
12696 CMP_CONDN_D = 0x15
12697 };
12698
12699 /* POOL32Fxf encoding of minor opcode extension field */
12700
12701 enum {
12702 CVT_L = 0x04,
12703 RSQRT_FMT = 0x08,
12704 FLOOR_L = 0x0c,
12705 CVT_PW_PS = 0x1c,
12706 CVT_W = 0x24,
12707 SQRT_FMT = 0x28,
12708 FLOOR_W = 0x2c,
12709 CVT_PS_PW = 0x3c,
12710 CFC1 = 0x40,
12711 RECIP_FMT = 0x48,
12712 CEIL_L = 0x4c,
12713 CTC1 = 0x60,
12714 CEIL_W = 0x6c,
12715 MFC1 = 0x80,
12716 CVT_S_PL = 0x84,
12717 TRUNC_L = 0x8c,
12718 MTC1 = 0xa0,
12719 CVT_S_PU = 0xa4,
12720 TRUNC_W = 0xac,
12721 MFHC1 = 0xc0,
12722 ROUND_L = 0xcc,
12723 MTHC1 = 0xe0,
12724 ROUND_W = 0xec,
12725
12726 MOV_FMT = 0x01,
12727 MOVF = 0x05,
12728 ABS_FMT = 0x0d,
12729 RSQRT1_FMT = 0x1d,
12730 MOVT = 0x25,
12731 NEG_FMT = 0x2d,
12732 CVT_D = 0x4d,
12733 RECIP1_FMT = 0x5d,
12734 CVT_S = 0x6d
12735 };
12736
12737 /* POOL32I encoding of minor opcode field (bits 25..21) */
12738
12739 enum {
12740 BLTZ = 0x00,
12741 BLTZAL = 0x01,
12742 BGEZ = 0x02,
12743 BGEZAL = 0x03,
12744 BLEZ = 0x04,
12745 BNEZC = 0x05,
12746 BGTZ = 0x06,
12747 BEQZC = 0x07,
12748 TLTI = 0x08,
12749 BC1EQZC = 0x08,
12750 TGEI = 0x09,
12751 BC1NEZC = 0x09,
12752 TLTIU = 0x0a,
12753 BC2EQZC = 0x0a,
12754 TGEIU = 0x0b,
12755 BC2NEZC = 0x0a,
12756 TNEI = 0x0c,
12757 R6_SYNCI = 0x0c,
12758 LUI = 0x0d,
12759 TEQI = 0x0e,
12760 SYNCI = 0x10,
12761 BLTZALS = 0x11,
12762 BGEZALS = 0x13,
12763 BC2F = 0x14,
12764 BC2T = 0x15,
12765 BPOSGE64 = 0x1a,
12766 BPOSGE32 = 0x1b,
12767 /* These overlap and are distinguished by bit16 of the instruction */
12768 BC1F = 0x1c,
12769 BC1T = 0x1d,
12770 BC1ANY2F = 0x1c,
12771 BC1ANY2T = 0x1d,
12772 BC1ANY4F = 0x1e,
12773 BC1ANY4T = 0x1f
12774 };
12775
12776 /* POOL16A encoding of minor opcode field */
12777
12778 enum {
12779 ADDU16 = 0x0,
12780 SUBU16 = 0x1
12781 };
12782
12783 /* POOL16B encoding of minor opcode field */
12784
12785 enum {
12786 SLL16 = 0x0,
12787 SRL16 = 0x1
12788 };
12789
12790 /* POOL16C encoding of minor opcode field */
12791
12792 enum {
12793 NOT16 = 0x00,
12794 XOR16 = 0x04,
12795 AND16 = 0x08,
12796 OR16 = 0x0c,
12797 LWM16 = 0x10,
12798 SWM16 = 0x14,
12799 JR16 = 0x18,
12800 JRC16 = 0x1a,
12801 JALR16 = 0x1c,
12802 JALR16S = 0x1e,
12803 MFHI16 = 0x20,
12804 MFLO16 = 0x24,
12805 BREAK16 = 0x28,
12806 SDBBP16 = 0x2c,
12807 JRADDIUSP = 0x30
12808 };
12809
12810 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12811
12812 enum {
12813 R6_NOT16 = 0x00,
12814 R6_AND16 = 0x01,
12815 R6_LWM16 = 0x02,
12816 R6_JRC16 = 0x03,
12817 MOVEP = 0x04,
12818 MOVEP_07 = 0x07,
12819 R6_XOR16 = 0x08,
12820 R6_OR16 = 0x09,
12821 R6_SWM16 = 0x0a,
12822 JALRC16 = 0x0b,
12823 MOVEP_0C = 0x0c,
12824 MOVEP_0F = 0x0f,
12825 JRCADDIUSP = 0x13,
12826 R6_BREAK16 = 0x1b,
12827 R6_SDBBP16 = 0x3b
12828 };
12829
12830 /* POOL16D encoding of minor opcode field */
12831
12832 enum {
12833 ADDIUS5 = 0x0,
12834 ADDIUSP = 0x1
12835 };
12836
12837 /* POOL16E encoding of minor opcode field */
12838
12839 enum {
12840 ADDIUR2 = 0x0,
12841 ADDIUR1SP = 0x1
12842 };
12843
12844 static int mmreg (int r)
12845 {
12846 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12847
12848 return map[r];
12849 }
12850
12851 /* Used for 16-bit store instructions. */
12852 static int mmreg2 (int r)
12853 {
12854 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12855
12856 return map[r];
12857 }
12858
12859 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12860 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12861 #define uMIPS_RS2(op) uMIPS_RS(op)
12862 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12863 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12864 #define uMIPS_RS5(op) (op & 0x1f)
12865
12866 /* Signed immediate */
12867 #define SIMM(op, start, width) \
12868 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12869 << (32-width)) \
12870 >> (32-width))
12871 /* Zero-extended immediate */
12872 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12873
12874 static void gen_addiur1sp(DisasContext *ctx)
12875 {
12876 int rd = mmreg(uMIPS_RD(ctx->opcode));
12877
12878 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12879 }
12880
12881 static void gen_addiur2(DisasContext *ctx)
12882 {
12883 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12884 int rd = mmreg(uMIPS_RD(ctx->opcode));
12885 int rs = mmreg(uMIPS_RS(ctx->opcode));
12886
12887 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12888 }
12889
12890 static void gen_addiusp(DisasContext *ctx)
12891 {
12892 int encoded = ZIMM(ctx->opcode, 1, 9);
12893 int decoded;
12894
12895 if (encoded <= 1) {
12896 decoded = 256 + encoded;
12897 } else if (encoded <= 255) {
12898 decoded = encoded;
12899 } else if (encoded <= 509) {
12900 decoded = encoded - 512;
12901 } else {
12902 decoded = encoded - 768;
12903 }
12904
12905 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12906 }
12907
12908 static void gen_addius5(DisasContext *ctx)
12909 {
12910 int imm = SIMM(ctx->opcode, 1, 4);
12911 int rd = (ctx->opcode >> 5) & 0x1f;
12912
12913 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12914 }
12915
12916 static void gen_andi16(DisasContext *ctx)
12917 {
12918 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12919 31, 32, 63, 64, 255, 32768, 65535 };
12920 int rd = mmreg(uMIPS_RD(ctx->opcode));
12921 int rs = mmreg(uMIPS_RS(ctx->opcode));
12922 int encoded = ZIMM(ctx->opcode, 0, 4);
12923
12924 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12925 }
12926
12927 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12928 int base, int16_t offset)
12929 {
12930 TCGv t0, t1;
12931 TCGv_i32 t2;
12932
12933 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12934 generate_exception_end(ctx, EXCP_RI);
12935 return;
12936 }
12937
12938 t0 = tcg_temp_new();
12939
12940 gen_base_offset_addr(ctx, t0, base, offset);
12941
12942 t1 = tcg_const_tl(reglist);
12943 t2 = tcg_const_i32(ctx->mem_idx);
12944
12945 save_cpu_state(ctx, 1);
12946 switch (opc) {
12947 case LWM32:
12948 gen_helper_lwm(cpu_env, t0, t1, t2);
12949 break;
12950 case SWM32:
12951 gen_helper_swm(cpu_env, t0, t1, t2);
12952 break;
12953 #ifdef TARGET_MIPS64
12954 case LDM:
12955 gen_helper_ldm(cpu_env, t0, t1, t2);
12956 break;
12957 case SDM:
12958 gen_helper_sdm(cpu_env, t0, t1, t2);
12959 break;
12960 #endif
12961 }
12962 tcg_temp_free(t0);
12963 tcg_temp_free(t1);
12964 tcg_temp_free_i32(t2);
12965 }
12966
12967
12968 static void gen_pool16c_insn(DisasContext *ctx)
12969 {
12970 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12971 int rs = mmreg(ctx->opcode & 0x7);
12972
12973 switch (((ctx->opcode) >> 4) & 0x3f) {
12974 case NOT16 + 0:
12975 case NOT16 + 1:
12976 case NOT16 + 2:
12977 case NOT16 + 3:
12978 gen_logic(ctx, OPC_NOR, rd, rs, 0);
12979 break;
12980 case XOR16 + 0:
12981 case XOR16 + 1:
12982 case XOR16 + 2:
12983 case XOR16 + 3:
12984 gen_logic(ctx, OPC_XOR, rd, rd, rs);
12985 break;
12986 case AND16 + 0:
12987 case AND16 + 1:
12988 case AND16 + 2:
12989 case AND16 + 3:
12990 gen_logic(ctx, OPC_AND, rd, rd, rs);
12991 break;
12992 case OR16 + 0:
12993 case OR16 + 1:
12994 case OR16 + 2:
12995 case OR16 + 3:
12996 gen_logic(ctx, OPC_OR, rd, rd, rs);
12997 break;
12998 case LWM16 + 0:
12999 case LWM16 + 1:
13000 case LWM16 + 2:
13001 case LWM16 + 3:
13002 {
13003 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13004 int offset = ZIMM(ctx->opcode, 0, 4);
13005
13006 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
13007 29, offset << 2);
13008 }
13009 break;
13010 case SWM16 + 0:
13011 case SWM16 + 1:
13012 case SWM16 + 2:
13013 case SWM16 + 3:
13014 {
13015 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13016 int offset = ZIMM(ctx->opcode, 0, 4);
13017
13018 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
13019 29, offset << 2);
13020 }
13021 break;
13022 case JR16 + 0:
13023 case JR16 + 1:
13024 {
13025 int reg = ctx->opcode & 0x1f;
13026
13027 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
13028 }
13029 break;
13030 case JRC16 + 0:
13031 case JRC16 + 1:
13032 {
13033 int reg = ctx->opcode & 0x1f;
13034 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
13035 /* Let normal delay slot handling in our caller take us
13036 to the branch target. */
13037 }
13038 break;
13039 case JALR16 + 0:
13040 case JALR16 + 1:
13041 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
13042 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13043 break;
13044 case JALR16S + 0:
13045 case JALR16S + 1:
13046 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
13047 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13048 break;
13049 case MFHI16 + 0:
13050 case MFHI16 + 1:
13051 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
13052 break;
13053 case MFLO16 + 0:
13054 case MFLO16 + 1:
13055 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
13056 break;
13057 case BREAK16:
13058 generate_exception_end(ctx, EXCP_BREAK);
13059 break;
13060 case SDBBP16:
13061 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
13062 gen_helper_do_semihosting(cpu_env);
13063 } else {
13064 /* XXX: not clear which exception should be raised
13065 * when in debug mode...
13066 */
13067 check_insn(ctx, ISA_MIPS32);
13068 generate_exception_end(ctx, EXCP_DBp);
13069 }
13070 break;
13071 case JRADDIUSP + 0:
13072 case JRADDIUSP + 1:
13073 {
13074 int imm = ZIMM(ctx->opcode, 0, 5);
13075 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
13076 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
13077 /* Let normal delay slot handling in our caller take us
13078 to the branch target. */
13079 }
13080 break;
13081 default:
13082 generate_exception_end(ctx, EXCP_RI);
13083 break;
13084 }
13085 }
13086
13087 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
13088 int enc_rs)
13089 {
13090 int rd, rs, re, rt;
13091 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13092 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13093 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13094 rd = rd_enc[enc_dest];
13095 re = re_enc[enc_dest];
13096 rs = rs_rt_enc[enc_rs];
13097 rt = rs_rt_enc[enc_rt];
13098 if (rs) {
13099 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
13100 } else {
13101 tcg_gen_movi_tl(cpu_gpr[rd], 0);
13102 }
13103 if (rt) {
13104 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
13105 } else {
13106 tcg_gen_movi_tl(cpu_gpr[re], 0);
13107 }
13108 }
13109
13110 static void gen_pool16c_r6_insn(DisasContext *ctx)
13111 {
13112 int rt = mmreg((ctx->opcode >> 7) & 0x7);
13113 int rs = mmreg((ctx->opcode >> 4) & 0x7);
13114
13115 switch (ctx->opcode & 0xf) {
13116 case R6_NOT16:
13117 gen_logic(ctx, OPC_NOR, rt, rs, 0);
13118 break;
13119 case R6_AND16:
13120 gen_logic(ctx, OPC_AND, rt, rt, rs);
13121 break;
13122 case R6_LWM16:
13123 {
13124 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13125 int offset = extract32(ctx->opcode, 4, 4);
13126 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
13127 }
13128 break;
13129 case R6_JRC16: /* JRCADDIUSP */
13130 if ((ctx->opcode >> 4) & 1) {
13131 /* JRCADDIUSP */
13132 int imm = extract32(ctx->opcode, 5, 5);
13133 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
13134 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
13135 } else {
13136 /* JRC16 */
13137 int rs = extract32(ctx->opcode, 5, 5);
13138 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
13139 }
13140 break;
13141 case MOVEP ... MOVEP_07:
13142 case MOVEP_0C ... MOVEP_0F:
13143 {
13144 int enc_dest = uMIPS_RD(ctx->opcode);
13145 int enc_rt = uMIPS_RS2(ctx->opcode);
13146 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
13147 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
13148 }
13149 break;
13150 case R6_XOR16:
13151 gen_logic(ctx, OPC_XOR, rt, rt, rs);
13152 break;
13153 case R6_OR16:
13154 gen_logic(ctx, OPC_OR, rt, rt, rs);
13155 break;
13156 case R6_SWM16:
13157 {
13158 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13159 int offset = extract32(ctx->opcode, 4, 4);
13160 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13161 }
13162 break;
13163 case JALRC16: /* BREAK16, SDBBP16 */
13164 switch (ctx->opcode & 0x3f) {
13165 case JALRC16:
13166 case JALRC16 + 0x20:
13167 /* JALRC16 */
13168 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13169 31, 0, 0);
13170 break;
13171 case R6_BREAK16:
13172 /* BREAK16 */
13173 generate_exception(ctx, EXCP_BREAK);
13174 break;
13175 case R6_SDBBP16:
13176 /* SDBBP16 */
13177 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13178 gen_helper_do_semihosting(cpu_env);
13179 } else {
13180 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13181 generate_exception(ctx, EXCP_RI);
13182 } else {
13183 generate_exception(ctx, EXCP_DBp);
13184 }
13185 }
13186 break;
13187 }
13188 break;
13189 default:
13190 generate_exception(ctx, EXCP_RI);
13191 break;
13192 }
13193 }
13194
13195 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13196 {
13197 TCGv t0 = tcg_temp_new();
13198 TCGv t1 = tcg_temp_new();
13199
13200 gen_load_gpr(t0, base);
13201
13202 if (index != 0) {
13203 gen_load_gpr(t1, index);
13204 tcg_gen_shli_tl(t1, t1, 2);
13205 gen_op_addr_add(ctx, t0, t1, t0);
13206 }
13207
13208 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13209 gen_store_gpr(t1, rd);
13210
13211 tcg_temp_free(t0);
13212 tcg_temp_free(t1);
13213 }
13214
13215 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13216 int base, int16_t offset)
13217 {
13218 TCGv t0, t1;
13219
13220 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
13221 generate_exception_end(ctx, EXCP_RI);
13222 return;
13223 }
13224
13225 t0 = tcg_temp_new();
13226 t1 = tcg_temp_new();
13227
13228 gen_base_offset_addr(ctx, t0, base, offset);
13229
13230 switch (opc) {
13231 case LWP:
13232 if (rd == base) {
13233 generate_exception_end(ctx, EXCP_RI);
13234 return;
13235 }
13236 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13237 gen_store_gpr(t1, rd);
13238 tcg_gen_movi_tl(t1, 4);
13239 gen_op_addr_add(ctx, t0, t0, t1);
13240 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13241 gen_store_gpr(t1, rd+1);
13242 break;
13243 case SWP:
13244 gen_load_gpr(t1, rd);
13245 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13246 tcg_gen_movi_tl(t1, 4);
13247 gen_op_addr_add(ctx, t0, t0, t1);
13248 gen_load_gpr(t1, rd+1);
13249 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13250 break;
13251 #ifdef TARGET_MIPS64
13252 case LDP:
13253 if (rd == base) {
13254 generate_exception_end(ctx, EXCP_RI);
13255 return;
13256 }
13257 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13258 gen_store_gpr(t1, rd);
13259 tcg_gen_movi_tl(t1, 8);
13260 gen_op_addr_add(ctx, t0, t0, t1);
13261 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13262 gen_store_gpr(t1, rd+1);
13263 break;
13264 case SDP:
13265 gen_load_gpr(t1, rd);
13266 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13267 tcg_gen_movi_tl(t1, 8);
13268 gen_op_addr_add(ctx, t0, t0, t1);
13269 gen_load_gpr(t1, rd+1);
13270 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13271 break;
13272 #endif
13273 }
13274 tcg_temp_free(t0);
13275 tcg_temp_free(t1);
13276 }
13277
13278 static void gen_sync(int stype)
13279 {
13280 TCGBar tcg_mo = TCG_BAR_SC;
13281
13282 switch (stype) {
13283 case 0x4: /* SYNC_WMB */
13284 tcg_mo |= TCG_MO_ST_ST;
13285 break;
13286 case 0x10: /* SYNC_MB */
13287 tcg_mo |= TCG_MO_ALL;
13288 break;
13289 case 0x11: /* SYNC_ACQUIRE */
13290 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13291 break;
13292 case 0x12: /* SYNC_RELEASE */
13293 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13294 break;
13295 case 0x13: /* SYNC_RMB */
13296 tcg_mo |= TCG_MO_LD_LD;
13297 break;
13298 default:
13299 tcg_mo |= TCG_MO_ALL;
13300 break;
13301 }
13302
13303 tcg_gen_mb(tcg_mo);
13304 }
13305
13306 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
13307 {
13308 int extension = (ctx->opcode >> 6) & 0x3f;
13309 int minor = (ctx->opcode >> 12) & 0xf;
13310 uint32_t mips32_op;
13311
13312 switch (extension) {
13313 case TEQ:
13314 mips32_op = OPC_TEQ;
13315 goto do_trap;
13316 case TGE:
13317 mips32_op = OPC_TGE;
13318 goto do_trap;
13319 case TGEU:
13320 mips32_op = OPC_TGEU;
13321 goto do_trap;
13322 case TLT:
13323 mips32_op = OPC_TLT;
13324 goto do_trap;
13325 case TLTU:
13326 mips32_op = OPC_TLTU;
13327 goto do_trap;
13328 case TNE:
13329 mips32_op = OPC_TNE;
13330 do_trap:
13331 gen_trap(ctx, mips32_op, rs, rt, -1);
13332 break;
13333 #ifndef CONFIG_USER_ONLY
13334 case MFC0:
13335 case MFC0 + 32:
13336 check_cp0_enabled(ctx);
13337 if (rt == 0) {
13338 /* Treat as NOP. */
13339 break;
13340 }
13341 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
13342 break;
13343 case MTC0:
13344 case MTC0 + 32:
13345 check_cp0_enabled(ctx);
13346 {
13347 TCGv t0 = tcg_temp_new();
13348
13349 gen_load_gpr(t0, rt);
13350 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
13351 tcg_temp_free(t0);
13352 }
13353 break;
13354 #endif
13355 case 0x2a:
13356 switch (minor & 3) {
13357 case MADD_ACC:
13358 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13359 break;
13360 case MADDU_ACC:
13361 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13362 break;
13363 case MSUB_ACC:
13364 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13365 break;
13366 case MSUBU_ACC:
13367 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13368 break;
13369 default:
13370 goto pool32axf_invalid;
13371 }
13372 break;
13373 case 0x32:
13374 switch (minor & 3) {
13375 case MULT_ACC:
13376 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13377 break;
13378 case MULTU_ACC:
13379 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13380 break;
13381 default:
13382 goto pool32axf_invalid;
13383 }
13384 break;
13385 case 0x2c:
13386 switch (minor) {
13387 case BITSWAP:
13388 check_insn(ctx, ISA_MIPS32R6);
13389 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13390 break;
13391 case SEB:
13392 gen_bshfl(ctx, OPC_SEB, rs, rt);
13393 break;
13394 case SEH:
13395 gen_bshfl(ctx, OPC_SEH, rs, rt);
13396 break;
13397 case CLO:
13398 mips32_op = OPC_CLO;
13399 goto do_cl;
13400 case CLZ:
13401 mips32_op = OPC_CLZ;
13402 do_cl:
13403 check_insn(ctx, ISA_MIPS32);
13404 gen_cl(ctx, mips32_op, rt, rs);
13405 break;
13406 case RDHWR:
13407 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13408 gen_rdhwr(ctx, rt, rs, 0);
13409 break;
13410 case WSBH:
13411 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13412 break;
13413 case MULT:
13414 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13415 mips32_op = OPC_MULT;
13416 goto do_mul;
13417 case MULTU:
13418 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13419 mips32_op = OPC_MULTU;
13420 goto do_mul;
13421 case DIV:
13422 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13423 mips32_op = OPC_DIV;
13424 goto do_div;
13425 case DIVU:
13426 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13427 mips32_op = OPC_DIVU;
13428 goto do_div;
13429 do_div:
13430 check_insn(ctx, ISA_MIPS32);
13431 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13432 break;
13433 case MADD:
13434 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13435 mips32_op = OPC_MADD;
13436 goto do_mul;
13437 case MADDU:
13438 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13439 mips32_op = OPC_MADDU;
13440 goto do_mul;
13441 case MSUB:
13442 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13443 mips32_op = OPC_MSUB;
13444 goto do_mul;
13445 case MSUBU:
13446 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13447 mips32_op = OPC_MSUBU;
13448 do_mul:
13449 check_insn(ctx, ISA_MIPS32);
13450 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13451 break;
13452 default:
13453 goto pool32axf_invalid;
13454 }
13455 break;
13456 case 0x34:
13457 switch (minor) {
13458 case MFC2:
13459 case MTC2:
13460 case MFHC2:
13461 case MTHC2:
13462 case CFC2:
13463 case CTC2:
13464 generate_exception_err(ctx, EXCP_CpU, 2);
13465 break;
13466 default:
13467 goto pool32axf_invalid;
13468 }
13469 break;
13470 case 0x3c:
13471 switch (minor) {
13472 case JALR: /* JALRC */
13473 case JALR_HB: /* JALRC_HB */
13474 if (ctx->insn_flags & ISA_MIPS32R6) {
13475 /* JALRC, JALRC_HB */
13476 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13477 } else {
13478 /* JALR, JALR_HB */
13479 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13480 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13481 }
13482 break;
13483 case JALRS:
13484 case JALRS_HB:
13485 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13486 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13487 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13488 break;
13489 default:
13490 goto pool32axf_invalid;
13491 }
13492 break;
13493 case 0x05:
13494 switch (minor) {
13495 case RDPGPR:
13496 check_cp0_enabled(ctx);
13497 check_insn(ctx, ISA_MIPS32R2);
13498 gen_load_srsgpr(rs, rt);
13499 break;
13500 case WRPGPR:
13501 check_cp0_enabled(ctx);
13502 check_insn(ctx, ISA_MIPS32R2);
13503 gen_store_srsgpr(rs, rt);
13504 break;
13505 default:
13506 goto pool32axf_invalid;
13507 }
13508 break;
13509 #ifndef CONFIG_USER_ONLY
13510 case 0x0d:
13511 switch (minor) {
13512 case TLBP:
13513 mips32_op = OPC_TLBP;
13514 goto do_cp0;
13515 case TLBR:
13516 mips32_op = OPC_TLBR;
13517 goto do_cp0;
13518 case TLBWI:
13519 mips32_op = OPC_TLBWI;
13520 goto do_cp0;
13521 case TLBWR:
13522 mips32_op = OPC_TLBWR;
13523 goto do_cp0;
13524 case TLBINV:
13525 mips32_op = OPC_TLBINV;
13526 goto do_cp0;
13527 case TLBINVF:
13528 mips32_op = OPC_TLBINVF;
13529 goto do_cp0;
13530 case WAIT:
13531 mips32_op = OPC_WAIT;
13532 goto do_cp0;
13533 case DERET:
13534 mips32_op = OPC_DERET;
13535 goto do_cp0;
13536 case ERET:
13537 mips32_op = OPC_ERET;
13538 do_cp0:
13539 gen_cp0(env, ctx, mips32_op, rt, rs);
13540 break;
13541 default:
13542 goto pool32axf_invalid;
13543 }
13544 break;
13545 case 0x1d:
13546 switch (minor) {
13547 case DI:
13548 check_cp0_enabled(ctx);
13549 {
13550 TCGv t0 = tcg_temp_new();
13551
13552 save_cpu_state(ctx, 1);
13553 gen_helper_di(t0, cpu_env);
13554 gen_store_gpr(t0, rs);
13555 /* Stop translation as we may have switched the execution mode */
13556 ctx->bstate = BS_STOP;
13557 tcg_temp_free(t0);
13558 }
13559 break;
13560 case EI:
13561 check_cp0_enabled(ctx);
13562 {
13563 TCGv t0 = tcg_temp_new();
13564
13565 save_cpu_state(ctx, 1);
13566 gen_helper_ei(t0, cpu_env);
13567 gen_store_gpr(t0, rs);
13568 /* Stop translation as we may have switched the execution mode */
13569 ctx->bstate = BS_STOP;
13570 tcg_temp_free(t0);
13571 }
13572 break;
13573 default:
13574 goto pool32axf_invalid;
13575 }
13576 break;
13577 #endif
13578 case 0x2d:
13579 switch (minor) {
13580 case SYNC:
13581 gen_sync(extract32(ctx->opcode, 16, 5));
13582 break;
13583 case SYSCALL:
13584 generate_exception_end(ctx, EXCP_SYSCALL);
13585 break;
13586 case SDBBP:
13587 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13588 gen_helper_do_semihosting(cpu_env);
13589 } else {
13590 check_insn(ctx, ISA_MIPS32);
13591 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13592 generate_exception_end(ctx, EXCP_RI);
13593 } else {
13594 generate_exception_end(ctx, EXCP_DBp);
13595 }
13596 }
13597 break;
13598 default:
13599 goto pool32axf_invalid;
13600 }
13601 break;
13602 case 0x01:
13603 switch (minor & 3) {
13604 case MFHI_ACC:
13605 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13606 break;
13607 case MFLO_ACC:
13608 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13609 break;
13610 case MTHI_ACC:
13611 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13612 break;
13613 case MTLO_ACC:
13614 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13615 break;
13616 default:
13617 goto pool32axf_invalid;
13618 }
13619 break;
13620 case 0x35:
13621 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13622 switch (minor) {
13623 case MFHI32:
13624 gen_HILO(ctx, OPC_MFHI, 0, rs);
13625 break;
13626 case MFLO32:
13627 gen_HILO(ctx, OPC_MFLO, 0, rs);
13628 break;
13629 case MTHI32:
13630 gen_HILO(ctx, OPC_MTHI, 0, rs);
13631 break;
13632 case MTLO32:
13633 gen_HILO(ctx, OPC_MTLO, 0, rs);
13634 break;
13635 default:
13636 goto pool32axf_invalid;
13637 }
13638 break;
13639 default:
13640 pool32axf_invalid:
13641 MIPS_INVAL("pool32axf");
13642 generate_exception_end(ctx, EXCP_RI);
13643 break;
13644 }
13645 }
13646
13647 /* Values for microMIPS fmt field. Variable-width, depending on which
13648 formats the instruction supports. */
13649
13650 enum {
13651 FMT_SD_S = 0,
13652 FMT_SD_D = 1,
13653
13654 FMT_SDPS_S = 0,
13655 FMT_SDPS_D = 1,
13656 FMT_SDPS_PS = 2,
13657
13658 FMT_SWL_S = 0,
13659 FMT_SWL_W = 1,
13660 FMT_SWL_L = 2,
13661
13662 FMT_DWL_D = 0,
13663 FMT_DWL_W = 1,
13664 FMT_DWL_L = 2
13665 };
13666
13667 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13668 {
13669 int extension = (ctx->opcode >> 6) & 0x3ff;
13670 uint32_t mips32_op;
13671
13672 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13673 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13674 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13675
13676 switch (extension) {
13677 case FLOAT_1BIT_FMT(CFC1, 0):
13678 mips32_op = OPC_CFC1;
13679 goto do_cp1;
13680 case FLOAT_1BIT_FMT(CTC1, 0):
13681 mips32_op = OPC_CTC1;
13682 goto do_cp1;
13683 case FLOAT_1BIT_FMT(MFC1, 0):
13684 mips32_op = OPC_MFC1;
13685 goto do_cp1;
13686 case FLOAT_1BIT_FMT(MTC1, 0):
13687 mips32_op = OPC_MTC1;
13688 goto do_cp1;
13689 case FLOAT_1BIT_FMT(MFHC1, 0):
13690 mips32_op = OPC_MFHC1;
13691 goto do_cp1;
13692 case FLOAT_1BIT_FMT(MTHC1, 0):
13693 mips32_op = OPC_MTHC1;
13694 do_cp1:
13695 gen_cp1(ctx, mips32_op, rt, rs);
13696 break;
13697
13698 /* Reciprocal square root */
13699 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13700 mips32_op = OPC_RSQRT_S;
13701 goto do_unaryfp;
13702 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13703 mips32_op = OPC_RSQRT_D;
13704 goto do_unaryfp;
13705
13706 /* Square root */
13707 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13708 mips32_op = OPC_SQRT_S;
13709 goto do_unaryfp;
13710 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13711 mips32_op = OPC_SQRT_D;
13712 goto do_unaryfp;
13713
13714 /* Reciprocal */
13715 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13716 mips32_op = OPC_RECIP_S;
13717 goto do_unaryfp;
13718 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13719 mips32_op = OPC_RECIP_D;
13720 goto do_unaryfp;
13721
13722 /* Floor */
13723 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13724 mips32_op = OPC_FLOOR_L_S;
13725 goto do_unaryfp;
13726 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13727 mips32_op = OPC_FLOOR_L_D;
13728 goto do_unaryfp;
13729 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13730 mips32_op = OPC_FLOOR_W_S;
13731 goto do_unaryfp;
13732 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13733 mips32_op = OPC_FLOOR_W_D;
13734 goto do_unaryfp;
13735
13736 /* Ceiling */
13737 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13738 mips32_op = OPC_CEIL_L_S;
13739 goto do_unaryfp;
13740 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13741 mips32_op = OPC_CEIL_L_D;
13742 goto do_unaryfp;
13743 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13744 mips32_op = OPC_CEIL_W_S;
13745 goto do_unaryfp;
13746 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13747 mips32_op = OPC_CEIL_W_D;
13748 goto do_unaryfp;
13749
13750 /* Truncation */
13751 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13752 mips32_op = OPC_TRUNC_L_S;
13753 goto do_unaryfp;
13754 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13755 mips32_op = OPC_TRUNC_L_D;
13756 goto do_unaryfp;
13757 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13758 mips32_op = OPC_TRUNC_W_S;
13759 goto do_unaryfp;
13760 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13761 mips32_op = OPC_TRUNC_W_D;
13762 goto do_unaryfp;
13763
13764 /* Round */
13765 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13766 mips32_op = OPC_ROUND_L_S;
13767 goto do_unaryfp;
13768 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13769 mips32_op = OPC_ROUND_L_D;
13770 goto do_unaryfp;
13771 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13772 mips32_op = OPC_ROUND_W_S;
13773 goto do_unaryfp;
13774 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13775 mips32_op = OPC_ROUND_W_D;
13776 goto do_unaryfp;
13777
13778 /* Integer to floating-point conversion */
13779 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13780 mips32_op = OPC_CVT_L_S;
13781 goto do_unaryfp;
13782 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13783 mips32_op = OPC_CVT_L_D;
13784 goto do_unaryfp;
13785 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13786 mips32_op = OPC_CVT_W_S;
13787 goto do_unaryfp;
13788 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13789 mips32_op = OPC_CVT_W_D;
13790 goto do_unaryfp;
13791
13792 /* Paired-foo conversions */
13793 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13794 mips32_op = OPC_CVT_S_PL;
13795 goto do_unaryfp;
13796 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13797 mips32_op = OPC_CVT_S_PU;
13798 goto do_unaryfp;
13799 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13800 mips32_op = OPC_CVT_PW_PS;
13801 goto do_unaryfp;
13802 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13803 mips32_op = OPC_CVT_PS_PW;
13804 goto do_unaryfp;
13805
13806 /* Floating-point moves */
13807 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13808 mips32_op = OPC_MOV_S;
13809 goto do_unaryfp;
13810 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13811 mips32_op = OPC_MOV_D;
13812 goto do_unaryfp;
13813 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13814 mips32_op = OPC_MOV_PS;
13815 goto do_unaryfp;
13816
13817 /* Absolute value */
13818 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13819 mips32_op = OPC_ABS_S;
13820 goto do_unaryfp;
13821 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13822 mips32_op = OPC_ABS_D;
13823 goto do_unaryfp;
13824 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13825 mips32_op = OPC_ABS_PS;
13826 goto do_unaryfp;
13827
13828 /* Negation */
13829 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13830 mips32_op = OPC_NEG_S;
13831 goto do_unaryfp;
13832 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13833 mips32_op = OPC_NEG_D;
13834 goto do_unaryfp;
13835 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13836 mips32_op = OPC_NEG_PS;
13837 goto do_unaryfp;
13838
13839 /* Reciprocal square root step */
13840 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13841 mips32_op = OPC_RSQRT1_S;
13842 goto do_unaryfp;
13843 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13844 mips32_op = OPC_RSQRT1_D;
13845 goto do_unaryfp;
13846 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13847 mips32_op = OPC_RSQRT1_PS;
13848 goto do_unaryfp;
13849
13850 /* Reciprocal step */
13851 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13852 mips32_op = OPC_RECIP1_S;
13853 goto do_unaryfp;
13854 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13855 mips32_op = OPC_RECIP1_S;
13856 goto do_unaryfp;
13857 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13858 mips32_op = OPC_RECIP1_PS;
13859 goto do_unaryfp;
13860
13861 /* Conversions from double */
13862 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13863 mips32_op = OPC_CVT_D_S;
13864 goto do_unaryfp;
13865 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13866 mips32_op = OPC_CVT_D_W;
13867 goto do_unaryfp;
13868 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13869 mips32_op = OPC_CVT_D_L;
13870 goto do_unaryfp;
13871
13872 /* Conversions from single */
13873 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13874 mips32_op = OPC_CVT_S_D;
13875 goto do_unaryfp;
13876 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13877 mips32_op = OPC_CVT_S_W;
13878 goto do_unaryfp;
13879 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13880 mips32_op = OPC_CVT_S_L;
13881 do_unaryfp:
13882 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13883 break;
13884
13885 /* Conditional moves on floating-point codes */
13886 case COND_FLOAT_MOV(MOVT, 0):
13887 case COND_FLOAT_MOV(MOVT, 1):
13888 case COND_FLOAT_MOV(MOVT, 2):
13889 case COND_FLOAT_MOV(MOVT, 3):
13890 case COND_FLOAT_MOV(MOVT, 4):
13891 case COND_FLOAT_MOV(MOVT, 5):
13892 case COND_FLOAT_MOV(MOVT, 6):
13893 case COND_FLOAT_MOV(MOVT, 7):
13894 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13895 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13896 break;
13897 case COND_FLOAT_MOV(MOVF, 0):
13898 case COND_FLOAT_MOV(MOVF, 1):
13899 case COND_FLOAT_MOV(MOVF, 2):
13900 case COND_FLOAT_MOV(MOVF, 3):
13901 case COND_FLOAT_MOV(MOVF, 4):
13902 case COND_FLOAT_MOV(MOVF, 5):
13903 case COND_FLOAT_MOV(MOVF, 6):
13904 case COND_FLOAT_MOV(MOVF, 7):
13905 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13906 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13907 break;
13908 default:
13909 MIPS_INVAL("pool32fxf");
13910 generate_exception_end(ctx, EXCP_RI);
13911 break;
13912 }
13913 }
13914
13915 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13916 {
13917 int32_t offset;
13918 uint16_t insn;
13919 int rt, rs, rd, rr;
13920 int16_t imm;
13921 uint32_t op, minor, minor2, mips32_op;
13922 uint32_t cond, fmt, cc;
13923
13924 insn = cpu_lduw_code(env, ctx->pc + 2);
13925 ctx->opcode = (ctx->opcode << 16) | insn;
13926
13927 rt = (ctx->opcode >> 21) & 0x1f;
13928 rs = (ctx->opcode >> 16) & 0x1f;
13929 rd = (ctx->opcode >> 11) & 0x1f;
13930 rr = (ctx->opcode >> 6) & 0x1f;
13931 imm = (int16_t) ctx->opcode;
13932
13933 op = (ctx->opcode >> 26) & 0x3f;
13934 switch (op) {
13935 case POOL32A:
13936 minor = ctx->opcode & 0x3f;
13937 switch (minor) {
13938 case 0x00:
13939 minor = (ctx->opcode >> 6) & 0xf;
13940 switch (minor) {
13941 case SLL32:
13942 mips32_op = OPC_SLL;
13943 goto do_shifti;
13944 case SRA:
13945 mips32_op = OPC_SRA;
13946 goto do_shifti;
13947 case SRL32:
13948 mips32_op = OPC_SRL;
13949 goto do_shifti;
13950 case ROTR:
13951 mips32_op = OPC_ROTR;
13952 do_shifti:
13953 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13954 break;
13955 case SELEQZ:
13956 check_insn(ctx, ISA_MIPS32R6);
13957 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13958 break;
13959 case SELNEZ:
13960 check_insn(ctx, ISA_MIPS32R6);
13961 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13962 break;
13963 case R6_RDHWR:
13964 check_insn(ctx, ISA_MIPS32R6);
13965 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13966 break;
13967 default:
13968 goto pool32a_invalid;
13969 }
13970 break;
13971 case 0x10:
13972 minor = (ctx->opcode >> 6) & 0xf;
13973 switch (minor) {
13974 /* Arithmetic */
13975 case ADD:
13976 mips32_op = OPC_ADD;
13977 goto do_arith;
13978 case ADDU32:
13979 mips32_op = OPC_ADDU;
13980 goto do_arith;
13981 case SUB:
13982 mips32_op = OPC_SUB;
13983 goto do_arith;
13984 case SUBU32:
13985 mips32_op = OPC_SUBU;
13986 goto do_arith;
13987 case MUL:
13988 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13989 mips32_op = OPC_MUL;
13990 do_arith:
13991 gen_arith(ctx, mips32_op, rd, rs, rt);
13992 break;
13993 /* Shifts */
13994 case SLLV:
13995 mips32_op = OPC_SLLV;
13996 goto do_shift;
13997 case SRLV:
13998 mips32_op = OPC_SRLV;
13999 goto do_shift;
14000 case SRAV:
14001 mips32_op = OPC_SRAV;
14002 goto do_shift;
14003 case ROTRV:
14004 mips32_op = OPC_ROTRV;
14005 do_shift:
14006 gen_shift(ctx, mips32_op, rd, rs, rt);
14007 break;
14008 /* Logical operations */
14009 case AND:
14010 mips32_op = OPC_AND;
14011 goto do_logic;
14012 case OR32:
14013 mips32_op = OPC_OR;
14014 goto do_logic;
14015 case NOR:
14016 mips32_op = OPC_NOR;
14017 goto do_logic;
14018 case XOR32:
14019 mips32_op = OPC_XOR;
14020 do_logic:
14021 gen_logic(ctx, mips32_op, rd, rs, rt);
14022 break;
14023 /* Set less than */
14024 case SLT:
14025 mips32_op = OPC_SLT;
14026 goto do_slt;
14027 case SLTU:
14028 mips32_op = OPC_SLTU;
14029 do_slt:
14030 gen_slt(ctx, mips32_op, rd, rs, rt);
14031 break;
14032 default:
14033 goto pool32a_invalid;
14034 }
14035 break;
14036 case 0x18:
14037 minor = (ctx->opcode >> 6) & 0xf;
14038 switch (minor) {
14039 /* Conditional moves */
14040 case MOVN: /* MUL */
14041 if (ctx->insn_flags & ISA_MIPS32R6) {
14042 /* MUL */
14043 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
14044 } else {
14045 /* MOVN */
14046 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
14047 }
14048 break;
14049 case MOVZ: /* MUH */
14050 if (ctx->insn_flags & ISA_MIPS32R6) {
14051 /* MUH */
14052 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
14053 } else {
14054 /* MOVZ */
14055 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
14056 }
14057 break;
14058 case MULU:
14059 check_insn(ctx, ISA_MIPS32R6);
14060 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
14061 break;
14062 case MUHU:
14063 check_insn(ctx, ISA_MIPS32R6);
14064 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
14065 break;
14066 case LWXS: /* DIV */
14067 if (ctx->insn_flags & ISA_MIPS32R6) {
14068 /* DIV */
14069 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
14070 } else {
14071 /* LWXS */
14072 gen_ldxs(ctx, rs, rt, rd);
14073 }
14074 break;
14075 case MOD:
14076 check_insn(ctx, ISA_MIPS32R6);
14077 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
14078 break;
14079 case R6_DIVU:
14080 check_insn(ctx, ISA_MIPS32R6);
14081 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
14082 break;
14083 case MODU:
14084 check_insn(ctx, ISA_MIPS32R6);
14085 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
14086 break;
14087 default:
14088 goto pool32a_invalid;
14089 }
14090 break;
14091 case INS:
14092 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
14093 return;
14094 case LSA:
14095 check_insn(ctx, ISA_MIPS32R6);
14096 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
14097 extract32(ctx->opcode, 9, 2));
14098 break;
14099 case ALIGN:
14100 check_insn(ctx, ISA_MIPS32R6);
14101 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
14102 extract32(ctx->opcode, 9, 2));
14103 break;
14104 case EXT:
14105 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
14106 return;
14107 case POOL32AXF:
14108 gen_pool32axf(env, ctx, rt, rs);
14109 break;
14110 case BREAK32:
14111 generate_exception_end(ctx, EXCP_BREAK);
14112 break;
14113 case SIGRIE:
14114 check_insn(ctx, ISA_MIPS32R6);
14115 generate_exception_end(ctx, EXCP_RI);
14116 break;
14117 default:
14118 pool32a_invalid:
14119 MIPS_INVAL("pool32a");
14120 generate_exception_end(ctx, EXCP_RI);
14121 break;
14122 }
14123 break;
14124 case POOL32B:
14125 minor = (ctx->opcode >> 12) & 0xf;
14126 switch (minor) {
14127 case CACHE:
14128 check_cp0_enabled(ctx);
14129 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14130 gen_cache_operation(ctx, rt, rs, imm);
14131 }
14132 break;
14133 case LWC2:
14134 case SWC2:
14135 /* COP2: Not implemented. */
14136 generate_exception_err(ctx, EXCP_CpU, 2);
14137 break;
14138 #ifdef TARGET_MIPS64
14139 case LDP:
14140 case SDP:
14141 check_insn(ctx, ISA_MIPS3);
14142 check_mips_64(ctx);
14143 /* Fallthrough */
14144 #endif
14145 case LWP:
14146 case SWP:
14147 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14148 break;
14149 #ifdef TARGET_MIPS64
14150 case LDM:
14151 case SDM:
14152 check_insn(ctx, ISA_MIPS3);
14153 check_mips_64(ctx);
14154 /* Fallthrough */
14155 #endif
14156 case LWM32:
14157 case SWM32:
14158 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14159 break;
14160 default:
14161 MIPS_INVAL("pool32b");
14162 generate_exception_end(ctx, EXCP_RI);
14163 break;
14164 }
14165 break;
14166 case POOL32F:
14167 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
14168 minor = ctx->opcode & 0x3f;
14169 check_cp1_enabled(ctx);
14170 switch (minor) {
14171 case ALNV_PS:
14172 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14173 mips32_op = OPC_ALNV_PS;
14174 goto do_madd;
14175 case MADD_S:
14176 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14177 mips32_op = OPC_MADD_S;
14178 goto do_madd;
14179 case MADD_D:
14180 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14181 mips32_op = OPC_MADD_D;
14182 goto do_madd;
14183 case MADD_PS:
14184 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14185 mips32_op = OPC_MADD_PS;
14186 goto do_madd;
14187 case MSUB_S:
14188 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14189 mips32_op = OPC_MSUB_S;
14190 goto do_madd;
14191 case MSUB_D:
14192 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14193 mips32_op = OPC_MSUB_D;
14194 goto do_madd;
14195 case MSUB_PS:
14196 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14197 mips32_op = OPC_MSUB_PS;
14198 goto do_madd;
14199 case NMADD_S:
14200 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14201 mips32_op = OPC_NMADD_S;
14202 goto do_madd;
14203 case NMADD_D:
14204 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14205 mips32_op = OPC_NMADD_D;
14206 goto do_madd;
14207 case NMADD_PS:
14208 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14209 mips32_op = OPC_NMADD_PS;
14210 goto do_madd;
14211 case NMSUB_S:
14212 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14213 mips32_op = OPC_NMSUB_S;
14214 goto do_madd;
14215 case NMSUB_D:
14216 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14217 mips32_op = OPC_NMSUB_D;
14218 goto do_madd;
14219 case NMSUB_PS:
14220 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14221 mips32_op = OPC_NMSUB_PS;
14222 do_madd:
14223 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14224 break;
14225 case CABS_COND_FMT:
14226 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14227 cond = (ctx->opcode >> 6) & 0xf;
14228 cc = (ctx->opcode >> 13) & 0x7;
14229 fmt = (ctx->opcode >> 10) & 0x3;
14230 switch (fmt) {
14231 case 0x0:
14232 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14233 break;
14234 case 0x1:
14235 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14236 break;
14237 case 0x2:
14238 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14239 break;
14240 default:
14241 goto pool32f_invalid;
14242 }
14243 break;
14244 case C_COND_FMT:
14245 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14246 cond = (ctx->opcode >> 6) & 0xf;
14247 cc = (ctx->opcode >> 13) & 0x7;
14248 fmt = (ctx->opcode >> 10) & 0x3;
14249 switch (fmt) {
14250 case 0x0:
14251 gen_cmp_s(ctx, cond, rt, rs, cc);
14252 break;
14253 case 0x1:
14254 gen_cmp_d(ctx, cond, rt, rs, cc);
14255 break;
14256 case 0x2:
14257 gen_cmp_ps(ctx, cond, rt, rs, cc);
14258 break;
14259 default:
14260 goto pool32f_invalid;
14261 }
14262 break;
14263 case CMP_CONDN_S:
14264 check_insn(ctx, ISA_MIPS32R6);
14265 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14266 break;
14267 case CMP_CONDN_D:
14268 check_insn(ctx, ISA_MIPS32R6);
14269 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14270 break;
14271 case POOL32FXF:
14272 gen_pool32fxf(ctx, rt, rs);
14273 break;
14274 case 0x00:
14275 /* PLL foo */
14276 switch ((ctx->opcode >> 6) & 0x7) {
14277 case PLL_PS:
14278 mips32_op = OPC_PLL_PS;
14279 goto do_ps;
14280 case PLU_PS:
14281 mips32_op = OPC_PLU_PS;
14282 goto do_ps;
14283 case PUL_PS:
14284 mips32_op = OPC_PUL_PS;
14285 goto do_ps;
14286 case PUU_PS:
14287 mips32_op = OPC_PUU_PS;
14288 goto do_ps;
14289 case CVT_PS_S:
14290 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14291 mips32_op = OPC_CVT_PS_S;
14292 do_ps:
14293 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14294 break;
14295 default:
14296 goto pool32f_invalid;
14297 }
14298 break;
14299 case MIN_FMT:
14300 check_insn(ctx, ISA_MIPS32R6);
14301 switch ((ctx->opcode >> 9) & 0x3) {
14302 case FMT_SDPS_S:
14303 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14304 break;
14305 case FMT_SDPS_D:
14306 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14307 break;
14308 default:
14309 goto pool32f_invalid;
14310 }
14311 break;
14312 case 0x08:
14313 /* [LS][WDU]XC1 */
14314 switch ((ctx->opcode >> 6) & 0x7) {
14315 case LWXC1:
14316 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14317 mips32_op = OPC_LWXC1;
14318 goto do_ldst_cp1;
14319 case SWXC1:
14320 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14321 mips32_op = OPC_SWXC1;
14322 goto do_ldst_cp1;
14323 case LDXC1:
14324 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14325 mips32_op = OPC_LDXC1;
14326 goto do_ldst_cp1;
14327 case SDXC1:
14328 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14329 mips32_op = OPC_SDXC1;
14330 goto do_ldst_cp1;
14331 case LUXC1:
14332 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14333 mips32_op = OPC_LUXC1;
14334 goto do_ldst_cp1;
14335 case SUXC1:
14336 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14337 mips32_op = OPC_SUXC1;
14338 do_ldst_cp1:
14339 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14340 break;
14341 default:
14342 goto pool32f_invalid;
14343 }
14344 break;
14345 case MAX_FMT:
14346 check_insn(ctx, ISA_MIPS32R6);
14347 switch ((ctx->opcode >> 9) & 0x3) {
14348 case FMT_SDPS_S:
14349 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14350 break;
14351 case FMT_SDPS_D:
14352 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14353 break;
14354 default:
14355 goto pool32f_invalid;
14356 }
14357 break;
14358 case 0x18:
14359 /* 3D insns */
14360 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14361 fmt = (ctx->opcode >> 9) & 0x3;
14362 switch ((ctx->opcode >> 6) & 0x7) {
14363 case RSQRT2_FMT:
14364 switch (fmt) {
14365 case FMT_SDPS_S:
14366 mips32_op = OPC_RSQRT2_S;
14367 goto do_3d;
14368 case FMT_SDPS_D:
14369 mips32_op = OPC_RSQRT2_D;
14370 goto do_3d;
14371 case FMT_SDPS_PS:
14372 mips32_op = OPC_RSQRT2_PS;
14373 goto do_3d;
14374 default:
14375 goto pool32f_invalid;
14376 }
14377 break;
14378 case RECIP2_FMT:
14379 switch (fmt) {
14380 case FMT_SDPS_S:
14381 mips32_op = OPC_RECIP2_S;
14382 goto do_3d;
14383 case FMT_SDPS_D:
14384 mips32_op = OPC_RECIP2_D;
14385 goto do_3d;
14386 case FMT_SDPS_PS:
14387 mips32_op = OPC_RECIP2_PS;
14388 goto do_3d;
14389 default:
14390 goto pool32f_invalid;
14391 }
14392 break;
14393 case ADDR_PS:
14394 mips32_op = OPC_ADDR_PS;
14395 goto do_3d;
14396 case MULR_PS:
14397 mips32_op = OPC_MULR_PS;
14398 do_3d:
14399 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14400 break;
14401 default:
14402 goto pool32f_invalid;
14403 }
14404 break;
14405 case 0x20:
14406 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14407 cc = (ctx->opcode >> 13) & 0x7;
14408 fmt = (ctx->opcode >> 9) & 0x3;
14409 switch ((ctx->opcode >> 6) & 0x7) {
14410 case MOVF_FMT: /* RINT_FMT */
14411 if (ctx->insn_flags & ISA_MIPS32R6) {
14412 /* RINT_FMT */
14413 switch (fmt) {
14414 case FMT_SDPS_S:
14415 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14416 break;
14417 case FMT_SDPS_D:
14418 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14419 break;
14420 default:
14421 goto pool32f_invalid;
14422 }
14423 } else {
14424 /* MOVF_FMT */
14425 switch (fmt) {
14426 case FMT_SDPS_S:
14427 gen_movcf_s(ctx, rs, rt, cc, 0);
14428 break;
14429 case FMT_SDPS_D:
14430 gen_movcf_d(ctx, rs, rt, cc, 0);
14431 break;
14432 case FMT_SDPS_PS:
14433 check_ps(ctx);
14434 gen_movcf_ps(ctx, rs, rt, cc, 0);
14435 break;
14436 default:
14437 goto pool32f_invalid;
14438 }
14439 }
14440 break;
14441 case MOVT_FMT: /* CLASS_FMT */
14442 if (ctx->insn_flags & ISA_MIPS32R6) {
14443 /* CLASS_FMT */
14444 switch (fmt) {
14445 case FMT_SDPS_S:
14446 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14447 break;
14448 case FMT_SDPS_D:
14449 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14450 break;
14451 default:
14452 goto pool32f_invalid;
14453 }
14454 } else {
14455 /* MOVT_FMT */
14456 switch (fmt) {
14457 case FMT_SDPS_S:
14458 gen_movcf_s(ctx, rs, rt, cc, 1);
14459 break;
14460 case FMT_SDPS_D:
14461 gen_movcf_d(ctx, rs, rt, cc, 1);
14462 break;
14463 case FMT_SDPS_PS:
14464 check_ps(ctx);
14465 gen_movcf_ps(ctx, rs, rt, cc, 1);
14466 break;
14467 default:
14468 goto pool32f_invalid;
14469 }
14470 }
14471 break;
14472 case PREFX:
14473 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14474 break;
14475 default:
14476 goto pool32f_invalid;
14477 }
14478 break;
14479 #define FINSN_3ARG_SDPS(prfx) \
14480 switch ((ctx->opcode >> 8) & 0x3) { \
14481 case FMT_SDPS_S: \
14482 mips32_op = OPC_##prfx##_S; \
14483 goto do_fpop; \
14484 case FMT_SDPS_D: \
14485 mips32_op = OPC_##prfx##_D; \
14486 goto do_fpop; \
14487 case FMT_SDPS_PS: \
14488 check_ps(ctx); \
14489 mips32_op = OPC_##prfx##_PS; \
14490 goto do_fpop; \
14491 default: \
14492 goto pool32f_invalid; \
14493 }
14494 case MINA_FMT:
14495 check_insn(ctx, ISA_MIPS32R6);
14496 switch ((ctx->opcode >> 9) & 0x3) {
14497 case FMT_SDPS_S:
14498 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14499 break;
14500 case FMT_SDPS_D:
14501 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14502 break;
14503 default:
14504 goto pool32f_invalid;
14505 }
14506 break;
14507 case MAXA_FMT:
14508 check_insn(ctx, ISA_MIPS32R6);
14509 switch ((ctx->opcode >> 9) & 0x3) {
14510 case FMT_SDPS_S:
14511 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14512 break;
14513 case FMT_SDPS_D:
14514 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14515 break;
14516 default:
14517 goto pool32f_invalid;
14518 }
14519 break;
14520 case 0x30:
14521 /* regular FP ops */
14522 switch ((ctx->opcode >> 6) & 0x3) {
14523 case ADD_FMT:
14524 FINSN_3ARG_SDPS(ADD);
14525 break;
14526 case SUB_FMT:
14527 FINSN_3ARG_SDPS(SUB);
14528 break;
14529 case MUL_FMT:
14530 FINSN_3ARG_SDPS(MUL);
14531 break;
14532 case DIV_FMT:
14533 fmt = (ctx->opcode >> 8) & 0x3;
14534 if (fmt == 1) {
14535 mips32_op = OPC_DIV_D;
14536 } else if (fmt == 0) {
14537 mips32_op = OPC_DIV_S;
14538 } else {
14539 goto pool32f_invalid;
14540 }
14541 goto do_fpop;
14542 default:
14543 goto pool32f_invalid;
14544 }
14545 break;
14546 case 0x38:
14547 /* cmovs */
14548 switch ((ctx->opcode >> 6) & 0x7) {
14549 case MOVN_FMT: /* SELNEZ_FMT */
14550 if (ctx->insn_flags & ISA_MIPS32R6) {
14551 /* SELNEZ_FMT */
14552 switch ((ctx->opcode >> 9) & 0x3) {
14553 case FMT_SDPS_S:
14554 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14555 break;
14556 case FMT_SDPS_D:
14557 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14558 break;
14559 default:
14560 goto pool32f_invalid;
14561 }
14562 } else {
14563 /* MOVN_FMT */
14564 FINSN_3ARG_SDPS(MOVN);
14565 }
14566 break;
14567 case MOVN_FMT_04:
14568 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14569 FINSN_3ARG_SDPS(MOVN);
14570 break;
14571 case MOVZ_FMT: /* SELEQZ_FMT */
14572 if (ctx->insn_flags & ISA_MIPS32R6) {
14573 /* SELEQZ_FMT */
14574 switch ((ctx->opcode >> 9) & 0x3) {
14575 case FMT_SDPS_S:
14576 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14577 break;
14578 case FMT_SDPS_D:
14579 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14580 break;
14581 default:
14582 goto pool32f_invalid;
14583 }
14584 } else {
14585 /* MOVZ_FMT */
14586 FINSN_3ARG_SDPS(MOVZ);
14587 }
14588 break;
14589 case MOVZ_FMT_05:
14590 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14591 FINSN_3ARG_SDPS(MOVZ);
14592 break;
14593 case SEL_FMT:
14594 check_insn(ctx, ISA_MIPS32R6);
14595 switch ((ctx->opcode >> 9) & 0x3) {
14596 case FMT_SDPS_S:
14597 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14598 break;
14599 case FMT_SDPS_D:
14600 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14601 break;
14602 default:
14603 goto pool32f_invalid;
14604 }
14605 break;
14606 case MADDF_FMT:
14607 check_insn(ctx, ISA_MIPS32R6);
14608 switch ((ctx->opcode >> 9) & 0x3) {
14609 case FMT_SDPS_S:
14610 mips32_op = OPC_MADDF_S;
14611 goto do_fpop;
14612 case FMT_SDPS_D:
14613 mips32_op = OPC_MADDF_D;
14614 goto do_fpop;
14615 default:
14616 goto pool32f_invalid;
14617 }
14618 break;
14619 case MSUBF_FMT:
14620 check_insn(ctx, ISA_MIPS32R6);
14621 switch ((ctx->opcode >> 9) & 0x3) {
14622 case FMT_SDPS_S:
14623 mips32_op = OPC_MSUBF_S;
14624 goto do_fpop;
14625 case FMT_SDPS_D:
14626 mips32_op = OPC_MSUBF_D;
14627 goto do_fpop;
14628 default:
14629 goto pool32f_invalid;
14630 }
14631 break;
14632 default:
14633 goto pool32f_invalid;
14634 }
14635 break;
14636 do_fpop:
14637 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14638 break;
14639 default:
14640 pool32f_invalid:
14641 MIPS_INVAL("pool32f");
14642 generate_exception_end(ctx, EXCP_RI);
14643 break;
14644 }
14645 } else {
14646 generate_exception_err(ctx, EXCP_CpU, 1);
14647 }
14648 break;
14649 case POOL32I:
14650 minor = (ctx->opcode >> 21) & 0x1f;
14651 switch (minor) {
14652 case BLTZ:
14653 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14654 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14655 break;
14656 case BLTZAL:
14657 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14658 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14659 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14660 break;
14661 case BLTZALS:
14662 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14663 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14664 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14665 break;
14666 case BGEZ:
14667 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14668 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14669 break;
14670 case BGEZAL:
14671 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14672 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14673 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14674 break;
14675 case BGEZALS:
14676 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14677 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14678 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14679 break;
14680 case BLEZ:
14681 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14682 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14683 break;
14684 case BGTZ:
14685 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14686 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14687 break;
14688
14689 /* Traps */
14690 case TLTI: /* BC1EQZC */
14691 if (ctx->insn_flags & ISA_MIPS32R6) {
14692 /* BC1EQZC */
14693 check_cp1_enabled(ctx);
14694 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14695 } else {
14696 /* TLTI */
14697 mips32_op = OPC_TLTI;
14698 goto do_trapi;
14699 }
14700 break;
14701 case TGEI: /* BC1NEZC */
14702 if (ctx->insn_flags & ISA_MIPS32R6) {
14703 /* BC1NEZC */
14704 check_cp1_enabled(ctx);
14705 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14706 } else {
14707 /* TGEI */
14708 mips32_op = OPC_TGEI;
14709 goto do_trapi;
14710 }
14711 break;
14712 case TLTIU:
14713 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14714 mips32_op = OPC_TLTIU;
14715 goto do_trapi;
14716 case TGEIU:
14717 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14718 mips32_op = OPC_TGEIU;
14719 goto do_trapi;
14720 case TNEI: /* SYNCI */
14721 if (ctx->insn_flags & ISA_MIPS32R6) {
14722 /* SYNCI */
14723 /* Break the TB to be able to sync copied instructions
14724 immediately */
14725 ctx->bstate = BS_STOP;
14726 } else {
14727 /* TNEI */
14728 mips32_op = OPC_TNEI;
14729 goto do_trapi;
14730 }
14731 break;
14732 case TEQI:
14733 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14734 mips32_op = OPC_TEQI;
14735 do_trapi:
14736 gen_trap(ctx, mips32_op, rs, -1, imm);
14737 break;
14738
14739 case BNEZC:
14740 case BEQZC:
14741 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14742 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14743 4, rs, 0, imm << 1, 0);
14744 /* Compact branches don't have a delay slot, so just let
14745 the normal delay slot handling take us to the branch
14746 target. */
14747 break;
14748 case LUI:
14749 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14750 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14751 break;
14752 case SYNCI:
14753 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14754 /* Break the TB to be able to sync copied instructions
14755 immediately */
14756 ctx->bstate = BS_STOP;
14757 break;
14758 case BC2F:
14759 case BC2T:
14760 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14761 /* COP2: Not implemented. */
14762 generate_exception_err(ctx, EXCP_CpU, 2);
14763 break;
14764 case BC1F:
14765 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14766 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14767 goto do_cp1branch;
14768 case BC1T:
14769 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14770 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14771 goto do_cp1branch;
14772 case BC1ANY4F:
14773 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14774 mips32_op = OPC_BC1FANY4;
14775 goto do_cp1mips3d;
14776 case BC1ANY4T:
14777 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14778 mips32_op = OPC_BC1TANY4;
14779 do_cp1mips3d:
14780 check_cop1x(ctx);
14781 check_insn(ctx, ASE_MIPS3D);
14782 /* Fall through */
14783 do_cp1branch:
14784 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14785 check_cp1_enabled(ctx);
14786 gen_compute_branch1(ctx, mips32_op,
14787 (ctx->opcode >> 18) & 0x7, imm << 1);
14788 } else {
14789 generate_exception_err(ctx, EXCP_CpU, 1);
14790 }
14791 break;
14792 case BPOSGE64:
14793 case BPOSGE32:
14794 /* MIPS DSP: not implemented */
14795 /* Fall through */
14796 default:
14797 MIPS_INVAL("pool32i");
14798 generate_exception_end(ctx, EXCP_RI);
14799 break;
14800 }
14801 break;
14802 case POOL32C:
14803 minor = (ctx->opcode >> 12) & 0xf;
14804 offset = sextract32(ctx->opcode, 0,
14805 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14806 switch (minor) {
14807 case LWL:
14808 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14809 mips32_op = OPC_LWL;
14810 goto do_ld_lr;
14811 case SWL:
14812 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14813 mips32_op = OPC_SWL;
14814 goto do_st_lr;
14815 case LWR:
14816 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14817 mips32_op = OPC_LWR;
14818 goto do_ld_lr;
14819 case SWR:
14820 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14821 mips32_op = OPC_SWR;
14822 goto do_st_lr;
14823 #if defined(TARGET_MIPS64)
14824 case LDL:
14825 check_insn(ctx, ISA_MIPS3);
14826 check_mips_64(ctx);
14827 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14828 mips32_op = OPC_LDL;
14829 goto do_ld_lr;
14830 case SDL:
14831 check_insn(ctx, ISA_MIPS3);
14832 check_mips_64(ctx);
14833 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14834 mips32_op = OPC_SDL;
14835 goto do_st_lr;
14836 case LDR:
14837 check_insn(ctx, ISA_MIPS3);
14838 check_mips_64(ctx);
14839 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14840 mips32_op = OPC_LDR;
14841 goto do_ld_lr;
14842 case SDR:
14843 check_insn(ctx, ISA_MIPS3);
14844 check_mips_64(ctx);
14845 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14846 mips32_op = OPC_SDR;
14847 goto do_st_lr;
14848 case LWU:
14849 check_insn(ctx, ISA_MIPS3);
14850 check_mips_64(ctx);
14851 mips32_op = OPC_LWU;
14852 goto do_ld_lr;
14853 case LLD:
14854 check_insn(ctx, ISA_MIPS3);
14855 check_mips_64(ctx);
14856 mips32_op = OPC_LLD;
14857 goto do_ld_lr;
14858 #endif
14859 case LL:
14860 mips32_op = OPC_LL;
14861 goto do_ld_lr;
14862 do_ld_lr:
14863 gen_ld(ctx, mips32_op, rt, rs, offset);
14864 break;
14865 do_st_lr:
14866 gen_st(ctx, mips32_op, rt, rs, offset);
14867 break;
14868 case SC:
14869 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14870 break;
14871 #if defined(TARGET_MIPS64)
14872 case SCD:
14873 check_insn(ctx, ISA_MIPS3);
14874 check_mips_64(ctx);
14875 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14876 break;
14877 #endif
14878 case LD_EVA:
14879 if (!ctx->eva) {
14880 MIPS_INVAL("pool32c ld-eva");
14881 generate_exception_end(ctx, EXCP_RI);
14882 break;
14883 }
14884 check_cp0_enabled(ctx);
14885
14886 minor2 = (ctx->opcode >> 9) & 0x7;
14887 offset = sextract32(ctx->opcode, 0, 9);
14888 switch (minor2) {
14889 case LBUE:
14890 mips32_op = OPC_LBUE;
14891 goto do_ld_lr;
14892 case LHUE:
14893 mips32_op = OPC_LHUE;
14894 goto do_ld_lr;
14895 case LWLE:
14896 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14897 mips32_op = OPC_LWLE;
14898 goto do_ld_lr;
14899 case LWRE:
14900 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14901 mips32_op = OPC_LWRE;
14902 goto do_ld_lr;
14903 case LBE:
14904 mips32_op = OPC_LBE;
14905 goto do_ld_lr;
14906 case LHE:
14907 mips32_op = OPC_LHE;
14908 goto do_ld_lr;
14909 case LLE:
14910 mips32_op = OPC_LLE;
14911 goto do_ld_lr;
14912 case LWE:
14913 mips32_op = OPC_LWE;
14914 goto do_ld_lr;
14915 };
14916 break;
14917 case ST_EVA:
14918 if (!ctx->eva) {
14919 MIPS_INVAL("pool32c st-eva");
14920 generate_exception_end(ctx, EXCP_RI);
14921 break;
14922 }
14923 check_cp0_enabled(ctx);
14924
14925 minor2 = (ctx->opcode >> 9) & 0x7;
14926 offset = sextract32(ctx->opcode, 0, 9);
14927 switch (minor2) {
14928 case SWLE:
14929 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14930 mips32_op = OPC_SWLE;
14931 goto do_st_lr;
14932 case SWRE:
14933 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14934 mips32_op = OPC_SWRE;
14935 goto do_st_lr;
14936 case PREFE:
14937 /* Treat as no-op */
14938 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14939 /* hint codes 24-31 are reserved and signal RI */
14940 generate_exception(ctx, EXCP_RI);
14941 }
14942 break;
14943 case CACHEE:
14944 /* Treat as no-op */
14945 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14946 gen_cache_operation(ctx, rt, rs, offset);
14947 }
14948 break;
14949 case SBE:
14950 mips32_op = OPC_SBE;
14951 goto do_st_lr;
14952 case SHE:
14953 mips32_op = OPC_SHE;
14954 goto do_st_lr;
14955 case SCE:
14956 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
14957 break;
14958 case SWE:
14959 mips32_op = OPC_SWE;
14960 goto do_st_lr;
14961 };
14962 break;
14963 case PREF:
14964 /* Treat as no-op */
14965 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14966 /* hint codes 24-31 are reserved and signal RI */
14967 generate_exception(ctx, EXCP_RI);
14968 }
14969 break;
14970 default:
14971 MIPS_INVAL("pool32c");
14972 generate_exception_end(ctx, EXCP_RI);
14973 break;
14974 }
14975 break;
14976 case ADDI32: /* AUI, LUI */
14977 if (ctx->insn_flags & ISA_MIPS32R6) {
14978 /* AUI, LUI */
14979 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14980 } else {
14981 /* ADDI32 */
14982 mips32_op = OPC_ADDI;
14983 goto do_addi;
14984 }
14985 break;
14986 case ADDIU32:
14987 mips32_op = OPC_ADDIU;
14988 do_addi:
14989 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
14990 break;
14991
14992 /* Logical operations */
14993 case ORI32:
14994 mips32_op = OPC_ORI;
14995 goto do_logici;
14996 case XORI32:
14997 mips32_op = OPC_XORI;
14998 goto do_logici;
14999 case ANDI32:
15000 mips32_op = OPC_ANDI;
15001 do_logici:
15002 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
15003 break;
15004
15005 /* Set less than immediate */
15006 case SLTI32:
15007 mips32_op = OPC_SLTI;
15008 goto do_slti;
15009 case SLTIU32:
15010 mips32_op = OPC_SLTIU;
15011 do_slti:
15012 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
15013 break;
15014 case JALX32:
15015 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15016 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15017 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
15018 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15019 break;
15020 case JALS32: /* BOVC, BEQC, BEQZALC */
15021 if (ctx->insn_flags & ISA_MIPS32R6) {
15022 if (rs >= rt) {
15023 /* BOVC */
15024 mips32_op = OPC_BOVC;
15025 } else if (rs < rt && rs == 0) {
15026 /* BEQZALC */
15027 mips32_op = OPC_BEQZALC;
15028 } else {
15029 /* BEQC */
15030 mips32_op = OPC_BEQC;
15031 }
15032 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15033 } else {
15034 /* JALS32 */
15035 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
15036 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
15037 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15038 }
15039 break;
15040 case BEQ32: /* BC */
15041 if (ctx->insn_flags & ISA_MIPS32R6) {
15042 /* BC */
15043 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
15044 sextract32(ctx->opcode << 1, 0, 27));
15045 } else {
15046 /* BEQ32 */
15047 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
15048 }
15049 break;
15050 case BNE32: /* BALC */
15051 if (ctx->insn_flags & ISA_MIPS32R6) {
15052 /* BALC */
15053 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
15054 sextract32(ctx->opcode << 1, 0, 27));
15055 } else {
15056 /* BNE32 */
15057 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
15058 }
15059 break;
15060 case J32: /* BGTZC, BLTZC, BLTC */
15061 if (ctx->insn_flags & ISA_MIPS32R6) {
15062 if (rs == 0 && rt != 0) {
15063 /* BGTZC */
15064 mips32_op = OPC_BGTZC;
15065 } else if (rs != 0 && rt != 0 && rs == rt) {
15066 /* BLTZC */
15067 mips32_op = OPC_BLTZC;
15068 } else {
15069 /* BLTC */
15070 mips32_op = OPC_BLTC;
15071 }
15072 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15073 } else {
15074 /* J32 */
15075 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
15076 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15077 }
15078 break;
15079 case JAL32: /* BLEZC, BGEZC, BGEC */
15080 if (ctx->insn_flags & ISA_MIPS32R6) {
15081 if (rs == 0 && rt != 0) {
15082 /* BLEZC */
15083 mips32_op = OPC_BLEZC;
15084 } else if (rs != 0 && rt != 0 && rs == rt) {
15085 /* BGEZC */
15086 mips32_op = OPC_BGEZC;
15087 } else {
15088 /* BGEC */
15089 mips32_op = OPC_BGEC;
15090 }
15091 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15092 } else {
15093 /* JAL32 */
15094 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
15095 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15096 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15097 }
15098 break;
15099 /* Floating point (COP1) */
15100 case LWC132:
15101 mips32_op = OPC_LWC1;
15102 goto do_cop1;
15103 case LDC132:
15104 mips32_op = OPC_LDC1;
15105 goto do_cop1;
15106 case SWC132:
15107 mips32_op = OPC_SWC1;
15108 goto do_cop1;
15109 case SDC132:
15110 mips32_op = OPC_SDC1;
15111 do_cop1:
15112 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
15113 break;
15114 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15115 if (ctx->insn_flags & ISA_MIPS32R6) {
15116 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15117 switch ((ctx->opcode >> 16) & 0x1f) {
15118 case ADDIUPC_00 ... ADDIUPC_07:
15119 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
15120 break;
15121 case AUIPC:
15122 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
15123 break;
15124 case ALUIPC:
15125 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
15126 break;
15127 case LWPC_08 ... LWPC_0F:
15128 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
15129 break;
15130 default:
15131 generate_exception(ctx, EXCP_RI);
15132 break;
15133 }
15134 } else {
15135 /* ADDIUPC */
15136 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
15137 int offset = SIMM(ctx->opcode, 0, 23) << 2;
15138
15139 gen_addiupc(ctx, reg, offset, 0, 0);
15140 }
15141 break;
15142 case BNVC: /* BNEC, BNEZALC */
15143 check_insn(ctx, ISA_MIPS32R6);
15144 if (rs >= rt) {
15145 /* BNVC */
15146 mips32_op = OPC_BNVC;
15147 } else if (rs < rt && rs == 0) {
15148 /* BNEZALC */
15149 mips32_op = OPC_BNEZALC;
15150 } else {
15151 /* BNEC */
15152 mips32_op = OPC_BNEC;
15153 }
15154 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15155 break;
15156 case R6_BNEZC: /* JIALC */
15157 check_insn(ctx, ISA_MIPS32R6);
15158 if (rt != 0) {
15159 /* BNEZC */
15160 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
15161 sextract32(ctx->opcode << 1, 0, 22));
15162 } else {
15163 /* JIALC */
15164 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
15165 }
15166 break;
15167 case R6_BEQZC: /* JIC */
15168 check_insn(ctx, ISA_MIPS32R6);
15169 if (rt != 0) {
15170 /* BEQZC */
15171 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
15172 sextract32(ctx->opcode << 1, 0, 22));
15173 } else {
15174 /* JIC */
15175 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
15176 }
15177 break;
15178 case BLEZALC: /* BGEZALC, BGEUC */
15179 check_insn(ctx, ISA_MIPS32R6);
15180 if (rs == 0 && rt != 0) {
15181 /* BLEZALC */
15182 mips32_op = OPC_BLEZALC;
15183 } else if (rs != 0 && rt != 0 && rs == rt) {
15184 /* BGEZALC */
15185 mips32_op = OPC_BGEZALC;
15186 } else {
15187 /* BGEUC */
15188 mips32_op = OPC_BGEUC;
15189 }
15190 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15191 break;
15192 case BGTZALC: /* BLTZALC, BLTUC */
15193 check_insn(ctx, ISA_MIPS32R6);
15194 if (rs == 0 && rt != 0) {
15195 /* BGTZALC */
15196 mips32_op = OPC_BGTZALC;
15197 } else if (rs != 0 && rt != 0 && rs == rt) {
15198 /* BLTZALC */
15199 mips32_op = OPC_BLTZALC;
15200 } else {
15201 /* BLTUC */
15202 mips32_op = OPC_BLTUC;
15203 }
15204 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15205 break;
15206 /* Loads and stores */
15207 case LB32:
15208 mips32_op = OPC_LB;
15209 goto do_ld;
15210 case LBU32:
15211 mips32_op = OPC_LBU;
15212 goto do_ld;
15213 case LH32:
15214 mips32_op = OPC_LH;
15215 goto do_ld;
15216 case LHU32:
15217 mips32_op = OPC_LHU;
15218 goto do_ld;
15219 case LW32:
15220 mips32_op = OPC_LW;
15221 goto do_ld;
15222 #ifdef TARGET_MIPS64
15223 case LD32:
15224 check_insn(ctx, ISA_MIPS3);
15225 check_mips_64(ctx);
15226 mips32_op = OPC_LD;
15227 goto do_ld;
15228 case SD32:
15229 check_insn(ctx, ISA_MIPS3);
15230 check_mips_64(ctx);
15231 mips32_op = OPC_SD;
15232 goto do_st;
15233 #endif
15234 case SB32:
15235 mips32_op = OPC_SB;
15236 goto do_st;
15237 case SH32:
15238 mips32_op = OPC_SH;
15239 goto do_st;
15240 case SW32:
15241 mips32_op = OPC_SW;
15242 goto do_st;
15243 do_ld:
15244 gen_ld(ctx, mips32_op, rt, rs, imm);
15245 break;
15246 do_st:
15247 gen_st(ctx, mips32_op, rt, rs, imm);
15248 break;
15249 default:
15250 generate_exception_end(ctx, EXCP_RI);
15251 break;
15252 }
15253 }
15254
15255 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
15256 {
15257 uint32_t op;
15258
15259 /* make sure instructions are on a halfword boundary */
15260 if (ctx->pc & 0x1) {
15261 env->CP0_BadVAddr = ctx->pc;
15262 generate_exception_end(ctx, EXCP_AdEL);
15263 return 2;
15264 }
15265
15266 op = (ctx->opcode >> 10) & 0x3f;
15267 /* Enforce properly-sized instructions in a delay slot */
15268 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15269 switch (op & 0x7) { /* MSB-3..MSB-5 */
15270 case 0:
15271 /* POOL32A, POOL32B, POOL32I, POOL32C */
15272 case 4:
15273 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15274 case 5:
15275 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15276 case 6:
15277 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15278 case 7:
15279 /* LB32, LH32, LWC132, LDC132, LW32 */
15280 if (ctx->hflags & MIPS_HFLAG_BDS16) {
15281 generate_exception_end(ctx, EXCP_RI);
15282 return 2;
15283 }
15284 break;
15285 case 1:
15286 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15287 case 2:
15288 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15289 case 3:
15290 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15291 if (ctx->hflags & MIPS_HFLAG_BDS32) {
15292 generate_exception_end(ctx, EXCP_RI);
15293 return 2;
15294 }
15295 break;
15296 }
15297 }
15298
15299 switch (op) {
15300 case POOL16A:
15301 {
15302 int rd = mmreg(uMIPS_RD(ctx->opcode));
15303 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15304 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15305 uint32_t opc = 0;
15306
15307 switch (ctx->opcode & 0x1) {
15308 case ADDU16:
15309 opc = OPC_ADDU;
15310 break;
15311 case SUBU16:
15312 opc = OPC_SUBU;
15313 break;
15314 }
15315 if (ctx->insn_flags & ISA_MIPS32R6) {
15316 /* In the Release 6 the register number location in
15317 * the instruction encoding has changed.
15318 */
15319 gen_arith(ctx, opc, rs1, rd, rs2);
15320 } else {
15321 gen_arith(ctx, opc, rd, rs1, rs2);
15322 }
15323 }
15324 break;
15325 case POOL16B:
15326 {
15327 int rd = mmreg(uMIPS_RD(ctx->opcode));
15328 int rs = mmreg(uMIPS_RS(ctx->opcode));
15329 int amount = (ctx->opcode >> 1) & 0x7;
15330 uint32_t opc = 0;
15331 amount = amount == 0 ? 8 : amount;
15332
15333 switch (ctx->opcode & 0x1) {
15334 case SLL16:
15335 opc = OPC_SLL;
15336 break;
15337 case SRL16:
15338 opc = OPC_SRL;
15339 break;
15340 }
15341
15342 gen_shift_imm(ctx, opc, rd, rs, amount);
15343 }
15344 break;
15345 case POOL16C:
15346 if (ctx->insn_flags & ISA_MIPS32R6) {
15347 gen_pool16c_r6_insn(ctx);
15348 } else {
15349 gen_pool16c_insn(ctx);
15350 }
15351 break;
15352 case LWGP16:
15353 {
15354 int rd = mmreg(uMIPS_RD(ctx->opcode));
15355 int rb = 28; /* GP */
15356 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15357
15358 gen_ld(ctx, OPC_LW, rd, rb, offset);
15359 }
15360 break;
15361 case POOL16F:
15362 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15363 if (ctx->opcode & 1) {
15364 generate_exception_end(ctx, EXCP_RI);
15365 } else {
15366 /* MOVEP */
15367 int enc_dest = uMIPS_RD(ctx->opcode);
15368 int enc_rt = uMIPS_RS2(ctx->opcode);
15369 int enc_rs = uMIPS_RS1(ctx->opcode);
15370 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15371 }
15372 break;
15373 case LBU16:
15374 {
15375 int rd = mmreg(uMIPS_RD(ctx->opcode));
15376 int rb = mmreg(uMIPS_RS(ctx->opcode));
15377 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15378 offset = (offset == 0xf ? -1 : offset);
15379
15380 gen_ld(ctx, OPC_LBU, rd, rb, offset);
15381 }
15382 break;
15383 case LHU16:
15384 {
15385 int rd = mmreg(uMIPS_RD(ctx->opcode));
15386 int rb = mmreg(uMIPS_RS(ctx->opcode));
15387 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15388
15389 gen_ld(ctx, OPC_LHU, rd, rb, offset);
15390 }
15391 break;
15392 case LWSP16:
15393 {
15394 int rd = (ctx->opcode >> 5) & 0x1f;
15395 int rb = 29; /* SP */
15396 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15397
15398 gen_ld(ctx, OPC_LW, rd, rb, offset);
15399 }
15400 break;
15401 case LW16:
15402 {
15403 int rd = mmreg(uMIPS_RD(ctx->opcode));
15404 int rb = mmreg(uMIPS_RS(ctx->opcode));
15405 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15406
15407 gen_ld(ctx, OPC_LW, rd, rb, offset);
15408 }
15409 break;
15410 case SB16:
15411 {
15412 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15413 int rb = mmreg(uMIPS_RS(ctx->opcode));
15414 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15415
15416 gen_st(ctx, OPC_SB, rd, rb, offset);
15417 }
15418 break;
15419 case SH16:
15420 {
15421 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15422 int rb = mmreg(uMIPS_RS(ctx->opcode));
15423 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15424
15425 gen_st(ctx, OPC_SH, rd, rb, offset);
15426 }
15427 break;
15428 case SWSP16:
15429 {
15430 int rd = (ctx->opcode >> 5) & 0x1f;
15431 int rb = 29; /* SP */
15432 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15433
15434 gen_st(ctx, OPC_SW, rd, rb, offset);
15435 }
15436 break;
15437 case SW16:
15438 {
15439 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15440 int rb = mmreg(uMIPS_RS(ctx->opcode));
15441 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15442
15443 gen_st(ctx, OPC_SW, rd, rb, offset);
15444 }
15445 break;
15446 case MOVE16:
15447 {
15448 int rd = uMIPS_RD5(ctx->opcode);
15449 int rs = uMIPS_RS5(ctx->opcode);
15450
15451 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
15452 }
15453 break;
15454 case ANDI16:
15455 gen_andi16(ctx);
15456 break;
15457 case POOL16D:
15458 switch (ctx->opcode & 0x1) {
15459 case ADDIUS5:
15460 gen_addius5(ctx);
15461 break;
15462 case ADDIUSP:
15463 gen_addiusp(ctx);
15464 break;
15465 }
15466 break;
15467 case POOL16E:
15468 switch (ctx->opcode & 0x1) {
15469 case ADDIUR2:
15470 gen_addiur2(ctx);
15471 break;
15472 case ADDIUR1SP:
15473 gen_addiur1sp(ctx);
15474 break;
15475 }
15476 break;
15477 case B16: /* BC16 */
15478 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
15479 sextract32(ctx->opcode, 0, 10) << 1,
15480 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15481 break;
15482 case BNEZ16: /* BNEZC16 */
15483 case BEQZ16: /* BEQZC16 */
15484 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15485 mmreg(uMIPS_RD(ctx->opcode)),
15486 0, sextract32(ctx->opcode, 0, 7) << 1,
15487 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15488
15489 break;
15490 case LI16:
15491 {
15492 int reg = mmreg(uMIPS_RD(ctx->opcode));
15493 int imm = ZIMM(ctx->opcode, 0, 7);
15494
15495 imm = (imm == 0x7f ? -1 : imm);
15496 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15497 }
15498 break;
15499 case RES_29:
15500 case RES_31:
15501 case RES_39:
15502 generate_exception_end(ctx, EXCP_RI);
15503 break;
15504 default:
15505 decode_micromips32_opc(env, ctx);
15506 return 4;
15507 }
15508
15509 return 2;
15510 }
15511
15512 /* SmartMIPS extension to MIPS32 */
15513
15514 #if defined(TARGET_MIPS64)
15515
15516 /* MDMX extension to MIPS64 */
15517
15518 #endif
15519
15520 /* MIPSDSP functions. */
15521 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
15522 int rd, int base, int offset)
15523 {
15524 TCGv t0;
15525
15526 check_dsp(ctx);
15527 t0 = tcg_temp_new();
15528
15529 if (base == 0) {
15530 gen_load_gpr(t0, offset);
15531 } else if (offset == 0) {
15532 gen_load_gpr(t0, base);
15533 } else {
15534 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15535 }
15536
15537 switch (opc) {
15538 case OPC_LBUX:
15539 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
15540 gen_store_gpr(t0, rd);
15541 break;
15542 case OPC_LHX:
15543 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
15544 gen_store_gpr(t0, rd);
15545 break;
15546 case OPC_LWX:
15547 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
15548 gen_store_gpr(t0, rd);
15549 break;
15550 #if defined(TARGET_MIPS64)
15551 case OPC_LDX:
15552 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
15553 gen_store_gpr(t0, rd);
15554 break;
15555 #endif
15556 }
15557 tcg_temp_free(t0);
15558 }
15559
15560 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15561 int ret, int v1, int v2)
15562 {
15563 TCGv v1_t;
15564 TCGv v2_t;
15565
15566 if (ret == 0) {
15567 /* Treat as NOP. */
15568 return;
15569 }
15570
15571 v1_t = tcg_temp_new();
15572 v2_t = tcg_temp_new();
15573
15574 gen_load_gpr(v1_t, v1);
15575 gen_load_gpr(v2_t, v2);
15576
15577 switch (op1) {
15578 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15579 case OPC_MULT_G_2E:
15580 check_dspr2(ctx);
15581 switch (op2) {
15582 case OPC_ADDUH_QB:
15583 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15584 break;
15585 case OPC_ADDUH_R_QB:
15586 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15587 break;
15588 case OPC_ADDQH_PH:
15589 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15590 break;
15591 case OPC_ADDQH_R_PH:
15592 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15593 break;
15594 case OPC_ADDQH_W:
15595 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15596 break;
15597 case OPC_ADDQH_R_W:
15598 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15599 break;
15600 case OPC_SUBUH_QB:
15601 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15602 break;
15603 case OPC_SUBUH_R_QB:
15604 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15605 break;
15606 case OPC_SUBQH_PH:
15607 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15608 break;
15609 case OPC_SUBQH_R_PH:
15610 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15611 break;
15612 case OPC_SUBQH_W:
15613 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15614 break;
15615 case OPC_SUBQH_R_W:
15616 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15617 break;
15618 }
15619 break;
15620 case OPC_ABSQ_S_PH_DSP:
15621 switch (op2) {
15622 case OPC_ABSQ_S_QB:
15623 check_dspr2(ctx);
15624 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15625 break;
15626 case OPC_ABSQ_S_PH:
15627 check_dsp(ctx);
15628 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15629 break;
15630 case OPC_ABSQ_S_W:
15631 check_dsp(ctx);
15632 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15633 break;
15634 case OPC_PRECEQ_W_PHL:
15635 check_dsp(ctx);
15636 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15637 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15638 break;
15639 case OPC_PRECEQ_W_PHR:
15640 check_dsp(ctx);
15641 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15642 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15643 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15644 break;
15645 case OPC_PRECEQU_PH_QBL:
15646 check_dsp(ctx);
15647 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15648 break;
15649 case OPC_PRECEQU_PH_QBR:
15650 check_dsp(ctx);
15651 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15652 break;
15653 case OPC_PRECEQU_PH_QBLA:
15654 check_dsp(ctx);
15655 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15656 break;
15657 case OPC_PRECEQU_PH_QBRA:
15658 check_dsp(ctx);
15659 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15660 break;
15661 case OPC_PRECEU_PH_QBL:
15662 check_dsp(ctx);
15663 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15664 break;
15665 case OPC_PRECEU_PH_QBR:
15666 check_dsp(ctx);
15667 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15668 break;
15669 case OPC_PRECEU_PH_QBLA:
15670 check_dsp(ctx);
15671 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15672 break;
15673 case OPC_PRECEU_PH_QBRA:
15674 check_dsp(ctx);
15675 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15676 break;
15677 }
15678 break;
15679 case OPC_ADDU_QB_DSP:
15680 switch (op2) {
15681 case OPC_ADDQ_PH:
15682 check_dsp(ctx);
15683 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15684 break;
15685 case OPC_ADDQ_S_PH:
15686 check_dsp(ctx);
15687 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15688 break;
15689 case OPC_ADDQ_S_W:
15690 check_dsp(ctx);
15691 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15692 break;
15693 case OPC_ADDU_QB:
15694 check_dsp(ctx);
15695 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15696 break;
15697 case OPC_ADDU_S_QB:
15698 check_dsp(ctx);
15699 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15700 break;
15701 case OPC_ADDU_PH:
15702 check_dspr2(ctx);
15703 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15704 break;
15705 case OPC_ADDU_S_PH:
15706 check_dspr2(ctx);
15707 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15708 break;
15709 case OPC_SUBQ_PH:
15710 check_dsp(ctx);
15711 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15712 break;
15713 case OPC_SUBQ_S_PH:
15714 check_dsp(ctx);
15715 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15716 break;
15717 case OPC_SUBQ_S_W:
15718 check_dsp(ctx);
15719 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15720 break;
15721 case OPC_SUBU_QB:
15722 check_dsp(ctx);
15723 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15724 break;
15725 case OPC_SUBU_S_QB:
15726 check_dsp(ctx);
15727 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15728 break;
15729 case OPC_SUBU_PH:
15730 check_dspr2(ctx);
15731 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15732 break;
15733 case OPC_SUBU_S_PH:
15734 check_dspr2(ctx);
15735 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15736 break;
15737 case OPC_ADDSC:
15738 check_dsp(ctx);
15739 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15740 break;
15741 case OPC_ADDWC:
15742 check_dsp(ctx);
15743 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15744 break;
15745 case OPC_MODSUB:
15746 check_dsp(ctx);
15747 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15748 break;
15749 case OPC_RADDU_W_QB:
15750 check_dsp(ctx);
15751 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15752 break;
15753 }
15754 break;
15755 case OPC_CMPU_EQ_QB_DSP:
15756 switch (op2) {
15757 case OPC_PRECR_QB_PH:
15758 check_dspr2(ctx);
15759 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15760 break;
15761 case OPC_PRECRQ_QB_PH:
15762 check_dsp(ctx);
15763 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15764 break;
15765 case OPC_PRECR_SRA_PH_W:
15766 check_dspr2(ctx);
15767 {
15768 TCGv_i32 sa_t = tcg_const_i32(v2);
15769 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15770 cpu_gpr[ret]);
15771 tcg_temp_free_i32(sa_t);
15772 break;
15773 }
15774 case OPC_PRECR_SRA_R_PH_W:
15775 check_dspr2(ctx);
15776 {
15777 TCGv_i32 sa_t = tcg_const_i32(v2);
15778 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15779 cpu_gpr[ret]);
15780 tcg_temp_free_i32(sa_t);
15781 break;
15782 }
15783 case OPC_PRECRQ_PH_W:
15784 check_dsp(ctx);
15785 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15786 break;
15787 case OPC_PRECRQ_RS_PH_W:
15788 check_dsp(ctx);
15789 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15790 break;
15791 case OPC_PRECRQU_S_QB_PH:
15792 check_dsp(ctx);
15793 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15794 break;
15795 }
15796 break;
15797 #ifdef TARGET_MIPS64
15798 case OPC_ABSQ_S_QH_DSP:
15799 switch (op2) {
15800 case OPC_PRECEQ_L_PWL:
15801 check_dsp(ctx);
15802 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15803 break;
15804 case OPC_PRECEQ_L_PWR:
15805 check_dsp(ctx);
15806 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15807 break;
15808 case OPC_PRECEQ_PW_QHL:
15809 check_dsp(ctx);
15810 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15811 break;
15812 case OPC_PRECEQ_PW_QHR:
15813 check_dsp(ctx);
15814 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15815 break;
15816 case OPC_PRECEQ_PW_QHLA:
15817 check_dsp(ctx);
15818 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15819 break;
15820 case OPC_PRECEQ_PW_QHRA:
15821 check_dsp(ctx);
15822 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15823 break;
15824 case OPC_PRECEQU_QH_OBL:
15825 check_dsp(ctx);
15826 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15827 break;
15828 case OPC_PRECEQU_QH_OBR:
15829 check_dsp(ctx);
15830 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15831 break;
15832 case OPC_PRECEQU_QH_OBLA:
15833 check_dsp(ctx);
15834 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15835 break;
15836 case OPC_PRECEQU_QH_OBRA:
15837 check_dsp(ctx);
15838 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15839 break;
15840 case OPC_PRECEU_QH_OBL:
15841 check_dsp(ctx);
15842 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15843 break;
15844 case OPC_PRECEU_QH_OBR:
15845 check_dsp(ctx);
15846 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15847 break;
15848 case OPC_PRECEU_QH_OBLA:
15849 check_dsp(ctx);
15850 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15851 break;
15852 case OPC_PRECEU_QH_OBRA:
15853 check_dsp(ctx);
15854 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15855 break;
15856 case OPC_ABSQ_S_OB:
15857 check_dspr2(ctx);
15858 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15859 break;
15860 case OPC_ABSQ_S_PW:
15861 check_dsp(ctx);
15862 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15863 break;
15864 case OPC_ABSQ_S_QH:
15865 check_dsp(ctx);
15866 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15867 break;
15868 }
15869 break;
15870 case OPC_ADDU_OB_DSP:
15871 switch (op2) {
15872 case OPC_RADDU_L_OB:
15873 check_dsp(ctx);
15874 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15875 break;
15876 case OPC_SUBQ_PW:
15877 check_dsp(ctx);
15878 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15879 break;
15880 case OPC_SUBQ_S_PW:
15881 check_dsp(ctx);
15882 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15883 break;
15884 case OPC_SUBQ_QH:
15885 check_dsp(ctx);
15886 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15887 break;
15888 case OPC_SUBQ_S_QH:
15889 check_dsp(ctx);
15890 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15891 break;
15892 case OPC_SUBU_OB:
15893 check_dsp(ctx);
15894 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15895 break;
15896 case OPC_SUBU_S_OB:
15897 check_dsp(ctx);
15898 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15899 break;
15900 case OPC_SUBU_QH:
15901 check_dspr2(ctx);
15902 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15903 break;
15904 case OPC_SUBU_S_QH:
15905 check_dspr2(ctx);
15906 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15907 break;
15908 case OPC_SUBUH_OB:
15909 check_dspr2(ctx);
15910 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15911 break;
15912 case OPC_SUBUH_R_OB:
15913 check_dspr2(ctx);
15914 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15915 break;
15916 case OPC_ADDQ_PW:
15917 check_dsp(ctx);
15918 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15919 break;
15920 case OPC_ADDQ_S_PW:
15921 check_dsp(ctx);
15922 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15923 break;
15924 case OPC_ADDQ_QH:
15925 check_dsp(ctx);
15926 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15927 break;
15928 case OPC_ADDQ_S_QH:
15929 check_dsp(ctx);
15930 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15931 break;
15932 case OPC_ADDU_OB:
15933 check_dsp(ctx);
15934 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15935 break;
15936 case OPC_ADDU_S_OB:
15937 check_dsp(ctx);
15938 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15939 break;
15940 case OPC_ADDU_QH:
15941 check_dspr2(ctx);
15942 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15943 break;
15944 case OPC_ADDU_S_QH:
15945 check_dspr2(ctx);
15946 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15947 break;
15948 case OPC_ADDUH_OB:
15949 check_dspr2(ctx);
15950 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15951 break;
15952 case OPC_ADDUH_R_OB:
15953 check_dspr2(ctx);
15954 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15955 break;
15956 }
15957 break;
15958 case OPC_CMPU_EQ_OB_DSP:
15959 switch (op2) {
15960 case OPC_PRECR_OB_QH:
15961 check_dspr2(ctx);
15962 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15963 break;
15964 case OPC_PRECR_SRA_QH_PW:
15965 check_dspr2(ctx);
15966 {
15967 TCGv_i32 ret_t = tcg_const_i32(ret);
15968 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15969 tcg_temp_free_i32(ret_t);
15970 break;
15971 }
15972 case OPC_PRECR_SRA_R_QH_PW:
15973 check_dspr2(ctx);
15974 {
15975 TCGv_i32 sa_v = tcg_const_i32(ret);
15976 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15977 tcg_temp_free_i32(sa_v);
15978 break;
15979 }
15980 case OPC_PRECRQ_OB_QH:
15981 check_dsp(ctx);
15982 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15983 break;
15984 case OPC_PRECRQ_PW_L:
15985 check_dsp(ctx);
15986 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15987 break;
15988 case OPC_PRECRQ_QH_PW:
15989 check_dsp(ctx);
15990 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15991 break;
15992 case OPC_PRECRQ_RS_QH_PW:
15993 check_dsp(ctx);
15994 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15995 break;
15996 case OPC_PRECRQU_S_OB_QH:
15997 check_dsp(ctx);
15998 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15999 break;
16000 }
16001 break;
16002 #endif
16003 }
16004
16005 tcg_temp_free(v1_t);
16006 tcg_temp_free(v2_t);
16007 }
16008
16009 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
16010 int ret, int v1, int v2)
16011 {
16012 uint32_t op2;
16013 TCGv t0;
16014 TCGv v1_t;
16015 TCGv v2_t;
16016
16017 if (ret == 0) {
16018 /* Treat as NOP. */
16019 return;
16020 }
16021
16022 t0 = tcg_temp_new();
16023 v1_t = tcg_temp_new();
16024 v2_t = tcg_temp_new();
16025
16026 tcg_gen_movi_tl(t0, v1);
16027 gen_load_gpr(v1_t, v1);
16028 gen_load_gpr(v2_t, v2);
16029
16030 switch (opc) {
16031 case OPC_SHLL_QB_DSP:
16032 {
16033 op2 = MASK_SHLL_QB(ctx->opcode);
16034 switch (op2) {
16035 case OPC_SHLL_QB:
16036 check_dsp(ctx);
16037 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
16038 break;
16039 case OPC_SHLLV_QB:
16040 check_dsp(ctx);
16041 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16042 break;
16043 case OPC_SHLL_PH:
16044 check_dsp(ctx);
16045 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16046 break;
16047 case OPC_SHLLV_PH:
16048 check_dsp(ctx);
16049 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16050 break;
16051 case OPC_SHLL_S_PH:
16052 check_dsp(ctx);
16053 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16054 break;
16055 case OPC_SHLLV_S_PH:
16056 check_dsp(ctx);
16057 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16058 break;
16059 case OPC_SHLL_S_W:
16060 check_dsp(ctx);
16061 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
16062 break;
16063 case OPC_SHLLV_S_W:
16064 check_dsp(ctx);
16065 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16066 break;
16067 case OPC_SHRL_QB:
16068 check_dsp(ctx);
16069 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
16070 break;
16071 case OPC_SHRLV_QB:
16072 check_dsp(ctx);
16073 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
16074 break;
16075 case OPC_SHRL_PH:
16076 check_dspr2(ctx);
16077 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
16078 break;
16079 case OPC_SHRLV_PH:
16080 check_dspr2(ctx);
16081 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
16082 break;
16083 case OPC_SHRA_QB:
16084 check_dspr2(ctx);
16085 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
16086 break;
16087 case OPC_SHRA_R_QB:
16088 check_dspr2(ctx);
16089 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
16090 break;
16091 case OPC_SHRAV_QB:
16092 check_dspr2(ctx);
16093 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
16094 break;
16095 case OPC_SHRAV_R_QB:
16096 check_dspr2(ctx);
16097 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
16098 break;
16099 case OPC_SHRA_PH:
16100 check_dsp(ctx);
16101 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
16102 break;
16103 case OPC_SHRA_R_PH:
16104 check_dsp(ctx);
16105 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
16106 break;
16107 case OPC_SHRAV_PH:
16108 check_dsp(ctx);
16109 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
16110 break;
16111 case OPC_SHRAV_R_PH:
16112 check_dsp(ctx);
16113 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
16114 break;
16115 case OPC_SHRA_R_W:
16116 check_dsp(ctx);
16117 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
16118 break;
16119 case OPC_SHRAV_R_W:
16120 check_dsp(ctx);
16121 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
16122 break;
16123 default: /* Invalid */
16124 MIPS_INVAL("MASK SHLL.QB");
16125 generate_exception_end(ctx, EXCP_RI);
16126 break;
16127 }
16128 break;
16129 }
16130 #ifdef TARGET_MIPS64
16131 case OPC_SHLL_OB_DSP:
16132 op2 = MASK_SHLL_OB(ctx->opcode);
16133 switch (op2) {
16134 case OPC_SHLL_PW:
16135 check_dsp(ctx);
16136 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16137 break;
16138 case OPC_SHLLV_PW:
16139 check_dsp(ctx);
16140 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16141 break;
16142 case OPC_SHLL_S_PW:
16143 check_dsp(ctx);
16144 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16145 break;
16146 case OPC_SHLLV_S_PW:
16147 check_dsp(ctx);
16148 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16149 break;
16150 case OPC_SHLL_OB:
16151 check_dsp(ctx);
16152 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
16153 break;
16154 case OPC_SHLLV_OB:
16155 check_dsp(ctx);
16156 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16157 break;
16158 case OPC_SHLL_QH:
16159 check_dsp(ctx);
16160 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16161 break;
16162 case OPC_SHLLV_QH:
16163 check_dsp(ctx);
16164 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16165 break;
16166 case OPC_SHLL_S_QH:
16167 check_dsp(ctx);
16168 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16169 break;
16170 case OPC_SHLLV_S_QH:
16171 check_dsp(ctx);
16172 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16173 break;
16174 case OPC_SHRA_OB:
16175 check_dspr2(ctx);
16176 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
16177 break;
16178 case OPC_SHRAV_OB:
16179 check_dspr2(ctx);
16180 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
16181 break;
16182 case OPC_SHRA_R_OB:
16183 check_dspr2(ctx);
16184 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
16185 break;
16186 case OPC_SHRAV_R_OB:
16187 check_dspr2(ctx);
16188 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
16189 break;
16190 case OPC_SHRA_PW:
16191 check_dsp(ctx);
16192 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
16193 break;
16194 case OPC_SHRAV_PW:
16195 check_dsp(ctx);
16196 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
16197 break;
16198 case OPC_SHRA_R_PW:
16199 check_dsp(ctx);
16200 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
16201 break;
16202 case OPC_SHRAV_R_PW:
16203 check_dsp(ctx);
16204 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
16205 break;
16206 case OPC_SHRA_QH:
16207 check_dsp(ctx);
16208 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
16209 break;
16210 case OPC_SHRAV_QH:
16211 check_dsp(ctx);
16212 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
16213 break;
16214 case OPC_SHRA_R_QH:
16215 check_dsp(ctx);
16216 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
16217 break;
16218 case OPC_SHRAV_R_QH:
16219 check_dsp(ctx);
16220 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
16221 break;
16222 case OPC_SHRL_OB:
16223 check_dsp(ctx);
16224 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
16225 break;
16226 case OPC_SHRLV_OB:
16227 check_dsp(ctx);
16228 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
16229 break;
16230 case OPC_SHRL_QH:
16231 check_dspr2(ctx);
16232 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
16233 break;
16234 case OPC_SHRLV_QH:
16235 check_dspr2(ctx);
16236 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
16237 break;
16238 default: /* Invalid */
16239 MIPS_INVAL("MASK SHLL.OB");
16240 generate_exception_end(ctx, EXCP_RI);
16241 break;
16242 }
16243 break;
16244 #endif
16245 }
16246
16247 tcg_temp_free(t0);
16248 tcg_temp_free(v1_t);
16249 tcg_temp_free(v2_t);
16250 }
16251
16252 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16253 int ret, int v1, int v2, int check_ret)
16254 {
16255 TCGv_i32 t0;
16256 TCGv v1_t;
16257 TCGv v2_t;
16258
16259 if ((ret == 0) && (check_ret == 1)) {
16260 /* Treat as NOP. */
16261 return;
16262 }
16263
16264 t0 = tcg_temp_new_i32();
16265 v1_t = tcg_temp_new();
16266 v2_t = tcg_temp_new();
16267
16268 tcg_gen_movi_i32(t0, ret);
16269 gen_load_gpr(v1_t, v1);
16270 gen_load_gpr(v2_t, v2);
16271
16272 switch (op1) {
16273 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16274 * the same mask and op1. */
16275 case OPC_MULT_G_2E:
16276 check_dspr2(ctx);
16277 switch (op2) {
16278 case OPC_MUL_PH:
16279 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16280 break;
16281 case OPC_MUL_S_PH:
16282 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16283 break;
16284 case OPC_MULQ_S_W:
16285 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16286 break;
16287 case OPC_MULQ_RS_W:
16288 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16289 break;
16290 }
16291 break;
16292 case OPC_DPA_W_PH_DSP:
16293 switch (op2) {
16294 case OPC_DPAU_H_QBL:
16295 check_dsp(ctx);
16296 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16297 break;
16298 case OPC_DPAU_H_QBR:
16299 check_dsp(ctx);
16300 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16301 break;
16302 case OPC_DPSU_H_QBL:
16303 check_dsp(ctx);
16304 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16305 break;
16306 case OPC_DPSU_H_QBR:
16307 check_dsp(ctx);
16308 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16309 break;
16310 case OPC_DPA_W_PH:
16311 check_dspr2(ctx);
16312 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16313 break;
16314 case OPC_DPAX_W_PH:
16315 check_dspr2(ctx);
16316 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16317 break;
16318 case OPC_DPAQ_S_W_PH:
16319 check_dsp(ctx);
16320 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16321 break;
16322 case OPC_DPAQX_S_W_PH:
16323 check_dspr2(ctx);
16324 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16325 break;
16326 case OPC_DPAQX_SA_W_PH:
16327 check_dspr2(ctx);
16328 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16329 break;
16330 case OPC_DPS_W_PH:
16331 check_dspr2(ctx);
16332 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16333 break;
16334 case OPC_DPSX_W_PH:
16335 check_dspr2(ctx);
16336 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16337 break;
16338 case OPC_DPSQ_S_W_PH:
16339 check_dsp(ctx);
16340 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16341 break;
16342 case OPC_DPSQX_S_W_PH:
16343 check_dspr2(ctx);
16344 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16345 break;
16346 case OPC_DPSQX_SA_W_PH:
16347 check_dspr2(ctx);
16348 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16349 break;
16350 case OPC_MULSAQ_S_W_PH:
16351 check_dsp(ctx);
16352 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16353 break;
16354 case OPC_DPAQ_SA_L_W:
16355 check_dsp(ctx);
16356 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16357 break;
16358 case OPC_DPSQ_SA_L_W:
16359 check_dsp(ctx);
16360 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16361 break;
16362 case OPC_MAQ_S_W_PHL:
16363 check_dsp(ctx);
16364 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16365 break;
16366 case OPC_MAQ_S_W_PHR:
16367 check_dsp(ctx);
16368 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16369 break;
16370 case OPC_MAQ_SA_W_PHL:
16371 check_dsp(ctx);
16372 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16373 break;
16374 case OPC_MAQ_SA_W_PHR:
16375 check_dsp(ctx);
16376 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16377 break;
16378 case OPC_MULSA_W_PH:
16379 check_dspr2(ctx);
16380 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16381 break;
16382 }
16383 break;
16384 #ifdef TARGET_MIPS64
16385 case OPC_DPAQ_W_QH_DSP:
16386 {
16387 int ac = ret & 0x03;
16388 tcg_gen_movi_i32(t0, ac);
16389
16390 switch (op2) {
16391 case OPC_DMADD:
16392 check_dsp(ctx);
16393 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16394 break;
16395 case OPC_DMADDU:
16396 check_dsp(ctx);
16397 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16398 break;
16399 case OPC_DMSUB:
16400 check_dsp(ctx);
16401 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16402 break;
16403 case OPC_DMSUBU:
16404 check_dsp(ctx);
16405 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16406 break;
16407 case OPC_DPA_W_QH:
16408 check_dspr2(ctx);
16409 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16410 break;
16411 case OPC_DPAQ_S_W_QH:
16412 check_dsp(ctx);
16413 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16414 break;
16415 case OPC_DPAQ_SA_L_PW:
16416 check_dsp(ctx);
16417 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16418 break;
16419 case OPC_DPAU_H_OBL:
16420 check_dsp(ctx);
16421 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16422 break;
16423 case OPC_DPAU_H_OBR:
16424 check_dsp(ctx);
16425 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16426 break;
16427 case OPC_DPS_W_QH:
16428 check_dspr2(ctx);
16429 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16430 break;
16431 case OPC_DPSQ_S_W_QH:
16432 check_dsp(ctx);
16433 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16434 break;
16435 case OPC_DPSQ_SA_L_PW:
16436 check_dsp(ctx);
16437 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16438 break;
16439 case OPC_DPSU_H_OBL:
16440 check_dsp(ctx);
16441 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16442 break;
16443 case OPC_DPSU_H_OBR:
16444 check_dsp(ctx);
16445 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16446 break;
16447 case OPC_MAQ_S_L_PWL:
16448 check_dsp(ctx);
16449 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16450 break;
16451 case OPC_MAQ_S_L_PWR:
16452 check_dsp(ctx);
16453 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16454 break;
16455 case OPC_MAQ_S_W_QHLL:
16456 check_dsp(ctx);
16457 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16458 break;
16459 case OPC_MAQ_SA_W_QHLL:
16460 check_dsp(ctx);
16461 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16462 break;
16463 case OPC_MAQ_S_W_QHLR:
16464 check_dsp(ctx);
16465 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16466 break;
16467 case OPC_MAQ_SA_W_QHLR:
16468 check_dsp(ctx);
16469 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16470 break;
16471 case OPC_MAQ_S_W_QHRL:
16472 check_dsp(ctx);
16473 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16474 break;
16475 case OPC_MAQ_SA_W_QHRL:
16476 check_dsp(ctx);
16477 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16478 break;
16479 case OPC_MAQ_S_W_QHRR:
16480 check_dsp(ctx);
16481 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16482 break;
16483 case OPC_MAQ_SA_W_QHRR:
16484 check_dsp(ctx);
16485 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16486 break;
16487 case OPC_MULSAQ_S_L_PW:
16488 check_dsp(ctx);
16489 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16490 break;
16491 case OPC_MULSAQ_S_W_QH:
16492 check_dsp(ctx);
16493 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16494 break;
16495 }
16496 }
16497 break;
16498 #endif
16499 case OPC_ADDU_QB_DSP:
16500 switch (op2) {
16501 case OPC_MULEU_S_PH_QBL:
16502 check_dsp(ctx);
16503 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16504 break;
16505 case OPC_MULEU_S_PH_QBR:
16506 check_dsp(ctx);
16507 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16508 break;
16509 case OPC_MULQ_RS_PH:
16510 check_dsp(ctx);
16511 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16512 break;
16513 case OPC_MULEQ_S_W_PHL:
16514 check_dsp(ctx);
16515 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16516 break;
16517 case OPC_MULEQ_S_W_PHR:
16518 check_dsp(ctx);
16519 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16520 break;
16521 case OPC_MULQ_S_PH:
16522 check_dspr2(ctx);
16523 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16524 break;
16525 }
16526 break;
16527 #ifdef TARGET_MIPS64
16528 case OPC_ADDU_OB_DSP:
16529 switch (op2) {
16530 case OPC_MULEQ_S_PW_QHL:
16531 check_dsp(ctx);
16532 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16533 break;
16534 case OPC_MULEQ_S_PW_QHR:
16535 check_dsp(ctx);
16536 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16537 break;
16538 case OPC_MULEU_S_QH_OBL:
16539 check_dsp(ctx);
16540 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16541 break;
16542 case OPC_MULEU_S_QH_OBR:
16543 check_dsp(ctx);
16544 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16545 break;
16546 case OPC_MULQ_RS_QH:
16547 check_dsp(ctx);
16548 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16549 break;
16550 }
16551 break;
16552 #endif
16553 }
16554
16555 tcg_temp_free_i32(t0);
16556 tcg_temp_free(v1_t);
16557 tcg_temp_free(v2_t);
16558 }
16559
16560 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16561 int ret, int val)
16562 {
16563 int16_t imm;
16564 TCGv t0;
16565 TCGv val_t;
16566
16567 if (ret == 0) {
16568 /* Treat as NOP. */
16569 return;
16570 }
16571
16572 t0 = tcg_temp_new();
16573 val_t = tcg_temp_new();
16574 gen_load_gpr(val_t, val);
16575
16576 switch (op1) {
16577 case OPC_ABSQ_S_PH_DSP:
16578 switch (op2) {
16579 case OPC_BITREV:
16580 check_dsp(ctx);
16581 gen_helper_bitrev(cpu_gpr[ret], val_t);
16582 break;
16583 case OPC_REPL_QB:
16584 check_dsp(ctx);
16585 {
16586 target_long result;
16587 imm = (ctx->opcode >> 16) & 0xFF;
16588 result = (uint32_t)imm << 24 |
16589 (uint32_t)imm << 16 |
16590 (uint32_t)imm << 8 |
16591 (uint32_t)imm;
16592 result = (int32_t)result;
16593 tcg_gen_movi_tl(cpu_gpr[ret], result);
16594 }
16595 break;
16596 case OPC_REPLV_QB:
16597 check_dsp(ctx);
16598 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16599 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16600 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16601 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16602 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16603 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16604 break;
16605 case OPC_REPL_PH:
16606 check_dsp(ctx);
16607 {
16608 imm = (ctx->opcode >> 16) & 0x03FF;
16609 imm = (int16_t)(imm << 6) >> 6;
16610 tcg_gen_movi_tl(cpu_gpr[ret], \
16611 (target_long)((int32_t)imm << 16 | \
16612 (uint16_t)imm));
16613 }
16614 break;
16615 case OPC_REPLV_PH:
16616 check_dsp(ctx);
16617 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16618 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16619 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16620 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16621 break;
16622 }
16623 break;
16624 #ifdef TARGET_MIPS64
16625 case OPC_ABSQ_S_QH_DSP:
16626 switch (op2) {
16627 case OPC_REPL_OB:
16628 check_dsp(ctx);
16629 {
16630 target_long temp;
16631
16632 imm = (ctx->opcode >> 16) & 0xFF;
16633 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16634 temp = (temp << 16) | temp;
16635 temp = (temp << 32) | temp;
16636 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16637 break;
16638 }
16639 case OPC_REPL_PW:
16640 check_dsp(ctx);
16641 {
16642 target_long temp;
16643
16644 imm = (ctx->opcode >> 16) & 0x03FF;
16645 imm = (int16_t)(imm << 6) >> 6;
16646 temp = ((target_long)imm << 32) \
16647 | ((target_long)imm & 0xFFFFFFFF);
16648 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16649 break;
16650 }
16651 case OPC_REPL_QH:
16652 check_dsp(ctx);
16653 {
16654 target_long temp;
16655
16656 imm = (ctx->opcode >> 16) & 0x03FF;
16657 imm = (int16_t)(imm << 6) >> 6;
16658
16659 temp = ((uint64_t)(uint16_t)imm << 48) |
16660 ((uint64_t)(uint16_t)imm << 32) |
16661 ((uint64_t)(uint16_t)imm << 16) |
16662 (uint64_t)(uint16_t)imm;
16663 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16664 break;
16665 }
16666 case OPC_REPLV_OB:
16667 check_dsp(ctx);
16668 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16669 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16670 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16671 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16672 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16673 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16674 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16675 break;
16676 case OPC_REPLV_PW:
16677 check_dsp(ctx);
16678 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16679 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16680 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16681 break;
16682 case OPC_REPLV_QH:
16683 check_dsp(ctx);
16684 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16685 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16686 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16687 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16688 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16689 break;
16690 }
16691 break;
16692 #endif
16693 }
16694 tcg_temp_free(t0);
16695 tcg_temp_free(val_t);
16696 }
16697
16698 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16699 uint32_t op1, uint32_t op2,
16700 int ret, int v1, int v2, int check_ret)
16701 {
16702 TCGv t1;
16703 TCGv v1_t;
16704 TCGv v2_t;
16705
16706 if ((ret == 0) && (check_ret == 1)) {
16707 /* Treat as NOP. */
16708 return;
16709 }
16710
16711 t1 = tcg_temp_new();
16712 v1_t = tcg_temp_new();
16713 v2_t = tcg_temp_new();
16714
16715 gen_load_gpr(v1_t, v1);
16716 gen_load_gpr(v2_t, v2);
16717
16718 switch (op1) {
16719 case OPC_CMPU_EQ_QB_DSP:
16720 switch (op2) {
16721 case OPC_CMPU_EQ_QB:
16722 check_dsp(ctx);
16723 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16724 break;
16725 case OPC_CMPU_LT_QB:
16726 check_dsp(ctx);
16727 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16728 break;
16729 case OPC_CMPU_LE_QB:
16730 check_dsp(ctx);
16731 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16732 break;
16733 case OPC_CMPGU_EQ_QB:
16734 check_dsp(ctx);
16735 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16736 break;
16737 case OPC_CMPGU_LT_QB:
16738 check_dsp(ctx);
16739 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16740 break;
16741 case OPC_CMPGU_LE_QB:
16742 check_dsp(ctx);
16743 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16744 break;
16745 case OPC_CMPGDU_EQ_QB:
16746 check_dspr2(ctx);
16747 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16748 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16749 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16750 tcg_gen_shli_tl(t1, t1, 24);
16751 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16752 break;
16753 case OPC_CMPGDU_LT_QB:
16754 check_dspr2(ctx);
16755 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16756 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16757 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16758 tcg_gen_shli_tl(t1, t1, 24);
16759 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16760 break;
16761 case OPC_CMPGDU_LE_QB:
16762 check_dspr2(ctx);
16763 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16764 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16765 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16766 tcg_gen_shli_tl(t1, t1, 24);
16767 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16768 break;
16769 case OPC_CMP_EQ_PH:
16770 check_dsp(ctx);
16771 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16772 break;
16773 case OPC_CMP_LT_PH:
16774 check_dsp(ctx);
16775 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16776 break;
16777 case OPC_CMP_LE_PH:
16778 check_dsp(ctx);
16779 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16780 break;
16781 case OPC_PICK_QB:
16782 check_dsp(ctx);
16783 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16784 break;
16785 case OPC_PICK_PH:
16786 check_dsp(ctx);
16787 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16788 break;
16789 case OPC_PACKRL_PH:
16790 check_dsp(ctx);
16791 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16792 break;
16793 }
16794 break;
16795 #ifdef TARGET_MIPS64
16796 case OPC_CMPU_EQ_OB_DSP:
16797 switch (op2) {
16798 case OPC_CMP_EQ_PW:
16799 check_dsp(ctx);
16800 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16801 break;
16802 case OPC_CMP_LT_PW:
16803 check_dsp(ctx);
16804 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16805 break;
16806 case OPC_CMP_LE_PW:
16807 check_dsp(ctx);
16808 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16809 break;
16810 case OPC_CMP_EQ_QH:
16811 check_dsp(ctx);
16812 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16813 break;
16814 case OPC_CMP_LT_QH:
16815 check_dsp(ctx);
16816 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16817 break;
16818 case OPC_CMP_LE_QH:
16819 check_dsp(ctx);
16820 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16821 break;
16822 case OPC_CMPGDU_EQ_OB:
16823 check_dspr2(ctx);
16824 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16825 break;
16826 case OPC_CMPGDU_LT_OB:
16827 check_dspr2(ctx);
16828 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16829 break;
16830 case OPC_CMPGDU_LE_OB:
16831 check_dspr2(ctx);
16832 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16833 break;
16834 case OPC_CMPGU_EQ_OB:
16835 check_dsp(ctx);
16836 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16837 break;
16838 case OPC_CMPGU_LT_OB:
16839 check_dsp(ctx);
16840 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16841 break;
16842 case OPC_CMPGU_LE_OB:
16843 check_dsp(ctx);
16844 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16845 break;
16846 case OPC_CMPU_EQ_OB:
16847 check_dsp(ctx);
16848 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16849 break;
16850 case OPC_CMPU_LT_OB:
16851 check_dsp(ctx);
16852 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16853 break;
16854 case OPC_CMPU_LE_OB:
16855 check_dsp(ctx);
16856 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16857 break;
16858 case OPC_PACKRL_PW:
16859 check_dsp(ctx);
16860 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16861 break;
16862 case OPC_PICK_OB:
16863 check_dsp(ctx);
16864 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16865 break;
16866 case OPC_PICK_PW:
16867 check_dsp(ctx);
16868 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16869 break;
16870 case OPC_PICK_QH:
16871 check_dsp(ctx);
16872 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16873 break;
16874 }
16875 break;
16876 #endif
16877 }
16878
16879 tcg_temp_free(t1);
16880 tcg_temp_free(v1_t);
16881 tcg_temp_free(v2_t);
16882 }
16883
16884 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16885 uint32_t op1, int rt, int rs, int sa)
16886 {
16887 TCGv t0;
16888
16889 check_dspr2(ctx);
16890
16891 if (rt == 0) {
16892 /* Treat as NOP. */
16893 return;
16894 }
16895
16896 t0 = tcg_temp_new();
16897 gen_load_gpr(t0, rs);
16898
16899 switch (op1) {
16900 case OPC_APPEND_DSP:
16901 switch (MASK_APPEND(ctx->opcode)) {
16902 case OPC_APPEND:
16903 if (sa != 0) {
16904 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16905 }
16906 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16907 break;
16908 case OPC_PREPEND:
16909 if (sa != 0) {
16910 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16911 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16912 tcg_gen_shli_tl(t0, t0, 32 - sa);
16913 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16914 }
16915 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16916 break;
16917 case OPC_BALIGN:
16918 sa &= 3;
16919 if (sa != 0 && sa != 2) {
16920 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16921 tcg_gen_ext32u_tl(t0, t0);
16922 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16923 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16924 }
16925 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16926 break;
16927 default: /* Invalid */
16928 MIPS_INVAL("MASK APPEND");
16929 generate_exception_end(ctx, EXCP_RI);
16930 break;
16931 }
16932 break;
16933 #ifdef TARGET_MIPS64
16934 case OPC_DAPPEND_DSP:
16935 switch (MASK_DAPPEND(ctx->opcode)) {
16936 case OPC_DAPPEND:
16937 if (sa != 0) {
16938 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16939 }
16940 break;
16941 case OPC_PREPENDD:
16942 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16943 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16944 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16945 break;
16946 case OPC_PREPENDW:
16947 if (sa != 0) {
16948 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16949 tcg_gen_shli_tl(t0, t0, 64 - sa);
16950 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16951 }
16952 break;
16953 case OPC_DBALIGN:
16954 sa &= 7;
16955 if (sa != 0 && sa != 2 && sa != 4) {
16956 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16957 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16958 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16959 }
16960 break;
16961 default: /* Invalid */
16962 MIPS_INVAL("MASK DAPPEND");
16963 generate_exception_end(ctx, EXCP_RI);
16964 break;
16965 }
16966 break;
16967 #endif
16968 }
16969 tcg_temp_free(t0);
16970 }
16971
16972 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16973 int ret, int v1, int v2, int check_ret)
16974
16975 {
16976 TCGv t0;
16977 TCGv t1;
16978 TCGv v1_t;
16979 TCGv v2_t;
16980 int16_t imm;
16981
16982 if ((ret == 0) && (check_ret == 1)) {
16983 /* Treat as NOP. */
16984 return;
16985 }
16986
16987 t0 = tcg_temp_new();
16988 t1 = tcg_temp_new();
16989 v1_t = tcg_temp_new();
16990 v2_t = tcg_temp_new();
16991
16992 gen_load_gpr(v1_t, v1);
16993 gen_load_gpr(v2_t, v2);
16994
16995 switch (op1) {
16996 case OPC_EXTR_W_DSP:
16997 check_dsp(ctx);
16998 switch (op2) {
16999 case OPC_EXTR_W:
17000 tcg_gen_movi_tl(t0, v2);
17001 tcg_gen_movi_tl(t1, v1);
17002 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
17003 break;
17004 case OPC_EXTR_R_W:
17005 tcg_gen_movi_tl(t0, v2);
17006 tcg_gen_movi_tl(t1, v1);
17007 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17008 break;
17009 case OPC_EXTR_RS_W:
17010 tcg_gen_movi_tl(t0, v2);
17011 tcg_gen_movi_tl(t1, v1);
17012 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17013 break;
17014 case OPC_EXTR_S_H:
17015 tcg_gen_movi_tl(t0, v2);
17016 tcg_gen_movi_tl(t1, v1);
17017 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17018 break;
17019 case OPC_EXTRV_S_H:
17020 tcg_gen_movi_tl(t0, v2);
17021 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
17022 break;
17023 case OPC_EXTRV_W:
17024 tcg_gen_movi_tl(t0, v2);
17025 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17026 break;
17027 case OPC_EXTRV_R_W:
17028 tcg_gen_movi_tl(t0, v2);
17029 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17030 break;
17031 case OPC_EXTRV_RS_W:
17032 tcg_gen_movi_tl(t0, v2);
17033 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17034 break;
17035 case OPC_EXTP:
17036 tcg_gen_movi_tl(t0, v2);
17037 tcg_gen_movi_tl(t1, v1);
17038 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
17039 break;
17040 case OPC_EXTPV:
17041 tcg_gen_movi_tl(t0, v2);
17042 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
17043 break;
17044 case OPC_EXTPDP:
17045 tcg_gen_movi_tl(t0, v2);
17046 tcg_gen_movi_tl(t1, v1);
17047 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
17048 break;
17049 case OPC_EXTPDPV:
17050 tcg_gen_movi_tl(t0, v2);
17051 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17052 break;
17053 case OPC_SHILO:
17054 imm = (ctx->opcode >> 20) & 0x3F;
17055 tcg_gen_movi_tl(t0, ret);
17056 tcg_gen_movi_tl(t1, imm);
17057 gen_helper_shilo(t0, t1, cpu_env);
17058 break;
17059 case OPC_SHILOV:
17060 tcg_gen_movi_tl(t0, ret);
17061 gen_helper_shilo(t0, v1_t, cpu_env);
17062 break;
17063 case OPC_MTHLIP:
17064 tcg_gen_movi_tl(t0, ret);
17065 gen_helper_mthlip(t0, v1_t, cpu_env);
17066 break;
17067 case OPC_WRDSP:
17068 imm = (ctx->opcode >> 11) & 0x3FF;
17069 tcg_gen_movi_tl(t0, imm);
17070 gen_helper_wrdsp(v1_t, t0, cpu_env);
17071 break;
17072 case OPC_RDDSP:
17073 imm = (ctx->opcode >> 16) & 0x03FF;
17074 tcg_gen_movi_tl(t0, imm);
17075 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
17076 break;
17077 }
17078 break;
17079 #ifdef TARGET_MIPS64
17080 case OPC_DEXTR_W_DSP:
17081 check_dsp(ctx);
17082 switch (op2) {
17083 case OPC_DMTHLIP:
17084 tcg_gen_movi_tl(t0, ret);
17085 gen_helper_dmthlip(v1_t, t0, cpu_env);
17086 break;
17087 case OPC_DSHILO:
17088 {
17089 int shift = (ctx->opcode >> 19) & 0x7F;
17090 int ac = (ctx->opcode >> 11) & 0x03;
17091 tcg_gen_movi_tl(t0, shift);
17092 tcg_gen_movi_tl(t1, ac);
17093 gen_helper_dshilo(t0, t1, cpu_env);
17094 break;
17095 }
17096 case OPC_DSHILOV:
17097 {
17098 int ac = (ctx->opcode >> 11) & 0x03;
17099 tcg_gen_movi_tl(t0, ac);
17100 gen_helper_dshilo(v1_t, t0, cpu_env);
17101 break;
17102 }
17103 case OPC_DEXTP:
17104 tcg_gen_movi_tl(t0, v2);
17105 tcg_gen_movi_tl(t1, v1);
17106
17107 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
17108 break;
17109 case OPC_DEXTPV:
17110 tcg_gen_movi_tl(t0, v2);
17111 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
17112 break;
17113 case OPC_DEXTPDP:
17114 tcg_gen_movi_tl(t0, v2);
17115 tcg_gen_movi_tl(t1, v1);
17116 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
17117 break;
17118 case OPC_DEXTPDPV:
17119 tcg_gen_movi_tl(t0, v2);
17120 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17121 break;
17122 case OPC_DEXTR_L:
17123 tcg_gen_movi_tl(t0, v2);
17124 tcg_gen_movi_tl(t1, v1);
17125 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
17126 break;
17127 case OPC_DEXTR_R_L:
17128 tcg_gen_movi_tl(t0, v2);
17129 tcg_gen_movi_tl(t1, v1);
17130 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
17131 break;
17132 case OPC_DEXTR_RS_L:
17133 tcg_gen_movi_tl(t0, v2);
17134 tcg_gen_movi_tl(t1, v1);
17135 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
17136 break;
17137 case OPC_DEXTR_W:
17138 tcg_gen_movi_tl(t0, v2);
17139 tcg_gen_movi_tl(t1, v1);
17140 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
17141 break;
17142 case OPC_DEXTR_R_W:
17143 tcg_gen_movi_tl(t0, v2);
17144 tcg_gen_movi_tl(t1, v1);
17145 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17146 break;
17147 case OPC_DEXTR_RS_W:
17148 tcg_gen_movi_tl(t0, v2);
17149 tcg_gen_movi_tl(t1, v1);
17150 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17151 break;
17152 case OPC_DEXTR_S_H:
17153 tcg_gen_movi_tl(t0, v2);
17154 tcg_gen_movi_tl(t1, v1);
17155 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17156 break;
17157 case OPC_DEXTRV_S_H:
17158 tcg_gen_movi_tl(t0, v2);
17159 tcg_gen_movi_tl(t1, v1);
17160 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17161 break;
17162 case OPC_DEXTRV_L:
17163 tcg_gen_movi_tl(t0, v2);
17164 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17165 break;
17166 case OPC_DEXTRV_R_L:
17167 tcg_gen_movi_tl(t0, v2);
17168 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17169 break;
17170 case OPC_DEXTRV_RS_L:
17171 tcg_gen_movi_tl(t0, v2);
17172 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17173 break;
17174 case OPC_DEXTRV_W:
17175 tcg_gen_movi_tl(t0, v2);
17176 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17177 break;
17178 case OPC_DEXTRV_R_W:
17179 tcg_gen_movi_tl(t0, v2);
17180 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17181 break;
17182 case OPC_DEXTRV_RS_W:
17183 tcg_gen_movi_tl(t0, v2);
17184 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17185 break;
17186 }
17187 break;
17188 #endif
17189 }
17190
17191 tcg_temp_free(t0);
17192 tcg_temp_free(t1);
17193 tcg_temp_free(v1_t);
17194 tcg_temp_free(v2_t);
17195 }
17196
17197 /* End MIPSDSP functions. */
17198
17199 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
17200 {
17201 int rs, rt, rd, sa;
17202 uint32_t op1, op2;
17203
17204 rs = (ctx->opcode >> 21) & 0x1f;
17205 rt = (ctx->opcode >> 16) & 0x1f;
17206 rd = (ctx->opcode >> 11) & 0x1f;
17207 sa = (ctx->opcode >> 6) & 0x1f;
17208
17209 op1 = MASK_SPECIAL(ctx->opcode);
17210 switch (op1) {
17211 case OPC_LSA:
17212 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
17213 break;
17214 case OPC_MULT ... OPC_DIVU:
17215 op2 = MASK_R6_MULDIV(ctx->opcode);
17216 switch (op2) {
17217 case R6_OPC_MUL:
17218 case R6_OPC_MUH:
17219 case R6_OPC_MULU:
17220 case R6_OPC_MUHU:
17221 case R6_OPC_DIV:
17222 case R6_OPC_MOD:
17223 case R6_OPC_DIVU:
17224 case R6_OPC_MODU:
17225 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17226 break;
17227 default:
17228 MIPS_INVAL("special_r6 muldiv");
17229 generate_exception_end(ctx, EXCP_RI);
17230 break;
17231 }
17232 break;
17233 case OPC_SELEQZ:
17234 case OPC_SELNEZ:
17235 gen_cond_move(ctx, op1, rd, rs, rt);
17236 break;
17237 case R6_OPC_CLO:
17238 case R6_OPC_CLZ:
17239 if (rt == 0 && sa == 1) {
17240 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17241 We need additionally to check other fields */
17242 gen_cl(ctx, op1, rd, rs);
17243 } else {
17244 generate_exception_end(ctx, EXCP_RI);
17245 }
17246 break;
17247 case R6_OPC_SDBBP:
17248 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17249 gen_helper_do_semihosting(cpu_env);
17250 } else {
17251 if (ctx->hflags & MIPS_HFLAG_SBRI) {
17252 generate_exception_end(ctx, EXCP_RI);
17253 } else {
17254 generate_exception_end(ctx, EXCP_DBp);
17255 }
17256 }
17257 break;
17258 #if defined(TARGET_MIPS64)
17259 case OPC_DLSA:
17260 check_mips_64(ctx);
17261 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
17262 break;
17263 case R6_OPC_DCLO:
17264 case R6_OPC_DCLZ:
17265 if (rt == 0 && sa == 1) {
17266 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17267 We need additionally to check other fields */
17268 check_mips_64(ctx);
17269 gen_cl(ctx, op1, rd, rs);
17270 } else {
17271 generate_exception_end(ctx, EXCP_RI);
17272 }
17273 break;
17274 case OPC_DMULT ... OPC_DDIVU:
17275 op2 = MASK_R6_MULDIV(ctx->opcode);
17276 switch (op2) {
17277 case R6_OPC_DMUL:
17278 case R6_OPC_DMUH:
17279 case R6_OPC_DMULU:
17280 case R6_OPC_DMUHU:
17281 case R6_OPC_DDIV:
17282 case R6_OPC_DMOD:
17283 case R6_OPC_DDIVU:
17284 case R6_OPC_DMODU:
17285 check_mips_64(ctx);
17286 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17287 break;
17288 default:
17289 MIPS_INVAL("special_r6 muldiv");
17290 generate_exception_end(ctx, EXCP_RI);
17291 break;
17292 }
17293 break;
17294 #endif
17295 default: /* Invalid */
17296 MIPS_INVAL("special_r6");
17297 generate_exception_end(ctx, EXCP_RI);
17298 break;
17299 }
17300 }
17301
17302 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17303 {
17304 int rs, rt, rd, sa;
17305 uint32_t op1;
17306
17307 rs = (ctx->opcode >> 21) & 0x1f;
17308 rt = (ctx->opcode >> 16) & 0x1f;
17309 rd = (ctx->opcode >> 11) & 0x1f;
17310 sa = (ctx->opcode >> 6) & 0x1f;
17311
17312 op1 = MASK_SPECIAL(ctx->opcode);
17313 switch (op1) {
17314 case OPC_MOVN: /* Conditional move */
17315 case OPC_MOVZ:
17316 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17317 INSN_LOONGSON2E | INSN_LOONGSON2F);
17318 gen_cond_move(ctx, op1, rd, rs, rt);
17319 break;
17320 case OPC_MFHI: /* Move from HI/LO */
17321 case OPC_MFLO:
17322 gen_HILO(ctx, op1, rs & 3, rd);
17323 break;
17324 case OPC_MTHI:
17325 case OPC_MTLO: /* Move to HI/LO */
17326 gen_HILO(ctx, op1, rd & 3, rs);
17327 break;
17328 case OPC_MOVCI:
17329 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17330 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17331 check_cp1_enabled(ctx);
17332 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17333 (ctx->opcode >> 16) & 1);
17334 } else {
17335 generate_exception_err(ctx, EXCP_CpU, 1);
17336 }
17337 break;
17338 case OPC_MULT:
17339 case OPC_MULTU:
17340 if (sa) {
17341 check_insn(ctx, INSN_VR54XX);
17342 op1 = MASK_MUL_VR54XX(ctx->opcode);
17343 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17344 } else {
17345 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17346 }
17347 break;
17348 case OPC_DIV:
17349 case OPC_DIVU:
17350 gen_muldiv(ctx, op1, 0, rs, rt);
17351 break;
17352 #if defined(TARGET_MIPS64)
17353 case OPC_DMULT ... OPC_DDIVU:
17354 check_insn(ctx, ISA_MIPS3);
17355 check_mips_64(ctx);
17356 gen_muldiv(ctx, op1, 0, rs, rt);
17357 break;
17358 #endif
17359 case OPC_JR:
17360 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17361 break;
17362 case OPC_SPIM:
17363 #ifdef MIPS_STRICT_STANDARD
17364 MIPS_INVAL("SPIM");
17365 generate_exception_end(ctx, EXCP_RI);
17366 #else
17367 /* Implemented as RI exception for now. */
17368 MIPS_INVAL("spim (unofficial)");
17369 generate_exception_end(ctx, EXCP_RI);
17370 #endif
17371 break;
17372 default: /* Invalid */
17373 MIPS_INVAL("special_legacy");
17374 generate_exception_end(ctx, EXCP_RI);
17375 break;
17376 }
17377 }
17378
17379 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
17380 {
17381 int rs, rt, rd, sa;
17382 uint32_t op1;
17383
17384 rs = (ctx->opcode >> 21) & 0x1f;
17385 rt = (ctx->opcode >> 16) & 0x1f;
17386 rd = (ctx->opcode >> 11) & 0x1f;
17387 sa = (ctx->opcode >> 6) & 0x1f;
17388
17389 op1 = MASK_SPECIAL(ctx->opcode);
17390 switch (op1) {
17391 case OPC_SLL: /* Shift with immediate */
17392 if (sa == 5 && rd == 0 &&
17393 rs == 0 && rt == 0) { /* PAUSE */
17394 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17395 (ctx->hflags & MIPS_HFLAG_BMASK)) {
17396 generate_exception_end(ctx, EXCP_RI);
17397 break;
17398 }
17399 }
17400 /* Fallthrough */
17401 case OPC_SRA:
17402 gen_shift_imm(ctx, op1, rd, rt, sa);
17403 break;
17404 case OPC_SRL:
17405 switch ((ctx->opcode >> 21) & 0x1f) {
17406 case 1:
17407 /* rotr is decoded as srl on non-R2 CPUs */
17408 if (ctx->insn_flags & ISA_MIPS32R2) {
17409 op1 = OPC_ROTR;
17410 }
17411 /* Fallthrough */
17412 case 0:
17413 gen_shift_imm(ctx, op1, rd, rt, sa);
17414 break;
17415 default:
17416 generate_exception_end(ctx, EXCP_RI);
17417 break;
17418 }
17419 break;
17420 case OPC_ADD ... OPC_SUBU:
17421 gen_arith(ctx, op1, rd, rs, rt);
17422 break;
17423 case OPC_SLLV: /* Shifts */
17424 case OPC_SRAV:
17425 gen_shift(ctx, op1, rd, rs, rt);
17426 break;
17427 case OPC_SRLV:
17428 switch ((ctx->opcode >> 6) & 0x1f) {
17429 case 1:
17430 /* rotrv is decoded as srlv on non-R2 CPUs */
17431 if (ctx->insn_flags & ISA_MIPS32R2) {
17432 op1 = OPC_ROTRV;
17433 }
17434 /* Fallthrough */
17435 case 0:
17436 gen_shift(ctx, op1, rd, rs, rt);
17437 break;
17438 default:
17439 generate_exception_end(ctx, EXCP_RI);
17440 break;
17441 }
17442 break;
17443 case OPC_SLT: /* Set on less than */
17444 case OPC_SLTU:
17445 gen_slt(ctx, op1, rd, rs, rt);
17446 break;
17447 case OPC_AND: /* Logic*/
17448 case OPC_OR:
17449 case OPC_NOR:
17450 case OPC_XOR:
17451 gen_logic(ctx, op1, rd, rs, rt);
17452 break;
17453 case OPC_JALR:
17454 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17455 break;
17456 case OPC_TGE ... OPC_TEQ: /* Traps */
17457 case OPC_TNE:
17458 check_insn(ctx, ISA_MIPS2);
17459 gen_trap(ctx, op1, rs, rt, -1);
17460 break;
17461 case OPC_LSA: /* OPC_PMON */
17462 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17463 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17464 decode_opc_special_r6(env, ctx);
17465 } else {
17466 /* Pmon entry point, also R4010 selsl */
17467 #ifdef MIPS_STRICT_STANDARD
17468 MIPS_INVAL("PMON / selsl");
17469 generate_exception_end(ctx, EXCP_RI);
17470 #else
17471 gen_helper_0e0i(pmon, sa);
17472 #endif
17473 }
17474 break;
17475 case OPC_SYSCALL:
17476 generate_exception_end(ctx, EXCP_SYSCALL);
17477 break;
17478 case OPC_BREAK:
17479 generate_exception_end(ctx, EXCP_BREAK);
17480 break;
17481 case OPC_SYNC:
17482 check_insn(ctx, ISA_MIPS2);
17483 gen_sync(extract32(ctx->opcode, 6, 5));
17484 break;
17485
17486 #if defined(TARGET_MIPS64)
17487 /* MIPS64 specific opcodes */
17488 case OPC_DSLL:
17489 case OPC_DSRA:
17490 case OPC_DSLL32:
17491 case OPC_DSRA32:
17492 check_insn(ctx, ISA_MIPS3);
17493 check_mips_64(ctx);
17494 gen_shift_imm(ctx, op1, rd, rt, sa);
17495 break;
17496 case OPC_DSRL:
17497 switch ((ctx->opcode >> 21) & 0x1f) {
17498 case 1:
17499 /* drotr is decoded as dsrl on non-R2 CPUs */
17500 if (ctx->insn_flags & ISA_MIPS32R2) {
17501 op1 = OPC_DROTR;
17502 }
17503 /* Fallthrough */
17504 case 0:
17505 check_insn(ctx, ISA_MIPS3);
17506 check_mips_64(ctx);
17507 gen_shift_imm(ctx, op1, rd, rt, sa);
17508 break;
17509 default:
17510 generate_exception_end(ctx, EXCP_RI);
17511 break;
17512 }
17513 break;
17514 case OPC_DSRL32:
17515 switch ((ctx->opcode >> 21) & 0x1f) {
17516 case 1:
17517 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17518 if (ctx->insn_flags & ISA_MIPS32R2) {
17519 op1 = OPC_DROTR32;
17520 }
17521 /* Fallthrough */
17522 case 0:
17523 check_insn(ctx, ISA_MIPS3);
17524 check_mips_64(ctx);
17525 gen_shift_imm(ctx, op1, rd, rt, sa);
17526 break;
17527 default:
17528 generate_exception_end(ctx, EXCP_RI);
17529 break;
17530 }
17531 break;
17532 case OPC_DADD ... OPC_DSUBU:
17533 check_insn(ctx, ISA_MIPS3);
17534 check_mips_64(ctx);
17535 gen_arith(ctx, op1, rd, rs, rt);
17536 break;
17537 case OPC_DSLLV:
17538 case OPC_DSRAV:
17539 check_insn(ctx, ISA_MIPS3);
17540 check_mips_64(ctx);
17541 gen_shift(ctx, op1, rd, rs, rt);
17542 break;
17543 case OPC_DSRLV:
17544 switch ((ctx->opcode >> 6) & 0x1f) {
17545 case 1:
17546 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17547 if (ctx->insn_flags & ISA_MIPS32R2) {
17548 op1 = OPC_DROTRV;
17549 }
17550 /* Fallthrough */
17551 case 0:
17552 check_insn(ctx, ISA_MIPS3);
17553 check_mips_64(ctx);
17554 gen_shift(ctx, op1, rd, rs, rt);
17555 break;
17556 default:
17557 generate_exception_end(ctx, EXCP_RI);
17558 break;
17559 }
17560 break;
17561 case OPC_DLSA:
17562 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17563 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17564 decode_opc_special_r6(env, ctx);
17565 }
17566 break;
17567 #endif
17568 default:
17569 if (ctx->insn_flags & ISA_MIPS32R6) {
17570 decode_opc_special_r6(env, ctx);
17571 } else {
17572 decode_opc_special_legacy(env, ctx);
17573 }
17574 }
17575 }
17576
17577 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17578 {
17579 int rs, rt, rd;
17580 uint32_t op1;
17581
17582 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17583
17584 rs = (ctx->opcode >> 21) & 0x1f;
17585 rt = (ctx->opcode >> 16) & 0x1f;
17586 rd = (ctx->opcode >> 11) & 0x1f;
17587
17588 op1 = MASK_SPECIAL2(ctx->opcode);
17589 switch (op1) {
17590 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17591 case OPC_MSUB ... OPC_MSUBU:
17592 check_insn(ctx, ISA_MIPS32);
17593 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17594 break;
17595 case OPC_MUL:
17596 gen_arith(ctx, op1, rd, rs, rt);
17597 break;
17598 case OPC_DIV_G_2F:
17599 case OPC_DIVU_G_2F:
17600 case OPC_MULT_G_2F:
17601 case OPC_MULTU_G_2F:
17602 case OPC_MOD_G_2F:
17603 case OPC_MODU_G_2F:
17604 check_insn(ctx, INSN_LOONGSON2F);
17605 gen_loongson_integer(ctx, op1, rd, rs, rt);
17606 break;
17607 case OPC_CLO:
17608 case OPC_CLZ:
17609 check_insn(ctx, ISA_MIPS32);
17610 gen_cl(ctx, op1, rd, rs);
17611 break;
17612 case OPC_SDBBP:
17613 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17614 gen_helper_do_semihosting(cpu_env);
17615 } else {
17616 /* XXX: not clear which exception should be raised
17617 * when in debug mode...
17618 */
17619 check_insn(ctx, ISA_MIPS32);
17620 generate_exception_end(ctx, EXCP_DBp);
17621 }
17622 break;
17623 #if defined(TARGET_MIPS64)
17624 case OPC_DCLO:
17625 case OPC_DCLZ:
17626 check_insn(ctx, ISA_MIPS64);
17627 check_mips_64(ctx);
17628 gen_cl(ctx, op1, rd, rs);
17629 break;
17630 case OPC_DMULT_G_2F:
17631 case OPC_DMULTU_G_2F:
17632 case OPC_DDIV_G_2F:
17633 case OPC_DDIVU_G_2F:
17634 case OPC_DMOD_G_2F:
17635 case OPC_DMODU_G_2F:
17636 check_insn(ctx, INSN_LOONGSON2F);
17637 gen_loongson_integer(ctx, op1, rd, rs, rt);
17638 break;
17639 #endif
17640 default: /* Invalid */
17641 MIPS_INVAL("special2_legacy");
17642 generate_exception_end(ctx, EXCP_RI);
17643 break;
17644 }
17645 }
17646
17647 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17648 {
17649 int rs, rt, rd, sa;
17650 uint32_t op1, op2;
17651 int16_t imm;
17652
17653 rs = (ctx->opcode >> 21) & 0x1f;
17654 rt = (ctx->opcode >> 16) & 0x1f;
17655 rd = (ctx->opcode >> 11) & 0x1f;
17656 sa = (ctx->opcode >> 6) & 0x1f;
17657 imm = (int16_t)ctx->opcode >> 7;
17658
17659 op1 = MASK_SPECIAL3(ctx->opcode);
17660 switch (op1) {
17661 case R6_OPC_PREF:
17662 if (rt >= 24) {
17663 /* hint codes 24-31 are reserved and signal RI */
17664 generate_exception_end(ctx, EXCP_RI);
17665 }
17666 /* Treat as NOP. */
17667 break;
17668 case R6_OPC_CACHE:
17669 check_cp0_enabled(ctx);
17670 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17671 gen_cache_operation(ctx, rt, rs, imm);
17672 }
17673 break;
17674 case R6_OPC_SC:
17675 gen_st_cond(ctx, op1, rt, rs, imm);
17676 break;
17677 case R6_OPC_LL:
17678 gen_ld(ctx, op1, rt, rs, imm);
17679 break;
17680 case OPC_BSHFL:
17681 {
17682 if (rd == 0) {
17683 /* Treat as NOP. */
17684 break;
17685 }
17686 op2 = MASK_BSHFL(ctx->opcode);
17687 switch (op2) {
17688 case OPC_ALIGN ... OPC_ALIGN_END:
17689 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17690 break;
17691 case OPC_BITSWAP:
17692 gen_bitswap(ctx, op2, rd, rt);
17693 break;
17694 }
17695 }
17696 break;
17697 #if defined(TARGET_MIPS64)
17698 case R6_OPC_SCD:
17699 gen_st_cond(ctx, op1, rt, rs, imm);
17700 break;
17701 case R6_OPC_LLD:
17702 gen_ld(ctx, op1, rt, rs, imm);
17703 break;
17704 case OPC_DBSHFL:
17705 check_mips_64(ctx);
17706 {
17707 if (rd == 0) {
17708 /* Treat as NOP. */
17709 break;
17710 }
17711 op2 = MASK_DBSHFL(ctx->opcode);
17712 switch (op2) {
17713 case OPC_DALIGN ... OPC_DALIGN_END:
17714 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17715 break;
17716 case OPC_DBITSWAP:
17717 gen_bitswap(ctx, op2, rd, rt);
17718 break;
17719 }
17720
17721 }
17722 break;
17723 #endif
17724 default: /* Invalid */
17725 MIPS_INVAL("special3_r6");
17726 generate_exception_end(ctx, EXCP_RI);
17727 break;
17728 }
17729 }
17730
17731 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17732 {
17733 int rs, rt, rd;
17734 uint32_t op1, op2;
17735
17736 rs = (ctx->opcode >> 21) & 0x1f;
17737 rt = (ctx->opcode >> 16) & 0x1f;
17738 rd = (ctx->opcode >> 11) & 0x1f;
17739
17740 op1 = MASK_SPECIAL3(ctx->opcode);
17741 switch (op1) {
17742 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17743 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17744 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17745 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17746 * the same mask and op1. */
17747 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17748 op2 = MASK_ADDUH_QB(ctx->opcode);
17749 switch (op2) {
17750 case OPC_ADDUH_QB:
17751 case OPC_ADDUH_R_QB:
17752 case OPC_ADDQH_PH:
17753 case OPC_ADDQH_R_PH:
17754 case OPC_ADDQH_W:
17755 case OPC_ADDQH_R_W:
17756 case OPC_SUBUH_QB:
17757 case OPC_SUBUH_R_QB:
17758 case OPC_SUBQH_PH:
17759 case OPC_SUBQH_R_PH:
17760 case OPC_SUBQH_W:
17761 case OPC_SUBQH_R_W:
17762 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17763 break;
17764 case OPC_MUL_PH:
17765 case OPC_MUL_S_PH:
17766 case OPC_MULQ_S_W:
17767 case OPC_MULQ_RS_W:
17768 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17769 break;
17770 default:
17771 MIPS_INVAL("MASK ADDUH.QB");
17772 generate_exception_end(ctx, EXCP_RI);
17773 break;
17774 }
17775 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17776 gen_loongson_integer(ctx, op1, rd, rs, rt);
17777 } else {
17778 generate_exception_end(ctx, EXCP_RI);
17779 }
17780 break;
17781 case OPC_LX_DSP:
17782 op2 = MASK_LX(ctx->opcode);
17783 switch (op2) {
17784 #if defined(TARGET_MIPS64)
17785 case OPC_LDX:
17786 #endif
17787 case OPC_LBUX:
17788 case OPC_LHX:
17789 case OPC_LWX:
17790 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17791 break;
17792 default: /* Invalid */
17793 MIPS_INVAL("MASK LX");
17794 generate_exception_end(ctx, EXCP_RI);
17795 break;
17796 }
17797 break;
17798 case OPC_ABSQ_S_PH_DSP:
17799 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17800 switch (op2) {
17801 case OPC_ABSQ_S_QB:
17802 case OPC_ABSQ_S_PH:
17803 case OPC_ABSQ_S_W:
17804 case OPC_PRECEQ_W_PHL:
17805 case OPC_PRECEQ_W_PHR:
17806 case OPC_PRECEQU_PH_QBL:
17807 case OPC_PRECEQU_PH_QBR:
17808 case OPC_PRECEQU_PH_QBLA:
17809 case OPC_PRECEQU_PH_QBRA:
17810 case OPC_PRECEU_PH_QBL:
17811 case OPC_PRECEU_PH_QBR:
17812 case OPC_PRECEU_PH_QBLA:
17813 case OPC_PRECEU_PH_QBRA:
17814 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17815 break;
17816 case OPC_BITREV:
17817 case OPC_REPL_QB:
17818 case OPC_REPLV_QB:
17819 case OPC_REPL_PH:
17820 case OPC_REPLV_PH:
17821 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17822 break;
17823 default:
17824 MIPS_INVAL("MASK ABSQ_S.PH");
17825 generate_exception_end(ctx, EXCP_RI);
17826 break;
17827 }
17828 break;
17829 case OPC_ADDU_QB_DSP:
17830 op2 = MASK_ADDU_QB(ctx->opcode);
17831 switch (op2) {
17832 case OPC_ADDQ_PH:
17833 case OPC_ADDQ_S_PH:
17834 case OPC_ADDQ_S_W:
17835 case OPC_ADDU_QB:
17836 case OPC_ADDU_S_QB:
17837 case OPC_ADDU_PH:
17838 case OPC_ADDU_S_PH:
17839 case OPC_SUBQ_PH:
17840 case OPC_SUBQ_S_PH:
17841 case OPC_SUBQ_S_W:
17842 case OPC_SUBU_QB:
17843 case OPC_SUBU_S_QB:
17844 case OPC_SUBU_PH:
17845 case OPC_SUBU_S_PH:
17846 case OPC_ADDSC:
17847 case OPC_ADDWC:
17848 case OPC_MODSUB:
17849 case OPC_RADDU_W_QB:
17850 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17851 break;
17852 case OPC_MULEU_S_PH_QBL:
17853 case OPC_MULEU_S_PH_QBR:
17854 case OPC_MULQ_RS_PH:
17855 case OPC_MULEQ_S_W_PHL:
17856 case OPC_MULEQ_S_W_PHR:
17857 case OPC_MULQ_S_PH:
17858 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17859 break;
17860 default: /* Invalid */
17861 MIPS_INVAL("MASK ADDU.QB");
17862 generate_exception_end(ctx, EXCP_RI);
17863 break;
17864
17865 }
17866 break;
17867 case OPC_CMPU_EQ_QB_DSP:
17868 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17869 switch (op2) {
17870 case OPC_PRECR_SRA_PH_W:
17871 case OPC_PRECR_SRA_R_PH_W:
17872 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17873 break;
17874 case OPC_PRECR_QB_PH:
17875 case OPC_PRECRQ_QB_PH:
17876 case OPC_PRECRQ_PH_W:
17877 case OPC_PRECRQ_RS_PH_W:
17878 case OPC_PRECRQU_S_QB_PH:
17879 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17880 break;
17881 case OPC_CMPU_EQ_QB:
17882 case OPC_CMPU_LT_QB:
17883 case OPC_CMPU_LE_QB:
17884 case OPC_CMP_EQ_PH:
17885 case OPC_CMP_LT_PH:
17886 case OPC_CMP_LE_PH:
17887 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17888 break;
17889 case OPC_CMPGU_EQ_QB:
17890 case OPC_CMPGU_LT_QB:
17891 case OPC_CMPGU_LE_QB:
17892 case OPC_CMPGDU_EQ_QB:
17893 case OPC_CMPGDU_LT_QB:
17894 case OPC_CMPGDU_LE_QB:
17895 case OPC_PICK_QB:
17896 case OPC_PICK_PH:
17897 case OPC_PACKRL_PH:
17898 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17899 break;
17900 default: /* Invalid */
17901 MIPS_INVAL("MASK CMPU.EQ.QB");
17902 generate_exception_end(ctx, EXCP_RI);
17903 break;
17904 }
17905 break;
17906 case OPC_SHLL_QB_DSP:
17907 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17908 break;
17909 case OPC_DPA_W_PH_DSP:
17910 op2 = MASK_DPA_W_PH(ctx->opcode);
17911 switch (op2) {
17912 case OPC_DPAU_H_QBL:
17913 case OPC_DPAU_H_QBR:
17914 case OPC_DPSU_H_QBL:
17915 case OPC_DPSU_H_QBR:
17916 case OPC_DPA_W_PH:
17917 case OPC_DPAX_W_PH:
17918 case OPC_DPAQ_S_W_PH:
17919 case OPC_DPAQX_S_W_PH:
17920 case OPC_DPAQX_SA_W_PH:
17921 case OPC_DPS_W_PH:
17922 case OPC_DPSX_W_PH:
17923 case OPC_DPSQ_S_W_PH:
17924 case OPC_DPSQX_S_W_PH:
17925 case OPC_DPSQX_SA_W_PH:
17926 case OPC_MULSAQ_S_W_PH:
17927 case OPC_DPAQ_SA_L_W:
17928 case OPC_DPSQ_SA_L_W:
17929 case OPC_MAQ_S_W_PHL:
17930 case OPC_MAQ_S_W_PHR:
17931 case OPC_MAQ_SA_W_PHL:
17932 case OPC_MAQ_SA_W_PHR:
17933 case OPC_MULSA_W_PH:
17934 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17935 break;
17936 default: /* Invalid */
17937 MIPS_INVAL("MASK DPAW.PH");
17938 generate_exception_end(ctx, EXCP_RI);
17939 break;
17940 }
17941 break;
17942 case OPC_INSV_DSP:
17943 op2 = MASK_INSV(ctx->opcode);
17944 switch (op2) {
17945 case OPC_INSV:
17946 check_dsp(ctx);
17947 {
17948 TCGv t0, t1;
17949
17950 if (rt == 0) {
17951 break;
17952 }
17953
17954 t0 = tcg_temp_new();
17955 t1 = tcg_temp_new();
17956
17957 gen_load_gpr(t0, rt);
17958 gen_load_gpr(t1, rs);
17959
17960 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17961
17962 tcg_temp_free(t0);
17963 tcg_temp_free(t1);
17964 break;
17965 }
17966 default: /* Invalid */
17967 MIPS_INVAL("MASK INSV");
17968 generate_exception_end(ctx, EXCP_RI);
17969 break;
17970 }
17971 break;
17972 case OPC_APPEND_DSP:
17973 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17974 break;
17975 case OPC_EXTR_W_DSP:
17976 op2 = MASK_EXTR_W(ctx->opcode);
17977 switch (op2) {
17978 case OPC_EXTR_W:
17979 case OPC_EXTR_R_W:
17980 case OPC_EXTR_RS_W:
17981 case OPC_EXTR_S_H:
17982 case OPC_EXTRV_S_H:
17983 case OPC_EXTRV_W:
17984 case OPC_EXTRV_R_W:
17985 case OPC_EXTRV_RS_W:
17986 case OPC_EXTP:
17987 case OPC_EXTPV:
17988 case OPC_EXTPDP:
17989 case OPC_EXTPDPV:
17990 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17991 break;
17992 case OPC_RDDSP:
17993 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17994 break;
17995 case OPC_SHILO:
17996 case OPC_SHILOV:
17997 case OPC_MTHLIP:
17998 case OPC_WRDSP:
17999 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
18000 break;
18001 default: /* Invalid */
18002 MIPS_INVAL("MASK EXTR.W");
18003 generate_exception_end(ctx, EXCP_RI);
18004 break;
18005 }
18006 break;
18007 #if defined(TARGET_MIPS64)
18008 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
18009 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
18010 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
18011 check_insn(ctx, INSN_LOONGSON2E);
18012 gen_loongson_integer(ctx, op1, rd, rs, rt);
18013 break;
18014 case OPC_ABSQ_S_QH_DSP:
18015 op2 = MASK_ABSQ_S_QH(ctx->opcode);
18016 switch (op2) {
18017 case OPC_PRECEQ_L_PWL:
18018 case OPC_PRECEQ_L_PWR:
18019 case OPC_PRECEQ_PW_QHL:
18020 case OPC_PRECEQ_PW_QHR:
18021 case OPC_PRECEQ_PW_QHLA:
18022 case OPC_PRECEQ_PW_QHRA:
18023 case OPC_PRECEQU_QH_OBL:
18024 case OPC_PRECEQU_QH_OBR:
18025 case OPC_PRECEQU_QH_OBLA:
18026 case OPC_PRECEQU_QH_OBRA:
18027 case OPC_PRECEU_QH_OBL:
18028 case OPC_PRECEU_QH_OBR:
18029 case OPC_PRECEU_QH_OBLA:
18030 case OPC_PRECEU_QH_OBRA:
18031 case OPC_ABSQ_S_OB:
18032 case OPC_ABSQ_S_PW:
18033 case OPC_ABSQ_S_QH:
18034 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18035 break;
18036 case OPC_REPL_OB:
18037 case OPC_REPL_PW:
18038 case OPC_REPL_QH:
18039 case OPC_REPLV_OB:
18040 case OPC_REPLV_PW:
18041 case OPC_REPLV_QH:
18042 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
18043 break;
18044 default: /* Invalid */
18045 MIPS_INVAL("MASK ABSQ_S.QH");
18046 generate_exception_end(ctx, EXCP_RI);
18047 break;
18048 }
18049 break;
18050 case OPC_ADDU_OB_DSP:
18051 op2 = MASK_ADDU_OB(ctx->opcode);
18052 switch (op2) {
18053 case OPC_RADDU_L_OB:
18054 case OPC_SUBQ_PW:
18055 case OPC_SUBQ_S_PW:
18056 case OPC_SUBQ_QH:
18057 case OPC_SUBQ_S_QH:
18058 case OPC_SUBU_OB:
18059 case OPC_SUBU_S_OB:
18060 case OPC_SUBU_QH:
18061 case OPC_SUBU_S_QH:
18062 case OPC_SUBUH_OB:
18063 case OPC_SUBUH_R_OB:
18064 case OPC_ADDQ_PW:
18065 case OPC_ADDQ_S_PW:
18066 case OPC_ADDQ_QH:
18067 case OPC_ADDQ_S_QH:
18068 case OPC_ADDU_OB:
18069 case OPC_ADDU_S_OB:
18070 case OPC_ADDU_QH:
18071 case OPC_ADDU_S_QH:
18072 case OPC_ADDUH_OB:
18073 case OPC_ADDUH_R_OB:
18074 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18075 break;
18076 case OPC_MULEQ_S_PW_QHL:
18077 case OPC_MULEQ_S_PW_QHR:
18078 case OPC_MULEU_S_QH_OBL:
18079 case OPC_MULEU_S_QH_OBR:
18080 case OPC_MULQ_RS_QH:
18081 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
18082 break;
18083 default: /* Invalid */
18084 MIPS_INVAL("MASK ADDU.OB");
18085 generate_exception_end(ctx, EXCP_RI);
18086 break;
18087 }
18088 break;
18089 case OPC_CMPU_EQ_OB_DSP:
18090 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
18091 switch (op2) {
18092 case OPC_PRECR_SRA_QH_PW:
18093 case OPC_PRECR_SRA_R_QH_PW:
18094 /* Return value is rt. */
18095 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
18096 break;
18097 case OPC_PRECR_OB_QH:
18098 case OPC_PRECRQ_OB_QH:
18099 case OPC_PRECRQ_PW_L:
18100 case OPC_PRECRQ_QH_PW:
18101 case OPC_PRECRQ_RS_QH_PW:
18102 case OPC_PRECRQU_S_OB_QH:
18103 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18104 break;
18105 case OPC_CMPU_EQ_OB:
18106 case OPC_CMPU_LT_OB:
18107 case OPC_CMPU_LE_OB:
18108 case OPC_CMP_EQ_QH:
18109 case OPC_CMP_LT_QH:
18110 case OPC_CMP_LE_QH:
18111 case OPC_CMP_EQ_PW:
18112 case OPC_CMP_LT_PW:
18113 case OPC_CMP_LE_PW:
18114 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
18115 break;
18116 case OPC_CMPGDU_EQ_OB:
18117 case OPC_CMPGDU_LT_OB:
18118 case OPC_CMPGDU_LE_OB:
18119 case OPC_CMPGU_EQ_OB:
18120 case OPC_CMPGU_LT_OB:
18121 case OPC_CMPGU_LE_OB:
18122 case OPC_PACKRL_PW:
18123 case OPC_PICK_OB:
18124 case OPC_PICK_PW:
18125 case OPC_PICK_QH:
18126 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
18127 break;
18128 default: /* Invalid */
18129 MIPS_INVAL("MASK CMPU_EQ.OB");
18130 generate_exception_end(ctx, EXCP_RI);
18131 break;
18132 }
18133 break;
18134 case OPC_DAPPEND_DSP:
18135 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18136 break;
18137 case OPC_DEXTR_W_DSP:
18138 op2 = MASK_DEXTR_W(ctx->opcode);
18139 switch (op2) {
18140 case OPC_DEXTP:
18141 case OPC_DEXTPDP:
18142 case OPC_DEXTPDPV:
18143 case OPC_DEXTPV:
18144 case OPC_DEXTR_L:
18145 case OPC_DEXTR_R_L:
18146 case OPC_DEXTR_RS_L:
18147 case OPC_DEXTR_W:
18148 case OPC_DEXTR_R_W:
18149 case OPC_DEXTR_RS_W:
18150 case OPC_DEXTR_S_H:
18151 case OPC_DEXTRV_L:
18152 case OPC_DEXTRV_R_L:
18153 case OPC_DEXTRV_RS_L:
18154 case OPC_DEXTRV_S_H:
18155 case OPC_DEXTRV_W:
18156 case OPC_DEXTRV_R_W:
18157 case OPC_DEXTRV_RS_W:
18158 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
18159 break;
18160 case OPC_DMTHLIP:
18161 case OPC_DSHILO:
18162 case OPC_DSHILOV:
18163 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
18164 break;
18165 default: /* Invalid */
18166 MIPS_INVAL("MASK EXTR.W");
18167 generate_exception_end(ctx, EXCP_RI);
18168 break;
18169 }
18170 break;
18171 case OPC_DPAQ_W_QH_DSP:
18172 op2 = MASK_DPAQ_W_QH(ctx->opcode);
18173 switch (op2) {
18174 case OPC_DPAU_H_OBL:
18175 case OPC_DPAU_H_OBR:
18176 case OPC_DPSU_H_OBL:
18177 case OPC_DPSU_H_OBR:
18178 case OPC_DPA_W_QH:
18179 case OPC_DPAQ_S_W_QH:
18180 case OPC_DPS_W_QH:
18181 case OPC_DPSQ_S_W_QH:
18182 case OPC_MULSAQ_S_W_QH:
18183 case OPC_DPAQ_SA_L_PW:
18184 case OPC_DPSQ_SA_L_PW:
18185 case OPC_MULSAQ_S_L_PW:
18186 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18187 break;
18188 case OPC_MAQ_S_W_QHLL:
18189 case OPC_MAQ_S_W_QHLR:
18190 case OPC_MAQ_S_W_QHRL:
18191 case OPC_MAQ_S_W_QHRR:
18192 case OPC_MAQ_SA_W_QHLL:
18193 case OPC_MAQ_SA_W_QHLR:
18194 case OPC_MAQ_SA_W_QHRL:
18195 case OPC_MAQ_SA_W_QHRR:
18196 case OPC_MAQ_S_L_PWL:
18197 case OPC_MAQ_S_L_PWR:
18198 case OPC_DMADD:
18199 case OPC_DMADDU:
18200 case OPC_DMSUB:
18201 case OPC_DMSUBU:
18202 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18203 break;
18204 default: /* Invalid */
18205 MIPS_INVAL("MASK DPAQ.W.QH");
18206 generate_exception_end(ctx, EXCP_RI);
18207 break;
18208 }
18209 break;
18210 case OPC_DINSV_DSP:
18211 op2 = MASK_INSV(ctx->opcode);
18212 switch (op2) {
18213 case OPC_DINSV:
18214 {
18215 TCGv t0, t1;
18216
18217 if (rt == 0) {
18218 break;
18219 }
18220 check_dsp(ctx);
18221
18222 t0 = tcg_temp_new();
18223 t1 = tcg_temp_new();
18224
18225 gen_load_gpr(t0, rt);
18226 gen_load_gpr(t1, rs);
18227
18228 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
18229
18230 tcg_temp_free(t0);
18231 tcg_temp_free(t1);
18232 break;
18233 }
18234 default: /* Invalid */
18235 MIPS_INVAL("MASK DINSV");
18236 generate_exception_end(ctx, EXCP_RI);
18237 break;
18238 }
18239 break;
18240 case OPC_SHLL_OB_DSP:
18241 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18242 break;
18243 #endif
18244 default: /* Invalid */
18245 MIPS_INVAL("special3_legacy");
18246 generate_exception_end(ctx, EXCP_RI);
18247 break;
18248 }
18249 }
18250
18251 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18252 {
18253 int rs, rt, rd, sa;
18254 uint32_t op1, op2;
18255 int16_t imm;
18256
18257 rs = (ctx->opcode >> 21) & 0x1f;
18258 rt = (ctx->opcode >> 16) & 0x1f;
18259 rd = (ctx->opcode >> 11) & 0x1f;
18260 sa = (ctx->opcode >> 6) & 0x1f;
18261 imm = sextract32(ctx->opcode, 7, 9);
18262
18263 op1 = MASK_SPECIAL3(ctx->opcode);
18264
18265 /*
18266 * EVA loads and stores overlap Loongson 2E instructions decoded by
18267 * decode_opc_special3_legacy(), so be careful to allow their decoding when
18268 * EVA is absent.
18269 */
18270 if (ctx->eva) {
18271 switch (op1) {
18272 case OPC_LWLE ... OPC_LWRE:
18273 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18274 /* fall through */
18275 case OPC_LBUE ... OPC_LHUE:
18276 case OPC_LBE ... OPC_LWE:
18277 check_cp0_enabled(ctx);
18278 gen_ld(ctx, op1, rt, rs, imm);
18279 return;
18280 case OPC_SWLE ... OPC_SWRE:
18281 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18282 /* fall through */
18283 case OPC_SBE ... OPC_SHE:
18284 case OPC_SWE:
18285 check_cp0_enabled(ctx);
18286 gen_st(ctx, op1, rt, rs, imm);
18287 return;
18288 case OPC_SCE:
18289 check_cp0_enabled(ctx);
18290 gen_st_cond(ctx, op1, rt, rs, imm);
18291 return;
18292 case OPC_CACHEE:
18293 check_cp0_enabled(ctx);
18294 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
18295 gen_cache_operation(ctx, rt, rs, imm);
18296 }
18297 /* Treat as NOP. */
18298 return;
18299 case OPC_PREFE:
18300 check_cp0_enabled(ctx);
18301 /* Treat as NOP. */
18302 return;
18303 }
18304 }
18305
18306 switch (op1) {
18307 case OPC_EXT:
18308 case OPC_INS:
18309 check_insn(ctx, ISA_MIPS32R2);
18310 gen_bitops(ctx, op1, rt, rs, sa, rd);
18311 break;
18312 case OPC_BSHFL:
18313 op2 = MASK_BSHFL(ctx->opcode);
18314 switch (op2) {
18315 case OPC_ALIGN ... OPC_ALIGN_END:
18316 case OPC_BITSWAP:
18317 check_insn(ctx, ISA_MIPS32R6);
18318 decode_opc_special3_r6(env, ctx);
18319 break;
18320 default:
18321 check_insn(ctx, ISA_MIPS32R2);
18322 gen_bshfl(ctx, op2, rt, rd);
18323 break;
18324 }
18325 break;
18326 #if defined(TARGET_MIPS64)
18327 case OPC_DEXTM ... OPC_DEXT:
18328 case OPC_DINSM ... OPC_DINS:
18329 check_insn(ctx, ISA_MIPS64R2);
18330 check_mips_64(ctx);
18331 gen_bitops(ctx, op1, rt, rs, sa, rd);
18332 break;
18333 case OPC_DBSHFL:
18334 op2 = MASK_DBSHFL(ctx->opcode);
18335 switch (op2) {
18336 case OPC_DALIGN ... OPC_DALIGN_END:
18337 case OPC_DBITSWAP:
18338 check_insn(ctx, ISA_MIPS32R6);
18339 decode_opc_special3_r6(env, ctx);
18340 break;
18341 default:
18342 check_insn(ctx, ISA_MIPS64R2);
18343 check_mips_64(ctx);
18344 op2 = MASK_DBSHFL(ctx->opcode);
18345 gen_bshfl(ctx, op2, rt, rd);
18346 break;
18347 }
18348 break;
18349 #endif
18350 case OPC_RDHWR:
18351 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
18352 break;
18353 case OPC_FORK:
18354 check_insn(ctx, ASE_MT);
18355 {
18356 TCGv t0 = tcg_temp_new();
18357 TCGv t1 = tcg_temp_new();
18358
18359 gen_load_gpr(t0, rt);
18360 gen_load_gpr(t1, rs);
18361 gen_helper_fork(t0, t1);
18362 tcg_temp_free(t0);
18363 tcg_temp_free(t1);
18364 }
18365 break;
18366 case OPC_YIELD:
18367 check_insn(ctx, ASE_MT);
18368 {
18369 TCGv t0 = tcg_temp_new();
18370
18371 gen_load_gpr(t0, rs);
18372 gen_helper_yield(t0, cpu_env, t0);
18373 gen_store_gpr(t0, rd);
18374 tcg_temp_free(t0);
18375 }
18376 break;
18377 default:
18378 if (ctx->insn_flags & ISA_MIPS32R6) {
18379 decode_opc_special3_r6(env, ctx);
18380 } else {
18381 decode_opc_special3_legacy(env, ctx);
18382 }
18383 }
18384 }
18385
18386 /* MIPS SIMD Architecture (MSA) */
18387 static inline int check_msa_access(DisasContext *ctx)
18388 {
18389 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18390 !(ctx->hflags & MIPS_HFLAG_F64))) {
18391 generate_exception_end(ctx, EXCP_RI);
18392 return 0;
18393 }
18394
18395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18396 if (ctx->insn_flags & ASE_MSA) {
18397 generate_exception_end(ctx, EXCP_MSADIS);
18398 return 0;
18399 } else {
18400 generate_exception_end(ctx, EXCP_RI);
18401 return 0;
18402 }
18403 }
18404 return 1;
18405 }
18406
18407 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18408 {
18409 /* generates tcg ops to check if any element is 0 */
18410 /* Note this function only works with MSA_WRLEN = 128 */
18411 uint64_t eval_zero_or_big = 0;
18412 uint64_t eval_big = 0;
18413 TCGv_i64 t0 = tcg_temp_new_i64();
18414 TCGv_i64 t1 = tcg_temp_new_i64();
18415 switch (df) {
18416 case DF_BYTE:
18417 eval_zero_or_big = 0x0101010101010101ULL;
18418 eval_big = 0x8080808080808080ULL;
18419 break;
18420 case DF_HALF:
18421 eval_zero_or_big = 0x0001000100010001ULL;
18422 eval_big = 0x8000800080008000ULL;
18423 break;
18424 case DF_WORD:
18425 eval_zero_or_big = 0x0000000100000001ULL;
18426 eval_big = 0x8000000080000000ULL;
18427 break;
18428 case DF_DOUBLE:
18429 eval_zero_or_big = 0x0000000000000001ULL;
18430 eval_big = 0x8000000000000000ULL;
18431 break;
18432 }
18433 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18434 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18435 tcg_gen_andi_i64(t0, t0, eval_big);
18436 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18437 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18438 tcg_gen_andi_i64(t1, t1, eval_big);
18439 tcg_gen_or_i64(t0, t0, t1);
18440 /* if all bits are zero then all elements are not zero */
18441 /* if some bit is non-zero then some element is zero */
18442 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18443 tcg_gen_trunc_i64_tl(tresult, t0);
18444 tcg_temp_free_i64(t0);
18445 tcg_temp_free_i64(t1);
18446 }
18447
18448 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18449 {
18450 uint8_t df = (ctx->opcode >> 21) & 0x3;
18451 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18452 int64_t s16 = (int16_t)ctx->opcode;
18453
18454 check_msa_access(ctx);
18455
18456 if (ctx->hflags & MIPS_HFLAG_BMASK) {
18457 generate_exception_end(ctx, EXCP_RI);
18458 return;
18459 }
18460 switch (op1) {
18461 case OPC_BZ_V:
18462 case OPC_BNZ_V:
18463 {
18464 TCGv_i64 t0 = tcg_temp_new_i64();
18465 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18466 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18467 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18468 tcg_gen_trunc_i64_tl(bcond, t0);
18469 tcg_temp_free_i64(t0);
18470 }
18471 break;
18472 case OPC_BZ_B:
18473 case OPC_BZ_H:
18474 case OPC_BZ_W:
18475 case OPC_BZ_D:
18476 gen_check_zero_element(bcond, df, wt);
18477 break;
18478 case OPC_BNZ_B:
18479 case OPC_BNZ_H:
18480 case OPC_BNZ_W:
18481 case OPC_BNZ_D:
18482 gen_check_zero_element(bcond, df, wt);
18483 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18484 break;
18485 }
18486
18487 ctx->btarget = ctx->pc + (s16 << 2) + 4;
18488
18489 ctx->hflags |= MIPS_HFLAG_BC;
18490 ctx->hflags |= MIPS_HFLAG_BDS32;
18491 }
18492
18493 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18494 {
18495 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18496 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18497 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18498 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18499
18500 TCGv_i32 twd = tcg_const_i32(wd);
18501 TCGv_i32 tws = tcg_const_i32(ws);
18502 TCGv_i32 ti8 = tcg_const_i32(i8);
18503
18504 switch (MASK_MSA_I8(ctx->opcode)) {
18505 case OPC_ANDI_B:
18506 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18507 break;
18508 case OPC_ORI_B:
18509 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18510 break;
18511 case OPC_NORI_B:
18512 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18513 break;
18514 case OPC_XORI_B:
18515 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18516 break;
18517 case OPC_BMNZI_B:
18518 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18519 break;
18520 case OPC_BMZI_B:
18521 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18522 break;
18523 case OPC_BSELI_B:
18524 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18525 break;
18526 case OPC_SHF_B:
18527 case OPC_SHF_H:
18528 case OPC_SHF_W:
18529 {
18530 uint8_t df = (ctx->opcode >> 24) & 0x3;
18531 if (df == DF_DOUBLE) {
18532 generate_exception_end(ctx, EXCP_RI);
18533 } else {
18534 TCGv_i32 tdf = tcg_const_i32(df);
18535 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18536 tcg_temp_free_i32(tdf);
18537 }
18538 }
18539 break;
18540 default:
18541 MIPS_INVAL("MSA instruction");
18542 generate_exception_end(ctx, EXCP_RI);
18543 break;
18544 }
18545
18546 tcg_temp_free_i32(twd);
18547 tcg_temp_free_i32(tws);
18548 tcg_temp_free_i32(ti8);
18549 }
18550
18551 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18552 {
18553 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18554 uint8_t df = (ctx->opcode >> 21) & 0x3;
18555 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18556 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18557 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18558 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18559
18560 TCGv_i32 tdf = tcg_const_i32(df);
18561 TCGv_i32 twd = tcg_const_i32(wd);
18562 TCGv_i32 tws = tcg_const_i32(ws);
18563 TCGv_i32 timm = tcg_temp_new_i32();
18564 tcg_gen_movi_i32(timm, u5);
18565
18566 switch (MASK_MSA_I5(ctx->opcode)) {
18567 case OPC_ADDVI_df:
18568 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18569 break;
18570 case OPC_SUBVI_df:
18571 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18572 break;
18573 case OPC_MAXI_S_df:
18574 tcg_gen_movi_i32(timm, s5);
18575 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18576 break;
18577 case OPC_MAXI_U_df:
18578 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18579 break;
18580 case OPC_MINI_S_df:
18581 tcg_gen_movi_i32(timm, s5);
18582 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18583 break;
18584 case OPC_MINI_U_df:
18585 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18586 break;
18587 case OPC_CEQI_df:
18588 tcg_gen_movi_i32(timm, s5);
18589 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18590 break;
18591 case OPC_CLTI_S_df:
18592 tcg_gen_movi_i32(timm, s5);
18593 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18594 break;
18595 case OPC_CLTI_U_df:
18596 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18597 break;
18598 case OPC_CLEI_S_df:
18599 tcg_gen_movi_i32(timm, s5);
18600 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18601 break;
18602 case OPC_CLEI_U_df:
18603 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18604 break;
18605 case OPC_LDI_df:
18606 {
18607 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18608 tcg_gen_movi_i32(timm, s10);
18609 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18610 }
18611 break;
18612 default:
18613 MIPS_INVAL("MSA instruction");
18614 generate_exception_end(ctx, EXCP_RI);
18615 break;
18616 }
18617
18618 tcg_temp_free_i32(tdf);
18619 tcg_temp_free_i32(twd);
18620 tcg_temp_free_i32(tws);
18621 tcg_temp_free_i32(timm);
18622 }
18623
18624 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18625 {
18626 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18627 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18628 uint32_t df = 0, m = 0;
18629 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18630 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18631
18632 TCGv_i32 tdf;
18633 TCGv_i32 tm;
18634 TCGv_i32 twd;
18635 TCGv_i32 tws;
18636
18637 if ((dfm & 0x40) == 0x00) {
18638 m = dfm & 0x3f;
18639 df = DF_DOUBLE;
18640 } else if ((dfm & 0x60) == 0x40) {
18641 m = dfm & 0x1f;
18642 df = DF_WORD;
18643 } else if ((dfm & 0x70) == 0x60) {
18644 m = dfm & 0x0f;
18645 df = DF_HALF;
18646 } else if ((dfm & 0x78) == 0x70) {
18647 m = dfm & 0x7;
18648 df = DF_BYTE;
18649 } else {
18650 generate_exception_end(ctx, EXCP_RI);
18651 return;
18652 }
18653
18654 tdf = tcg_const_i32(df);
18655 tm = tcg_const_i32(m);
18656 twd = tcg_const_i32(wd);
18657 tws = tcg_const_i32(ws);
18658
18659 switch (MASK_MSA_BIT(ctx->opcode)) {
18660 case OPC_SLLI_df:
18661 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18662 break;
18663 case OPC_SRAI_df:
18664 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18665 break;
18666 case OPC_SRLI_df:
18667 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18668 break;
18669 case OPC_BCLRI_df:
18670 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18671 break;
18672 case OPC_BSETI_df:
18673 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18674 break;
18675 case OPC_BNEGI_df:
18676 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18677 break;
18678 case OPC_BINSLI_df:
18679 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18680 break;
18681 case OPC_BINSRI_df:
18682 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18683 break;
18684 case OPC_SAT_S_df:
18685 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18686 break;
18687 case OPC_SAT_U_df:
18688 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18689 break;
18690 case OPC_SRARI_df:
18691 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18692 break;
18693 case OPC_SRLRI_df:
18694 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18695 break;
18696 default:
18697 MIPS_INVAL("MSA instruction");
18698 generate_exception_end(ctx, EXCP_RI);
18699 break;
18700 }
18701
18702 tcg_temp_free_i32(tdf);
18703 tcg_temp_free_i32(tm);
18704 tcg_temp_free_i32(twd);
18705 tcg_temp_free_i32(tws);
18706 }
18707
18708 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18709 {
18710 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18711 uint8_t df = (ctx->opcode >> 21) & 0x3;
18712 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18713 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18714 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18715
18716 TCGv_i32 tdf = tcg_const_i32(df);
18717 TCGv_i32 twd = tcg_const_i32(wd);
18718 TCGv_i32 tws = tcg_const_i32(ws);
18719 TCGv_i32 twt = tcg_const_i32(wt);
18720
18721 switch (MASK_MSA_3R(ctx->opcode)) {
18722 case OPC_SLL_df:
18723 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18724 break;
18725 case OPC_ADDV_df:
18726 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18727 break;
18728 case OPC_CEQ_df:
18729 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18730 break;
18731 case OPC_ADD_A_df:
18732 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18733 break;
18734 case OPC_SUBS_S_df:
18735 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18736 break;
18737 case OPC_MULV_df:
18738 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18739 break;
18740 case OPC_SLD_df:
18741 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18742 break;
18743 case OPC_VSHF_df:
18744 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18745 break;
18746 case OPC_SRA_df:
18747 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18748 break;
18749 case OPC_SUBV_df:
18750 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18751 break;
18752 case OPC_ADDS_A_df:
18753 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18754 break;
18755 case OPC_SUBS_U_df:
18756 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18757 break;
18758 case OPC_MADDV_df:
18759 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18760 break;
18761 case OPC_SPLAT_df:
18762 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18763 break;
18764 case OPC_SRAR_df:
18765 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18766 break;
18767 case OPC_SRL_df:
18768 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18769 break;
18770 case OPC_MAX_S_df:
18771 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18772 break;
18773 case OPC_CLT_S_df:
18774 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18775 break;
18776 case OPC_ADDS_S_df:
18777 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18778 break;
18779 case OPC_SUBSUS_U_df:
18780 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18781 break;
18782 case OPC_MSUBV_df:
18783 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18784 break;
18785 case OPC_PCKEV_df:
18786 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18787 break;
18788 case OPC_SRLR_df:
18789 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18790 break;
18791 case OPC_BCLR_df:
18792 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18793 break;
18794 case OPC_MAX_U_df:
18795 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18796 break;
18797 case OPC_CLT_U_df:
18798 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18799 break;
18800 case OPC_ADDS_U_df:
18801 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18802 break;
18803 case OPC_SUBSUU_S_df:
18804 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18805 break;
18806 case OPC_PCKOD_df:
18807 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18808 break;
18809 case OPC_BSET_df:
18810 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18811 break;
18812 case OPC_MIN_S_df:
18813 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18814 break;
18815 case OPC_CLE_S_df:
18816 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18817 break;
18818 case OPC_AVE_S_df:
18819 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18820 break;
18821 case OPC_ASUB_S_df:
18822 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18823 break;
18824 case OPC_DIV_S_df:
18825 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18826 break;
18827 case OPC_ILVL_df:
18828 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18829 break;
18830 case OPC_BNEG_df:
18831 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18832 break;
18833 case OPC_MIN_U_df:
18834 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18835 break;
18836 case OPC_CLE_U_df:
18837 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18838 break;
18839 case OPC_AVE_U_df:
18840 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18841 break;
18842 case OPC_ASUB_U_df:
18843 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18844 break;
18845 case OPC_DIV_U_df:
18846 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18847 break;
18848 case OPC_ILVR_df:
18849 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18850 break;
18851 case OPC_BINSL_df:
18852 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18853 break;
18854 case OPC_MAX_A_df:
18855 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18856 break;
18857 case OPC_AVER_S_df:
18858 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18859 break;
18860 case OPC_MOD_S_df:
18861 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18862 break;
18863 case OPC_ILVEV_df:
18864 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18865 break;
18866 case OPC_BINSR_df:
18867 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18868 break;
18869 case OPC_MIN_A_df:
18870 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18871 break;
18872 case OPC_AVER_U_df:
18873 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18874 break;
18875 case OPC_MOD_U_df:
18876 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18877 break;
18878 case OPC_ILVOD_df:
18879 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18880 break;
18881
18882 case OPC_DOTP_S_df:
18883 case OPC_DOTP_U_df:
18884 case OPC_DPADD_S_df:
18885 case OPC_DPADD_U_df:
18886 case OPC_DPSUB_S_df:
18887 case OPC_HADD_S_df:
18888 case OPC_DPSUB_U_df:
18889 case OPC_HADD_U_df:
18890 case OPC_HSUB_S_df:
18891 case OPC_HSUB_U_df:
18892 if (df == DF_BYTE) {
18893 generate_exception_end(ctx, EXCP_RI);
18894 break;
18895 }
18896 switch (MASK_MSA_3R(ctx->opcode)) {
18897 case OPC_DOTP_S_df:
18898 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18899 break;
18900 case OPC_DOTP_U_df:
18901 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18902 break;
18903 case OPC_DPADD_S_df:
18904 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18905 break;
18906 case OPC_DPADD_U_df:
18907 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18908 break;
18909 case OPC_DPSUB_S_df:
18910 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18911 break;
18912 case OPC_HADD_S_df:
18913 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18914 break;
18915 case OPC_DPSUB_U_df:
18916 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18917 break;
18918 case OPC_HADD_U_df:
18919 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18920 break;
18921 case OPC_HSUB_S_df:
18922 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18923 break;
18924 case OPC_HSUB_U_df:
18925 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18926 break;
18927 }
18928 break;
18929 default:
18930 MIPS_INVAL("MSA instruction");
18931 generate_exception_end(ctx, EXCP_RI);
18932 break;
18933 }
18934 tcg_temp_free_i32(twd);
18935 tcg_temp_free_i32(tws);
18936 tcg_temp_free_i32(twt);
18937 tcg_temp_free_i32(tdf);
18938 }
18939
18940 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18941 {
18942 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18943 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18944 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18945 TCGv telm = tcg_temp_new();
18946 TCGv_i32 tsr = tcg_const_i32(source);
18947 TCGv_i32 tdt = tcg_const_i32(dest);
18948
18949 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18950 case OPC_CTCMSA:
18951 gen_load_gpr(telm, source);
18952 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18953 break;
18954 case OPC_CFCMSA:
18955 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18956 gen_store_gpr(telm, dest);
18957 break;
18958 case OPC_MOVE_V:
18959 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18960 break;
18961 default:
18962 MIPS_INVAL("MSA instruction");
18963 generate_exception_end(ctx, EXCP_RI);
18964 break;
18965 }
18966
18967 tcg_temp_free(telm);
18968 tcg_temp_free_i32(tdt);
18969 tcg_temp_free_i32(tsr);
18970 }
18971
18972 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18973 uint32_t n)
18974 {
18975 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18976 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18977 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18978
18979 TCGv_i32 tws = tcg_const_i32(ws);
18980 TCGv_i32 twd = tcg_const_i32(wd);
18981 TCGv_i32 tn = tcg_const_i32(n);
18982 TCGv_i32 tdf = tcg_const_i32(df);
18983
18984 switch (MASK_MSA_ELM(ctx->opcode)) {
18985 case OPC_SLDI_df:
18986 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18987 break;
18988 case OPC_SPLATI_df:
18989 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18990 break;
18991 case OPC_INSVE_df:
18992 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18993 break;
18994 case OPC_COPY_S_df:
18995 case OPC_COPY_U_df:
18996 case OPC_INSERT_df:
18997 #if !defined(TARGET_MIPS64)
18998 /* Double format valid only for MIPS64 */
18999 if (df == DF_DOUBLE) {
19000 generate_exception_end(ctx, EXCP_RI);
19001 break;
19002 }
19003 #endif
19004 switch (MASK_MSA_ELM(ctx->opcode)) {
19005 case OPC_COPY_S_df:
19006 if (likely(wd != 0)) {
19007 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
19008 }
19009 break;
19010 case OPC_COPY_U_df:
19011 if (likely(wd != 0)) {
19012 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
19013 }
19014 break;
19015 case OPC_INSERT_df:
19016 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
19017 break;
19018 }
19019 break;
19020 default:
19021 MIPS_INVAL("MSA instruction");
19022 generate_exception_end(ctx, EXCP_RI);
19023 }
19024 tcg_temp_free_i32(twd);
19025 tcg_temp_free_i32(tws);
19026 tcg_temp_free_i32(tn);
19027 tcg_temp_free_i32(tdf);
19028 }
19029
19030 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
19031 {
19032 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
19033 uint32_t df = 0, n = 0;
19034
19035 if ((dfn & 0x30) == 0x00) {
19036 n = dfn & 0x0f;
19037 df = DF_BYTE;
19038 } else if ((dfn & 0x38) == 0x20) {
19039 n = dfn & 0x07;
19040 df = DF_HALF;
19041 } else if ((dfn & 0x3c) == 0x30) {
19042 n = dfn & 0x03;
19043 df = DF_WORD;
19044 } else if ((dfn & 0x3e) == 0x38) {
19045 n = dfn & 0x01;
19046 df = DF_DOUBLE;
19047 } else if (dfn == 0x3E) {
19048 /* CTCMSA, CFCMSA, MOVE.V */
19049 gen_msa_elm_3e(env, ctx);
19050 return;
19051 } else {
19052 generate_exception_end(ctx, EXCP_RI);
19053 return;
19054 }
19055
19056 gen_msa_elm_df(env, ctx, df, n);
19057 }
19058
19059 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
19060 {
19061 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19062 uint8_t df = (ctx->opcode >> 21) & 0x1;
19063 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19064 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19065 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19066
19067 TCGv_i32 twd = tcg_const_i32(wd);
19068 TCGv_i32 tws = tcg_const_i32(ws);
19069 TCGv_i32 twt = tcg_const_i32(wt);
19070 TCGv_i32 tdf = tcg_temp_new_i32();
19071
19072 /* adjust df value for floating-point instruction */
19073 tcg_gen_movi_i32(tdf, df + 2);
19074
19075 switch (MASK_MSA_3RF(ctx->opcode)) {
19076 case OPC_FCAF_df:
19077 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
19078 break;
19079 case OPC_FADD_df:
19080 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
19081 break;
19082 case OPC_FCUN_df:
19083 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
19084 break;
19085 case OPC_FSUB_df:
19086 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
19087 break;
19088 case OPC_FCOR_df:
19089 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
19090 break;
19091 case OPC_FCEQ_df:
19092 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
19093 break;
19094 case OPC_FMUL_df:
19095 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
19096 break;
19097 case OPC_FCUNE_df:
19098 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
19099 break;
19100 case OPC_FCUEQ_df:
19101 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
19102 break;
19103 case OPC_FDIV_df:
19104 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
19105 break;
19106 case OPC_FCNE_df:
19107 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
19108 break;
19109 case OPC_FCLT_df:
19110 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
19111 break;
19112 case OPC_FMADD_df:
19113 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
19114 break;
19115 case OPC_MUL_Q_df:
19116 tcg_gen_movi_i32(tdf, df + 1);
19117 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
19118 break;
19119 case OPC_FCULT_df:
19120 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
19121 break;
19122 case OPC_FMSUB_df:
19123 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
19124 break;
19125 case OPC_MADD_Q_df:
19126 tcg_gen_movi_i32(tdf, df + 1);
19127 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
19128 break;
19129 case OPC_FCLE_df:
19130 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
19131 break;
19132 case OPC_MSUB_Q_df:
19133 tcg_gen_movi_i32(tdf, df + 1);
19134 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
19135 break;
19136 case OPC_FCULE_df:
19137 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
19138 break;
19139 case OPC_FEXP2_df:
19140 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
19141 break;
19142 case OPC_FSAF_df:
19143 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
19144 break;
19145 case OPC_FEXDO_df:
19146 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
19147 break;
19148 case OPC_FSUN_df:
19149 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
19150 break;
19151 case OPC_FSOR_df:
19152 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
19153 break;
19154 case OPC_FSEQ_df:
19155 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
19156 break;
19157 case OPC_FTQ_df:
19158 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
19159 break;
19160 case OPC_FSUNE_df:
19161 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
19162 break;
19163 case OPC_FSUEQ_df:
19164 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
19165 break;
19166 case OPC_FSNE_df:
19167 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
19168 break;
19169 case OPC_FSLT_df:
19170 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
19171 break;
19172 case OPC_FMIN_df:
19173 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
19174 break;
19175 case OPC_MULR_Q_df:
19176 tcg_gen_movi_i32(tdf, df + 1);
19177 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
19178 break;
19179 case OPC_FSULT_df:
19180 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
19181 break;
19182 case OPC_FMIN_A_df:
19183 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
19184 break;
19185 case OPC_MADDR_Q_df:
19186 tcg_gen_movi_i32(tdf, df + 1);
19187 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
19188 break;
19189 case OPC_FSLE_df:
19190 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
19191 break;
19192 case OPC_FMAX_df:
19193 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
19194 break;
19195 case OPC_MSUBR_Q_df:
19196 tcg_gen_movi_i32(tdf, df + 1);
19197 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
19198 break;
19199 case OPC_FSULE_df:
19200 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
19201 break;
19202 case OPC_FMAX_A_df:
19203 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
19204 break;
19205 default:
19206 MIPS_INVAL("MSA instruction");
19207 generate_exception_end(ctx, EXCP_RI);
19208 break;
19209 }
19210
19211 tcg_temp_free_i32(twd);
19212 tcg_temp_free_i32(tws);
19213 tcg_temp_free_i32(twt);
19214 tcg_temp_free_i32(tdf);
19215 }
19216
19217 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
19218 {
19219 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19220 (op & (0x7 << 18)))
19221 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19222 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19223 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19224 uint8_t df = (ctx->opcode >> 16) & 0x3;
19225 TCGv_i32 twd = tcg_const_i32(wd);
19226 TCGv_i32 tws = tcg_const_i32(ws);
19227 TCGv_i32 twt = tcg_const_i32(wt);
19228 TCGv_i32 tdf = tcg_const_i32(df);
19229
19230 switch (MASK_MSA_2R(ctx->opcode)) {
19231 case OPC_FILL_df:
19232 #if !defined(TARGET_MIPS64)
19233 /* Double format valid only for MIPS64 */
19234 if (df == DF_DOUBLE) {
19235 generate_exception_end(ctx, EXCP_RI);
19236 break;
19237 }
19238 #endif
19239 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
19240 break;
19241 case OPC_PCNT_df:
19242 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
19243 break;
19244 case OPC_NLOC_df:
19245 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
19246 break;
19247 case OPC_NLZC_df:
19248 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
19249 break;
19250 default:
19251 MIPS_INVAL("MSA instruction");
19252 generate_exception_end(ctx, EXCP_RI);
19253 break;
19254 }
19255
19256 tcg_temp_free_i32(twd);
19257 tcg_temp_free_i32(tws);
19258 tcg_temp_free_i32(twt);
19259 tcg_temp_free_i32(tdf);
19260 }
19261
19262 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
19263 {
19264 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19265 (op & (0xf << 17)))
19266 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19267 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19268 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19269 uint8_t df = (ctx->opcode >> 16) & 0x1;
19270 TCGv_i32 twd = tcg_const_i32(wd);
19271 TCGv_i32 tws = tcg_const_i32(ws);
19272 TCGv_i32 twt = tcg_const_i32(wt);
19273 /* adjust df value for floating-point instruction */
19274 TCGv_i32 tdf = tcg_const_i32(df + 2);
19275
19276 switch (MASK_MSA_2RF(ctx->opcode)) {
19277 case OPC_FCLASS_df:
19278 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
19279 break;
19280 case OPC_FTRUNC_S_df:
19281 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
19282 break;
19283 case OPC_FTRUNC_U_df:
19284 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
19285 break;
19286 case OPC_FSQRT_df:
19287 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
19288 break;
19289 case OPC_FRSQRT_df:
19290 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
19291 break;
19292 case OPC_FRCP_df:
19293 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19294 break;
19295 case OPC_FRINT_df:
19296 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19297 break;
19298 case OPC_FLOG2_df:
19299 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19300 break;
19301 case OPC_FEXUPL_df:
19302 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19303 break;
19304 case OPC_FEXUPR_df:
19305 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19306 break;
19307 case OPC_FFQL_df:
19308 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19309 break;
19310 case OPC_FFQR_df:
19311 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19312 break;
19313 case OPC_FTINT_S_df:
19314 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19315 break;
19316 case OPC_FTINT_U_df:
19317 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19318 break;
19319 case OPC_FFINT_S_df:
19320 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19321 break;
19322 case OPC_FFINT_U_df:
19323 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19324 break;
19325 }
19326
19327 tcg_temp_free_i32(twd);
19328 tcg_temp_free_i32(tws);
19329 tcg_temp_free_i32(twt);
19330 tcg_temp_free_i32(tdf);
19331 }
19332
19333 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19334 {
19335 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19336 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19337 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19338 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19339 TCGv_i32 twd = tcg_const_i32(wd);
19340 TCGv_i32 tws = tcg_const_i32(ws);
19341 TCGv_i32 twt = tcg_const_i32(wt);
19342
19343 switch (MASK_MSA_VEC(ctx->opcode)) {
19344 case OPC_AND_V:
19345 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19346 break;
19347 case OPC_OR_V:
19348 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19349 break;
19350 case OPC_NOR_V:
19351 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19352 break;
19353 case OPC_XOR_V:
19354 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19355 break;
19356 case OPC_BMNZ_V:
19357 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19358 break;
19359 case OPC_BMZ_V:
19360 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19361 break;
19362 case OPC_BSEL_V:
19363 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19364 break;
19365 default:
19366 MIPS_INVAL("MSA instruction");
19367 generate_exception_end(ctx, EXCP_RI);
19368 break;
19369 }
19370
19371 tcg_temp_free_i32(twd);
19372 tcg_temp_free_i32(tws);
19373 tcg_temp_free_i32(twt);
19374 }
19375
19376 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19377 {
19378 switch (MASK_MSA_VEC(ctx->opcode)) {
19379 case OPC_AND_V:
19380 case OPC_OR_V:
19381 case OPC_NOR_V:
19382 case OPC_XOR_V:
19383 case OPC_BMNZ_V:
19384 case OPC_BMZ_V:
19385 case OPC_BSEL_V:
19386 gen_msa_vec_v(env, ctx);
19387 break;
19388 case OPC_MSA_2R:
19389 gen_msa_2r(env, ctx);
19390 break;
19391 case OPC_MSA_2RF:
19392 gen_msa_2rf(env, ctx);
19393 break;
19394 default:
19395 MIPS_INVAL("MSA instruction");
19396 generate_exception_end(ctx, EXCP_RI);
19397 break;
19398 }
19399 }
19400
19401 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19402 {
19403 uint32_t opcode = ctx->opcode;
19404 check_insn(ctx, ASE_MSA);
19405 check_msa_access(ctx);
19406
19407 switch (MASK_MSA_MINOR(opcode)) {
19408 case OPC_MSA_I8_00:
19409 case OPC_MSA_I8_01:
19410 case OPC_MSA_I8_02:
19411 gen_msa_i8(env, ctx);
19412 break;
19413 case OPC_MSA_I5_06:
19414 case OPC_MSA_I5_07:
19415 gen_msa_i5(env, ctx);
19416 break;
19417 case OPC_MSA_BIT_09:
19418 case OPC_MSA_BIT_0A:
19419 gen_msa_bit(env, ctx);
19420 break;
19421 case OPC_MSA_3R_0D:
19422 case OPC_MSA_3R_0E:
19423 case OPC_MSA_3R_0F:
19424 case OPC_MSA_3R_10:
19425 case OPC_MSA_3R_11:
19426 case OPC_MSA_3R_12:
19427 case OPC_MSA_3R_13:
19428 case OPC_MSA_3R_14:
19429 case OPC_MSA_3R_15:
19430 gen_msa_3r(env, ctx);
19431 break;
19432 case OPC_MSA_ELM:
19433 gen_msa_elm(env, ctx);
19434 break;
19435 case OPC_MSA_3RF_1A:
19436 case OPC_MSA_3RF_1B:
19437 case OPC_MSA_3RF_1C:
19438 gen_msa_3rf(env, ctx);
19439 break;
19440 case OPC_MSA_VEC:
19441 gen_msa_vec(env, ctx);
19442 break;
19443 case OPC_LD_B:
19444 case OPC_LD_H:
19445 case OPC_LD_W:
19446 case OPC_LD_D:
19447 case OPC_ST_B:
19448 case OPC_ST_H:
19449 case OPC_ST_W:
19450 case OPC_ST_D:
19451 {
19452 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19453 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19454 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19455 uint8_t df = (ctx->opcode >> 0) & 0x3;
19456
19457 TCGv_i32 twd = tcg_const_i32(wd);
19458 TCGv taddr = tcg_temp_new();
19459 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
19460
19461 switch (MASK_MSA_MINOR(opcode)) {
19462 case OPC_LD_B:
19463 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19464 break;
19465 case OPC_LD_H:
19466 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19467 break;
19468 case OPC_LD_W:
19469 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19470 break;
19471 case OPC_LD_D:
19472 gen_helper_msa_ld_d(cpu_env, twd, taddr);
19473 break;
19474 case OPC_ST_B:
19475 gen_helper_msa_st_b(cpu_env, twd, taddr);
19476 break;
19477 case OPC_ST_H:
19478 gen_helper_msa_st_h(cpu_env, twd, taddr);
19479 break;
19480 case OPC_ST_W:
19481 gen_helper_msa_st_w(cpu_env, twd, taddr);
19482 break;
19483 case OPC_ST_D:
19484 gen_helper_msa_st_d(cpu_env, twd, taddr);
19485 break;
19486 }
19487
19488 tcg_temp_free_i32(twd);
19489 tcg_temp_free(taddr);
19490 }
19491 break;
19492 default:
19493 MIPS_INVAL("MSA instruction");
19494 generate_exception_end(ctx, EXCP_RI);
19495 break;
19496 }
19497
19498 }
19499
19500 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
19501 {
19502 int32_t offset;
19503 int rs, rt, rd, sa;
19504 uint32_t op, op1;
19505 int16_t imm;
19506
19507 /* make sure instructions are on a word boundary */
19508 if (ctx->pc & 0x3) {
19509 env->CP0_BadVAddr = ctx->pc;
19510 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
19511 return;
19512 }
19513
19514 /* Handle blikely not taken case */
19515 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
19516 TCGLabel *l1 = gen_new_label();
19517
19518 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19519 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19520 gen_goto_tb(ctx, 1, ctx->pc + 4);
19521 gen_set_label(l1);
19522 }
19523
19524 op = MASK_OP_MAJOR(ctx->opcode);
19525 rs = (ctx->opcode >> 21) & 0x1f;
19526 rt = (ctx->opcode >> 16) & 0x1f;
19527 rd = (ctx->opcode >> 11) & 0x1f;
19528 sa = (ctx->opcode >> 6) & 0x1f;
19529 imm = (int16_t)ctx->opcode;
19530 switch (op) {
19531 case OPC_SPECIAL:
19532 decode_opc_special(env, ctx);
19533 break;
19534 case OPC_SPECIAL2:
19535 decode_opc_special2_legacy(env, ctx);
19536 break;
19537 case OPC_SPECIAL3:
19538 decode_opc_special3(env, ctx);
19539 break;
19540 case OPC_REGIMM:
19541 op1 = MASK_REGIMM(ctx->opcode);
19542 switch (op1) {
19543 case OPC_BLTZL: /* REGIMM branches */
19544 case OPC_BGEZL:
19545 case OPC_BLTZALL:
19546 case OPC_BGEZALL:
19547 check_insn(ctx, ISA_MIPS2);
19548 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19549 /* Fallthrough */
19550 case OPC_BLTZ:
19551 case OPC_BGEZ:
19552 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19553 break;
19554 case OPC_BLTZAL:
19555 case OPC_BGEZAL:
19556 if (ctx->insn_flags & ISA_MIPS32R6) {
19557 if (rs == 0) {
19558 /* OPC_NAL, OPC_BAL */
19559 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
19560 } else {
19561 generate_exception_end(ctx, EXCP_RI);
19562 }
19563 } else {
19564 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19565 }
19566 break;
19567 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19568 case OPC_TNEI:
19569 check_insn(ctx, ISA_MIPS2);
19570 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19571 gen_trap(ctx, op1, rs, -1, imm);
19572 break;
19573 case OPC_SIGRIE:
19574 check_insn(ctx, ISA_MIPS32R6);
19575 generate_exception_end(ctx, EXCP_RI);
19576 break;
19577 case OPC_SYNCI:
19578 check_insn(ctx, ISA_MIPS32R2);
19579 /* Break the TB to be able to sync copied instructions
19580 immediately */
19581 ctx->bstate = BS_STOP;
19582 break;
19583 case OPC_BPOSGE32: /* MIPS DSP branch */
19584 #if defined(TARGET_MIPS64)
19585 case OPC_BPOSGE64:
19586 #endif
19587 check_dsp(ctx);
19588 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
19589 break;
19590 #if defined(TARGET_MIPS64)
19591 case OPC_DAHI:
19592 check_insn(ctx, ISA_MIPS32R6);
19593 check_mips_64(ctx);
19594 if (rs != 0) {
19595 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19596 }
19597 break;
19598 case OPC_DATI:
19599 check_insn(ctx, ISA_MIPS32R6);
19600 check_mips_64(ctx);
19601 if (rs != 0) {
19602 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19603 }
19604 break;
19605 #endif
19606 default: /* Invalid */
19607 MIPS_INVAL("regimm");
19608 generate_exception_end(ctx, EXCP_RI);
19609 break;
19610 }
19611 break;
19612 case OPC_CP0:
19613 check_cp0_enabled(ctx);
19614 op1 = MASK_CP0(ctx->opcode);
19615 switch (op1) {
19616 case OPC_MFC0:
19617 case OPC_MTC0:
19618 case OPC_MFTR:
19619 case OPC_MTTR:
19620 case OPC_MFHC0:
19621 case OPC_MTHC0:
19622 #if defined(TARGET_MIPS64)
19623 case OPC_DMFC0:
19624 case OPC_DMTC0:
19625 #endif
19626 #ifndef CONFIG_USER_ONLY
19627 gen_cp0(env, ctx, op1, rt, rd);
19628 #endif /* !CONFIG_USER_ONLY */
19629 break;
19630 case OPC_C0_FIRST ... OPC_C0_LAST:
19631 #ifndef CONFIG_USER_ONLY
19632 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19633 #endif /* !CONFIG_USER_ONLY */
19634 break;
19635 case OPC_MFMC0:
19636 #ifndef CONFIG_USER_ONLY
19637 {
19638 uint32_t op2;
19639 TCGv t0 = tcg_temp_new();
19640
19641 op2 = MASK_MFMC0(ctx->opcode);
19642 switch (op2) {
19643 case OPC_DMT:
19644 check_insn(ctx, ASE_MT);
19645 gen_helper_dmt(t0);
19646 gen_store_gpr(t0, rt);
19647 break;
19648 case OPC_EMT:
19649 check_insn(ctx, ASE_MT);
19650 gen_helper_emt(t0);
19651 gen_store_gpr(t0, rt);
19652 break;
19653 case OPC_DVPE:
19654 check_insn(ctx, ASE_MT);
19655 gen_helper_dvpe(t0, cpu_env);
19656 gen_store_gpr(t0, rt);
19657 break;
19658 case OPC_EVPE:
19659 check_insn(ctx, ASE_MT);
19660 gen_helper_evpe(t0, cpu_env);
19661 gen_store_gpr(t0, rt);
19662 break;
19663 case OPC_DVP:
19664 check_insn(ctx, ISA_MIPS32R6);
19665 if (ctx->vp) {
19666 gen_helper_dvp(t0, cpu_env);
19667 gen_store_gpr(t0, rt);
19668 }
19669 break;
19670 case OPC_EVP:
19671 check_insn(ctx, ISA_MIPS32R6);
19672 if (ctx->vp) {
19673 gen_helper_evp(t0, cpu_env);
19674 gen_store_gpr(t0, rt);
19675 }
19676 break;
19677 case OPC_DI:
19678 check_insn(ctx, ISA_MIPS32R2);
19679 save_cpu_state(ctx, 1);
19680 gen_helper_di(t0, cpu_env);
19681 gen_store_gpr(t0, rt);
19682 /* Stop translation as we may have switched
19683 the execution mode. */
19684 ctx->bstate = BS_STOP;
19685 break;
19686 case OPC_EI:
19687 check_insn(ctx, ISA_MIPS32R2);
19688 save_cpu_state(ctx, 1);
19689 gen_helper_ei(t0, cpu_env);
19690 gen_store_gpr(t0, rt);
19691 /* Stop translation as we may have switched
19692 the execution mode. */
19693 ctx->bstate = BS_STOP;
19694 break;
19695 default: /* Invalid */
19696 MIPS_INVAL("mfmc0");
19697 generate_exception_end(ctx, EXCP_RI);
19698 break;
19699 }
19700 tcg_temp_free(t0);
19701 }
19702 #endif /* !CONFIG_USER_ONLY */
19703 break;
19704 case OPC_RDPGPR:
19705 check_insn(ctx, ISA_MIPS32R2);
19706 gen_load_srsgpr(rt, rd);
19707 break;
19708 case OPC_WRPGPR:
19709 check_insn(ctx, ISA_MIPS32R2);
19710 gen_store_srsgpr(rt, rd);
19711 break;
19712 default:
19713 MIPS_INVAL("cp0");
19714 generate_exception_end(ctx, EXCP_RI);
19715 break;
19716 }
19717 break;
19718 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19719 if (ctx->insn_flags & ISA_MIPS32R6) {
19720 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19721 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19722 } else {
19723 /* OPC_ADDI */
19724 /* Arithmetic with immediate opcode */
19725 gen_arith_imm(ctx, op, rt, rs, imm);
19726 }
19727 break;
19728 case OPC_ADDIU:
19729 gen_arith_imm(ctx, op, rt, rs, imm);
19730 break;
19731 case OPC_SLTI: /* Set on less than with immediate opcode */
19732 case OPC_SLTIU:
19733 gen_slt_imm(ctx, op, rt, rs, imm);
19734 break;
19735 case OPC_ANDI: /* Arithmetic with immediate opcode */
19736 case OPC_LUI: /* OPC_AUI */
19737 case OPC_ORI:
19738 case OPC_XORI:
19739 gen_logic_imm(ctx, op, rt, rs, imm);
19740 break;
19741 case OPC_J ... OPC_JAL: /* Jump */
19742 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19743 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19744 break;
19745 /* Branch */
19746 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19747 if (ctx->insn_flags & ISA_MIPS32R6) {
19748 if (rt == 0) {
19749 generate_exception_end(ctx, EXCP_RI);
19750 break;
19751 }
19752 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19753 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19754 } else {
19755 /* OPC_BLEZL */
19756 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19757 }
19758 break;
19759 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19760 if (ctx->insn_flags & ISA_MIPS32R6) {
19761 if (rt == 0) {
19762 generate_exception_end(ctx, EXCP_RI);
19763 break;
19764 }
19765 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19766 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19767 } else {
19768 /* OPC_BGTZL */
19769 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19770 }
19771 break;
19772 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19773 if (rt == 0) {
19774 /* OPC_BLEZ */
19775 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19776 } else {
19777 check_insn(ctx, ISA_MIPS32R6);
19778 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19779 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19780 }
19781 break;
19782 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19783 if (rt == 0) {
19784 /* OPC_BGTZ */
19785 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19786 } else {
19787 check_insn(ctx, ISA_MIPS32R6);
19788 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19789 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19790 }
19791 break;
19792 case OPC_BEQL:
19793 case OPC_BNEL:
19794 check_insn(ctx, ISA_MIPS2);
19795 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19796 /* Fallthrough */
19797 case OPC_BEQ:
19798 case OPC_BNE:
19799 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19800 break;
19801 case OPC_LL: /* Load and stores */
19802 check_insn(ctx, ISA_MIPS2);
19803 /* Fallthrough */
19804 case OPC_LWL:
19805 case OPC_LWR:
19806 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19807 /* Fallthrough */
19808 case OPC_LB ... OPC_LH:
19809 case OPC_LW ... OPC_LHU:
19810 gen_ld(ctx, op, rt, rs, imm);
19811 break;
19812 case OPC_SWL:
19813 case OPC_SWR:
19814 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19815 /* fall through */
19816 case OPC_SB ... OPC_SH:
19817 case OPC_SW:
19818 gen_st(ctx, op, rt, rs, imm);
19819 break;
19820 case OPC_SC:
19821 check_insn(ctx, ISA_MIPS2);
19822 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19823 gen_st_cond(ctx, op, rt, rs, imm);
19824 break;
19825 case OPC_CACHE:
19826 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19827 check_cp0_enabled(ctx);
19828 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19829 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19830 gen_cache_operation(ctx, rt, rs, imm);
19831 }
19832 /* Treat as NOP. */
19833 break;
19834 case OPC_PREF:
19835 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19836 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19837 /* Treat as NOP. */
19838 break;
19839
19840 /* Floating point (COP1). */
19841 case OPC_LWC1:
19842 case OPC_LDC1:
19843 case OPC_SWC1:
19844 case OPC_SDC1:
19845 gen_cop1_ldst(ctx, op, rt, rs, imm);
19846 break;
19847
19848 case OPC_CP1:
19849 op1 = MASK_CP1(ctx->opcode);
19850
19851 switch (op1) {
19852 case OPC_MFHC1:
19853 case OPC_MTHC1:
19854 check_cp1_enabled(ctx);
19855 check_insn(ctx, ISA_MIPS32R2);
19856 case OPC_MFC1:
19857 case OPC_CFC1:
19858 case OPC_MTC1:
19859 case OPC_CTC1:
19860 check_cp1_enabled(ctx);
19861 gen_cp1(ctx, op1, rt, rd);
19862 break;
19863 #if defined(TARGET_MIPS64)
19864 case OPC_DMFC1:
19865 case OPC_DMTC1:
19866 check_cp1_enabled(ctx);
19867 check_insn(ctx, ISA_MIPS3);
19868 check_mips_64(ctx);
19869 gen_cp1(ctx, op1, rt, rd);
19870 break;
19871 #endif
19872 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19873 check_cp1_enabled(ctx);
19874 if (ctx->insn_flags & ISA_MIPS32R6) {
19875 /* OPC_BC1EQZ */
19876 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19877 rt, imm << 2, 4);
19878 } else {
19879 /* OPC_BC1ANY2 */
19880 check_cop1x(ctx);
19881 check_insn(ctx, ASE_MIPS3D);
19882 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19883 (rt >> 2) & 0x7, imm << 2);
19884 }
19885 break;
19886 case OPC_BC1NEZ:
19887 check_cp1_enabled(ctx);
19888 check_insn(ctx, ISA_MIPS32R6);
19889 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19890 rt, imm << 2, 4);
19891 break;
19892 case OPC_BC1ANY4:
19893 check_cp1_enabled(ctx);
19894 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19895 check_cop1x(ctx);
19896 check_insn(ctx, ASE_MIPS3D);
19897 /* fall through */
19898 case OPC_BC1:
19899 check_cp1_enabled(ctx);
19900 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19901 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19902 (rt >> 2) & 0x7, imm << 2);
19903 break;
19904 case OPC_PS_FMT:
19905 check_ps(ctx);
19906 /* fall through */
19907 case OPC_S_FMT:
19908 case OPC_D_FMT:
19909 check_cp1_enabled(ctx);
19910 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19911 (imm >> 8) & 0x7);
19912 break;
19913 case OPC_W_FMT:
19914 case OPC_L_FMT:
19915 {
19916 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19917 check_cp1_enabled(ctx);
19918 if (ctx->insn_flags & ISA_MIPS32R6) {
19919 switch (r6_op) {
19920 case R6_OPC_CMP_AF_S:
19921 case R6_OPC_CMP_UN_S:
19922 case R6_OPC_CMP_EQ_S:
19923 case R6_OPC_CMP_UEQ_S:
19924 case R6_OPC_CMP_LT_S:
19925 case R6_OPC_CMP_ULT_S:
19926 case R6_OPC_CMP_LE_S:
19927 case R6_OPC_CMP_ULE_S:
19928 case R6_OPC_CMP_SAF_S:
19929 case R6_OPC_CMP_SUN_S:
19930 case R6_OPC_CMP_SEQ_S:
19931 case R6_OPC_CMP_SEUQ_S:
19932 case R6_OPC_CMP_SLT_S:
19933 case R6_OPC_CMP_SULT_S:
19934 case R6_OPC_CMP_SLE_S:
19935 case R6_OPC_CMP_SULE_S:
19936 case R6_OPC_CMP_OR_S:
19937 case R6_OPC_CMP_UNE_S:
19938 case R6_OPC_CMP_NE_S:
19939 case R6_OPC_CMP_SOR_S:
19940 case R6_OPC_CMP_SUNE_S:
19941 case R6_OPC_CMP_SNE_S:
19942 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19943 break;
19944 case R6_OPC_CMP_AF_D:
19945 case R6_OPC_CMP_UN_D:
19946 case R6_OPC_CMP_EQ_D:
19947 case R6_OPC_CMP_UEQ_D:
19948 case R6_OPC_CMP_LT_D:
19949 case R6_OPC_CMP_ULT_D:
19950 case R6_OPC_CMP_LE_D:
19951 case R6_OPC_CMP_ULE_D:
19952 case R6_OPC_CMP_SAF_D:
19953 case R6_OPC_CMP_SUN_D:
19954 case R6_OPC_CMP_SEQ_D:
19955 case R6_OPC_CMP_SEUQ_D:
19956 case R6_OPC_CMP_SLT_D:
19957 case R6_OPC_CMP_SULT_D:
19958 case R6_OPC_CMP_SLE_D:
19959 case R6_OPC_CMP_SULE_D:
19960 case R6_OPC_CMP_OR_D:
19961 case R6_OPC_CMP_UNE_D:
19962 case R6_OPC_CMP_NE_D:
19963 case R6_OPC_CMP_SOR_D:
19964 case R6_OPC_CMP_SUNE_D:
19965 case R6_OPC_CMP_SNE_D:
19966 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19967 break;
19968 default:
19969 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19970 rt, rd, sa, (imm >> 8) & 0x7);
19971
19972 break;
19973 }
19974 } else {
19975 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19976 (imm >> 8) & 0x7);
19977 }
19978 break;
19979 }
19980 case OPC_BZ_V:
19981 case OPC_BNZ_V:
19982 case OPC_BZ_B:
19983 case OPC_BZ_H:
19984 case OPC_BZ_W:
19985 case OPC_BZ_D:
19986 case OPC_BNZ_B:
19987 case OPC_BNZ_H:
19988 case OPC_BNZ_W:
19989 case OPC_BNZ_D:
19990 check_insn(ctx, ASE_MSA);
19991 gen_msa_branch(env, ctx, op1);
19992 break;
19993 default:
19994 MIPS_INVAL("cp1");
19995 generate_exception_end(ctx, EXCP_RI);
19996 break;
19997 }
19998 break;
19999
20000 /* Compact branches [R6] and COP2 [non-R6] */
20001 case OPC_BC: /* OPC_LWC2 */
20002 case OPC_BALC: /* OPC_SWC2 */
20003 if (ctx->insn_flags & ISA_MIPS32R6) {
20004 /* OPC_BC, OPC_BALC */
20005 gen_compute_compact_branch(ctx, op, 0, 0,
20006 sextract32(ctx->opcode << 2, 0, 28));
20007 } else {
20008 /* OPC_LWC2, OPC_SWC2 */
20009 /* COP2: Not implemented. */
20010 generate_exception_err(ctx, EXCP_CpU, 2);
20011 }
20012 break;
20013 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
20014 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
20015 if (ctx->insn_flags & ISA_MIPS32R6) {
20016 if (rs != 0) {
20017 /* OPC_BEQZC, OPC_BNEZC */
20018 gen_compute_compact_branch(ctx, op, rs, 0,
20019 sextract32(ctx->opcode << 2, 0, 23));
20020 } else {
20021 /* OPC_JIC, OPC_JIALC */
20022 gen_compute_compact_branch(ctx, op, 0, rt, imm);
20023 }
20024 } else {
20025 /* OPC_LWC2, OPC_SWC2 */
20026 /* COP2: Not implemented. */
20027 generate_exception_err(ctx, EXCP_CpU, 2);
20028 }
20029 break;
20030 case OPC_CP2:
20031 check_insn(ctx, INSN_LOONGSON2F);
20032 /* Note that these instructions use different fields. */
20033 gen_loongson_multimedia(ctx, sa, rd, rt);
20034 break;
20035
20036 case OPC_CP3:
20037 check_insn_opc_removed(ctx, ISA_MIPS32R6);
20038 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20039 check_cp1_enabled(ctx);
20040 op1 = MASK_CP3(ctx->opcode);
20041 switch (op1) {
20042 case OPC_LUXC1:
20043 case OPC_SUXC1:
20044 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20045 /* Fallthrough */
20046 case OPC_LWXC1:
20047 case OPC_LDXC1:
20048 case OPC_SWXC1:
20049 case OPC_SDXC1:
20050 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
20051 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
20052 break;
20053 case OPC_PREFX:
20054 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
20055 /* Treat as NOP. */
20056 break;
20057 case OPC_ALNV_PS:
20058 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20059 /* Fallthrough */
20060 case OPC_MADD_S:
20061 case OPC_MADD_D:
20062 case OPC_MADD_PS:
20063 case OPC_MSUB_S:
20064 case OPC_MSUB_D:
20065 case OPC_MSUB_PS:
20066 case OPC_NMADD_S:
20067 case OPC_NMADD_D:
20068 case OPC_NMADD_PS:
20069 case OPC_NMSUB_S:
20070 case OPC_NMSUB_D:
20071 case OPC_NMSUB_PS:
20072 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
20073 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
20074 break;
20075 default:
20076 MIPS_INVAL("cp3");
20077 generate_exception_end(ctx, EXCP_RI);
20078 break;
20079 }
20080 } else {
20081 generate_exception_err(ctx, EXCP_CpU, 1);
20082 }
20083 break;
20084
20085 #if defined(TARGET_MIPS64)
20086 /* MIPS64 opcodes */
20087 case OPC_LDL ... OPC_LDR:
20088 case OPC_LLD:
20089 check_insn_opc_removed(ctx, ISA_MIPS32R6);
20090 /* fall through */
20091 case OPC_LWU:
20092 case OPC_LD:
20093 check_insn(ctx, ISA_MIPS3);
20094 check_mips_64(ctx);
20095 gen_ld(ctx, op, rt, rs, imm);
20096 break;
20097 case OPC_SDL ... OPC_SDR:
20098 check_insn_opc_removed(ctx, ISA_MIPS32R6);
20099 /* fall through */
20100 case OPC_SD:
20101 check_insn(ctx, ISA_MIPS3);
20102 check_mips_64(ctx);
20103 gen_st(ctx, op, rt, rs, imm);
20104 break;
20105 case OPC_SCD:
20106 check_insn_opc_removed(ctx, ISA_MIPS32R6);
20107 check_insn(ctx, ISA_MIPS3);
20108 check_mips_64(ctx);
20109 gen_st_cond(ctx, op, rt, rs, imm);
20110 break;
20111 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
20112 if (ctx->insn_flags & ISA_MIPS32R6) {
20113 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
20114 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20115 } else {
20116 /* OPC_DADDI */
20117 check_insn(ctx, ISA_MIPS3);
20118 check_mips_64(ctx);
20119 gen_arith_imm(ctx, op, rt, rs, imm);
20120 }
20121 break;
20122 case OPC_DADDIU:
20123 check_insn(ctx, ISA_MIPS3);
20124 check_mips_64(ctx);
20125 gen_arith_imm(ctx, op, rt, rs, imm);
20126 break;
20127 #else
20128 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
20129 if (ctx->insn_flags & ISA_MIPS32R6) {
20130 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20131 } else {
20132 MIPS_INVAL("major opcode");
20133 generate_exception_end(ctx, EXCP_RI);
20134 }
20135 break;
20136 #endif
20137 case OPC_DAUI: /* OPC_JALX */
20138 if (ctx->insn_flags & ISA_MIPS32R6) {
20139 #if defined(TARGET_MIPS64)
20140 /* OPC_DAUI */
20141 check_mips_64(ctx);
20142 if (rs == 0) {
20143 generate_exception(ctx, EXCP_RI);
20144 } else if (rt != 0) {
20145 TCGv t0 = tcg_temp_new();
20146 gen_load_gpr(t0, rs);
20147 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
20148 tcg_temp_free(t0);
20149 }
20150 #else
20151 generate_exception_end(ctx, EXCP_RI);
20152 MIPS_INVAL("major opcode");
20153 #endif
20154 } else {
20155 /* OPC_JALX */
20156 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
20157 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
20158 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
20159 }
20160 break;
20161 case OPC_MSA: /* OPC_MDMX */
20162 /* MDMX: Not implemented. */
20163 gen_msa(env, ctx);
20164 break;
20165 case OPC_PCREL:
20166 check_insn(ctx, ISA_MIPS32R6);
20167 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
20168 break;
20169 default: /* Invalid */
20170 MIPS_INVAL("major opcode");
20171 generate_exception_end(ctx, EXCP_RI);
20172 break;
20173 }
20174 }
20175
20176 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
20177 {
20178 CPUMIPSState *env = cs->env_ptr;
20179 DisasContext ctx;
20180 target_ulong pc_start;
20181 target_ulong next_page_start;
20182 int num_insns;
20183 int max_insns;
20184 int insn_bytes;
20185 int is_slot;
20186
20187 pc_start = tb->pc;
20188 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
20189 ctx.pc = pc_start;
20190 ctx.saved_pc = -1;
20191 ctx.singlestep_enabled = cs->singlestep_enabled;
20192 ctx.insn_flags = env->insn_flags;
20193 ctx.CP0_Config1 = env->CP0_Config1;
20194 ctx.tb = tb;
20195 ctx.bstate = BS_NONE;
20196 ctx.btarget = 0;
20197 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
20198 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
20199 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
20200 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
20201 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
20202 ctx.PAMask = env->PAMask;
20203 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
20204 ctx.eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
20205 ctx.sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
20206 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
20207 ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
20208 /* Restore delay slot state from the tb context. */
20209 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
20210 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
20211 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
20212 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
20213 ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
20214 ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
20215 ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
20216 ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
20217 restore_cpu_state(env, &ctx);
20218 #ifdef CONFIG_USER_ONLY
20219 ctx.mem_idx = MIPS_HFLAG_UM;
20220 #else
20221 ctx.mem_idx = hflags_mmu_index(ctx.hflags);
20222 #endif
20223 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
20224 MO_UNALN : MO_ALIGN;
20225 num_insns = 0;
20226 max_insns = tb->cflags & CF_COUNT_MASK;
20227 if (max_insns == 0) {
20228 max_insns = CF_COUNT_MASK;
20229 }
20230 if (max_insns > TCG_MAX_INSNS) {
20231 max_insns = TCG_MAX_INSNS;
20232 }
20233
20234 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
20235 gen_tb_start(tb);
20236 while (ctx.bstate == BS_NONE) {
20237 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
20238 num_insns++;
20239
20240 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
20241 save_cpu_state(&ctx, 1);
20242 ctx.bstate = BS_BRANCH;
20243 gen_helper_raise_exception_debug(cpu_env);
20244 /* The address covered by the breakpoint must be included in
20245 [tb->pc, tb->pc + tb->size) in order to for it to be
20246 properly cleared -- thus we increment the PC here so that
20247 the logic setting tb->size below does the right thing. */
20248 ctx.pc += 4;
20249 goto done_generating;
20250 }
20251
20252 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
20253 gen_io_start();
20254 }
20255
20256 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
20257 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
20258 ctx.opcode = cpu_ldl_code(env, ctx.pc);
20259 insn_bytes = 4;
20260 decode_opc(env, &ctx);
20261 } else if (ctx.insn_flags & ASE_MICROMIPS) {
20262 ctx.opcode = cpu_lduw_code(env, ctx.pc);
20263 insn_bytes = decode_micromips_opc(env, &ctx);
20264 } else if (ctx.insn_flags & ASE_MIPS16) {
20265 ctx.opcode = cpu_lduw_code(env, ctx.pc);
20266 insn_bytes = decode_mips16_opc(env, &ctx);
20267 } else {
20268 generate_exception_end(&ctx, EXCP_RI);
20269 break;
20270 }
20271
20272 if (ctx.hflags & MIPS_HFLAG_BMASK) {
20273 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
20274 MIPS_HFLAG_FBNSLOT))) {
20275 /* force to generate branch as there is neither delay nor
20276 forbidden slot */
20277 is_slot = 1;
20278 }
20279 if ((ctx.hflags & MIPS_HFLAG_M16) &&
20280 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
20281 /* Force to generate branch as microMIPS R6 doesn't restrict
20282 branches in the forbidden slot. */
20283 is_slot = 1;
20284 }
20285 }
20286 if (is_slot) {
20287 gen_branch(&ctx, insn_bytes);
20288 }
20289 ctx.pc += insn_bytes;
20290
20291 /* Execute a branch and its delay slot as a single instruction.
20292 This is what GDB expects and is consistent with what the
20293 hardware does (e.g. if a delay slot instruction faults, the
20294 reported PC is the PC of the branch). */
20295 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
20296 break;
20297 }
20298
20299 if (ctx.pc >= next_page_start) {
20300 break;
20301 }
20302
20303 if (tcg_op_buf_full()) {
20304 break;
20305 }
20306
20307 if (num_insns >= max_insns)
20308 break;
20309
20310 if (singlestep)
20311 break;
20312 }
20313 if (tb->cflags & CF_LAST_IO) {
20314 gen_io_end();
20315 }
20316 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
20317 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
20318 gen_helper_raise_exception_debug(cpu_env);
20319 } else {
20320 switch (ctx.bstate) {
20321 case BS_STOP:
20322 gen_goto_tb(&ctx, 0, ctx.pc);
20323 break;
20324 case BS_NONE:
20325 save_cpu_state(&ctx, 0);
20326 gen_goto_tb(&ctx, 0, ctx.pc);
20327 break;
20328 case BS_EXCP:
20329 tcg_gen_exit_tb(0);
20330 break;
20331 case BS_BRANCH:
20332 default:
20333 break;
20334 }
20335 }
20336 done_generating:
20337 gen_tb_end(tb, num_insns);
20338
20339 tb->size = ctx.pc - pc_start;
20340 tb->icount = num_insns;
20341
20342 #ifdef DEBUG_DISAS
20343 LOG_DISAS("\n");
20344 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
20345 && qemu_log_in_addr_range(pc_start)) {
20346 qemu_log_lock();
20347 qemu_log("IN: %s\n", lookup_symbol(pc_start));
20348 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
20349 qemu_log("\n");
20350 qemu_log_unlock();
20351 }
20352 #endif
20353 }
20354
20355 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
20356 int flags)
20357 {
20358 int i;
20359 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
20360
20361 #define printfpr(fp) \
20362 do { \
20363 if (is_fpu64) \
20364 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20365 " fd:%13g fs:%13g psu: %13g\n", \
20366 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20367 (double)(fp)->fd, \
20368 (double)(fp)->fs[FP_ENDIAN_IDX], \
20369 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20370 else { \
20371 fpr_t tmp; \
20372 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20373 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20374 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20375 " fd:%13g fs:%13g psu:%13g\n", \
20376 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20377 (double)tmp.fd, \
20378 (double)tmp.fs[FP_ENDIAN_IDX], \
20379 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20380 } \
20381 } while(0)
20382
20383
20384 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20385 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
20386 get_float_exception_flags(&env->active_fpu.fp_status));
20387 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20388 fpu_fprintf(f, "%3s: ", fregnames[i]);
20389 printfpr(&env->active_fpu.fpr[i]);
20390 }
20391
20392 #undef printfpr
20393 }
20394
20395 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20396 int flags)
20397 {
20398 MIPSCPU *cpu = MIPS_CPU(cs);
20399 CPUMIPSState *env = &cpu->env;
20400 int i;
20401
20402 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20403 " LO=0x" TARGET_FMT_lx " ds %04x "
20404 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
20405 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20406 env->hflags, env->btarget, env->bcond);
20407 for (i = 0; i < 32; i++) {
20408 if ((i & 3) == 0)
20409 cpu_fprintf(f, "GPR%02d:", i);
20410 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
20411 if ((i & 3) == 3)
20412 cpu_fprintf(f, "\n");
20413 }
20414
20415 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
20416 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
20417 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20418 PRIx64 "\n",
20419 env->CP0_Config0, env->CP0_Config1, env->lladdr);
20420 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20421 env->CP0_Config2, env->CP0_Config3);
20422 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20423 env->CP0_Config4, env->CP0_Config5);
20424 if (env->hflags & MIPS_HFLAG_FPU)
20425 fpu_dump_state(env, f, cpu_fprintf, flags);
20426 }
20427
20428 void mips_tcg_init(void)
20429 {
20430 int i;
20431 static int inited;
20432
20433 /* Initialize various static tables. */
20434 if (inited)
20435 return;
20436
20437 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
20438 tcg_ctx.tcg_env = cpu_env;
20439
20440 TCGV_UNUSED(cpu_gpr[0]);
20441 for (i = 1; i < 32; i++)
20442 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
20443 offsetof(CPUMIPSState, active_tc.gpr[i]),
20444 regnames[i]);
20445
20446 for (i = 0; i < 32; i++) {
20447 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20448 msa_wr_d[i * 2] =
20449 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
20450 /* The scalar floating-point unit (FPU) registers are mapped on
20451 * the MSA vector registers. */
20452 fpu_f64[i] = msa_wr_d[i * 2];
20453 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20454 msa_wr_d[i * 2 + 1] =
20455 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
20456 }
20457
20458 cpu_PC = tcg_global_mem_new(cpu_env,
20459 offsetof(CPUMIPSState, active_tc.PC), "PC");
20460 for (i = 0; i < MIPS_DSP_ACC; i++) {
20461 cpu_HI[i] = tcg_global_mem_new(cpu_env,
20462 offsetof(CPUMIPSState, active_tc.HI[i]),
20463 regnames_HI[i]);
20464 cpu_LO[i] = tcg_global_mem_new(cpu_env,
20465 offsetof(CPUMIPSState, active_tc.LO[i]),
20466 regnames_LO[i]);
20467 }
20468 cpu_dspctrl = tcg_global_mem_new(cpu_env,
20469 offsetof(CPUMIPSState, active_tc.DSPControl),
20470 "DSPControl");
20471 bcond = tcg_global_mem_new(cpu_env,
20472 offsetof(CPUMIPSState, bcond), "bcond");
20473 btarget = tcg_global_mem_new(cpu_env,
20474 offsetof(CPUMIPSState, btarget), "btarget");
20475 hflags = tcg_global_mem_new_i32(cpu_env,
20476 offsetof(CPUMIPSState, hflags), "hflags");
20477
20478 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
20479 offsetof(CPUMIPSState, active_fpu.fcr0),
20480 "fcr0");
20481 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
20482 offsetof(CPUMIPSState, active_fpu.fcr31),
20483 "fcr31");
20484
20485 inited = 1;
20486 }
20487
20488 #include "translate_init.c"
20489
20490 MIPSCPU *cpu_mips_init(const char *cpu_model)
20491 {
20492 MIPSCPU *cpu;
20493 CPUMIPSState *env;
20494 const mips_def_t *def;
20495
20496 def = cpu_mips_find_by_name(cpu_model);
20497 if (!def)
20498 return NULL;
20499 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20500 env = &cpu->env;
20501 env->cpu_model = def;
20502 env->exception_base = (int32_t)0xBFC00000;
20503
20504 #ifndef CONFIG_USER_ONLY
20505 mmu_init(env, def);
20506 #endif
20507 fpu_init(env, def);
20508 mvp_init(env, def);
20509
20510 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20511
20512 return cpu;
20513 }
20514
20515 bool cpu_supports_cps_smp(const char *cpu_model)
20516 {
20517 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20518 if (!def) {
20519 return false;
20520 }
20521
20522 return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20523 }
20524
20525 bool cpu_supports_isa(const char *cpu_model, unsigned int isa)
20526 {
20527 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20528 if (!def) {
20529 return false;
20530 }
20531
20532 return (def->insn_flags & isa) != 0;
20533 }
20534
20535 void cpu_set_exception_base(int vp_index, target_ulong address)
20536 {
20537 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20538 vp->env.exception_base = address;
20539 }
20540
20541 void cpu_state_reset(CPUMIPSState *env)
20542 {
20543 MIPSCPU *cpu = mips_env_get_cpu(env);
20544 CPUState *cs = CPU(cpu);
20545
20546 /* Reset registers to their default values */
20547 env->CP0_PRid = env->cpu_model->CP0_PRid;
20548 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20549 #ifdef TARGET_WORDS_BIGENDIAN
20550 env->CP0_Config0 |= (1 << CP0C0_BE);
20551 #endif
20552 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20553 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20554 env->CP0_Config3 = env->cpu_model->CP0_Config3;
20555 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20556 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
20557 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20558 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
20559 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20560 env->CP0_Config7 = env->cpu_model->CP0_Config7;
20561 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20562 << env->cpu_model->CP0_LLAddr_shift;
20563 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
20564 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20565 env->CCRes = env->cpu_model->CCRes;
20566 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20567 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20568 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20569 env->current_tc = 0;
20570 env->SEGBITS = env->cpu_model->SEGBITS;
20571 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20572 #if defined(TARGET_MIPS64)
20573 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20574 env->SEGMask |= 3ULL << 62;
20575 }
20576 #endif
20577 env->PABITS = env->cpu_model->PABITS;
20578 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20579 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20580 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20581 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20582 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20583 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20584 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20585 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20586 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20587 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
20588 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20589 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
20590 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
20591 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
20592 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
20593 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
20594 env->msair = env->cpu_model->MSAIR;
20595 env->insn_flags = env->cpu_model->insn_flags;
20596
20597 #if defined(CONFIG_USER_ONLY)
20598 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
20599 # ifdef TARGET_MIPS64
20600 /* Enable 64-bit register mode. */
20601 env->CP0_Status |= (1 << CP0St_PX);
20602 # endif
20603 # ifdef TARGET_ABI_MIPSN64
20604 /* Enable 64-bit address mode. */
20605 env->CP0_Status |= (1 << CP0St_UX);
20606 # endif
20607 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20608 hardware registers. */
20609 env->CP0_HWREna |= 0x0000000F;
20610 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
20611 env->CP0_Status |= (1 << CP0St_CU1);
20612 }
20613 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20614 env->CP0_Status |= (1 << CP0St_MX);
20615 }
20616 # if defined(TARGET_MIPS64)
20617 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20618 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20619 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
20620 env->CP0_Status |= (1 << CP0St_FR);
20621 }
20622 # endif
20623 #else
20624 if (env->hflags & MIPS_HFLAG_BMASK) {
20625 /* If the exception was raised from a delay slot,
20626 come back to the jump. */
20627 env->CP0_ErrorEPC = (env->active_tc.PC
20628 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
20629 } else {
20630 env->CP0_ErrorEPC = env->active_tc.PC;
20631 }
20632 env->active_tc.PC = env->exception_base;
20633 env->CP0_Random = env->tlb->nb_tlb - 1;
20634 env->tlb->tlb_in_use = env->tlb->nb_tlb;
20635 env->CP0_Wired = 0;
20636 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
20637 env->CP0_EBase = (cs->cpu_index & 0x3FF);
20638 if (mips_um_ksegs_enabled()) {
20639 env->CP0_EBase |= 0x40000000;
20640 } else {
20641 env->CP0_EBase |= (int32_t)0x80000000;
20642 }
20643 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20644 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20645 }
20646 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20647 0x3ff : 0xff;
20648 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20649 /* vectored interrupts not implemented, timer on int 7,
20650 no performance counters. */
20651 env->CP0_IntCtl = 0xe0000000;
20652 {
20653 int i;
20654
20655 for (i = 0; i < 7; i++) {
20656 env->CP0_WatchLo[i] = 0;
20657 env->CP0_WatchHi[i] = 0x80000000;
20658 }
20659 env->CP0_WatchLo[7] = 0;
20660 env->CP0_WatchHi[7] = 0;
20661 }
20662 /* Count register increments in debug mode, EJTAG version 1 */
20663 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
20664
20665 cpu_mips_store_count(env, 1);
20666
20667 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20668 int i;
20669
20670 /* Only TC0 on VPE 0 starts as active. */
20671 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20672 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20673 env->tcs[i].CP0_TCHalt = 1;
20674 }
20675 env->active_tc.CP0_TCHalt = 1;
20676 cs->halted = 1;
20677
20678 if (cs->cpu_index == 0) {
20679 /* VPE0 starts up enabled. */
20680 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20681 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20682
20683 /* TC0 starts up unhalted. */
20684 cs->halted = 0;
20685 env->active_tc.CP0_TCHalt = 0;
20686 env->tcs[0].CP0_TCHalt = 0;
20687 /* With thread 0 active. */
20688 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20689 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20690 }
20691 }
20692
20693 /*
20694 * Configure default legacy segmentation control. We use this regardless of
20695 * whether segmentation control is presented to the guest.
20696 */
20697 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
20698 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
20699 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
20700 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
20701 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
20702 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20703 (2 << CP0SC_C);
20704 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
20705 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20706 (3 << CP0SC_C)) << 16;
20707 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
20708 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20709 (1 << CP0SC_EU) | (2 << CP0SC_C);
20710 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
20711 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20712 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
20713 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
20714 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
20715 #endif
20716 if ((env->insn_flags & ISA_MIPS32R6) &&
20717 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20718 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20719 env->CP0_Status |= (1 << CP0St_FR);
20720 }
20721
20722 /* MSA */
20723 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20724 msa_reset(env);
20725 }
20726
20727 compute_hflags(env);
20728 restore_fp_status(env);
20729 restore_pamask(env);
20730 cs->exception_index = EXCP_NONE;
20731
20732 if (semihosting_get_argc()) {
20733 /* UHI interface can be used to obtain argc and argv */
20734 env->active_tc.gpr[4] = -1;
20735 }
20736 }
20737
20738 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20739 target_ulong *data)
20740 {
20741 env->active_tc.PC = data[0];
20742 env->hflags &= ~MIPS_HFLAG_BMASK;
20743 env->hflags |= data[1];
20744 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20745 case MIPS_HFLAG_BR:
20746 break;
20747 case MIPS_HFLAG_BC:
20748 case MIPS_HFLAG_BL:
20749 case MIPS_HFLAG_B:
20750 env->btarget = data[2];
20751 break;
20752 }
20753 }