]> git.proxmox.com Git - mirror_qemu.git/blob - target/mips/translate.c
Merge remote-tracking branch 'remotes/vivier2/tags/trivial-branch-pull-request' into...
[mirror_qemu.git] / target / mips / translate.c
1 /*
2 * MIPS 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 "internal.h"
27 #include "disas/disas.h"
28 #include "exec/exec-all.h"
29 #include "tcg-op.h"
30 #include "exec/cpu_ldst.h"
31 #include "hw/mips/cpudevs.h"
32
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
35 #include "hw/semihosting/semihost.h"
36
37 #include "target/mips/trace.h"
38 #include "trace-tcg.h"
39 #include "exec/translator.h"
40 #include "exec/log.h"
41 #include "qemu/qemu-print.h"
42
43 #define MIPS_DEBUG_DISAS 0
44
45 /* MIPS major opcodes */
46 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
47
48 enum {
49 /* indirect opcode tables */
50 OPC_SPECIAL = (0x00 << 26),
51 OPC_REGIMM = (0x01 << 26),
52 OPC_CP0 = (0x10 << 26),
53 OPC_CP1 = (0x11 << 26),
54 OPC_CP2 = (0x12 << 26),
55 OPC_CP3 = (0x13 << 26),
56 OPC_SPECIAL2 = (0x1C << 26),
57 OPC_SPECIAL3 = (0x1F << 26),
58 /* arithmetic with immediate */
59 OPC_ADDI = (0x08 << 26),
60 OPC_ADDIU = (0x09 << 26),
61 OPC_SLTI = (0x0A << 26),
62 OPC_SLTIU = (0x0B << 26),
63 /* logic with immediate */
64 OPC_ANDI = (0x0C << 26),
65 OPC_ORI = (0x0D << 26),
66 OPC_XORI = (0x0E << 26),
67 OPC_LUI = (0x0F << 26),
68 /* arithmetic with immediate */
69 OPC_DADDI = (0x18 << 26),
70 OPC_DADDIU = (0x19 << 26),
71 /* Jump and branches */
72 OPC_J = (0x02 << 26),
73 OPC_JAL = (0x03 << 26),
74 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
75 OPC_BEQL = (0x14 << 26),
76 OPC_BNE = (0x05 << 26),
77 OPC_BNEL = (0x15 << 26),
78 OPC_BLEZ = (0x06 << 26),
79 OPC_BLEZL = (0x16 << 26),
80 OPC_BGTZ = (0x07 << 26),
81 OPC_BGTZL = (0x17 << 26),
82 OPC_JALX = (0x1D << 26),
83 OPC_DAUI = (0x1D << 26),
84 /* Load and stores */
85 OPC_LDL = (0x1A << 26),
86 OPC_LDR = (0x1B << 26),
87 OPC_LB = (0x20 << 26),
88 OPC_LH = (0x21 << 26),
89 OPC_LWL = (0x22 << 26),
90 OPC_LW = (0x23 << 26),
91 OPC_LWPC = OPC_LW | 0x5,
92 OPC_LBU = (0x24 << 26),
93 OPC_LHU = (0x25 << 26),
94 OPC_LWR = (0x26 << 26),
95 OPC_LWU = (0x27 << 26),
96 OPC_SB = (0x28 << 26),
97 OPC_SH = (0x29 << 26),
98 OPC_SWL = (0x2A << 26),
99 OPC_SW = (0x2B << 26),
100 OPC_SDL = (0x2C << 26),
101 OPC_SDR = (0x2D << 26),
102 OPC_SWR = (0x2E << 26),
103 OPC_LL = (0x30 << 26),
104 OPC_LLD = (0x34 << 26),
105 OPC_LD = (0x37 << 26),
106 OPC_LDPC = OPC_LD | 0x5,
107 OPC_SC = (0x38 << 26),
108 OPC_SCD = (0x3C << 26),
109 OPC_SD = (0x3F << 26),
110 /* Floating point load/store */
111 OPC_LWC1 = (0x31 << 26),
112 OPC_LWC2 = (0x32 << 26),
113 OPC_LDC1 = (0x35 << 26),
114 OPC_LDC2 = (0x36 << 26),
115 OPC_SWC1 = (0x39 << 26),
116 OPC_SWC2 = (0x3A << 26),
117 OPC_SDC1 = (0x3D << 26),
118 OPC_SDC2 = (0x3E << 26),
119 /* Compact Branches */
120 OPC_BLEZALC = (0x06 << 26),
121 OPC_BGEZALC = (0x06 << 26),
122 OPC_BGEUC = (0x06 << 26),
123 OPC_BGTZALC = (0x07 << 26),
124 OPC_BLTZALC = (0x07 << 26),
125 OPC_BLTUC = (0x07 << 26),
126 OPC_BOVC = (0x08 << 26),
127 OPC_BEQZALC = (0x08 << 26),
128 OPC_BEQC = (0x08 << 26),
129 OPC_BLEZC = (0x16 << 26),
130 OPC_BGEZC = (0x16 << 26),
131 OPC_BGEC = (0x16 << 26),
132 OPC_BGTZC = (0x17 << 26),
133 OPC_BLTZC = (0x17 << 26),
134 OPC_BLTC = (0x17 << 26),
135 OPC_BNVC = (0x18 << 26),
136 OPC_BNEZALC = (0x18 << 26),
137 OPC_BNEC = (0x18 << 26),
138 OPC_BC = (0x32 << 26),
139 OPC_BEQZC = (0x36 << 26),
140 OPC_JIC = (0x36 << 26),
141 OPC_BALC = (0x3A << 26),
142 OPC_BNEZC = (0x3E << 26),
143 OPC_JIALC = (0x3E << 26),
144 /* MDMX ASE specific */
145 OPC_MDMX = (0x1E << 26),
146 /* MSA ASE, same as MDMX */
147 OPC_MSA = OPC_MDMX,
148 /* Cache and prefetch */
149 OPC_CACHE = (0x2F << 26),
150 OPC_PREF = (0x33 << 26),
151 /* PC-relative address computation / loads */
152 OPC_PCREL = (0x3B << 26),
153 };
154
155 /* PC-relative address computation / loads */
156 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
157 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
158 enum {
159 /* Instructions determined by bits 19 and 20 */
160 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
161 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
162 OPC_LWUPC = OPC_PCREL | (2 << 19),
163
164 /* Instructions determined by bits 16 ... 20 */
165 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
166 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
167
168 /* Other */
169 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
170 };
171
172 /* MIPS special opcodes */
173 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
174
175 enum {
176 /* Shifts */
177 OPC_SLL = 0x00 | OPC_SPECIAL,
178 /* NOP is SLL r0, r0, 0 */
179 /* SSNOP is SLL r0, r0, 1 */
180 /* EHB is SLL r0, r0, 3 */
181 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
182 OPC_ROTR = OPC_SRL | (1 << 21),
183 OPC_SRA = 0x03 | OPC_SPECIAL,
184 OPC_SLLV = 0x04 | OPC_SPECIAL,
185 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
186 OPC_ROTRV = OPC_SRLV | (1 << 6),
187 OPC_SRAV = 0x07 | OPC_SPECIAL,
188 OPC_DSLLV = 0x14 | OPC_SPECIAL,
189 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
190 OPC_DROTRV = OPC_DSRLV | (1 << 6),
191 OPC_DSRAV = 0x17 | OPC_SPECIAL,
192 OPC_DSLL = 0x38 | OPC_SPECIAL,
193 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
194 OPC_DROTR = OPC_DSRL | (1 << 21),
195 OPC_DSRA = 0x3B | OPC_SPECIAL,
196 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
197 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
198 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
199 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
200 /* Multiplication / division */
201 OPC_MULT = 0x18 | OPC_SPECIAL,
202 OPC_MULTU = 0x19 | OPC_SPECIAL,
203 OPC_DIV = 0x1A | OPC_SPECIAL,
204 OPC_DIVU = 0x1B | OPC_SPECIAL,
205 OPC_DMULT = 0x1C | OPC_SPECIAL,
206 OPC_DMULTU = 0x1D | OPC_SPECIAL,
207 OPC_DDIV = 0x1E | OPC_SPECIAL,
208 OPC_DDIVU = 0x1F | OPC_SPECIAL,
209
210 /* 2 registers arithmetic / logic */
211 OPC_ADD = 0x20 | OPC_SPECIAL,
212 OPC_ADDU = 0x21 | OPC_SPECIAL,
213 OPC_SUB = 0x22 | OPC_SPECIAL,
214 OPC_SUBU = 0x23 | OPC_SPECIAL,
215 OPC_AND = 0x24 | OPC_SPECIAL,
216 OPC_OR = 0x25 | OPC_SPECIAL,
217 OPC_XOR = 0x26 | OPC_SPECIAL,
218 OPC_NOR = 0x27 | OPC_SPECIAL,
219 OPC_SLT = 0x2A | OPC_SPECIAL,
220 OPC_SLTU = 0x2B | OPC_SPECIAL,
221 OPC_DADD = 0x2C | OPC_SPECIAL,
222 OPC_DADDU = 0x2D | OPC_SPECIAL,
223 OPC_DSUB = 0x2E | OPC_SPECIAL,
224 OPC_DSUBU = 0x2F | OPC_SPECIAL,
225 /* Jumps */
226 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
227 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
228 /* Traps */
229 OPC_TGE = 0x30 | OPC_SPECIAL,
230 OPC_TGEU = 0x31 | OPC_SPECIAL,
231 OPC_TLT = 0x32 | OPC_SPECIAL,
232 OPC_TLTU = 0x33 | OPC_SPECIAL,
233 OPC_TEQ = 0x34 | OPC_SPECIAL,
234 OPC_TNE = 0x36 | OPC_SPECIAL,
235 /* HI / LO registers load & stores */
236 OPC_MFHI = 0x10 | OPC_SPECIAL,
237 OPC_MTHI = 0x11 | OPC_SPECIAL,
238 OPC_MFLO = 0x12 | OPC_SPECIAL,
239 OPC_MTLO = 0x13 | OPC_SPECIAL,
240 /* Conditional moves */
241 OPC_MOVZ = 0x0A | OPC_SPECIAL,
242 OPC_MOVN = 0x0B | OPC_SPECIAL,
243
244 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
245 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
246
247 OPC_MOVCI = 0x01 | OPC_SPECIAL,
248
249 /* Special */
250 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
251 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
252 OPC_BREAK = 0x0D | OPC_SPECIAL,
253 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
254 OPC_SYNC = 0x0F | OPC_SPECIAL,
255
256 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
257 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
258 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
259 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
260 };
261
262 /*
263 * R6 Multiply and Divide instructions have the same opcode
264 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
265 */
266 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
267
268 enum {
269 R6_OPC_MUL = OPC_MULT | (2 << 6),
270 R6_OPC_MUH = OPC_MULT | (3 << 6),
271 R6_OPC_MULU = OPC_MULTU | (2 << 6),
272 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
273 R6_OPC_DIV = OPC_DIV | (2 << 6),
274 R6_OPC_MOD = OPC_DIV | (3 << 6),
275 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
276 R6_OPC_MODU = OPC_DIVU | (3 << 6),
277
278 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
279 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
280 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
281 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
282 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
283 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
284 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
285 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
286
287 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
288 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
289 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
290 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
291 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
292
293 OPC_LSA = 0x05 | OPC_SPECIAL,
294 OPC_DLSA = 0x15 | OPC_SPECIAL,
295 };
296
297 /* Multiplication variants of the vr54xx. */
298 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
299
300 enum {
301 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
302 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
303 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
304 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
305 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
306 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
307 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
308 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
309 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
310 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
311 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
312 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
313 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
314 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
315 };
316
317 /* REGIMM (rt field) opcodes */
318 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
319
320 enum {
321 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
322 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
323 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
324 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
325 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
326 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
327 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
328 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
329 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
330 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
331 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
332 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
333 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
334 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
335 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
336 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
337
338 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
339 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
340 };
341
342 /* Special2 opcodes */
343 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
344
345 enum {
346 /* Multiply & xxx operations */
347 OPC_MADD = 0x00 | OPC_SPECIAL2,
348 OPC_MADDU = 0x01 | OPC_SPECIAL2,
349 OPC_MUL = 0x02 | OPC_SPECIAL2,
350 OPC_MSUB = 0x04 | OPC_SPECIAL2,
351 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
352 /* Loongson 2F */
353 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
354 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
355 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
356 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
357 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
358 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
359 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
360 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
361 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
362 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
363 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
364 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
365 /* Misc */
366 OPC_CLZ = 0x20 | OPC_SPECIAL2,
367 OPC_CLO = 0x21 | OPC_SPECIAL2,
368 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
369 OPC_DCLO = 0x25 | OPC_SPECIAL2,
370 /* Special */
371 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
372 };
373
374 /* Special3 opcodes */
375 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
376
377 enum {
378 OPC_EXT = 0x00 | OPC_SPECIAL3,
379 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
380 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
381 OPC_DEXT = 0x03 | OPC_SPECIAL3,
382 OPC_INS = 0x04 | OPC_SPECIAL3,
383 OPC_DINSM = 0x05 | OPC_SPECIAL3,
384 OPC_DINSU = 0x06 | OPC_SPECIAL3,
385 OPC_DINS = 0x07 | OPC_SPECIAL3,
386 OPC_FORK = 0x08 | OPC_SPECIAL3,
387 OPC_YIELD = 0x09 | OPC_SPECIAL3,
388 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
389 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
390 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
391
392 /* Loongson 2E */
393 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
394 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
395 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
396 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
397 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
398 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
399 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
400 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
401 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
402 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
403 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
404 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
405
406 /* MIPS DSP Load */
407 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
408 /* MIPS DSP Arithmetic */
409 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
410 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
411 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
412 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
413 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
414 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
415 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
416 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
417 /* MIPS DSP GPR-Based Shift Sub-class */
418 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
419 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
420 /* MIPS DSP Multiply Sub-class insns */
421 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
422 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
423 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
424 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
425 /* DSP Bit/Manipulation Sub-class */
426 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
427 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
428 /* MIPS DSP Append Sub-class */
429 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
430 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
431 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
432 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
433 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
434
435 /* EVA */
436 OPC_LWLE = 0x19 | OPC_SPECIAL3,
437 OPC_LWRE = 0x1A | OPC_SPECIAL3,
438 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
439 OPC_SBE = 0x1C | OPC_SPECIAL3,
440 OPC_SHE = 0x1D | OPC_SPECIAL3,
441 OPC_SCE = 0x1E | OPC_SPECIAL3,
442 OPC_SWE = 0x1F | OPC_SPECIAL3,
443 OPC_SWLE = 0x21 | OPC_SPECIAL3,
444 OPC_SWRE = 0x22 | OPC_SPECIAL3,
445 OPC_PREFE = 0x23 | OPC_SPECIAL3,
446 OPC_LBUE = 0x28 | OPC_SPECIAL3,
447 OPC_LHUE = 0x29 | OPC_SPECIAL3,
448 OPC_LBE = 0x2C | OPC_SPECIAL3,
449 OPC_LHE = 0x2D | OPC_SPECIAL3,
450 OPC_LLE = 0x2E | OPC_SPECIAL3,
451 OPC_LWE = 0x2F | OPC_SPECIAL3,
452
453 /* R6 */
454 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
455 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
456 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
457 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
458 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
459 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
460 };
461
462 /* BSHFL opcodes */
463 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
464
465 enum {
466 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
467 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
468 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
469 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
470 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
471 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
472 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
473 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
474 };
475
476 /* DBSHFL opcodes */
477 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
478
479 enum {
480 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
481 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
482 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
483 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
484 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
485 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
486 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
487 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
488 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
489 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
490 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
491 };
492
493 /* MIPS DSP REGIMM opcodes */
494 enum {
495 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
496 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
497 };
498
499 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
500 /* MIPS DSP Load */
501 enum {
502 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
503 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
504 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
505 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
506 };
507
508 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
509 enum {
510 /* MIPS DSP Arithmetic Sub-class */
511 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
512 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
513 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
515 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
516 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
517 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
518 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
519 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
520 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
521 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
522 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
523 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
524 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
525 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
526 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
527 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
528 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
529 /* MIPS DSP Multiply Sub-class insns */
530 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
531 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
532 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
533 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
534 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
535 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
536 };
537
538 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
539 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 enum {
541 /* MIPS DSP Arithmetic Sub-class */
542 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
543 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
544 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
545 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
546 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
548 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
549 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
550 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
551 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
552 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
553 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
554 /* MIPS DSP Multiply Sub-class insns */
555 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
556 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
557 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
558 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
559 };
560
561 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
562 enum {
563 /* MIPS DSP Arithmetic Sub-class */
564 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
566 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
567 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
572 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
573 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
574 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
575 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
576 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
577 /* DSP Bit/Manipulation Sub-class */
578 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
579 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
580 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
581 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
582 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
583 };
584
585 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
586 enum {
587 /* MIPS DSP Arithmetic Sub-class */
588 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
592 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
593 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
595 /* DSP Compare-Pick Sub-class */
596 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
600 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
601 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
602 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
603 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
604 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
605 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
606 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
607 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
608 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
609 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
610 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
611 };
612
613 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
614 enum {
615 /* MIPS DSP GPR-Based Shift Sub-class */
616 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
627 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
628 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
629 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
630 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
631 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
632 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
633 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
634 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
635 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
636 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
637 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
638 };
639
640 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
641 enum {
642 /* MIPS DSP Multiply Sub-class insns */
643 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
646 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
649 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
652 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
654 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
655 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
656 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
657 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
658 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
659 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
660 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
661 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
662 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
663 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
664 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
665 };
666
667 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
668 enum {
669 /* DSP Bit/Manipulation Sub-class */
670 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
671 };
672
673 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
674 enum {
675 /* MIPS DSP Append Sub-class */
676 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
677 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
678 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
679 };
680
681 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
682 enum {
683 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
684 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
685 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
686 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
687 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
688 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
689 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
690 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
691 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
692 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
693 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
694 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
695 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
696 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
697 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
698 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
699 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
700 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
701 };
702
703 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704 enum {
705 /* MIPS DSP Arithmetic Sub-class */
706 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
712 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
713 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
719 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
720 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
721 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
722 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
723 /* DSP Bit/Manipulation Sub-class */
724 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
725 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
726 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
727 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
728 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
729 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
730 };
731
732 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
733 enum {
734 /* MIPS DSP Multiply Sub-class insns */
735 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
736 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
737 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
738 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
739 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
740 /* MIPS DSP Arithmetic Sub-class */
741 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
742 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
743 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
744 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
745 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
746 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
747 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
748 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
749 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
750 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
751 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
752 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
753 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
754 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
755 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
756 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
757 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
758 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
759 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
760 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
761 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
762 };
763
764 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
765 enum {
766 /* DSP Compare-Pick Sub-class */
767 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
775 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
776 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
783 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
784 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
785 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
786 /* MIPS DSP Arithmetic Sub-class */
787 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
788 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
789 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
790 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
792 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
793 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
794 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
795 };
796
797 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
798 enum {
799 /* DSP Append Sub-class */
800 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
801 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
802 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
803 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
804 };
805
806 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
807 enum {
808 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
809 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
810 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
819 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
820 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
821 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
822 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
823 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
824 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
825 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
826 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
827 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
828 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
829 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
830 };
831
832 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
833 enum {
834 /* DSP Bit/Manipulation Sub-class */
835 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
836 };
837
838 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
839 enum {
840 /* MIPS DSP Multiply Sub-class insns */
841 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
856 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
857 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
858 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
859 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
860 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
861 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
862 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
863 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
864 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
865 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
866 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
867 };
868
869 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
870 enum {
871 /* MIPS DSP GPR-Based Shift Sub-class */
872 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
887 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
888 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
889 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
890 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
891 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
892 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
893 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
894 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
895 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
896 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
897 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
898 };
899
900 /* Coprocessor 0 (rs field) */
901 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
902
903 enum {
904 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
905 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
906 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
907 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
908 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
909 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
910 OPC_MFTR = (0x08 << 21) | OPC_CP0,
911 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
912 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
913 OPC_MTTR = (0x0C << 21) | OPC_CP0,
914 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
915 OPC_C0 = (0x10 << 21) | OPC_CP0,
916 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
917 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
918 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
919 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
920 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
921 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
922 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
923 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
924 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
925 OPC_C0_A = (0x1A << 21) | OPC_CP0,
926 OPC_C0_B = (0x1B << 21) | OPC_CP0,
927 OPC_C0_C = (0x1C << 21) | OPC_CP0,
928 OPC_C0_D = (0x1D << 21) | OPC_CP0,
929 OPC_C0_E = (0x1E << 21) | OPC_CP0,
930 OPC_C0_F = (0x1F << 21) | OPC_CP0,
931 };
932
933 /* MFMC0 opcodes */
934 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
935
936 enum {
937 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
938 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
939 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
940 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
941 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
942 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
943 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
944 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
945 };
946
947 /* Coprocessor 0 (with rs == C0) */
948 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
949
950 enum {
951 OPC_TLBR = 0x01 | OPC_C0,
952 OPC_TLBWI = 0x02 | OPC_C0,
953 OPC_TLBINV = 0x03 | OPC_C0,
954 OPC_TLBINVF = 0x04 | OPC_C0,
955 OPC_TLBWR = 0x06 | OPC_C0,
956 OPC_TLBP = 0x08 | OPC_C0,
957 OPC_RFE = 0x10 | OPC_C0,
958 OPC_ERET = 0x18 | OPC_C0,
959 OPC_DERET = 0x1F | OPC_C0,
960 OPC_WAIT = 0x20 | OPC_C0,
961 };
962
963 /* Coprocessor 1 (rs field) */
964 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
965
966 /* Values for the fmt field in FP instructions */
967 enum {
968 /* 0 - 15 are reserved */
969 FMT_S = 16, /* single fp */
970 FMT_D = 17, /* double fp */
971 FMT_E = 18, /* extended fp */
972 FMT_Q = 19, /* quad fp */
973 FMT_W = 20, /* 32-bit fixed */
974 FMT_L = 21, /* 64-bit fixed */
975 FMT_PS = 22, /* paired single fp */
976 /* 23 - 31 are reserved */
977 };
978
979 enum {
980 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
981 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
982 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
983 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
984 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
985 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
986 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
987 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
988 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
989 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
990 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
991 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
992 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
993 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
994 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
995 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
996 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
997 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
998 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
999 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
1000 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
1001 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
1002 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
1003 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
1004 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
1005 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
1006 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
1007 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
1008 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
1009 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
1010 };
1011
1012 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1013 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1014
1015 enum {
1016 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1017 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1018 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1019 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1020 };
1021
1022 enum {
1023 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1024 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1025 };
1026
1027 enum {
1028 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1029 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1030 };
1031
1032 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1033
1034 enum {
1035 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1036 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1037 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1038 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1039 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1040 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1041 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1042 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1043 OPC_BC2 = (0x08 << 21) | OPC_CP2,
1044 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1045 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1046 };
1047
1048 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1049
1050 enum {
1051 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1052 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1053 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1054 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1055 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1056 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1057 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1058 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1059
1060 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1061 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1062 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1063 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1064 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1065 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1066 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1067 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1068
1069 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1070 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1071 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1072 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1073 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1074 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1075 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1076 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1077
1078 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1079 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1080 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1081 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1082 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1083 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1084 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1085 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1086
1087 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1088 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1089 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1090 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1091 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1092 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1093
1094 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1095 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1096 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1097 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1098 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1099 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1100
1101 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1102 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1103 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1104 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1105 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1106 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1107
1108 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1109 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1110 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1111 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1112 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1113 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1114
1115 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1116 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1117 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1118 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1119 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1120 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1121
1122 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1123 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1124 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1125 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1126 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1127 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1128
1129 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1130 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1131 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1132 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1133 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1134 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1135
1136 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1137 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1138 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1139 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1140 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1141 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1142 };
1143
1144
1145 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1146
1147 enum {
1148 OPC_LWXC1 = 0x00 | OPC_CP3,
1149 OPC_LDXC1 = 0x01 | OPC_CP3,
1150 OPC_LUXC1 = 0x05 | OPC_CP3,
1151 OPC_SWXC1 = 0x08 | OPC_CP3,
1152 OPC_SDXC1 = 0x09 | OPC_CP3,
1153 OPC_SUXC1 = 0x0D | OPC_CP3,
1154 OPC_PREFX = 0x0F | OPC_CP3,
1155 OPC_ALNV_PS = 0x1E | OPC_CP3,
1156 OPC_MADD_S = 0x20 | OPC_CP3,
1157 OPC_MADD_D = 0x21 | OPC_CP3,
1158 OPC_MADD_PS = 0x26 | OPC_CP3,
1159 OPC_MSUB_S = 0x28 | OPC_CP3,
1160 OPC_MSUB_D = 0x29 | OPC_CP3,
1161 OPC_MSUB_PS = 0x2E | OPC_CP3,
1162 OPC_NMADD_S = 0x30 | OPC_CP3,
1163 OPC_NMADD_D = 0x31 | OPC_CP3,
1164 OPC_NMADD_PS= 0x36 | OPC_CP3,
1165 OPC_NMSUB_S = 0x38 | OPC_CP3,
1166 OPC_NMSUB_D = 0x39 | OPC_CP3,
1167 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1168 };
1169
1170 /* MSA Opcodes */
1171 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1172 enum {
1173 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1174 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1175 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1176 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1177 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1178 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1179 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1180 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1181 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1182 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1183 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1184 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1185 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1186 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1187 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1188 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1189 OPC_MSA_ELM = 0x19 | OPC_MSA,
1190 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1191 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1192 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1193 OPC_MSA_VEC = 0x1E | OPC_MSA,
1194
1195 /* MI10 instruction */
1196 OPC_LD_B = (0x20) | OPC_MSA,
1197 OPC_LD_H = (0x21) | OPC_MSA,
1198 OPC_LD_W = (0x22) | OPC_MSA,
1199 OPC_LD_D = (0x23) | OPC_MSA,
1200 OPC_ST_B = (0x24) | OPC_MSA,
1201 OPC_ST_H = (0x25) | OPC_MSA,
1202 OPC_ST_W = (0x26) | OPC_MSA,
1203 OPC_ST_D = (0x27) | OPC_MSA,
1204 };
1205
1206 enum {
1207 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1208 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1209 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1210 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1211 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1212 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1213 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1214 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1215 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1216 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1217 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1218 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1219 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1220
1221 /* I8 instruction */
1222 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1223 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1224 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1225 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1226 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1227 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1228 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1229 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1230 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1231 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1232
1233 /* VEC/2R/2RF instruction */
1234 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1235 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1236 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1237 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1238 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1239 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1240 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1241
1242 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1243 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1244
1245 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1246 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1247 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1248 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1249 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1250
1251 /* 2RF instruction df(bit 16) = _w, _d */
1252 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1253 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1254 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1255 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1256 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1257 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1258 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1259 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1260 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1261 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1262 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1263 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1264 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1265 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1266 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1267 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1268
1269 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1270 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1271 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1272 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1273 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1274 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1275 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1276 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1277 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1278 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1279 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1280 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1281 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1282 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1283 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1284 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1285 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1286 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1287 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1288 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1289 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1290 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1291 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1292 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1293 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1294 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1295 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1296 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1297 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1298 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1299 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1300 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1301 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1302 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1303 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1304 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1305 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1306 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1307 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1308 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1309 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1310 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1311 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1312 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1313 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1314 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1315 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1316 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1317 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1318 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1319 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1320 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1321 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1322 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1323 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1324 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1325 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1326 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1327 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1328 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1329 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1330 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1331 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1332 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1333
1334 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1335 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1336 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1337 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1338 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1339 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1341 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1342 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1343 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1344
1345 /* 3RF instruction _df(bit 21) = _w, _d */
1346 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1347 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1348 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1349 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1350 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1351 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1352 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1353 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1356 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1357 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1358 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1359 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1361 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1362 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1363 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1364 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1365 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1366 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1367 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1368 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1369 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1370 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1372 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1373 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1374 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1375 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1376 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1377 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1378 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1379 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1380 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1381 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1382 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1383 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1384 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1385 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1386 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1387
1388 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1389 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1390 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1391 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1392 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1393 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1394 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1395 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1396 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1397 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1398 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1399 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1400 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1401 };
1402
1403
1404 /*
1405 *
1406 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1407 * ============================================
1408 *
1409 *
1410 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1411 * instructions set. It is designed to fit the needs of signal, graphical and
1412 * video processing applications. MXU instruction set is used in Xburst family
1413 * of microprocessors by Ingenic.
1414 *
1415 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1416 * the control register.
1417 *
1418 *
1419 * The notation used in MXU assembler mnemonics
1420 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1421 *
1422 * Register operands:
1423 *
1424 * XRa, XRb, XRc, XRd - MXU registers
1425 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1426 *
1427 * Non-register operands:
1428 *
1429 * aptn1 - 1-bit accumulate add/subtract pattern
1430 * aptn2 - 2-bit accumulate add/subtract pattern
1431 * eptn2 - 2-bit execute add/subtract pattern
1432 * optn2 - 2-bit operand pattern
1433 * optn3 - 3-bit operand pattern
1434 * sft4 - 4-bit shift amount
1435 * strd2 - 2-bit stride amount
1436 *
1437 * Prefixes:
1438 *
1439 * Level of parallelism: Operand size:
1440 * S - single operation at a time 32 - word
1441 * D - two operations in parallel 16 - half word
1442 * Q - four operations in parallel 8 - byte
1443 *
1444 * Operations:
1445 *
1446 * ADD - Add or subtract
1447 * ADDC - Add with carry-in
1448 * ACC - Accumulate
1449 * ASUM - Sum together then accumulate (add or subtract)
1450 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1451 * AVG - Average between 2 operands
1452 * ABD - Absolute difference
1453 * ALN - Align data
1454 * AND - Logical bitwise 'and' operation
1455 * CPS - Copy sign
1456 * EXTR - Extract bits
1457 * I2M - Move from GPR register to MXU register
1458 * LDD - Load data from memory to XRF
1459 * LDI - Load data from memory to XRF (and increase the address base)
1460 * LUI - Load unsigned immediate
1461 * MUL - Multiply
1462 * MULU - Unsigned multiply
1463 * MADD - 64-bit operand add 32x32 product
1464 * MSUB - 64-bit operand subtract 32x32 product
1465 * MAC - Multiply and accumulate (add or subtract)
1466 * MAD - Multiply and add or subtract
1467 * MAX - Maximum between 2 operands
1468 * MIN - Minimum between 2 operands
1469 * M2I - Move from MXU register to GPR register
1470 * MOVZ - Move if zero
1471 * MOVN - Move if non-zero
1472 * NOR - Logical bitwise 'nor' operation
1473 * OR - Logical bitwise 'or' operation
1474 * STD - Store data from XRF to memory
1475 * SDI - Store data from XRF to memory (and increase the address base)
1476 * SLT - Set of less than comparison
1477 * SAD - Sum of absolute differences
1478 * SLL - Logical shift left
1479 * SLR - Logical shift right
1480 * SAR - Arithmetic shift right
1481 * SAT - Saturation
1482 * SFL - Shuffle
1483 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1484 * XOR - Logical bitwise 'exclusive or' operation
1485 *
1486 * Suffixes:
1487 *
1488 * E - Expand results
1489 * F - Fixed point multiplication
1490 * L - Low part result
1491 * R - Doing rounding
1492 * V - Variable instead of immediate
1493 * W - Combine above L and V
1494 *
1495 *
1496 * The list of MXU instructions grouped by functionality
1497 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1498 *
1499 * Load/Store instructions Multiplication instructions
1500 * ----------------------- ---------------------------
1501 *
1502 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1503 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1504 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1505 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1506 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1507 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1508 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1509 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1510 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1511 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1512 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1513 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1514 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1515 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1516 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1517 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1518 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1519 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1520 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1521 * S16SDI XRa, Rb, s10, eptn2
1522 * S8LDD XRa, Rb, s8, eptn3
1523 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1524 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1525 * S8SDI XRa, Rb, s8, eptn3
1526 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1527 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1528 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1529 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1530 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1531 * S32CPS XRa, XRb, XRc
1532 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1533 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1534 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1535 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1536 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1537 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1538 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1539 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1540 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1541 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1542 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1543 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1544 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1545 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1546 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1547 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1548 * Q8SLT XRa, XRb, XRc
1549 * Q8SLTU XRa, XRb, XRc
1550 * Q8MOVZ XRa, XRb, XRc Shift instructions
1551 * Q8MOVN XRa, XRb, XRc ------------------
1552 *
1553 * D32SLL XRa, XRb, XRc, XRd, sft4
1554 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1555 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1556 * D32SARL XRa, XRb, XRc, sft4
1557 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1558 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1559 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1560 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1561 * Q16SLL XRa, XRb, XRc, XRd, sft4
1562 * Q16SLR XRa, XRb, XRc, XRd, sft4
1563 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1564 * ------------------------- Q16SLLV XRa, XRb, Rb
1565 * Q16SLRV XRa, XRb, Rb
1566 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1567 * S32ALN XRa, XRb, XRc, Rb
1568 * S32ALNI XRa, XRb, XRc, s3
1569 * S32LUI XRa, s8, optn3 Move instructions
1570 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1571 * S32EXTRV XRa, XRb, Rs, Rt
1572 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1573 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1574 *
1575 *
1576 * The opcode organization of MXU instructions
1577 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1578 *
1579 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1580 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1581 * other bits up to the instruction level is as follows:
1582 *
1583 * bits
1584 * 05..00
1585 *
1586 * ┌─ 000000 ─ OPC_MXU_S32MADD
1587 * ├─ 000001 ─ OPC_MXU_S32MADDU
1588 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1589 * │
1590 * │ 20..18
1591 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1592 * │ ├─ 001 ─ OPC_MXU_S32MIN
1593 * │ ├─ 010 ─ OPC_MXU_D16MAX
1594 * │ ├─ 011 ─ OPC_MXU_D16MIN
1595 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1596 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1597 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1598 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1599 * ├─ 000100 ─ OPC_MXU_S32MSUB
1600 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1601 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1602 * │ ├─ 001 ─ OPC_MXU_D16SLT
1603 * │ ├─ 010 ─ OPC_MXU_D16AVG
1604 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1605 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1606 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1607 * │ └─ 111 ─ OPC_MXU_Q8ADD
1608 * │
1609 * │ 20..18
1610 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1611 * │ ├─ 010 ─ OPC_MXU_D16CPS
1612 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1613 * │ └─ 110 ─ OPC_MXU_Q16SAT
1614 * ├─ 001000 ─ OPC_MXU_D16MUL
1615 * │ 25..24
1616 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1617 * │ └─ 01 ─ OPC_MXU_D16MULE
1618 * ├─ 001010 ─ OPC_MXU_D16MAC
1619 * ├─ 001011 ─ OPC_MXU_D16MACF
1620 * ├─ 001100 ─ OPC_MXU_D16MADL
1621 * ├─ 001101 ─ OPC_MXU_S16MAD
1622 * ├─ 001110 ─ OPC_MXU_Q16ADD
1623 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1624 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1625 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1626 * │
1627 * │ 23
1628 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1629 * │ └─ 1 ─ OPC_MXU_S32STDR
1630 * │
1631 * │ 13..10
1632 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1633 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1634 * │
1635 * │ 13..10
1636 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1637 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1638 * │
1639 * │ 23
1640 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1641 * │ └─ 1 ─ OPC_MXU_S32LDIR
1642 * │
1643 * │ 23
1644 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1645 * │ └─ 1 ─ OPC_MXU_S32SDIR
1646 * │
1647 * │ 13..10
1648 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1649 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1650 * │
1651 * │ 13..10
1652 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1653 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1654 * ├─ 011000 ─ OPC_MXU_D32ADD
1655 * │ 23..22
1656 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1657 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1658 * │ └─ 10 ─ OPC_MXU_D32ASUM
1659 * ├─ 011010 ─ <not assigned>
1660 * │ 23..22
1661 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1662 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1663 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1664 * │
1665 * │ 23..22
1666 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1667 * │ ├─ 01 ─ OPC_MXU_D8SUM
1668 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1669 * ├─ 011110 ─ <not assigned>
1670 * ├─ 011111 ─ <not assigned>
1671 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1672 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1673 * ├─ 100010 ─ OPC_MXU_S8LDD
1674 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1675 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1676 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1677 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1678 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1679 * │
1680 * │ 20..18
1681 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1682 * │ ├─ 001 ─ OPC_MXU_S32ALN
1683 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1684 * │ ├─ 011 ─ OPC_MXU_S32LUI
1685 * │ ├─ 100 ─ OPC_MXU_S32NOR
1686 * │ ├─ 101 ─ OPC_MXU_S32AND
1687 * │ ├─ 110 ─ OPC_MXU_S32OR
1688 * │ └─ 111 ─ OPC_MXU_S32XOR
1689 * │
1690 * │ 7..5
1691 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1692 * │ ├─ 001 ─ OPC_MXU_LXH
1693 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1694 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1695 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1696 * ├─ 101100 ─ OPC_MXU_S16LDI
1697 * ├─ 101101 ─ OPC_MXU_S16SDI
1698 * ├─ 101110 ─ OPC_MXU_S32M2I
1699 * ├─ 101111 ─ OPC_MXU_S32I2M
1700 * ├─ 110000 ─ OPC_MXU_D32SLL
1701 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1702 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1703 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1704 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1705 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1706 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1707 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1708 * │
1709 * ├─ 110111 ─ OPC_MXU_Q16SAR
1710 * │ 23..22
1711 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1712 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1713 * │
1714 * │ 20..18
1715 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1716 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1717 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1718 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1719 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1720 * │ └─ 101 ─ OPC_MXU_S32MOVN
1721 * │
1722 * │ 23..22
1723 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1724 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1725 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1726 * ├─ 111100 ─ OPC_MXU_Q8MADL
1727 * ├─ 111101 ─ OPC_MXU_S32SFL
1728 * ├─ 111110 ─ OPC_MXU_Q8SAD
1729 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1730 *
1731 *
1732 * Compiled after:
1733 *
1734 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1735 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1736 */
1737
1738 enum {
1739 OPC_MXU_S32MADD = 0x00,
1740 OPC_MXU_S32MADDU = 0x01,
1741 OPC__MXU_MUL = 0x02,
1742 OPC_MXU__POOL00 = 0x03,
1743 OPC_MXU_S32MSUB = 0x04,
1744 OPC_MXU_S32MSUBU = 0x05,
1745 OPC_MXU__POOL01 = 0x06,
1746 OPC_MXU__POOL02 = 0x07,
1747 OPC_MXU_D16MUL = 0x08,
1748 OPC_MXU__POOL03 = 0x09,
1749 OPC_MXU_D16MAC = 0x0A,
1750 OPC_MXU_D16MACF = 0x0B,
1751 OPC_MXU_D16MADL = 0x0C,
1752 OPC_MXU_S16MAD = 0x0D,
1753 OPC_MXU_Q16ADD = 0x0E,
1754 OPC_MXU_D16MACE = 0x0F,
1755 OPC_MXU__POOL04 = 0x10,
1756 OPC_MXU__POOL05 = 0x11,
1757 OPC_MXU__POOL06 = 0x12,
1758 OPC_MXU__POOL07 = 0x13,
1759 OPC_MXU__POOL08 = 0x14,
1760 OPC_MXU__POOL09 = 0x15,
1761 OPC_MXU__POOL10 = 0x16,
1762 OPC_MXU__POOL11 = 0x17,
1763 OPC_MXU_D32ADD = 0x18,
1764 OPC_MXU__POOL12 = 0x19,
1765 /* not assigned 0x1A */
1766 OPC_MXU__POOL13 = 0x1B,
1767 OPC_MXU__POOL14 = 0x1C,
1768 OPC_MXU_Q8ACCE = 0x1D,
1769 /* not assigned 0x1E */
1770 /* not assigned 0x1F */
1771 /* not assigned 0x20 */
1772 /* not assigned 0x21 */
1773 OPC_MXU_S8LDD = 0x22,
1774 OPC_MXU_S8STD = 0x23,
1775 OPC_MXU_S8LDI = 0x24,
1776 OPC_MXU_S8SDI = 0x25,
1777 OPC_MXU__POOL15 = 0x26,
1778 OPC_MXU__POOL16 = 0x27,
1779 OPC_MXU__POOL17 = 0x28,
1780 /* not assigned 0x29 */
1781 OPC_MXU_S16LDD = 0x2A,
1782 OPC_MXU_S16STD = 0x2B,
1783 OPC_MXU_S16LDI = 0x2C,
1784 OPC_MXU_S16SDI = 0x2D,
1785 OPC_MXU_S32M2I = 0x2E,
1786 OPC_MXU_S32I2M = 0x2F,
1787 OPC_MXU_D32SLL = 0x30,
1788 OPC_MXU_D32SLR = 0x31,
1789 OPC_MXU_D32SARL = 0x32,
1790 OPC_MXU_D32SAR = 0x33,
1791 OPC_MXU_Q16SLL = 0x34,
1792 OPC_MXU_Q16SLR = 0x35,
1793 OPC_MXU__POOL18 = 0x36,
1794 OPC_MXU_Q16SAR = 0x37,
1795 OPC_MXU__POOL19 = 0x38,
1796 OPC_MXU__POOL20 = 0x39,
1797 OPC_MXU__POOL21 = 0x3A,
1798 OPC_MXU_Q16SCOP = 0x3B,
1799 OPC_MXU_Q8MADL = 0x3C,
1800 OPC_MXU_S32SFL = 0x3D,
1801 OPC_MXU_Q8SAD = 0x3E,
1802 /* not assigned 0x3F */
1803 };
1804
1805
1806 /*
1807 * MXU pool 00
1808 */
1809 enum {
1810 OPC_MXU_S32MAX = 0x00,
1811 OPC_MXU_S32MIN = 0x01,
1812 OPC_MXU_D16MAX = 0x02,
1813 OPC_MXU_D16MIN = 0x03,
1814 OPC_MXU_Q8MAX = 0x04,
1815 OPC_MXU_Q8MIN = 0x05,
1816 OPC_MXU_Q8SLT = 0x06,
1817 OPC_MXU_Q8SLTU = 0x07,
1818 };
1819
1820 /*
1821 * MXU pool 01
1822 */
1823 enum {
1824 OPC_MXU_S32SLT = 0x00,
1825 OPC_MXU_D16SLT = 0x01,
1826 OPC_MXU_D16AVG = 0x02,
1827 OPC_MXU_D16AVGR = 0x03,
1828 OPC_MXU_Q8AVG = 0x04,
1829 OPC_MXU_Q8AVGR = 0x05,
1830 OPC_MXU_Q8ADD = 0x07,
1831 };
1832
1833 /*
1834 * MXU pool 02
1835 */
1836 enum {
1837 OPC_MXU_S32CPS = 0x00,
1838 OPC_MXU_D16CPS = 0x02,
1839 OPC_MXU_Q8ABD = 0x04,
1840 OPC_MXU_Q16SAT = 0x06,
1841 };
1842
1843 /*
1844 * MXU pool 03
1845 */
1846 enum {
1847 OPC_MXU_D16MULF = 0x00,
1848 OPC_MXU_D16MULE = 0x01,
1849 };
1850
1851 /*
1852 * MXU pool 04
1853 */
1854 enum {
1855 OPC_MXU_S32LDD = 0x00,
1856 OPC_MXU_S32LDDR = 0x01,
1857 };
1858
1859 /*
1860 * MXU pool 05
1861 */
1862 enum {
1863 OPC_MXU_S32STD = 0x00,
1864 OPC_MXU_S32STDR = 0x01,
1865 };
1866
1867 /*
1868 * MXU pool 06
1869 */
1870 enum {
1871 OPC_MXU_S32LDDV = 0x00,
1872 OPC_MXU_S32LDDVR = 0x01,
1873 };
1874
1875 /*
1876 * MXU pool 07
1877 */
1878 enum {
1879 OPC_MXU_S32STDV = 0x00,
1880 OPC_MXU_S32STDVR = 0x01,
1881 };
1882
1883 /*
1884 * MXU pool 08
1885 */
1886 enum {
1887 OPC_MXU_S32LDI = 0x00,
1888 OPC_MXU_S32LDIR = 0x01,
1889 };
1890
1891 /*
1892 * MXU pool 09
1893 */
1894 enum {
1895 OPC_MXU_S32SDI = 0x00,
1896 OPC_MXU_S32SDIR = 0x01,
1897 };
1898
1899 /*
1900 * MXU pool 10
1901 */
1902 enum {
1903 OPC_MXU_S32LDIV = 0x00,
1904 OPC_MXU_S32LDIVR = 0x01,
1905 };
1906
1907 /*
1908 * MXU pool 11
1909 */
1910 enum {
1911 OPC_MXU_S32SDIV = 0x00,
1912 OPC_MXU_S32SDIVR = 0x01,
1913 };
1914
1915 /*
1916 * MXU pool 12
1917 */
1918 enum {
1919 OPC_MXU_D32ACC = 0x00,
1920 OPC_MXU_D32ACCM = 0x01,
1921 OPC_MXU_D32ASUM = 0x02,
1922 };
1923
1924 /*
1925 * MXU pool 13
1926 */
1927 enum {
1928 OPC_MXU_Q16ACC = 0x00,
1929 OPC_MXU_Q16ACCM = 0x01,
1930 OPC_MXU_Q16ASUM = 0x02,
1931 };
1932
1933 /*
1934 * MXU pool 14
1935 */
1936 enum {
1937 OPC_MXU_Q8ADDE = 0x00,
1938 OPC_MXU_D8SUM = 0x01,
1939 OPC_MXU_D8SUMC = 0x02,
1940 };
1941
1942 /*
1943 * MXU pool 15
1944 */
1945 enum {
1946 OPC_MXU_S32MUL = 0x00,
1947 OPC_MXU_S32MULU = 0x01,
1948 OPC_MXU_S32EXTR = 0x02,
1949 OPC_MXU_S32EXTRV = 0x03,
1950 };
1951
1952 /*
1953 * MXU pool 16
1954 */
1955 enum {
1956 OPC_MXU_D32SARW = 0x00,
1957 OPC_MXU_S32ALN = 0x01,
1958 OPC_MXU_S32ALNI = 0x02,
1959 OPC_MXU_S32LUI = 0x03,
1960 OPC_MXU_S32NOR = 0x04,
1961 OPC_MXU_S32AND = 0x05,
1962 OPC_MXU_S32OR = 0x06,
1963 OPC_MXU_S32XOR = 0x07,
1964 };
1965
1966 /*
1967 * MXU pool 17
1968 */
1969 enum {
1970 OPC_MXU_LXB = 0x00,
1971 OPC_MXU_LXH = 0x01,
1972 OPC_MXU_LXW = 0x03,
1973 OPC_MXU_LXBU = 0x04,
1974 OPC_MXU_LXHU = 0x05,
1975 };
1976
1977 /*
1978 * MXU pool 18
1979 */
1980 enum {
1981 OPC_MXU_D32SLLV = 0x00,
1982 OPC_MXU_D32SLRV = 0x01,
1983 OPC_MXU_D32SARV = 0x03,
1984 OPC_MXU_Q16SLLV = 0x04,
1985 OPC_MXU_Q16SLRV = 0x05,
1986 OPC_MXU_Q16SARV = 0x07,
1987 };
1988
1989 /*
1990 * MXU pool 19
1991 */
1992 enum {
1993 OPC_MXU_Q8MUL = 0x00,
1994 OPC_MXU_Q8MULSU = 0x01,
1995 };
1996
1997 /*
1998 * MXU pool 20
1999 */
2000 enum {
2001 OPC_MXU_Q8MOVZ = 0x00,
2002 OPC_MXU_Q8MOVN = 0x01,
2003 OPC_MXU_D16MOVZ = 0x02,
2004 OPC_MXU_D16MOVN = 0x03,
2005 OPC_MXU_S32MOVZ = 0x04,
2006 OPC_MXU_S32MOVN = 0x05,
2007 };
2008
2009 /*
2010 * MXU pool 21
2011 */
2012 enum {
2013 OPC_MXU_Q8MAC = 0x00,
2014 OPC_MXU_Q8MACSU = 0x01,
2015 };
2016
2017 /*
2018 * Overview of the TX79-specific instruction set
2019 * =============================================
2020 *
2021 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2022 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2023 * instructions and certain multimedia instructions (MMIs). These MMIs
2024 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2025 * or sixteen 8-bit paths.
2026 *
2027 * Reference:
2028 *
2029 * The Toshiba TX System RISC TX79 Core Architecture manual,
2030 * https://wiki.qemu.org/File:C790.pdf
2031 *
2032 * Three-Operand Multiply and Multiply-Add (4 instructions)
2033 * --------------------------------------------------------
2034 * MADD [rd,] rs, rt Multiply/Add
2035 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2036 * MULT [rd,] rs, rt Multiply (3-operand)
2037 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2038 *
2039 * Multiply Instructions for Pipeline 1 (10 instructions)
2040 * ------------------------------------------------------
2041 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2042 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2043 * DIV1 rs, rt Divide Pipeline 1
2044 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2045 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2046 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2047 * MFHI1 rd Move From HI1 Register
2048 * MFLO1 rd Move From LO1 Register
2049 * MTHI1 rs Move To HI1 Register
2050 * MTLO1 rs Move To LO1 Register
2051 *
2052 * Arithmetic (19 instructions)
2053 * ----------------------------
2054 * PADDB rd, rs, rt Parallel Add Byte
2055 * PSUBB rd, rs, rt Parallel Subtract Byte
2056 * PADDH rd, rs, rt Parallel Add Halfword
2057 * PSUBH rd, rs, rt Parallel Subtract Halfword
2058 * PADDW rd, rs, rt Parallel Add Word
2059 * PSUBW rd, rs, rt Parallel Subtract Word
2060 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2061 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2062 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2063 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2064 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2065 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2066 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2067 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2068 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2069 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2070 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2071 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2072 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2073 *
2074 * Min/Max (4 instructions)
2075 * ------------------------
2076 * PMAXH rd, rs, rt Parallel Maximum Halfword
2077 * PMINH rd, rs, rt Parallel Minimum Halfword
2078 * PMAXW rd, rs, rt Parallel Maximum Word
2079 * PMINW rd, rs, rt Parallel Minimum Word
2080 *
2081 * Absolute (2 instructions)
2082 * -------------------------
2083 * PABSH rd, rt Parallel Absolute Halfword
2084 * PABSW rd, rt Parallel Absolute Word
2085 *
2086 * Logical (4 instructions)
2087 * ------------------------
2088 * PAND rd, rs, rt Parallel AND
2089 * POR rd, rs, rt Parallel OR
2090 * PXOR rd, rs, rt Parallel XOR
2091 * PNOR rd, rs, rt Parallel NOR
2092 *
2093 * Shift (9 instructions)
2094 * ----------------------
2095 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2096 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2097 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2098 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2099 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2100 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2101 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2102 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2103 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2104 *
2105 * Compare (6 instructions)
2106 * ------------------------
2107 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2108 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2109 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2110 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2111 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2112 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2113 *
2114 * LZC (1 instruction)
2115 * -------------------
2116 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2117 *
2118 * Quadword Load and Store (2 instructions)
2119 * ----------------------------------------
2120 * LQ rt, offset(base) Load Quadword
2121 * SQ rt, offset(base) Store Quadword
2122 *
2123 * Multiply and Divide (19 instructions)
2124 * -------------------------------------
2125 * PMULTW rd, rs, rt Parallel Multiply Word
2126 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2127 * PDIVW rs, rt Parallel Divide Word
2128 * PDIVUW rs, rt Parallel Divide Unsigned Word
2129 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2130 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2131 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2132 * PMULTH rd, rs, rt Parallel Multiply Halfword
2133 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2134 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2135 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2136 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2137 * PDIVBW rs, rt Parallel Divide Broadcast Word
2138 * PMFHI rd Parallel Move From HI Register
2139 * PMFLO rd Parallel Move From LO Register
2140 * PMTHI rs Parallel Move To HI Register
2141 * PMTLO rs Parallel Move To LO Register
2142 * PMFHL rd Parallel Move From HI/LO Register
2143 * PMTHL rs Parallel Move To HI/LO Register
2144 *
2145 * Pack/Extend (11 instructions)
2146 * -----------------------------
2147 * PPAC5 rd, rt Parallel Pack to 5 bits
2148 * PPACB rd, rs, rt Parallel Pack to Byte
2149 * PPACH rd, rs, rt Parallel Pack to Halfword
2150 * PPACW rd, rs, rt Parallel Pack to Word
2151 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2152 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2153 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2154 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2155 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2156 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2157 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2158 *
2159 * Others (16 instructions)
2160 * ------------------------
2161 * PCPYH rd, rt Parallel Copy Halfword
2162 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2163 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2164 * PREVH rd, rt Parallel Reverse Halfword
2165 * PINTH rd, rs, rt Parallel Interleave Halfword
2166 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2167 * PEXEH rd, rt Parallel Exchange Even Halfword
2168 * PEXCH rd, rt Parallel Exchange Center Halfword
2169 * PEXEW rd, rt Parallel Exchange Even Word
2170 * PEXCW rd, rt Parallel Exchange Center Word
2171 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2172 * MFSA rd Move from Shift Amount Register
2173 * MTSA rs Move to Shift Amount Register
2174 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2175 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2176 * PROT3W rd, rt Parallel Rotate 3 Words
2177 *
2178 * MMI (MultiMedia Instruction) encodings
2179 * ======================================
2180 *
2181 * MMI instructions encoding table keys:
2182 *
2183 * * This code is reserved for future use. An attempt to execute it
2184 * causes a Reserved Instruction exception.
2185 * % This code indicates an instruction class. The instruction word
2186 * must be further decoded by examining additional tables that show
2187 * the values for other instruction fields.
2188 * # This code is reserved for the unsupported instructions DMULT,
2189 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2190 * to execute it causes a Reserved Instruction exception.
2191 *
2192 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2193 *
2194 * 31 26 0
2195 * +--------+----------------------------------------+
2196 * | opcode | |
2197 * +--------+----------------------------------------+
2198 *
2199 * opcode bits 28..26
2200 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2201 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2202 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2203 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2204 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2205 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2206 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2207 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2208 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2209 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2210 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2211 */
2212
2213 enum {
2214 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2215 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */
2216 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
2217 };
2218
2219 /*
2220 * MMI instructions with opcode field = MMI:
2221 *
2222 * 31 26 5 0
2223 * +--------+-------------------------------+--------+
2224 * | MMI | |function|
2225 * +--------+-------------------------------+--------+
2226 *
2227 * function bits 2..0
2228 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2229 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2230 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2231 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2232 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2233 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2234 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2235 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2236 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2237 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2238 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2239 */
2240
2241 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2242 enum {
2243 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2244 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2245 MMI_OPC_PLZCW = 0x04 | MMI_OPC_CLASS_MMI,
2246 MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2247 MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2248 MMI_OPC_MFHI1 = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2249 MMI_OPC_MTHI1 = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2250 MMI_OPC_MFLO1 = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2251 MMI_OPC_MTLO1 = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2252 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2253 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2254 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
2255 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2256 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
2257 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
2258 MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2259 MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2260 MMI_OPC_PMFHL = 0x30 | MMI_OPC_CLASS_MMI,
2261 MMI_OPC_PMTHL = 0x31 | MMI_OPC_CLASS_MMI,
2262 MMI_OPC_PSLLH = 0x34 | MMI_OPC_CLASS_MMI,
2263 MMI_OPC_PSRLH = 0x36 | MMI_OPC_CLASS_MMI,
2264 MMI_OPC_PSRAH = 0x37 | MMI_OPC_CLASS_MMI,
2265 MMI_OPC_PSLLW = 0x3C | MMI_OPC_CLASS_MMI,
2266 MMI_OPC_PSRLW = 0x3E | MMI_OPC_CLASS_MMI,
2267 MMI_OPC_PSRAW = 0x3F | MMI_OPC_CLASS_MMI,
2268 };
2269
2270 /*
2271 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2272 *
2273 * 31 26 10 6 5 0
2274 * +--------+----------------------+--------+--------+
2275 * | MMI | |function| MMI0 |
2276 * +--------+----------------------+--------+--------+
2277 *
2278 * function bits 7..6
2279 * bits | 0 | 1 | 2 | 3
2280 * 10..8 | 00 | 01 | 10 | 11
2281 * -------+-------+-------+-------+-------
2282 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2283 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2284 * 2 010 | PADDB | PSUBB | PCGTB | *
2285 * 3 011 | * | * | * | *
2286 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2287 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2288 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2289 * 7 111 | * | * | PEXT5 | PPAC5
2290 */
2291
2292 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2293 enum {
2294 MMI_OPC_0_PADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2295 MMI_OPC_0_PSUBW = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2296 MMI_OPC_0_PCGTW = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2297 MMI_OPC_0_PMAXW = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2298 MMI_OPC_0_PADDH = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2299 MMI_OPC_0_PSUBH = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2300 MMI_OPC_0_PCGTH = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2301 MMI_OPC_0_PMAXH = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2302 MMI_OPC_0_PADDB = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2303 MMI_OPC_0_PSUBB = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2304 MMI_OPC_0_PCGTB = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2305 MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2306 MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2307 MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2308 MMI_OPC_0_PPACW = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2309 MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2310 MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2311 MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2312 MMI_OPC_0_PPACH = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2313 MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2314 MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2315 MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2316 MMI_OPC_0_PPACB = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2317 MMI_OPC_0_PEXT5 = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2318 MMI_OPC_0_PPAC5 = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2319 };
2320
2321 /*
2322 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2323 *
2324 * 31 26 10 6 5 0
2325 * +--------+----------------------+--------+--------+
2326 * | MMI | |function| MMI1 |
2327 * +--------+----------------------+--------+--------+
2328 *
2329 * function bits 7..6
2330 * bits | 0 | 1 | 2 | 3
2331 * 10..8 | 00 | 01 | 10 | 11
2332 * -------+-------+-------+-------+-------
2333 * 0 000 | * | PABSW | PCEQW | PMINW
2334 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2335 * 2 010 | * | * | PCEQB | *
2336 * 3 011 | * | * | * | *
2337 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2338 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2339 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2340 * 7 111 | * | * | * | *
2341 */
2342
2343 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2344 enum {
2345 MMI_OPC_1_PABSW = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2346 MMI_OPC_1_PCEQW = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2347 MMI_OPC_1_PMINW = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2348 MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2349 MMI_OPC_1_PABSH = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2350 MMI_OPC_1_PCEQH = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2351 MMI_OPC_1_PMINH = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2352 MMI_OPC_1_PCEQB = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2353 MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2354 MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2355 MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2356 MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2357 MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2358 MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2359 MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2360 MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2361 MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2362 MMI_OPC_1_QFSRV = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2363 };
2364
2365 /*
2366 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2367 *
2368 * 31 26 10 6 5 0
2369 * +--------+----------------------+--------+--------+
2370 * | MMI | |function| MMI2 |
2371 * +--------+----------------------+--------+--------+
2372 *
2373 * function bits 7..6
2374 * bits | 0 | 1 | 2 | 3
2375 * 10..8 | 00 | 01 | 10 | 11
2376 * -------+-------+-------+-------+-------
2377 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2378 * 1 001 | PMSUBW| * | * | *
2379 * 2 010 | PMFHI | PMFLO | PINTH | *
2380 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2381 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2382 * 5 101 | PMSUBH| PHMSBH| * | *
2383 * 6 110 | * | * | PEXEH | PREVH
2384 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2385 */
2386
2387 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2388 enum {
2389 MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2390 MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2391 MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2392 MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2393 MMI_OPC_2_PMFHI = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2394 MMI_OPC_2_PMFLO = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2395 MMI_OPC_2_PINTH = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2396 MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2397 MMI_OPC_2_PDIVW = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2398 MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2399 MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2400 MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2401 MMI_OPC_2_PAND = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2402 MMI_OPC_2_PXOR = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2403 MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2404 MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2405 MMI_OPC_2_PEXEH = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2406 MMI_OPC_2_PREVH = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2407 MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2408 MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2409 MMI_OPC_2_PEXEW = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2410 MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2411 };
2412
2413 /*
2414 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2415 *
2416 * 31 26 10 6 5 0
2417 * +--------+----------------------+--------+--------+
2418 * | MMI | |function| MMI3 |
2419 * +--------+----------------------+--------+--------+
2420 *
2421 * function bits 7..6
2422 * bits | 0 | 1 | 2 | 3
2423 * 10..8 | 00 | 01 | 10 | 11
2424 * -------+-------+-------+-------+-------
2425 * 0 000 |PMADDUW| * | * | PSRAVW
2426 * 1 001 | * | * | * | *
2427 * 2 010 | PMTHI | PMTLO | PINTEH| *
2428 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2429 * 4 100 | * | * | POR | PNOR
2430 * 5 101 | * | * | * | *
2431 * 6 110 | * | * | PEXCH | PCPYH
2432 * 7 111 | * | * | PEXCW | *
2433 */
2434
2435 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2436 enum {
2437 MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2438 MMI_OPC_3_PSRAVW = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2439 MMI_OPC_3_PMTHI = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2440 MMI_OPC_3_PMTLO = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2441 MMI_OPC_3_PINTEH = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2442 MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2443 MMI_OPC_3_PDIVUW = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2444 MMI_OPC_3_PCPYUD = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2445 MMI_OPC_3_POR = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2446 MMI_OPC_3_PNOR = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2447 MMI_OPC_3_PEXCH = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2448 MMI_OPC_3_PCPYH = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2449 MMI_OPC_3_PEXCW = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2450 };
2451
2452 /* global register indices */
2453 static TCGv cpu_gpr[32], cpu_PC;
2454 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2455 static TCGv cpu_dspctrl, btarget, bcond;
2456 static TCGv cpu_lladdr, cpu_llval;
2457 static TCGv_i32 hflags;
2458 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2459 static TCGv_i64 fpu_f64[32];
2460 static TCGv_i64 msa_wr_d[64];
2461
2462 #if defined(TARGET_MIPS64)
2463 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2464 static TCGv_i64 cpu_mmr[32];
2465 #endif
2466
2467 #if !defined(TARGET_MIPS64)
2468 /* MXU registers */
2469 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2470 static TCGv mxu_CR;
2471 #endif
2472
2473 #include "exec/gen-icount.h"
2474
2475 #define gen_helper_0e0i(name, arg) do { \
2476 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2477 gen_helper_##name(cpu_env, helper_tmp); \
2478 tcg_temp_free_i32(helper_tmp); \
2479 } while(0)
2480
2481 #define gen_helper_0e1i(name, arg1, arg2) do { \
2482 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2483 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2484 tcg_temp_free_i32(helper_tmp); \
2485 } while(0)
2486
2487 #define gen_helper_1e0i(name, ret, arg1) do { \
2488 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2489 gen_helper_##name(ret, cpu_env, helper_tmp); \
2490 tcg_temp_free_i32(helper_tmp); \
2491 } while(0)
2492
2493 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2494 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2495 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2496 tcg_temp_free_i32(helper_tmp); \
2497 } while(0)
2498
2499 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2500 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2501 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2502 tcg_temp_free_i32(helper_tmp); \
2503 } while(0)
2504
2505 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2506 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2507 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2508 tcg_temp_free_i32(helper_tmp); \
2509 } while(0)
2510
2511 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2512 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2513 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2514 tcg_temp_free_i32(helper_tmp); \
2515 } while(0)
2516
2517 typedef struct DisasContext {
2518 DisasContextBase base;
2519 target_ulong saved_pc;
2520 target_ulong page_start;
2521 uint32_t opcode;
2522 uint64_t insn_flags;
2523 int32_t CP0_Config1;
2524 int32_t CP0_Config2;
2525 int32_t CP0_Config3;
2526 int32_t CP0_Config5;
2527 /* Routine used to access memory */
2528 int mem_idx;
2529 TCGMemOp default_tcg_memop_mask;
2530 uint32_t hflags, saved_hflags;
2531 target_ulong btarget;
2532 bool ulri;
2533 int kscrexist;
2534 bool rxi;
2535 int ie;
2536 bool bi;
2537 bool bp;
2538 uint64_t PAMask;
2539 bool mvh;
2540 bool eva;
2541 bool sc;
2542 int CP0_LLAddr_shift;
2543 bool ps;
2544 bool vp;
2545 bool cmgcr;
2546 bool mrp;
2547 bool nan2008;
2548 bool abs2008;
2549 bool saar;
2550 } DisasContext;
2551
2552 #define DISAS_STOP DISAS_TARGET_0
2553 #define DISAS_EXIT DISAS_TARGET_1
2554
2555 static const char * const regnames[] = {
2556 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2557 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2558 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2559 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2560 };
2561
2562 static const char * const regnames_HI[] = {
2563 "HI0", "HI1", "HI2", "HI3",
2564 };
2565
2566 static const char * const regnames_LO[] = {
2567 "LO0", "LO1", "LO2", "LO3",
2568 };
2569
2570 static const char * const fregnames[] = {
2571 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2572 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2573 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2574 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2575 };
2576
2577 static const char * const msaregnames[] = {
2578 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2579 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2580 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2581 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2582 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2583 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2584 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2585 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2586 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2587 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2588 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2589 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2590 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2591 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2592 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2593 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2594 };
2595
2596 #if !defined(TARGET_MIPS64)
2597 static const char * const mxuregnames[] = {
2598 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2599 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2600 };
2601 #endif
2602
2603 #define LOG_DISAS(...) \
2604 do { \
2605 if (MIPS_DEBUG_DISAS) { \
2606 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2607 } \
2608 } while (0)
2609
2610 #define MIPS_INVAL(op) \
2611 do { \
2612 if (MIPS_DEBUG_DISAS) { \
2613 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2614 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2615 ctx->base.pc_next, ctx->opcode, op, \
2616 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2617 ((ctx->opcode >> 16) & 0x1F)); \
2618 } \
2619 } while (0)
2620
2621 /* General purpose registers moves. */
2622 static inline void gen_load_gpr(TCGv t, int reg)
2623 {
2624 if (reg == 0) {
2625 tcg_gen_movi_tl(t, 0);
2626 } else {
2627 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2628 }
2629 }
2630
2631 static inline void gen_store_gpr(TCGv t, int reg)
2632 {
2633 if (reg != 0) {
2634 tcg_gen_mov_tl(cpu_gpr[reg], t);
2635 }
2636 }
2637
2638 /* Moves to/from shadow registers. */
2639 static inline void gen_load_srsgpr(int from, int to)
2640 {
2641 TCGv t0 = tcg_temp_new();
2642
2643 if (from == 0) {
2644 tcg_gen_movi_tl(t0, 0);
2645 } else {
2646 TCGv_i32 t2 = tcg_temp_new_i32();
2647 TCGv_ptr addr = tcg_temp_new_ptr();
2648
2649 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2650 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2651 tcg_gen_andi_i32(t2, t2, 0xf);
2652 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2653 tcg_gen_ext_i32_ptr(addr, t2);
2654 tcg_gen_add_ptr(addr, cpu_env, addr);
2655
2656 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2657 tcg_temp_free_ptr(addr);
2658 tcg_temp_free_i32(t2);
2659 }
2660 gen_store_gpr(t0, to);
2661 tcg_temp_free(t0);
2662 }
2663
2664 static inline void gen_store_srsgpr (int from, int to)
2665 {
2666 if (to != 0) {
2667 TCGv t0 = tcg_temp_new();
2668 TCGv_i32 t2 = tcg_temp_new_i32();
2669 TCGv_ptr addr = tcg_temp_new_ptr();
2670
2671 gen_load_gpr(t0, from);
2672 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2673 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2674 tcg_gen_andi_i32(t2, t2, 0xf);
2675 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2676 tcg_gen_ext_i32_ptr(addr, t2);
2677 tcg_gen_add_ptr(addr, cpu_env, addr);
2678
2679 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2680 tcg_temp_free_ptr(addr);
2681 tcg_temp_free_i32(t2);
2682 tcg_temp_free(t0);
2683 }
2684 }
2685
2686 #if !defined(TARGET_MIPS64)
2687 /* MXU General purpose registers moves. */
2688 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2689 {
2690 if (reg == 0) {
2691 tcg_gen_movi_tl(t, 0);
2692 } else if (reg <= 15) {
2693 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2694 }
2695 }
2696
2697 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2698 {
2699 if (reg > 0 && reg <= 15) {
2700 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2701 }
2702 }
2703
2704 /* MXU control register moves. */
2705 static inline void gen_load_mxu_cr(TCGv t)
2706 {
2707 tcg_gen_mov_tl(t, mxu_CR);
2708 }
2709
2710 static inline void gen_store_mxu_cr(TCGv t)
2711 {
2712 /* TODO: Add handling of RW rules for MXU_CR. */
2713 tcg_gen_mov_tl(mxu_CR, t);
2714 }
2715 #endif
2716
2717
2718 /* Tests */
2719 static inline void gen_save_pc(target_ulong pc)
2720 {
2721 tcg_gen_movi_tl(cpu_PC, pc);
2722 }
2723
2724 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2725 {
2726 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2727 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2728 gen_save_pc(ctx->base.pc_next);
2729 ctx->saved_pc = ctx->base.pc_next;
2730 }
2731 if (ctx->hflags != ctx->saved_hflags) {
2732 tcg_gen_movi_i32(hflags, ctx->hflags);
2733 ctx->saved_hflags = ctx->hflags;
2734 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2735 case MIPS_HFLAG_BR:
2736 break;
2737 case MIPS_HFLAG_BC:
2738 case MIPS_HFLAG_BL:
2739 case MIPS_HFLAG_B:
2740 tcg_gen_movi_tl(btarget, ctx->btarget);
2741 break;
2742 }
2743 }
2744 }
2745
2746 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2747 {
2748 ctx->saved_hflags = ctx->hflags;
2749 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2750 case MIPS_HFLAG_BR:
2751 break;
2752 case MIPS_HFLAG_BC:
2753 case MIPS_HFLAG_BL:
2754 case MIPS_HFLAG_B:
2755 ctx->btarget = env->btarget;
2756 break;
2757 }
2758 }
2759
2760 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2761 {
2762 TCGv_i32 texcp = tcg_const_i32(excp);
2763 TCGv_i32 terr = tcg_const_i32(err);
2764 save_cpu_state(ctx, 1);
2765 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2766 tcg_temp_free_i32(terr);
2767 tcg_temp_free_i32(texcp);
2768 ctx->base.is_jmp = DISAS_NORETURN;
2769 }
2770
2771 static inline void generate_exception(DisasContext *ctx, int excp)
2772 {
2773 gen_helper_0e0i(raise_exception, excp);
2774 }
2775
2776 static inline void generate_exception_end(DisasContext *ctx, int excp)
2777 {
2778 generate_exception_err(ctx, excp, 0);
2779 }
2780
2781 /* Floating point register moves. */
2782 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2783 {
2784 if (ctx->hflags & MIPS_HFLAG_FRE) {
2785 generate_exception(ctx, EXCP_RI);
2786 }
2787 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2788 }
2789
2790 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2791 {
2792 TCGv_i64 t64;
2793 if (ctx->hflags & MIPS_HFLAG_FRE) {
2794 generate_exception(ctx, EXCP_RI);
2795 }
2796 t64 = tcg_temp_new_i64();
2797 tcg_gen_extu_i32_i64(t64, t);
2798 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2799 tcg_temp_free_i64(t64);
2800 }
2801
2802 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2803 {
2804 if (ctx->hflags & MIPS_HFLAG_F64) {
2805 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2806 } else {
2807 gen_load_fpr32(ctx, t, reg | 1);
2808 }
2809 }
2810
2811 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2812 {
2813 if (ctx->hflags & MIPS_HFLAG_F64) {
2814 TCGv_i64 t64 = tcg_temp_new_i64();
2815 tcg_gen_extu_i32_i64(t64, t);
2816 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2817 tcg_temp_free_i64(t64);
2818 } else {
2819 gen_store_fpr32(ctx, t, reg | 1);
2820 }
2821 }
2822
2823 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2824 {
2825 if (ctx->hflags & MIPS_HFLAG_F64) {
2826 tcg_gen_mov_i64(t, fpu_f64[reg]);
2827 } else {
2828 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2829 }
2830 }
2831
2832 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2833 {
2834 if (ctx->hflags & MIPS_HFLAG_F64) {
2835 tcg_gen_mov_i64(fpu_f64[reg], t);
2836 } else {
2837 TCGv_i64 t0;
2838 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2839 t0 = tcg_temp_new_i64();
2840 tcg_gen_shri_i64(t0, t, 32);
2841 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2842 tcg_temp_free_i64(t0);
2843 }
2844 }
2845
2846 static inline int get_fp_bit(int cc)
2847 {
2848 if (cc) {
2849 return 24 + cc;
2850 } else {
2851 return 23;
2852 }
2853 }
2854
2855 /* Addresses computation */
2856 static inline void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0,
2857 TCGv arg1)
2858 {
2859 tcg_gen_add_tl(ret, arg0, arg1);
2860
2861 #if defined(TARGET_MIPS64)
2862 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2863 tcg_gen_ext32s_i64(ret, ret);
2864 }
2865 #endif
2866 }
2867
2868 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2869 target_long ofs)
2870 {
2871 tcg_gen_addi_tl(ret, base, ofs);
2872
2873 #if defined(TARGET_MIPS64)
2874 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2875 tcg_gen_ext32s_i64(ret, ret);
2876 }
2877 #endif
2878 }
2879
2880 /* Addresses computation (translation time) */
2881 static target_long addr_add(DisasContext *ctx, target_long base,
2882 target_long offset)
2883 {
2884 target_long sum = base + offset;
2885
2886 #if defined(TARGET_MIPS64)
2887 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2888 sum = (int32_t)sum;
2889 }
2890 #endif
2891 return sum;
2892 }
2893
2894 /* Sign-extract the low 32-bits to a target_long. */
2895 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2896 {
2897 #if defined(TARGET_MIPS64)
2898 tcg_gen_ext32s_i64(ret, arg);
2899 #else
2900 tcg_gen_extrl_i64_i32(ret, arg);
2901 #endif
2902 }
2903
2904 /* Sign-extract the high 32-bits to a target_long. */
2905 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2906 {
2907 #if defined(TARGET_MIPS64)
2908 tcg_gen_sari_i64(ret, arg, 32);
2909 #else
2910 tcg_gen_extrh_i64_i32(ret, arg);
2911 #endif
2912 }
2913
2914 static inline void check_cp0_enabled(DisasContext *ctx)
2915 {
2916 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2917 generate_exception_err(ctx, EXCP_CpU, 0);
2918 }
2919 }
2920
2921 static inline void check_cp1_enabled(DisasContext *ctx)
2922 {
2923 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
2924 generate_exception_err(ctx, EXCP_CpU, 1);
2925 }
2926 }
2927
2928 /*
2929 * Verify that the processor is running with COP1X instructions enabled.
2930 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2931 * opcode tables.
2932 */
2933 static inline void check_cop1x(DisasContext *ctx)
2934 {
2935 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
2936 generate_exception_end(ctx, EXCP_RI);
2937 }
2938 }
2939
2940 /*
2941 * Verify that the processor is running with 64-bit floating-point
2942 * operations enabled.
2943 */
2944 static inline void check_cp1_64bitmode(DisasContext *ctx)
2945 {
2946 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
2947 generate_exception_end(ctx, EXCP_RI);
2948 }
2949 }
2950
2951 /*
2952 * Verify if floating point register is valid; an operation is not defined
2953 * if bit 0 of any register specification is set and the FR bit in the
2954 * Status register equals zero, since the register numbers specify an
2955 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2956 * in the Status register equals one, both even and odd register numbers
2957 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2958 *
2959 * Multiple 64 bit wide registers can be checked by calling
2960 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2961 */
2962 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2963 {
2964 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
2965 generate_exception_end(ctx, EXCP_RI);
2966 }
2967 }
2968
2969 /*
2970 * Verify that the processor is running with DSP instructions enabled.
2971 * This is enabled by CP0 Status register MX(24) bit.
2972 */
2973 static inline void check_dsp(DisasContext *ctx)
2974 {
2975 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2976 if (ctx->insn_flags & ASE_DSP) {
2977 generate_exception_end(ctx, EXCP_DSPDIS);
2978 } else {
2979 generate_exception_end(ctx, EXCP_RI);
2980 }
2981 }
2982 }
2983
2984 static inline void check_dsp_r2(DisasContext *ctx)
2985 {
2986 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2987 if (ctx->insn_flags & ASE_DSP) {
2988 generate_exception_end(ctx, EXCP_DSPDIS);
2989 } else {
2990 generate_exception_end(ctx, EXCP_RI);
2991 }
2992 }
2993 }
2994
2995 static inline void check_dsp_r3(DisasContext *ctx)
2996 {
2997 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2998 if (ctx->insn_flags & ASE_DSP) {
2999 generate_exception_end(ctx, EXCP_DSPDIS);
3000 } else {
3001 generate_exception_end(ctx, EXCP_RI);
3002 }
3003 }
3004 }
3005
3006 /*
3007 * This code generates a "reserved instruction" exception if the
3008 * CPU does not support the instruction set corresponding to flags.
3009 */
3010 static inline void check_insn(DisasContext *ctx, uint64_t flags)
3011 {
3012 if (unlikely(!(ctx->insn_flags & flags))) {
3013 generate_exception_end(ctx, EXCP_RI);
3014 }
3015 }
3016
3017 /*
3018 * This code generates a "reserved instruction" exception if the
3019 * CPU has corresponding flag set which indicates that the instruction
3020 * has been removed.
3021 */
3022 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3023 {
3024 if (unlikely(ctx->insn_flags & flags)) {
3025 generate_exception_end(ctx, EXCP_RI);
3026 }
3027 }
3028
3029 /*
3030 * The Linux kernel traps certain reserved instruction exceptions to
3031 * emulate the corresponding instructions. QEMU is the kernel in user
3032 * mode, so those traps are emulated by accepting the instructions.
3033 *
3034 * A reserved instruction exception is generated for flagged CPUs if
3035 * QEMU runs in system mode.
3036 */
3037 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3038 {
3039 #ifndef CONFIG_USER_ONLY
3040 check_insn_opc_removed(ctx, flags);
3041 #endif
3042 }
3043
3044 /*
3045 * This code generates a "reserved instruction" exception if the
3046 * CPU does not support 64-bit paired-single (PS) floating point data type.
3047 */
3048 static inline void check_ps(DisasContext *ctx)
3049 {
3050 if (unlikely(!ctx->ps)) {
3051 generate_exception(ctx, EXCP_RI);
3052 }
3053 check_cp1_64bitmode(ctx);
3054 }
3055
3056 #ifdef TARGET_MIPS64
3057 /*
3058 * This code generates a "reserved instruction" exception if 64-bit
3059 * instructions are not enabled.
3060 */
3061 static inline void check_mips_64(DisasContext *ctx)
3062 {
3063 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) {
3064 generate_exception_end(ctx, EXCP_RI);
3065 }
3066 }
3067 #endif
3068
3069 #ifndef CONFIG_USER_ONLY
3070 static inline void check_mvh(DisasContext *ctx)
3071 {
3072 if (unlikely(!ctx->mvh)) {
3073 generate_exception(ctx, EXCP_RI);
3074 }
3075 }
3076 #endif
3077
3078 /*
3079 * This code generates a "reserved instruction" exception if the
3080 * Config5 XNP bit is set.
3081 */
3082 static inline void check_xnp(DisasContext *ctx)
3083 {
3084 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3085 generate_exception_end(ctx, EXCP_RI);
3086 }
3087 }
3088
3089 #ifndef CONFIG_USER_ONLY
3090 /*
3091 * This code generates a "reserved instruction" exception if the
3092 * Config3 PW bit is NOT set.
3093 */
3094 static inline void check_pw(DisasContext *ctx)
3095 {
3096 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3097 generate_exception_end(ctx, EXCP_RI);
3098 }
3099 }
3100 #endif
3101
3102 /*
3103 * This code generates a "reserved instruction" exception if the
3104 * Config3 MT bit is NOT set.
3105 */
3106 static inline void check_mt(DisasContext *ctx)
3107 {
3108 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3109 generate_exception_end(ctx, EXCP_RI);
3110 }
3111 }
3112
3113 #ifndef CONFIG_USER_ONLY
3114 /*
3115 * This code generates a "coprocessor unusable" exception if CP0 is not
3116 * available, and, if that is not the case, generates a "reserved instruction"
3117 * exception if the Config5 MT bit is NOT set. This is needed for availability
3118 * control of some of MT ASE instructions.
3119 */
3120 static inline void check_cp0_mt(DisasContext *ctx)
3121 {
3122 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3123 generate_exception_err(ctx, EXCP_CpU, 0);
3124 } else {
3125 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3126 generate_exception_err(ctx, EXCP_RI, 0);
3127 }
3128 }
3129 }
3130 #endif
3131
3132 /*
3133 * This code generates a "reserved instruction" exception if the
3134 * Config5 NMS bit is set.
3135 */
3136 static inline void check_nms(DisasContext *ctx)
3137 {
3138 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3139 generate_exception_end(ctx, EXCP_RI);
3140 }
3141 }
3142
3143 /*
3144 * This code generates a "reserved instruction" exception if the
3145 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3146 * Config2 TL, and Config5 L2C are unset.
3147 */
3148 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3149 {
3150 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3151 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3152 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3153 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3154 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3155 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
3156 generate_exception_end(ctx, EXCP_RI);
3157 }
3158 }
3159
3160 /*
3161 * This code generates a "reserved instruction" exception if the
3162 * Config5 EVA bit is NOT set.
3163 */
3164 static inline void check_eva(DisasContext *ctx)
3165 {
3166 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3167 generate_exception_end(ctx, EXCP_RI);
3168 }
3169 }
3170
3171
3172 /*
3173 * Define small wrappers for gen_load_fpr* so that we have a uniform
3174 * calling interface for 32 and 64-bit FPRs. No sense in changing
3175 * all callers for gen_load_fpr32 when we need the CTX parameter for
3176 * this one use.
3177 */
3178 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3179 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3180 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3181 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3182 int ft, int fs, int cc) \
3183 { \
3184 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3185 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3186 switch (ifmt) { \
3187 case FMT_PS: \
3188 check_ps(ctx); \
3189 break; \
3190 case FMT_D: \
3191 if (abs) { \
3192 check_cop1x(ctx); \
3193 } \
3194 check_cp1_registers(ctx, fs | ft); \
3195 break; \
3196 case FMT_S: \
3197 if (abs) { \
3198 check_cop1x(ctx); \
3199 } \
3200 break; \
3201 } \
3202 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3203 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3204 switch (n) { \
3205 case 0: \
3206 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
3207 break; \
3208 case 1: \
3209 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
3210 break; \
3211 case 2: \
3212 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
3213 break; \
3214 case 3: \
3215 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
3216 break; \
3217 case 4: \
3218 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
3219 break; \
3220 case 5: \
3221 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
3222 break; \
3223 case 6: \
3224 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
3225 break; \
3226 case 7: \
3227 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
3228 break; \
3229 case 8: \
3230 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
3231 break; \
3232 case 9: \
3233 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
3234 break; \
3235 case 10: \
3236 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
3237 break; \
3238 case 11: \
3239 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
3240 break; \
3241 case 12: \
3242 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
3243 break; \
3244 case 13: \
3245 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
3246 break; \
3247 case 14: \
3248 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
3249 break; \
3250 case 15: \
3251 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
3252 break; \
3253 default: \
3254 abort(); \
3255 } \
3256 tcg_temp_free_i##bits (fp0); \
3257 tcg_temp_free_i##bits (fp1); \
3258 }
3259
3260 FOP_CONDS(, 0, d, FMT_D, 64)
3261 FOP_CONDS(abs, 1, d, FMT_D, 64)
3262 FOP_CONDS(, 0, s, FMT_S, 32)
3263 FOP_CONDS(abs, 1, s, FMT_S, 32)
3264 FOP_CONDS(, 0, ps, FMT_PS, 64)
3265 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3266 #undef FOP_CONDS
3267
3268 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3269 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3270 int ft, int fs, int fd) \
3271 { \
3272 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3273 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3274 if (ifmt == FMT_D) { \
3275 check_cp1_registers(ctx, fs | ft | fd); \
3276 } \
3277 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3278 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3279 switch (n) { \
3280 case 0: \
3281 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3282 break; \
3283 case 1: \
3284 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3285 break; \
3286 case 2: \
3287 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3288 break; \
3289 case 3: \
3290 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3291 break; \
3292 case 4: \
3293 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3294 break; \
3295 case 5: \
3296 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3297 break; \
3298 case 6: \
3299 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3300 break; \
3301 case 7: \
3302 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3303 break; \
3304 case 8: \
3305 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3306 break; \
3307 case 9: \
3308 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3309 break; \
3310 case 10: \
3311 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3312 break; \
3313 case 11: \
3314 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3315 break; \
3316 case 12: \
3317 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3318 break; \
3319 case 13: \
3320 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3321 break; \
3322 case 14: \
3323 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3324 break; \
3325 case 15: \
3326 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3327 break; \
3328 case 17: \
3329 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3330 break; \
3331 case 18: \
3332 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3333 break; \
3334 case 19: \
3335 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3336 break; \
3337 case 25: \
3338 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3339 break; \
3340 case 26: \
3341 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3342 break; \
3343 case 27: \
3344 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3345 break; \
3346 default: \
3347 abort(); \
3348 } \
3349 STORE; \
3350 tcg_temp_free_i ## bits (fp0); \
3351 tcg_temp_free_i ## bits (fp1); \
3352 }
3353
3354 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3355 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3356 #undef FOP_CONDNS
3357 #undef gen_ldcmp_fpr32
3358 #undef gen_ldcmp_fpr64
3359
3360 /* load/store instructions. */
3361 #ifdef CONFIG_USER_ONLY
3362 #define OP_LD_ATOMIC(insn,fname) \
3363 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3364 DisasContext *ctx) \
3365 { \
3366 TCGv t0 = tcg_temp_new(); \
3367 tcg_gen_mov_tl(t0, arg1); \
3368 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3369 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3370 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3371 tcg_temp_free(t0); \
3372 }
3373 #else
3374 #define OP_LD_ATOMIC(insn,fname) \
3375 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3376 DisasContext *ctx) \
3377 { \
3378 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3379 }
3380 #endif
3381 OP_LD_ATOMIC(ll,ld32s);
3382 #if defined(TARGET_MIPS64)
3383 OP_LD_ATOMIC(lld,ld64);
3384 #endif
3385 #undef OP_LD_ATOMIC
3386
3387 static void gen_base_offset_addr(DisasContext *ctx, TCGv addr,
3388 int base, int offset)
3389 {
3390 if (base == 0) {
3391 tcg_gen_movi_tl(addr, offset);
3392 } else if (offset == 0) {
3393 gen_load_gpr(addr, base);
3394 } else {
3395 tcg_gen_movi_tl(addr, offset);
3396 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3397 }
3398 }
3399
3400 static target_ulong pc_relative_pc(DisasContext *ctx)
3401 {
3402 target_ulong pc = ctx->base.pc_next;
3403
3404 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3405 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3406
3407 pc -= branch_bytes;
3408 }
3409
3410 pc &= ~(target_ulong)3;
3411 return pc;
3412 }
3413
3414 /* Load */
3415 static void gen_ld(DisasContext *ctx, uint32_t opc,
3416 int rt, int base, int offset)
3417 {
3418 TCGv t0, t1, t2;
3419 int mem_idx = ctx->mem_idx;
3420
3421 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3422 /*
3423 * Loongson CPU uses a load to zero register for prefetch.
3424 * We emulate it as a NOP. On other CPU we must perform the
3425 * actual memory access.
3426 */
3427 return;
3428 }
3429
3430 t0 = tcg_temp_new();
3431 gen_base_offset_addr(ctx, t0, base, offset);
3432
3433 switch (opc) {
3434 #if defined(TARGET_MIPS64)
3435 case OPC_LWU:
3436 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3437 ctx->default_tcg_memop_mask);
3438 gen_store_gpr(t0, rt);
3439 break;
3440 case OPC_LD:
3441 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3442 ctx->default_tcg_memop_mask);
3443 gen_store_gpr(t0, rt);
3444 break;
3445 case OPC_LLD:
3446 case R6_OPC_LLD:
3447 op_ld_lld(t0, t0, mem_idx, ctx);
3448 gen_store_gpr(t0, rt);
3449 break;
3450 case OPC_LDL:
3451 t1 = tcg_temp_new();
3452 /*
3453 * Do a byte access to possibly trigger a page
3454 * fault with the unaligned address.
3455 */
3456 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3457 tcg_gen_andi_tl(t1, t0, 7);
3458 #ifndef TARGET_WORDS_BIGENDIAN
3459 tcg_gen_xori_tl(t1, t1, 7);
3460 #endif
3461 tcg_gen_shli_tl(t1, t1, 3);
3462 tcg_gen_andi_tl(t0, t0, ~7);
3463 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3464 tcg_gen_shl_tl(t0, t0, t1);
3465 t2 = tcg_const_tl(-1);
3466 tcg_gen_shl_tl(t2, t2, t1);
3467 gen_load_gpr(t1, rt);
3468 tcg_gen_andc_tl(t1, t1, t2);
3469 tcg_temp_free(t2);
3470 tcg_gen_or_tl(t0, t0, t1);
3471 tcg_temp_free(t1);
3472 gen_store_gpr(t0, rt);
3473 break;
3474 case OPC_LDR:
3475 t1 = tcg_temp_new();
3476 /*
3477 * Do a byte access to possibly trigger a page
3478 * fault with the unaligned address.
3479 */
3480 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3481 tcg_gen_andi_tl(t1, t0, 7);
3482 #ifdef TARGET_WORDS_BIGENDIAN
3483 tcg_gen_xori_tl(t1, t1, 7);
3484 #endif
3485 tcg_gen_shli_tl(t1, t1, 3);
3486 tcg_gen_andi_tl(t0, t0, ~7);
3487 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3488 tcg_gen_shr_tl(t0, t0, t1);
3489 tcg_gen_xori_tl(t1, t1, 63);
3490 t2 = tcg_const_tl(0xfffffffffffffffeull);
3491 tcg_gen_shl_tl(t2, t2, t1);
3492 gen_load_gpr(t1, rt);
3493 tcg_gen_and_tl(t1, t1, t2);
3494 tcg_temp_free(t2);
3495 tcg_gen_or_tl(t0, t0, t1);
3496 tcg_temp_free(t1);
3497 gen_store_gpr(t0, rt);
3498 break;
3499 case OPC_LDPC:
3500 t1 = tcg_const_tl(pc_relative_pc(ctx));
3501 gen_op_addr_add(ctx, t0, t0, t1);
3502 tcg_temp_free(t1);
3503 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3504 gen_store_gpr(t0, rt);
3505 break;
3506 #endif
3507 case OPC_LWPC:
3508 t1 = tcg_const_tl(pc_relative_pc(ctx));
3509 gen_op_addr_add(ctx, t0, t0, t1);
3510 tcg_temp_free(t1);
3511 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3512 gen_store_gpr(t0, rt);
3513 break;
3514 case OPC_LWE:
3515 mem_idx = MIPS_HFLAG_UM;
3516 /* fall through */
3517 case OPC_LW:
3518 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3519 ctx->default_tcg_memop_mask);
3520 gen_store_gpr(t0, rt);
3521 break;
3522 case OPC_LHE:
3523 mem_idx = MIPS_HFLAG_UM;
3524 /* fall through */
3525 case OPC_LH:
3526 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3527 ctx->default_tcg_memop_mask);
3528 gen_store_gpr(t0, rt);
3529 break;
3530 case OPC_LHUE:
3531 mem_idx = MIPS_HFLAG_UM;
3532 /* fall through */
3533 case OPC_LHU:
3534 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3535 ctx->default_tcg_memop_mask);
3536 gen_store_gpr(t0, rt);
3537 break;
3538 case OPC_LBE:
3539 mem_idx = MIPS_HFLAG_UM;
3540 /* fall through */
3541 case OPC_LB:
3542 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3543 gen_store_gpr(t0, rt);
3544 break;
3545 case OPC_LBUE:
3546 mem_idx = MIPS_HFLAG_UM;
3547 /* fall through */
3548 case OPC_LBU:
3549 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3550 gen_store_gpr(t0, rt);
3551 break;
3552 case OPC_LWLE:
3553 mem_idx = MIPS_HFLAG_UM;
3554 /* fall through */
3555 case OPC_LWL:
3556 t1 = tcg_temp_new();
3557 /*
3558 * Do a byte access to possibly trigger a page
3559 * fault with the unaligned address.
3560 */
3561 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3562 tcg_gen_andi_tl(t1, t0, 3);
3563 #ifndef TARGET_WORDS_BIGENDIAN
3564 tcg_gen_xori_tl(t1, t1, 3);
3565 #endif
3566 tcg_gen_shli_tl(t1, t1, 3);
3567 tcg_gen_andi_tl(t0, t0, ~3);
3568 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3569 tcg_gen_shl_tl(t0, t0, t1);
3570 t2 = tcg_const_tl(-1);
3571 tcg_gen_shl_tl(t2, t2, t1);
3572 gen_load_gpr(t1, rt);
3573 tcg_gen_andc_tl(t1, t1, t2);
3574 tcg_temp_free(t2);
3575 tcg_gen_or_tl(t0, t0, t1);
3576 tcg_temp_free(t1);
3577 tcg_gen_ext32s_tl(t0, t0);
3578 gen_store_gpr(t0, rt);
3579 break;
3580 case OPC_LWRE:
3581 mem_idx = MIPS_HFLAG_UM;
3582 /* fall through */
3583 case OPC_LWR:
3584 t1 = tcg_temp_new();
3585 /*
3586 * Do a byte access to possibly trigger a page
3587 * fault with the unaligned address.
3588 */
3589 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3590 tcg_gen_andi_tl(t1, t0, 3);
3591 #ifdef TARGET_WORDS_BIGENDIAN
3592 tcg_gen_xori_tl(t1, t1, 3);
3593 #endif
3594 tcg_gen_shli_tl(t1, t1, 3);
3595 tcg_gen_andi_tl(t0, t0, ~3);
3596 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3597 tcg_gen_shr_tl(t0, t0, t1);
3598 tcg_gen_xori_tl(t1, t1, 31);
3599 t2 = tcg_const_tl(0xfffffffeull);
3600 tcg_gen_shl_tl(t2, t2, t1);
3601 gen_load_gpr(t1, rt);
3602 tcg_gen_and_tl(t1, t1, t2);
3603 tcg_temp_free(t2);
3604 tcg_gen_or_tl(t0, t0, t1);
3605 tcg_temp_free(t1);
3606 tcg_gen_ext32s_tl(t0, t0);
3607 gen_store_gpr(t0, rt);
3608 break;
3609 case OPC_LLE:
3610 mem_idx = MIPS_HFLAG_UM;
3611 /* fall through */
3612 case OPC_LL:
3613 case R6_OPC_LL:
3614 op_ld_ll(t0, t0, mem_idx, ctx);
3615 gen_store_gpr(t0, rt);
3616 break;
3617 }
3618 tcg_temp_free(t0);
3619 }
3620
3621 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3622 uint32_t reg1, uint32_t reg2)
3623 {
3624 TCGv taddr = tcg_temp_new();
3625 TCGv_i64 tval = tcg_temp_new_i64();
3626 TCGv tmp1 = tcg_temp_new();
3627 TCGv tmp2 = tcg_temp_new();
3628
3629 gen_base_offset_addr(ctx, taddr, base, offset);
3630 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3631 #ifdef TARGET_WORDS_BIGENDIAN
3632 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3633 #else
3634 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3635 #endif
3636 gen_store_gpr(tmp1, reg1);
3637 tcg_temp_free(tmp1);
3638 gen_store_gpr(tmp2, reg2);
3639 tcg_temp_free(tmp2);
3640 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3641 tcg_temp_free_i64(tval);
3642 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3643 tcg_temp_free(taddr);
3644 }
3645
3646 /* Store */
3647 static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
3648 int base, int offset)
3649 {
3650 TCGv t0 = tcg_temp_new();
3651 TCGv t1 = tcg_temp_new();
3652 int mem_idx = ctx->mem_idx;
3653
3654 gen_base_offset_addr(ctx, t0, base, offset);
3655 gen_load_gpr(t1, rt);
3656 switch (opc) {
3657 #if defined(TARGET_MIPS64)
3658 case OPC_SD:
3659 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3660 ctx->default_tcg_memop_mask);
3661 break;
3662 case OPC_SDL:
3663 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3664 break;
3665 case OPC_SDR:
3666 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3667 break;
3668 #endif
3669 case OPC_SWE:
3670 mem_idx = MIPS_HFLAG_UM;
3671 /* fall through */
3672 case OPC_SW:
3673 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3674 ctx->default_tcg_memop_mask);
3675 break;
3676 case OPC_SHE:
3677 mem_idx = MIPS_HFLAG_UM;
3678 /* fall through */
3679 case OPC_SH:
3680 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3681 ctx->default_tcg_memop_mask);
3682 break;
3683 case OPC_SBE:
3684 mem_idx = MIPS_HFLAG_UM;
3685 /* fall through */
3686 case OPC_SB:
3687 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3688 break;
3689 case OPC_SWLE:
3690 mem_idx = MIPS_HFLAG_UM;
3691 /* fall through */
3692 case OPC_SWL:
3693 gen_helper_0e2i(swl, t1, t0, mem_idx);
3694 break;
3695 case OPC_SWRE:
3696 mem_idx = MIPS_HFLAG_UM;
3697 /* fall through */
3698 case OPC_SWR:
3699 gen_helper_0e2i(swr, t1, t0, mem_idx);
3700 break;
3701 }
3702 tcg_temp_free(t0);
3703 tcg_temp_free(t1);
3704 }
3705
3706
3707 /* Store conditional */
3708 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3709 TCGMemOp tcg_mo, bool eva)
3710 {
3711 TCGv addr, t0, val;
3712 TCGLabel *l1 = gen_new_label();
3713 TCGLabel *done = gen_new_label();
3714
3715 t0 = tcg_temp_new();
3716 addr = tcg_temp_new();
3717 /* compare the address against that of the preceeding LL */
3718 gen_base_offset_addr(ctx, addr, base, offset);
3719 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3720 tcg_temp_free(addr);
3721 tcg_gen_movi_tl(t0, 0);
3722 gen_store_gpr(t0, rt);
3723 tcg_gen_br(done);
3724
3725 gen_set_label(l1);
3726 /* generate cmpxchg */
3727 val = tcg_temp_new();
3728 gen_load_gpr(val, rt);
3729 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3730 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3731 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3732 gen_store_gpr(t0, rt);
3733 tcg_temp_free(val);
3734
3735 gen_set_label(done);
3736 tcg_temp_free(t0);
3737 }
3738
3739
3740 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3741 uint32_t reg1, uint32_t reg2, bool eva)
3742 {
3743 TCGv taddr = tcg_temp_local_new();
3744 TCGv lladdr = tcg_temp_local_new();
3745 TCGv_i64 tval = tcg_temp_new_i64();
3746 TCGv_i64 llval = tcg_temp_new_i64();
3747 TCGv_i64 val = tcg_temp_new_i64();
3748 TCGv tmp1 = tcg_temp_new();
3749 TCGv tmp2 = tcg_temp_new();
3750 TCGLabel *lab_fail = gen_new_label();
3751 TCGLabel *lab_done = gen_new_label();
3752
3753 gen_base_offset_addr(ctx, taddr, base, offset);
3754
3755 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3756 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3757
3758 gen_load_gpr(tmp1, reg1);
3759 gen_load_gpr(tmp2, reg2);
3760
3761 #ifdef TARGET_WORDS_BIGENDIAN
3762 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3763 #else
3764 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3765 #endif
3766
3767 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3768 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3769 eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3770 if (reg1 != 0) {
3771 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3772 }
3773 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3774
3775 gen_set_label(lab_fail);
3776
3777 if (reg1 != 0) {
3778 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3779 }
3780 gen_set_label(lab_done);
3781 tcg_gen_movi_tl(lladdr, -1);
3782 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3783 }
3784
3785 /* Load and store */
3786 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
3787 TCGv t0)
3788 {
3789 /*
3790 * Don't do NOP if destination is zero: we must perform the actual
3791 * memory access.
3792 */
3793 switch (opc) {
3794 case OPC_LWC1:
3795 {
3796 TCGv_i32 fp0 = tcg_temp_new_i32();
3797 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3798 ctx->default_tcg_memop_mask);
3799 gen_store_fpr32(ctx, fp0, ft);
3800 tcg_temp_free_i32(fp0);
3801 }
3802 break;
3803 case OPC_SWC1:
3804 {
3805 TCGv_i32 fp0 = tcg_temp_new_i32();
3806 gen_load_fpr32(ctx, fp0, ft);
3807 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3808 ctx->default_tcg_memop_mask);
3809 tcg_temp_free_i32(fp0);
3810 }
3811 break;
3812 case OPC_LDC1:
3813 {
3814 TCGv_i64 fp0 = tcg_temp_new_i64();
3815 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3816 ctx->default_tcg_memop_mask);
3817 gen_store_fpr64(ctx, fp0, ft);
3818 tcg_temp_free_i64(fp0);
3819 }
3820 break;
3821 case OPC_SDC1:
3822 {
3823 TCGv_i64 fp0 = tcg_temp_new_i64();
3824 gen_load_fpr64(ctx, fp0, ft);
3825 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3826 ctx->default_tcg_memop_mask);
3827 tcg_temp_free_i64(fp0);
3828 }
3829 break;
3830 default:
3831 MIPS_INVAL("flt_ldst");
3832 generate_exception_end(ctx, EXCP_RI);
3833 break;
3834 }
3835 }
3836
3837 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3838 int rs, int16_t imm)
3839 {
3840 TCGv t0 = tcg_temp_new();
3841
3842 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3843 check_cp1_enabled(ctx);
3844 switch (op) {
3845 case OPC_LDC1:
3846 case OPC_SDC1:
3847 check_insn(ctx, ISA_MIPS2);
3848 /* Fallthrough */
3849 default:
3850 gen_base_offset_addr(ctx, t0, rs, imm);
3851 gen_flt_ldst(ctx, op, rt, t0);
3852 }
3853 } else {
3854 generate_exception_err(ctx, EXCP_CpU, 1);
3855 }
3856 tcg_temp_free(t0);
3857 }
3858
3859 /* Arithmetic with immediate operand */
3860 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3861 int rt, int rs, int imm)
3862 {
3863 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3864
3865 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3866 /*
3867 * If no destination, treat it as a NOP.
3868 * For addi, we must generate the overflow exception when needed.
3869 */
3870 return;
3871 }
3872 switch (opc) {
3873 case OPC_ADDI:
3874 {
3875 TCGv t0 = tcg_temp_local_new();
3876 TCGv t1 = tcg_temp_new();
3877 TCGv t2 = tcg_temp_new();
3878 TCGLabel *l1 = gen_new_label();
3879
3880 gen_load_gpr(t1, rs);
3881 tcg_gen_addi_tl(t0, t1, uimm);
3882 tcg_gen_ext32s_tl(t0, t0);
3883
3884 tcg_gen_xori_tl(t1, t1, ~uimm);
3885 tcg_gen_xori_tl(t2, t0, uimm);
3886 tcg_gen_and_tl(t1, t1, t2);
3887 tcg_temp_free(t2);
3888 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3889 tcg_temp_free(t1);
3890 /* operands of same sign, result different sign */
3891 generate_exception(ctx, EXCP_OVERFLOW);
3892 gen_set_label(l1);
3893 tcg_gen_ext32s_tl(t0, t0);
3894 gen_store_gpr(t0, rt);
3895 tcg_temp_free(t0);
3896 }
3897 break;
3898 case OPC_ADDIU:
3899 if (rs != 0) {
3900 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3901 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3902 } else {
3903 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3904 }
3905 break;
3906 #if defined(TARGET_MIPS64)
3907 case OPC_DADDI:
3908 {
3909 TCGv t0 = tcg_temp_local_new();
3910 TCGv t1 = tcg_temp_new();
3911 TCGv t2 = tcg_temp_new();
3912 TCGLabel *l1 = gen_new_label();
3913
3914 gen_load_gpr(t1, rs);
3915 tcg_gen_addi_tl(t0, t1, uimm);
3916
3917 tcg_gen_xori_tl(t1, t1, ~uimm);
3918 tcg_gen_xori_tl(t2, t0, uimm);
3919 tcg_gen_and_tl(t1, t1, t2);
3920 tcg_temp_free(t2);
3921 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3922 tcg_temp_free(t1);
3923 /* operands of same sign, result different sign */
3924 generate_exception(ctx, EXCP_OVERFLOW);
3925 gen_set_label(l1);
3926 gen_store_gpr(t0, rt);
3927 tcg_temp_free(t0);
3928 }
3929 break;
3930 case OPC_DADDIU:
3931 if (rs != 0) {
3932 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3933 } else {
3934 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3935 }
3936 break;
3937 #endif
3938 }
3939 }
3940
3941 /* Logic with immediate operand */
3942 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3943 int rt, int rs, int16_t imm)
3944 {
3945 target_ulong uimm;
3946
3947 if (rt == 0) {
3948 /* If no destination, treat it as a NOP. */
3949 return;
3950 }
3951 uimm = (uint16_t)imm;
3952 switch (opc) {
3953 case OPC_ANDI:
3954 if (likely(rs != 0)) {
3955 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3956 } else {
3957 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3958 }
3959 break;
3960 case OPC_ORI:
3961 if (rs != 0) {
3962 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3963 } else {
3964 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3965 }
3966 break;
3967 case OPC_XORI:
3968 if (likely(rs != 0)) {
3969 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3970 } else {
3971 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3972 }
3973 break;
3974 case OPC_LUI:
3975 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3976 /* OPC_AUI */
3977 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3978 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3979 } else {
3980 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3981 }
3982 break;
3983
3984 default:
3985 break;
3986 }
3987 }
3988
3989 /* Set on less than with immediate operand */
3990 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3991 int rt, int rs, int16_t imm)
3992 {
3993 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3994 TCGv t0;
3995
3996 if (rt == 0) {
3997 /* If no destination, treat it as a NOP. */
3998 return;
3999 }
4000 t0 = tcg_temp_new();
4001 gen_load_gpr(t0, rs);
4002 switch (opc) {
4003 case OPC_SLTI:
4004 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
4005 break;
4006 case OPC_SLTIU:
4007 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
4008 break;
4009 }
4010 tcg_temp_free(t0);
4011 }
4012
4013 /* Shifts with immediate operand */
4014 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
4015 int rt, int rs, int16_t imm)
4016 {
4017 target_ulong uimm = ((uint16_t)imm) & 0x1f;
4018 TCGv t0;
4019
4020 if (rt == 0) {
4021 /* If no destination, treat it as a NOP. */
4022 return;
4023 }
4024
4025 t0 = tcg_temp_new();
4026 gen_load_gpr(t0, rs);
4027 switch (opc) {
4028 case OPC_SLL:
4029 tcg_gen_shli_tl(t0, t0, uimm);
4030 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4031 break;
4032 case OPC_SRA:
4033 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4034 break;
4035 case OPC_SRL:
4036 if (uimm != 0) {
4037 tcg_gen_ext32u_tl(t0, t0);
4038 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4039 } else {
4040 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4041 }
4042 break;
4043 case OPC_ROTR:
4044 if (uimm != 0) {
4045 TCGv_i32 t1 = tcg_temp_new_i32();
4046
4047 tcg_gen_trunc_tl_i32(t1, t0);
4048 tcg_gen_rotri_i32(t1, t1, uimm);
4049 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
4050 tcg_temp_free_i32(t1);
4051 } else {
4052 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4053 }
4054 break;
4055 #if defined(TARGET_MIPS64)
4056 case OPC_DSLL:
4057 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
4058 break;
4059 case OPC_DSRA:
4060 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4061 break;
4062 case OPC_DSRL:
4063 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4064 break;
4065 case OPC_DROTR:
4066 if (uimm != 0) {
4067 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
4068 } else {
4069 tcg_gen_mov_tl(cpu_gpr[rt], t0);
4070 }
4071 break;
4072 case OPC_DSLL32:
4073 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4074 break;
4075 case OPC_DSRA32:
4076 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4077 break;
4078 case OPC_DSRL32:
4079 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4080 break;
4081 case OPC_DROTR32:
4082 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4083 break;
4084 #endif
4085 }
4086 tcg_temp_free(t0);
4087 }
4088
4089 /* Arithmetic */
4090 static void gen_arith(DisasContext *ctx, uint32_t opc,
4091 int rd, int rs, int rt)
4092 {
4093 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4094 && opc != OPC_DADD && opc != OPC_DSUB) {
4095 /*
4096 * If no destination, treat it as a NOP.
4097 * For add & sub, we must generate the overflow exception when needed.
4098 */
4099 return;
4100 }
4101
4102 switch (opc) {
4103 case OPC_ADD:
4104 {
4105 TCGv t0 = tcg_temp_local_new();
4106 TCGv t1 = tcg_temp_new();
4107 TCGv t2 = tcg_temp_new();
4108 TCGLabel *l1 = gen_new_label();
4109
4110 gen_load_gpr(t1, rs);
4111 gen_load_gpr(t2, rt);
4112 tcg_gen_add_tl(t0, t1, t2);
4113 tcg_gen_ext32s_tl(t0, t0);
4114 tcg_gen_xor_tl(t1, t1, t2);
4115 tcg_gen_xor_tl(t2, t0, t2);
4116 tcg_gen_andc_tl(t1, t2, t1);
4117 tcg_temp_free(t2);
4118 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4119 tcg_temp_free(t1);
4120 /* operands of same sign, result different sign */
4121 generate_exception(ctx, EXCP_OVERFLOW);
4122 gen_set_label(l1);
4123 gen_store_gpr(t0, rd);
4124 tcg_temp_free(t0);
4125 }
4126 break;
4127 case OPC_ADDU:
4128 if (rs != 0 && rt != 0) {
4129 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4130 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4131 } else if (rs == 0 && rt != 0) {
4132 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4133 } else if (rs != 0 && rt == 0) {
4134 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4135 } else {
4136 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4137 }
4138 break;
4139 case OPC_SUB:
4140 {
4141 TCGv t0 = tcg_temp_local_new();
4142 TCGv t1 = tcg_temp_new();
4143 TCGv t2 = tcg_temp_new();
4144 TCGLabel *l1 = gen_new_label();
4145
4146 gen_load_gpr(t1, rs);
4147 gen_load_gpr(t2, rt);
4148 tcg_gen_sub_tl(t0, t1, t2);
4149 tcg_gen_ext32s_tl(t0, t0);
4150 tcg_gen_xor_tl(t2, t1, t2);
4151 tcg_gen_xor_tl(t1, t0, t1);
4152 tcg_gen_and_tl(t1, t1, t2);
4153 tcg_temp_free(t2);
4154 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4155 tcg_temp_free(t1);
4156 /*
4157 * operands of different sign, first operand and the result
4158 * of different sign
4159 */
4160 generate_exception(ctx, EXCP_OVERFLOW);
4161 gen_set_label(l1);
4162 gen_store_gpr(t0, rd);
4163 tcg_temp_free(t0);
4164 }
4165 break;
4166 case OPC_SUBU:
4167 if (rs != 0 && rt != 0) {
4168 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4169 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4170 } else if (rs == 0 && rt != 0) {
4171 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4172 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4173 } else if (rs != 0 && rt == 0) {
4174 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4175 } else {
4176 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4177 }
4178 break;
4179 #if defined(TARGET_MIPS64)
4180 case OPC_DADD:
4181 {
4182 TCGv t0 = tcg_temp_local_new();
4183 TCGv t1 = tcg_temp_new();
4184 TCGv t2 = tcg_temp_new();
4185 TCGLabel *l1 = gen_new_label();
4186
4187 gen_load_gpr(t1, rs);
4188 gen_load_gpr(t2, rt);
4189 tcg_gen_add_tl(t0, t1, t2);
4190 tcg_gen_xor_tl(t1, t1, t2);
4191 tcg_gen_xor_tl(t2, t0, t2);
4192 tcg_gen_andc_tl(t1, t2, t1);
4193 tcg_temp_free(t2);
4194 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4195 tcg_temp_free(t1);
4196 /* operands of same sign, result different sign */
4197 generate_exception(ctx, EXCP_OVERFLOW);
4198 gen_set_label(l1);
4199 gen_store_gpr(t0, rd);
4200 tcg_temp_free(t0);
4201 }
4202 break;
4203 case OPC_DADDU:
4204 if (rs != 0 && rt != 0) {
4205 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4206 } else if (rs == 0 && rt != 0) {
4207 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4208 } else if (rs != 0 && rt == 0) {
4209 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4210 } else {
4211 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4212 }
4213 break;
4214 case OPC_DSUB:
4215 {
4216 TCGv t0 = tcg_temp_local_new();
4217 TCGv t1 = tcg_temp_new();
4218 TCGv t2 = tcg_temp_new();
4219 TCGLabel *l1 = gen_new_label();
4220
4221 gen_load_gpr(t1, rs);
4222 gen_load_gpr(t2, rt);
4223 tcg_gen_sub_tl(t0, t1, t2);
4224 tcg_gen_xor_tl(t2, t1, t2);
4225 tcg_gen_xor_tl(t1, t0, t1);
4226 tcg_gen_and_tl(t1, t1, t2);
4227 tcg_temp_free(t2);
4228 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4229 tcg_temp_free(t1);
4230 /* operands of different sign, first operand and result different sign */
4231 generate_exception(ctx, EXCP_OVERFLOW);
4232 gen_set_label(l1);
4233 gen_store_gpr(t0, rd);
4234 tcg_temp_free(t0);
4235 }
4236 break;
4237 case OPC_DSUBU:
4238 if (rs != 0 && rt != 0) {
4239 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4240 } else if (rs == 0 && rt != 0) {
4241 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4242 } else if (rs != 0 && rt == 0) {
4243 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4244 } else {
4245 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4246 }
4247 break;
4248 #endif
4249 case OPC_MUL:
4250 if (likely(rs != 0 && rt != 0)) {
4251 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4252 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4253 } else {
4254 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4255 }
4256 break;
4257 }
4258 }
4259
4260 /* Conditional move */
4261 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4262 int rd, int rs, int rt)
4263 {
4264 TCGv t0, t1, t2;
4265
4266 if (rd == 0) {
4267 /* If no destination, treat it as a NOP. */
4268 return;
4269 }
4270
4271 t0 = tcg_temp_new();
4272 gen_load_gpr(t0, rt);
4273 t1 = tcg_const_tl(0);
4274 t2 = tcg_temp_new();
4275 gen_load_gpr(t2, rs);
4276 switch (opc) {
4277 case OPC_MOVN:
4278 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4279 break;
4280 case OPC_MOVZ:
4281 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4282 break;
4283 case OPC_SELNEZ:
4284 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4285 break;
4286 case OPC_SELEQZ:
4287 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4288 break;
4289 }
4290 tcg_temp_free(t2);
4291 tcg_temp_free(t1);
4292 tcg_temp_free(t0);
4293 }
4294
4295 /* Logic */
4296 static void gen_logic(DisasContext *ctx, uint32_t opc,
4297 int rd, int rs, int rt)
4298 {
4299 if (rd == 0) {
4300 /* If no destination, treat it as a NOP. */
4301 return;
4302 }
4303
4304 switch (opc) {
4305 case OPC_AND:
4306 if (likely(rs != 0 && rt != 0)) {
4307 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4308 } else {
4309 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4310 }
4311 break;
4312 case OPC_NOR:
4313 if (rs != 0 && rt != 0) {
4314 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4315 } else if (rs == 0 && rt != 0) {
4316 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4317 } else if (rs != 0 && rt == 0) {
4318 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4319 } else {
4320 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4321 }
4322 break;
4323 case OPC_OR:
4324 if (likely(rs != 0 && rt != 0)) {
4325 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4326 } else if (rs == 0 && rt != 0) {
4327 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4328 } else if (rs != 0 && rt == 0) {
4329 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4330 } else {
4331 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4332 }
4333 break;
4334 case OPC_XOR:
4335 if (likely(rs != 0 && rt != 0)) {
4336 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4337 } else if (rs == 0 && rt != 0) {
4338 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4339 } else if (rs != 0 && rt == 0) {
4340 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4341 } else {
4342 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4343 }
4344 break;
4345 }
4346 }
4347
4348 /* Set on lower than */
4349 static void gen_slt(DisasContext *ctx, uint32_t opc,
4350 int rd, int rs, int rt)
4351 {
4352 TCGv t0, t1;
4353
4354 if (rd == 0) {
4355 /* If no destination, treat it as a NOP. */
4356 return;
4357 }
4358
4359 t0 = tcg_temp_new();
4360 t1 = tcg_temp_new();
4361 gen_load_gpr(t0, rs);
4362 gen_load_gpr(t1, rt);
4363 switch (opc) {
4364 case OPC_SLT:
4365 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4366 break;
4367 case OPC_SLTU:
4368 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4369 break;
4370 }
4371 tcg_temp_free(t0);
4372 tcg_temp_free(t1);
4373 }
4374
4375 /* Shifts */
4376 static void gen_shift(DisasContext *ctx, uint32_t opc,
4377 int rd, int rs, int rt)
4378 {
4379 TCGv t0, t1;
4380
4381 if (rd == 0) {
4382 /*
4383 * If no destination, treat it as a NOP.
4384 * For add & sub, we must generate the overflow exception when needed.
4385 */
4386 return;
4387 }
4388
4389 t0 = tcg_temp_new();
4390 t1 = tcg_temp_new();
4391 gen_load_gpr(t0, rs);
4392 gen_load_gpr(t1, rt);
4393 switch (opc) {
4394 case OPC_SLLV:
4395 tcg_gen_andi_tl(t0, t0, 0x1f);
4396 tcg_gen_shl_tl(t0, t1, t0);
4397 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4398 break;
4399 case OPC_SRAV:
4400 tcg_gen_andi_tl(t0, t0, 0x1f);
4401 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4402 break;
4403 case OPC_SRLV:
4404 tcg_gen_ext32u_tl(t1, t1);
4405 tcg_gen_andi_tl(t0, t0, 0x1f);
4406 tcg_gen_shr_tl(t0, t1, t0);
4407 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4408 break;
4409 case OPC_ROTRV:
4410 {
4411 TCGv_i32 t2 = tcg_temp_new_i32();
4412 TCGv_i32 t3 = tcg_temp_new_i32();
4413
4414 tcg_gen_trunc_tl_i32(t2, t0);
4415 tcg_gen_trunc_tl_i32(t3, t1);
4416 tcg_gen_andi_i32(t2, t2, 0x1f);
4417 tcg_gen_rotr_i32(t2, t3, t2);
4418 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4419 tcg_temp_free_i32(t2);
4420 tcg_temp_free_i32(t3);
4421 }
4422 break;
4423 #if defined(TARGET_MIPS64)
4424 case OPC_DSLLV:
4425 tcg_gen_andi_tl(t0, t0, 0x3f);
4426 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4427 break;
4428 case OPC_DSRAV:
4429 tcg_gen_andi_tl(t0, t0, 0x3f);
4430 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4431 break;
4432 case OPC_DSRLV:
4433 tcg_gen_andi_tl(t0, t0, 0x3f);
4434 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4435 break;
4436 case OPC_DROTRV:
4437 tcg_gen_andi_tl(t0, t0, 0x3f);
4438 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4439 break;
4440 #endif
4441 }
4442 tcg_temp_free(t0);
4443 tcg_temp_free(t1);
4444 }
4445
4446 #if defined(TARGET_MIPS64)
4447 /* Copy GPR to and from TX79 HI1/LO1 register. */
4448 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4449 {
4450 if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4451 /* Treat as NOP. */
4452 return;
4453 }
4454
4455 switch (opc) {
4456 case MMI_OPC_MFHI1:
4457 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4458 break;
4459 case MMI_OPC_MFLO1:
4460 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4461 break;
4462 case MMI_OPC_MTHI1:
4463 if (reg != 0) {
4464 tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4465 } else {
4466 tcg_gen_movi_tl(cpu_HI[1], 0);
4467 }
4468 break;
4469 case MMI_OPC_MTLO1:
4470 if (reg != 0) {
4471 tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4472 } else {
4473 tcg_gen_movi_tl(cpu_LO[1], 0);
4474 }
4475 break;
4476 default:
4477 MIPS_INVAL("mfthilo1 TX79");
4478 generate_exception_end(ctx, EXCP_RI);
4479 break;
4480 }
4481 }
4482 #endif
4483
4484 /* Arithmetic on HI/LO registers */
4485 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4486 {
4487 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4488 /* Treat as NOP. */
4489 return;
4490 }
4491
4492 if (acc != 0) {
4493 check_dsp(ctx);
4494 }
4495
4496 switch (opc) {
4497 case OPC_MFHI:
4498 #if defined(TARGET_MIPS64)
4499 if (acc != 0) {
4500 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4501 } else
4502 #endif
4503 {
4504 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4505 }
4506 break;
4507 case OPC_MFLO:
4508 #if defined(TARGET_MIPS64)
4509 if (acc != 0) {
4510 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4511 } else
4512 #endif
4513 {
4514 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4515 }
4516 break;
4517 case OPC_MTHI:
4518 if (reg != 0) {
4519 #if defined(TARGET_MIPS64)
4520 if (acc != 0) {
4521 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4522 } else
4523 #endif
4524 {
4525 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4526 }
4527 } else {
4528 tcg_gen_movi_tl(cpu_HI[acc], 0);
4529 }
4530 break;
4531 case OPC_MTLO:
4532 if (reg != 0) {
4533 #if defined(TARGET_MIPS64)
4534 if (acc != 0) {
4535 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4536 } else
4537 #endif
4538 {
4539 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4540 }
4541 } else {
4542 tcg_gen_movi_tl(cpu_LO[acc], 0);
4543 }
4544 break;
4545 }
4546 }
4547
4548 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4549 TCGMemOp memop)
4550 {
4551 TCGv t0 = tcg_const_tl(addr);
4552 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4553 gen_store_gpr(t0, reg);
4554 tcg_temp_free(t0);
4555 }
4556
4557 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4558 int rs)
4559 {
4560 target_long offset;
4561 target_long addr;
4562
4563 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4564 case OPC_ADDIUPC:
4565 if (rs != 0) {
4566 offset = sextract32(ctx->opcode << 2, 0, 21);
4567 addr = addr_add(ctx, pc, offset);
4568 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4569 }
4570 break;
4571 case R6_OPC_LWPC:
4572 offset = sextract32(ctx->opcode << 2, 0, 21);
4573 addr = addr_add(ctx, pc, offset);
4574 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4575 break;
4576 #if defined(TARGET_MIPS64)
4577 case OPC_LWUPC:
4578 check_mips_64(ctx);
4579 offset = sextract32(ctx->opcode << 2, 0, 21);
4580 addr = addr_add(ctx, pc, offset);
4581 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4582 break;
4583 #endif
4584 default:
4585 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4586 case OPC_AUIPC:
4587 if (rs != 0) {
4588 offset = sextract32(ctx->opcode, 0, 16) << 16;
4589 addr = addr_add(ctx, pc, offset);
4590 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4591 }
4592 break;
4593 case OPC_ALUIPC:
4594 if (rs != 0) {
4595 offset = sextract32(ctx->opcode, 0, 16) << 16;
4596 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4597 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4598 }
4599 break;
4600 #if defined(TARGET_MIPS64)
4601 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4602 case R6_OPC_LDPC + (1 << 16):
4603 case R6_OPC_LDPC + (2 << 16):
4604 case R6_OPC_LDPC + (3 << 16):
4605 check_mips_64(ctx);
4606 offset = sextract32(ctx->opcode << 3, 0, 21);
4607 addr = addr_add(ctx, (pc & ~0x7), offset);
4608 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4609 break;
4610 #endif
4611 default:
4612 MIPS_INVAL("OPC_PCREL");
4613 generate_exception_end(ctx, EXCP_RI);
4614 break;
4615 }
4616 break;
4617 }
4618 }
4619
4620 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4621 {
4622 TCGv t0, t1;
4623
4624 if (rd == 0) {
4625 /* Treat as NOP. */
4626 return;
4627 }
4628
4629 t0 = tcg_temp_new();
4630 t1 = tcg_temp_new();
4631
4632 gen_load_gpr(t0, rs);
4633 gen_load_gpr(t1, rt);
4634
4635 switch (opc) {
4636 case R6_OPC_DIV:
4637 {
4638 TCGv t2 = tcg_temp_new();
4639 TCGv t3 = tcg_temp_new();
4640 tcg_gen_ext32s_tl(t0, t0);
4641 tcg_gen_ext32s_tl(t1, t1);
4642 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4643 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4644 tcg_gen_and_tl(t2, t2, t3);
4645 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4646 tcg_gen_or_tl(t2, t2, t3);
4647 tcg_gen_movi_tl(t3, 0);
4648 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4649 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4650 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4651 tcg_temp_free(t3);
4652 tcg_temp_free(t2);
4653 }
4654 break;
4655 case R6_OPC_MOD:
4656 {
4657 TCGv t2 = tcg_temp_new();
4658 TCGv t3 = tcg_temp_new();
4659 tcg_gen_ext32s_tl(t0, t0);
4660 tcg_gen_ext32s_tl(t1, t1);
4661 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4662 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4663 tcg_gen_and_tl(t2, t2, t3);
4664 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4665 tcg_gen_or_tl(t2, t2, t3);
4666 tcg_gen_movi_tl(t3, 0);
4667 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4668 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4669 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4670 tcg_temp_free(t3);
4671 tcg_temp_free(t2);
4672 }
4673 break;
4674 case R6_OPC_DIVU:
4675 {
4676 TCGv t2 = tcg_const_tl(0);
4677 TCGv t3 = tcg_const_tl(1);
4678 tcg_gen_ext32u_tl(t0, t0);
4679 tcg_gen_ext32u_tl(t1, t1);
4680 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4681 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4682 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4683 tcg_temp_free(t3);
4684 tcg_temp_free(t2);
4685 }
4686 break;
4687 case R6_OPC_MODU:
4688 {
4689 TCGv t2 = tcg_const_tl(0);
4690 TCGv t3 = tcg_const_tl(1);
4691 tcg_gen_ext32u_tl(t0, t0);
4692 tcg_gen_ext32u_tl(t1, t1);
4693 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4694 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4695 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4696 tcg_temp_free(t3);
4697 tcg_temp_free(t2);
4698 }
4699 break;
4700 case R6_OPC_MUL:
4701 {
4702 TCGv_i32 t2 = tcg_temp_new_i32();
4703 TCGv_i32 t3 = tcg_temp_new_i32();
4704 tcg_gen_trunc_tl_i32(t2, t0);
4705 tcg_gen_trunc_tl_i32(t3, t1);
4706 tcg_gen_mul_i32(t2, t2, t3);
4707 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4708 tcg_temp_free_i32(t2);
4709 tcg_temp_free_i32(t3);
4710 }
4711 break;
4712 case R6_OPC_MUH:
4713 {
4714 TCGv_i32 t2 = tcg_temp_new_i32();
4715 TCGv_i32 t3 = tcg_temp_new_i32();
4716 tcg_gen_trunc_tl_i32(t2, t0);
4717 tcg_gen_trunc_tl_i32(t3, t1);
4718 tcg_gen_muls2_i32(t2, t3, t2, t3);
4719 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4720 tcg_temp_free_i32(t2);
4721 tcg_temp_free_i32(t3);
4722 }
4723 break;
4724 case R6_OPC_MULU:
4725 {
4726 TCGv_i32 t2 = tcg_temp_new_i32();
4727 TCGv_i32 t3 = tcg_temp_new_i32();
4728 tcg_gen_trunc_tl_i32(t2, t0);
4729 tcg_gen_trunc_tl_i32(t3, t1);
4730 tcg_gen_mul_i32(t2, t2, t3);
4731 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4732 tcg_temp_free_i32(t2);
4733 tcg_temp_free_i32(t3);
4734 }
4735 break;
4736 case R6_OPC_MUHU:
4737 {
4738 TCGv_i32 t2 = tcg_temp_new_i32();
4739 TCGv_i32 t3 = tcg_temp_new_i32();
4740 tcg_gen_trunc_tl_i32(t2, t0);
4741 tcg_gen_trunc_tl_i32(t3, t1);
4742 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4743 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4744 tcg_temp_free_i32(t2);
4745 tcg_temp_free_i32(t3);
4746 }
4747 break;
4748 #if defined(TARGET_MIPS64)
4749 case R6_OPC_DDIV:
4750 {
4751 TCGv t2 = tcg_temp_new();
4752 TCGv t3 = tcg_temp_new();
4753 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4754 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4755 tcg_gen_and_tl(t2, t2, t3);
4756 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4757 tcg_gen_or_tl(t2, t2, t3);
4758 tcg_gen_movi_tl(t3, 0);
4759 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4760 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4761 tcg_temp_free(t3);
4762 tcg_temp_free(t2);
4763 }
4764 break;
4765 case R6_OPC_DMOD:
4766 {
4767 TCGv t2 = tcg_temp_new();
4768 TCGv t3 = tcg_temp_new();
4769 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4770 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4771 tcg_gen_and_tl(t2, t2, t3);
4772 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4773 tcg_gen_or_tl(t2, t2, t3);
4774 tcg_gen_movi_tl(t3, 0);
4775 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4776 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4777 tcg_temp_free(t3);
4778 tcg_temp_free(t2);
4779 }
4780 break;
4781 case R6_OPC_DDIVU:
4782 {
4783 TCGv t2 = tcg_const_tl(0);
4784 TCGv t3 = tcg_const_tl(1);
4785 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4786 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4787 tcg_temp_free(t3);
4788 tcg_temp_free(t2);
4789 }
4790 break;
4791 case R6_OPC_DMODU:
4792 {
4793 TCGv t2 = tcg_const_tl(0);
4794 TCGv t3 = tcg_const_tl(1);
4795 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4796 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4797 tcg_temp_free(t3);
4798 tcg_temp_free(t2);
4799 }
4800 break;
4801 case R6_OPC_DMUL:
4802 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4803 break;
4804 case R6_OPC_DMUH:
4805 {
4806 TCGv t2 = tcg_temp_new();
4807 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4808 tcg_temp_free(t2);
4809 }
4810 break;
4811 case R6_OPC_DMULU:
4812 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4813 break;
4814 case R6_OPC_DMUHU:
4815 {
4816 TCGv t2 = tcg_temp_new();
4817 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4818 tcg_temp_free(t2);
4819 }
4820 break;
4821 #endif
4822 default:
4823 MIPS_INVAL("r6 mul/div");
4824 generate_exception_end(ctx, EXCP_RI);
4825 goto out;
4826 }
4827 out:
4828 tcg_temp_free(t0);
4829 tcg_temp_free(t1);
4830 }
4831
4832 #if defined(TARGET_MIPS64)
4833 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4834 {
4835 TCGv t0, t1;
4836
4837 t0 = tcg_temp_new();
4838 t1 = tcg_temp_new();
4839
4840 gen_load_gpr(t0, rs);
4841 gen_load_gpr(t1, rt);
4842
4843 switch (opc) {
4844 case MMI_OPC_DIV1:
4845 {
4846 TCGv t2 = tcg_temp_new();
4847 TCGv t3 = tcg_temp_new();
4848 tcg_gen_ext32s_tl(t0, t0);
4849 tcg_gen_ext32s_tl(t1, t1);
4850 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4851 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4852 tcg_gen_and_tl(t2, t2, t3);
4853 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4854 tcg_gen_or_tl(t2, t2, t3);
4855 tcg_gen_movi_tl(t3, 0);
4856 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4857 tcg_gen_div_tl(cpu_LO[1], t0, t1);
4858 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4859 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4860 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4861 tcg_temp_free(t3);
4862 tcg_temp_free(t2);
4863 }
4864 break;
4865 case MMI_OPC_DIVU1:
4866 {
4867 TCGv t2 = tcg_const_tl(0);
4868 TCGv t3 = tcg_const_tl(1);
4869 tcg_gen_ext32u_tl(t0, t0);
4870 tcg_gen_ext32u_tl(t1, t1);
4871 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4872 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4873 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4874 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4875 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4876 tcg_temp_free(t3);
4877 tcg_temp_free(t2);
4878 }
4879 break;
4880 default:
4881 MIPS_INVAL("div1 TX79");
4882 generate_exception_end(ctx, EXCP_RI);
4883 goto out;
4884 }
4885 out:
4886 tcg_temp_free(t0);
4887 tcg_temp_free(t1);
4888 }
4889 #endif
4890
4891 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4892 int acc, int rs, int rt)
4893 {
4894 TCGv t0, t1;
4895
4896 t0 = tcg_temp_new();
4897 t1 = tcg_temp_new();
4898
4899 gen_load_gpr(t0, rs);
4900 gen_load_gpr(t1, rt);
4901
4902 if (acc != 0) {
4903 check_dsp(ctx);
4904 }
4905
4906 switch (opc) {
4907 case OPC_DIV:
4908 {
4909 TCGv t2 = tcg_temp_new();
4910 TCGv t3 = tcg_temp_new();
4911 tcg_gen_ext32s_tl(t0, t0);
4912 tcg_gen_ext32s_tl(t1, t1);
4913 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4914 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4915 tcg_gen_and_tl(t2, t2, t3);
4916 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4917 tcg_gen_or_tl(t2, t2, t3);
4918 tcg_gen_movi_tl(t3, 0);
4919 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4920 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4921 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4922 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4923 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4924 tcg_temp_free(t3);
4925 tcg_temp_free(t2);
4926 }
4927 break;
4928 case OPC_DIVU:
4929 {
4930 TCGv t2 = tcg_const_tl(0);
4931 TCGv t3 = tcg_const_tl(1);
4932 tcg_gen_ext32u_tl(t0, t0);
4933 tcg_gen_ext32u_tl(t1, t1);
4934 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4935 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4936 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4937 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4938 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4939 tcg_temp_free(t3);
4940 tcg_temp_free(t2);
4941 }
4942 break;
4943 case OPC_MULT:
4944 {
4945 TCGv_i32 t2 = tcg_temp_new_i32();
4946 TCGv_i32 t3 = tcg_temp_new_i32();
4947 tcg_gen_trunc_tl_i32(t2, t0);
4948 tcg_gen_trunc_tl_i32(t3, t1);
4949 tcg_gen_muls2_i32(t2, t3, t2, t3);
4950 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4951 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4952 tcg_temp_free_i32(t2);
4953 tcg_temp_free_i32(t3);
4954 }
4955 break;
4956 case OPC_MULTU:
4957 {
4958 TCGv_i32 t2 = tcg_temp_new_i32();
4959 TCGv_i32 t3 = tcg_temp_new_i32();
4960 tcg_gen_trunc_tl_i32(t2, t0);
4961 tcg_gen_trunc_tl_i32(t3, t1);
4962 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4963 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4964 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4965 tcg_temp_free_i32(t2);
4966 tcg_temp_free_i32(t3);
4967 }
4968 break;
4969 #if defined(TARGET_MIPS64)
4970 case OPC_DDIV:
4971 {
4972 TCGv t2 = tcg_temp_new();
4973 TCGv t3 = tcg_temp_new();
4974 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4975 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4976 tcg_gen_and_tl(t2, t2, t3);
4977 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4978 tcg_gen_or_tl(t2, t2, t3);
4979 tcg_gen_movi_tl(t3, 0);
4980 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4981 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4982 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4983 tcg_temp_free(t3);
4984 tcg_temp_free(t2);
4985 }
4986 break;
4987 case OPC_DDIVU:
4988 {
4989 TCGv t2 = tcg_const_tl(0);
4990 TCGv t3 = tcg_const_tl(1);
4991 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4992 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4993 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4994 tcg_temp_free(t3);
4995 tcg_temp_free(t2);
4996 }
4997 break;
4998 case OPC_DMULT:
4999 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5000 break;
5001 case OPC_DMULTU:
5002 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5003 break;
5004 #endif
5005 case OPC_MADD:
5006 {
5007 TCGv_i64 t2 = tcg_temp_new_i64();
5008 TCGv_i64 t3 = tcg_temp_new_i64();
5009
5010 tcg_gen_ext_tl_i64(t2, t0);
5011 tcg_gen_ext_tl_i64(t3, t1);
5012 tcg_gen_mul_i64(t2, t2, t3);
5013 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5014 tcg_gen_add_i64(t2, t2, t3);
5015 tcg_temp_free_i64(t3);
5016 gen_move_low32(cpu_LO[acc], t2);
5017 gen_move_high32(cpu_HI[acc], t2);
5018 tcg_temp_free_i64(t2);
5019 }
5020 break;
5021 case OPC_MADDU:
5022 {
5023 TCGv_i64 t2 = tcg_temp_new_i64();
5024 TCGv_i64 t3 = tcg_temp_new_i64();
5025
5026 tcg_gen_ext32u_tl(t0, t0);
5027 tcg_gen_ext32u_tl(t1, t1);
5028 tcg_gen_extu_tl_i64(t2, t0);
5029 tcg_gen_extu_tl_i64(t3, t1);
5030 tcg_gen_mul_i64(t2, t2, t3);
5031 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5032 tcg_gen_add_i64(t2, t2, t3);
5033 tcg_temp_free_i64(t3);
5034 gen_move_low32(cpu_LO[acc], t2);
5035 gen_move_high32(cpu_HI[acc], t2);
5036 tcg_temp_free_i64(t2);
5037 }
5038 break;
5039 case OPC_MSUB:
5040 {
5041 TCGv_i64 t2 = tcg_temp_new_i64();
5042 TCGv_i64 t3 = tcg_temp_new_i64();
5043
5044 tcg_gen_ext_tl_i64(t2, t0);
5045 tcg_gen_ext_tl_i64(t3, t1);
5046 tcg_gen_mul_i64(t2, t2, t3);
5047 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5048 tcg_gen_sub_i64(t2, t3, t2);
5049 tcg_temp_free_i64(t3);
5050 gen_move_low32(cpu_LO[acc], t2);
5051 gen_move_high32(cpu_HI[acc], t2);
5052 tcg_temp_free_i64(t2);
5053 }
5054 break;
5055 case OPC_MSUBU:
5056 {
5057 TCGv_i64 t2 = tcg_temp_new_i64();
5058 TCGv_i64 t3 = tcg_temp_new_i64();
5059
5060 tcg_gen_ext32u_tl(t0, t0);
5061 tcg_gen_ext32u_tl(t1, t1);
5062 tcg_gen_extu_tl_i64(t2, t0);
5063 tcg_gen_extu_tl_i64(t3, t1);
5064 tcg_gen_mul_i64(t2, t2, t3);
5065 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5066 tcg_gen_sub_i64(t2, t3, t2);
5067 tcg_temp_free_i64(t3);
5068 gen_move_low32(cpu_LO[acc], t2);
5069 gen_move_high32(cpu_HI[acc], t2);
5070 tcg_temp_free_i64(t2);
5071 }
5072 break;
5073 default:
5074 MIPS_INVAL("mul/div");
5075 generate_exception_end(ctx, EXCP_RI);
5076 goto out;
5077 }
5078 out:
5079 tcg_temp_free(t0);
5080 tcg_temp_free(t1);
5081 }
5082
5083 /*
5084 * These MULT[U] and MADD[U] instructions implemented in for example
5085 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5086 * architectures are special three-operand variants with the syntax
5087 *
5088 * MULT[U][1] rd, rs, rt
5089 *
5090 * such that
5091 *
5092 * (rd, LO, HI) <- rs * rt
5093 *
5094 * and
5095 *
5096 * MADD[U][1] rd, rs, rt
5097 *
5098 * such that
5099 *
5100 * (rd, LO, HI) <- (LO, HI) + rs * rt
5101 *
5102 * where the low-order 32-bits of the result is placed into both the
5103 * GPR rd and the special register LO. The high-order 32-bits of the
5104 * result is placed into the special register HI.
5105 *
5106 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5107 * which is the zero register that always reads as 0.
5108 */
5109 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5110 int rd, int rs, int rt)
5111 {
5112 TCGv t0 = tcg_temp_new();
5113 TCGv t1 = tcg_temp_new();
5114 int acc = 0;
5115
5116 gen_load_gpr(t0, rs);
5117 gen_load_gpr(t1, rt);
5118
5119 switch (opc) {
5120 case MMI_OPC_MULT1:
5121 acc = 1;
5122 /* Fall through */
5123 case OPC_MULT:
5124 {
5125 TCGv_i32 t2 = tcg_temp_new_i32();
5126 TCGv_i32 t3 = tcg_temp_new_i32();
5127 tcg_gen_trunc_tl_i32(t2, t0);
5128 tcg_gen_trunc_tl_i32(t3, t1);
5129 tcg_gen_muls2_i32(t2, t3, t2, t3);
5130 if (rd) {
5131 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5132 }
5133 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5134 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5135 tcg_temp_free_i32(t2);
5136 tcg_temp_free_i32(t3);
5137 }
5138 break;
5139 case MMI_OPC_MULTU1:
5140 acc = 1;
5141 /* Fall through */
5142 case OPC_MULTU:
5143 {
5144 TCGv_i32 t2 = tcg_temp_new_i32();
5145 TCGv_i32 t3 = tcg_temp_new_i32();
5146 tcg_gen_trunc_tl_i32(t2, t0);
5147 tcg_gen_trunc_tl_i32(t3, t1);
5148 tcg_gen_mulu2_i32(t2, t3, t2, t3);
5149 if (rd) {
5150 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5151 }
5152 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5153 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5154 tcg_temp_free_i32(t2);
5155 tcg_temp_free_i32(t3);
5156 }
5157 break;
5158 case MMI_OPC_MADD1:
5159 acc = 1;
5160 /* Fall through */
5161 case MMI_OPC_MADD:
5162 {
5163 TCGv_i64 t2 = tcg_temp_new_i64();
5164 TCGv_i64 t3 = tcg_temp_new_i64();
5165
5166 tcg_gen_ext_tl_i64(t2, t0);
5167 tcg_gen_ext_tl_i64(t3, t1);
5168 tcg_gen_mul_i64(t2, t2, t3);
5169 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5170 tcg_gen_add_i64(t2, t2, t3);
5171 tcg_temp_free_i64(t3);
5172 gen_move_low32(cpu_LO[acc], t2);
5173 gen_move_high32(cpu_HI[acc], t2);
5174 if (rd) {
5175 gen_move_low32(cpu_gpr[rd], t2);
5176 }
5177 tcg_temp_free_i64(t2);
5178 }
5179 break;
5180 case MMI_OPC_MADDU1:
5181 acc = 1;
5182 /* Fall through */
5183 case MMI_OPC_MADDU:
5184 {
5185 TCGv_i64 t2 = tcg_temp_new_i64();
5186 TCGv_i64 t3 = tcg_temp_new_i64();
5187
5188 tcg_gen_ext32u_tl(t0, t0);
5189 tcg_gen_ext32u_tl(t1, t1);
5190 tcg_gen_extu_tl_i64(t2, t0);
5191 tcg_gen_extu_tl_i64(t3, t1);
5192 tcg_gen_mul_i64(t2, t2, t3);
5193 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5194 tcg_gen_add_i64(t2, t2, t3);
5195 tcg_temp_free_i64(t3);
5196 gen_move_low32(cpu_LO[acc], t2);
5197 gen_move_high32(cpu_HI[acc], t2);
5198 if (rd) {
5199 gen_move_low32(cpu_gpr[rd], t2);
5200 }
5201 tcg_temp_free_i64(t2);
5202 }
5203 break;
5204 default:
5205 MIPS_INVAL("mul/madd TXx9");
5206 generate_exception_end(ctx, EXCP_RI);
5207 goto out;
5208 }
5209
5210 out:
5211 tcg_temp_free(t0);
5212 tcg_temp_free(t1);
5213 }
5214
5215 static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc,
5216 int rd, int rs, int rt)
5217 {
5218 TCGv t0 = tcg_temp_new();
5219 TCGv t1 = tcg_temp_new();
5220
5221 gen_load_gpr(t0, rs);
5222 gen_load_gpr(t1, rt);
5223
5224 switch (opc) {
5225 case OPC_VR54XX_MULS:
5226 gen_helper_muls(t0, cpu_env, t0, t1);
5227 break;
5228 case OPC_VR54XX_MULSU:
5229 gen_helper_mulsu(t0, cpu_env, t0, t1);
5230 break;
5231 case OPC_VR54XX_MACC:
5232 gen_helper_macc(t0, cpu_env, t0, t1);
5233 break;
5234 case OPC_VR54XX_MACCU:
5235 gen_helper_maccu(t0, cpu_env, t0, t1);
5236 break;
5237 case OPC_VR54XX_MSAC:
5238 gen_helper_msac(t0, cpu_env, t0, t1);
5239 break;
5240 case OPC_VR54XX_MSACU:
5241 gen_helper_msacu(t0, cpu_env, t0, t1);
5242 break;
5243 case OPC_VR54XX_MULHI:
5244 gen_helper_mulhi(t0, cpu_env, t0, t1);
5245 break;
5246 case OPC_VR54XX_MULHIU:
5247 gen_helper_mulhiu(t0, cpu_env, t0, t1);
5248 break;
5249 case OPC_VR54XX_MULSHI:
5250 gen_helper_mulshi(t0, cpu_env, t0, t1);
5251 break;
5252 case OPC_VR54XX_MULSHIU:
5253 gen_helper_mulshiu(t0, cpu_env, t0, t1);
5254 break;
5255 case OPC_VR54XX_MACCHI:
5256 gen_helper_macchi(t0, cpu_env, t0, t1);
5257 break;
5258 case OPC_VR54XX_MACCHIU:
5259 gen_helper_macchiu(t0, cpu_env, t0, t1);
5260 break;
5261 case OPC_VR54XX_MSACHI:
5262 gen_helper_msachi(t0, cpu_env, t0, t1);
5263 break;
5264 case OPC_VR54XX_MSACHIU:
5265 gen_helper_msachiu(t0, cpu_env, t0, t1);
5266 break;
5267 default:
5268 MIPS_INVAL("mul vr54xx");
5269 generate_exception_end(ctx, EXCP_RI);
5270 goto out;
5271 }
5272 gen_store_gpr(t0, rd);
5273
5274 out:
5275 tcg_temp_free(t0);
5276 tcg_temp_free(t1);
5277 }
5278
5279 static void gen_cl(DisasContext *ctx, uint32_t opc,
5280 int rd, int rs)
5281 {
5282 TCGv t0;
5283
5284 if (rd == 0) {
5285 /* Treat as NOP. */
5286 return;
5287 }
5288 t0 = cpu_gpr[rd];
5289 gen_load_gpr(t0, rs);
5290
5291 switch (opc) {
5292 case OPC_CLO:
5293 case R6_OPC_CLO:
5294 #if defined(TARGET_MIPS64)
5295 case OPC_DCLO:
5296 case R6_OPC_DCLO:
5297 #endif
5298 tcg_gen_not_tl(t0, t0);
5299 break;
5300 }
5301
5302 switch (opc) {
5303 case OPC_CLO:
5304 case R6_OPC_CLO:
5305 case OPC_CLZ:
5306 case R6_OPC_CLZ:
5307 tcg_gen_ext32u_tl(t0, t0);
5308 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5309 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5310 break;
5311 #if defined(TARGET_MIPS64)
5312 case OPC_DCLO:
5313 case R6_OPC_DCLO:
5314 case OPC_DCLZ:
5315 case R6_OPC_DCLZ:
5316 tcg_gen_clzi_i64(t0, t0, 64);
5317 break;
5318 #endif
5319 }
5320 }
5321
5322 /* Godson integer instructions */
5323 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5324 int rd, int rs, int rt)
5325 {
5326 TCGv t0, t1;
5327
5328 if (rd == 0) {
5329 /* Treat as NOP. */
5330 return;
5331 }
5332
5333 switch (opc) {
5334 case OPC_MULT_G_2E:
5335 case OPC_MULT_G_2F:
5336 case OPC_MULTU_G_2E:
5337 case OPC_MULTU_G_2F:
5338 #if defined(TARGET_MIPS64)
5339 case OPC_DMULT_G_2E:
5340 case OPC_DMULT_G_2F:
5341 case OPC_DMULTU_G_2E:
5342 case OPC_DMULTU_G_2F:
5343 #endif
5344 t0 = tcg_temp_new();
5345 t1 = tcg_temp_new();
5346 break;
5347 default:
5348 t0 = tcg_temp_local_new();
5349 t1 = tcg_temp_local_new();
5350 break;
5351 }
5352
5353 gen_load_gpr(t0, rs);
5354 gen_load_gpr(t1, rt);
5355
5356 switch (opc) {
5357 case OPC_MULT_G_2E:
5358 case OPC_MULT_G_2F:
5359 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5360 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5361 break;
5362 case OPC_MULTU_G_2E:
5363 case OPC_MULTU_G_2F:
5364 tcg_gen_ext32u_tl(t0, t0);
5365 tcg_gen_ext32u_tl(t1, t1);
5366 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5367 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5368 break;
5369 case OPC_DIV_G_2E:
5370 case OPC_DIV_G_2F:
5371 {
5372 TCGLabel *l1 = gen_new_label();
5373 TCGLabel *l2 = gen_new_label();
5374 TCGLabel *l3 = gen_new_label();
5375 tcg_gen_ext32s_tl(t0, t0);
5376 tcg_gen_ext32s_tl(t1, t1);
5377 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5378 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5379 tcg_gen_br(l3);
5380 gen_set_label(l1);
5381 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5382 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5383 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5384 tcg_gen_br(l3);
5385 gen_set_label(l2);
5386 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5387 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5388 gen_set_label(l3);
5389 }
5390 break;
5391 case OPC_DIVU_G_2E:
5392 case OPC_DIVU_G_2F:
5393 {
5394 TCGLabel *l1 = gen_new_label();
5395 TCGLabel *l2 = gen_new_label();
5396 tcg_gen_ext32u_tl(t0, t0);
5397 tcg_gen_ext32u_tl(t1, t1);
5398 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5399 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5400 tcg_gen_br(l2);
5401 gen_set_label(l1);
5402 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5403 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5404 gen_set_label(l2);
5405 }
5406 break;
5407 case OPC_MOD_G_2E:
5408 case OPC_MOD_G_2F:
5409 {
5410 TCGLabel *l1 = gen_new_label();
5411 TCGLabel *l2 = gen_new_label();
5412 TCGLabel *l3 = gen_new_label();
5413 tcg_gen_ext32u_tl(t0, t0);
5414 tcg_gen_ext32u_tl(t1, t1);
5415 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5416 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5417 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5418 gen_set_label(l1);
5419 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5420 tcg_gen_br(l3);
5421 gen_set_label(l2);
5422 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5423 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5424 gen_set_label(l3);
5425 }
5426 break;
5427 case OPC_MODU_G_2E:
5428 case OPC_MODU_G_2F:
5429 {
5430 TCGLabel *l1 = gen_new_label();
5431 TCGLabel *l2 = gen_new_label();
5432 tcg_gen_ext32u_tl(t0, t0);
5433 tcg_gen_ext32u_tl(t1, t1);
5434 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5435 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5436 tcg_gen_br(l2);
5437 gen_set_label(l1);
5438 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5439 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5440 gen_set_label(l2);
5441 }
5442 break;
5443 #if defined(TARGET_MIPS64)
5444 case OPC_DMULT_G_2E:
5445 case OPC_DMULT_G_2F:
5446 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5447 break;
5448 case OPC_DMULTU_G_2E:
5449 case OPC_DMULTU_G_2F:
5450 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5451 break;
5452 case OPC_DDIV_G_2E:
5453 case OPC_DDIV_G_2F:
5454 {
5455 TCGLabel *l1 = gen_new_label();
5456 TCGLabel *l2 = gen_new_label();
5457 TCGLabel *l3 = gen_new_label();
5458 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5459 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5460 tcg_gen_br(l3);
5461 gen_set_label(l1);
5462 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5463 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5464 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5465 tcg_gen_br(l3);
5466 gen_set_label(l2);
5467 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5468 gen_set_label(l3);
5469 }
5470 break;
5471 case OPC_DDIVU_G_2E:
5472 case OPC_DDIVU_G_2F:
5473 {
5474 TCGLabel *l1 = gen_new_label();
5475 TCGLabel *l2 = gen_new_label();
5476 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5477 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5478 tcg_gen_br(l2);
5479 gen_set_label(l1);
5480 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5481 gen_set_label(l2);
5482 }
5483 break;
5484 case OPC_DMOD_G_2E:
5485 case OPC_DMOD_G_2F:
5486 {
5487 TCGLabel *l1 = gen_new_label();
5488 TCGLabel *l2 = gen_new_label();
5489 TCGLabel *l3 = gen_new_label();
5490 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5491 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5492 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5493 gen_set_label(l1);
5494 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5495 tcg_gen_br(l3);
5496 gen_set_label(l2);
5497 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5498 gen_set_label(l3);
5499 }
5500 break;
5501 case OPC_DMODU_G_2E:
5502 case OPC_DMODU_G_2F:
5503 {
5504 TCGLabel *l1 = gen_new_label();
5505 TCGLabel *l2 = gen_new_label();
5506 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5507 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5508 tcg_gen_br(l2);
5509 gen_set_label(l1);
5510 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5511 gen_set_label(l2);
5512 }
5513 break;
5514 #endif
5515 }
5516
5517 tcg_temp_free(t0);
5518 tcg_temp_free(t1);
5519 }
5520
5521 /* Loongson multimedia instructions */
5522 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5523 {
5524 uint32_t opc, shift_max;
5525 TCGv_i64 t0, t1;
5526
5527 opc = MASK_LMI(ctx->opcode);
5528 switch (opc) {
5529 case OPC_ADD_CP2:
5530 case OPC_SUB_CP2:
5531 case OPC_DADD_CP2:
5532 case OPC_DSUB_CP2:
5533 t0 = tcg_temp_local_new_i64();
5534 t1 = tcg_temp_local_new_i64();
5535 break;
5536 default:
5537 t0 = tcg_temp_new_i64();
5538 t1 = tcg_temp_new_i64();
5539 break;
5540 }
5541
5542 check_cp1_enabled(ctx);
5543 gen_load_fpr64(ctx, t0, rs);
5544 gen_load_fpr64(ctx, t1, rt);
5545
5546 #define LMI_HELPER(UP, LO) \
5547 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5548 #define LMI_HELPER_1(UP, LO) \
5549 case OPC_##UP: gen_helper_##LO(t0, t0); break
5550 #define LMI_DIRECT(UP, LO, OP) \
5551 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5552
5553 switch (opc) {
5554 LMI_HELPER(PADDSH, paddsh);
5555 LMI_HELPER(PADDUSH, paddush);
5556 LMI_HELPER(PADDH, paddh);
5557 LMI_HELPER(PADDW, paddw);
5558 LMI_HELPER(PADDSB, paddsb);
5559 LMI_HELPER(PADDUSB, paddusb);
5560 LMI_HELPER(PADDB, paddb);
5561
5562 LMI_HELPER(PSUBSH, psubsh);
5563 LMI_HELPER(PSUBUSH, psubush);
5564 LMI_HELPER(PSUBH, psubh);
5565 LMI_HELPER(PSUBW, psubw);
5566 LMI_HELPER(PSUBSB, psubsb);
5567 LMI_HELPER(PSUBUSB, psubusb);
5568 LMI_HELPER(PSUBB, psubb);
5569
5570 LMI_HELPER(PSHUFH, pshufh);
5571 LMI_HELPER(PACKSSWH, packsswh);
5572 LMI_HELPER(PACKSSHB, packsshb);
5573 LMI_HELPER(PACKUSHB, packushb);
5574
5575 LMI_HELPER(PUNPCKLHW, punpcklhw);
5576 LMI_HELPER(PUNPCKHHW, punpckhhw);
5577 LMI_HELPER(PUNPCKLBH, punpcklbh);
5578 LMI_HELPER(PUNPCKHBH, punpckhbh);
5579 LMI_HELPER(PUNPCKLWD, punpcklwd);
5580 LMI_HELPER(PUNPCKHWD, punpckhwd);
5581
5582 LMI_HELPER(PAVGH, pavgh);
5583 LMI_HELPER(PAVGB, pavgb);
5584 LMI_HELPER(PMAXSH, pmaxsh);
5585 LMI_HELPER(PMINSH, pminsh);
5586 LMI_HELPER(PMAXUB, pmaxub);
5587 LMI_HELPER(PMINUB, pminub);
5588
5589 LMI_HELPER(PCMPEQW, pcmpeqw);
5590 LMI_HELPER(PCMPGTW, pcmpgtw);
5591 LMI_HELPER(PCMPEQH, pcmpeqh);
5592 LMI_HELPER(PCMPGTH, pcmpgth);
5593 LMI_HELPER(PCMPEQB, pcmpeqb);
5594 LMI_HELPER(PCMPGTB, pcmpgtb);
5595
5596 LMI_HELPER(PSLLW, psllw);
5597 LMI_HELPER(PSLLH, psllh);
5598 LMI_HELPER(PSRLW, psrlw);
5599 LMI_HELPER(PSRLH, psrlh);
5600 LMI_HELPER(PSRAW, psraw);
5601 LMI_HELPER(PSRAH, psrah);
5602
5603 LMI_HELPER(PMULLH, pmullh);
5604 LMI_HELPER(PMULHH, pmulhh);
5605 LMI_HELPER(PMULHUH, pmulhuh);
5606 LMI_HELPER(PMADDHW, pmaddhw);
5607
5608 LMI_HELPER(PASUBUB, pasubub);
5609 LMI_HELPER_1(BIADD, biadd);
5610 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5611
5612 LMI_DIRECT(PADDD, paddd, add);
5613 LMI_DIRECT(PSUBD, psubd, sub);
5614 LMI_DIRECT(XOR_CP2, xor, xor);
5615 LMI_DIRECT(NOR_CP2, nor, nor);
5616 LMI_DIRECT(AND_CP2, and, and);
5617 LMI_DIRECT(OR_CP2, or, or);
5618
5619 case OPC_PANDN:
5620 tcg_gen_andc_i64(t0, t1, t0);
5621 break;
5622
5623 case OPC_PINSRH_0:
5624 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5625 break;
5626 case OPC_PINSRH_1:
5627 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5628 break;
5629 case OPC_PINSRH_2:
5630 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5631 break;
5632 case OPC_PINSRH_3:
5633 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5634 break;
5635
5636 case OPC_PEXTRH:
5637 tcg_gen_andi_i64(t1, t1, 3);
5638 tcg_gen_shli_i64(t1, t1, 4);
5639 tcg_gen_shr_i64(t0, t0, t1);
5640 tcg_gen_ext16u_i64(t0, t0);
5641 break;
5642
5643 case OPC_ADDU_CP2:
5644 tcg_gen_add_i64(t0, t0, t1);
5645 tcg_gen_ext32s_i64(t0, t0);
5646 break;
5647 case OPC_SUBU_CP2:
5648 tcg_gen_sub_i64(t0, t0, t1);
5649 tcg_gen_ext32s_i64(t0, t0);
5650 break;
5651
5652 case OPC_SLL_CP2:
5653 shift_max = 32;
5654 goto do_shift;
5655 case OPC_SRL_CP2:
5656 shift_max = 32;
5657 goto do_shift;
5658 case OPC_SRA_CP2:
5659 shift_max = 32;
5660 goto do_shift;
5661 case OPC_DSLL_CP2:
5662 shift_max = 64;
5663 goto do_shift;
5664 case OPC_DSRL_CP2:
5665 shift_max = 64;
5666 goto do_shift;
5667 case OPC_DSRA_CP2:
5668 shift_max = 64;
5669 goto do_shift;
5670 do_shift:
5671 /* Make sure shift count isn't TCG undefined behaviour. */
5672 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5673
5674 switch (opc) {
5675 case OPC_SLL_CP2:
5676 case OPC_DSLL_CP2:
5677 tcg_gen_shl_i64(t0, t0, t1);
5678 break;
5679 case OPC_SRA_CP2:
5680 case OPC_DSRA_CP2:
5681 /*
5682 * Since SRA is UndefinedResult without sign-extended inputs,
5683 * we can treat SRA and DSRA the same.
5684 */
5685 tcg_gen_sar_i64(t0, t0, t1);
5686 break;
5687 case OPC_SRL_CP2:
5688 /* We want to shift in zeros for SRL; zero-extend first. */
5689 tcg_gen_ext32u_i64(t0, t0);
5690 /* FALLTHRU */
5691 case OPC_DSRL_CP2:
5692 tcg_gen_shr_i64(t0, t0, t1);
5693 break;
5694 }
5695
5696 if (shift_max == 32) {
5697 tcg_gen_ext32s_i64(t0, t0);
5698 }
5699
5700 /* Shifts larger than MAX produce zero. */
5701 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5702 tcg_gen_neg_i64(t1, t1);
5703 tcg_gen_and_i64(t0, t0, t1);
5704 break;
5705
5706 case OPC_ADD_CP2:
5707 case OPC_DADD_CP2:
5708 {
5709 TCGv_i64 t2 = tcg_temp_new_i64();
5710 TCGLabel *lab = gen_new_label();
5711
5712 tcg_gen_mov_i64(t2, t0);
5713 tcg_gen_add_i64(t0, t1, t2);
5714 if (opc == OPC_ADD_CP2) {
5715 tcg_gen_ext32s_i64(t0, t0);
5716 }
5717 tcg_gen_xor_i64(t1, t1, t2);
5718 tcg_gen_xor_i64(t2, t2, t0);
5719 tcg_gen_andc_i64(t1, t2, t1);
5720 tcg_temp_free_i64(t2);
5721 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5722 generate_exception(ctx, EXCP_OVERFLOW);
5723 gen_set_label(lab);
5724 break;
5725 }
5726
5727 case OPC_SUB_CP2:
5728 case OPC_DSUB_CP2:
5729 {
5730 TCGv_i64 t2 = tcg_temp_new_i64();
5731 TCGLabel *lab = gen_new_label();
5732
5733 tcg_gen_mov_i64(t2, t0);
5734 tcg_gen_sub_i64(t0, t1, t2);
5735 if (opc == OPC_SUB_CP2) {
5736 tcg_gen_ext32s_i64(t0, t0);
5737 }
5738 tcg_gen_xor_i64(t1, t1, t2);
5739 tcg_gen_xor_i64(t2, t2, t0);
5740 tcg_gen_and_i64(t1, t1, t2);
5741 tcg_temp_free_i64(t2);
5742 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5743 generate_exception(ctx, EXCP_OVERFLOW);
5744 gen_set_label(lab);
5745 break;
5746 }
5747
5748 case OPC_PMULUW:
5749 tcg_gen_ext32u_i64(t0, t0);
5750 tcg_gen_ext32u_i64(t1, t1);
5751 tcg_gen_mul_i64(t0, t0, t1);
5752 break;
5753
5754 case OPC_SEQU_CP2:
5755 case OPC_SEQ_CP2:
5756 case OPC_SLTU_CP2:
5757 case OPC_SLT_CP2:
5758 case OPC_SLEU_CP2:
5759 case OPC_SLE_CP2:
5760 /*
5761 * ??? Document is unclear: Set FCC[CC]. Does that mean the
5762 * FD field is the CC field?
5763 */
5764 default:
5765 MIPS_INVAL("loongson_cp2");
5766 generate_exception_end(ctx, EXCP_RI);
5767 return;
5768 }
5769
5770 #undef LMI_HELPER
5771 #undef LMI_DIRECT
5772
5773 gen_store_fpr64(ctx, t0, rd);
5774
5775 tcg_temp_free_i64(t0);
5776 tcg_temp_free_i64(t1);
5777 }
5778
5779 /* Traps */
5780 static void gen_trap (DisasContext *ctx, uint32_t opc,
5781 int rs, int rt, int16_t imm)
5782 {
5783 int cond;
5784 TCGv t0 = tcg_temp_new();
5785 TCGv t1 = tcg_temp_new();
5786
5787 cond = 0;
5788 /* Load needed operands */
5789 switch (opc) {
5790 case OPC_TEQ:
5791 case OPC_TGE:
5792 case OPC_TGEU:
5793 case OPC_TLT:
5794 case OPC_TLTU:
5795 case OPC_TNE:
5796 /* Compare two registers */
5797 if (rs != rt) {
5798 gen_load_gpr(t0, rs);
5799 gen_load_gpr(t1, rt);
5800 cond = 1;
5801 }
5802 break;
5803 case OPC_TEQI:
5804 case OPC_TGEI:
5805 case OPC_TGEIU:
5806 case OPC_TLTI:
5807 case OPC_TLTIU:
5808 case OPC_TNEI:
5809 /* Compare register to immediate */
5810 if (rs != 0 || imm != 0) {
5811 gen_load_gpr(t0, rs);
5812 tcg_gen_movi_tl(t1, (int32_t)imm);
5813 cond = 1;
5814 }
5815 break;
5816 }
5817 if (cond == 0) {
5818 switch (opc) {
5819 case OPC_TEQ: /* rs == rs */
5820 case OPC_TEQI: /* r0 == 0 */
5821 case OPC_TGE: /* rs >= rs */
5822 case OPC_TGEI: /* r0 >= 0 */
5823 case OPC_TGEU: /* rs >= rs unsigned */
5824 case OPC_TGEIU: /* r0 >= 0 unsigned */
5825 /* Always trap */
5826 generate_exception_end(ctx, EXCP_TRAP);
5827 break;
5828 case OPC_TLT: /* rs < rs */
5829 case OPC_TLTI: /* r0 < 0 */
5830 case OPC_TLTU: /* rs < rs unsigned */
5831 case OPC_TLTIU: /* r0 < 0 unsigned */
5832 case OPC_TNE: /* rs != rs */
5833 case OPC_TNEI: /* r0 != 0 */
5834 /* Never trap: treat as NOP. */
5835 break;
5836 }
5837 } else {
5838 TCGLabel *l1 = gen_new_label();
5839
5840 switch (opc) {
5841 case OPC_TEQ:
5842 case OPC_TEQI:
5843 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5844 break;
5845 case OPC_TGE:
5846 case OPC_TGEI:
5847 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5848 break;
5849 case OPC_TGEU:
5850 case OPC_TGEIU:
5851 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5852 break;
5853 case OPC_TLT:
5854 case OPC_TLTI:
5855 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5856 break;
5857 case OPC_TLTU:
5858 case OPC_TLTIU:
5859 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5860 break;
5861 case OPC_TNE:
5862 case OPC_TNEI:
5863 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5864 break;
5865 }
5866 generate_exception(ctx, EXCP_TRAP);
5867 gen_set_label(l1);
5868 }
5869 tcg_temp_free(t0);
5870 tcg_temp_free(t1);
5871 }
5872
5873 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5874 {
5875 if (unlikely(ctx->base.singlestep_enabled)) {
5876 return false;
5877 }
5878
5879 #ifndef CONFIG_USER_ONLY
5880 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5881 #else
5882 return true;
5883 #endif
5884 }
5885
5886 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5887 {
5888 if (use_goto_tb(ctx, dest)) {
5889 tcg_gen_goto_tb(n);
5890 gen_save_pc(dest);
5891 tcg_gen_exit_tb(ctx->base.tb, n);
5892 } else {
5893 gen_save_pc(dest);
5894 if (ctx->base.singlestep_enabled) {
5895 save_cpu_state(ctx, 0);
5896 gen_helper_raise_exception_debug(cpu_env);
5897 }
5898 tcg_gen_lookup_and_goto_ptr();
5899 }
5900 }
5901
5902 /* Branches (before delay slot) */
5903 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5904 int insn_bytes,
5905 int rs, int rt, int32_t offset,
5906 int delayslot_size)
5907 {
5908 target_ulong btgt = -1;
5909 int blink = 0;
5910 int bcond_compute = 0;
5911 TCGv t0 = tcg_temp_new();
5912 TCGv t1 = tcg_temp_new();
5913
5914 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5915 #ifdef MIPS_DEBUG_DISAS
5916 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5917 TARGET_FMT_lx "\n", ctx->base.pc_next);
5918 #endif
5919 generate_exception_end(ctx, EXCP_RI);
5920 goto out;
5921 }
5922
5923 /* Load needed operands */
5924 switch (opc) {
5925 case OPC_BEQ:
5926 case OPC_BEQL:
5927 case OPC_BNE:
5928 case OPC_BNEL:
5929 /* Compare two registers */
5930 if (rs != rt) {
5931 gen_load_gpr(t0, rs);
5932 gen_load_gpr(t1, rt);
5933 bcond_compute = 1;
5934 }
5935 btgt = ctx->base.pc_next + insn_bytes + offset;
5936 break;
5937 case OPC_BGEZ:
5938 case OPC_BGEZAL:
5939 case OPC_BGEZALL:
5940 case OPC_BGEZL:
5941 case OPC_BGTZ:
5942 case OPC_BGTZL:
5943 case OPC_BLEZ:
5944 case OPC_BLEZL:
5945 case OPC_BLTZ:
5946 case OPC_BLTZAL:
5947 case OPC_BLTZALL:
5948 case OPC_BLTZL:
5949 /* Compare to zero */
5950 if (rs != 0) {
5951 gen_load_gpr(t0, rs);
5952 bcond_compute = 1;
5953 }
5954 btgt = ctx->base.pc_next + insn_bytes + offset;
5955 break;
5956 case OPC_BPOSGE32:
5957 #if defined(TARGET_MIPS64)
5958 case OPC_BPOSGE64:
5959 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5960 #else
5961 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5962 #endif
5963 bcond_compute = 1;
5964 btgt = ctx->base.pc_next + insn_bytes + offset;
5965 break;
5966 case OPC_J:
5967 case OPC_JAL:
5968 case OPC_JALX:
5969 /* Jump to immediate */
5970 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5971 (uint32_t)offset;
5972 break;
5973 case OPC_JR:
5974 case OPC_JALR:
5975 /* Jump to register */
5976 if (offset != 0 && offset != 16) {
5977 /*
5978 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5979 * others are reserved.
5980 */
5981 MIPS_INVAL("jump hint");
5982 generate_exception_end(ctx, EXCP_RI);
5983 goto out;
5984 }
5985 gen_load_gpr(btarget, rs);
5986 break;
5987 default:
5988 MIPS_INVAL("branch/jump");
5989 generate_exception_end(ctx, EXCP_RI);
5990 goto out;
5991 }
5992 if (bcond_compute == 0) {
5993 /* No condition to be computed */
5994 switch (opc) {
5995 case OPC_BEQ: /* rx == rx */
5996 case OPC_BEQL: /* rx == rx likely */
5997 case OPC_BGEZ: /* 0 >= 0 */
5998 case OPC_BGEZL: /* 0 >= 0 likely */
5999 case OPC_BLEZ: /* 0 <= 0 */
6000 case OPC_BLEZL: /* 0 <= 0 likely */
6001 /* Always take */
6002 ctx->hflags |= MIPS_HFLAG_B;
6003 break;
6004 case OPC_BGEZAL: /* 0 >= 0 */
6005 case OPC_BGEZALL: /* 0 >= 0 likely */
6006 /* Always take and link */
6007 blink = 31;
6008 ctx->hflags |= MIPS_HFLAG_B;
6009 break;
6010 case OPC_BNE: /* rx != rx */
6011 case OPC_BGTZ: /* 0 > 0 */
6012 case OPC_BLTZ: /* 0 < 0 */
6013 /* Treat as NOP. */
6014 goto out;
6015 case OPC_BLTZAL: /* 0 < 0 */
6016 /*
6017 * Handle as an unconditional branch to get correct delay
6018 * slot checking.
6019 */
6020 blink = 31;
6021 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
6022 ctx->hflags |= MIPS_HFLAG_B;
6023 break;
6024 case OPC_BLTZALL: /* 0 < 0 likely */
6025 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6026 /* Skip the instruction in the delay slot */
6027 ctx->base.pc_next += 4;
6028 goto out;
6029 case OPC_BNEL: /* rx != rx likely */
6030 case OPC_BGTZL: /* 0 > 0 likely */
6031 case OPC_BLTZL: /* 0 < 0 likely */
6032 /* Skip the instruction in the delay slot */
6033 ctx->base.pc_next += 4;
6034 goto out;
6035 case OPC_J:
6036 ctx->hflags |= MIPS_HFLAG_B;
6037 break;
6038 case OPC_JALX:
6039 ctx->hflags |= MIPS_HFLAG_BX;
6040 /* Fallthrough */
6041 case OPC_JAL:
6042 blink = 31;
6043 ctx->hflags |= MIPS_HFLAG_B;
6044 break;
6045 case OPC_JR:
6046 ctx->hflags |= MIPS_HFLAG_BR;
6047 break;
6048 case OPC_JALR:
6049 blink = rt;
6050 ctx->hflags |= MIPS_HFLAG_BR;
6051 break;
6052 default:
6053 MIPS_INVAL("branch/jump");
6054 generate_exception_end(ctx, EXCP_RI);
6055 goto out;
6056 }
6057 } else {
6058 switch (opc) {
6059 case OPC_BEQ:
6060 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6061 goto not_likely;
6062 case OPC_BEQL:
6063 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6064 goto likely;
6065 case OPC_BNE:
6066 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6067 goto not_likely;
6068 case OPC_BNEL:
6069 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6070 goto likely;
6071 case OPC_BGEZ:
6072 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6073 goto not_likely;
6074 case OPC_BGEZL:
6075 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6076 goto likely;
6077 case OPC_BGEZAL:
6078 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6079 blink = 31;
6080 goto not_likely;
6081 case OPC_BGEZALL:
6082 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6083 blink = 31;
6084 goto likely;
6085 case OPC_BGTZ:
6086 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6087 goto not_likely;
6088 case OPC_BGTZL:
6089 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6090 goto likely;
6091 case OPC_BLEZ:
6092 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6093 goto not_likely;
6094 case OPC_BLEZL:
6095 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6096 goto likely;
6097 case OPC_BLTZ:
6098 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6099 goto not_likely;
6100 case OPC_BLTZL:
6101 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6102 goto likely;
6103 case OPC_BPOSGE32:
6104 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6105 goto not_likely;
6106 #if defined(TARGET_MIPS64)
6107 case OPC_BPOSGE64:
6108 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6109 goto not_likely;
6110 #endif
6111 case OPC_BLTZAL:
6112 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6113 blink = 31;
6114 not_likely:
6115 ctx->hflags |= MIPS_HFLAG_BC;
6116 break;
6117 case OPC_BLTZALL:
6118 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6119 blink = 31;
6120 likely:
6121 ctx->hflags |= MIPS_HFLAG_BL;
6122 break;
6123 default:
6124 MIPS_INVAL("conditional branch/jump");
6125 generate_exception_end(ctx, EXCP_RI);
6126 goto out;
6127 }
6128 }
6129
6130 ctx->btarget = btgt;
6131
6132 switch (delayslot_size) {
6133 case 2:
6134 ctx->hflags |= MIPS_HFLAG_BDS16;
6135 break;
6136 case 4:
6137 ctx->hflags |= MIPS_HFLAG_BDS32;
6138 break;
6139 }
6140
6141 if (blink > 0) {
6142 int post_delay = insn_bytes + delayslot_size;
6143 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6144
6145 tcg_gen_movi_tl(cpu_gpr[blink],
6146 ctx->base.pc_next + post_delay + lowbit);
6147 }
6148
6149 out:
6150 if (insn_bytes == 2) {
6151 ctx->hflags |= MIPS_HFLAG_B16;
6152 }
6153 tcg_temp_free(t0);
6154 tcg_temp_free(t1);
6155 }
6156
6157
6158 /* nanoMIPS Branches */
6159 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6160 int insn_bytes,
6161 int rs, int rt, int32_t offset)
6162 {
6163 target_ulong btgt = -1;
6164 int bcond_compute = 0;
6165 TCGv t0 = tcg_temp_new();
6166 TCGv t1 = tcg_temp_new();
6167
6168 /* Load needed operands */
6169 switch (opc) {
6170 case OPC_BEQ:
6171 case OPC_BNE:
6172 /* Compare two registers */
6173 if (rs != rt) {
6174 gen_load_gpr(t0, rs);
6175 gen_load_gpr(t1, rt);
6176 bcond_compute = 1;
6177 }
6178 btgt = ctx->base.pc_next + insn_bytes + offset;
6179 break;
6180 case OPC_BGEZAL:
6181 /* Compare to zero */
6182 if (rs != 0) {
6183 gen_load_gpr(t0, rs);
6184 bcond_compute = 1;
6185 }
6186 btgt = ctx->base.pc_next + insn_bytes + offset;
6187 break;
6188 case OPC_BPOSGE32:
6189 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6190 bcond_compute = 1;
6191 btgt = ctx->base.pc_next + insn_bytes + offset;
6192 break;
6193 case OPC_JR:
6194 case OPC_JALR:
6195 /* Jump to register */
6196 if (offset != 0 && offset != 16) {
6197 /*
6198 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6199 * others are reserved.
6200 */
6201 MIPS_INVAL("jump hint");
6202 generate_exception_end(ctx, EXCP_RI);
6203 goto out;
6204 }
6205 gen_load_gpr(btarget, rs);
6206 break;
6207 default:
6208 MIPS_INVAL("branch/jump");
6209 generate_exception_end(ctx, EXCP_RI);
6210 goto out;
6211 }
6212 if (bcond_compute == 0) {
6213 /* No condition to be computed */
6214 switch (opc) {
6215 case OPC_BEQ: /* rx == rx */
6216 /* Always take */
6217 ctx->hflags |= MIPS_HFLAG_B;
6218 break;
6219 case OPC_BGEZAL: /* 0 >= 0 */
6220 /* Always take and link */
6221 tcg_gen_movi_tl(cpu_gpr[31],
6222 ctx->base.pc_next + insn_bytes);
6223 ctx->hflags |= MIPS_HFLAG_B;
6224 break;
6225 case OPC_BNE: /* rx != rx */
6226 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6227 /* Skip the instruction in the delay slot */
6228 ctx->base.pc_next += 4;
6229 goto out;
6230 case OPC_JR:
6231 ctx->hflags |= MIPS_HFLAG_BR;
6232 break;
6233 case OPC_JALR:
6234 if (rt > 0) {
6235 tcg_gen_movi_tl(cpu_gpr[rt],
6236 ctx->base.pc_next + insn_bytes);
6237 }
6238 ctx->hflags |= MIPS_HFLAG_BR;
6239 break;
6240 default:
6241 MIPS_INVAL("branch/jump");
6242 generate_exception_end(ctx, EXCP_RI);
6243 goto out;
6244 }
6245 } else {
6246 switch (opc) {
6247 case OPC_BEQ:
6248 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6249 goto not_likely;
6250 case OPC_BNE:
6251 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6252 goto not_likely;
6253 case OPC_BGEZAL:
6254 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6255 tcg_gen_movi_tl(cpu_gpr[31],
6256 ctx->base.pc_next + insn_bytes);
6257 goto not_likely;
6258 case OPC_BPOSGE32:
6259 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6260 not_likely:
6261 ctx->hflags |= MIPS_HFLAG_BC;
6262 break;
6263 default:
6264 MIPS_INVAL("conditional branch/jump");
6265 generate_exception_end(ctx, EXCP_RI);
6266 goto out;
6267 }
6268 }
6269
6270 ctx->btarget = btgt;
6271
6272 out:
6273 if (insn_bytes == 2) {
6274 ctx->hflags |= MIPS_HFLAG_B16;
6275 }
6276 tcg_temp_free(t0);
6277 tcg_temp_free(t1);
6278 }
6279
6280
6281 /* special3 bitfield operations */
6282 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
6283 int rs, int lsb, int msb)
6284 {
6285 TCGv t0 = tcg_temp_new();
6286 TCGv t1 = tcg_temp_new();
6287
6288 gen_load_gpr(t1, rs);
6289 switch (opc) {
6290 case OPC_EXT:
6291 if (lsb + msb > 31) {
6292 goto fail;
6293 }
6294 if (msb != 31) {
6295 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6296 } else {
6297 /*
6298 * The two checks together imply that lsb == 0,
6299 * so this is a simple sign-extension.
6300 */
6301 tcg_gen_ext32s_tl(t0, t1);
6302 }
6303 break;
6304 #if defined(TARGET_MIPS64)
6305 case OPC_DEXTU:
6306 lsb += 32;
6307 goto do_dext;
6308 case OPC_DEXTM:
6309 msb += 32;
6310 goto do_dext;
6311 case OPC_DEXT:
6312 do_dext:
6313 if (lsb + msb > 63) {
6314 goto fail;
6315 }
6316 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6317 break;
6318 #endif
6319 case OPC_INS:
6320 if (lsb > msb) {
6321 goto fail;
6322 }
6323 gen_load_gpr(t0, rt);
6324 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6325 tcg_gen_ext32s_tl(t0, t0);
6326 break;
6327 #if defined(TARGET_MIPS64)
6328 case OPC_DINSU:
6329 lsb += 32;
6330 /* FALLTHRU */
6331 case OPC_DINSM:
6332 msb += 32;
6333 /* FALLTHRU */
6334 case OPC_DINS:
6335 if (lsb > msb) {
6336 goto fail;
6337 }
6338 gen_load_gpr(t0, rt);
6339 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6340 break;
6341 #endif
6342 default:
6343 fail:
6344 MIPS_INVAL("bitops");
6345 generate_exception_end(ctx, EXCP_RI);
6346 tcg_temp_free(t0);
6347 tcg_temp_free(t1);
6348 return;
6349 }
6350 gen_store_gpr(t0, rt);
6351 tcg_temp_free(t0);
6352 tcg_temp_free(t1);
6353 }
6354
6355 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
6356 {
6357 TCGv t0;
6358
6359 if (rd == 0) {
6360 /* If no destination, treat it as a NOP. */
6361 return;
6362 }
6363
6364 t0 = tcg_temp_new();
6365 gen_load_gpr(t0, rt);
6366 switch (op2) {
6367 case OPC_WSBH:
6368 {
6369 TCGv t1 = tcg_temp_new();
6370 TCGv t2 = tcg_const_tl(0x00FF00FF);
6371
6372 tcg_gen_shri_tl(t1, t0, 8);
6373 tcg_gen_and_tl(t1, t1, t2);
6374 tcg_gen_and_tl(t0, t0, t2);
6375 tcg_gen_shli_tl(t0, t0, 8);
6376 tcg_gen_or_tl(t0, t0, t1);
6377 tcg_temp_free(t2);
6378 tcg_temp_free(t1);
6379 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6380 }
6381 break;
6382 case OPC_SEB:
6383 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6384 break;
6385 case OPC_SEH:
6386 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6387 break;
6388 #if defined(TARGET_MIPS64)
6389 case OPC_DSBH:
6390 {
6391 TCGv t1 = tcg_temp_new();
6392 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6393
6394 tcg_gen_shri_tl(t1, t0, 8);
6395 tcg_gen_and_tl(t1, t1, t2);
6396 tcg_gen_and_tl(t0, t0, t2);
6397 tcg_gen_shli_tl(t0, t0, 8);
6398 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6399 tcg_temp_free(t2);
6400 tcg_temp_free(t1);
6401 }
6402 break;
6403 case OPC_DSHD:
6404 {
6405 TCGv t1 = tcg_temp_new();
6406 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6407
6408 tcg_gen_shri_tl(t1, t0, 16);
6409 tcg_gen_and_tl(t1, t1, t2);
6410 tcg_gen_and_tl(t0, t0, t2);
6411 tcg_gen_shli_tl(t0, t0, 16);
6412 tcg_gen_or_tl(t0, t0, t1);
6413 tcg_gen_shri_tl(t1, t0, 32);
6414 tcg_gen_shli_tl(t0, t0, 32);
6415 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6416 tcg_temp_free(t2);
6417 tcg_temp_free(t1);
6418 }
6419 break;
6420 #endif
6421 default:
6422 MIPS_INVAL("bsfhl");
6423 generate_exception_end(ctx, EXCP_RI);
6424 tcg_temp_free(t0);
6425 return;
6426 }
6427 tcg_temp_free(t0);
6428 }
6429
6430 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6431 int imm2)
6432 {
6433 TCGv t0;
6434 TCGv t1;
6435 if (rd == 0) {
6436 /* Treat as NOP. */
6437 return;
6438 }
6439 t0 = tcg_temp_new();
6440 t1 = tcg_temp_new();
6441 gen_load_gpr(t0, rs);
6442 gen_load_gpr(t1, rt);
6443 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6444 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6445 if (opc == OPC_LSA) {
6446 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6447 }
6448
6449 tcg_temp_free(t1);
6450 tcg_temp_free(t0);
6451
6452 return;
6453 }
6454
6455 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6456 int rt, int bits)
6457 {
6458 TCGv t0;
6459 if (rd == 0) {
6460 /* Treat as NOP. */
6461 return;
6462 }
6463 t0 = tcg_temp_new();
6464 if (bits == 0 || bits == wordsz) {
6465 if (bits == 0) {
6466 gen_load_gpr(t0, rt);
6467 } else {
6468 gen_load_gpr(t0, rs);
6469 }
6470 switch (wordsz) {
6471 case 32:
6472 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6473 break;
6474 #if defined(TARGET_MIPS64)
6475 case 64:
6476 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6477 break;
6478 #endif
6479 }
6480 } else {
6481 TCGv t1 = tcg_temp_new();
6482 gen_load_gpr(t0, rt);
6483 gen_load_gpr(t1, rs);
6484 switch (wordsz) {
6485 case 32:
6486 {
6487 TCGv_i64 t2 = tcg_temp_new_i64();
6488 tcg_gen_concat_tl_i64(t2, t1, t0);
6489 tcg_gen_shri_i64(t2, t2, 32 - bits);
6490 gen_move_low32(cpu_gpr[rd], t2);
6491 tcg_temp_free_i64(t2);
6492 }
6493 break;
6494 #if defined(TARGET_MIPS64)
6495 case 64:
6496 tcg_gen_shli_tl(t0, t0, bits);
6497 tcg_gen_shri_tl(t1, t1, 64 - bits);
6498 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6499 break;
6500 #endif
6501 }
6502 tcg_temp_free(t1);
6503 }
6504
6505 tcg_temp_free(t0);
6506 }
6507
6508 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6509 int bp)
6510 {
6511 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6512 }
6513
6514 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6515 int shift)
6516 {
6517 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6518 }
6519
6520 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6521 {
6522 TCGv t0;
6523 if (rd == 0) {
6524 /* Treat as NOP. */
6525 return;
6526 }
6527 t0 = tcg_temp_new();
6528 gen_load_gpr(t0, rt);
6529 switch (opc) {
6530 case OPC_BITSWAP:
6531 gen_helper_bitswap(cpu_gpr[rd], t0);
6532 break;
6533 #if defined(TARGET_MIPS64)
6534 case OPC_DBITSWAP:
6535 gen_helper_dbitswap(cpu_gpr[rd], t0);
6536 break;
6537 #endif
6538 }
6539 tcg_temp_free(t0);
6540 }
6541
6542 #ifndef CONFIG_USER_ONLY
6543 /* CP0 (MMU and control) */
6544 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6545 {
6546 TCGv_i64 t0 = tcg_temp_new_i64();
6547 TCGv_i64 t1 = tcg_temp_new_i64();
6548
6549 tcg_gen_ext_tl_i64(t0, arg);
6550 tcg_gen_ld_i64(t1, cpu_env, off);
6551 #if defined(TARGET_MIPS64)
6552 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6553 #else
6554 tcg_gen_concat32_i64(t1, t1, t0);
6555 #endif
6556 tcg_gen_st_i64(t1, cpu_env, off);
6557 tcg_temp_free_i64(t1);
6558 tcg_temp_free_i64(t0);
6559 }
6560
6561 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6562 {
6563 TCGv_i64 t0 = tcg_temp_new_i64();
6564 TCGv_i64 t1 = tcg_temp_new_i64();
6565
6566 tcg_gen_ext_tl_i64(t0, arg);
6567 tcg_gen_ld_i64(t1, cpu_env, off);
6568 tcg_gen_concat32_i64(t1, t1, t0);
6569 tcg_gen_st_i64(t1, cpu_env, off);
6570 tcg_temp_free_i64(t1);
6571 tcg_temp_free_i64(t0);
6572 }
6573
6574 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6575 {
6576 TCGv_i64 t0 = tcg_temp_new_i64();
6577
6578 tcg_gen_ld_i64(t0, cpu_env, off);
6579 #if defined(TARGET_MIPS64)
6580 tcg_gen_shri_i64(t0, t0, 30);
6581 #else
6582 tcg_gen_shri_i64(t0, t0, 32);
6583 #endif
6584 gen_move_low32(arg, t0);
6585 tcg_temp_free_i64(t0);
6586 }
6587
6588 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6589 {
6590 TCGv_i64 t0 = tcg_temp_new_i64();
6591
6592 tcg_gen_ld_i64(t0, cpu_env, off);
6593 tcg_gen_shri_i64(t0, t0, 32 + shift);
6594 gen_move_low32(arg, t0);
6595 tcg_temp_free_i64(t0);
6596 }
6597
6598 static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
6599 {
6600 TCGv_i32 t0 = tcg_temp_new_i32();
6601
6602 tcg_gen_ld_i32(t0, cpu_env, off);
6603 tcg_gen_ext_i32_tl(arg, t0);
6604 tcg_temp_free_i32(t0);
6605 }
6606
6607 static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
6608 {
6609 tcg_gen_ld_tl(arg, cpu_env, off);
6610 tcg_gen_ext32s_tl(arg, arg);
6611 }
6612
6613 static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
6614 {
6615 TCGv_i32 t0 = tcg_temp_new_i32();
6616
6617 tcg_gen_trunc_tl_i32(t0, arg);
6618 tcg_gen_st_i32(t0, cpu_env, off);
6619 tcg_temp_free_i32(t0);
6620 }
6621
6622 #define CP0_CHECK(c) \
6623 do { \
6624 if (!(c)) { \
6625 goto cp0_unimplemented; \
6626 } \
6627 } while (0)
6628
6629 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6630 {
6631 const char *register_name = "invalid";
6632
6633 switch (reg) {
6634 case CP0_REGISTER_02:
6635 switch (sel) {
6636 case 0:
6637 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6638 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6639 register_name = "EntryLo0";
6640 break;
6641 default:
6642 goto cp0_unimplemented;
6643 }
6644 break;
6645 case CP0_REGISTER_03:
6646 switch (sel) {
6647 case 0:
6648 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6649 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6650 register_name = "EntryLo1";
6651 break;
6652 default:
6653 goto cp0_unimplemented;
6654 }
6655 break;
6656 case CP0_REGISTER_09:
6657 switch (sel) {
6658 case 7:
6659 CP0_CHECK(ctx->saar);
6660 gen_helper_mfhc0_saar(arg, cpu_env);
6661 register_name = "SAAR";
6662 break;
6663 default:
6664 goto cp0_unimplemented;
6665 }
6666 break;
6667 case CP0_REGISTER_17:
6668 switch (sel) {
6669 case 0:
6670 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
6671 ctx->CP0_LLAddr_shift);
6672 register_name = "LLAddr";
6673 break;
6674 case 1:
6675 CP0_CHECK(ctx->mrp);
6676 gen_helper_mfhc0_maar(arg, cpu_env);
6677 register_name = "MAAR";
6678 break;
6679 default:
6680 goto cp0_unimplemented;
6681 }
6682 break;
6683 case CP0_REGISTER_28:
6684 switch (sel) {
6685 case 0:
6686 case 2:
6687 case 4:
6688 case 6:
6689 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6690 register_name = "TagLo";
6691 break;
6692 default:
6693 goto cp0_unimplemented;
6694 }
6695 break;
6696 default:
6697 goto cp0_unimplemented;
6698 }
6699 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6700 return;
6701
6702 cp0_unimplemented:
6703 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6704 register_name, reg, sel);
6705 tcg_gen_movi_tl(arg, 0);
6706 }
6707
6708 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6709 {
6710 const char *register_name = "invalid";
6711 uint64_t mask = ctx->PAMask >> 36;
6712
6713 switch (reg) {
6714 case CP0_REGISTER_02:
6715 switch (sel) {
6716 case 0:
6717 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6718 tcg_gen_andi_tl(arg, arg, mask);
6719 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6720 register_name = "EntryLo0";
6721 break;
6722 default:
6723 goto cp0_unimplemented;
6724 }
6725 break;
6726 case CP0_REGISTER_03:
6727 switch (sel) {
6728 case 0:
6729 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6730 tcg_gen_andi_tl(arg, arg, mask);
6731 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6732 register_name = "EntryLo1";
6733 break;
6734 default:
6735 goto cp0_unimplemented;
6736 }
6737 break;
6738 case CP0_REGISTER_09:
6739 switch (sel) {
6740 case 7:
6741 CP0_CHECK(ctx->saar);
6742 gen_helper_mthc0_saar(cpu_env, arg);
6743 register_name = "SAAR";
6744 break;
6745 default:
6746 goto cp0_unimplemented;
6747 }
6748 case CP0_REGISTER_17:
6749 switch (sel) {
6750 case 0:
6751 /*
6752 * LLAddr is read-only (the only exception is bit 0 if LLB is
6753 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6754 * relevant for modern MIPS cores supporting MTHC0, therefore
6755 * treating MTHC0 to LLAddr as NOP.
6756 */
6757 register_name = "LLAddr";
6758 break;
6759 case 1:
6760 CP0_CHECK(ctx->mrp);
6761 gen_helper_mthc0_maar(cpu_env, arg);
6762 register_name = "MAAR";
6763 break;
6764 default:
6765 goto cp0_unimplemented;
6766 }
6767 break;
6768 case CP0_REGISTER_28:
6769 switch (sel) {
6770 case 0:
6771 case 2:
6772 case 4:
6773 case 6:
6774 tcg_gen_andi_tl(arg, arg, mask);
6775 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6776 register_name = "TagLo";
6777 break;
6778 default:
6779 goto cp0_unimplemented;
6780 }
6781 break;
6782 default:
6783 goto cp0_unimplemented;
6784 }
6785 trace_mips_translate_c0("mthc0", register_name, reg, sel);
6786
6787 cp0_unimplemented:
6788 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6789 register_name, reg, sel);
6790 }
6791
6792 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6793 {
6794 if (ctx->insn_flags & ISA_MIPS32R6) {
6795 tcg_gen_movi_tl(arg, 0);
6796 } else {
6797 tcg_gen_movi_tl(arg, ~0);
6798 }
6799 }
6800
6801 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6802 {
6803 const char *register_name = "invalid";
6804
6805 if (sel != 0) {
6806 check_insn(ctx, ISA_MIPS32);
6807 }
6808
6809 switch (reg) {
6810 case CP0_REGISTER_00:
6811 switch (sel) {
6812 case 0:
6813 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6814 register_name = "Index";
6815 break;
6816 case 1:
6817 CP0_CHECK(ctx->insn_flags & ASE_MT);
6818 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6819 register_name = "MVPControl";
6820 break;
6821 case 2:
6822 CP0_CHECK(ctx->insn_flags & ASE_MT);
6823 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6824 register_name = "MVPConf0";
6825 break;
6826 case 3:
6827 CP0_CHECK(ctx->insn_flags & ASE_MT);
6828 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6829 register_name = "MVPConf1";
6830 break;
6831 case 4:
6832 CP0_CHECK(ctx->vp);
6833 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6834 register_name = "VPControl";
6835 break;
6836 default:
6837 goto cp0_unimplemented;
6838 }
6839 break;
6840 case CP0_REGISTER_01:
6841 switch (sel) {
6842 case 0:
6843 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6844 gen_helper_mfc0_random(arg, cpu_env);
6845 register_name = "Random";
6846 break;
6847 case 1:
6848 CP0_CHECK(ctx->insn_flags & ASE_MT);
6849 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6850 register_name = "VPEControl";
6851 break;
6852 case 2:
6853 CP0_CHECK(ctx->insn_flags & ASE_MT);
6854 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6855 register_name = "VPEConf0";
6856 break;
6857 case 3:
6858 CP0_CHECK(ctx->insn_flags & ASE_MT);
6859 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6860 register_name = "VPEConf1";
6861 break;
6862 case 4:
6863 CP0_CHECK(ctx->insn_flags & ASE_MT);
6864 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6865 register_name = "YQMask";
6866 break;
6867 case 5:
6868 CP0_CHECK(ctx->insn_flags & ASE_MT);
6869 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6870 register_name = "VPESchedule";
6871 break;
6872 case 6:
6873 CP0_CHECK(ctx->insn_flags & ASE_MT);
6874 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6875 register_name = "VPEScheFBack";
6876 break;
6877 case 7:
6878 CP0_CHECK(ctx->insn_flags & ASE_MT);
6879 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6880 register_name = "VPEOpt";
6881 break;
6882 default:
6883 goto cp0_unimplemented;
6884 }
6885 break;
6886 case CP0_REGISTER_02:
6887 switch (sel) {
6888 case 0:
6889 {
6890 TCGv_i64 tmp = tcg_temp_new_i64();
6891 tcg_gen_ld_i64(tmp, cpu_env,
6892 offsetof(CPUMIPSState, CP0_EntryLo0));
6893 #if defined(TARGET_MIPS64)
6894 if (ctx->rxi) {
6895 /* Move RI/XI fields to bits 31:30 */
6896 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6897 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6898 }
6899 #endif
6900 gen_move_low32(arg, tmp);
6901 tcg_temp_free_i64(tmp);
6902 }
6903 register_name = "EntryLo0";
6904 break;
6905 case 1:
6906 CP0_CHECK(ctx->insn_flags & ASE_MT);
6907 gen_helper_mfc0_tcstatus(arg, cpu_env);
6908 register_name = "TCStatus";
6909 break;
6910 case 2:
6911 CP0_CHECK(ctx->insn_flags & ASE_MT);
6912 gen_helper_mfc0_tcbind(arg, cpu_env);
6913 register_name = "TCBind";
6914 break;
6915 case 3:
6916 CP0_CHECK(ctx->insn_flags & ASE_MT);
6917 gen_helper_mfc0_tcrestart(arg, cpu_env);
6918 register_name = "TCRestart";
6919 break;
6920 case 4:
6921 CP0_CHECK(ctx->insn_flags & ASE_MT);
6922 gen_helper_mfc0_tchalt(arg, cpu_env);
6923 register_name = "TCHalt";
6924 break;
6925 case 5:
6926 CP0_CHECK(ctx->insn_flags & ASE_MT);
6927 gen_helper_mfc0_tccontext(arg, cpu_env);
6928 register_name = "TCContext";
6929 break;
6930 case 6:
6931 CP0_CHECK(ctx->insn_flags & ASE_MT);
6932 gen_helper_mfc0_tcschedule(arg, cpu_env);
6933 register_name = "TCSchedule";
6934 break;
6935 case 7:
6936 CP0_CHECK(ctx->insn_flags & ASE_MT);
6937 gen_helper_mfc0_tcschefback(arg, cpu_env);
6938 register_name = "TCScheFBack";
6939 break;
6940 default:
6941 goto cp0_unimplemented;
6942 }
6943 break;
6944 case CP0_REGISTER_03:
6945 switch (sel) {
6946 case 0:
6947 {
6948 TCGv_i64 tmp = tcg_temp_new_i64();
6949 tcg_gen_ld_i64(tmp, cpu_env,
6950 offsetof(CPUMIPSState, CP0_EntryLo1));
6951 #if defined(TARGET_MIPS64)
6952 if (ctx->rxi) {
6953 /* Move RI/XI fields to bits 31:30 */
6954 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6955 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6956 }
6957 #endif
6958 gen_move_low32(arg, tmp);
6959 tcg_temp_free_i64(tmp);
6960 }
6961 register_name = "EntryLo1";
6962 break;
6963 case 1:
6964 CP0_CHECK(ctx->vp);
6965 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6966 register_name = "GlobalNumber";
6967 break;
6968 default:
6969 goto cp0_unimplemented;
6970 }
6971 break;
6972 case CP0_REGISTER_04:
6973 switch (sel) {
6974 case 0:
6975 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6976 tcg_gen_ext32s_tl(arg, arg);
6977 register_name = "Context";
6978 break;
6979 case 1:
6980 /* gen_helper_mfc0_contextconfig(arg); - SmartMIPS ASE */
6981 register_name = "ContextConfig";
6982 goto cp0_unimplemented;
6983 case 2:
6984 CP0_CHECK(ctx->ulri);
6985 tcg_gen_ld_tl(arg, cpu_env,
6986 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6987 tcg_gen_ext32s_tl(arg, arg);
6988 register_name = "UserLocal";
6989 break;
6990 default:
6991 goto cp0_unimplemented;
6992 }
6993 break;
6994 case CP0_REGISTER_05:
6995 switch (sel) {
6996 case 0:
6997 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6998 register_name = "PageMask";
6999 break;
7000 case 1:
7001 check_insn(ctx, ISA_MIPS32R2);
7002 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7003 register_name = "PageGrain";
7004 break;
7005 case 2:
7006 CP0_CHECK(ctx->sc);
7007 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7008 tcg_gen_ext32s_tl(arg, arg);
7009 register_name = "SegCtl0";
7010 break;
7011 case 3:
7012 CP0_CHECK(ctx->sc);
7013 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7014 tcg_gen_ext32s_tl(arg, arg);
7015 register_name = "SegCtl1";
7016 break;
7017 case 4:
7018 CP0_CHECK(ctx->sc);
7019 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7020 tcg_gen_ext32s_tl(arg, arg);
7021 register_name = "SegCtl2";
7022 break;
7023 case 5:
7024 check_pw(ctx);
7025 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7026 register_name = "PWBase";
7027 break;
7028 case 6:
7029 check_pw(ctx);
7030 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
7031 register_name = "PWField";
7032 break;
7033 case 7:
7034 check_pw(ctx);
7035 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
7036 register_name = "PWSize";
7037 break;
7038 default:
7039 goto cp0_unimplemented;
7040 }
7041 break;
7042 case CP0_REGISTER_06:
7043 switch (sel) {
7044 case 0:
7045 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7046 register_name = "Wired";
7047 break;
7048 case 1:
7049 check_insn(ctx, ISA_MIPS32R2);
7050 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7051 register_name = "SRSConf0";
7052 break;
7053 case 2:
7054 check_insn(ctx, ISA_MIPS32R2);
7055 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7056 register_name = "SRSConf1";
7057 break;
7058 case 3:
7059 check_insn(ctx, ISA_MIPS32R2);
7060 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7061 register_name = "SRSConf2";
7062 break;
7063 case 4:
7064 check_insn(ctx, ISA_MIPS32R2);
7065 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7066 register_name = "SRSConf3";
7067 break;
7068 case 5:
7069 check_insn(ctx, ISA_MIPS32R2);
7070 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7071 register_name = "SRSConf4";
7072 break;
7073 case 6:
7074 check_pw(ctx);
7075 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7076 register_name = "PWCtl";
7077 break;
7078 default:
7079 goto cp0_unimplemented;
7080 }
7081 break;
7082 case CP0_REGISTER_07:
7083 switch (sel) {
7084 case 0:
7085 check_insn(ctx, ISA_MIPS32R2);
7086 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7087 register_name = "HWREna";
7088 break;
7089 default:
7090 goto cp0_unimplemented;
7091 }
7092 break;
7093 case CP0_REGISTER_08:
7094 switch (sel) {
7095 case 0:
7096 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7097 tcg_gen_ext32s_tl(arg, arg);
7098 register_name = "BadVAddr";
7099 break;
7100 case 1:
7101 CP0_CHECK(ctx->bi);
7102 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7103 register_name = "BadInstr";
7104 break;
7105 case 2:
7106 CP0_CHECK(ctx->bp);
7107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7108 register_name = "BadInstrP";
7109 break;
7110 case 3:
7111 CP0_CHECK(ctx->bi);
7112 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7113 tcg_gen_andi_tl(arg, arg, ~0xffff);
7114 register_name = "BadInstrX";
7115 break;
7116 default:
7117 goto cp0_unimplemented;
7118 }
7119 break;
7120 case CP0_REGISTER_09:
7121 switch (sel) {
7122 case 0:
7123 /* Mark as an IO operation because we read the time. */
7124 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7125 gen_io_start();
7126 }
7127 gen_helper_mfc0_count(arg, cpu_env);
7128 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7129 gen_io_end();
7130 }
7131 /*
7132 * Break the TB to be able to take timer interrupts immediately
7133 * after reading count. DISAS_STOP isn't sufficient, we need to
7134 * ensure we break completely out of translated code.
7135 */
7136 gen_save_pc(ctx->base.pc_next + 4);
7137 ctx->base.is_jmp = DISAS_EXIT;
7138 register_name = "Count";
7139 break;
7140 case 6:
7141 CP0_CHECK(ctx->saar);
7142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7143 register_name = "SAARI";
7144 break;
7145 case 7:
7146 CP0_CHECK(ctx->saar);
7147 gen_helper_mfc0_saar(arg, cpu_env);
7148 register_name = "SAAR";
7149 break;
7150 default:
7151 goto cp0_unimplemented;
7152 }
7153 break;
7154 case CP0_REGISTER_10:
7155 switch (sel) {
7156 case 0:
7157 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7158 tcg_gen_ext32s_tl(arg, arg);
7159 register_name = "EntryHi";
7160 break;
7161 default:
7162 goto cp0_unimplemented;
7163 }
7164 break;
7165 case CP0_REGISTER_11:
7166 switch (sel) {
7167 case 0:
7168 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7169 register_name = "Compare";
7170 break;
7171 /* 6,7 are implementation dependent */
7172 default:
7173 goto cp0_unimplemented;
7174 }
7175 break;
7176 case CP0_REGISTER_12:
7177 switch (sel) {
7178 case 0:
7179 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7180 register_name = "Status";
7181 break;
7182 case 1:
7183 check_insn(ctx, ISA_MIPS32R2);
7184 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7185 register_name = "IntCtl";
7186 break;
7187 case 2:
7188 check_insn(ctx, ISA_MIPS32R2);
7189 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7190 register_name = "SRSCtl";
7191 break;
7192 case 3:
7193 check_insn(ctx, ISA_MIPS32R2);
7194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7195 register_name = "SRSMap";
7196 break;
7197 default:
7198 goto cp0_unimplemented;
7199 }
7200 break;
7201 case CP0_REGISTER_13:
7202 switch (sel) {
7203 case 0:
7204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7205 register_name = "Cause";
7206 break;
7207 default:
7208 goto cp0_unimplemented;
7209 }
7210 break;
7211 case CP0_REGISTER_14:
7212 switch (sel) {
7213 case 0:
7214 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7215 tcg_gen_ext32s_tl(arg, arg);
7216 register_name = "EPC";
7217 break;
7218 default:
7219 goto cp0_unimplemented;
7220 }
7221 break;
7222 case CP0_REGISTER_15:
7223 switch (sel) {
7224 case 0:
7225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7226 register_name = "PRid";
7227 break;
7228 case 1:
7229 check_insn(ctx, ISA_MIPS32R2);
7230 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7231 tcg_gen_ext32s_tl(arg, arg);
7232 register_name = "EBase";
7233 break;
7234 case 3:
7235 check_insn(ctx, ISA_MIPS32R2);
7236 CP0_CHECK(ctx->cmgcr);
7237 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7238 tcg_gen_ext32s_tl(arg, arg);
7239 register_name = "CMGCRBase";
7240 break;
7241 default:
7242 goto cp0_unimplemented;
7243 }
7244 break;
7245 case CP0_REGISTER_16:
7246 switch (sel) {
7247 case 0:
7248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7249 register_name = "Config";
7250 break;
7251 case 1:
7252 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7253 register_name = "Config1";
7254 break;
7255 case 2:
7256 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7257 register_name = "Config2";
7258 break;
7259 case 3:
7260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7261 register_name = "Config3";
7262 break;
7263 case 4:
7264 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7265 register_name = "Config4";
7266 break;
7267 case 5:
7268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7269 register_name = "Config5";
7270 break;
7271 /* 6,7 are implementation dependent */
7272 case 6:
7273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7274 register_name = "Config6";
7275 break;
7276 case 7:
7277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7278 register_name = "Config7";
7279 break;
7280 default:
7281 goto cp0_unimplemented;
7282 }
7283 break;
7284 case CP0_REGISTER_17:
7285 switch (sel) {
7286 case 0:
7287 gen_helper_mfc0_lladdr(arg, cpu_env);
7288 register_name = "LLAddr";
7289 break;
7290 case 1:
7291 CP0_CHECK(ctx->mrp);
7292 gen_helper_mfc0_maar(arg, cpu_env);
7293 register_name = "MAAR";
7294 break;
7295 case 2:
7296 CP0_CHECK(ctx->mrp);
7297 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7298 register_name = "MAARI";
7299 break;
7300 default:
7301 goto cp0_unimplemented;
7302 }
7303 break;
7304 case CP0_REGISTER_18:
7305 switch (sel) {
7306 case 0:
7307 case 1:
7308 case 2:
7309 case 3:
7310 case 4:
7311 case 5:
7312 case 6:
7313 case 7:
7314 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7315 gen_helper_1e0i(mfc0_watchlo, arg, sel);
7316 register_name = "WatchLo";
7317 break;
7318 default:
7319 goto cp0_unimplemented;
7320 }
7321 break;
7322 case CP0_REGISTER_19:
7323 switch (sel) {
7324 case 0:
7325 case 1:
7326 case 2:
7327 case 3:
7328 case 4:
7329 case 5:
7330 case 6:
7331 case 7:
7332 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7333 gen_helper_1e0i(mfc0_watchhi, arg, sel);
7334 register_name = "WatchHi";
7335 break;
7336 default:
7337 goto cp0_unimplemented;
7338 }
7339 break;
7340 case CP0_REGISTER_20:
7341 switch (sel) {
7342 case 0:
7343 #if defined(TARGET_MIPS64)
7344 check_insn(ctx, ISA_MIPS3);
7345 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7346 tcg_gen_ext32s_tl(arg, arg);
7347 register_name = "XContext";
7348 break;
7349 #endif
7350 default:
7351 goto cp0_unimplemented;
7352 }
7353 break;
7354 case CP0_REGISTER_21:
7355 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7356 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7357 switch (sel) {
7358 case 0:
7359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7360 register_name = "Framemask";
7361 break;
7362 default:
7363 goto cp0_unimplemented;
7364 }
7365 break;
7366 case CP0_REGISTER_22:
7367 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7368 register_name = "'Diagnostic"; /* implementation dependent */
7369 break;
7370 case CP0_REGISTER_23:
7371 switch (sel) {
7372 case 0:
7373 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7374 register_name = "Debug";
7375 break;
7376 case 1:
7377 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7378 register_name = "TraceControl";
7379 goto cp0_unimplemented;
7380 case 2:
7381 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7382 register_name = "TraceControl2";
7383 goto cp0_unimplemented;
7384 case 3:
7385 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7386 register_name = "UserTraceData";
7387 goto cp0_unimplemented;
7388 case 4:
7389 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7390 register_name = "TraceBPC";
7391 goto cp0_unimplemented;
7392 default:
7393 goto cp0_unimplemented;
7394 }
7395 break;
7396 case CP0_REGISTER_24:
7397 switch (sel) {
7398 case 0:
7399 /* EJTAG support */
7400 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7401 tcg_gen_ext32s_tl(arg, arg);
7402 register_name = "DEPC";
7403 break;
7404 default:
7405 goto cp0_unimplemented;
7406 }
7407 break;
7408 case CP0_REGISTER_25:
7409 switch (sel) {
7410 case 0:
7411 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7412 register_name = "Performance0";
7413 break;
7414 case 1:
7415 /* gen_helper_mfc0_performance1(arg); */
7416 register_name = "Performance1";
7417 goto cp0_unimplemented;
7418 case 2:
7419 /* gen_helper_mfc0_performance2(arg); */
7420 register_name = "Performance2";
7421 goto cp0_unimplemented;
7422 case 3:
7423 /* gen_helper_mfc0_performance3(arg); */
7424 register_name = "Performance3";
7425 goto cp0_unimplemented;
7426 case 4:
7427 /* gen_helper_mfc0_performance4(arg); */
7428 register_name = "Performance4";
7429 goto cp0_unimplemented;
7430 case 5:
7431 /* gen_helper_mfc0_performance5(arg); */
7432 register_name = "Performance5";
7433 goto cp0_unimplemented;
7434 case 6:
7435 /* gen_helper_mfc0_performance6(arg); */
7436 register_name = "Performance6";
7437 goto cp0_unimplemented;
7438 case 7:
7439 /* gen_helper_mfc0_performance7(arg); */
7440 register_name = "Performance7";
7441 goto cp0_unimplemented;
7442 default:
7443 goto cp0_unimplemented;
7444 }
7445 break;
7446 case CP0_REGISTER_26:
7447 switch (sel) {
7448 case 0:
7449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7450 register_name = "ErrCtl";
7451 break;
7452 default:
7453 goto cp0_unimplemented;
7454 }
7455 break;
7456 case CP0_REGISTER_27:
7457 switch (sel) {
7458 case 0:
7459 case 1:
7460 case 2:
7461 case 3:
7462 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7463 register_name = "CacheErr";
7464 break;
7465 default:
7466 goto cp0_unimplemented;
7467 }
7468 break;
7469 case CP0_REGISTER_28:
7470 switch (sel) {
7471 case 0:
7472 case 2:
7473 case 4:
7474 case 6:
7475 {
7476 TCGv_i64 tmp = tcg_temp_new_i64();
7477 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7478 gen_move_low32(arg, tmp);
7479 tcg_temp_free_i64(tmp);
7480 }
7481 register_name = "TagLo";
7482 break;
7483 case 1:
7484 case 3:
7485 case 5:
7486 case 7:
7487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7488 register_name = "DataLo";
7489 break;
7490 default:
7491 goto cp0_unimplemented;
7492 }
7493 break;
7494 case CP0_REGISTER_29:
7495 switch (sel) {
7496 case 0:
7497 case 2:
7498 case 4:
7499 case 6:
7500 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7501 register_name = "TagHi";
7502 break;
7503 case 1:
7504 case 3:
7505 case 5:
7506 case 7:
7507 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7508 register_name = "DataHi";
7509 break;
7510 default:
7511 goto cp0_unimplemented;
7512 }
7513 break;
7514 case CP0_REGISTER_30:
7515 switch (sel) {
7516 case 0:
7517 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7518 tcg_gen_ext32s_tl(arg, arg);
7519 register_name = "ErrorEPC";
7520 break;
7521 default:
7522 goto cp0_unimplemented;
7523 }
7524 break;
7525 case CP0_REGISTER_31:
7526 switch (sel) {
7527 case 0:
7528 /* EJTAG support */
7529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7530 register_name = "DESAVE";
7531 break;
7532 case 2:
7533 case 3:
7534 case 4:
7535 case 5:
7536 case 6:
7537 case 7:
7538 CP0_CHECK(ctx->kscrexist & (1 << sel));
7539 tcg_gen_ld_tl(arg, cpu_env,
7540 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7541 tcg_gen_ext32s_tl(arg, arg);
7542 register_name = "KScratch";
7543 break;
7544 default:
7545 goto cp0_unimplemented;
7546 }
7547 break;
7548 default:
7549 goto cp0_unimplemented;
7550 }
7551 trace_mips_translate_c0("mfc0", register_name, reg, sel);
7552 return;
7553
7554 cp0_unimplemented:
7555 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7556 register_name, reg, sel);
7557 gen_mfc0_unimplemented(ctx, arg);
7558 }
7559
7560 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7561 {
7562 const char *register_name = "invalid";
7563
7564 if (sel != 0) {
7565 check_insn(ctx, ISA_MIPS32);
7566 }
7567
7568 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7569 gen_io_start();
7570 }
7571
7572 switch (reg) {
7573 case CP0_REGISTER_00:
7574 switch (sel) {
7575 case 0:
7576 gen_helper_mtc0_index(cpu_env, arg);
7577 register_name = "Index";
7578 break;
7579 case 1:
7580 CP0_CHECK(ctx->insn_flags & ASE_MT);
7581 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7582 register_name = "MVPControl";
7583 break;
7584 case 2:
7585 CP0_CHECK(ctx->insn_flags & ASE_MT);
7586 /* ignored */
7587 register_name = "MVPConf0";
7588 break;
7589 case 3:
7590 CP0_CHECK(ctx->insn_flags & ASE_MT);
7591 /* ignored */
7592 register_name = "MVPConf1";
7593 break;
7594 case 4:
7595 CP0_CHECK(ctx->vp);
7596 /* ignored */
7597 register_name = "VPControl";
7598 break;
7599 default:
7600 goto cp0_unimplemented;
7601 }
7602 break;
7603 case CP0_REGISTER_01:
7604 switch (sel) {
7605 case 0:
7606 /* ignored */
7607 register_name = "Random";
7608 break;
7609 case 1:
7610 CP0_CHECK(ctx->insn_flags & ASE_MT);
7611 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7612 register_name = "VPEControl";
7613 break;
7614 case 2:
7615 CP0_CHECK(ctx->insn_flags & ASE_MT);
7616 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7617 register_name = "VPEConf0";
7618 break;
7619 case 3:
7620 CP0_CHECK(ctx->insn_flags & ASE_MT);
7621 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7622 register_name = "VPEConf1";
7623 break;
7624 case 4:
7625 CP0_CHECK(ctx->insn_flags & ASE_MT);
7626 gen_helper_mtc0_yqmask(cpu_env, arg);
7627 register_name = "YQMask";
7628 break;
7629 case 5:
7630 CP0_CHECK(ctx->insn_flags & ASE_MT);
7631 tcg_gen_st_tl(arg, cpu_env,
7632 offsetof(CPUMIPSState, CP0_VPESchedule));
7633 register_name = "VPESchedule";
7634 break;
7635 case 6:
7636 CP0_CHECK(ctx->insn_flags & ASE_MT);
7637 tcg_gen_st_tl(arg, cpu_env,
7638 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7639 register_name = "VPEScheFBack";
7640 break;
7641 case 7:
7642 CP0_CHECK(ctx->insn_flags & ASE_MT);
7643 gen_helper_mtc0_vpeopt(cpu_env, arg);
7644 register_name = "VPEOpt";
7645 break;
7646 default:
7647 goto cp0_unimplemented;
7648 }
7649 break;
7650 case CP0_REGISTER_02:
7651 switch (sel) {
7652 case 0:
7653 gen_helper_mtc0_entrylo0(cpu_env, arg);
7654 register_name = "EntryLo0";
7655 break;
7656 case 1:
7657 CP0_CHECK(ctx->insn_flags & ASE_MT);
7658 gen_helper_mtc0_tcstatus(cpu_env, arg);
7659 register_name = "TCStatus";
7660 break;
7661 case 2:
7662 CP0_CHECK(ctx->insn_flags & ASE_MT);
7663 gen_helper_mtc0_tcbind(cpu_env, arg);
7664 register_name = "TCBind";
7665 break;
7666 case 3:
7667 CP0_CHECK(ctx->insn_flags & ASE_MT);
7668 gen_helper_mtc0_tcrestart(cpu_env, arg);
7669 register_name = "TCRestart";
7670 break;
7671 case 4:
7672 CP0_CHECK(ctx->insn_flags & ASE_MT);
7673 gen_helper_mtc0_tchalt(cpu_env, arg);
7674 register_name = "TCHalt";
7675 break;
7676 case 5:
7677 CP0_CHECK(ctx->insn_flags & ASE_MT);
7678 gen_helper_mtc0_tccontext(cpu_env, arg);
7679 register_name = "TCContext";
7680 break;
7681 case 6:
7682 CP0_CHECK(ctx->insn_flags & ASE_MT);
7683 gen_helper_mtc0_tcschedule(cpu_env, arg);
7684 register_name = "TCSchedule";
7685 break;
7686 case 7:
7687 CP0_CHECK(ctx->insn_flags & ASE_MT);
7688 gen_helper_mtc0_tcschefback(cpu_env, arg);
7689 register_name = "TCScheFBack";
7690 break;
7691 default:
7692 goto cp0_unimplemented;
7693 }
7694 break;
7695 case CP0_REGISTER_03:
7696 switch (sel) {
7697 case 0:
7698 gen_helper_mtc0_entrylo1(cpu_env, arg);
7699 register_name = "EntryLo1";
7700 break;
7701 case 1:
7702 CP0_CHECK(ctx->vp);
7703 /* ignored */
7704 register_name = "GlobalNumber";
7705 break;
7706 default:
7707 goto cp0_unimplemented;
7708 }
7709 break;
7710 case CP0_REGISTER_04:
7711 switch (sel) {
7712 case 0:
7713 gen_helper_mtc0_context(cpu_env, arg);
7714 register_name = "Context";
7715 break;
7716 case 1:
7717 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7718 register_name = "ContextConfig";
7719 goto cp0_unimplemented;
7720 case 2:
7721 CP0_CHECK(ctx->ulri);
7722 tcg_gen_st_tl(arg, cpu_env,
7723 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7724 register_name = "UserLocal";
7725 break;
7726 default:
7727 goto cp0_unimplemented;
7728 }
7729 break;
7730 case CP0_REGISTER_05:
7731 switch (sel) {
7732 case 0:
7733 gen_helper_mtc0_pagemask(cpu_env, arg);
7734 register_name = "PageMask";
7735 break;
7736 case 1:
7737 check_insn(ctx, ISA_MIPS32R2);
7738 gen_helper_mtc0_pagegrain(cpu_env, arg);
7739 register_name = "PageGrain";
7740 ctx->base.is_jmp = DISAS_STOP;
7741 break;
7742 case 2:
7743 CP0_CHECK(ctx->sc);
7744 gen_helper_mtc0_segctl0(cpu_env, arg);
7745 register_name = "SegCtl0";
7746 break;
7747 case 3:
7748 CP0_CHECK(ctx->sc);
7749 gen_helper_mtc0_segctl1(cpu_env, arg);
7750 register_name = "SegCtl1";
7751 break;
7752 case 4:
7753 CP0_CHECK(ctx->sc);
7754 gen_helper_mtc0_segctl2(cpu_env, arg);
7755 register_name = "SegCtl2";
7756 break;
7757 case 5:
7758 check_pw(ctx);
7759 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7760 register_name = "PWBase";
7761 break;
7762 case 6:
7763 check_pw(ctx);
7764 gen_helper_mtc0_pwfield(cpu_env, arg);
7765 register_name = "PWField";
7766 break;
7767 case 7:
7768 check_pw(ctx);
7769 gen_helper_mtc0_pwsize(cpu_env, arg);
7770 register_name = "PWSize";
7771 break;
7772 default:
7773 goto cp0_unimplemented;
7774 }
7775 break;
7776 case CP0_REGISTER_06:
7777 switch (sel) {
7778 case 0:
7779 gen_helper_mtc0_wired(cpu_env, arg);
7780 register_name = "Wired";
7781 break;
7782 case 1:
7783 check_insn(ctx, ISA_MIPS32R2);
7784 gen_helper_mtc0_srsconf0(cpu_env, arg);
7785 register_name = "SRSConf0";
7786 break;
7787 case 2:
7788 check_insn(ctx, ISA_MIPS32R2);
7789 gen_helper_mtc0_srsconf1(cpu_env, arg);
7790 register_name = "SRSConf1";
7791 break;
7792 case 3:
7793 check_insn(ctx, ISA_MIPS32R2);
7794 gen_helper_mtc0_srsconf2(cpu_env, arg);
7795 register_name = "SRSConf2";
7796 break;
7797 case 4:
7798 check_insn(ctx, ISA_MIPS32R2);
7799 gen_helper_mtc0_srsconf3(cpu_env, arg);
7800 register_name = "SRSConf3";
7801 break;
7802 case 5:
7803 check_insn(ctx, ISA_MIPS32R2);
7804 gen_helper_mtc0_srsconf4(cpu_env, arg);
7805 register_name = "SRSConf4";
7806 break;
7807 case 6:
7808 check_pw(ctx);
7809 gen_helper_mtc0_pwctl(cpu_env, arg);
7810 register_name = "PWCtl";
7811 break;
7812 default:
7813 goto cp0_unimplemented;
7814 }
7815 break;
7816 case CP0_REGISTER_07:
7817 switch (sel) {
7818 case 0:
7819 check_insn(ctx, ISA_MIPS32R2);
7820 gen_helper_mtc0_hwrena(cpu_env, arg);
7821 ctx->base.is_jmp = DISAS_STOP;
7822 register_name = "HWREna";
7823 break;
7824 default:
7825 goto cp0_unimplemented;
7826 }
7827 break;
7828 case CP0_REGISTER_08:
7829 switch (sel) {
7830 case 0:
7831 /* ignored */
7832 register_name = "BadVAddr";
7833 break;
7834 case 1:
7835 /* ignored */
7836 register_name = "BadInstr";
7837 break;
7838 case 2:
7839 /* ignored */
7840 register_name = "BadInstrP";
7841 break;
7842 case 3:
7843 /* ignored */
7844 register_name = "BadInstrX";
7845 break;
7846 default:
7847 goto cp0_unimplemented;
7848 }
7849 break;
7850 case CP0_REGISTER_09:
7851 switch (sel) {
7852 case 0:
7853 gen_helper_mtc0_count(cpu_env, arg);
7854 register_name = "Count";
7855 break;
7856 case 6:
7857 CP0_CHECK(ctx->saar);
7858 gen_helper_mtc0_saari(cpu_env, arg);
7859 register_name = "SAARI";
7860 break;
7861 case 7:
7862 CP0_CHECK(ctx->saar);
7863 gen_helper_mtc0_saar(cpu_env, arg);
7864 register_name = "SAAR";
7865 break;
7866 default:
7867 goto cp0_unimplemented;
7868 }
7869 break;
7870 case CP0_REGISTER_10:
7871 switch (sel) {
7872 case 0:
7873 gen_helper_mtc0_entryhi(cpu_env, arg);
7874 register_name = "EntryHi";
7875 break;
7876 default:
7877 goto cp0_unimplemented;
7878 }
7879 break;
7880 case CP0_REGISTER_11:
7881 switch (sel) {
7882 case 0:
7883 gen_helper_mtc0_compare(cpu_env, arg);
7884 register_name = "Compare";
7885 break;
7886 /* 6,7 are implementation dependent */
7887 default:
7888 goto cp0_unimplemented;
7889 }
7890 break;
7891 case CP0_REGISTER_12:
7892 switch (sel) {
7893 case 0:
7894 save_cpu_state(ctx, 1);
7895 gen_helper_mtc0_status(cpu_env, arg);
7896 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7897 gen_save_pc(ctx->base.pc_next + 4);
7898 ctx->base.is_jmp = DISAS_EXIT;
7899 register_name = "Status";
7900 break;
7901 case 1:
7902 check_insn(ctx, ISA_MIPS32R2);
7903 gen_helper_mtc0_intctl(cpu_env, arg);
7904 /* Stop translation as we may have switched the execution mode */
7905 ctx->base.is_jmp = DISAS_STOP;
7906 register_name = "IntCtl";
7907 break;
7908 case 2:
7909 check_insn(ctx, ISA_MIPS32R2);
7910 gen_helper_mtc0_srsctl(cpu_env, arg);
7911 /* Stop translation as we may have switched the execution mode */
7912 ctx->base.is_jmp = DISAS_STOP;
7913 register_name = "SRSCtl";
7914 break;
7915 case 3:
7916 check_insn(ctx, ISA_MIPS32R2);
7917 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7918 /* Stop translation as we may have switched the execution mode */
7919 ctx->base.is_jmp = DISAS_STOP;
7920 register_name = "SRSMap";
7921 break;
7922 default:
7923 goto cp0_unimplemented;
7924 }
7925 break;
7926 case CP0_REGISTER_13:
7927 switch (sel) {
7928 case 0:
7929 save_cpu_state(ctx, 1);
7930 gen_helper_mtc0_cause(cpu_env, arg);
7931 /*
7932 * Stop translation as we may have triggered an interrupt.
7933 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7934 * translated code to check for pending interrupts.
7935 */
7936 gen_save_pc(ctx->base.pc_next + 4);
7937 ctx->base.is_jmp = DISAS_EXIT;
7938 register_name = "Cause";
7939 break;
7940 default:
7941 goto cp0_unimplemented;
7942 }
7943 break;
7944 case CP0_REGISTER_14:
7945 switch (sel) {
7946 case 0:
7947 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7948 register_name = "EPC";
7949 break;
7950 default:
7951 goto cp0_unimplemented;
7952 }
7953 break;
7954 case CP0_REGISTER_15:
7955 switch (sel) {
7956 case 0:
7957 /* ignored */
7958 register_name = "PRid";
7959 break;
7960 case 1:
7961 check_insn(ctx, ISA_MIPS32R2);
7962 gen_helper_mtc0_ebase(cpu_env, arg);
7963 register_name = "EBase";
7964 break;
7965 default:
7966 goto cp0_unimplemented;
7967 }
7968 break;
7969 case CP0_REGISTER_16:
7970 switch (sel) {
7971 case 0:
7972 gen_helper_mtc0_config0(cpu_env, arg);
7973 register_name = "Config";
7974 /* Stop translation as we may have switched the execution mode */
7975 ctx->base.is_jmp = DISAS_STOP;
7976 break;
7977 case 1:
7978 /* ignored, read only */
7979 register_name = "Config1";
7980 break;
7981 case 2:
7982 gen_helper_mtc0_config2(cpu_env, arg);
7983 register_name = "Config2";
7984 /* Stop translation as we may have switched the execution mode */
7985 ctx->base.is_jmp = DISAS_STOP;
7986 break;
7987 case 3:
7988 gen_helper_mtc0_config3(cpu_env, arg);
7989 register_name = "Config3";
7990 /* Stop translation as we may have switched the execution mode */
7991 ctx->base.is_jmp = DISAS_STOP;
7992 break;
7993 case 4:
7994 gen_helper_mtc0_config4(cpu_env, arg);
7995 register_name = "Config4";
7996 ctx->base.is_jmp = DISAS_STOP;
7997 break;
7998 case 5:
7999 gen_helper_mtc0_config5(cpu_env, arg);
8000 register_name = "Config5";
8001 /* Stop translation as we may have switched the execution mode */
8002 ctx->base.is_jmp = DISAS_STOP;
8003 break;
8004 /* 6,7 are implementation dependent */
8005 case 6:
8006 /* ignored */
8007 register_name = "Config6";
8008 break;
8009 case 7:
8010 /* ignored */
8011 register_name = "Config7";
8012 break;
8013 default:
8014 register_name = "Invalid config selector";
8015 goto cp0_unimplemented;
8016 }
8017 break;
8018 case CP0_REGISTER_17:
8019 switch (sel) {
8020 case 0:
8021 gen_helper_mtc0_lladdr(cpu_env, arg);
8022 register_name = "LLAddr";
8023 break;
8024 case 1:
8025 CP0_CHECK(ctx->mrp);
8026 gen_helper_mtc0_maar(cpu_env, arg);
8027 register_name = "MAAR";
8028 break;
8029 case 2:
8030 CP0_CHECK(ctx->mrp);
8031 gen_helper_mtc0_maari(cpu_env, arg);
8032 register_name = "MAARI";
8033 break;
8034 default:
8035 goto cp0_unimplemented;
8036 }
8037 break;
8038 case CP0_REGISTER_18:
8039 switch (sel) {
8040 case 0:
8041 case 1:
8042 case 2:
8043 case 3:
8044 case 4:
8045 case 5:
8046 case 6:
8047 case 7:
8048 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8049 gen_helper_0e1i(mtc0_watchlo, arg, sel);
8050 register_name = "WatchLo";
8051 break;
8052 default:
8053 goto cp0_unimplemented;
8054 }
8055 break;
8056 case CP0_REGISTER_19:
8057 switch (sel) {
8058 case 0:
8059 case 1:
8060 case 2:
8061 case 3:
8062 case 4:
8063 case 5:
8064 case 6:
8065 case 7:
8066 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8067 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8068 register_name = "WatchHi";
8069 break;
8070 default:
8071 goto cp0_unimplemented;
8072 }
8073 break;
8074 case CP0_REGISTER_20:
8075 switch (sel) {
8076 case 0:
8077 #if defined(TARGET_MIPS64)
8078 check_insn(ctx, ISA_MIPS3);
8079 gen_helper_mtc0_xcontext(cpu_env, arg);
8080 register_name = "XContext";
8081 break;
8082 #endif
8083 default:
8084 goto cp0_unimplemented;
8085 }
8086 break;
8087 case CP0_REGISTER_21:
8088 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8089 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8090 switch (sel) {
8091 case 0:
8092 gen_helper_mtc0_framemask(cpu_env, arg);
8093 register_name = "Framemask";
8094 break;
8095 default:
8096 goto cp0_unimplemented;
8097 }
8098 break;
8099 case CP0_REGISTER_22:
8100 /* ignored */
8101 register_name = "Diagnostic"; /* implementation dependent */
8102 break;
8103 case CP0_REGISTER_23:
8104 switch (sel) {
8105 case 0:
8106 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8107 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8108 gen_save_pc(ctx->base.pc_next + 4);
8109 ctx->base.is_jmp = DISAS_EXIT;
8110 register_name = "Debug";
8111 break;
8112 case 1:
8113 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8114 register_name = "TraceControl";
8115 /* Stop translation as we may have switched the execution mode */
8116 ctx->base.is_jmp = DISAS_STOP;
8117 goto cp0_unimplemented;
8118 case 2:
8119 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8120 register_name = "TraceControl2";
8121 /* Stop translation as we may have switched the execution mode */
8122 ctx->base.is_jmp = DISAS_STOP;
8123 goto cp0_unimplemented;
8124 case 3:
8125 /* Stop translation as we may have switched the execution mode */
8126 ctx->base.is_jmp = DISAS_STOP;
8127 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8128 register_name = "UserTraceData";
8129 /* Stop translation as we may have switched the execution mode */
8130 ctx->base.is_jmp = DISAS_STOP;
8131 goto cp0_unimplemented;
8132 case 4:
8133 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8134 /* Stop translation as we may have switched the execution mode */
8135 ctx->base.is_jmp = DISAS_STOP;
8136 register_name = "TraceBPC";
8137 goto cp0_unimplemented;
8138 default:
8139 goto cp0_unimplemented;
8140 }
8141 break;
8142 case CP0_REGISTER_24:
8143 switch (sel) {
8144 case 0:
8145 /* EJTAG support */
8146 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8147 register_name = "DEPC";
8148 break;
8149 default:
8150 goto cp0_unimplemented;
8151 }
8152 break;
8153 case CP0_REGISTER_25:
8154 switch (sel) {
8155 case 0:
8156 gen_helper_mtc0_performance0(cpu_env, arg);
8157 register_name = "Performance0";
8158 break;
8159 case 1:
8160 /* gen_helper_mtc0_performance1(arg); */
8161 register_name = "Performance1";
8162 goto cp0_unimplemented;
8163 case 2:
8164 /* gen_helper_mtc0_performance2(arg); */
8165 register_name = "Performance2";
8166 goto cp0_unimplemented;
8167 case 3:
8168 /* gen_helper_mtc0_performance3(arg); */
8169 register_name = "Performance3";
8170 goto cp0_unimplemented;
8171 case 4:
8172 /* gen_helper_mtc0_performance4(arg); */
8173 register_name = "Performance4";
8174 goto cp0_unimplemented;
8175 case 5:
8176 /* gen_helper_mtc0_performance5(arg); */
8177 register_name = "Performance5";
8178 goto cp0_unimplemented;
8179 case 6:
8180 /* gen_helper_mtc0_performance6(arg); */
8181 register_name = "Performance6";
8182 goto cp0_unimplemented;
8183 case 7:
8184 /* gen_helper_mtc0_performance7(arg); */
8185 register_name = "Performance7";
8186 goto cp0_unimplemented;
8187 default:
8188 goto cp0_unimplemented;
8189 }
8190 break;
8191 case CP0_REGISTER_26:
8192 switch (sel) {
8193 case 0:
8194 gen_helper_mtc0_errctl(cpu_env, arg);
8195 ctx->base.is_jmp = DISAS_STOP;
8196 register_name = "ErrCtl";
8197 break;
8198 default:
8199 goto cp0_unimplemented;
8200 }
8201 break;
8202 case CP0_REGISTER_27:
8203 switch (sel) {
8204 case 0:
8205 case 1:
8206 case 2:
8207 case 3:
8208 /* ignored */
8209 register_name = "CacheErr";
8210 break;
8211 default:
8212 goto cp0_unimplemented;
8213 }
8214 break;
8215 case CP0_REGISTER_28:
8216 switch (sel) {
8217 case 0:
8218 case 2:
8219 case 4:
8220 case 6:
8221 gen_helper_mtc0_taglo(cpu_env, arg);
8222 register_name = "TagLo";
8223 break;
8224 case 1:
8225 case 3:
8226 case 5:
8227 case 7:
8228 gen_helper_mtc0_datalo(cpu_env, arg);
8229 register_name = "DataLo";
8230 break;
8231 default:
8232 goto cp0_unimplemented;
8233 }
8234 break;
8235 case CP0_REGISTER_29:
8236 switch (sel) {
8237 case 0:
8238 case 2:
8239 case 4:
8240 case 6:
8241 gen_helper_mtc0_taghi(cpu_env, arg);
8242 register_name = "TagHi";
8243 break;
8244 case 1:
8245 case 3:
8246 case 5:
8247 case 7:
8248 gen_helper_mtc0_datahi(cpu_env, arg);
8249 register_name = "DataHi";
8250 break;
8251 default:
8252 register_name = "invalid sel";
8253 goto cp0_unimplemented;
8254 }
8255 break;
8256 case CP0_REGISTER_30:
8257 switch (sel) {
8258 case 0:
8259 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8260 register_name = "ErrorEPC";
8261 break;
8262 default:
8263 goto cp0_unimplemented;
8264 }
8265 break;
8266 case CP0_REGISTER_31:
8267 switch (sel) {
8268 case 0:
8269 /* EJTAG support */
8270 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8271 register_name = "DESAVE";
8272 break;
8273 case 2:
8274 case 3:
8275 case 4:
8276 case 5:
8277 case 6:
8278 case 7:
8279 CP0_CHECK(ctx->kscrexist & (1 << sel));
8280 tcg_gen_st_tl(arg, cpu_env,
8281 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8282 register_name = "KScratch";
8283 break;
8284 default:
8285 goto cp0_unimplemented;
8286 }
8287 break;
8288 default:
8289 goto cp0_unimplemented;
8290 }
8291 trace_mips_translate_c0("mtc0", register_name, reg, sel);
8292
8293 /* For simplicity assume that all writes can cause interrupts. */
8294 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8295 gen_io_end();
8296 /*
8297 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8298 * translated code to check for pending interrupts.
8299 */
8300 gen_save_pc(ctx->base.pc_next + 4);
8301 ctx->base.is_jmp = DISAS_EXIT;
8302 }
8303 return;
8304
8305 cp0_unimplemented:
8306 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8307 register_name, reg, sel);
8308 }
8309
8310 #if defined(TARGET_MIPS64)
8311 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8312 {
8313 const char *register_name = "invalid";
8314
8315 if (sel != 0) {
8316 check_insn(ctx, ISA_MIPS64);
8317 }
8318
8319 switch (reg) {
8320 case CP0_REGISTER_00:
8321 switch (sel) {
8322 case 0:
8323 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8324 register_name = "Index";
8325 break;
8326 case 1:
8327 CP0_CHECK(ctx->insn_flags & ASE_MT);
8328 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8329 register_name = "MVPControl";
8330 break;
8331 case 2:
8332 CP0_CHECK(ctx->insn_flags & ASE_MT);
8333 gen_helper_mfc0_mvpconf0(arg, cpu_env);
8334 register_name = "MVPConf0";
8335 break;
8336 case 3:
8337 CP0_CHECK(ctx->insn_flags & ASE_MT);
8338 gen_helper_mfc0_mvpconf1(arg, cpu_env);
8339 register_name = "MVPConf1";
8340 break;
8341 case 4:
8342 CP0_CHECK(ctx->vp);
8343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8344 register_name = "VPControl";
8345 break;
8346 default:
8347 goto cp0_unimplemented;
8348 }
8349 break;
8350 case CP0_REGISTER_01:
8351 switch (sel) {
8352 case 0:
8353 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8354 gen_helper_mfc0_random(arg, cpu_env);
8355 register_name = "Random";
8356 break;
8357 case 1:
8358 CP0_CHECK(ctx->insn_flags & ASE_MT);
8359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8360 register_name = "VPEControl";
8361 break;
8362 case 2:
8363 CP0_CHECK(ctx->insn_flags & ASE_MT);
8364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8365 register_name = "VPEConf0";
8366 break;
8367 case 3:
8368 CP0_CHECK(ctx->insn_flags & ASE_MT);
8369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8370 register_name = "VPEConf1";
8371 break;
8372 case 4:
8373 CP0_CHECK(ctx->insn_flags & ASE_MT);
8374 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8375 register_name = "YQMask";
8376 break;
8377 case 5:
8378 CP0_CHECK(ctx->insn_flags & ASE_MT);
8379 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8380 register_name = "VPESchedule";
8381 break;
8382 case 6:
8383 CP0_CHECK(ctx->insn_flags & ASE_MT);
8384 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8385 register_name = "VPEScheFBack";
8386 break;
8387 case 7:
8388 CP0_CHECK(ctx->insn_flags & ASE_MT);
8389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8390 register_name = "VPEOpt";
8391 break;
8392 default:
8393 goto cp0_unimplemented;
8394 }
8395 break;
8396 case CP0_REGISTER_02:
8397 switch (sel) {
8398 case 0:
8399 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8400 register_name = "EntryLo0";
8401 break;
8402 case 1:
8403 CP0_CHECK(ctx->insn_flags & ASE_MT);
8404 gen_helper_mfc0_tcstatus(arg, cpu_env);
8405 register_name = "TCStatus";
8406 break;
8407 case 2:
8408 CP0_CHECK(ctx->insn_flags & ASE_MT);
8409 gen_helper_mfc0_tcbind(arg, cpu_env);
8410 register_name = "TCBind";
8411 break;
8412 case 3:
8413 CP0_CHECK(ctx->insn_flags & ASE_MT);
8414 gen_helper_dmfc0_tcrestart(arg, cpu_env);
8415 register_name = "TCRestart";
8416 break;
8417 case 4:
8418 CP0_CHECK(ctx->insn_flags & ASE_MT);
8419 gen_helper_dmfc0_tchalt(arg, cpu_env);
8420 register_name = "TCHalt";
8421 break;
8422 case 5:
8423 CP0_CHECK(ctx->insn_flags & ASE_MT);
8424 gen_helper_dmfc0_tccontext(arg, cpu_env);
8425 register_name = "TCContext";
8426 break;
8427 case 6:
8428 CP0_CHECK(ctx->insn_flags & ASE_MT);
8429 gen_helper_dmfc0_tcschedule(arg, cpu_env);
8430 register_name = "TCSchedule";
8431 break;
8432 case 7:
8433 CP0_CHECK(ctx->insn_flags & ASE_MT);
8434 gen_helper_dmfc0_tcschefback(arg, cpu_env);
8435 register_name = "TCScheFBack";
8436 break;
8437 default:
8438 goto cp0_unimplemented;
8439 }
8440 break;
8441 case CP0_REGISTER_03:
8442 switch (sel) {
8443 case 0:
8444 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8445 register_name = "EntryLo1";
8446 break;
8447 case 1:
8448 CP0_CHECK(ctx->vp);
8449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8450 register_name = "GlobalNumber";
8451 break;
8452 default:
8453 goto cp0_unimplemented;
8454 }
8455 break;
8456 case CP0_REGISTER_04:
8457 switch (sel) {
8458 case 0:
8459 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8460 register_name = "Context";
8461 break;
8462 case 1:
8463 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8464 register_name = "ContextConfig";
8465 goto cp0_unimplemented;
8466 case 2:
8467 CP0_CHECK(ctx->ulri);
8468 tcg_gen_ld_tl(arg, cpu_env,
8469 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8470 register_name = "UserLocal";
8471 break;
8472 default:
8473 goto cp0_unimplemented;
8474 }
8475 break;
8476 case CP0_REGISTER_05:
8477 switch (sel) {
8478 case 0:
8479 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8480 register_name = "PageMask";
8481 break;
8482 case 1:
8483 check_insn(ctx, ISA_MIPS32R2);
8484 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8485 register_name = "PageGrain";
8486 break;
8487 case 2:
8488 CP0_CHECK(ctx->sc);
8489 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8490 register_name = "SegCtl0";
8491 break;
8492 case 3:
8493 CP0_CHECK(ctx->sc);
8494 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8495 register_name = "SegCtl1";
8496 break;
8497 case 4:
8498 CP0_CHECK(ctx->sc);
8499 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8500 register_name = "SegCtl2";
8501 break;
8502 case 5:
8503 check_pw(ctx);
8504 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8505 register_name = "PWBase";
8506 break;
8507 case 6:
8508 check_pw(ctx);
8509 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8510 register_name = "PWField";
8511 break;
8512 case 7:
8513 check_pw(ctx);
8514 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8515 register_name = "PWSize";
8516 break;
8517 default:
8518 goto cp0_unimplemented;
8519 }
8520 break;
8521 case CP0_REGISTER_06:
8522 switch (sel) {
8523 case 0:
8524 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8525 register_name = "Wired";
8526 break;
8527 case 1:
8528 check_insn(ctx, ISA_MIPS32R2);
8529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8530 register_name = "SRSConf0";
8531 break;
8532 case 2:
8533 check_insn(ctx, ISA_MIPS32R2);
8534 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8535 register_name = "SRSConf1";
8536 break;
8537 case 3:
8538 check_insn(ctx, ISA_MIPS32R2);
8539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8540 register_name = "SRSConf2";
8541 break;
8542 case 4:
8543 check_insn(ctx, ISA_MIPS32R2);
8544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8545 register_name = "SRSConf3";
8546 break;
8547 case 5:
8548 check_insn(ctx, ISA_MIPS32R2);
8549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8550 register_name = "SRSConf4";
8551 break;
8552 case 6:
8553 check_pw(ctx);
8554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8555 register_name = "PWCtl";
8556 break;
8557 default:
8558 goto cp0_unimplemented;
8559 }
8560 break;
8561 case CP0_REGISTER_07:
8562 switch (sel) {
8563 case 0:
8564 check_insn(ctx, ISA_MIPS32R2);
8565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8566 register_name = "HWREna";
8567 break;
8568 default:
8569 goto cp0_unimplemented;
8570 }
8571 break;
8572 case CP0_REGISTER_08:
8573 switch (sel) {
8574 case 0:
8575 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8576 register_name = "BadVAddr";
8577 break;
8578 case 1:
8579 CP0_CHECK(ctx->bi);
8580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8581 register_name = "BadInstr";
8582 break;
8583 case 2:
8584 CP0_CHECK(ctx->bp);
8585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8586 register_name = "BadInstrP";
8587 break;
8588 case 3:
8589 CP0_CHECK(ctx->bi);
8590 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8591 tcg_gen_andi_tl(arg, arg, ~0xffff);
8592 register_name = "BadInstrX";
8593 break;
8594 default:
8595 goto cp0_unimplemented;
8596 }
8597 break;
8598 case CP0_REGISTER_09:
8599 switch (sel) {
8600 case 0:
8601 /* Mark as an IO operation because we read the time. */
8602 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8603 gen_io_start();
8604 }
8605 gen_helper_mfc0_count(arg, cpu_env);
8606 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8607 gen_io_end();
8608 }
8609 /*
8610 * Break the TB to be able to take timer interrupts immediately
8611 * after reading count. DISAS_STOP isn't sufficient, we need to
8612 * ensure we break completely out of translated code.
8613 */
8614 gen_save_pc(ctx->base.pc_next + 4);
8615 ctx->base.is_jmp = DISAS_EXIT;
8616 register_name = "Count";
8617 break;
8618 case 6:
8619 CP0_CHECK(ctx->saar);
8620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8621 register_name = "SAARI";
8622 break;
8623 case 7:
8624 CP0_CHECK(ctx->saar);
8625 gen_helper_dmfc0_saar(arg, cpu_env);
8626 register_name = "SAAR";
8627 break;
8628 default:
8629 goto cp0_unimplemented;
8630 }
8631 break;
8632 case CP0_REGISTER_10:
8633 switch (sel) {
8634 case 0:
8635 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8636 register_name = "EntryHi";
8637 break;
8638 default:
8639 goto cp0_unimplemented;
8640 }
8641 break;
8642 case CP0_REGISTER_11:
8643 switch (sel) {
8644 case 0:
8645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8646 register_name = "Compare";
8647 break;
8648 /* 6,7 are implementation dependent */
8649 default:
8650 goto cp0_unimplemented;
8651 }
8652 break;
8653 case CP0_REGISTER_12:
8654 switch (sel) {
8655 case 0:
8656 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8657 register_name = "Status";
8658 break;
8659 case 1:
8660 check_insn(ctx, ISA_MIPS32R2);
8661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8662 register_name = "IntCtl";
8663 break;
8664 case 2:
8665 check_insn(ctx, ISA_MIPS32R2);
8666 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8667 register_name = "SRSCtl";
8668 break;
8669 case 3:
8670 check_insn(ctx, ISA_MIPS32R2);
8671 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8672 register_name = "SRSMap";
8673 break;
8674 default:
8675 goto cp0_unimplemented;
8676 }
8677 break;
8678 case CP0_REGISTER_13:
8679 switch (sel) {
8680 case 0:
8681 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8682 register_name = "Cause";
8683 break;
8684 default:
8685 goto cp0_unimplemented;
8686 }
8687 break;
8688 case CP0_REGISTER_14:
8689 switch (sel) {
8690 case 0:
8691 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8692 register_name = "EPC";
8693 break;
8694 default:
8695 goto cp0_unimplemented;
8696 }
8697 break;
8698 case CP0_REGISTER_15:
8699 switch (sel) {
8700 case 0:
8701 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8702 register_name = "PRid";
8703 break;
8704 case 1:
8705 check_insn(ctx, ISA_MIPS32R2);
8706 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8707 register_name = "EBase";
8708 break;
8709 case 3:
8710 check_insn(ctx, ISA_MIPS32R2);
8711 CP0_CHECK(ctx->cmgcr);
8712 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8713 register_name = "CMGCRBase";
8714 break;
8715 default:
8716 goto cp0_unimplemented;
8717 }
8718 break;
8719 case CP0_REGISTER_16:
8720 switch (sel) {
8721 case 0:
8722 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8723 register_name = "Config";
8724 break;
8725 case 1:
8726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8727 register_name = "Config1";
8728 break;
8729 case 2:
8730 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8731 register_name = "Config2";
8732 break;
8733 case 3:
8734 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8735 register_name = "Config3";
8736 break;
8737 case 4:
8738 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8739 register_name = "Config4";
8740 break;
8741 case 5:
8742 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8743 register_name = "Config5";
8744 break;
8745 /* 6,7 are implementation dependent */
8746 case 6:
8747 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8748 register_name = "Config6";
8749 break;
8750 case 7:
8751 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8752 register_name = "Config7";
8753 break;
8754 default:
8755 goto cp0_unimplemented;
8756 }
8757 break;
8758 case CP0_REGISTER_17:
8759 switch (sel) {
8760 case 0:
8761 gen_helper_dmfc0_lladdr(arg, cpu_env);
8762 register_name = "LLAddr";
8763 break;
8764 case 1:
8765 CP0_CHECK(ctx->mrp);
8766 gen_helper_dmfc0_maar(arg, cpu_env);
8767 register_name = "MAAR";
8768 break;
8769 case 2:
8770 CP0_CHECK(ctx->mrp);
8771 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8772 register_name = "MAARI";
8773 break;
8774 default:
8775 goto cp0_unimplemented;
8776 }
8777 break;
8778 case CP0_REGISTER_18:
8779 switch (sel) {
8780 case 0:
8781 case 1:
8782 case 2:
8783 case 3:
8784 case 4:
8785 case 5:
8786 case 6:
8787 case 7:
8788 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8789 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8790 register_name = "WatchLo";
8791 break;
8792 default:
8793 goto cp0_unimplemented;
8794 }
8795 break;
8796 case CP0_REGISTER_19:
8797 switch (sel) {
8798 case 0:
8799 case 1:
8800 case 2:
8801 case 3:
8802 case 4:
8803 case 5:
8804 case 6:
8805 case 7:
8806 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8807 gen_helper_1e0i(mfc0_watchhi, arg, sel);
8808 register_name = "WatchHi";
8809 break;
8810 default:
8811 goto cp0_unimplemented;
8812 }
8813 break;
8814 case CP0_REGISTER_20:
8815 switch (sel) {
8816 case 0:
8817 check_insn(ctx, ISA_MIPS3);
8818 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8819 register_name = "XContext";
8820 break;
8821 default:
8822 goto cp0_unimplemented;
8823 }
8824 break;
8825 case CP0_REGISTER_21:
8826 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8827 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8828 switch (sel) {
8829 case 0:
8830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8831 register_name = "Framemask";
8832 break;
8833 default:
8834 goto cp0_unimplemented;
8835 }
8836 break;
8837 case CP0_REGISTER_22:
8838 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8839 register_name = "'Diagnostic"; /* implementation dependent */
8840 break;
8841 case CP0_REGISTER_23:
8842 switch (sel) {
8843 case 0:
8844 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8845 register_name = "Debug";
8846 break;
8847 case 1:
8848 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8849 register_name = "TraceControl";
8850 goto cp0_unimplemented;
8851 case 2:
8852 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8853 register_name = "TraceControl2";
8854 goto cp0_unimplemented;
8855 case 3:
8856 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8857 register_name = "UserTraceData";
8858 goto cp0_unimplemented;
8859 case 4:
8860 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8861 register_name = "TraceBPC";
8862 goto cp0_unimplemented;
8863 default:
8864 goto cp0_unimplemented;
8865 }
8866 break;
8867 case CP0_REGISTER_24:
8868 switch (sel) {
8869 case 0:
8870 /* EJTAG support */
8871 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8872 register_name = "DEPC";
8873 break;
8874 default:
8875 goto cp0_unimplemented;
8876 }
8877 break;
8878 case CP0_REGISTER_25:
8879 switch (sel) {
8880 case 0:
8881 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8882 register_name = "Performance0";
8883 break;
8884 case 1:
8885 /* gen_helper_dmfc0_performance1(arg); */
8886 register_name = "Performance1";
8887 goto cp0_unimplemented;
8888 case 2:
8889 /* gen_helper_dmfc0_performance2(arg); */
8890 register_name = "Performance2";
8891 goto cp0_unimplemented;
8892 case 3:
8893 /* gen_helper_dmfc0_performance3(arg); */
8894 register_name = "Performance3";
8895 goto cp0_unimplemented;
8896 case 4:
8897 /* gen_helper_dmfc0_performance4(arg); */
8898 register_name = "Performance4";
8899 goto cp0_unimplemented;
8900 case 5:
8901 /* gen_helper_dmfc0_performance5(arg); */
8902 register_name = "Performance5";
8903 goto cp0_unimplemented;
8904 case 6:
8905 /* gen_helper_dmfc0_performance6(arg); */
8906 register_name = "Performance6";
8907 goto cp0_unimplemented;
8908 case 7:
8909 /* gen_helper_dmfc0_performance7(arg); */
8910 register_name = "Performance7";
8911 goto cp0_unimplemented;
8912 default:
8913 goto cp0_unimplemented;
8914 }
8915 break;
8916 case CP0_REGISTER_26:
8917 switch (sel) {
8918 case 0:
8919 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8920 register_name = "ErrCtl";
8921 break;
8922 default:
8923 goto cp0_unimplemented;
8924 }
8925 break;
8926 case CP0_REGISTER_27:
8927 switch (sel) {
8928 /* ignored */
8929 case 0:
8930 case 1:
8931 case 2:
8932 case 3:
8933 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8934 register_name = "CacheErr";
8935 break;
8936 default:
8937 goto cp0_unimplemented;
8938 }
8939 break;
8940 case CP0_REGISTER_28:
8941 switch (sel) {
8942 case 0:
8943 case 2:
8944 case 4:
8945 case 6:
8946 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8947 register_name = "TagLo";
8948 break;
8949 case 1:
8950 case 3:
8951 case 5:
8952 case 7:
8953 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8954 register_name = "DataLo";
8955 break;
8956 default:
8957 goto cp0_unimplemented;
8958 }
8959 break;
8960 case CP0_REGISTER_29:
8961 switch (sel) {
8962 case 0:
8963 case 2:
8964 case 4:
8965 case 6:
8966 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8967 register_name = "TagHi";
8968 break;
8969 case 1:
8970 case 3:
8971 case 5:
8972 case 7:
8973 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8974 register_name = "DataHi";
8975 break;
8976 default:
8977 goto cp0_unimplemented;
8978 }
8979 break;
8980 case CP0_REGISTER_30:
8981 switch (sel) {
8982 case 0:
8983 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8984 register_name = "ErrorEPC";
8985 break;
8986 default:
8987 goto cp0_unimplemented;
8988 }
8989 break;
8990 case CP0_REGISTER_31:
8991 switch (sel) {
8992 case 0:
8993 /* EJTAG support */
8994 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8995 register_name = "DESAVE";
8996 break;
8997 case 2:
8998 case 3:
8999 case 4:
9000 case 5:
9001 case 6:
9002 case 7:
9003 CP0_CHECK(ctx->kscrexist & (1 << sel));
9004 tcg_gen_ld_tl(arg, cpu_env,
9005 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9006 register_name = "KScratch";
9007 break;
9008 default:
9009 goto cp0_unimplemented;
9010 }
9011 break;
9012 default:
9013 goto cp0_unimplemented;
9014 }
9015 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
9016 return;
9017
9018 cp0_unimplemented:
9019 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
9020 register_name, reg, sel);
9021 gen_mfc0_unimplemented(ctx, arg);
9022 }
9023
9024 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9025 {
9026 const char *register_name = "invalid";
9027
9028 if (sel != 0) {
9029 check_insn(ctx, ISA_MIPS64);
9030 }
9031
9032 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9033 gen_io_start();
9034 }
9035
9036 switch (reg) {
9037 case CP0_REGISTER_00:
9038 switch (sel) {
9039 case 0:
9040 gen_helper_mtc0_index(cpu_env, arg);
9041 register_name = "Index";
9042 break;
9043 case 1:
9044 CP0_CHECK(ctx->insn_flags & ASE_MT);
9045 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9046 register_name = "MVPControl";
9047 break;
9048 case 2:
9049 CP0_CHECK(ctx->insn_flags & ASE_MT);
9050 /* ignored */
9051 register_name = "MVPConf0";
9052 break;
9053 case 3:
9054 CP0_CHECK(ctx->insn_flags & ASE_MT);
9055 /* ignored */
9056 register_name = "MVPConf1";
9057 break;
9058 case 4:
9059 CP0_CHECK(ctx->vp);
9060 /* ignored */
9061 register_name = "VPControl";
9062 break;
9063 default:
9064 goto cp0_unimplemented;
9065 }
9066 break;
9067 case CP0_REGISTER_01:
9068 switch (sel) {
9069 case 0:
9070 /* ignored */
9071 register_name = "Random";
9072 break;
9073 case 1:
9074 CP0_CHECK(ctx->insn_flags & ASE_MT);
9075 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9076 register_name = "VPEControl";
9077 break;
9078 case 2:
9079 CP0_CHECK(ctx->insn_flags & ASE_MT);
9080 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9081 register_name = "VPEConf0";
9082 break;
9083 case 3:
9084 CP0_CHECK(ctx->insn_flags & ASE_MT);
9085 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9086 register_name = "VPEConf1";
9087 break;
9088 case 4:
9089 CP0_CHECK(ctx->insn_flags & ASE_MT);
9090 gen_helper_mtc0_yqmask(cpu_env, arg);
9091 register_name = "YQMask";
9092 break;
9093 case 5:
9094 CP0_CHECK(ctx->insn_flags & ASE_MT);
9095 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9096 register_name = "VPESchedule";
9097 break;
9098 case 6:
9099 CP0_CHECK(ctx->insn_flags & ASE_MT);
9100 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9101 register_name = "VPEScheFBack";
9102 break;
9103 case 7:
9104 CP0_CHECK(ctx->insn_flags & ASE_MT);
9105 gen_helper_mtc0_vpeopt(cpu_env, arg);
9106 register_name = "VPEOpt";
9107 break;
9108 default:
9109 goto cp0_unimplemented;
9110 }
9111 break;
9112 case CP0_REGISTER_02:
9113 switch (sel) {
9114 case 0:
9115 gen_helper_dmtc0_entrylo0(cpu_env, arg);
9116 register_name = "EntryLo0";
9117 break;
9118 case 1:
9119 CP0_CHECK(ctx->insn_flags & ASE_MT);
9120 gen_helper_mtc0_tcstatus(cpu_env, arg);
9121 register_name = "TCStatus";
9122 break;
9123 case 2:
9124 CP0_CHECK(ctx->insn_flags & ASE_MT);
9125 gen_helper_mtc0_tcbind(cpu_env, arg);
9126 register_name = "TCBind";
9127 break;
9128 case 3:
9129 CP0_CHECK(ctx->insn_flags & ASE_MT);
9130 gen_helper_mtc0_tcrestart(cpu_env, arg);
9131 register_name = "TCRestart";
9132 break;
9133 case 4:
9134 CP0_CHECK(ctx->insn_flags & ASE_MT);
9135 gen_helper_mtc0_tchalt(cpu_env, arg);
9136 register_name = "TCHalt";
9137 break;
9138 case 5:
9139 CP0_CHECK(ctx->insn_flags & ASE_MT);
9140 gen_helper_mtc0_tccontext(cpu_env, arg);
9141 register_name = "TCContext";
9142 break;
9143 case 6:
9144 CP0_CHECK(ctx->insn_flags & ASE_MT);
9145 gen_helper_mtc0_tcschedule(cpu_env, arg);
9146 register_name = "TCSchedule";
9147 break;
9148 case 7:
9149 CP0_CHECK(ctx->insn_flags & ASE_MT);
9150 gen_helper_mtc0_tcschefback(cpu_env, arg);
9151 register_name = "TCScheFBack";
9152 break;
9153 default:
9154 goto cp0_unimplemented;
9155 }
9156 break;
9157 case CP0_REGISTER_03:
9158 switch (sel) {
9159 case 0:
9160 gen_helper_dmtc0_entrylo1(cpu_env, arg);
9161 register_name = "EntryLo1";
9162 break;
9163 case 1:
9164 CP0_CHECK(ctx->vp);
9165 /* ignored */
9166 register_name = "GlobalNumber";
9167 break;
9168 default:
9169 goto cp0_unimplemented;
9170 }
9171 break;
9172 case CP0_REGISTER_04:
9173 switch (sel) {
9174 case 0:
9175 gen_helper_mtc0_context(cpu_env, arg);
9176 register_name = "Context";
9177 break;
9178 case 1:
9179 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
9180 register_name = "ContextConfig";
9181 goto cp0_unimplemented;
9182 case 2:
9183 CP0_CHECK(ctx->ulri);
9184 tcg_gen_st_tl(arg, cpu_env,
9185 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9186 register_name = "UserLocal";
9187 break;
9188 default:
9189 goto cp0_unimplemented;
9190 }
9191 break;
9192 case CP0_REGISTER_05:
9193 switch (sel) {
9194 case 0:
9195 gen_helper_mtc0_pagemask(cpu_env, arg);
9196 register_name = "PageMask";
9197 break;
9198 case 1:
9199 check_insn(ctx, ISA_MIPS32R2);
9200 gen_helper_mtc0_pagegrain(cpu_env, arg);
9201 register_name = "PageGrain";
9202 break;
9203 case 2:
9204 CP0_CHECK(ctx->sc);
9205 gen_helper_mtc0_segctl0(cpu_env, arg);
9206 register_name = "SegCtl0";
9207 break;
9208 case 3:
9209 CP0_CHECK(ctx->sc);
9210 gen_helper_mtc0_segctl1(cpu_env, arg);
9211 register_name = "SegCtl1";
9212 break;
9213 case 4:
9214 CP0_CHECK(ctx->sc);
9215 gen_helper_mtc0_segctl2(cpu_env, arg);
9216 register_name = "SegCtl2";
9217 break;
9218 case 5:
9219 check_pw(ctx);
9220 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9221 register_name = "PWBase";
9222 break;
9223 case 6:
9224 check_pw(ctx);
9225 gen_helper_mtc0_pwfield(cpu_env, arg);
9226 register_name = "PWField";
9227 break;
9228 case 7:
9229 check_pw(ctx);
9230 gen_helper_mtc0_pwsize(cpu_env, arg);
9231 register_name = "PWSize";
9232 break;
9233 default:
9234 goto cp0_unimplemented;
9235 }
9236 break;
9237 case CP0_REGISTER_06:
9238 switch (sel) {
9239 case 0:
9240 gen_helper_mtc0_wired(cpu_env, arg);
9241 register_name = "Wired";
9242 break;
9243 case 1:
9244 check_insn(ctx, ISA_MIPS32R2);
9245 gen_helper_mtc0_srsconf0(cpu_env, arg);
9246 register_name = "SRSConf0";
9247 break;
9248 case 2:
9249 check_insn(ctx, ISA_MIPS32R2);
9250 gen_helper_mtc0_srsconf1(cpu_env, arg);
9251 register_name = "SRSConf1";
9252 break;
9253 case 3:
9254 check_insn(ctx, ISA_MIPS32R2);
9255 gen_helper_mtc0_srsconf2(cpu_env, arg);
9256 register_name = "SRSConf2";
9257 break;
9258 case 4:
9259 check_insn(ctx, ISA_MIPS32R2);
9260 gen_helper_mtc0_srsconf3(cpu_env, arg);
9261 register_name = "SRSConf3";
9262 break;
9263 case 5:
9264 check_insn(ctx, ISA_MIPS32R2);
9265 gen_helper_mtc0_srsconf4(cpu_env, arg);
9266 register_name = "SRSConf4";
9267 break;
9268 case 6:
9269 check_pw(ctx);
9270 gen_helper_mtc0_pwctl(cpu_env, arg);
9271 register_name = "PWCtl";
9272 break;
9273 default:
9274 goto cp0_unimplemented;
9275 }
9276 break;
9277 case CP0_REGISTER_07:
9278 switch (sel) {
9279 case 0:
9280 check_insn(ctx, ISA_MIPS32R2);
9281 gen_helper_mtc0_hwrena(cpu_env, arg);
9282 ctx->base.is_jmp = DISAS_STOP;
9283 register_name = "HWREna";
9284 break;
9285 default:
9286 goto cp0_unimplemented;
9287 }
9288 break;
9289 case CP0_REGISTER_08:
9290 switch (sel) {
9291 case 0:
9292 /* ignored */
9293 register_name = "BadVAddr";
9294 break;
9295 case 1:
9296 /* ignored */
9297 register_name = "BadInstr";
9298 break;
9299 case 2:
9300 /* ignored */
9301 register_name = "BadInstrP";
9302 break;
9303 case 3:
9304 /* ignored */
9305 register_name = "BadInstrX";
9306 break;
9307 default:
9308 goto cp0_unimplemented;
9309 }
9310 break;
9311 case CP0_REGISTER_09:
9312 switch (sel) {
9313 case 0:
9314 gen_helper_mtc0_count(cpu_env, arg);
9315 register_name = "Count";
9316 break;
9317 case 6:
9318 CP0_CHECK(ctx->saar);
9319 gen_helper_mtc0_saari(cpu_env, arg);
9320 register_name = "SAARI";
9321 break;
9322 case 7:
9323 CP0_CHECK(ctx->saar);
9324 gen_helper_mtc0_saar(cpu_env, arg);
9325 register_name = "SAAR";
9326 break;
9327 default:
9328 goto cp0_unimplemented;
9329 }
9330 /* Stop translation as we may have switched the execution mode */
9331 ctx->base.is_jmp = DISAS_STOP;
9332 break;
9333 case CP0_REGISTER_10:
9334 switch (sel) {
9335 case 0:
9336 gen_helper_mtc0_entryhi(cpu_env, arg);
9337 register_name = "EntryHi";
9338 break;
9339 default:
9340 goto cp0_unimplemented;
9341 }
9342 break;
9343 case CP0_REGISTER_11:
9344 switch (sel) {
9345 case 0:
9346 gen_helper_mtc0_compare(cpu_env, arg);
9347 register_name = "Compare";
9348 break;
9349 /* 6,7 are implementation dependent */
9350 default:
9351 goto cp0_unimplemented;
9352 }
9353 /* Stop translation as we may have switched the execution mode */
9354 ctx->base.is_jmp = DISAS_STOP;
9355 break;
9356 case CP0_REGISTER_12:
9357 switch (sel) {
9358 case 0:
9359 save_cpu_state(ctx, 1);
9360 gen_helper_mtc0_status(cpu_env, arg);
9361 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9362 gen_save_pc(ctx->base.pc_next + 4);
9363 ctx->base.is_jmp = DISAS_EXIT;
9364 register_name = "Status";
9365 break;
9366 case 1:
9367 check_insn(ctx, ISA_MIPS32R2);
9368 gen_helper_mtc0_intctl(cpu_env, arg);
9369 /* Stop translation as we may have switched the execution mode */
9370 ctx->base.is_jmp = DISAS_STOP;
9371 register_name = "IntCtl";
9372 break;
9373 case 2:
9374 check_insn(ctx, ISA_MIPS32R2);
9375 gen_helper_mtc0_srsctl(cpu_env, arg);
9376 /* Stop translation as we may have switched the execution mode */
9377 ctx->base.is_jmp = DISAS_STOP;
9378 register_name = "SRSCtl";
9379 break;
9380 case 3:
9381 check_insn(ctx, ISA_MIPS32R2);
9382 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9383 /* Stop translation as we may have switched the execution mode */
9384 ctx->base.is_jmp = DISAS_STOP;
9385 register_name = "SRSMap";
9386 break;
9387 default:
9388 goto cp0_unimplemented;
9389 }
9390 break;
9391 case CP0_REGISTER_13:
9392 switch (sel) {
9393 case 0:
9394 save_cpu_state(ctx, 1);
9395 gen_helper_mtc0_cause(cpu_env, arg);
9396 /*
9397 * Stop translation as we may have triggered an interrupt.
9398 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9399 * translated code to check for pending interrupts.
9400 */
9401 gen_save_pc(ctx->base.pc_next + 4);
9402 ctx->base.is_jmp = DISAS_EXIT;
9403 register_name = "Cause";
9404 break;
9405 default:
9406 goto cp0_unimplemented;
9407 }
9408 break;
9409 case CP0_REGISTER_14:
9410 switch (sel) {
9411 case 0:
9412 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9413 register_name = "EPC";
9414 break;
9415 default:
9416 goto cp0_unimplemented;
9417 }
9418 break;
9419 case CP0_REGISTER_15:
9420 switch (sel) {
9421 case 0:
9422 /* ignored */
9423 register_name = "PRid";
9424 break;
9425 case 1:
9426 check_insn(ctx, ISA_MIPS32R2);
9427 gen_helper_mtc0_ebase(cpu_env, arg);
9428 register_name = "EBase";
9429 break;
9430 default:
9431 goto cp0_unimplemented;
9432 }
9433 break;
9434 case CP0_REGISTER_16:
9435 switch (sel) {
9436 case 0:
9437 gen_helper_mtc0_config0(cpu_env, arg);
9438 register_name = "Config";
9439 /* Stop translation as we may have switched the execution mode */
9440 ctx->base.is_jmp = DISAS_STOP;
9441 break;
9442 case 1:
9443 /* ignored, read only */
9444 register_name = "Config1";
9445 break;
9446 case 2:
9447 gen_helper_mtc0_config2(cpu_env, arg);
9448 register_name = "Config2";
9449 /* Stop translation as we may have switched the execution mode */
9450 ctx->base.is_jmp = DISAS_STOP;
9451 break;
9452 case 3:
9453 gen_helper_mtc0_config3(cpu_env, arg);
9454 register_name = "Config3";
9455 /* Stop translation as we may have switched the execution mode */
9456 ctx->base.is_jmp = DISAS_STOP;
9457 break;
9458 case 4:
9459 /* currently ignored */
9460 register_name = "Config4";
9461 break;
9462 case 5:
9463 gen_helper_mtc0_config5(cpu_env, arg);
9464 register_name = "Config5";
9465 /* Stop translation as we may have switched the execution mode */
9466 ctx->base.is_jmp = DISAS_STOP;
9467 break;
9468 /* 6,7 are implementation dependent */
9469 default:
9470 register_name = "Invalid config selector";
9471 goto cp0_unimplemented;
9472 }
9473 break;
9474 case CP0_REGISTER_17:
9475 switch (sel) {
9476 case 0:
9477 gen_helper_mtc0_lladdr(cpu_env, arg);
9478 register_name = "LLAddr";
9479 break;
9480 case 1:
9481 CP0_CHECK(ctx->mrp);
9482 gen_helper_mtc0_maar(cpu_env, arg);
9483 register_name = "MAAR";
9484 break;
9485 case 2:
9486 CP0_CHECK(ctx->mrp);
9487 gen_helper_mtc0_maari(cpu_env, arg);
9488 register_name = "MAARI";
9489 break;
9490 default:
9491 goto cp0_unimplemented;
9492 }
9493 break;
9494 case CP0_REGISTER_18:
9495 switch (sel) {
9496 case 0:
9497 case 1:
9498 case 2:
9499 case 3:
9500 case 4:
9501 case 5:
9502 case 6:
9503 case 7:
9504 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9505 gen_helper_0e1i(mtc0_watchlo, arg, sel);
9506 register_name = "WatchLo";
9507 break;
9508 default:
9509 goto cp0_unimplemented;
9510 }
9511 break;
9512 case CP0_REGISTER_19:
9513 switch (sel) {
9514 case 0:
9515 case 1:
9516 case 2:
9517 case 3:
9518 case 4:
9519 case 5:
9520 case 6:
9521 case 7:
9522 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9523 gen_helper_0e1i(mtc0_watchhi, arg, sel);
9524 register_name = "WatchHi";
9525 break;
9526 default:
9527 goto cp0_unimplemented;
9528 }
9529 break;
9530 case CP0_REGISTER_20:
9531 switch (sel) {
9532 case 0:
9533 check_insn(ctx, ISA_MIPS3);
9534 gen_helper_mtc0_xcontext(cpu_env, arg);
9535 register_name = "XContext";
9536 break;
9537 default:
9538 goto cp0_unimplemented;
9539 }
9540 break;
9541 case CP0_REGISTER_21:
9542 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9543 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9544 switch (sel) {
9545 case 0:
9546 gen_helper_mtc0_framemask(cpu_env, arg);
9547 register_name = "Framemask";
9548 break;
9549 default:
9550 goto cp0_unimplemented;
9551 }
9552 break;
9553 case CP0_REGISTER_22:
9554 /* ignored */
9555 register_name = "Diagnostic"; /* implementation dependent */
9556 break;
9557 case CP0_REGISTER_23:
9558 switch (sel) {
9559 case 0:
9560 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9561 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9562 gen_save_pc(ctx->base.pc_next + 4);
9563 ctx->base.is_jmp = DISAS_EXIT;
9564 register_name = "Debug";
9565 break;
9566 case 1:
9567 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9568 /* Stop translation as we may have switched the execution mode */
9569 ctx->base.is_jmp = DISAS_STOP;
9570 register_name = "TraceControl";
9571 goto cp0_unimplemented;
9572 case 2:
9573 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9574 /* Stop translation as we may have switched the execution mode */
9575 ctx->base.is_jmp = DISAS_STOP;
9576 register_name = "TraceControl2";
9577 goto cp0_unimplemented;
9578 case 3:
9579 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9580 /* Stop translation as we may have switched the execution mode */
9581 ctx->base.is_jmp = DISAS_STOP;
9582 register_name = "UserTraceData";
9583 goto cp0_unimplemented;
9584 case 4:
9585 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9586 /* Stop translation as we may have switched the execution mode */
9587 ctx->base.is_jmp = DISAS_STOP;
9588 register_name = "TraceBPC";
9589 goto cp0_unimplemented;
9590 default:
9591 goto cp0_unimplemented;
9592 }
9593 break;
9594 case CP0_REGISTER_24:
9595 switch (sel) {
9596 case 0:
9597 /* EJTAG support */
9598 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9599 register_name = "DEPC";
9600 break;
9601 default:
9602 goto cp0_unimplemented;
9603 }
9604 break;
9605 case CP0_REGISTER_25:
9606 switch (sel) {
9607 case 0:
9608 gen_helper_mtc0_performance0(cpu_env, arg);
9609 register_name = "Performance0";
9610 break;
9611 case 1:
9612 /* gen_helper_mtc0_performance1(cpu_env, arg); */
9613 register_name = "Performance1";
9614 goto cp0_unimplemented;
9615 case 2:
9616 /* gen_helper_mtc0_performance2(cpu_env, arg); */
9617 register_name = "Performance2";
9618 goto cp0_unimplemented;
9619 case 3:
9620 /* gen_helper_mtc0_performance3(cpu_env, arg); */
9621 register_name = "Performance3";
9622 goto cp0_unimplemented;
9623 case 4:
9624 /* gen_helper_mtc0_performance4(cpu_env, arg); */
9625 register_name = "Performance4";
9626 goto cp0_unimplemented;
9627 case 5:
9628 /* gen_helper_mtc0_performance5(cpu_env, arg); */
9629 register_name = "Performance5";
9630 goto cp0_unimplemented;
9631 case 6:
9632 /* gen_helper_mtc0_performance6(cpu_env, arg); */
9633 register_name = "Performance6";
9634 goto cp0_unimplemented;
9635 case 7:
9636 /* gen_helper_mtc0_performance7(cpu_env, arg); */
9637 register_name = "Performance7";
9638 goto cp0_unimplemented;
9639 default:
9640 goto cp0_unimplemented;
9641 }
9642 break;
9643 case CP0_REGISTER_26:
9644 switch (sel) {
9645 case 0:
9646 gen_helper_mtc0_errctl(cpu_env, arg);
9647 ctx->base.is_jmp = DISAS_STOP;
9648 register_name = "ErrCtl";
9649 break;
9650 default:
9651 goto cp0_unimplemented;
9652 }
9653 break;
9654 case CP0_REGISTER_27:
9655 switch (sel) {
9656 case 0:
9657 case 1:
9658 case 2:
9659 case 3:
9660 /* ignored */
9661 register_name = "CacheErr";
9662 break;
9663 default:
9664 goto cp0_unimplemented;
9665 }
9666 break;
9667 case CP0_REGISTER_28:
9668 switch (sel) {
9669 case 0:
9670 case 2:
9671 case 4:
9672 case 6:
9673 gen_helper_mtc0_taglo(cpu_env, arg);
9674 register_name = "TagLo";
9675 break;
9676 case 1:
9677 case 3:
9678 case 5:
9679 case 7:
9680 gen_helper_mtc0_datalo(cpu_env, arg);
9681 register_name = "DataLo";
9682 break;
9683 default:
9684 goto cp0_unimplemented;
9685 }
9686 break;
9687 case CP0_REGISTER_29:
9688 switch (sel) {
9689 case 0:
9690 case 2:
9691 case 4:
9692 case 6:
9693 gen_helper_mtc0_taghi(cpu_env, arg);
9694 register_name = "TagHi";
9695 break;
9696 case 1:
9697 case 3:
9698 case 5:
9699 case 7:
9700 gen_helper_mtc0_datahi(cpu_env, arg);
9701 register_name = "DataHi";
9702 break;
9703 default:
9704 register_name = "invalid sel";
9705 goto cp0_unimplemented;
9706 }
9707 break;
9708 case CP0_REGISTER_30:
9709 switch (sel) {
9710 case 0:
9711 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9712 register_name = "ErrorEPC";
9713 break;
9714 default:
9715 goto cp0_unimplemented;
9716 }
9717 break;
9718 case CP0_REGISTER_31:
9719 switch (sel) {
9720 case 0:
9721 /* EJTAG support */
9722 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9723 register_name = "DESAVE";
9724 break;
9725 case 2:
9726 case 3:
9727 case 4:
9728 case 5:
9729 case 6:
9730 case 7:
9731 CP0_CHECK(ctx->kscrexist & (1 << sel));
9732 tcg_gen_st_tl(arg, cpu_env,
9733 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9734 register_name = "KScratch";
9735 break;
9736 default:
9737 goto cp0_unimplemented;
9738 }
9739 break;
9740 default:
9741 goto cp0_unimplemented;
9742 }
9743 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9744
9745 /* For simplicity assume that all writes can cause interrupts. */
9746 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9747 gen_io_end();
9748 /*
9749 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9750 * translated code to check for pending interrupts.
9751 */
9752 gen_save_pc(ctx->base.pc_next + 4);
9753 ctx->base.is_jmp = DISAS_EXIT;
9754 }
9755 return;
9756
9757 cp0_unimplemented:
9758 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9759 register_name, reg, sel);
9760 }
9761 #endif /* TARGET_MIPS64 */
9762
9763 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9764 int u, int sel, int h)
9765 {
9766 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9767 TCGv t0 = tcg_temp_local_new();
9768
9769 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9770 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9771 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
9772 tcg_gen_movi_tl(t0, -1);
9773 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9774 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
9775 tcg_gen_movi_tl(t0, -1);
9776 } else if (u == 0) {
9777 switch (rt) {
9778 case 1:
9779 switch (sel) {
9780 case 1:
9781 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9782 break;
9783 case 2:
9784 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9785 break;
9786 default:
9787 goto die;
9788 break;
9789 }
9790 break;
9791 case 2:
9792 switch (sel) {
9793 case 1:
9794 gen_helper_mftc0_tcstatus(t0, cpu_env);
9795 break;
9796 case 2:
9797 gen_helper_mftc0_tcbind(t0, cpu_env);
9798 break;
9799 case 3:
9800 gen_helper_mftc0_tcrestart(t0, cpu_env);
9801 break;
9802 case 4:
9803 gen_helper_mftc0_tchalt(t0, cpu_env);
9804 break;
9805 case 5:
9806 gen_helper_mftc0_tccontext(t0, cpu_env);
9807 break;
9808 case 6:
9809 gen_helper_mftc0_tcschedule(t0, cpu_env);
9810 break;
9811 case 7:
9812 gen_helper_mftc0_tcschefback(t0, cpu_env);
9813 break;
9814 default:
9815 gen_mfc0(ctx, t0, rt, sel);
9816 break;
9817 }
9818 break;
9819 case 10:
9820 switch (sel) {
9821 case 0:
9822 gen_helper_mftc0_entryhi(t0, cpu_env);
9823 break;
9824 default:
9825 gen_mfc0(ctx, t0, rt, sel);
9826 break;
9827 }
9828 case 12:
9829 switch (sel) {
9830 case 0:
9831 gen_helper_mftc0_status(t0, cpu_env);
9832 break;
9833 default:
9834 gen_mfc0(ctx, t0, rt, sel);
9835 break;
9836 }
9837 case 13:
9838 switch (sel) {
9839 case 0:
9840 gen_helper_mftc0_cause(t0, cpu_env);
9841 break;
9842 default:
9843 goto die;
9844 break;
9845 }
9846 break;
9847 case 14:
9848 switch (sel) {
9849 case 0:
9850 gen_helper_mftc0_epc(t0, cpu_env);
9851 break;
9852 default:
9853 goto die;
9854 break;
9855 }
9856 break;
9857 case 15:
9858 switch (sel) {
9859 case 1:
9860 gen_helper_mftc0_ebase(t0, cpu_env);
9861 break;
9862 default:
9863 goto die;
9864 break;
9865 }
9866 break;
9867 case 16:
9868 switch (sel) {
9869 case 0:
9870 case 1:
9871 case 2:
9872 case 3:
9873 case 4:
9874 case 5:
9875 case 6:
9876 case 7:
9877 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9878 break;
9879 default:
9880 goto die;
9881 break;
9882 }
9883 break;
9884 case 23:
9885 switch (sel) {
9886 case 0:
9887 gen_helper_mftc0_debug(t0, cpu_env);
9888 break;
9889 default:
9890 gen_mfc0(ctx, t0, rt, sel);
9891 break;
9892 }
9893 break;
9894 default:
9895 gen_mfc0(ctx, t0, rt, sel);
9896 }
9897 } else switch (sel) {
9898 /* GPR registers. */
9899 case 0:
9900 gen_helper_1e0i(mftgpr, t0, rt);
9901 break;
9902 /* Auxiliary CPU registers */
9903 case 1:
9904 switch (rt) {
9905 case 0:
9906 gen_helper_1e0i(mftlo, t0, 0);
9907 break;
9908 case 1:
9909 gen_helper_1e0i(mfthi, t0, 0);
9910 break;
9911 case 2:
9912 gen_helper_1e0i(mftacx, t0, 0);
9913 break;
9914 case 4:
9915 gen_helper_1e0i(mftlo, t0, 1);
9916 break;
9917 case 5:
9918 gen_helper_1e0i(mfthi, t0, 1);
9919 break;
9920 case 6:
9921 gen_helper_1e0i(mftacx, t0, 1);
9922 break;
9923 case 8:
9924 gen_helper_1e0i(mftlo, t0, 2);
9925 break;
9926 case 9:
9927 gen_helper_1e0i(mfthi, t0, 2);
9928 break;
9929 case 10:
9930 gen_helper_1e0i(mftacx, t0, 2);
9931 break;
9932 case 12:
9933 gen_helper_1e0i(mftlo, t0, 3);
9934 break;
9935 case 13:
9936 gen_helper_1e0i(mfthi, t0, 3);
9937 break;
9938 case 14:
9939 gen_helper_1e0i(mftacx, t0, 3);
9940 break;
9941 case 16:
9942 gen_helper_mftdsp(t0, cpu_env);
9943 break;
9944 default:
9945 goto die;
9946 }
9947 break;
9948 /* Floating point (COP1). */
9949 case 2:
9950 /* XXX: For now we support only a single FPU context. */
9951 if (h == 0) {
9952 TCGv_i32 fp0 = tcg_temp_new_i32();
9953
9954 gen_load_fpr32(ctx, fp0, rt);
9955 tcg_gen_ext_i32_tl(t0, fp0);
9956 tcg_temp_free_i32(fp0);
9957 } else {
9958 TCGv_i32 fp0 = tcg_temp_new_i32();
9959
9960 gen_load_fpr32h(ctx, fp0, rt);
9961 tcg_gen_ext_i32_tl(t0, fp0);
9962 tcg_temp_free_i32(fp0);
9963 }
9964 break;
9965 case 3:
9966 /* XXX: For now we support only a single FPU context. */
9967 gen_helper_1e0i(cfc1, t0, rt);
9968 break;
9969 /* COP2: Not implemented. */
9970 case 4:
9971 case 5:
9972 /* fall through */
9973 default:
9974 goto die;
9975 }
9976 trace_mips_translate_tr("mftr", rt, u, sel, h);
9977 gen_store_gpr(t0, rd);
9978 tcg_temp_free(t0);
9979 return;
9980
9981 die:
9982 tcg_temp_free(t0);
9983 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9984 generate_exception_end(ctx, EXCP_RI);
9985 }
9986
9987 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9988 int u, int sel, int h)
9989 {
9990 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9991 TCGv t0 = tcg_temp_local_new();
9992
9993 gen_load_gpr(t0, rt);
9994 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9995 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9996 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
9997 /* NOP */
9998 ;
9999 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
10000 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
10001 /* NOP */
10002 ;
10003 } else if (u == 0) {
10004 switch (rd) {
10005 case 1:
10006 switch (sel) {
10007 case 1:
10008 gen_helper_mttc0_vpecontrol(cpu_env, t0);
10009 break;
10010 case 2:
10011 gen_helper_mttc0_vpeconf0(cpu_env, t0);
10012 break;
10013 default:
10014 goto die;
10015 break;
10016 }
10017 break;
10018 case 2:
10019 switch (sel) {
10020 case 1:
10021 gen_helper_mttc0_tcstatus(cpu_env, t0);
10022 break;
10023 case 2:
10024 gen_helper_mttc0_tcbind(cpu_env, t0);
10025 break;
10026 case 3:
10027 gen_helper_mttc0_tcrestart(cpu_env, t0);
10028 break;
10029 case 4:
10030 gen_helper_mttc0_tchalt(cpu_env, t0);
10031 break;
10032 case 5:
10033 gen_helper_mttc0_tccontext(cpu_env, t0);
10034 break;
10035 case 6:
10036 gen_helper_mttc0_tcschedule(cpu_env, t0);
10037 break;
10038 case 7:
10039 gen_helper_mttc0_tcschefback(cpu_env, t0);
10040 break;
10041 default:
10042 gen_mtc0(ctx, t0, rd, sel);
10043 break;
10044 }
10045 break;
10046 case 10:
10047 switch (sel) {
10048 case 0:
10049 gen_helper_mttc0_entryhi(cpu_env, t0);
10050 break;
10051 default:
10052 gen_mtc0(ctx, t0, rd, sel);
10053 break;
10054 }
10055 case 12:
10056 switch (sel) {
10057 case 0:
10058 gen_helper_mttc0_status(cpu_env, t0);
10059 break;
10060 default:
10061 gen_mtc0(ctx, t0, rd, sel);
10062 break;
10063 }
10064 case 13:
10065 switch (sel) {
10066 case 0:
10067 gen_helper_mttc0_cause(cpu_env, t0);
10068 break;
10069 default:
10070 goto die;
10071 break;
10072 }
10073 break;
10074 case 15:
10075 switch (sel) {
10076 case 1:
10077 gen_helper_mttc0_ebase(cpu_env, t0);
10078 break;
10079 default:
10080 goto die;
10081 break;
10082 }
10083 break;
10084 case 23:
10085 switch (sel) {
10086 case 0:
10087 gen_helper_mttc0_debug(cpu_env, t0);
10088 break;
10089 default:
10090 gen_mtc0(ctx, t0, rd, sel);
10091 break;
10092 }
10093 break;
10094 default:
10095 gen_mtc0(ctx, t0, rd, sel);
10096 }
10097 } else switch (sel) {
10098 /* GPR registers. */
10099 case 0:
10100 gen_helper_0e1i(mttgpr, t0, rd);
10101 break;
10102 /* Auxiliary CPU registers */
10103 case 1:
10104 switch (rd) {
10105 case 0:
10106 gen_helper_0e1i(mttlo, t0, 0);
10107 break;
10108 case 1:
10109 gen_helper_0e1i(mtthi, t0, 0);
10110 break;
10111 case 2:
10112 gen_helper_0e1i(mttacx, t0, 0);
10113 break;
10114 case 4:
10115 gen_helper_0e1i(mttlo, t0, 1);
10116 break;
10117 case 5:
10118 gen_helper_0e1i(mtthi, t0, 1);
10119 break;
10120 case 6:
10121 gen_helper_0e1i(mttacx, t0, 1);
10122 break;
10123 case 8:
10124 gen_helper_0e1i(mttlo, t0, 2);
10125 break;
10126 case 9:
10127 gen_helper_0e1i(mtthi, t0, 2);
10128 break;
10129 case 10:
10130 gen_helper_0e1i(mttacx, t0, 2);
10131 break;
10132 case 12:
10133 gen_helper_0e1i(mttlo, t0, 3);
10134 break;
10135 case 13:
10136 gen_helper_0e1i(mtthi, t0, 3);
10137 break;
10138 case 14:
10139 gen_helper_0e1i(mttacx, t0, 3);
10140 break;
10141 case 16:
10142 gen_helper_mttdsp(cpu_env, t0);
10143 break;
10144 default:
10145 goto die;
10146 }
10147 break;
10148 /* Floating point (COP1). */
10149 case 2:
10150 /* XXX: For now we support only a single FPU context. */
10151 if (h == 0) {
10152 TCGv_i32 fp0 = tcg_temp_new_i32();
10153
10154 tcg_gen_trunc_tl_i32(fp0, t0);
10155 gen_store_fpr32(ctx, fp0, rd);
10156 tcg_temp_free_i32(fp0);
10157 } else {
10158 TCGv_i32 fp0 = tcg_temp_new_i32();
10159
10160 tcg_gen_trunc_tl_i32(fp0, t0);
10161 gen_store_fpr32h(ctx, fp0, rd);
10162 tcg_temp_free_i32(fp0);
10163 }
10164 break;
10165 case 3:
10166 /* XXX: For now we support only a single FPU context. */
10167 {
10168 TCGv_i32 fs_tmp = tcg_const_i32(rd);
10169
10170 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10171 tcg_temp_free_i32(fs_tmp);
10172 }
10173 /* Stop translation as we may have changed hflags */
10174 ctx->base.is_jmp = DISAS_STOP;
10175 break;
10176 /* COP2: Not implemented. */
10177 case 4:
10178 case 5:
10179 /* fall through */
10180 default:
10181 goto die;
10182 }
10183 trace_mips_translate_tr("mttr", rd, u, sel, h);
10184 tcg_temp_free(t0);
10185 return;
10186
10187 die:
10188 tcg_temp_free(t0);
10189 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10190 generate_exception_end(ctx, EXCP_RI);
10191 }
10192
10193 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
10194 int rt, int rd)
10195 {
10196 const char *opn = "ldst";
10197
10198 check_cp0_enabled(ctx);
10199 switch (opc) {
10200 case OPC_MFC0:
10201 if (rt == 0) {
10202 /* Treat as NOP. */
10203 return;
10204 }
10205 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10206 opn = "mfc0";
10207 break;
10208 case OPC_MTC0:
10209 {
10210 TCGv t0 = tcg_temp_new();
10211
10212 gen_load_gpr(t0, rt);
10213 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10214 tcg_temp_free(t0);
10215 }
10216 opn = "mtc0";
10217 break;
10218 #if defined(TARGET_MIPS64)
10219 case OPC_DMFC0:
10220 check_insn(ctx, ISA_MIPS3);
10221 if (rt == 0) {
10222 /* Treat as NOP. */
10223 return;
10224 }
10225 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10226 opn = "dmfc0";
10227 break;
10228 case OPC_DMTC0:
10229 check_insn(ctx, ISA_MIPS3);
10230 {
10231 TCGv t0 = tcg_temp_new();
10232
10233 gen_load_gpr(t0, rt);
10234 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10235 tcg_temp_free(t0);
10236 }
10237 opn = "dmtc0";
10238 break;
10239 #endif
10240 case OPC_MFHC0:
10241 check_mvh(ctx);
10242 if (rt == 0) {
10243 /* Treat as NOP. */
10244 return;
10245 }
10246 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10247 opn = "mfhc0";
10248 break;
10249 case OPC_MTHC0:
10250 check_mvh(ctx);
10251 {
10252 TCGv t0 = tcg_temp_new();
10253 gen_load_gpr(t0, rt);
10254 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10255 tcg_temp_free(t0);
10256 }
10257 opn = "mthc0";
10258 break;
10259 case OPC_MFTR:
10260 check_cp0_enabled(ctx);
10261 if (rd == 0) {
10262 /* Treat as NOP. */
10263 return;
10264 }
10265 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10266 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10267 opn = "mftr";
10268 break;
10269 case OPC_MTTR:
10270 check_cp0_enabled(ctx);
10271 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10272 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10273 opn = "mttr";
10274 break;
10275 case OPC_TLBWI:
10276 opn = "tlbwi";
10277 if (!env->tlb->helper_tlbwi) {
10278 goto die;
10279 }
10280 gen_helper_tlbwi(cpu_env);
10281 break;
10282 case OPC_TLBINV:
10283 opn = "tlbinv";
10284 if (ctx->ie >= 2) {
10285 if (!env->tlb->helper_tlbinv) {
10286 goto die;
10287 }
10288 gen_helper_tlbinv(cpu_env);
10289 } /* treat as nop if TLBINV not supported */
10290 break;
10291 case OPC_TLBINVF:
10292 opn = "tlbinvf";
10293 if (ctx->ie >= 2) {
10294 if (!env->tlb->helper_tlbinvf) {
10295 goto die;
10296 }
10297 gen_helper_tlbinvf(cpu_env);
10298 } /* treat as nop if TLBINV not supported */
10299 break;
10300 case OPC_TLBWR:
10301 opn = "tlbwr";
10302 if (!env->tlb->helper_tlbwr) {
10303 goto die;
10304 }
10305 gen_helper_tlbwr(cpu_env);
10306 break;
10307 case OPC_TLBP:
10308 opn = "tlbp";
10309 if (!env->tlb->helper_tlbp) {
10310 goto die;
10311 }
10312 gen_helper_tlbp(cpu_env);
10313 break;
10314 case OPC_TLBR:
10315 opn = "tlbr";
10316 if (!env->tlb->helper_tlbr) {
10317 goto die;
10318 }
10319 gen_helper_tlbr(cpu_env);
10320 break;
10321 case OPC_ERET: /* OPC_ERETNC */
10322 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10323 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10324 goto die;
10325 } else {
10326 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10327 if (ctx->opcode & (1 << bit_shift)) {
10328 /* OPC_ERETNC */
10329 opn = "eretnc";
10330 check_insn(ctx, ISA_MIPS32R5);
10331 gen_helper_eretnc(cpu_env);
10332 } else {
10333 /* OPC_ERET */
10334 opn = "eret";
10335 check_insn(ctx, ISA_MIPS2);
10336 gen_helper_eret(cpu_env);
10337 }
10338 ctx->base.is_jmp = DISAS_EXIT;
10339 }
10340 break;
10341 case OPC_DERET:
10342 opn = "deret";
10343 check_insn(ctx, ISA_MIPS32);
10344 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10345 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10346 goto die;
10347 }
10348 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10349 MIPS_INVAL(opn);
10350 generate_exception_end(ctx, EXCP_RI);
10351 } else {
10352 gen_helper_deret(cpu_env);
10353 ctx->base.is_jmp = DISAS_EXIT;
10354 }
10355 break;
10356 case OPC_WAIT:
10357 opn = "wait";
10358 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10359 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10360 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10361 goto die;
10362 }
10363 /* If we get an exception, we want to restart at next instruction */
10364 ctx->base.pc_next += 4;
10365 save_cpu_state(ctx, 1);
10366 ctx->base.pc_next -= 4;
10367 gen_helper_wait(cpu_env);
10368 ctx->base.is_jmp = DISAS_NORETURN;
10369 break;
10370 default:
10371 die:
10372 MIPS_INVAL(opn);
10373 generate_exception_end(ctx, EXCP_RI);
10374 return;
10375 }
10376 (void)opn; /* avoid a compiler warning */
10377 }
10378 #endif /* !CONFIG_USER_ONLY */
10379
10380 /* CP1 Branches (before delay slot) */
10381 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10382 int32_t cc, int32_t offset)
10383 {
10384 target_ulong btarget;
10385 TCGv_i32 t0 = tcg_temp_new_i32();
10386
10387 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10388 generate_exception_end(ctx, EXCP_RI);
10389 goto out;
10390 }
10391
10392 if (cc != 0) {
10393 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10394 }
10395
10396 btarget = ctx->base.pc_next + 4 + offset;
10397
10398 switch (op) {
10399 case OPC_BC1F:
10400 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10401 tcg_gen_not_i32(t0, t0);
10402 tcg_gen_andi_i32(t0, t0, 1);
10403 tcg_gen_extu_i32_tl(bcond, t0);
10404 goto not_likely;
10405 case OPC_BC1FL:
10406 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10407 tcg_gen_not_i32(t0, t0);
10408 tcg_gen_andi_i32(t0, t0, 1);
10409 tcg_gen_extu_i32_tl(bcond, t0);
10410 goto likely;
10411 case OPC_BC1T:
10412 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10413 tcg_gen_andi_i32(t0, t0, 1);
10414 tcg_gen_extu_i32_tl(bcond, t0);
10415 goto not_likely;
10416 case OPC_BC1TL:
10417 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10418 tcg_gen_andi_i32(t0, t0, 1);
10419 tcg_gen_extu_i32_tl(bcond, t0);
10420 likely:
10421 ctx->hflags |= MIPS_HFLAG_BL;
10422 break;
10423 case OPC_BC1FANY2:
10424 {
10425 TCGv_i32 t1 = tcg_temp_new_i32();
10426 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10427 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10428 tcg_gen_nand_i32(t0, t0, t1);
10429 tcg_temp_free_i32(t1);
10430 tcg_gen_andi_i32(t0, t0, 1);
10431 tcg_gen_extu_i32_tl(bcond, t0);
10432 }
10433 goto not_likely;
10434 case OPC_BC1TANY2:
10435 {
10436 TCGv_i32 t1 = tcg_temp_new_i32();
10437 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10438 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10439 tcg_gen_or_i32(t0, t0, t1);
10440 tcg_temp_free_i32(t1);
10441 tcg_gen_andi_i32(t0, t0, 1);
10442 tcg_gen_extu_i32_tl(bcond, t0);
10443 }
10444 goto not_likely;
10445 case OPC_BC1FANY4:
10446 {
10447 TCGv_i32 t1 = tcg_temp_new_i32();
10448 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10449 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10450 tcg_gen_and_i32(t0, t0, t1);
10451 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10452 tcg_gen_and_i32(t0, t0, t1);
10453 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10454 tcg_gen_nand_i32(t0, t0, t1);
10455 tcg_temp_free_i32(t1);
10456 tcg_gen_andi_i32(t0, t0, 1);
10457 tcg_gen_extu_i32_tl(bcond, t0);
10458 }
10459 goto not_likely;
10460 case OPC_BC1TANY4:
10461 {
10462 TCGv_i32 t1 = tcg_temp_new_i32();
10463 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10464 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10465 tcg_gen_or_i32(t0, t0, t1);
10466 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10467 tcg_gen_or_i32(t0, t0, t1);
10468 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10469 tcg_gen_or_i32(t0, t0, t1);
10470 tcg_temp_free_i32(t1);
10471 tcg_gen_andi_i32(t0, t0, 1);
10472 tcg_gen_extu_i32_tl(bcond, t0);
10473 }
10474 not_likely:
10475 ctx->hflags |= MIPS_HFLAG_BC;
10476 break;
10477 default:
10478 MIPS_INVAL("cp1 cond branch");
10479 generate_exception_end(ctx, EXCP_RI);
10480 goto out;
10481 }
10482 ctx->btarget = btarget;
10483 ctx->hflags |= MIPS_HFLAG_BDS32;
10484 out:
10485 tcg_temp_free_i32(t0);
10486 }
10487
10488 /* R6 CP1 Branches */
10489 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10490 int32_t ft, int32_t offset,
10491 int delayslot_size)
10492 {
10493 target_ulong btarget;
10494 TCGv_i64 t0 = tcg_temp_new_i64();
10495
10496 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10497 #ifdef MIPS_DEBUG_DISAS
10498 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10499 "\n", ctx->base.pc_next);
10500 #endif
10501 generate_exception_end(ctx, EXCP_RI);
10502 goto out;
10503 }
10504
10505 gen_load_fpr64(ctx, t0, ft);
10506 tcg_gen_andi_i64(t0, t0, 1);
10507
10508 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10509
10510 switch (op) {
10511 case OPC_BC1EQZ:
10512 tcg_gen_xori_i64(t0, t0, 1);
10513 ctx->hflags |= MIPS_HFLAG_BC;
10514 break;
10515 case OPC_BC1NEZ:
10516 /* t0 already set */
10517 ctx->hflags |= MIPS_HFLAG_BC;
10518 break;
10519 default:
10520 MIPS_INVAL("cp1 cond branch");
10521 generate_exception_end(ctx, EXCP_RI);
10522 goto out;
10523 }
10524
10525 tcg_gen_trunc_i64_tl(bcond, t0);
10526
10527 ctx->btarget = btarget;
10528
10529 switch (delayslot_size) {
10530 case 2:
10531 ctx->hflags |= MIPS_HFLAG_BDS16;
10532 break;
10533 case 4:
10534 ctx->hflags |= MIPS_HFLAG_BDS32;
10535 break;
10536 }
10537
10538 out:
10539 tcg_temp_free_i64(t0);
10540 }
10541
10542 /* Coprocessor 1 (FPU) */
10543
10544 #define FOP(func, fmt) (((fmt) << 21) | (func))
10545
10546 enum fopcode {
10547 OPC_ADD_S = FOP(0, FMT_S),
10548 OPC_SUB_S = FOP(1, FMT_S),
10549 OPC_MUL_S = FOP(2, FMT_S),
10550 OPC_DIV_S = FOP(3, FMT_S),
10551 OPC_SQRT_S = FOP(4, FMT_S),
10552 OPC_ABS_S = FOP(5, FMT_S),
10553 OPC_MOV_S = FOP(6, FMT_S),
10554 OPC_NEG_S = FOP(7, FMT_S),
10555 OPC_ROUND_L_S = FOP(8, FMT_S),
10556 OPC_TRUNC_L_S = FOP(9, FMT_S),
10557 OPC_CEIL_L_S = FOP(10, FMT_S),
10558 OPC_FLOOR_L_S = FOP(11, FMT_S),
10559 OPC_ROUND_W_S = FOP(12, FMT_S),
10560 OPC_TRUNC_W_S = FOP(13, FMT_S),
10561 OPC_CEIL_W_S = FOP(14, FMT_S),
10562 OPC_FLOOR_W_S = FOP(15, FMT_S),
10563 OPC_SEL_S = FOP(16, FMT_S),
10564 OPC_MOVCF_S = FOP(17, FMT_S),
10565 OPC_MOVZ_S = FOP(18, FMT_S),
10566 OPC_MOVN_S = FOP(19, FMT_S),
10567 OPC_SELEQZ_S = FOP(20, FMT_S),
10568 OPC_RECIP_S = FOP(21, FMT_S),
10569 OPC_RSQRT_S = FOP(22, FMT_S),
10570 OPC_SELNEZ_S = FOP(23, FMT_S),
10571 OPC_MADDF_S = FOP(24, FMT_S),
10572 OPC_MSUBF_S = FOP(25, FMT_S),
10573 OPC_RINT_S = FOP(26, FMT_S),
10574 OPC_CLASS_S = FOP(27, FMT_S),
10575 OPC_MIN_S = FOP(28, FMT_S),
10576 OPC_RECIP2_S = FOP(28, FMT_S),
10577 OPC_MINA_S = FOP(29, FMT_S),
10578 OPC_RECIP1_S = FOP(29, FMT_S),
10579 OPC_MAX_S = FOP(30, FMT_S),
10580 OPC_RSQRT1_S = FOP(30, FMT_S),
10581 OPC_MAXA_S = FOP(31, FMT_S),
10582 OPC_RSQRT2_S = FOP(31, FMT_S),
10583 OPC_CVT_D_S = FOP(33, FMT_S),
10584 OPC_CVT_W_S = FOP(36, FMT_S),
10585 OPC_CVT_L_S = FOP(37, FMT_S),
10586 OPC_CVT_PS_S = FOP(38, FMT_S),
10587 OPC_CMP_F_S = FOP(48, FMT_S),
10588 OPC_CMP_UN_S = FOP(49, FMT_S),
10589 OPC_CMP_EQ_S = FOP(50, FMT_S),
10590 OPC_CMP_UEQ_S = FOP(51, FMT_S),
10591 OPC_CMP_OLT_S = FOP(52, FMT_S),
10592 OPC_CMP_ULT_S = FOP(53, FMT_S),
10593 OPC_CMP_OLE_S = FOP(54, FMT_S),
10594 OPC_CMP_ULE_S = FOP(55, FMT_S),
10595 OPC_CMP_SF_S = FOP(56, FMT_S),
10596 OPC_CMP_NGLE_S = FOP(57, FMT_S),
10597 OPC_CMP_SEQ_S = FOP(58, FMT_S),
10598 OPC_CMP_NGL_S = FOP(59, FMT_S),
10599 OPC_CMP_LT_S = FOP(60, FMT_S),
10600 OPC_CMP_NGE_S = FOP(61, FMT_S),
10601 OPC_CMP_LE_S = FOP(62, FMT_S),
10602 OPC_CMP_NGT_S = FOP(63, FMT_S),
10603
10604 OPC_ADD_D = FOP(0, FMT_D),
10605 OPC_SUB_D = FOP(1, FMT_D),
10606 OPC_MUL_D = FOP(2, FMT_D),
10607 OPC_DIV_D = FOP(3, FMT_D),
10608 OPC_SQRT_D = FOP(4, FMT_D),
10609 OPC_ABS_D = FOP(5, FMT_D),
10610 OPC_MOV_D = FOP(6, FMT_D),
10611 OPC_NEG_D = FOP(7, FMT_D),
10612 OPC_ROUND_L_D = FOP(8, FMT_D),
10613 OPC_TRUNC_L_D = FOP(9, FMT_D),
10614 OPC_CEIL_L_D = FOP(10, FMT_D),
10615 OPC_FLOOR_L_D = FOP(11, FMT_D),
10616 OPC_ROUND_W_D = FOP(12, FMT_D),
10617 OPC_TRUNC_W_D = FOP(13, FMT_D),
10618 OPC_CEIL_W_D = FOP(14, FMT_D),
10619 OPC_FLOOR_W_D = FOP(15, FMT_D),
10620 OPC_SEL_D = FOP(16, FMT_D),
10621 OPC_MOVCF_D = FOP(17, FMT_D),
10622 OPC_MOVZ_D = FOP(18, FMT_D),
10623 OPC_MOVN_D = FOP(19, FMT_D),
10624 OPC_SELEQZ_D = FOP(20, FMT_D),
10625 OPC_RECIP_D = FOP(21, FMT_D),
10626 OPC_RSQRT_D = FOP(22, FMT_D),
10627 OPC_SELNEZ_D = FOP(23, FMT_D),
10628 OPC_MADDF_D = FOP(24, FMT_D),
10629 OPC_MSUBF_D = FOP(25, FMT_D),
10630 OPC_RINT_D = FOP(26, FMT_D),
10631 OPC_CLASS_D = FOP(27, FMT_D),
10632 OPC_MIN_D = FOP(28, FMT_D),
10633 OPC_RECIP2_D = FOP(28, FMT_D),
10634 OPC_MINA_D = FOP(29, FMT_D),
10635 OPC_RECIP1_D = FOP(29, FMT_D),
10636 OPC_MAX_D = FOP(30, FMT_D),
10637 OPC_RSQRT1_D = FOP(30, FMT_D),
10638 OPC_MAXA_D = FOP(31, FMT_D),
10639 OPC_RSQRT2_D = FOP(31, FMT_D),
10640 OPC_CVT_S_D = FOP(32, FMT_D),
10641 OPC_CVT_W_D = FOP(36, FMT_D),
10642 OPC_CVT_L_D = FOP(37, FMT_D),
10643 OPC_CMP_F_D = FOP(48, FMT_D),
10644 OPC_CMP_UN_D = FOP(49, FMT_D),
10645 OPC_CMP_EQ_D = FOP(50, FMT_D),
10646 OPC_CMP_UEQ_D = FOP(51, FMT_D),
10647 OPC_CMP_OLT_D = FOP(52, FMT_D),
10648 OPC_CMP_ULT_D = FOP(53, FMT_D),
10649 OPC_CMP_OLE_D = FOP(54, FMT_D),
10650 OPC_CMP_ULE_D = FOP(55, FMT_D),
10651 OPC_CMP_SF_D = FOP(56, FMT_D),
10652 OPC_CMP_NGLE_D = FOP(57, FMT_D),
10653 OPC_CMP_SEQ_D = FOP(58, FMT_D),
10654 OPC_CMP_NGL_D = FOP(59, FMT_D),
10655 OPC_CMP_LT_D = FOP(60, FMT_D),
10656 OPC_CMP_NGE_D = FOP(61, FMT_D),
10657 OPC_CMP_LE_D = FOP(62, FMT_D),
10658 OPC_CMP_NGT_D = FOP(63, FMT_D),
10659
10660 OPC_CVT_S_W = FOP(32, FMT_W),
10661 OPC_CVT_D_W = FOP(33, FMT_W),
10662 OPC_CVT_S_L = FOP(32, FMT_L),
10663 OPC_CVT_D_L = FOP(33, FMT_L),
10664 OPC_CVT_PS_PW = FOP(38, FMT_W),
10665
10666 OPC_ADD_PS = FOP(0, FMT_PS),
10667 OPC_SUB_PS = FOP(1, FMT_PS),
10668 OPC_MUL_PS = FOP(2, FMT_PS),
10669 OPC_DIV_PS = FOP(3, FMT_PS),
10670 OPC_ABS_PS = FOP(5, FMT_PS),
10671 OPC_MOV_PS = FOP(6, FMT_PS),
10672 OPC_NEG_PS = FOP(7, FMT_PS),
10673 OPC_MOVCF_PS = FOP(17, FMT_PS),
10674 OPC_MOVZ_PS = FOP(18, FMT_PS),
10675 OPC_MOVN_PS = FOP(19, FMT_PS),
10676 OPC_ADDR_PS = FOP(24, FMT_PS),
10677 OPC_MULR_PS = FOP(26, FMT_PS),
10678 OPC_RECIP2_PS = FOP(28, FMT_PS),
10679 OPC_RECIP1_PS = FOP(29, FMT_PS),
10680 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10681 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10682
10683 OPC_CVT_S_PU = FOP(32, FMT_PS),
10684 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10685 OPC_CVT_S_PL = FOP(40, FMT_PS),
10686 OPC_PLL_PS = FOP(44, FMT_PS),
10687 OPC_PLU_PS = FOP(45, FMT_PS),
10688 OPC_PUL_PS = FOP(46, FMT_PS),
10689 OPC_PUU_PS = FOP(47, FMT_PS),
10690 OPC_CMP_F_PS = FOP(48, FMT_PS),
10691 OPC_CMP_UN_PS = FOP(49, FMT_PS),
10692 OPC_CMP_EQ_PS = FOP(50, FMT_PS),
10693 OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
10694 OPC_CMP_OLT_PS = FOP(52, FMT_PS),
10695 OPC_CMP_ULT_PS = FOP(53, FMT_PS),
10696 OPC_CMP_OLE_PS = FOP(54, FMT_PS),
10697 OPC_CMP_ULE_PS = FOP(55, FMT_PS),
10698 OPC_CMP_SF_PS = FOP(56, FMT_PS),
10699 OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
10700 OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
10701 OPC_CMP_NGL_PS = FOP(59, FMT_PS),
10702 OPC_CMP_LT_PS = FOP(60, FMT_PS),
10703 OPC_CMP_NGE_PS = FOP(61, FMT_PS),
10704 OPC_CMP_LE_PS = FOP(62, FMT_PS),
10705 OPC_CMP_NGT_PS = FOP(63, FMT_PS),
10706 };
10707
10708 enum r6_f_cmp_op {
10709 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10710 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10711 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10712 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10713 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10714 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10715 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10716 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10717 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10718 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10719 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10720 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10721 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10722 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10723 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10724 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10725 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10726 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10727 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10728 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10729 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10730 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10731
10732 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10733 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10734 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10735 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10736 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10737 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10738 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10739 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10740 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10741 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10742 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10743 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10744 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10745 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10746 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10747 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10748 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10749 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10750 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10751 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10752 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10753 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10754 };
10755
10756 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
10757 {
10758 TCGv t0 = tcg_temp_new();
10759
10760 switch (opc) {
10761 case OPC_MFC1:
10762 {
10763 TCGv_i32 fp0 = tcg_temp_new_i32();
10764
10765 gen_load_fpr32(ctx, fp0, fs);
10766 tcg_gen_ext_i32_tl(t0, fp0);
10767 tcg_temp_free_i32(fp0);
10768 }
10769 gen_store_gpr(t0, rt);
10770 break;
10771 case OPC_MTC1:
10772 gen_load_gpr(t0, rt);
10773 {
10774 TCGv_i32 fp0 = tcg_temp_new_i32();
10775
10776 tcg_gen_trunc_tl_i32(fp0, t0);
10777 gen_store_fpr32(ctx, fp0, fs);
10778 tcg_temp_free_i32(fp0);
10779 }
10780 break;
10781 case OPC_CFC1:
10782 gen_helper_1e0i(cfc1, t0, fs);
10783 gen_store_gpr(t0, rt);
10784 break;
10785 case OPC_CTC1:
10786 gen_load_gpr(t0, rt);
10787 save_cpu_state(ctx, 0);
10788 {
10789 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10790
10791 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10792 tcg_temp_free_i32(fs_tmp);
10793 }
10794 /* Stop translation as we may have changed hflags */
10795 ctx->base.is_jmp = DISAS_STOP;
10796 break;
10797 #if defined(TARGET_MIPS64)
10798 case OPC_DMFC1:
10799 gen_load_fpr64(ctx, t0, fs);
10800 gen_store_gpr(t0, rt);
10801 break;
10802 case OPC_DMTC1:
10803 gen_load_gpr(t0, rt);
10804 gen_store_fpr64(ctx, t0, fs);
10805 break;
10806 #endif
10807 case OPC_MFHC1:
10808 {
10809 TCGv_i32 fp0 = tcg_temp_new_i32();
10810
10811 gen_load_fpr32h(ctx, fp0, fs);
10812 tcg_gen_ext_i32_tl(t0, fp0);
10813 tcg_temp_free_i32(fp0);
10814 }
10815 gen_store_gpr(t0, rt);
10816 break;
10817 case OPC_MTHC1:
10818 gen_load_gpr(t0, rt);
10819 {
10820 TCGv_i32 fp0 = tcg_temp_new_i32();
10821
10822 tcg_gen_trunc_tl_i32(fp0, t0);
10823 gen_store_fpr32h(ctx, fp0, fs);
10824 tcg_temp_free_i32(fp0);
10825 }
10826 break;
10827 default:
10828 MIPS_INVAL("cp1 move");
10829 generate_exception_end(ctx, EXCP_RI);
10830 goto out;
10831 }
10832
10833 out:
10834 tcg_temp_free(t0);
10835 }
10836
10837 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
10838 {
10839 TCGLabel *l1;
10840 TCGCond cond;
10841 TCGv_i32 t0;
10842
10843 if (rd == 0) {
10844 /* Treat as NOP. */
10845 return;
10846 }
10847
10848 if (tf) {
10849 cond = TCG_COND_EQ;
10850 } else {
10851 cond = TCG_COND_NE;
10852 }
10853
10854 l1 = gen_new_label();
10855 t0 = tcg_temp_new_i32();
10856 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10857 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10858 tcg_temp_free_i32(t0);
10859 if (rs == 0) {
10860 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10861 } else {
10862 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10863 }
10864 gen_set_label(l1);
10865 }
10866
10867 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10868 int tf)
10869 {
10870 int cond;
10871 TCGv_i32 t0 = tcg_temp_new_i32();
10872 TCGLabel *l1 = gen_new_label();
10873
10874 if (tf) {
10875 cond = TCG_COND_EQ;
10876 } else {
10877 cond = TCG_COND_NE;
10878 }
10879
10880 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10881 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10882 gen_load_fpr32(ctx, t0, fs);
10883 gen_store_fpr32(ctx, t0, fd);
10884 gen_set_label(l1);
10885 tcg_temp_free_i32(t0);
10886 }
10887
10888 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
10889 int tf)
10890 {
10891 int cond;
10892 TCGv_i32 t0 = tcg_temp_new_i32();
10893 TCGv_i64 fp0;
10894 TCGLabel *l1 = gen_new_label();
10895
10896 if (tf) {
10897 cond = TCG_COND_EQ;
10898 } else {
10899 cond = TCG_COND_NE;
10900 }
10901
10902 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10903 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10904 tcg_temp_free_i32(t0);
10905 fp0 = tcg_temp_new_i64();
10906 gen_load_fpr64(ctx, fp0, fs);
10907 gen_store_fpr64(ctx, fp0, fd);
10908 tcg_temp_free_i64(fp0);
10909 gen_set_label(l1);
10910 }
10911
10912 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10913 int cc, int tf)
10914 {
10915 int cond;
10916 TCGv_i32 t0 = tcg_temp_new_i32();
10917 TCGLabel *l1 = gen_new_label();
10918 TCGLabel *l2 = gen_new_label();
10919
10920 if (tf) {
10921 cond = TCG_COND_EQ;
10922 } else {
10923 cond = TCG_COND_NE;
10924 }
10925
10926 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10927 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10928 gen_load_fpr32(ctx, t0, fs);
10929 gen_store_fpr32(ctx, t0, fd);
10930 gen_set_label(l1);
10931
10932 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10933 tcg_gen_brcondi_i32(cond, t0, 0, l2);
10934 gen_load_fpr32h(ctx, t0, fs);
10935 gen_store_fpr32h(ctx, t0, fd);
10936 tcg_temp_free_i32(t0);
10937 gen_set_label(l2);
10938 }
10939
10940 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10941 int fs)
10942 {
10943 TCGv_i32 t1 = tcg_const_i32(0);
10944 TCGv_i32 fp0 = tcg_temp_new_i32();
10945 TCGv_i32 fp1 = tcg_temp_new_i32();
10946 TCGv_i32 fp2 = tcg_temp_new_i32();
10947 gen_load_fpr32(ctx, fp0, fd);
10948 gen_load_fpr32(ctx, fp1, ft);
10949 gen_load_fpr32(ctx, fp2, fs);
10950
10951 switch (op1) {
10952 case OPC_SEL_S:
10953 tcg_gen_andi_i32(fp0, fp0, 1);
10954 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10955 break;
10956 case OPC_SELEQZ_S:
10957 tcg_gen_andi_i32(fp1, fp1, 1);
10958 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10959 break;
10960 case OPC_SELNEZ_S:
10961 tcg_gen_andi_i32(fp1, fp1, 1);
10962 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10963 break;
10964 default:
10965 MIPS_INVAL("gen_sel_s");
10966 generate_exception_end(ctx, EXCP_RI);
10967 break;
10968 }
10969
10970 gen_store_fpr32(ctx, fp0, fd);
10971 tcg_temp_free_i32(fp2);
10972 tcg_temp_free_i32(fp1);
10973 tcg_temp_free_i32(fp0);
10974 tcg_temp_free_i32(t1);
10975 }
10976
10977 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10978 int fs)
10979 {
10980 TCGv_i64 t1 = tcg_const_i64(0);
10981 TCGv_i64 fp0 = tcg_temp_new_i64();
10982 TCGv_i64 fp1 = tcg_temp_new_i64();
10983 TCGv_i64 fp2 = tcg_temp_new_i64();
10984 gen_load_fpr64(ctx, fp0, fd);
10985 gen_load_fpr64(ctx, fp1, ft);
10986 gen_load_fpr64(ctx, fp2, fs);
10987
10988 switch (op1) {
10989 case OPC_SEL_D:
10990 tcg_gen_andi_i64(fp0, fp0, 1);
10991 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10992 break;
10993 case OPC_SELEQZ_D:
10994 tcg_gen_andi_i64(fp1, fp1, 1);
10995 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10996 break;
10997 case OPC_SELNEZ_D:
10998 tcg_gen_andi_i64(fp1, fp1, 1);
10999 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11000 break;
11001 default:
11002 MIPS_INVAL("gen_sel_d");
11003 generate_exception_end(ctx, EXCP_RI);
11004 break;
11005 }
11006
11007 gen_store_fpr64(ctx, fp0, fd);
11008 tcg_temp_free_i64(fp2);
11009 tcg_temp_free_i64(fp1);
11010 tcg_temp_free_i64(fp0);
11011 tcg_temp_free_i64(t1);
11012 }
11013
11014 static void gen_farith(DisasContext *ctx, enum fopcode op1,
11015 int ft, int fs, int fd, int cc)
11016 {
11017 uint32_t func = ctx->opcode & 0x3f;
11018 switch (op1) {
11019 case OPC_ADD_S:
11020 {
11021 TCGv_i32 fp0 = tcg_temp_new_i32();
11022 TCGv_i32 fp1 = tcg_temp_new_i32();
11023
11024 gen_load_fpr32(ctx, fp0, fs);
11025 gen_load_fpr32(ctx, fp1, ft);
11026 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
11027 tcg_temp_free_i32(fp1);
11028 gen_store_fpr32(ctx, fp0, fd);
11029 tcg_temp_free_i32(fp0);
11030 }
11031 break;
11032 case OPC_SUB_S:
11033 {
11034 TCGv_i32 fp0 = tcg_temp_new_i32();
11035 TCGv_i32 fp1 = tcg_temp_new_i32();
11036
11037 gen_load_fpr32(ctx, fp0, fs);
11038 gen_load_fpr32(ctx, fp1, ft);
11039 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
11040 tcg_temp_free_i32(fp1);
11041 gen_store_fpr32(ctx, fp0, fd);
11042 tcg_temp_free_i32(fp0);
11043 }
11044 break;
11045 case OPC_MUL_S:
11046 {
11047 TCGv_i32 fp0 = tcg_temp_new_i32();
11048 TCGv_i32 fp1 = tcg_temp_new_i32();
11049
11050 gen_load_fpr32(ctx, fp0, fs);
11051 gen_load_fpr32(ctx, fp1, ft);
11052 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
11053 tcg_temp_free_i32(fp1);
11054 gen_store_fpr32(ctx, fp0, fd);
11055 tcg_temp_free_i32(fp0);
11056 }
11057 break;
11058 case OPC_DIV_S:
11059 {
11060 TCGv_i32 fp0 = tcg_temp_new_i32();
11061 TCGv_i32 fp1 = tcg_temp_new_i32();
11062
11063 gen_load_fpr32(ctx, fp0, fs);
11064 gen_load_fpr32(ctx, fp1, ft);
11065 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
11066 tcg_temp_free_i32(fp1);
11067 gen_store_fpr32(ctx, fp0, fd);
11068 tcg_temp_free_i32(fp0);
11069 }
11070 break;
11071 case OPC_SQRT_S:
11072 {
11073 TCGv_i32 fp0 = tcg_temp_new_i32();
11074
11075 gen_load_fpr32(ctx, fp0, fs);
11076 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
11077 gen_store_fpr32(ctx, fp0, fd);
11078 tcg_temp_free_i32(fp0);
11079 }
11080 break;
11081 case OPC_ABS_S:
11082 {
11083 TCGv_i32 fp0 = tcg_temp_new_i32();
11084
11085 gen_load_fpr32(ctx, fp0, fs);
11086 if (ctx->abs2008) {
11087 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
11088 } else {
11089 gen_helper_float_abs_s(fp0, fp0);
11090 }
11091 gen_store_fpr32(ctx, fp0, fd);
11092 tcg_temp_free_i32(fp0);
11093 }
11094 break;
11095 case OPC_MOV_S:
11096 {
11097 TCGv_i32 fp0 = tcg_temp_new_i32();
11098
11099 gen_load_fpr32(ctx, fp0, fs);
11100 gen_store_fpr32(ctx, fp0, fd);
11101 tcg_temp_free_i32(fp0);
11102 }
11103 break;
11104 case OPC_NEG_S:
11105 {
11106 TCGv_i32 fp0 = tcg_temp_new_i32();
11107
11108 gen_load_fpr32(ctx, fp0, fs);
11109 if (ctx->abs2008) {
11110 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
11111 } else {
11112 gen_helper_float_chs_s(fp0, fp0);
11113 }
11114 gen_store_fpr32(ctx, fp0, fd);
11115 tcg_temp_free_i32(fp0);
11116 }
11117 break;
11118 case OPC_ROUND_L_S:
11119 check_cp1_64bitmode(ctx);
11120 {
11121 TCGv_i32 fp32 = tcg_temp_new_i32();
11122 TCGv_i64 fp64 = tcg_temp_new_i64();
11123
11124 gen_load_fpr32(ctx, fp32, fs);
11125 if (ctx->nan2008) {
11126 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11127 } else {
11128 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11129 }
11130 tcg_temp_free_i32(fp32);
11131 gen_store_fpr64(ctx, fp64, fd);
11132 tcg_temp_free_i64(fp64);
11133 }
11134 break;
11135 case OPC_TRUNC_L_S:
11136 check_cp1_64bitmode(ctx);
11137 {
11138 TCGv_i32 fp32 = tcg_temp_new_i32();
11139 TCGv_i64 fp64 = tcg_temp_new_i64();
11140
11141 gen_load_fpr32(ctx, fp32, fs);
11142 if (ctx->nan2008) {
11143 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11144 } else {
11145 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11146 }
11147 tcg_temp_free_i32(fp32);
11148 gen_store_fpr64(ctx, fp64, fd);
11149 tcg_temp_free_i64(fp64);
11150 }
11151 break;
11152 case OPC_CEIL_L_S:
11153 check_cp1_64bitmode(ctx);
11154 {
11155 TCGv_i32 fp32 = tcg_temp_new_i32();
11156 TCGv_i64 fp64 = tcg_temp_new_i64();
11157
11158 gen_load_fpr32(ctx, fp32, fs);
11159 if (ctx->nan2008) {
11160 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11161 } else {
11162 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11163 }
11164 tcg_temp_free_i32(fp32);
11165 gen_store_fpr64(ctx, fp64, fd);
11166 tcg_temp_free_i64(fp64);
11167 }
11168 break;
11169 case OPC_FLOOR_L_S:
11170 check_cp1_64bitmode(ctx);
11171 {
11172 TCGv_i32 fp32 = tcg_temp_new_i32();
11173 TCGv_i64 fp64 = tcg_temp_new_i64();
11174
11175 gen_load_fpr32(ctx, fp32, fs);
11176 if (ctx->nan2008) {
11177 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11178 } else {
11179 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11180 }
11181 tcg_temp_free_i32(fp32);
11182 gen_store_fpr64(ctx, fp64, fd);
11183 tcg_temp_free_i64(fp64);
11184 }
11185 break;
11186 case OPC_ROUND_W_S:
11187 {
11188 TCGv_i32 fp0 = tcg_temp_new_i32();
11189
11190 gen_load_fpr32(ctx, fp0, fs);
11191 if (ctx->nan2008) {
11192 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11193 } else {
11194 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11195 }
11196 gen_store_fpr32(ctx, fp0, fd);
11197 tcg_temp_free_i32(fp0);
11198 }
11199 break;
11200 case OPC_TRUNC_W_S:
11201 {
11202 TCGv_i32 fp0 = tcg_temp_new_i32();
11203
11204 gen_load_fpr32(ctx, fp0, fs);
11205 if (ctx->nan2008) {
11206 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11207 } else {
11208 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11209 }
11210 gen_store_fpr32(ctx, fp0, fd);
11211 tcg_temp_free_i32(fp0);
11212 }
11213 break;
11214 case OPC_CEIL_W_S:
11215 {
11216 TCGv_i32 fp0 = tcg_temp_new_i32();
11217
11218 gen_load_fpr32(ctx, fp0, fs);
11219 if (ctx->nan2008) {
11220 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11221 } else {
11222 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11223 }
11224 gen_store_fpr32(ctx, fp0, fd);
11225 tcg_temp_free_i32(fp0);
11226 }
11227 break;
11228 case OPC_FLOOR_W_S:
11229 {
11230 TCGv_i32 fp0 = tcg_temp_new_i32();
11231
11232 gen_load_fpr32(ctx, fp0, fs);
11233 if (ctx->nan2008) {
11234 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11235 } else {
11236 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11237 }
11238 gen_store_fpr32(ctx, fp0, fd);
11239 tcg_temp_free_i32(fp0);
11240 }
11241 break;
11242 case OPC_SEL_S:
11243 check_insn(ctx, ISA_MIPS32R6);
11244 gen_sel_s(ctx, op1, fd, ft, fs);
11245 break;
11246 case OPC_SELEQZ_S:
11247 check_insn(ctx, ISA_MIPS32R6);
11248 gen_sel_s(ctx, op1, fd, ft, fs);
11249 break;
11250 case OPC_SELNEZ_S:
11251 check_insn(ctx, ISA_MIPS32R6);
11252 gen_sel_s(ctx, op1, fd, ft, fs);
11253 break;
11254 case OPC_MOVCF_S:
11255 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11256 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11257 break;
11258 case OPC_MOVZ_S:
11259 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11260 {
11261 TCGLabel *l1 = gen_new_label();
11262 TCGv_i32 fp0;
11263
11264 if (ft != 0) {
11265 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11266 }
11267 fp0 = tcg_temp_new_i32();
11268 gen_load_fpr32(ctx, fp0, fs);
11269 gen_store_fpr32(ctx, fp0, fd);
11270 tcg_temp_free_i32(fp0);
11271 gen_set_label(l1);
11272 }
11273 break;
11274 case OPC_MOVN_S:
11275 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11276 {
11277 TCGLabel *l1 = gen_new_label();
11278 TCGv_i32 fp0;
11279
11280 if (ft != 0) {
11281 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11282 fp0 = tcg_temp_new_i32();
11283 gen_load_fpr32(ctx, fp0, fs);
11284 gen_store_fpr32(ctx, fp0, fd);
11285 tcg_temp_free_i32(fp0);
11286 gen_set_label(l1);
11287 }
11288 }
11289 break;
11290 case OPC_RECIP_S:
11291 {
11292 TCGv_i32 fp0 = tcg_temp_new_i32();
11293
11294 gen_load_fpr32(ctx, fp0, fs);
11295 gen_helper_float_recip_s(fp0, cpu_env, fp0);
11296 gen_store_fpr32(ctx, fp0, fd);
11297 tcg_temp_free_i32(fp0);
11298 }
11299 break;
11300 case OPC_RSQRT_S:
11301 {
11302 TCGv_i32 fp0 = tcg_temp_new_i32();
11303
11304 gen_load_fpr32(ctx, fp0, fs);
11305 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11306 gen_store_fpr32(ctx, fp0, fd);
11307 tcg_temp_free_i32(fp0);
11308 }
11309 break;
11310 case OPC_MADDF_S:
11311 check_insn(ctx, ISA_MIPS32R6);
11312 {
11313 TCGv_i32 fp0 = tcg_temp_new_i32();
11314 TCGv_i32 fp1 = tcg_temp_new_i32();
11315 TCGv_i32 fp2 = tcg_temp_new_i32();
11316 gen_load_fpr32(ctx, fp0, fs);
11317 gen_load_fpr32(ctx, fp1, ft);
11318 gen_load_fpr32(ctx, fp2, fd);
11319 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11320 gen_store_fpr32(ctx, fp2, fd);
11321 tcg_temp_free_i32(fp2);
11322 tcg_temp_free_i32(fp1);
11323 tcg_temp_free_i32(fp0);
11324 }
11325 break;
11326 case OPC_MSUBF_S:
11327 check_insn(ctx, ISA_MIPS32R6);
11328 {
11329 TCGv_i32 fp0 = tcg_temp_new_i32();
11330 TCGv_i32 fp1 = tcg_temp_new_i32();
11331 TCGv_i32 fp2 = tcg_temp_new_i32();
11332 gen_load_fpr32(ctx, fp0, fs);
11333 gen_load_fpr32(ctx, fp1, ft);
11334 gen_load_fpr32(ctx, fp2, fd);
11335 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11336 gen_store_fpr32(ctx, fp2, fd);
11337 tcg_temp_free_i32(fp2);
11338 tcg_temp_free_i32(fp1);
11339 tcg_temp_free_i32(fp0);
11340 }
11341 break;
11342 case OPC_RINT_S:
11343 check_insn(ctx, ISA_MIPS32R6);
11344 {
11345 TCGv_i32 fp0 = tcg_temp_new_i32();
11346 gen_load_fpr32(ctx, fp0, fs);
11347 gen_helper_float_rint_s(fp0, cpu_env, fp0);
11348 gen_store_fpr32(ctx, fp0, fd);
11349 tcg_temp_free_i32(fp0);
11350 }
11351 break;
11352 case OPC_CLASS_S:
11353 check_insn(ctx, ISA_MIPS32R6);
11354 {
11355 TCGv_i32 fp0 = tcg_temp_new_i32();
11356 gen_load_fpr32(ctx, fp0, fs);
11357 gen_helper_float_class_s(fp0, cpu_env, fp0);
11358 gen_store_fpr32(ctx, fp0, fd);
11359 tcg_temp_free_i32(fp0);
11360 }
11361 break;
11362 case OPC_MIN_S: /* OPC_RECIP2_S */
11363 if (ctx->insn_flags & ISA_MIPS32R6) {
11364 /* OPC_MIN_S */
11365 TCGv_i32 fp0 = tcg_temp_new_i32();
11366 TCGv_i32 fp1 = tcg_temp_new_i32();
11367 TCGv_i32 fp2 = tcg_temp_new_i32();
11368 gen_load_fpr32(ctx, fp0, fs);
11369 gen_load_fpr32(ctx, fp1, ft);
11370 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11371 gen_store_fpr32(ctx, fp2, fd);
11372 tcg_temp_free_i32(fp2);
11373 tcg_temp_free_i32(fp1);
11374 tcg_temp_free_i32(fp0);
11375 } else {
11376 /* OPC_RECIP2_S */
11377 check_cp1_64bitmode(ctx);
11378 {
11379 TCGv_i32 fp0 = tcg_temp_new_i32();
11380 TCGv_i32 fp1 = tcg_temp_new_i32();
11381
11382 gen_load_fpr32(ctx, fp0, fs);
11383 gen_load_fpr32(ctx, fp1, ft);
11384 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11385 tcg_temp_free_i32(fp1);
11386 gen_store_fpr32(ctx, fp0, fd);
11387 tcg_temp_free_i32(fp0);
11388 }
11389 }
11390 break;
11391 case OPC_MINA_S: /* OPC_RECIP1_S */
11392 if (ctx->insn_flags & ISA_MIPS32R6) {
11393 /* OPC_MINA_S */
11394 TCGv_i32 fp0 = tcg_temp_new_i32();
11395 TCGv_i32 fp1 = tcg_temp_new_i32();
11396 TCGv_i32 fp2 = tcg_temp_new_i32();
11397 gen_load_fpr32(ctx, fp0, fs);
11398 gen_load_fpr32(ctx, fp1, ft);
11399 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11400 gen_store_fpr32(ctx, fp2, fd);
11401 tcg_temp_free_i32(fp2);
11402 tcg_temp_free_i32(fp1);
11403 tcg_temp_free_i32(fp0);
11404 } else {
11405 /* OPC_RECIP1_S */
11406 check_cp1_64bitmode(ctx);
11407 {
11408 TCGv_i32 fp0 = tcg_temp_new_i32();
11409
11410 gen_load_fpr32(ctx, fp0, fs);
11411 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11412 gen_store_fpr32(ctx, fp0, fd);
11413 tcg_temp_free_i32(fp0);
11414 }
11415 }
11416 break;
11417 case OPC_MAX_S: /* OPC_RSQRT1_S */
11418 if (ctx->insn_flags & ISA_MIPS32R6) {
11419 /* OPC_MAX_S */
11420 TCGv_i32 fp0 = tcg_temp_new_i32();
11421 TCGv_i32 fp1 = tcg_temp_new_i32();
11422 gen_load_fpr32(ctx, fp0, fs);
11423 gen_load_fpr32(ctx, fp1, ft);
11424 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11425 gen_store_fpr32(ctx, fp1, fd);
11426 tcg_temp_free_i32(fp1);
11427 tcg_temp_free_i32(fp0);
11428 } else {
11429 /* OPC_RSQRT1_S */
11430 check_cp1_64bitmode(ctx);
11431 {
11432 TCGv_i32 fp0 = tcg_temp_new_i32();
11433
11434 gen_load_fpr32(ctx, fp0, fs);
11435 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11436 gen_store_fpr32(ctx, fp0, fd);
11437 tcg_temp_free_i32(fp0);
11438 }
11439 }
11440 break;
11441 case OPC_MAXA_S: /* OPC_RSQRT2_S */
11442 if (ctx->insn_flags & ISA_MIPS32R6) {
11443 /* OPC_MAXA_S */
11444 TCGv_i32 fp0 = tcg_temp_new_i32();
11445 TCGv_i32 fp1 = tcg_temp_new_i32();
11446 gen_load_fpr32(ctx, fp0, fs);
11447 gen_load_fpr32(ctx, fp1, ft);
11448 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11449 gen_store_fpr32(ctx, fp1, fd);
11450 tcg_temp_free_i32(fp1);
11451 tcg_temp_free_i32(fp0);
11452 } else {
11453 /* OPC_RSQRT2_S */
11454 check_cp1_64bitmode(ctx);
11455 {
11456 TCGv_i32 fp0 = tcg_temp_new_i32();
11457 TCGv_i32 fp1 = tcg_temp_new_i32();
11458
11459 gen_load_fpr32(ctx, fp0, fs);
11460 gen_load_fpr32(ctx, fp1, ft);
11461 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11462 tcg_temp_free_i32(fp1);
11463 gen_store_fpr32(ctx, fp0, fd);
11464 tcg_temp_free_i32(fp0);
11465 }
11466 }
11467 break;
11468 case OPC_CVT_D_S:
11469 check_cp1_registers(ctx, fd);
11470 {
11471 TCGv_i32 fp32 = tcg_temp_new_i32();
11472 TCGv_i64 fp64 = tcg_temp_new_i64();
11473
11474 gen_load_fpr32(ctx, fp32, fs);
11475 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11476 tcg_temp_free_i32(fp32);
11477 gen_store_fpr64(ctx, fp64, fd);
11478 tcg_temp_free_i64(fp64);
11479 }
11480 break;
11481 case OPC_CVT_W_S:
11482 {
11483 TCGv_i32 fp0 = tcg_temp_new_i32();
11484
11485 gen_load_fpr32(ctx, fp0, fs);
11486 if (ctx->nan2008) {
11487 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11488 } else {
11489 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11490 }
11491 gen_store_fpr32(ctx, fp0, fd);
11492 tcg_temp_free_i32(fp0);
11493 }
11494 break;
11495 case OPC_CVT_L_S:
11496 check_cp1_64bitmode(ctx);
11497 {
11498 TCGv_i32 fp32 = tcg_temp_new_i32();
11499 TCGv_i64 fp64 = tcg_temp_new_i64();
11500
11501 gen_load_fpr32(ctx, fp32, fs);
11502 if (ctx->nan2008) {
11503 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11504 } else {
11505 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11506 }
11507 tcg_temp_free_i32(fp32);
11508 gen_store_fpr64(ctx, fp64, fd);
11509 tcg_temp_free_i64(fp64);
11510 }
11511 break;
11512 case OPC_CVT_PS_S:
11513 check_ps(ctx);
11514 {
11515 TCGv_i64 fp64 = tcg_temp_new_i64();
11516 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11517 TCGv_i32 fp32_1 = tcg_temp_new_i32();
11518
11519 gen_load_fpr32(ctx, fp32_0, fs);
11520 gen_load_fpr32(ctx, fp32_1, ft);
11521 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11522 tcg_temp_free_i32(fp32_1);
11523 tcg_temp_free_i32(fp32_0);
11524 gen_store_fpr64(ctx, fp64, fd);
11525 tcg_temp_free_i64(fp64);
11526 }
11527 break;
11528 case OPC_CMP_F_S:
11529 case OPC_CMP_UN_S:
11530 case OPC_CMP_EQ_S:
11531 case OPC_CMP_UEQ_S:
11532 case OPC_CMP_OLT_S:
11533 case OPC_CMP_ULT_S:
11534 case OPC_CMP_OLE_S:
11535 case OPC_CMP_ULE_S:
11536 case OPC_CMP_SF_S:
11537 case OPC_CMP_NGLE_S:
11538 case OPC_CMP_SEQ_S:
11539 case OPC_CMP_NGL_S:
11540 case OPC_CMP_LT_S:
11541 case OPC_CMP_NGE_S:
11542 case OPC_CMP_LE_S:
11543 case OPC_CMP_NGT_S:
11544 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11545 if (ctx->opcode & (1 << 6)) {
11546 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11547 } else {
11548 gen_cmp_s(ctx, func-48, ft, fs, cc);
11549 }
11550 break;
11551 case OPC_ADD_D:
11552 check_cp1_registers(ctx, fs | ft | fd);
11553 {
11554 TCGv_i64 fp0 = tcg_temp_new_i64();
11555 TCGv_i64 fp1 = tcg_temp_new_i64();
11556
11557 gen_load_fpr64(ctx, fp0, fs);
11558 gen_load_fpr64(ctx, fp1, ft);
11559 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11560 tcg_temp_free_i64(fp1);
11561 gen_store_fpr64(ctx, fp0, fd);
11562 tcg_temp_free_i64(fp0);
11563 }
11564 break;
11565 case OPC_SUB_D:
11566 check_cp1_registers(ctx, fs | ft | fd);
11567 {
11568 TCGv_i64 fp0 = tcg_temp_new_i64();
11569 TCGv_i64 fp1 = tcg_temp_new_i64();
11570
11571 gen_load_fpr64(ctx, fp0, fs);
11572 gen_load_fpr64(ctx, fp1, ft);
11573 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11574 tcg_temp_free_i64(fp1);
11575 gen_store_fpr64(ctx, fp0, fd);
11576 tcg_temp_free_i64(fp0);
11577 }
11578 break;
11579 case OPC_MUL_D:
11580 check_cp1_registers(ctx, fs | ft | fd);
11581 {
11582 TCGv_i64 fp0 = tcg_temp_new_i64();
11583 TCGv_i64 fp1 = tcg_temp_new_i64();
11584
11585 gen_load_fpr64(ctx, fp0, fs);
11586 gen_load_fpr64(ctx, fp1, ft);
11587 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11588 tcg_temp_free_i64(fp1);
11589 gen_store_fpr64(ctx, fp0, fd);
11590 tcg_temp_free_i64(fp0);
11591 }
11592 break;
11593 case OPC_DIV_D:
11594 check_cp1_registers(ctx, fs | ft | fd);
11595 {
11596 TCGv_i64 fp0 = tcg_temp_new_i64();
11597 TCGv_i64 fp1 = tcg_temp_new_i64();
11598
11599 gen_load_fpr64(ctx, fp0, fs);
11600 gen_load_fpr64(ctx, fp1, ft);
11601 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11602 tcg_temp_free_i64(fp1);
11603 gen_store_fpr64(ctx, fp0, fd);
11604 tcg_temp_free_i64(fp0);
11605 }
11606 break;
11607 case OPC_SQRT_D:
11608 check_cp1_registers(ctx, fs | fd);
11609 {
11610 TCGv_i64 fp0 = tcg_temp_new_i64();
11611
11612 gen_load_fpr64(ctx, fp0, fs);
11613 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11614 gen_store_fpr64(ctx, fp0, fd);
11615 tcg_temp_free_i64(fp0);
11616 }
11617 break;
11618 case OPC_ABS_D:
11619 check_cp1_registers(ctx, fs | fd);
11620 {
11621 TCGv_i64 fp0 = tcg_temp_new_i64();
11622
11623 gen_load_fpr64(ctx, fp0, fs);
11624 if (ctx->abs2008) {
11625 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11626 } else {
11627 gen_helper_float_abs_d(fp0, fp0);
11628 }
11629 gen_store_fpr64(ctx, fp0, fd);
11630 tcg_temp_free_i64(fp0);
11631 }
11632 break;
11633 case OPC_MOV_D:
11634 check_cp1_registers(ctx, fs | fd);
11635 {
11636 TCGv_i64 fp0 = tcg_temp_new_i64();
11637
11638 gen_load_fpr64(ctx, fp0, fs);
11639 gen_store_fpr64(ctx, fp0, fd);
11640 tcg_temp_free_i64(fp0);
11641 }
11642 break;
11643 case OPC_NEG_D:
11644 check_cp1_registers(ctx, fs | fd);
11645 {
11646 TCGv_i64 fp0 = tcg_temp_new_i64();
11647
11648 gen_load_fpr64(ctx, fp0, fs);
11649 if (ctx->abs2008) {
11650 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11651 } else {
11652 gen_helper_float_chs_d(fp0, fp0);
11653 }
11654 gen_store_fpr64(ctx, fp0, fd);
11655 tcg_temp_free_i64(fp0);
11656 }
11657 break;
11658 case OPC_ROUND_L_D:
11659 check_cp1_64bitmode(ctx);
11660 {
11661 TCGv_i64 fp0 = tcg_temp_new_i64();
11662
11663 gen_load_fpr64(ctx, fp0, fs);
11664 if (ctx->nan2008) {
11665 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11666 } else {
11667 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11668 }
11669 gen_store_fpr64(ctx, fp0, fd);
11670 tcg_temp_free_i64(fp0);
11671 }
11672 break;
11673 case OPC_TRUNC_L_D:
11674 check_cp1_64bitmode(ctx);
11675 {
11676 TCGv_i64 fp0 = tcg_temp_new_i64();
11677
11678 gen_load_fpr64(ctx, fp0, fs);
11679 if (ctx->nan2008) {
11680 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11681 } else {
11682 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11683 }
11684 gen_store_fpr64(ctx, fp0, fd);
11685 tcg_temp_free_i64(fp0);
11686 }
11687 break;
11688 case OPC_CEIL_L_D:
11689 check_cp1_64bitmode(ctx);
11690 {
11691 TCGv_i64 fp0 = tcg_temp_new_i64();
11692
11693 gen_load_fpr64(ctx, fp0, fs);
11694 if (ctx->nan2008) {
11695 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11696 } else {
11697 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11698 }
11699 gen_store_fpr64(ctx, fp0, fd);
11700 tcg_temp_free_i64(fp0);
11701 }
11702 break;
11703 case OPC_FLOOR_L_D:
11704 check_cp1_64bitmode(ctx);
11705 {
11706 TCGv_i64 fp0 = tcg_temp_new_i64();
11707
11708 gen_load_fpr64(ctx, fp0, fs);
11709 if (ctx->nan2008) {
11710 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11711 } else {
11712 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11713 }
11714 gen_store_fpr64(ctx, fp0, fd);
11715 tcg_temp_free_i64(fp0);
11716 }
11717 break;
11718 case OPC_ROUND_W_D:
11719 check_cp1_registers(ctx, fs);
11720 {
11721 TCGv_i32 fp32 = tcg_temp_new_i32();
11722 TCGv_i64 fp64 = tcg_temp_new_i64();
11723
11724 gen_load_fpr64(ctx, fp64, fs);
11725 if (ctx->nan2008) {
11726 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11727 } else {
11728 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11729 }
11730 tcg_temp_free_i64(fp64);
11731 gen_store_fpr32(ctx, fp32, fd);
11732 tcg_temp_free_i32(fp32);
11733 }
11734 break;
11735 case OPC_TRUNC_W_D:
11736 check_cp1_registers(ctx, fs);
11737 {
11738 TCGv_i32 fp32 = tcg_temp_new_i32();
11739 TCGv_i64 fp64 = tcg_temp_new_i64();
11740
11741 gen_load_fpr64(ctx, fp64, fs);
11742 if (ctx->nan2008) {
11743 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11744 } else {
11745 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11746 }
11747 tcg_temp_free_i64(fp64);
11748 gen_store_fpr32(ctx, fp32, fd);
11749 tcg_temp_free_i32(fp32);
11750 }
11751 break;
11752 case OPC_CEIL_W_D:
11753 check_cp1_registers(ctx, fs);
11754 {
11755 TCGv_i32 fp32 = tcg_temp_new_i32();
11756 TCGv_i64 fp64 = tcg_temp_new_i64();
11757
11758 gen_load_fpr64(ctx, fp64, fs);
11759 if (ctx->nan2008) {
11760 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11761 } else {
11762 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11763 }
11764 tcg_temp_free_i64(fp64);
11765 gen_store_fpr32(ctx, fp32, fd);
11766 tcg_temp_free_i32(fp32);
11767 }
11768 break;
11769 case OPC_FLOOR_W_D:
11770 check_cp1_registers(ctx, fs);
11771 {
11772 TCGv_i32 fp32 = tcg_temp_new_i32();
11773 TCGv_i64 fp64 = tcg_temp_new_i64();
11774
11775 gen_load_fpr64(ctx, fp64, fs);
11776 if (ctx->nan2008) {
11777 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11778 } else {
11779 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11780 }
11781 tcg_temp_free_i64(fp64);
11782 gen_store_fpr32(ctx, fp32, fd);
11783 tcg_temp_free_i32(fp32);
11784 }
11785 break;
11786 case OPC_SEL_D:
11787 check_insn(ctx, ISA_MIPS32R6);
11788 gen_sel_d(ctx, op1, fd, ft, fs);
11789 break;
11790 case OPC_SELEQZ_D:
11791 check_insn(ctx, ISA_MIPS32R6);
11792 gen_sel_d(ctx, op1, fd, ft, fs);
11793 break;
11794 case OPC_SELNEZ_D:
11795 check_insn(ctx, ISA_MIPS32R6);
11796 gen_sel_d(ctx, op1, fd, ft, fs);
11797 break;
11798 case OPC_MOVCF_D:
11799 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11800 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11801 break;
11802 case OPC_MOVZ_D:
11803 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11804 {
11805 TCGLabel *l1 = gen_new_label();
11806 TCGv_i64 fp0;
11807
11808 if (ft != 0) {
11809 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11810 }
11811 fp0 = tcg_temp_new_i64();
11812 gen_load_fpr64(ctx, fp0, fs);
11813 gen_store_fpr64(ctx, fp0, fd);
11814 tcg_temp_free_i64(fp0);
11815 gen_set_label(l1);
11816 }
11817 break;
11818 case OPC_MOVN_D:
11819 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11820 {
11821 TCGLabel *l1 = gen_new_label();
11822 TCGv_i64 fp0;
11823
11824 if (ft != 0) {
11825 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11826 fp0 = tcg_temp_new_i64();
11827 gen_load_fpr64(ctx, fp0, fs);
11828 gen_store_fpr64(ctx, fp0, fd);
11829 tcg_temp_free_i64(fp0);
11830 gen_set_label(l1);
11831 }
11832 }
11833 break;
11834 case OPC_RECIP_D:
11835 check_cp1_registers(ctx, fs | fd);
11836 {
11837 TCGv_i64 fp0 = tcg_temp_new_i64();
11838
11839 gen_load_fpr64(ctx, fp0, fs);
11840 gen_helper_float_recip_d(fp0, cpu_env, fp0);
11841 gen_store_fpr64(ctx, fp0, fd);
11842 tcg_temp_free_i64(fp0);
11843 }
11844 break;
11845 case OPC_RSQRT_D:
11846 check_cp1_registers(ctx, fs | fd);
11847 {
11848 TCGv_i64 fp0 = tcg_temp_new_i64();
11849
11850 gen_load_fpr64(ctx, fp0, fs);
11851 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11852 gen_store_fpr64(ctx, fp0, fd);
11853 tcg_temp_free_i64(fp0);
11854 }
11855 break;
11856 case OPC_MADDF_D:
11857 check_insn(ctx, ISA_MIPS32R6);
11858 {
11859 TCGv_i64 fp0 = tcg_temp_new_i64();
11860 TCGv_i64 fp1 = tcg_temp_new_i64();
11861 TCGv_i64 fp2 = tcg_temp_new_i64();
11862 gen_load_fpr64(ctx, fp0, fs);
11863 gen_load_fpr64(ctx, fp1, ft);
11864 gen_load_fpr64(ctx, fp2, fd);
11865 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11866 gen_store_fpr64(ctx, fp2, fd);
11867 tcg_temp_free_i64(fp2);
11868 tcg_temp_free_i64(fp1);
11869 tcg_temp_free_i64(fp0);
11870 }
11871 break;
11872 case OPC_MSUBF_D:
11873 check_insn(ctx, ISA_MIPS32R6);
11874 {
11875 TCGv_i64 fp0 = tcg_temp_new_i64();
11876 TCGv_i64 fp1 = tcg_temp_new_i64();
11877 TCGv_i64 fp2 = tcg_temp_new_i64();
11878 gen_load_fpr64(ctx, fp0, fs);
11879 gen_load_fpr64(ctx, fp1, ft);
11880 gen_load_fpr64(ctx, fp2, fd);
11881 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11882 gen_store_fpr64(ctx, fp2, fd);
11883 tcg_temp_free_i64(fp2);
11884 tcg_temp_free_i64(fp1);
11885 tcg_temp_free_i64(fp0);
11886 }
11887 break;
11888 case OPC_RINT_D:
11889 check_insn(ctx, ISA_MIPS32R6);
11890 {
11891 TCGv_i64 fp0 = tcg_temp_new_i64();
11892 gen_load_fpr64(ctx, fp0, fs);
11893 gen_helper_float_rint_d(fp0, cpu_env, fp0);
11894 gen_store_fpr64(ctx, fp0, fd);
11895 tcg_temp_free_i64(fp0);
11896 }
11897 break;
11898 case OPC_CLASS_D:
11899 check_insn(ctx, ISA_MIPS32R6);
11900 {
11901 TCGv_i64 fp0 = tcg_temp_new_i64();
11902 gen_load_fpr64(ctx, fp0, fs);
11903 gen_helper_float_class_d(fp0, cpu_env, fp0);
11904 gen_store_fpr64(ctx, fp0, fd);
11905 tcg_temp_free_i64(fp0);
11906 }
11907 break;
11908 case OPC_MIN_D: /* OPC_RECIP2_D */
11909 if (ctx->insn_flags & ISA_MIPS32R6) {
11910 /* OPC_MIN_D */
11911 TCGv_i64 fp0 = tcg_temp_new_i64();
11912 TCGv_i64 fp1 = tcg_temp_new_i64();
11913 gen_load_fpr64(ctx, fp0, fs);
11914 gen_load_fpr64(ctx, fp1, ft);
11915 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11916 gen_store_fpr64(ctx, fp1, fd);
11917 tcg_temp_free_i64(fp1);
11918 tcg_temp_free_i64(fp0);
11919 } else {
11920 /* OPC_RECIP2_D */
11921 check_cp1_64bitmode(ctx);
11922 {
11923 TCGv_i64 fp0 = tcg_temp_new_i64();
11924 TCGv_i64 fp1 = tcg_temp_new_i64();
11925
11926 gen_load_fpr64(ctx, fp0, fs);
11927 gen_load_fpr64(ctx, fp1, ft);
11928 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11929 tcg_temp_free_i64(fp1);
11930 gen_store_fpr64(ctx, fp0, fd);
11931 tcg_temp_free_i64(fp0);
11932 }
11933 }
11934 break;
11935 case OPC_MINA_D: /* OPC_RECIP1_D */
11936 if (ctx->insn_flags & ISA_MIPS32R6) {
11937 /* OPC_MINA_D */
11938 TCGv_i64 fp0 = tcg_temp_new_i64();
11939 TCGv_i64 fp1 = tcg_temp_new_i64();
11940 gen_load_fpr64(ctx, fp0, fs);
11941 gen_load_fpr64(ctx, fp1, ft);
11942 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11943 gen_store_fpr64(ctx, fp1, fd);
11944 tcg_temp_free_i64(fp1);
11945 tcg_temp_free_i64(fp0);
11946 } else {
11947 /* OPC_RECIP1_D */
11948 check_cp1_64bitmode(ctx);
11949 {
11950 TCGv_i64 fp0 = tcg_temp_new_i64();
11951
11952 gen_load_fpr64(ctx, fp0, fs);
11953 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11954 gen_store_fpr64(ctx, fp0, fd);
11955 tcg_temp_free_i64(fp0);
11956 }
11957 }
11958 break;
11959 case OPC_MAX_D: /* OPC_RSQRT1_D */
11960 if (ctx->insn_flags & ISA_MIPS32R6) {
11961 /* OPC_MAX_D */
11962 TCGv_i64 fp0 = tcg_temp_new_i64();
11963 TCGv_i64 fp1 = tcg_temp_new_i64();
11964 gen_load_fpr64(ctx, fp0, fs);
11965 gen_load_fpr64(ctx, fp1, ft);
11966 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11967 gen_store_fpr64(ctx, fp1, fd);
11968 tcg_temp_free_i64(fp1);
11969 tcg_temp_free_i64(fp0);
11970 } else {
11971 /* OPC_RSQRT1_D */
11972 check_cp1_64bitmode(ctx);
11973 {
11974 TCGv_i64 fp0 = tcg_temp_new_i64();
11975
11976 gen_load_fpr64(ctx, fp0, fs);
11977 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11978 gen_store_fpr64(ctx, fp0, fd);
11979 tcg_temp_free_i64(fp0);
11980 }
11981 }
11982 break;
11983 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11984 if (ctx->insn_flags & ISA_MIPS32R6) {
11985 /* OPC_MAXA_D */
11986 TCGv_i64 fp0 = tcg_temp_new_i64();
11987 TCGv_i64 fp1 = tcg_temp_new_i64();
11988 gen_load_fpr64(ctx, fp0, fs);
11989 gen_load_fpr64(ctx, fp1, ft);
11990 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11991 gen_store_fpr64(ctx, fp1, fd);
11992 tcg_temp_free_i64(fp1);
11993 tcg_temp_free_i64(fp0);
11994 } else {
11995 /* OPC_RSQRT2_D */
11996 check_cp1_64bitmode(ctx);
11997 {
11998 TCGv_i64 fp0 = tcg_temp_new_i64();
11999 TCGv_i64 fp1 = tcg_temp_new_i64();
12000
12001 gen_load_fpr64(ctx, fp0, fs);
12002 gen_load_fpr64(ctx, fp1, ft);
12003 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
12004 tcg_temp_free_i64(fp1);
12005 gen_store_fpr64(ctx, fp0, fd);
12006 tcg_temp_free_i64(fp0);
12007 }
12008 }
12009 break;
12010 case OPC_CMP_F_D:
12011 case OPC_CMP_UN_D:
12012 case OPC_CMP_EQ_D:
12013 case OPC_CMP_UEQ_D:
12014 case OPC_CMP_OLT_D:
12015 case OPC_CMP_ULT_D:
12016 case OPC_CMP_OLE_D:
12017 case OPC_CMP_ULE_D:
12018 case OPC_CMP_SF_D:
12019 case OPC_CMP_NGLE_D:
12020 case OPC_CMP_SEQ_D:
12021 case OPC_CMP_NGL_D:
12022 case OPC_CMP_LT_D:
12023 case OPC_CMP_NGE_D:
12024 case OPC_CMP_LE_D:
12025 case OPC_CMP_NGT_D:
12026 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12027 if (ctx->opcode & (1 << 6)) {
12028 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
12029 } else {
12030 gen_cmp_d(ctx, func-48, ft, fs, cc);
12031 }
12032 break;
12033 case OPC_CVT_S_D:
12034 check_cp1_registers(ctx, fs);
12035 {
12036 TCGv_i32 fp32 = tcg_temp_new_i32();
12037 TCGv_i64 fp64 = tcg_temp_new_i64();
12038
12039 gen_load_fpr64(ctx, fp64, fs);
12040 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
12041 tcg_temp_free_i64(fp64);
12042 gen_store_fpr32(ctx, fp32, fd);
12043 tcg_temp_free_i32(fp32);
12044 }
12045 break;
12046 case OPC_CVT_W_D:
12047 check_cp1_registers(ctx, fs);
12048 {
12049 TCGv_i32 fp32 = tcg_temp_new_i32();
12050 TCGv_i64 fp64 = tcg_temp_new_i64();
12051
12052 gen_load_fpr64(ctx, fp64, fs);
12053 if (ctx->nan2008) {
12054 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
12055 } else {
12056 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
12057 }
12058 tcg_temp_free_i64(fp64);
12059 gen_store_fpr32(ctx, fp32, fd);
12060 tcg_temp_free_i32(fp32);
12061 }
12062 break;
12063 case OPC_CVT_L_D:
12064 check_cp1_64bitmode(ctx);
12065 {
12066 TCGv_i64 fp0 = tcg_temp_new_i64();
12067
12068 gen_load_fpr64(ctx, fp0, fs);
12069 if (ctx->nan2008) {
12070 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
12071 } else {
12072 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
12073 }
12074 gen_store_fpr64(ctx, fp0, fd);
12075 tcg_temp_free_i64(fp0);
12076 }
12077 break;
12078 case OPC_CVT_S_W:
12079 {
12080 TCGv_i32 fp0 = tcg_temp_new_i32();
12081
12082 gen_load_fpr32(ctx, fp0, fs);
12083 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
12084 gen_store_fpr32(ctx, fp0, fd);
12085 tcg_temp_free_i32(fp0);
12086 }
12087 break;
12088 case OPC_CVT_D_W:
12089 check_cp1_registers(ctx, fd);
12090 {
12091 TCGv_i32 fp32 = tcg_temp_new_i32();
12092 TCGv_i64 fp64 = tcg_temp_new_i64();
12093
12094 gen_load_fpr32(ctx, fp32, fs);
12095 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
12096 tcg_temp_free_i32(fp32);
12097 gen_store_fpr64(ctx, fp64, fd);
12098 tcg_temp_free_i64(fp64);
12099 }
12100 break;
12101 case OPC_CVT_S_L:
12102 check_cp1_64bitmode(ctx);
12103 {
12104 TCGv_i32 fp32 = tcg_temp_new_i32();
12105 TCGv_i64 fp64 = tcg_temp_new_i64();
12106
12107 gen_load_fpr64(ctx, fp64, fs);
12108 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
12109 tcg_temp_free_i64(fp64);
12110 gen_store_fpr32(ctx, fp32, fd);
12111 tcg_temp_free_i32(fp32);
12112 }
12113 break;
12114 case OPC_CVT_D_L:
12115 check_cp1_64bitmode(ctx);
12116 {
12117 TCGv_i64 fp0 = tcg_temp_new_i64();
12118
12119 gen_load_fpr64(ctx, fp0, fs);
12120 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
12121 gen_store_fpr64(ctx, fp0, fd);
12122 tcg_temp_free_i64(fp0);
12123 }
12124 break;
12125 case OPC_CVT_PS_PW:
12126 check_ps(ctx);
12127 {
12128 TCGv_i64 fp0 = tcg_temp_new_i64();
12129
12130 gen_load_fpr64(ctx, fp0, fs);
12131 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12132 gen_store_fpr64(ctx, fp0, fd);
12133 tcg_temp_free_i64(fp0);
12134 }
12135 break;
12136 case OPC_ADD_PS:
12137 check_ps(ctx);
12138 {
12139 TCGv_i64 fp0 = tcg_temp_new_i64();
12140 TCGv_i64 fp1 = tcg_temp_new_i64();
12141
12142 gen_load_fpr64(ctx, fp0, fs);
12143 gen_load_fpr64(ctx, fp1, ft);
12144 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12145 tcg_temp_free_i64(fp1);
12146 gen_store_fpr64(ctx, fp0, fd);
12147 tcg_temp_free_i64(fp0);
12148 }
12149 break;
12150 case OPC_SUB_PS:
12151 check_ps(ctx);
12152 {
12153 TCGv_i64 fp0 = tcg_temp_new_i64();
12154 TCGv_i64 fp1 = tcg_temp_new_i64();
12155
12156 gen_load_fpr64(ctx, fp0, fs);
12157 gen_load_fpr64(ctx, fp1, ft);
12158 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12159 tcg_temp_free_i64(fp1);
12160 gen_store_fpr64(ctx, fp0, fd);
12161 tcg_temp_free_i64(fp0);
12162 }
12163 break;
12164 case OPC_MUL_PS:
12165 check_ps(ctx);
12166 {
12167 TCGv_i64 fp0 = tcg_temp_new_i64();
12168 TCGv_i64 fp1 = tcg_temp_new_i64();
12169
12170 gen_load_fpr64(ctx, fp0, fs);
12171 gen_load_fpr64(ctx, fp1, ft);
12172 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12173 tcg_temp_free_i64(fp1);
12174 gen_store_fpr64(ctx, fp0, fd);
12175 tcg_temp_free_i64(fp0);
12176 }
12177 break;
12178 case OPC_ABS_PS:
12179 check_ps(ctx);
12180 {
12181 TCGv_i64 fp0 = tcg_temp_new_i64();
12182
12183 gen_load_fpr64(ctx, fp0, fs);
12184 gen_helper_float_abs_ps(fp0, fp0);
12185 gen_store_fpr64(ctx, fp0, fd);
12186 tcg_temp_free_i64(fp0);
12187 }
12188 break;
12189 case OPC_MOV_PS:
12190 check_ps(ctx);
12191 {
12192 TCGv_i64 fp0 = tcg_temp_new_i64();
12193
12194 gen_load_fpr64(ctx, fp0, fs);
12195 gen_store_fpr64(ctx, fp0, fd);
12196 tcg_temp_free_i64(fp0);
12197 }
12198 break;
12199 case OPC_NEG_PS:
12200 check_ps(ctx);
12201 {
12202 TCGv_i64 fp0 = tcg_temp_new_i64();
12203
12204 gen_load_fpr64(ctx, fp0, fs);
12205 gen_helper_float_chs_ps(fp0, fp0);
12206 gen_store_fpr64(ctx, fp0, fd);
12207 tcg_temp_free_i64(fp0);
12208 }
12209 break;
12210 case OPC_MOVCF_PS:
12211 check_ps(ctx);
12212 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12213 break;
12214 case OPC_MOVZ_PS:
12215 check_ps(ctx);
12216 {
12217 TCGLabel *l1 = gen_new_label();
12218 TCGv_i64 fp0;
12219
12220 if (ft != 0) {
12221 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12222 }
12223 fp0 = tcg_temp_new_i64();
12224 gen_load_fpr64(ctx, fp0, fs);
12225 gen_store_fpr64(ctx, fp0, fd);
12226 tcg_temp_free_i64(fp0);
12227 gen_set_label(l1);
12228 }
12229 break;
12230 case OPC_MOVN_PS:
12231 check_ps(ctx);
12232 {
12233 TCGLabel *l1 = gen_new_label();
12234 TCGv_i64 fp0;
12235
12236 if (ft != 0) {
12237 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12238 fp0 = tcg_temp_new_i64();
12239 gen_load_fpr64(ctx, fp0, fs);
12240 gen_store_fpr64(ctx, fp0, fd);
12241 tcg_temp_free_i64(fp0);
12242 gen_set_label(l1);
12243 }
12244 }
12245 break;
12246 case OPC_ADDR_PS:
12247 check_ps(ctx);
12248 {
12249 TCGv_i64 fp0 = tcg_temp_new_i64();
12250 TCGv_i64 fp1 = tcg_temp_new_i64();
12251
12252 gen_load_fpr64(ctx, fp0, ft);
12253 gen_load_fpr64(ctx, fp1, fs);
12254 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12255 tcg_temp_free_i64(fp1);
12256 gen_store_fpr64(ctx, fp0, fd);
12257 tcg_temp_free_i64(fp0);
12258 }
12259 break;
12260 case OPC_MULR_PS:
12261 check_ps(ctx);
12262 {
12263 TCGv_i64 fp0 = tcg_temp_new_i64();
12264 TCGv_i64 fp1 = tcg_temp_new_i64();
12265
12266 gen_load_fpr64(ctx, fp0, ft);
12267 gen_load_fpr64(ctx, fp1, fs);
12268 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12269 tcg_temp_free_i64(fp1);
12270 gen_store_fpr64(ctx, fp0, fd);
12271 tcg_temp_free_i64(fp0);
12272 }
12273 break;
12274 case OPC_RECIP2_PS:
12275 check_ps(ctx);
12276 {
12277 TCGv_i64 fp0 = tcg_temp_new_i64();
12278 TCGv_i64 fp1 = tcg_temp_new_i64();
12279
12280 gen_load_fpr64(ctx, fp0, fs);
12281 gen_load_fpr64(ctx, fp1, ft);
12282 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12283 tcg_temp_free_i64(fp1);
12284 gen_store_fpr64(ctx, fp0, fd);
12285 tcg_temp_free_i64(fp0);
12286 }
12287 break;
12288 case OPC_RECIP1_PS:
12289 check_ps(ctx);
12290 {
12291 TCGv_i64 fp0 = tcg_temp_new_i64();
12292
12293 gen_load_fpr64(ctx, fp0, fs);
12294 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12295 gen_store_fpr64(ctx, fp0, fd);
12296 tcg_temp_free_i64(fp0);
12297 }
12298 break;
12299 case OPC_RSQRT1_PS:
12300 check_ps(ctx);
12301 {
12302 TCGv_i64 fp0 = tcg_temp_new_i64();
12303
12304 gen_load_fpr64(ctx, fp0, fs);
12305 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12306 gen_store_fpr64(ctx, fp0, fd);
12307 tcg_temp_free_i64(fp0);
12308 }
12309 break;
12310 case OPC_RSQRT2_PS:
12311 check_ps(ctx);
12312 {
12313 TCGv_i64 fp0 = tcg_temp_new_i64();
12314 TCGv_i64 fp1 = tcg_temp_new_i64();
12315
12316 gen_load_fpr64(ctx, fp0, fs);
12317 gen_load_fpr64(ctx, fp1, ft);
12318 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12319 tcg_temp_free_i64(fp1);
12320 gen_store_fpr64(ctx, fp0, fd);
12321 tcg_temp_free_i64(fp0);
12322 }
12323 break;
12324 case OPC_CVT_S_PU:
12325 check_cp1_64bitmode(ctx);
12326 {
12327 TCGv_i32 fp0 = tcg_temp_new_i32();
12328
12329 gen_load_fpr32h(ctx, fp0, fs);
12330 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12331 gen_store_fpr32(ctx, fp0, fd);
12332 tcg_temp_free_i32(fp0);
12333 }
12334 break;
12335 case OPC_CVT_PW_PS:
12336 check_ps(ctx);
12337 {
12338 TCGv_i64 fp0 = tcg_temp_new_i64();
12339
12340 gen_load_fpr64(ctx, fp0, fs);
12341 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12342 gen_store_fpr64(ctx, fp0, fd);
12343 tcg_temp_free_i64(fp0);
12344 }
12345 break;
12346 case OPC_CVT_S_PL:
12347 check_cp1_64bitmode(ctx);
12348 {
12349 TCGv_i32 fp0 = tcg_temp_new_i32();
12350
12351 gen_load_fpr32(ctx, fp0, fs);
12352 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12353 gen_store_fpr32(ctx, fp0, fd);
12354 tcg_temp_free_i32(fp0);
12355 }
12356 break;
12357 case OPC_PLL_PS:
12358 check_ps(ctx);
12359 {
12360 TCGv_i32 fp0 = tcg_temp_new_i32();
12361 TCGv_i32 fp1 = tcg_temp_new_i32();
12362
12363 gen_load_fpr32(ctx, fp0, fs);
12364 gen_load_fpr32(ctx, fp1, ft);
12365 gen_store_fpr32h(ctx, fp0, fd);
12366 gen_store_fpr32(ctx, fp1, fd);
12367 tcg_temp_free_i32(fp0);
12368 tcg_temp_free_i32(fp1);
12369 }
12370 break;
12371 case OPC_PLU_PS:
12372 check_ps(ctx);
12373 {
12374 TCGv_i32 fp0 = tcg_temp_new_i32();
12375 TCGv_i32 fp1 = tcg_temp_new_i32();
12376
12377 gen_load_fpr32(ctx, fp0, fs);
12378 gen_load_fpr32h(ctx, fp1, ft);
12379 gen_store_fpr32(ctx, fp1, fd);
12380 gen_store_fpr32h(ctx, fp0, fd);
12381 tcg_temp_free_i32(fp0);
12382 tcg_temp_free_i32(fp1);
12383 }
12384 break;
12385 case OPC_PUL_PS:
12386 check_ps(ctx);
12387 {
12388 TCGv_i32 fp0 = tcg_temp_new_i32();
12389 TCGv_i32 fp1 = tcg_temp_new_i32();
12390
12391 gen_load_fpr32h(ctx, fp0, fs);
12392 gen_load_fpr32(ctx, fp1, ft);
12393 gen_store_fpr32(ctx, fp1, fd);
12394 gen_store_fpr32h(ctx, fp0, fd);
12395 tcg_temp_free_i32(fp0);
12396 tcg_temp_free_i32(fp1);
12397 }
12398 break;
12399 case OPC_PUU_PS:
12400 check_ps(ctx);
12401 {
12402 TCGv_i32 fp0 = tcg_temp_new_i32();
12403 TCGv_i32 fp1 = tcg_temp_new_i32();
12404
12405 gen_load_fpr32h(ctx, fp0, fs);
12406 gen_load_fpr32h(ctx, fp1, ft);
12407 gen_store_fpr32(ctx, fp1, fd);
12408 gen_store_fpr32h(ctx, fp0, fd);
12409 tcg_temp_free_i32(fp0);
12410 tcg_temp_free_i32(fp1);
12411 }
12412 break;
12413 case OPC_CMP_F_PS:
12414 case OPC_CMP_UN_PS:
12415 case OPC_CMP_EQ_PS:
12416 case OPC_CMP_UEQ_PS:
12417 case OPC_CMP_OLT_PS:
12418 case OPC_CMP_ULT_PS:
12419 case OPC_CMP_OLE_PS:
12420 case OPC_CMP_ULE_PS:
12421 case OPC_CMP_SF_PS:
12422 case OPC_CMP_NGLE_PS:
12423 case OPC_CMP_SEQ_PS:
12424 case OPC_CMP_NGL_PS:
12425 case OPC_CMP_LT_PS:
12426 case OPC_CMP_NGE_PS:
12427 case OPC_CMP_LE_PS:
12428 case OPC_CMP_NGT_PS:
12429 if (ctx->opcode & (1 << 6)) {
12430 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12431 } else {
12432 gen_cmp_ps(ctx, func-48, ft, fs, cc);
12433 }
12434 break;
12435 default:
12436 MIPS_INVAL("farith");
12437 generate_exception_end(ctx, EXCP_RI);
12438 return;
12439 }
12440 }
12441
12442 /* Coprocessor 3 (FPU) */
12443 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
12444 int fd, int fs, int base, int index)
12445 {
12446 TCGv t0 = tcg_temp_new();
12447
12448 if (base == 0) {
12449 gen_load_gpr(t0, index);
12450 } else if (index == 0) {
12451 gen_load_gpr(t0, base);
12452 } else {
12453 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12454 }
12455 /*
12456 * Don't do NOP if destination is zero: we must perform the actual
12457 * memory access.
12458 */
12459 switch (opc) {
12460 case OPC_LWXC1:
12461 check_cop1x(ctx);
12462 {
12463 TCGv_i32 fp0 = tcg_temp_new_i32();
12464
12465 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12466 tcg_gen_trunc_tl_i32(fp0, t0);
12467 gen_store_fpr32(ctx, fp0, fd);
12468 tcg_temp_free_i32(fp0);
12469 }
12470 break;
12471 case OPC_LDXC1:
12472 check_cop1x(ctx);
12473 check_cp1_registers(ctx, fd);
12474 {
12475 TCGv_i64 fp0 = tcg_temp_new_i64();
12476 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12477 gen_store_fpr64(ctx, fp0, fd);
12478 tcg_temp_free_i64(fp0);
12479 }
12480 break;
12481 case OPC_LUXC1:
12482 check_cp1_64bitmode(ctx);
12483 tcg_gen_andi_tl(t0, t0, ~0x7);
12484 {
12485 TCGv_i64 fp0 = tcg_temp_new_i64();
12486
12487 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12488 gen_store_fpr64(ctx, fp0, fd);
12489 tcg_temp_free_i64(fp0);
12490 }
12491 break;
12492 case OPC_SWXC1:
12493 check_cop1x(ctx);
12494 {
12495 TCGv_i32 fp0 = tcg_temp_new_i32();
12496 gen_load_fpr32(ctx, fp0, fs);
12497 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12498 tcg_temp_free_i32(fp0);
12499 }
12500 break;
12501 case OPC_SDXC1:
12502 check_cop1x(ctx);
12503 check_cp1_registers(ctx, fs);
12504 {
12505 TCGv_i64 fp0 = tcg_temp_new_i64();
12506 gen_load_fpr64(ctx, fp0, fs);
12507 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12508 tcg_temp_free_i64(fp0);
12509 }
12510 break;
12511 case OPC_SUXC1:
12512 check_cp1_64bitmode(ctx);
12513 tcg_gen_andi_tl(t0, t0, ~0x7);
12514 {
12515 TCGv_i64 fp0 = tcg_temp_new_i64();
12516 gen_load_fpr64(ctx, fp0, fs);
12517 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12518 tcg_temp_free_i64(fp0);
12519 }
12520 break;
12521 }
12522 tcg_temp_free(t0);
12523 }
12524
12525 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
12526 int fd, int fr, int fs, int ft)
12527 {
12528 switch (opc) {
12529 case OPC_ALNV_PS:
12530 check_ps(ctx);
12531 {
12532 TCGv t0 = tcg_temp_local_new();
12533 TCGv_i32 fp = tcg_temp_new_i32();
12534 TCGv_i32 fph = tcg_temp_new_i32();
12535 TCGLabel *l1 = gen_new_label();
12536 TCGLabel *l2 = gen_new_label();
12537
12538 gen_load_gpr(t0, fr);
12539 tcg_gen_andi_tl(t0, t0, 0x7);
12540
12541 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12542 gen_load_fpr32(ctx, fp, fs);
12543 gen_load_fpr32h(ctx, fph, fs);
12544 gen_store_fpr32(ctx, fp, fd);
12545 gen_store_fpr32h(ctx, fph, fd);
12546 tcg_gen_br(l2);
12547 gen_set_label(l1);
12548 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12549 tcg_temp_free(t0);
12550 #ifdef TARGET_WORDS_BIGENDIAN
12551 gen_load_fpr32(ctx, fp, fs);
12552 gen_load_fpr32h(ctx, fph, ft);
12553 gen_store_fpr32h(ctx, fp, fd);
12554 gen_store_fpr32(ctx, fph, fd);
12555 #else
12556 gen_load_fpr32h(ctx, fph, fs);
12557 gen_load_fpr32(ctx, fp, ft);
12558 gen_store_fpr32(ctx, fph, fd);
12559 gen_store_fpr32h(ctx, fp, fd);
12560 #endif
12561 gen_set_label(l2);
12562 tcg_temp_free_i32(fp);
12563 tcg_temp_free_i32(fph);
12564 }
12565 break;
12566 case OPC_MADD_S:
12567 check_cop1x(ctx);
12568 {
12569 TCGv_i32 fp0 = tcg_temp_new_i32();
12570 TCGv_i32 fp1 = tcg_temp_new_i32();
12571 TCGv_i32 fp2 = tcg_temp_new_i32();
12572
12573 gen_load_fpr32(ctx, fp0, fs);
12574 gen_load_fpr32(ctx, fp1, ft);
12575 gen_load_fpr32(ctx, fp2, fr);
12576 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12577 tcg_temp_free_i32(fp0);
12578 tcg_temp_free_i32(fp1);
12579 gen_store_fpr32(ctx, fp2, fd);
12580 tcg_temp_free_i32(fp2);
12581 }
12582 break;
12583 case OPC_MADD_D:
12584 check_cop1x(ctx);
12585 check_cp1_registers(ctx, fd | fs | ft | fr);
12586 {
12587 TCGv_i64 fp0 = tcg_temp_new_i64();
12588 TCGv_i64 fp1 = tcg_temp_new_i64();
12589 TCGv_i64 fp2 = tcg_temp_new_i64();
12590
12591 gen_load_fpr64(ctx, fp0, fs);
12592 gen_load_fpr64(ctx, fp1, ft);
12593 gen_load_fpr64(ctx, fp2, fr);
12594 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12595 tcg_temp_free_i64(fp0);
12596 tcg_temp_free_i64(fp1);
12597 gen_store_fpr64(ctx, fp2, fd);
12598 tcg_temp_free_i64(fp2);
12599 }
12600 break;
12601 case OPC_MADD_PS:
12602 check_ps(ctx);
12603 {
12604 TCGv_i64 fp0 = tcg_temp_new_i64();
12605 TCGv_i64 fp1 = tcg_temp_new_i64();
12606 TCGv_i64 fp2 = tcg_temp_new_i64();
12607
12608 gen_load_fpr64(ctx, fp0, fs);
12609 gen_load_fpr64(ctx, fp1, ft);
12610 gen_load_fpr64(ctx, fp2, fr);
12611 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12612 tcg_temp_free_i64(fp0);
12613 tcg_temp_free_i64(fp1);
12614 gen_store_fpr64(ctx, fp2, fd);
12615 tcg_temp_free_i64(fp2);
12616 }
12617 break;
12618 case OPC_MSUB_S:
12619 check_cop1x(ctx);
12620 {
12621 TCGv_i32 fp0 = tcg_temp_new_i32();
12622 TCGv_i32 fp1 = tcg_temp_new_i32();
12623 TCGv_i32 fp2 = tcg_temp_new_i32();
12624
12625 gen_load_fpr32(ctx, fp0, fs);
12626 gen_load_fpr32(ctx, fp1, ft);
12627 gen_load_fpr32(ctx, fp2, fr);
12628 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12629 tcg_temp_free_i32(fp0);
12630 tcg_temp_free_i32(fp1);
12631 gen_store_fpr32(ctx, fp2, fd);
12632 tcg_temp_free_i32(fp2);
12633 }
12634 break;
12635 case OPC_MSUB_D:
12636 check_cop1x(ctx);
12637 check_cp1_registers(ctx, fd | fs | ft | fr);
12638 {
12639 TCGv_i64 fp0 = tcg_temp_new_i64();
12640 TCGv_i64 fp1 = tcg_temp_new_i64();
12641 TCGv_i64 fp2 = tcg_temp_new_i64();
12642
12643 gen_load_fpr64(ctx, fp0, fs);
12644 gen_load_fpr64(ctx, fp1, ft);
12645 gen_load_fpr64(ctx, fp2, fr);
12646 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12647 tcg_temp_free_i64(fp0);
12648 tcg_temp_free_i64(fp1);
12649 gen_store_fpr64(ctx, fp2, fd);
12650 tcg_temp_free_i64(fp2);
12651 }
12652 break;
12653 case OPC_MSUB_PS:
12654 check_ps(ctx);
12655 {
12656 TCGv_i64 fp0 = tcg_temp_new_i64();
12657 TCGv_i64 fp1 = tcg_temp_new_i64();
12658 TCGv_i64 fp2 = tcg_temp_new_i64();
12659
12660 gen_load_fpr64(ctx, fp0, fs);
12661 gen_load_fpr64(ctx, fp1, ft);
12662 gen_load_fpr64(ctx, fp2, fr);
12663 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12664 tcg_temp_free_i64(fp0);
12665 tcg_temp_free_i64(fp1);
12666 gen_store_fpr64(ctx, fp2, fd);
12667 tcg_temp_free_i64(fp2);
12668 }
12669 break;
12670 case OPC_NMADD_S:
12671 check_cop1x(ctx);
12672 {
12673 TCGv_i32 fp0 = tcg_temp_new_i32();
12674 TCGv_i32 fp1 = tcg_temp_new_i32();
12675 TCGv_i32 fp2 = tcg_temp_new_i32();
12676
12677 gen_load_fpr32(ctx, fp0, fs);
12678 gen_load_fpr32(ctx, fp1, ft);
12679 gen_load_fpr32(ctx, fp2, fr);
12680 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12681 tcg_temp_free_i32(fp0);
12682 tcg_temp_free_i32(fp1);
12683 gen_store_fpr32(ctx, fp2, fd);
12684 tcg_temp_free_i32(fp2);
12685 }
12686 break;
12687 case OPC_NMADD_D:
12688 check_cop1x(ctx);
12689 check_cp1_registers(ctx, fd | fs | ft | fr);
12690 {
12691 TCGv_i64 fp0 = tcg_temp_new_i64();
12692 TCGv_i64 fp1 = tcg_temp_new_i64();
12693 TCGv_i64 fp2 = tcg_temp_new_i64();
12694
12695 gen_load_fpr64(ctx, fp0, fs);
12696 gen_load_fpr64(ctx, fp1, ft);
12697 gen_load_fpr64(ctx, fp2, fr);
12698 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12699 tcg_temp_free_i64(fp0);
12700 tcg_temp_free_i64(fp1);
12701 gen_store_fpr64(ctx, fp2, fd);
12702 tcg_temp_free_i64(fp2);
12703 }
12704 break;
12705 case OPC_NMADD_PS:
12706 check_ps(ctx);
12707 {
12708 TCGv_i64 fp0 = tcg_temp_new_i64();
12709 TCGv_i64 fp1 = tcg_temp_new_i64();
12710 TCGv_i64 fp2 = tcg_temp_new_i64();
12711
12712 gen_load_fpr64(ctx, fp0, fs);
12713 gen_load_fpr64(ctx, fp1, ft);
12714 gen_load_fpr64(ctx, fp2, fr);
12715 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12716 tcg_temp_free_i64(fp0);
12717 tcg_temp_free_i64(fp1);
12718 gen_store_fpr64(ctx, fp2, fd);
12719 tcg_temp_free_i64(fp2);
12720 }
12721 break;
12722 case OPC_NMSUB_S:
12723 check_cop1x(ctx);
12724 {
12725 TCGv_i32 fp0 = tcg_temp_new_i32();
12726 TCGv_i32 fp1 = tcg_temp_new_i32();
12727 TCGv_i32 fp2 = tcg_temp_new_i32();
12728
12729 gen_load_fpr32(ctx, fp0, fs);
12730 gen_load_fpr32(ctx, fp1, ft);
12731 gen_load_fpr32(ctx, fp2, fr);
12732 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12733 tcg_temp_free_i32(fp0);
12734 tcg_temp_free_i32(fp1);
12735 gen_store_fpr32(ctx, fp2, fd);
12736 tcg_temp_free_i32(fp2);
12737 }
12738 break;
12739 case OPC_NMSUB_D:
12740 check_cop1x(ctx);
12741 check_cp1_registers(ctx, fd | fs | ft | fr);
12742 {
12743 TCGv_i64 fp0 = tcg_temp_new_i64();
12744 TCGv_i64 fp1 = tcg_temp_new_i64();
12745 TCGv_i64 fp2 = tcg_temp_new_i64();
12746
12747 gen_load_fpr64(ctx, fp0, fs);
12748 gen_load_fpr64(ctx, fp1, ft);
12749 gen_load_fpr64(ctx, fp2, fr);
12750 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12751 tcg_temp_free_i64(fp0);
12752 tcg_temp_free_i64(fp1);
12753 gen_store_fpr64(ctx, fp2, fd);
12754 tcg_temp_free_i64(fp2);
12755 }
12756 break;
12757 case OPC_NMSUB_PS:
12758 check_ps(ctx);
12759 {
12760 TCGv_i64 fp0 = tcg_temp_new_i64();
12761 TCGv_i64 fp1 = tcg_temp_new_i64();
12762 TCGv_i64 fp2 = tcg_temp_new_i64();
12763
12764 gen_load_fpr64(ctx, fp0, fs);
12765 gen_load_fpr64(ctx, fp1, ft);
12766 gen_load_fpr64(ctx, fp2, fr);
12767 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12768 tcg_temp_free_i64(fp0);
12769 tcg_temp_free_i64(fp1);
12770 gen_store_fpr64(ctx, fp2, fd);
12771 tcg_temp_free_i64(fp2);
12772 }
12773 break;
12774 default:
12775 MIPS_INVAL("flt3_arith");
12776 generate_exception_end(ctx, EXCP_RI);
12777 return;
12778 }
12779 }
12780
12781 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12782 {
12783 TCGv t0;
12784
12785 #if !defined(CONFIG_USER_ONLY)
12786 /*
12787 * The Linux kernel will emulate rdhwr if it's not supported natively.
12788 * Therefore only check the ISA in system mode.
12789 */
12790 check_insn(ctx, ISA_MIPS32R2);
12791 #endif
12792 t0 = tcg_temp_new();
12793
12794 switch (rd) {
12795 case 0:
12796 gen_helper_rdhwr_cpunum(t0, cpu_env);
12797 gen_store_gpr(t0, rt);
12798 break;
12799 case 1:
12800 gen_helper_rdhwr_synci_step(t0, cpu_env);
12801 gen_store_gpr(t0, rt);
12802 break;
12803 case 2:
12804 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12805 gen_io_start();
12806 }
12807 gen_helper_rdhwr_cc(t0, cpu_env);
12808 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12809 gen_io_end();
12810 }
12811 gen_store_gpr(t0, rt);
12812 /*
12813 * Break the TB to be able to take timer interrupts immediately
12814 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12815 * we break completely out of translated code.
12816 */
12817 gen_save_pc(ctx->base.pc_next + 4);
12818 ctx->base.is_jmp = DISAS_EXIT;
12819 break;
12820 case 3:
12821 gen_helper_rdhwr_ccres(t0, cpu_env);
12822 gen_store_gpr(t0, rt);
12823 break;
12824 case 4:
12825 check_insn(ctx, ISA_MIPS32R6);
12826 if (sel != 0) {
12827 /*
12828 * Performance counter registers are not implemented other than
12829 * control register 0.
12830 */
12831 generate_exception(ctx, EXCP_RI);
12832 }
12833 gen_helper_rdhwr_performance(t0, cpu_env);
12834 gen_store_gpr(t0, rt);
12835 break;
12836 case 5:
12837 check_insn(ctx, ISA_MIPS32R6);
12838 gen_helper_rdhwr_xnp(t0, cpu_env);
12839 gen_store_gpr(t0, rt);
12840 break;
12841 case 29:
12842 #if defined(CONFIG_USER_ONLY)
12843 tcg_gen_ld_tl(t0, cpu_env,
12844 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12845 gen_store_gpr(t0, rt);
12846 break;
12847 #else
12848 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12849 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12850 tcg_gen_ld_tl(t0, cpu_env,
12851 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12852 gen_store_gpr(t0, rt);
12853 } else {
12854 generate_exception_end(ctx, EXCP_RI);
12855 }
12856 break;
12857 #endif
12858 default: /* Invalid */
12859 MIPS_INVAL("rdhwr");
12860 generate_exception_end(ctx, EXCP_RI);
12861 break;
12862 }
12863 tcg_temp_free(t0);
12864 }
12865
12866 static inline void clear_branch_hflags(DisasContext *ctx)
12867 {
12868 ctx->hflags &= ~MIPS_HFLAG_BMASK;
12869 if (ctx->base.is_jmp == DISAS_NEXT) {
12870 save_cpu_state(ctx, 0);
12871 } else {
12872 /*
12873 * It is not safe to save ctx->hflags as hflags may be changed
12874 * in execution time by the instruction in delay / forbidden slot.
12875 */
12876 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12877 }
12878 }
12879
12880 static void gen_branch(DisasContext *ctx, int insn_bytes)
12881 {
12882 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12883 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12884 /* Branches completion */
12885 clear_branch_hflags(ctx);
12886 ctx->base.is_jmp = DISAS_NORETURN;
12887 /* FIXME: Need to clear can_do_io. */
12888 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12889 case MIPS_HFLAG_FBNSLOT:
12890 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12891 break;
12892 case MIPS_HFLAG_B:
12893 /* unconditional branch */
12894 if (proc_hflags & MIPS_HFLAG_BX) {
12895 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12896 }
12897 gen_goto_tb(ctx, 0, ctx->btarget);
12898 break;
12899 case MIPS_HFLAG_BL:
12900 /* blikely taken case */
12901 gen_goto_tb(ctx, 0, ctx->btarget);
12902 break;
12903 case MIPS_HFLAG_BC:
12904 /* Conditional branch */
12905 {
12906 TCGLabel *l1 = gen_new_label();
12907
12908 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12909 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12910 gen_set_label(l1);
12911 gen_goto_tb(ctx, 0, ctx->btarget);
12912 }
12913 break;
12914 case MIPS_HFLAG_BR:
12915 /* unconditional branch to register */
12916 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12917 TCGv t0 = tcg_temp_new();
12918 TCGv_i32 t1 = tcg_temp_new_i32();
12919
12920 tcg_gen_andi_tl(t0, btarget, 0x1);
12921 tcg_gen_trunc_tl_i32(t1, t0);
12922 tcg_temp_free(t0);
12923 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12924 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12925 tcg_gen_or_i32(hflags, hflags, t1);
12926 tcg_temp_free_i32(t1);
12927
12928 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12929 } else {
12930 tcg_gen_mov_tl(cpu_PC, btarget);
12931 }
12932 if (ctx->base.singlestep_enabled) {
12933 save_cpu_state(ctx, 0);
12934 gen_helper_raise_exception_debug(cpu_env);
12935 }
12936 tcg_gen_lookup_and_goto_ptr();
12937 break;
12938 default:
12939 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12940 abort();
12941 }
12942 }
12943 }
12944
12945 /* Compact Branches */
12946 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12947 int rs, int rt, int32_t offset)
12948 {
12949 int bcond_compute = 0;
12950 TCGv t0 = tcg_temp_new();
12951 TCGv t1 = tcg_temp_new();
12952 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12953
12954 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12955 #ifdef MIPS_DEBUG_DISAS
12956 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12957 "\n", ctx->base.pc_next);
12958 #endif
12959 generate_exception_end(ctx, EXCP_RI);
12960 goto out;
12961 }
12962
12963 /* Load needed operands and calculate btarget */
12964 switch (opc) {
12965 /* compact branch */
12966 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12967 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12968 gen_load_gpr(t0, rs);
12969 gen_load_gpr(t1, rt);
12970 bcond_compute = 1;
12971 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12972 if (rs <= rt && rs == 0) {
12973 /* OPC_BEQZALC, OPC_BNEZALC */
12974 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12975 }
12976 break;
12977 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12978 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12979 gen_load_gpr(t0, rs);
12980 gen_load_gpr(t1, rt);
12981 bcond_compute = 1;
12982 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12983 break;
12984 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12985 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12986 if (rs == 0 || rs == rt) {
12987 /* OPC_BLEZALC, OPC_BGEZALC */
12988 /* OPC_BGTZALC, OPC_BLTZALC */
12989 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12990 }
12991 gen_load_gpr(t0, rs);
12992 gen_load_gpr(t1, rt);
12993 bcond_compute = 1;
12994 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12995 break;
12996 case OPC_BC:
12997 case OPC_BALC:
12998 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12999 break;
13000 case OPC_BEQZC:
13001 case OPC_BNEZC:
13002 if (rs != 0) {
13003 /* OPC_BEQZC, OPC_BNEZC */
13004 gen_load_gpr(t0, rs);
13005 bcond_compute = 1;
13006 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13007 } else {
13008 /* OPC_JIC, OPC_JIALC */
13009 TCGv tbase = tcg_temp_new();
13010 TCGv toffset = tcg_temp_new();
13011
13012 gen_load_gpr(tbase, rt);
13013 tcg_gen_movi_tl(toffset, offset);
13014 gen_op_addr_add(ctx, btarget, tbase, toffset);
13015 tcg_temp_free(tbase);
13016 tcg_temp_free(toffset);
13017 }
13018 break;
13019 default:
13020 MIPS_INVAL("Compact branch/jump");
13021 generate_exception_end(ctx, EXCP_RI);
13022 goto out;
13023 }
13024
13025 if (bcond_compute == 0) {
13026 /* Uncoditional compact branch */
13027 switch (opc) {
13028 case OPC_JIALC:
13029 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13030 /* Fallthrough */
13031 case OPC_JIC:
13032 ctx->hflags |= MIPS_HFLAG_BR;
13033 break;
13034 case OPC_BALC:
13035 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13036 /* Fallthrough */
13037 case OPC_BC:
13038 ctx->hflags |= MIPS_HFLAG_B;
13039 break;
13040 default:
13041 MIPS_INVAL("Compact branch/jump");
13042 generate_exception_end(ctx, EXCP_RI);
13043 goto out;
13044 }
13045
13046 /* Generating branch here as compact branches don't have delay slot */
13047 gen_branch(ctx, 4);
13048 } else {
13049 /* Conditional compact branch */
13050 TCGLabel *fs = gen_new_label();
13051 save_cpu_state(ctx, 0);
13052
13053 switch (opc) {
13054 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
13055 if (rs == 0 && rt != 0) {
13056 /* OPC_BLEZALC */
13057 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13058 } else if (rs != 0 && rt != 0 && rs == rt) {
13059 /* OPC_BGEZALC */
13060 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13061 } else {
13062 /* OPC_BGEUC */
13063 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
13064 }
13065 break;
13066 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
13067 if (rs == 0 && rt != 0) {
13068 /* OPC_BGTZALC */
13069 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13070 } else if (rs != 0 && rt != 0 && rs == rt) {
13071 /* OPC_BLTZALC */
13072 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13073 } else {
13074 /* OPC_BLTUC */
13075 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
13076 }
13077 break;
13078 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
13079 if (rs == 0 && rt != 0) {
13080 /* OPC_BLEZC */
13081 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13082 } else if (rs != 0 && rt != 0 && rs == rt) {
13083 /* OPC_BGEZC */
13084 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13085 } else {
13086 /* OPC_BGEC */
13087 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
13088 }
13089 break;
13090 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
13091 if (rs == 0 && rt != 0) {
13092 /* OPC_BGTZC */
13093 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13094 } else if (rs != 0 && rt != 0 && rs == rt) {
13095 /* OPC_BLTZC */
13096 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13097 } else {
13098 /* OPC_BLTC */
13099 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
13100 }
13101 break;
13102 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13103 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13104 if (rs >= rt) {
13105 /* OPC_BOVC, OPC_BNVC */
13106 TCGv t2 = tcg_temp_new();
13107 TCGv t3 = tcg_temp_new();
13108 TCGv t4 = tcg_temp_new();
13109 TCGv input_overflow = tcg_temp_new();
13110
13111 gen_load_gpr(t0, rs);
13112 gen_load_gpr(t1, rt);
13113 tcg_gen_ext32s_tl(t2, t0);
13114 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
13115 tcg_gen_ext32s_tl(t3, t1);
13116 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
13117 tcg_gen_or_tl(input_overflow, input_overflow, t4);
13118
13119 tcg_gen_add_tl(t4, t2, t3);
13120 tcg_gen_ext32s_tl(t4, t4);
13121 tcg_gen_xor_tl(t2, t2, t3);
13122 tcg_gen_xor_tl(t3, t4, t3);
13123 tcg_gen_andc_tl(t2, t3, t2);
13124 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
13125 tcg_gen_or_tl(t4, t4, input_overflow);
13126 if (opc == OPC_BOVC) {
13127 /* OPC_BOVC */
13128 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
13129 } else {
13130 /* OPC_BNVC */
13131 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
13132 }
13133 tcg_temp_free(input_overflow);
13134 tcg_temp_free(t4);
13135 tcg_temp_free(t3);
13136 tcg_temp_free(t2);
13137 } else if (rs < rt && rs == 0) {
13138 /* OPC_BEQZALC, OPC_BNEZALC */
13139 if (opc == OPC_BEQZALC) {
13140 /* OPC_BEQZALC */
13141 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13142 } else {
13143 /* OPC_BNEZALC */
13144 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13145 }
13146 } else {
13147 /* OPC_BEQC, OPC_BNEC */
13148 if (opc == OPC_BEQC) {
13149 /* OPC_BEQC */
13150 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13151 } else {
13152 /* OPC_BNEC */
13153 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13154 }
13155 }
13156 break;
13157 case OPC_BEQZC:
13158 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13159 break;
13160 case OPC_BNEZC:
13161 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13162 break;
13163 default:
13164 MIPS_INVAL("Compact conditional branch/jump");
13165 generate_exception_end(ctx, EXCP_RI);
13166 goto out;
13167 }
13168
13169 /* Generating branch here as compact branches don't have delay slot */
13170 gen_goto_tb(ctx, 1, ctx->btarget);
13171 gen_set_label(fs);
13172
13173 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13174 }
13175
13176 out:
13177 tcg_temp_free(t0);
13178 tcg_temp_free(t1);
13179 }
13180
13181 /* ISA extensions (ASEs) */
13182 /* MIPS16 extension to MIPS32 */
13183
13184 /* MIPS16 major opcodes */
13185 enum {
13186 M16_OPC_ADDIUSP = 0x00,
13187 M16_OPC_ADDIUPC = 0x01,
13188 M16_OPC_B = 0x02,
13189 M16_OPC_JAL = 0x03,
13190 M16_OPC_BEQZ = 0x04,
13191 M16_OPC_BNEQZ = 0x05,
13192 M16_OPC_SHIFT = 0x06,
13193 M16_OPC_LD = 0x07,
13194 M16_OPC_RRIA = 0x08,
13195 M16_OPC_ADDIU8 = 0x09,
13196 M16_OPC_SLTI = 0x0a,
13197 M16_OPC_SLTIU = 0x0b,
13198 M16_OPC_I8 = 0x0c,
13199 M16_OPC_LI = 0x0d,
13200 M16_OPC_CMPI = 0x0e,
13201 M16_OPC_SD = 0x0f,
13202 M16_OPC_LB = 0x10,
13203 M16_OPC_LH = 0x11,
13204 M16_OPC_LWSP = 0x12,
13205 M16_OPC_LW = 0x13,
13206 M16_OPC_LBU = 0x14,
13207 M16_OPC_LHU = 0x15,
13208 M16_OPC_LWPC = 0x16,
13209 M16_OPC_LWU = 0x17,
13210 M16_OPC_SB = 0x18,
13211 M16_OPC_SH = 0x19,
13212 M16_OPC_SWSP = 0x1a,
13213 M16_OPC_SW = 0x1b,
13214 M16_OPC_RRR = 0x1c,
13215 M16_OPC_RR = 0x1d,
13216 M16_OPC_EXTEND = 0x1e,
13217 M16_OPC_I64 = 0x1f
13218 };
13219
13220 /* I8 funct field */
13221 enum {
13222 I8_BTEQZ = 0x0,
13223 I8_BTNEZ = 0x1,
13224 I8_SWRASP = 0x2,
13225 I8_ADJSP = 0x3,
13226 I8_SVRS = 0x4,
13227 I8_MOV32R = 0x5,
13228 I8_MOVR32 = 0x7
13229 };
13230
13231 /* RRR f field */
13232 enum {
13233 RRR_DADDU = 0x0,
13234 RRR_ADDU = 0x1,
13235 RRR_DSUBU = 0x2,
13236 RRR_SUBU = 0x3
13237 };
13238
13239 /* RR funct field */
13240 enum {
13241 RR_JR = 0x00,
13242 RR_SDBBP = 0x01,
13243 RR_SLT = 0x02,
13244 RR_SLTU = 0x03,
13245 RR_SLLV = 0x04,
13246 RR_BREAK = 0x05,
13247 RR_SRLV = 0x06,
13248 RR_SRAV = 0x07,
13249 RR_DSRL = 0x08,
13250 RR_CMP = 0x0a,
13251 RR_NEG = 0x0b,
13252 RR_AND = 0x0c,
13253 RR_OR = 0x0d,
13254 RR_XOR = 0x0e,
13255 RR_NOT = 0x0f,
13256 RR_MFHI = 0x10,
13257 RR_CNVT = 0x11,
13258 RR_MFLO = 0x12,
13259 RR_DSRA = 0x13,
13260 RR_DSLLV = 0x14,
13261 RR_DSRLV = 0x16,
13262 RR_DSRAV = 0x17,
13263 RR_MULT = 0x18,
13264 RR_MULTU = 0x19,
13265 RR_DIV = 0x1a,
13266 RR_DIVU = 0x1b,
13267 RR_DMULT = 0x1c,
13268 RR_DMULTU = 0x1d,
13269 RR_DDIV = 0x1e,
13270 RR_DDIVU = 0x1f
13271 };
13272
13273 /* I64 funct field */
13274 enum {
13275 I64_LDSP = 0x0,
13276 I64_SDSP = 0x1,
13277 I64_SDRASP = 0x2,
13278 I64_DADJSP = 0x3,
13279 I64_LDPC = 0x4,
13280 I64_DADDIU5 = 0x5,
13281 I64_DADDIUPC = 0x6,
13282 I64_DADDIUSP = 0x7
13283 };
13284
13285 /* RR ry field for CNVT */
13286 enum {
13287 RR_RY_CNVT_ZEB = 0x0,
13288 RR_RY_CNVT_ZEH = 0x1,
13289 RR_RY_CNVT_ZEW = 0x2,
13290 RR_RY_CNVT_SEB = 0x4,
13291 RR_RY_CNVT_SEH = 0x5,
13292 RR_RY_CNVT_SEW = 0x6,
13293 };
13294
13295 static int xlat(int r)
13296 {
13297 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13298
13299 return map[r];
13300 }
13301
13302 static void gen_mips16_save(DisasContext *ctx,
13303 int xsregs, int aregs,
13304 int do_ra, int do_s0, int do_s1,
13305 int framesize)
13306 {
13307 TCGv t0 = tcg_temp_new();
13308 TCGv t1 = tcg_temp_new();
13309 TCGv t2 = tcg_temp_new();
13310 int args, astatic;
13311
13312 switch (aregs) {
13313 case 0:
13314 case 1:
13315 case 2:
13316 case 3:
13317 case 11:
13318 args = 0;
13319 break;
13320 case 4:
13321 case 5:
13322 case 6:
13323 case 7:
13324 args = 1;
13325 break;
13326 case 8:
13327 case 9:
13328 case 10:
13329 args = 2;
13330 break;
13331 case 12:
13332 case 13:
13333 args = 3;
13334 break;
13335 case 14:
13336 args = 4;
13337 break;
13338 default:
13339 generate_exception_end(ctx, EXCP_RI);
13340 return;
13341 }
13342
13343 switch (args) {
13344 case 4:
13345 gen_base_offset_addr(ctx, t0, 29, 12);
13346 gen_load_gpr(t1, 7);
13347 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13348 /* Fall through */
13349 case 3:
13350 gen_base_offset_addr(ctx, t0, 29, 8);
13351 gen_load_gpr(t1, 6);
13352 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13353 /* Fall through */
13354 case 2:
13355 gen_base_offset_addr(ctx, t0, 29, 4);
13356 gen_load_gpr(t1, 5);
13357 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13358 /* Fall through */
13359 case 1:
13360 gen_base_offset_addr(ctx, t0, 29, 0);
13361 gen_load_gpr(t1, 4);
13362 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13363 }
13364
13365 gen_load_gpr(t0, 29);
13366
13367 #define DECR_AND_STORE(reg) do { \
13368 tcg_gen_movi_tl(t2, -4); \
13369 gen_op_addr_add(ctx, t0, t0, t2); \
13370 gen_load_gpr(t1, reg); \
13371 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13372 } while (0)
13373
13374 if (do_ra) {
13375 DECR_AND_STORE(31);
13376 }
13377
13378 switch (xsregs) {
13379 case 7:
13380 DECR_AND_STORE(30);
13381 /* Fall through */
13382 case 6:
13383 DECR_AND_STORE(23);
13384 /* Fall through */
13385 case 5:
13386 DECR_AND_STORE(22);
13387 /* Fall through */
13388 case 4:
13389 DECR_AND_STORE(21);
13390 /* Fall through */
13391 case 3:
13392 DECR_AND_STORE(20);
13393 /* Fall through */
13394 case 2:
13395 DECR_AND_STORE(19);
13396 /* Fall through */
13397 case 1:
13398 DECR_AND_STORE(18);
13399 }
13400
13401 if (do_s1) {
13402 DECR_AND_STORE(17);
13403 }
13404 if (do_s0) {
13405 DECR_AND_STORE(16);
13406 }
13407
13408 switch (aregs) {
13409 case 0:
13410 case 4:
13411 case 8:
13412 case 12:
13413 case 14:
13414 astatic = 0;
13415 break;
13416 case 1:
13417 case 5:
13418 case 9:
13419 case 13:
13420 astatic = 1;
13421 break;
13422 case 2:
13423 case 6:
13424 case 10:
13425 astatic = 2;
13426 break;
13427 case 3:
13428 case 7:
13429 astatic = 3;
13430 break;
13431 case 11:
13432 astatic = 4;
13433 break;
13434 default:
13435 generate_exception_end(ctx, EXCP_RI);
13436 return;
13437 }
13438
13439 if (astatic > 0) {
13440 DECR_AND_STORE(7);
13441 if (astatic > 1) {
13442 DECR_AND_STORE(6);
13443 if (astatic > 2) {
13444 DECR_AND_STORE(5);
13445 if (astatic > 3) {
13446 DECR_AND_STORE(4);
13447 }
13448 }
13449 }
13450 }
13451 #undef DECR_AND_STORE
13452
13453 tcg_gen_movi_tl(t2, -framesize);
13454 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13455 tcg_temp_free(t0);
13456 tcg_temp_free(t1);
13457 tcg_temp_free(t2);
13458 }
13459
13460 static void gen_mips16_restore(DisasContext *ctx,
13461 int xsregs, int aregs,
13462 int do_ra, int do_s0, int do_s1,
13463 int framesize)
13464 {
13465 int astatic;
13466 TCGv t0 = tcg_temp_new();
13467 TCGv t1 = tcg_temp_new();
13468 TCGv t2 = tcg_temp_new();
13469
13470 tcg_gen_movi_tl(t2, framesize);
13471 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13472
13473 #define DECR_AND_LOAD(reg) do { \
13474 tcg_gen_movi_tl(t2, -4); \
13475 gen_op_addr_add(ctx, t0, t0, t2); \
13476 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13477 gen_store_gpr(t1, reg); \
13478 } while (0)
13479
13480 if (do_ra) {
13481 DECR_AND_LOAD(31);
13482 }
13483
13484 switch (xsregs) {
13485 case 7:
13486 DECR_AND_LOAD(30);
13487 /* Fall through */
13488 case 6:
13489 DECR_AND_LOAD(23);
13490 /* Fall through */
13491 case 5:
13492 DECR_AND_LOAD(22);
13493 /* Fall through */
13494 case 4:
13495 DECR_AND_LOAD(21);
13496 /* Fall through */
13497 case 3:
13498 DECR_AND_LOAD(20);
13499 /* Fall through */
13500 case 2:
13501 DECR_AND_LOAD(19);
13502 /* Fall through */
13503 case 1:
13504 DECR_AND_LOAD(18);
13505 }
13506
13507 if (do_s1) {
13508 DECR_AND_LOAD(17);
13509 }
13510 if (do_s0) {
13511 DECR_AND_LOAD(16);
13512 }
13513
13514 switch (aregs) {
13515 case 0:
13516 case 4:
13517 case 8:
13518 case 12:
13519 case 14:
13520 astatic = 0;
13521 break;
13522 case 1:
13523 case 5:
13524 case 9:
13525 case 13:
13526 astatic = 1;
13527 break;
13528 case 2:
13529 case 6:
13530 case 10:
13531 astatic = 2;
13532 break;
13533 case 3:
13534 case 7:
13535 astatic = 3;
13536 break;
13537 case 11:
13538 astatic = 4;
13539 break;
13540 default:
13541 generate_exception_end(ctx, EXCP_RI);
13542 return;
13543 }
13544
13545 if (astatic > 0) {
13546 DECR_AND_LOAD(7);
13547 if (astatic > 1) {
13548 DECR_AND_LOAD(6);
13549 if (astatic > 2) {
13550 DECR_AND_LOAD(5);
13551 if (astatic > 3) {
13552 DECR_AND_LOAD(4);
13553 }
13554 }
13555 }
13556 }
13557 #undef DECR_AND_LOAD
13558
13559 tcg_gen_movi_tl(t2, framesize);
13560 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13561 tcg_temp_free(t0);
13562 tcg_temp_free(t1);
13563 tcg_temp_free(t2);
13564 }
13565
13566 static void gen_addiupc(DisasContext *ctx, int rx, int imm,
13567 int is_64_bit, int extended)
13568 {
13569 TCGv t0;
13570
13571 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13572 generate_exception_end(ctx, EXCP_RI);
13573 return;
13574 }
13575
13576 t0 = tcg_temp_new();
13577
13578 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13579 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13580 if (!is_64_bit) {
13581 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13582 }
13583
13584 tcg_temp_free(t0);
13585 }
13586
13587 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13588 int16_t offset)
13589 {
13590 TCGv_i32 t0 = tcg_const_i32(op);
13591 TCGv t1 = tcg_temp_new();
13592 gen_base_offset_addr(ctx, t1, base, offset);
13593 gen_helper_cache(cpu_env, t1, t0);
13594 }
13595
13596 #if defined(TARGET_MIPS64)
13597 static void decode_i64_mips16(DisasContext *ctx,
13598 int ry, int funct, int16_t offset,
13599 int extended)
13600 {
13601 switch (funct) {
13602 case I64_LDSP:
13603 check_insn(ctx, ISA_MIPS3);
13604 check_mips_64(ctx);
13605 offset = extended ? offset : offset << 3;
13606 gen_ld(ctx, OPC_LD, ry, 29, offset);
13607 break;
13608 case I64_SDSP:
13609 check_insn(ctx, ISA_MIPS3);
13610 check_mips_64(ctx);
13611 offset = extended ? offset : offset << 3;
13612 gen_st(ctx, OPC_SD, ry, 29, offset);
13613 break;
13614 case I64_SDRASP:
13615 check_insn(ctx, ISA_MIPS3);
13616 check_mips_64(ctx);
13617 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13618 gen_st(ctx, OPC_SD, 31, 29, offset);
13619 break;
13620 case I64_DADJSP:
13621 check_insn(ctx, ISA_MIPS3);
13622 check_mips_64(ctx);
13623 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13624 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13625 break;
13626 case I64_LDPC:
13627 check_insn(ctx, ISA_MIPS3);
13628 check_mips_64(ctx);
13629 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13630 generate_exception_end(ctx, EXCP_RI);
13631 } else {
13632 offset = extended ? offset : offset << 3;
13633 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13634 }
13635 break;
13636 case I64_DADDIU5:
13637 check_insn(ctx, ISA_MIPS3);
13638 check_mips_64(ctx);
13639 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13640 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13641 break;
13642 case I64_DADDIUPC:
13643 check_insn(ctx, ISA_MIPS3);
13644 check_mips_64(ctx);
13645 offset = extended ? offset : offset << 2;
13646 gen_addiupc(ctx, ry, offset, 1, extended);
13647 break;
13648 case I64_DADDIUSP:
13649 check_insn(ctx, ISA_MIPS3);
13650 check_mips_64(ctx);
13651 offset = extended ? offset : offset << 2;
13652 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13653 break;
13654 }
13655 }
13656 #endif
13657
13658 static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
13659 {
13660 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13661 int op, rx, ry, funct, sa;
13662 int16_t imm, offset;
13663
13664 ctx->opcode = (ctx->opcode << 16) | extend;
13665 op = (ctx->opcode >> 11) & 0x1f;
13666 sa = (ctx->opcode >> 22) & 0x1f;
13667 funct = (ctx->opcode >> 8) & 0x7;
13668 rx = xlat((ctx->opcode >> 8) & 0x7);
13669 ry = xlat((ctx->opcode >> 5) & 0x7);
13670 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13671 | ((ctx->opcode >> 21) & 0x3f) << 5
13672 | (ctx->opcode & 0x1f));
13673
13674 /*
13675 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13676 * counterparts.
13677 */
13678 switch (op) {
13679 case M16_OPC_ADDIUSP:
13680 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13681 break;
13682 case M16_OPC_ADDIUPC:
13683 gen_addiupc(ctx, rx, imm, 0, 1);
13684 break;
13685 case M16_OPC_B:
13686 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13687 /* No delay slot, so just process as a normal instruction */
13688 break;
13689 case M16_OPC_BEQZ:
13690 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13691 /* No delay slot, so just process as a normal instruction */
13692 break;
13693 case M16_OPC_BNEQZ:
13694 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13695 /* No delay slot, so just process as a normal instruction */
13696 break;
13697 case M16_OPC_SHIFT:
13698 switch (ctx->opcode & 0x3) {
13699 case 0x0:
13700 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13701 break;
13702 case 0x1:
13703 #if defined(TARGET_MIPS64)
13704 check_mips_64(ctx);
13705 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13706 #else
13707 generate_exception_end(ctx, EXCP_RI);
13708 #endif
13709 break;
13710 case 0x2:
13711 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13712 break;
13713 case 0x3:
13714 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13715 break;
13716 }
13717 break;
13718 #if defined(TARGET_MIPS64)
13719 case M16_OPC_LD:
13720 check_insn(ctx, ISA_MIPS3);
13721 check_mips_64(ctx);
13722 gen_ld(ctx, OPC_LD, ry, rx, offset);
13723 break;
13724 #endif
13725 case M16_OPC_RRIA:
13726 imm = ctx->opcode & 0xf;
13727 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13728 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13729 imm = (int16_t) (imm << 1) >> 1;
13730 if ((ctx->opcode >> 4) & 0x1) {
13731 #if defined(TARGET_MIPS64)
13732 check_mips_64(ctx);
13733 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13734 #else
13735 generate_exception_end(ctx, EXCP_RI);
13736 #endif
13737 } else {
13738 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13739 }
13740 break;
13741 case M16_OPC_ADDIU8:
13742 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13743 break;
13744 case M16_OPC_SLTI:
13745 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13746 break;
13747 case M16_OPC_SLTIU:
13748 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13749 break;
13750 case M16_OPC_I8:
13751 switch (funct) {
13752 case I8_BTEQZ:
13753 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13754 break;
13755 case I8_BTNEZ:
13756 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13757 break;
13758 case I8_SWRASP:
13759 gen_st(ctx, OPC_SW, 31, 29, imm);
13760 break;
13761 case I8_ADJSP:
13762 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13763 break;
13764 case I8_SVRS:
13765 check_insn(ctx, ISA_MIPS32);
13766 {
13767 int xsregs = (ctx->opcode >> 24) & 0x7;
13768 int aregs = (ctx->opcode >> 16) & 0xf;
13769 int do_ra = (ctx->opcode >> 6) & 0x1;
13770 int do_s0 = (ctx->opcode >> 5) & 0x1;
13771 int do_s1 = (ctx->opcode >> 4) & 0x1;
13772 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13773 | (ctx->opcode & 0xf)) << 3;
13774
13775 if (ctx->opcode & (1 << 7)) {
13776 gen_mips16_save(ctx, xsregs, aregs,
13777 do_ra, do_s0, do_s1,
13778 framesize);
13779 } else {
13780 gen_mips16_restore(ctx, xsregs, aregs,
13781 do_ra, do_s0, do_s1,
13782 framesize);
13783 }
13784 }
13785 break;
13786 default:
13787 generate_exception_end(ctx, EXCP_RI);
13788 break;
13789 }
13790 break;
13791 case M16_OPC_LI:
13792 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13793 break;
13794 case M16_OPC_CMPI:
13795 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13796 break;
13797 #if defined(TARGET_MIPS64)
13798 case M16_OPC_SD:
13799 check_insn(ctx, ISA_MIPS3);
13800 check_mips_64(ctx);
13801 gen_st(ctx, OPC_SD, ry, rx, offset);
13802 break;
13803 #endif
13804 case M16_OPC_LB:
13805 gen_ld(ctx, OPC_LB, ry, rx, offset);
13806 break;
13807 case M16_OPC_LH:
13808 gen_ld(ctx, OPC_LH, ry, rx, offset);
13809 break;
13810 case M16_OPC_LWSP:
13811 gen_ld(ctx, OPC_LW, rx, 29, offset);
13812 break;
13813 case M16_OPC_LW:
13814 gen_ld(ctx, OPC_LW, ry, rx, offset);
13815 break;
13816 case M16_OPC_LBU:
13817 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13818 break;
13819 case M16_OPC_LHU:
13820 gen_ld(ctx, OPC_LHU, ry, rx, offset);
13821 break;
13822 case M16_OPC_LWPC:
13823 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13824 break;
13825 #if defined(TARGET_MIPS64)
13826 case M16_OPC_LWU:
13827 check_insn(ctx, ISA_MIPS3);
13828 check_mips_64(ctx);
13829 gen_ld(ctx, OPC_LWU, ry, rx, offset);
13830 break;
13831 #endif
13832 case M16_OPC_SB:
13833 gen_st(ctx, OPC_SB, ry, rx, offset);
13834 break;
13835 case M16_OPC_SH:
13836 gen_st(ctx, OPC_SH, ry, rx, offset);
13837 break;
13838 case M16_OPC_SWSP:
13839 gen_st(ctx, OPC_SW, rx, 29, offset);
13840 break;
13841 case M16_OPC_SW:
13842 gen_st(ctx, OPC_SW, ry, rx, offset);
13843 break;
13844 #if defined(TARGET_MIPS64)
13845 case M16_OPC_I64:
13846 decode_i64_mips16(ctx, ry, funct, offset, 1);
13847 break;
13848 #endif
13849 default:
13850 generate_exception_end(ctx, EXCP_RI);
13851 break;
13852 }
13853
13854 return 4;
13855 }
13856
13857 static inline bool is_uhi(int sdbbp_code)
13858 {
13859 #ifdef CONFIG_USER_ONLY
13860 return false;
13861 #else
13862 return semihosting_enabled() && sdbbp_code == 1;
13863 #endif
13864 }
13865
13866 #ifdef CONFIG_USER_ONLY
13867 /* The above should dead-code away any calls to this..*/
13868 static inline void gen_helper_do_semihosting(void *env)
13869 {
13870 g_assert_not_reached();
13871 }
13872 #endif
13873
13874 static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
13875 {
13876 int rx, ry;
13877 int sa;
13878 int op, cnvt_op, op1, offset;
13879 int funct;
13880 int n_bytes;
13881
13882 op = (ctx->opcode >> 11) & 0x1f;
13883 sa = (ctx->opcode >> 2) & 0x7;
13884 sa = sa == 0 ? 8 : sa;
13885 rx = xlat((ctx->opcode >> 8) & 0x7);
13886 cnvt_op = (ctx->opcode >> 5) & 0x7;
13887 ry = xlat((ctx->opcode >> 5) & 0x7);
13888 op1 = offset = ctx->opcode & 0x1f;
13889
13890 n_bytes = 2;
13891
13892 switch (op) {
13893 case M16_OPC_ADDIUSP:
13894 {
13895 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13896
13897 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13898 }
13899 break;
13900 case M16_OPC_ADDIUPC:
13901 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13902 break;
13903 case M16_OPC_B:
13904 offset = (ctx->opcode & 0x7ff) << 1;
13905 offset = (int16_t)(offset << 4) >> 4;
13906 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13907 /* No delay slot, so just process as a normal instruction */
13908 break;
13909 case M16_OPC_JAL:
13910 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13911 offset = (((ctx->opcode & 0x1f) << 21)
13912 | ((ctx->opcode >> 5) & 0x1f) << 16
13913 | offset) << 2;
13914 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13915 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13916 n_bytes = 4;
13917 break;
13918 case M16_OPC_BEQZ:
13919 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13920 ((int8_t)ctx->opcode) << 1, 0);
13921 /* No delay slot, so just process as a normal instruction */
13922 break;
13923 case M16_OPC_BNEQZ:
13924 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13925 ((int8_t)ctx->opcode) << 1, 0);
13926 /* No delay slot, so just process as a normal instruction */
13927 break;
13928 case M16_OPC_SHIFT:
13929 switch (ctx->opcode & 0x3) {
13930 case 0x0:
13931 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13932 break;
13933 case 0x1:
13934 #if defined(TARGET_MIPS64)
13935 check_insn(ctx, ISA_MIPS3);
13936 check_mips_64(ctx);
13937 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13938 #else
13939 generate_exception_end(ctx, EXCP_RI);
13940 #endif
13941 break;
13942 case 0x2:
13943 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13944 break;
13945 case 0x3:
13946 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13947 break;
13948 }
13949 break;
13950 #if defined(TARGET_MIPS64)
13951 case M16_OPC_LD:
13952 check_insn(ctx, ISA_MIPS3);
13953 check_mips_64(ctx);
13954 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13955 break;
13956 #endif
13957 case M16_OPC_RRIA:
13958 {
13959 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13960
13961 if ((ctx->opcode >> 4) & 1) {
13962 #if defined(TARGET_MIPS64)
13963 check_insn(ctx, ISA_MIPS3);
13964 check_mips_64(ctx);
13965 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13966 #else
13967 generate_exception_end(ctx, EXCP_RI);
13968 #endif
13969 } else {
13970 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13971 }
13972 }
13973 break;
13974 case M16_OPC_ADDIU8:
13975 {
13976 int16_t imm = (int8_t) ctx->opcode;
13977
13978 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13979 }
13980 break;
13981 case M16_OPC_SLTI:
13982 {
13983 int16_t imm = (uint8_t) ctx->opcode;
13984 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13985 }
13986 break;
13987 case M16_OPC_SLTIU:
13988 {
13989 int16_t imm = (uint8_t) ctx->opcode;
13990 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13991 }
13992 break;
13993 case M16_OPC_I8:
13994 {
13995 int reg32;
13996
13997 funct = (ctx->opcode >> 8) & 0x7;
13998 switch (funct) {
13999 case I8_BTEQZ:
14000 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
14001 ((int8_t)ctx->opcode) << 1, 0);
14002 break;
14003 case I8_BTNEZ:
14004 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
14005 ((int8_t)ctx->opcode) << 1, 0);
14006 break;
14007 case I8_SWRASP:
14008 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
14009 break;
14010 case I8_ADJSP:
14011 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
14012 ((int8_t)ctx->opcode) << 3);
14013 break;
14014 case I8_SVRS:
14015 check_insn(ctx, ISA_MIPS32);
14016 {
14017 int do_ra = ctx->opcode & (1 << 6);
14018 int do_s0 = ctx->opcode & (1 << 5);
14019 int do_s1 = ctx->opcode & (1 << 4);
14020 int framesize = ctx->opcode & 0xf;
14021
14022 if (framesize == 0) {
14023 framesize = 128;
14024 } else {
14025 framesize = framesize << 3;
14026 }
14027
14028 if (ctx->opcode & (1 << 7)) {
14029 gen_mips16_save(ctx, 0, 0,
14030 do_ra, do_s0, do_s1, framesize);
14031 } else {
14032 gen_mips16_restore(ctx, 0, 0,
14033 do_ra, do_s0, do_s1, framesize);
14034 }
14035 }
14036 break;
14037 case I8_MOV32R:
14038 {
14039 int rz = xlat(ctx->opcode & 0x7);
14040
14041 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
14042 ((ctx->opcode >> 5) & 0x7);
14043 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
14044 }
14045 break;
14046 case I8_MOVR32:
14047 reg32 = ctx->opcode & 0x1f;
14048 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
14049 break;
14050 default:
14051 generate_exception_end(ctx, EXCP_RI);
14052 break;
14053 }
14054 }
14055 break;
14056 case M16_OPC_LI:
14057 {
14058 int16_t imm = (uint8_t) ctx->opcode;
14059
14060 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
14061 }
14062 break;
14063 case M16_OPC_CMPI:
14064 {
14065 int16_t imm = (uint8_t) ctx->opcode;
14066 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
14067 }
14068 break;
14069 #if defined(TARGET_MIPS64)
14070 case M16_OPC_SD:
14071 check_insn(ctx, ISA_MIPS3);
14072 check_mips_64(ctx);
14073 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
14074 break;
14075 #endif
14076 case M16_OPC_LB:
14077 gen_ld(ctx, OPC_LB, ry, rx, offset);
14078 break;
14079 case M16_OPC_LH:
14080 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
14081 break;
14082 case M16_OPC_LWSP:
14083 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14084 break;
14085 case M16_OPC_LW:
14086 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
14087 break;
14088 case M16_OPC_LBU:
14089 gen_ld(ctx, OPC_LBU, ry, rx, offset);
14090 break;
14091 case M16_OPC_LHU:
14092 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
14093 break;
14094 case M16_OPC_LWPC:
14095 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
14096 break;
14097 #if defined(TARGET_MIPS64)
14098 case M16_OPC_LWU:
14099 check_insn(ctx, ISA_MIPS3);
14100 check_mips_64(ctx);
14101 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
14102 break;
14103 #endif
14104 case M16_OPC_SB:
14105 gen_st(ctx, OPC_SB, ry, rx, offset);
14106 break;
14107 case M16_OPC_SH:
14108 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
14109 break;
14110 case M16_OPC_SWSP:
14111 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14112 break;
14113 case M16_OPC_SW:
14114 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
14115 break;
14116 case M16_OPC_RRR:
14117 {
14118 int rz = xlat((ctx->opcode >> 2) & 0x7);
14119 int mips32_op;
14120
14121 switch (ctx->opcode & 0x3) {
14122 case RRR_ADDU:
14123 mips32_op = OPC_ADDU;
14124 break;
14125 case RRR_SUBU:
14126 mips32_op = OPC_SUBU;
14127 break;
14128 #if defined(TARGET_MIPS64)
14129 case RRR_DADDU:
14130 mips32_op = OPC_DADDU;
14131 check_insn(ctx, ISA_MIPS3);
14132 check_mips_64(ctx);
14133 break;
14134 case RRR_DSUBU:
14135 mips32_op = OPC_DSUBU;
14136 check_insn(ctx, ISA_MIPS3);
14137 check_mips_64(ctx);
14138 break;
14139 #endif
14140 default:
14141 generate_exception_end(ctx, EXCP_RI);
14142 goto done;
14143 }
14144
14145 gen_arith(ctx, mips32_op, rz, rx, ry);
14146 done:
14147 ;
14148 }
14149 break;
14150 case M16_OPC_RR:
14151 switch (op1) {
14152 case RR_JR:
14153 {
14154 int nd = (ctx->opcode >> 7) & 0x1;
14155 int link = (ctx->opcode >> 6) & 0x1;
14156 int ra = (ctx->opcode >> 5) & 0x1;
14157
14158 if (nd) {
14159 check_insn(ctx, ISA_MIPS32);
14160 }
14161
14162 if (link) {
14163 op = OPC_JALR;
14164 } else {
14165 op = OPC_JR;
14166 }
14167
14168 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14169 (nd ? 0 : 2));
14170 }
14171 break;
14172 case RR_SDBBP:
14173 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14174 gen_helper_do_semihosting(cpu_env);
14175 } else {
14176 /*
14177 * XXX: not clear which exception should be raised
14178 * when in debug mode...
14179 */
14180 check_insn(ctx, ISA_MIPS32);
14181 generate_exception_end(ctx, EXCP_DBp);
14182 }
14183 break;
14184 case RR_SLT:
14185 gen_slt(ctx, OPC_SLT, 24, rx, ry);
14186 break;
14187 case RR_SLTU:
14188 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14189 break;
14190 case RR_BREAK:
14191 generate_exception_end(ctx, EXCP_BREAK);
14192 break;
14193 case RR_SLLV:
14194 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14195 break;
14196 case RR_SRLV:
14197 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14198 break;
14199 case RR_SRAV:
14200 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14201 break;
14202 #if defined(TARGET_MIPS64)
14203 case RR_DSRL:
14204 check_insn(ctx, ISA_MIPS3);
14205 check_mips_64(ctx);
14206 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14207 break;
14208 #endif
14209 case RR_CMP:
14210 gen_logic(ctx, OPC_XOR, 24, rx, ry);
14211 break;
14212 case RR_NEG:
14213 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14214 break;
14215 case RR_AND:
14216 gen_logic(ctx, OPC_AND, rx, rx, ry);
14217 break;
14218 case RR_OR:
14219 gen_logic(ctx, OPC_OR, rx, rx, ry);
14220 break;
14221 case RR_XOR:
14222 gen_logic(ctx, OPC_XOR, rx, rx, ry);
14223 break;
14224 case RR_NOT:
14225 gen_logic(ctx, OPC_NOR, rx, ry, 0);
14226 break;
14227 case RR_MFHI:
14228 gen_HILO(ctx, OPC_MFHI, 0, rx);
14229 break;
14230 case RR_CNVT:
14231 check_insn(ctx, ISA_MIPS32);
14232 switch (cnvt_op) {
14233 case RR_RY_CNVT_ZEB:
14234 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14235 break;
14236 case RR_RY_CNVT_ZEH:
14237 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14238 break;
14239 case RR_RY_CNVT_SEB:
14240 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14241 break;
14242 case RR_RY_CNVT_SEH:
14243 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14244 break;
14245 #if defined (TARGET_MIPS64)
14246 case RR_RY_CNVT_ZEW:
14247 check_insn(ctx, ISA_MIPS64);
14248 check_mips_64(ctx);
14249 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14250 break;
14251 case RR_RY_CNVT_SEW:
14252 check_insn(ctx, ISA_MIPS64);
14253 check_mips_64(ctx);
14254 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14255 break;
14256 #endif
14257 default:
14258 generate_exception_end(ctx, EXCP_RI);
14259 break;
14260 }
14261 break;
14262 case RR_MFLO:
14263 gen_HILO(ctx, OPC_MFLO, 0, rx);
14264 break;
14265 #if defined(TARGET_MIPS64)
14266 case RR_DSRA:
14267 check_insn(ctx, ISA_MIPS3);
14268 check_mips_64(ctx);
14269 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14270 break;
14271 case RR_DSLLV:
14272 check_insn(ctx, ISA_MIPS3);
14273 check_mips_64(ctx);
14274 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14275 break;
14276 case RR_DSRLV:
14277 check_insn(ctx, ISA_MIPS3);
14278 check_mips_64(ctx);
14279 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14280 break;
14281 case RR_DSRAV:
14282 check_insn(ctx, ISA_MIPS3);
14283 check_mips_64(ctx);
14284 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14285 break;
14286 #endif
14287 case RR_MULT:
14288 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14289 break;
14290 case RR_MULTU:
14291 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14292 break;
14293 case RR_DIV:
14294 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14295 break;
14296 case RR_DIVU:
14297 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14298 break;
14299 #if defined(TARGET_MIPS64)
14300 case RR_DMULT:
14301 check_insn(ctx, ISA_MIPS3);
14302 check_mips_64(ctx);
14303 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14304 break;
14305 case RR_DMULTU:
14306 check_insn(ctx, ISA_MIPS3);
14307 check_mips_64(ctx);
14308 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14309 break;
14310 case RR_DDIV:
14311 check_insn(ctx, ISA_MIPS3);
14312 check_mips_64(ctx);
14313 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14314 break;
14315 case RR_DDIVU:
14316 check_insn(ctx, ISA_MIPS3);
14317 check_mips_64(ctx);
14318 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14319 break;
14320 #endif
14321 default:
14322 generate_exception_end(ctx, EXCP_RI);
14323 break;
14324 }
14325 break;
14326 case M16_OPC_EXTEND:
14327 decode_extended_mips16_opc(env, ctx);
14328 n_bytes = 4;
14329 break;
14330 #if defined(TARGET_MIPS64)
14331 case M16_OPC_I64:
14332 funct = (ctx->opcode >> 8) & 0x7;
14333 decode_i64_mips16(ctx, ry, funct, offset, 0);
14334 break;
14335 #endif
14336 default:
14337 generate_exception_end(ctx, EXCP_RI);
14338 break;
14339 }
14340
14341 return n_bytes;
14342 }
14343
14344 /* microMIPS extension to MIPS32/MIPS64 */
14345
14346 /*
14347 * microMIPS32/microMIPS64 major opcodes
14348 *
14349 * 1. MIPS Architecture for Programmers Volume II-B:
14350 * The microMIPS32 Instruction Set (Revision 3.05)
14351 *
14352 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14353 *
14354 * 2. MIPS Architecture For Programmers Volume II-A:
14355 * The MIPS64 Instruction Set (Revision 3.51)
14356 */
14357
14358 enum {
14359 POOL32A = 0x00,
14360 POOL16A = 0x01,
14361 LBU16 = 0x02,
14362 MOVE16 = 0x03,
14363 ADDI32 = 0x04,
14364 R6_LUI = 0x04,
14365 AUI = 0x04,
14366 LBU32 = 0x05,
14367 SB32 = 0x06,
14368 LB32 = 0x07,
14369
14370 POOL32B = 0x08,
14371 POOL16B = 0x09,
14372 LHU16 = 0x0a,
14373 ANDI16 = 0x0b,
14374 ADDIU32 = 0x0c,
14375 LHU32 = 0x0d,
14376 SH32 = 0x0e,
14377 LH32 = 0x0f,
14378
14379 POOL32I = 0x10,
14380 POOL16C = 0x11,
14381 LWSP16 = 0x12,
14382 POOL16D = 0x13,
14383 ORI32 = 0x14,
14384 POOL32F = 0x15,
14385 POOL32S = 0x16, /* MIPS64 */
14386 DADDIU32 = 0x17, /* MIPS64 */
14387
14388 POOL32C = 0x18,
14389 LWGP16 = 0x19,
14390 LW16 = 0x1a,
14391 POOL16E = 0x1b,
14392 XORI32 = 0x1c,
14393 JALS32 = 0x1d,
14394 BOVC = 0x1d,
14395 BEQC = 0x1d,
14396 BEQZALC = 0x1d,
14397 ADDIUPC = 0x1e,
14398 PCREL = 0x1e,
14399 BNVC = 0x1f,
14400 BNEC = 0x1f,
14401 BNEZALC = 0x1f,
14402
14403 R6_BEQZC = 0x20,
14404 JIC = 0x20,
14405 POOL16F = 0x21,
14406 SB16 = 0x22,
14407 BEQZ16 = 0x23,
14408 BEQZC16 = 0x23,
14409 SLTI32 = 0x24,
14410 BEQ32 = 0x25,
14411 BC = 0x25,
14412 SWC132 = 0x26,
14413 LWC132 = 0x27,
14414
14415 /* 0x29 is reserved */
14416 RES_29 = 0x29,
14417 R6_BNEZC = 0x28,
14418 JIALC = 0x28,
14419 SH16 = 0x2a,
14420 BNEZ16 = 0x2b,
14421 BNEZC16 = 0x2b,
14422 SLTIU32 = 0x2c,
14423 BNE32 = 0x2d,
14424 BALC = 0x2d,
14425 SDC132 = 0x2e,
14426 LDC132 = 0x2f,
14427
14428 /* 0x31 is reserved */
14429 RES_31 = 0x31,
14430 BLEZALC = 0x30,
14431 BGEZALC = 0x30,
14432 BGEUC = 0x30,
14433 SWSP16 = 0x32,
14434 B16 = 0x33,
14435 BC16 = 0x33,
14436 ANDI32 = 0x34,
14437 J32 = 0x35,
14438 BGTZC = 0x35,
14439 BLTZC = 0x35,
14440 BLTC = 0x35,
14441 SD32 = 0x36, /* MIPS64 */
14442 LD32 = 0x37, /* MIPS64 */
14443
14444 /* 0x39 is reserved */
14445 RES_39 = 0x39,
14446 BGTZALC = 0x38,
14447 BLTZALC = 0x38,
14448 BLTUC = 0x38,
14449 SW16 = 0x3a,
14450 LI16 = 0x3b,
14451 JALX32 = 0x3c,
14452 JAL32 = 0x3d,
14453 BLEZC = 0x3d,
14454 BGEZC = 0x3d,
14455 BGEC = 0x3d,
14456 SW32 = 0x3e,
14457 LW32 = 0x3f
14458 };
14459
14460 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14461 enum {
14462 ADDIUPC_00 = 0x00,
14463 ADDIUPC_01 = 0x01,
14464 ADDIUPC_02 = 0x02,
14465 ADDIUPC_03 = 0x03,
14466 ADDIUPC_04 = 0x04,
14467 ADDIUPC_05 = 0x05,
14468 ADDIUPC_06 = 0x06,
14469 ADDIUPC_07 = 0x07,
14470 AUIPC = 0x1e,
14471 ALUIPC = 0x1f,
14472 LWPC_08 = 0x08,
14473 LWPC_09 = 0x09,
14474 LWPC_0A = 0x0A,
14475 LWPC_0B = 0x0B,
14476 LWPC_0C = 0x0C,
14477 LWPC_0D = 0x0D,
14478 LWPC_0E = 0x0E,
14479 LWPC_0F = 0x0F,
14480 };
14481
14482 /* POOL32A encoding of minor opcode field */
14483
14484 enum {
14485 /*
14486 * These opcodes are distinguished only by bits 9..6; those bits are
14487 * what are recorded below.
14488 */
14489 SLL32 = 0x0,
14490 SRL32 = 0x1,
14491 SRA = 0x2,
14492 ROTR = 0x3,
14493 SELEQZ = 0x5,
14494 SELNEZ = 0x6,
14495 R6_RDHWR = 0x7,
14496
14497 SLLV = 0x0,
14498 SRLV = 0x1,
14499 SRAV = 0x2,
14500 ROTRV = 0x3,
14501 ADD = 0x4,
14502 ADDU32 = 0x5,
14503 SUB = 0x6,
14504 SUBU32 = 0x7,
14505 MUL = 0x8,
14506 AND = 0x9,
14507 OR32 = 0xa,
14508 NOR = 0xb,
14509 XOR32 = 0xc,
14510 SLT = 0xd,
14511 SLTU = 0xe,
14512
14513 MOVN = 0x0,
14514 R6_MUL = 0x0,
14515 MOVZ = 0x1,
14516 MUH = 0x1,
14517 MULU = 0x2,
14518 MUHU = 0x3,
14519 LWXS = 0x4,
14520 R6_DIV = 0x4,
14521 MOD = 0x5,
14522 R6_DIVU = 0x6,
14523 MODU = 0x7,
14524
14525 /* The following can be distinguished by their lower 6 bits. */
14526 BREAK32 = 0x07,
14527 INS = 0x0c,
14528 LSA = 0x0f,
14529 ALIGN = 0x1f,
14530 EXT = 0x2c,
14531 POOL32AXF = 0x3c,
14532 SIGRIE = 0x3f
14533 };
14534
14535 /* POOL32AXF encoding of minor opcode field extension */
14536
14537 /*
14538 * 1. MIPS Architecture for Programmers Volume II-B:
14539 * The microMIPS32 Instruction Set (Revision 3.05)
14540 *
14541 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14542 *
14543 * 2. MIPS Architecture for Programmers VolumeIV-e:
14544 * The MIPS DSP Application-Specific Extension
14545 * to the microMIPS32 Architecture (Revision 2.34)
14546 *
14547 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14548 */
14549
14550 enum {
14551 /* bits 11..6 */
14552 TEQ = 0x00,
14553 TGE = 0x08,
14554 TGEU = 0x10,
14555 TLT = 0x20,
14556 TLTU = 0x28,
14557 TNE = 0x30,
14558
14559 MFC0 = 0x03,
14560 MTC0 = 0x0b,
14561
14562 /* begin of microMIPS32 DSP */
14563
14564 /* bits 13..12 for 0x01 */
14565 MFHI_ACC = 0x0,
14566 MFLO_ACC = 0x1,
14567 MTHI_ACC = 0x2,
14568 MTLO_ACC = 0x3,
14569
14570 /* bits 13..12 for 0x2a */
14571 MADD_ACC = 0x0,
14572 MADDU_ACC = 0x1,
14573 MSUB_ACC = 0x2,
14574 MSUBU_ACC = 0x3,
14575
14576 /* bits 13..12 for 0x32 */
14577 MULT_ACC = 0x0,
14578 MULTU_ACC = 0x1,
14579
14580 /* end of microMIPS32 DSP */
14581
14582 /* bits 15..12 for 0x2c */
14583 BITSWAP = 0x0,
14584 SEB = 0x2,
14585 SEH = 0x3,
14586 CLO = 0x4,
14587 CLZ = 0x5,
14588 RDHWR = 0x6,
14589 WSBH = 0x7,
14590 MULT = 0x8,
14591 MULTU = 0x9,
14592 DIV = 0xa,
14593 DIVU = 0xb,
14594 MADD = 0xc,
14595 MADDU = 0xd,
14596 MSUB = 0xe,
14597 MSUBU = 0xf,
14598
14599 /* bits 15..12 for 0x34 */
14600 MFC2 = 0x4,
14601 MTC2 = 0x5,
14602 MFHC2 = 0x8,
14603 MTHC2 = 0x9,
14604 CFC2 = 0xc,
14605 CTC2 = 0xd,
14606
14607 /* bits 15..12 for 0x3c */
14608 JALR = 0x0,
14609 JR = 0x0, /* alias */
14610 JALRC = 0x0,
14611 JRC = 0x0,
14612 JALR_HB = 0x1,
14613 JALRC_HB = 0x1,
14614 JALRS = 0x4,
14615 JALRS_HB = 0x5,
14616
14617 /* bits 15..12 for 0x05 */
14618 RDPGPR = 0xe,
14619 WRPGPR = 0xf,
14620
14621 /* bits 15..12 for 0x0d */
14622 TLBP = 0x0,
14623 TLBR = 0x1,
14624 TLBWI = 0x2,
14625 TLBWR = 0x3,
14626 TLBINV = 0x4,
14627 TLBINVF = 0x5,
14628 WAIT = 0x9,
14629 IRET = 0xd,
14630 DERET = 0xe,
14631 ERET = 0xf,
14632
14633 /* bits 15..12 for 0x15 */
14634 DMT = 0x0,
14635 DVPE = 0x1,
14636 EMT = 0x2,
14637 EVPE = 0x3,
14638
14639 /* bits 15..12 for 0x1d */
14640 DI = 0x4,
14641 EI = 0x5,
14642
14643 /* bits 15..12 for 0x2d */
14644 SYNC = 0x6,
14645 SYSCALL = 0x8,
14646 SDBBP = 0xd,
14647
14648 /* bits 15..12 for 0x35 */
14649 MFHI32 = 0x0,
14650 MFLO32 = 0x1,
14651 MTHI32 = 0x2,
14652 MTLO32 = 0x3,
14653 };
14654
14655 /* POOL32B encoding of minor opcode field (bits 15..12) */
14656
14657 enum {
14658 LWC2 = 0x0,
14659 LWP = 0x1,
14660 LDP = 0x4,
14661 LWM32 = 0x5,
14662 CACHE = 0x6,
14663 LDM = 0x7,
14664 SWC2 = 0x8,
14665 SWP = 0x9,
14666 SDP = 0xc,
14667 SWM32 = 0xd,
14668 SDM = 0xf
14669 };
14670
14671 /* POOL32C encoding of minor opcode field (bits 15..12) */
14672
14673 enum {
14674 LWL = 0x0,
14675 SWL = 0x8,
14676 LWR = 0x1,
14677 SWR = 0x9,
14678 PREF = 0x2,
14679 ST_EVA = 0xa,
14680 LL = 0x3,
14681 SC = 0xb,
14682 LDL = 0x4,
14683 SDL = 0xc,
14684 LDR = 0x5,
14685 SDR = 0xd,
14686 LD_EVA = 0x6,
14687 LWU = 0xe,
14688 LLD = 0x7,
14689 SCD = 0xf
14690 };
14691
14692 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14693
14694 enum {
14695 LBUE = 0x0,
14696 LHUE = 0x1,
14697 LWLE = 0x2,
14698 LWRE = 0x3,
14699 LBE = 0x4,
14700 LHE = 0x5,
14701 LLE = 0x6,
14702 LWE = 0x7,
14703 };
14704
14705 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14706
14707 enum {
14708 SWLE = 0x0,
14709 SWRE = 0x1,
14710 PREFE = 0x2,
14711 CACHEE = 0x3,
14712 SBE = 0x4,
14713 SHE = 0x5,
14714 SCE = 0x6,
14715 SWE = 0x7,
14716 };
14717
14718 /* POOL32F encoding of minor opcode field (bits 5..0) */
14719
14720 enum {
14721 /* These are the bit 7..6 values */
14722 ADD_FMT = 0x0,
14723
14724 SUB_FMT = 0x1,
14725
14726 MUL_FMT = 0x2,
14727
14728 DIV_FMT = 0x3,
14729
14730 /* These are the bit 8..6 values */
14731 MOVN_FMT = 0x0,
14732 RSQRT2_FMT = 0x0,
14733 MOVF_FMT = 0x0,
14734 RINT_FMT = 0x0,
14735 SELNEZ_FMT = 0x0,
14736
14737 MOVZ_FMT = 0x1,
14738 LWXC1 = 0x1,
14739 MOVT_FMT = 0x1,
14740 CLASS_FMT = 0x1,
14741 SELEQZ_FMT = 0x1,
14742
14743 PLL_PS = 0x2,
14744 SWXC1 = 0x2,
14745 SEL_FMT = 0x2,
14746
14747 PLU_PS = 0x3,
14748 LDXC1 = 0x3,
14749
14750 MOVN_FMT_04 = 0x4,
14751 PUL_PS = 0x4,
14752 SDXC1 = 0x4,
14753 RECIP2_FMT = 0x4,
14754
14755 MOVZ_FMT_05 = 0x05,
14756 PUU_PS = 0x5,
14757 LUXC1 = 0x5,
14758
14759 CVT_PS_S = 0x6,
14760 SUXC1 = 0x6,
14761 ADDR_PS = 0x6,
14762 PREFX = 0x6,
14763 MADDF_FMT = 0x6,
14764
14765 MULR_PS = 0x7,
14766 MSUBF_FMT = 0x7,
14767
14768 MADD_S = 0x01,
14769 MADD_D = 0x09,
14770 MADD_PS = 0x11,
14771 ALNV_PS = 0x19,
14772 MSUB_S = 0x21,
14773 MSUB_D = 0x29,
14774 MSUB_PS = 0x31,
14775
14776 NMADD_S = 0x02,
14777 NMADD_D = 0x0a,
14778 NMADD_PS = 0x12,
14779 NMSUB_S = 0x22,
14780 NMSUB_D = 0x2a,
14781 NMSUB_PS = 0x32,
14782
14783 MIN_FMT = 0x3,
14784 MAX_FMT = 0xb,
14785 MINA_FMT = 0x23,
14786 MAXA_FMT = 0x2b,
14787 POOL32FXF = 0x3b,
14788
14789 CABS_COND_FMT = 0x1c, /* MIPS3D */
14790 C_COND_FMT = 0x3c,
14791
14792 CMP_CONDN_S = 0x5,
14793 CMP_CONDN_D = 0x15
14794 };
14795
14796 /* POOL32Fxf encoding of minor opcode extension field */
14797
14798 enum {
14799 CVT_L = 0x04,
14800 RSQRT_FMT = 0x08,
14801 FLOOR_L = 0x0c,
14802 CVT_PW_PS = 0x1c,
14803 CVT_W = 0x24,
14804 SQRT_FMT = 0x28,
14805 FLOOR_W = 0x2c,
14806 CVT_PS_PW = 0x3c,
14807 CFC1 = 0x40,
14808 RECIP_FMT = 0x48,
14809 CEIL_L = 0x4c,
14810 CTC1 = 0x60,
14811 CEIL_W = 0x6c,
14812 MFC1 = 0x80,
14813 CVT_S_PL = 0x84,
14814 TRUNC_L = 0x8c,
14815 MTC1 = 0xa0,
14816 CVT_S_PU = 0xa4,
14817 TRUNC_W = 0xac,
14818 MFHC1 = 0xc0,
14819 ROUND_L = 0xcc,
14820 MTHC1 = 0xe0,
14821 ROUND_W = 0xec,
14822
14823 MOV_FMT = 0x01,
14824 MOVF = 0x05,
14825 ABS_FMT = 0x0d,
14826 RSQRT1_FMT = 0x1d,
14827 MOVT = 0x25,
14828 NEG_FMT = 0x2d,
14829 CVT_D = 0x4d,
14830 RECIP1_FMT = 0x5d,
14831 CVT_S = 0x6d
14832 };
14833
14834 /* POOL32I encoding of minor opcode field (bits 25..21) */
14835
14836 enum {
14837 BLTZ = 0x00,
14838 BLTZAL = 0x01,
14839 BGEZ = 0x02,
14840 BGEZAL = 0x03,
14841 BLEZ = 0x04,
14842 BNEZC = 0x05,
14843 BGTZ = 0x06,
14844 BEQZC = 0x07,
14845 TLTI = 0x08,
14846 BC1EQZC = 0x08,
14847 TGEI = 0x09,
14848 BC1NEZC = 0x09,
14849 TLTIU = 0x0a,
14850 BC2EQZC = 0x0a,
14851 TGEIU = 0x0b,
14852 BC2NEZC = 0x0a,
14853 TNEI = 0x0c,
14854 R6_SYNCI = 0x0c,
14855 LUI = 0x0d,
14856 TEQI = 0x0e,
14857 SYNCI = 0x10,
14858 BLTZALS = 0x11,
14859 BGEZALS = 0x13,
14860 BC2F = 0x14,
14861 BC2T = 0x15,
14862 BPOSGE64 = 0x1a,
14863 BPOSGE32 = 0x1b,
14864 /* These overlap and are distinguished by bit16 of the instruction */
14865 BC1F = 0x1c,
14866 BC1T = 0x1d,
14867 BC1ANY2F = 0x1c,
14868 BC1ANY2T = 0x1d,
14869 BC1ANY4F = 0x1e,
14870 BC1ANY4T = 0x1f
14871 };
14872
14873 /* POOL16A encoding of minor opcode field */
14874
14875 enum {
14876 ADDU16 = 0x0,
14877 SUBU16 = 0x1
14878 };
14879
14880 /* POOL16B encoding of minor opcode field */
14881
14882 enum {
14883 SLL16 = 0x0,
14884 SRL16 = 0x1
14885 };
14886
14887 /* POOL16C encoding of minor opcode field */
14888
14889 enum {
14890 NOT16 = 0x00,
14891 XOR16 = 0x04,
14892 AND16 = 0x08,
14893 OR16 = 0x0c,
14894 LWM16 = 0x10,
14895 SWM16 = 0x14,
14896 JR16 = 0x18,
14897 JRC16 = 0x1a,
14898 JALR16 = 0x1c,
14899 JALR16S = 0x1e,
14900 MFHI16 = 0x20,
14901 MFLO16 = 0x24,
14902 BREAK16 = 0x28,
14903 SDBBP16 = 0x2c,
14904 JRADDIUSP = 0x30
14905 };
14906
14907 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14908
14909 enum {
14910 R6_NOT16 = 0x00,
14911 R6_AND16 = 0x01,
14912 R6_LWM16 = 0x02,
14913 R6_JRC16 = 0x03,
14914 MOVEP = 0x04,
14915 MOVEP_05 = 0x05,
14916 MOVEP_06 = 0x06,
14917 MOVEP_07 = 0x07,
14918 R6_XOR16 = 0x08,
14919 R6_OR16 = 0x09,
14920 R6_SWM16 = 0x0a,
14921 JALRC16 = 0x0b,
14922 MOVEP_0C = 0x0c,
14923 MOVEP_0D = 0x0d,
14924 MOVEP_0E = 0x0e,
14925 MOVEP_0F = 0x0f,
14926 JRCADDIUSP = 0x13,
14927 R6_BREAK16 = 0x1b,
14928 R6_SDBBP16 = 0x3b
14929 };
14930
14931 /* POOL16D encoding of minor opcode field */
14932
14933 enum {
14934 ADDIUS5 = 0x0,
14935 ADDIUSP = 0x1
14936 };
14937
14938 /* POOL16E encoding of minor opcode field */
14939
14940 enum {
14941 ADDIUR2 = 0x0,
14942 ADDIUR1SP = 0x1
14943 };
14944
14945 static int mmreg(int r)
14946 {
14947 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14948
14949 return map[r];
14950 }
14951
14952 /* Used for 16-bit store instructions. */
14953 static int mmreg2(int r)
14954 {
14955 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14956
14957 return map[r];
14958 }
14959
14960 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14961 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14962 #define uMIPS_RS2(op) uMIPS_RS(op)
14963 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14964 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14965 #define uMIPS_RS5(op) (op & 0x1f)
14966
14967 /* Signed immediate */
14968 #define SIMM(op, start, width) \
14969 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14970 << (32-width)) \
14971 >> (32-width))
14972 /* Zero-extended immediate */
14973 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14974
14975 static void gen_addiur1sp(DisasContext *ctx)
14976 {
14977 int rd = mmreg(uMIPS_RD(ctx->opcode));
14978
14979 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14980 }
14981
14982 static void gen_addiur2(DisasContext *ctx)
14983 {
14984 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14985 int rd = mmreg(uMIPS_RD(ctx->opcode));
14986 int rs = mmreg(uMIPS_RS(ctx->opcode));
14987
14988 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14989 }
14990
14991 static void gen_addiusp(DisasContext *ctx)
14992 {
14993 int encoded = ZIMM(ctx->opcode, 1, 9);
14994 int decoded;
14995
14996 if (encoded <= 1) {
14997 decoded = 256 + encoded;
14998 } else if (encoded <= 255) {
14999 decoded = encoded;
15000 } else if (encoded <= 509) {
15001 decoded = encoded - 512;
15002 } else {
15003 decoded = encoded - 768;
15004 }
15005
15006 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
15007 }
15008
15009 static void gen_addius5(DisasContext *ctx)
15010 {
15011 int imm = SIMM(ctx->opcode, 1, 4);
15012 int rd = (ctx->opcode >> 5) & 0x1f;
15013
15014 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
15015 }
15016
15017 static void gen_andi16(DisasContext *ctx)
15018 {
15019 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15020 31, 32, 63, 64, 255, 32768, 65535 };
15021 int rd = mmreg(uMIPS_RD(ctx->opcode));
15022 int rs = mmreg(uMIPS_RS(ctx->opcode));
15023 int encoded = ZIMM(ctx->opcode, 0, 4);
15024
15025 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
15026 }
15027
15028 static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist,
15029 int base, int16_t offset)
15030 {
15031 TCGv t0, t1;
15032 TCGv_i32 t2;
15033
15034 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15035 generate_exception_end(ctx, EXCP_RI);
15036 return;
15037 }
15038
15039 t0 = tcg_temp_new();
15040
15041 gen_base_offset_addr(ctx, t0, base, offset);
15042
15043 t1 = tcg_const_tl(reglist);
15044 t2 = tcg_const_i32(ctx->mem_idx);
15045
15046 save_cpu_state(ctx, 1);
15047 switch (opc) {
15048 case LWM32:
15049 gen_helper_lwm(cpu_env, t0, t1, t2);
15050 break;
15051 case SWM32:
15052 gen_helper_swm(cpu_env, t0, t1, t2);
15053 break;
15054 #ifdef TARGET_MIPS64
15055 case LDM:
15056 gen_helper_ldm(cpu_env, t0, t1, t2);
15057 break;
15058 case SDM:
15059 gen_helper_sdm(cpu_env, t0, t1, t2);
15060 break;
15061 #endif
15062 }
15063 tcg_temp_free(t0);
15064 tcg_temp_free(t1);
15065 tcg_temp_free_i32(t2);
15066 }
15067
15068
15069 static void gen_pool16c_insn(DisasContext *ctx)
15070 {
15071 int rd = mmreg((ctx->opcode >> 3) & 0x7);
15072 int rs = mmreg(ctx->opcode & 0x7);
15073
15074 switch (((ctx->opcode) >> 4) & 0x3f) {
15075 case NOT16 + 0:
15076 case NOT16 + 1:
15077 case NOT16 + 2:
15078 case NOT16 + 3:
15079 gen_logic(ctx, OPC_NOR, rd, rs, 0);
15080 break;
15081 case XOR16 + 0:
15082 case XOR16 + 1:
15083 case XOR16 + 2:
15084 case XOR16 + 3:
15085 gen_logic(ctx, OPC_XOR, rd, rd, rs);
15086 break;
15087 case AND16 + 0:
15088 case AND16 + 1:
15089 case AND16 + 2:
15090 case AND16 + 3:
15091 gen_logic(ctx, OPC_AND, rd, rd, rs);
15092 break;
15093 case OR16 + 0:
15094 case OR16 + 1:
15095 case OR16 + 2:
15096 case OR16 + 3:
15097 gen_logic(ctx, OPC_OR, rd, rd, rs);
15098 break;
15099 case LWM16 + 0:
15100 case LWM16 + 1:
15101 case LWM16 + 2:
15102 case LWM16 + 3:
15103 {
15104 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15105 int offset = ZIMM(ctx->opcode, 0, 4);
15106
15107 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
15108 29, offset << 2);
15109 }
15110 break;
15111 case SWM16 + 0:
15112 case SWM16 + 1:
15113 case SWM16 + 2:
15114 case SWM16 + 3:
15115 {
15116 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15117 int offset = ZIMM(ctx->opcode, 0, 4);
15118
15119 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
15120 29, offset << 2);
15121 }
15122 break;
15123 case JR16 + 0:
15124 case JR16 + 1:
15125 {
15126 int reg = ctx->opcode & 0x1f;
15127
15128 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
15129 }
15130 break;
15131 case JRC16 + 0:
15132 case JRC16 + 1:
15133 {
15134 int reg = ctx->opcode & 0x1f;
15135 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
15136 /*
15137 * Let normal delay slot handling in our caller take us
15138 * to the branch target.
15139 */
15140 }
15141 break;
15142 case JALR16 + 0:
15143 case JALR16 + 1:
15144 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15145 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15146 break;
15147 case JALR16S + 0:
15148 case JALR16S + 1:
15149 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15150 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15151 break;
15152 case MFHI16 + 0:
15153 case MFHI16 + 1:
15154 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15155 break;
15156 case MFLO16 + 0:
15157 case MFLO16 + 1:
15158 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15159 break;
15160 case BREAK16:
15161 generate_exception_end(ctx, EXCP_BREAK);
15162 break;
15163 case SDBBP16:
15164 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15165 gen_helper_do_semihosting(cpu_env);
15166 } else {
15167 /*
15168 * XXX: not clear which exception should be raised
15169 * when in debug mode...
15170 */
15171 check_insn(ctx, ISA_MIPS32);
15172 generate_exception_end(ctx, EXCP_DBp);
15173 }
15174 break;
15175 case JRADDIUSP + 0:
15176 case JRADDIUSP + 1:
15177 {
15178 int imm = ZIMM(ctx->opcode, 0, 5);
15179 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15180 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15181 /*
15182 * Let normal delay slot handling in our caller take us
15183 * to the branch target.
15184 */
15185 }
15186 break;
15187 default:
15188 generate_exception_end(ctx, EXCP_RI);
15189 break;
15190 }
15191 }
15192
15193 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15194 int enc_rs)
15195 {
15196 int rd, rs, re, rt;
15197 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15198 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15199 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15200 rd = rd_enc[enc_dest];
15201 re = re_enc[enc_dest];
15202 rs = rs_rt_enc[enc_rs];
15203 rt = rs_rt_enc[enc_rt];
15204 if (rs) {
15205 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15206 } else {
15207 tcg_gen_movi_tl(cpu_gpr[rd], 0);
15208 }
15209 if (rt) {
15210 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15211 } else {
15212 tcg_gen_movi_tl(cpu_gpr[re], 0);
15213 }
15214 }
15215
15216 static void gen_pool16c_r6_insn(DisasContext *ctx)
15217 {
15218 int rt = mmreg((ctx->opcode >> 7) & 0x7);
15219 int rs = mmreg((ctx->opcode >> 4) & 0x7);
15220
15221 switch (ctx->opcode & 0xf) {
15222 case R6_NOT16:
15223 gen_logic(ctx, OPC_NOR, rt, rs, 0);
15224 break;
15225 case R6_AND16:
15226 gen_logic(ctx, OPC_AND, rt, rt, rs);
15227 break;
15228 case R6_LWM16:
15229 {
15230 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15231 int offset = extract32(ctx->opcode, 4, 4);
15232 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15233 }
15234 break;
15235 case R6_JRC16: /* JRCADDIUSP */
15236 if ((ctx->opcode >> 4) & 1) {
15237 /* JRCADDIUSP */
15238 int imm = extract32(ctx->opcode, 5, 5);
15239 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15240 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15241 } else {
15242 /* JRC16 */
15243 rs = extract32(ctx->opcode, 5, 5);
15244 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15245 }
15246 break;
15247 case MOVEP:
15248 case MOVEP_05:
15249 case MOVEP_06:
15250 case MOVEP_07:
15251 case MOVEP_0C:
15252 case MOVEP_0D:
15253 case MOVEP_0E:
15254 case MOVEP_0F:
15255 {
15256 int enc_dest = uMIPS_RD(ctx->opcode);
15257 int enc_rt = uMIPS_RS2(ctx->opcode);
15258 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15259 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15260 }
15261 break;
15262 case R6_XOR16:
15263 gen_logic(ctx, OPC_XOR, rt, rt, rs);
15264 break;
15265 case R6_OR16:
15266 gen_logic(ctx, OPC_OR, rt, rt, rs);
15267 break;
15268 case R6_SWM16:
15269 {
15270 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15271 int offset = extract32(ctx->opcode, 4, 4);
15272 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15273 }
15274 break;
15275 case JALRC16: /* BREAK16, SDBBP16 */
15276 switch (ctx->opcode & 0x3f) {
15277 case JALRC16:
15278 case JALRC16 + 0x20:
15279 /* JALRC16 */
15280 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15281 31, 0, 0);
15282 break;
15283 case R6_BREAK16:
15284 /* BREAK16 */
15285 generate_exception(ctx, EXCP_BREAK);
15286 break;
15287 case R6_SDBBP16:
15288 /* SDBBP16 */
15289 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15290 gen_helper_do_semihosting(cpu_env);
15291 } else {
15292 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15293 generate_exception(ctx, EXCP_RI);
15294 } else {
15295 generate_exception(ctx, EXCP_DBp);
15296 }
15297 }
15298 break;
15299 }
15300 break;
15301 default:
15302 generate_exception(ctx, EXCP_RI);
15303 break;
15304 }
15305 }
15306
15307 static void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
15308 {
15309 TCGv t0 = tcg_temp_new();
15310 TCGv t1 = tcg_temp_new();
15311
15312 gen_load_gpr(t0, base);
15313
15314 if (index != 0) {
15315 gen_load_gpr(t1, index);
15316 tcg_gen_shli_tl(t1, t1, 2);
15317 gen_op_addr_add(ctx, t0, t1, t0);
15318 }
15319
15320 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15321 gen_store_gpr(t1, rd);
15322
15323 tcg_temp_free(t0);
15324 tcg_temp_free(t1);
15325 }
15326
15327 static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd,
15328 int base, int16_t offset)
15329 {
15330 TCGv t0, t1;
15331
15332 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15333 generate_exception_end(ctx, EXCP_RI);
15334 return;
15335 }
15336
15337 t0 = tcg_temp_new();
15338 t1 = tcg_temp_new();
15339
15340 gen_base_offset_addr(ctx, t0, base, offset);
15341
15342 switch (opc) {
15343 case LWP:
15344 if (rd == base) {
15345 generate_exception_end(ctx, EXCP_RI);
15346 return;
15347 }
15348 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15349 gen_store_gpr(t1, rd);
15350 tcg_gen_movi_tl(t1, 4);
15351 gen_op_addr_add(ctx, t0, t0, t1);
15352 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15353 gen_store_gpr(t1, rd + 1);
15354 break;
15355 case SWP:
15356 gen_load_gpr(t1, rd);
15357 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15358 tcg_gen_movi_tl(t1, 4);
15359 gen_op_addr_add(ctx, t0, t0, t1);
15360 gen_load_gpr(t1, rd + 1);
15361 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15362 break;
15363 #ifdef TARGET_MIPS64
15364 case LDP:
15365 if (rd == base) {
15366 generate_exception_end(ctx, EXCP_RI);
15367 return;
15368 }
15369 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15370 gen_store_gpr(t1, rd);
15371 tcg_gen_movi_tl(t1, 8);
15372 gen_op_addr_add(ctx, t0, t0, t1);
15373 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15374 gen_store_gpr(t1, rd + 1);
15375 break;
15376 case SDP:
15377 gen_load_gpr(t1, rd);
15378 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15379 tcg_gen_movi_tl(t1, 8);
15380 gen_op_addr_add(ctx, t0, t0, t1);
15381 gen_load_gpr(t1, rd + 1);
15382 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15383 break;
15384 #endif
15385 }
15386 tcg_temp_free(t0);
15387 tcg_temp_free(t1);
15388 }
15389
15390 static void gen_sync(int stype)
15391 {
15392 TCGBar tcg_mo = TCG_BAR_SC;
15393
15394 switch (stype) {
15395 case 0x4: /* SYNC_WMB */
15396 tcg_mo |= TCG_MO_ST_ST;
15397 break;
15398 case 0x10: /* SYNC_MB */
15399 tcg_mo |= TCG_MO_ALL;
15400 break;
15401 case 0x11: /* SYNC_ACQUIRE */
15402 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15403 break;
15404 case 0x12: /* SYNC_RELEASE */
15405 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15406 break;
15407 case 0x13: /* SYNC_RMB */
15408 tcg_mo |= TCG_MO_LD_LD;
15409 break;
15410 default:
15411 tcg_mo |= TCG_MO_ALL;
15412 break;
15413 }
15414
15415 tcg_gen_mb(tcg_mo);
15416 }
15417
15418 static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15419 {
15420 int extension = (ctx->opcode >> 6) & 0x3f;
15421 int minor = (ctx->opcode >> 12) & 0xf;
15422 uint32_t mips32_op;
15423
15424 switch (extension) {
15425 case TEQ:
15426 mips32_op = OPC_TEQ;
15427 goto do_trap;
15428 case TGE:
15429 mips32_op = OPC_TGE;
15430 goto do_trap;
15431 case TGEU:
15432 mips32_op = OPC_TGEU;
15433 goto do_trap;
15434 case TLT:
15435 mips32_op = OPC_TLT;
15436 goto do_trap;
15437 case TLTU:
15438 mips32_op = OPC_TLTU;
15439 goto do_trap;
15440 case TNE:
15441 mips32_op = OPC_TNE;
15442 do_trap:
15443 gen_trap(ctx, mips32_op, rs, rt, -1);
15444 break;
15445 #ifndef CONFIG_USER_ONLY
15446 case MFC0:
15447 case MFC0 + 32:
15448 check_cp0_enabled(ctx);
15449 if (rt == 0) {
15450 /* Treat as NOP. */
15451 break;
15452 }
15453 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15454 break;
15455 case MTC0:
15456 case MTC0 + 32:
15457 check_cp0_enabled(ctx);
15458 {
15459 TCGv t0 = tcg_temp_new();
15460
15461 gen_load_gpr(t0, rt);
15462 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15463 tcg_temp_free(t0);
15464 }
15465 break;
15466 #endif
15467 case 0x2a:
15468 switch (minor & 3) {
15469 case MADD_ACC:
15470 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15471 break;
15472 case MADDU_ACC:
15473 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15474 break;
15475 case MSUB_ACC:
15476 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15477 break;
15478 case MSUBU_ACC:
15479 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15480 break;
15481 default:
15482 goto pool32axf_invalid;
15483 }
15484 break;
15485 case 0x32:
15486 switch (minor & 3) {
15487 case MULT_ACC:
15488 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15489 break;
15490 case MULTU_ACC:
15491 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15492 break;
15493 default:
15494 goto pool32axf_invalid;
15495 }
15496 break;
15497 case 0x2c:
15498 switch (minor) {
15499 case BITSWAP:
15500 check_insn(ctx, ISA_MIPS32R6);
15501 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15502 break;
15503 case SEB:
15504 gen_bshfl(ctx, OPC_SEB, rs, rt);
15505 break;
15506 case SEH:
15507 gen_bshfl(ctx, OPC_SEH, rs, rt);
15508 break;
15509 case CLO:
15510 mips32_op = OPC_CLO;
15511 goto do_cl;
15512 case CLZ:
15513 mips32_op = OPC_CLZ;
15514 do_cl:
15515 check_insn(ctx, ISA_MIPS32);
15516 gen_cl(ctx, mips32_op, rt, rs);
15517 break;
15518 case RDHWR:
15519 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15520 gen_rdhwr(ctx, rt, rs, 0);
15521 break;
15522 case WSBH:
15523 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15524 break;
15525 case MULT:
15526 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15527 mips32_op = OPC_MULT;
15528 goto do_mul;
15529 case MULTU:
15530 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15531 mips32_op = OPC_MULTU;
15532 goto do_mul;
15533 case DIV:
15534 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15535 mips32_op = OPC_DIV;
15536 goto do_div;
15537 case DIVU:
15538 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15539 mips32_op = OPC_DIVU;
15540 goto do_div;
15541 do_div:
15542 check_insn(ctx, ISA_MIPS32);
15543 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15544 break;
15545 case MADD:
15546 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15547 mips32_op = OPC_MADD;
15548 goto do_mul;
15549 case MADDU:
15550 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15551 mips32_op = OPC_MADDU;
15552 goto do_mul;
15553 case MSUB:
15554 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15555 mips32_op = OPC_MSUB;
15556 goto do_mul;
15557 case MSUBU:
15558 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15559 mips32_op = OPC_MSUBU;
15560 do_mul:
15561 check_insn(ctx, ISA_MIPS32);
15562 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15563 break;
15564 default:
15565 goto pool32axf_invalid;
15566 }
15567 break;
15568 case 0x34:
15569 switch (minor) {
15570 case MFC2:
15571 case MTC2:
15572 case MFHC2:
15573 case MTHC2:
15574 case CFC2:
15575 case CTC2:
15576 generate_exception_err(ctx, EXCP_CpU, 2);
15577 break;
15578 default:
15579 goto pool32axf_invalid;
15580 }
15581 break;
15582 case 0x3c:
15583 switch (minor) {
15584 case JALR: /* JALRC */
15585 case JALR_HB: /* JALRC_HB */
15586 if (ctx->insn_flags & ISA_MIPS32R6) {
15587 /* JALRC, JALRC_HB */
15588 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15589 } else {
15590 /* JALR, JALR_HB */
15591 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15592 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15593 }
15594 break;
15595 case JALRS:
15596 case JALRS_HB:
15597 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15598 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15599 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15600 break;
15601 default:
15602 goto pool32axf_invalid;
15603 }
15604 break;
15605 case 0x05:
15606 switch (minor) {
15607 case RDPGPR:
15608 check_cp0_enabled(ctx);
15609 check_insn(ctx, ISA_MIPS32R2);
15610 gen_load_srsgpr(rs, rt);
15611 break;
15612 case WRPGPR:
15613 check_cp0_enabled(ctx);
15614 check_insn(ctx, ISA_MIPS32R2);
15615 gen_store_srsgpr(rs, rt);
15616 break;
15617 default:
15618 goto pool32axf_invalid;
15619 }
15620 break;
15621 #ifndef CONFIG_USER_ONLY
15622 case 0x0d:
15623 switch (minor) {
15624 case TLBP:
15625 mips32_op = OPC_TLBP;
15626 goto do_cp0;
15627 case TLBR:
15628 mips32_op = OPC_TLBR;
15629 goto do_cp0;
15630 case TLBWI:
15631 mips32_op = OPC_TLBWI;
15632 goto do_cp0;
15633 case TLBWR:
15634 mips32_op = OPC_TLBWR;
15635 goto do_cp0;
15636 case TLBINV:
15637 mips32_op = OPC_TLBINV;
15638 goto do_cp0;
15639 case TLBINVF:
15640 mips32_op = OPC_TLBINVF;
15641 goto do_cp0;
15642 case WAIT:
15643 mips32_op = OPC_WAIT;
15644 goto do_cp0;
15645 case DERET:
15646 mips32_op = OPC_DERET;
15647 goto do_cp0;
15648 case ERET:
15649 mips32_op = OPC_ERET;
15650 do_cp0:
15651 gen_cp0(env, ctx, mips32_op, rt, rs);
15652 break;
15653 default:
15654 goto pool32axf_invalid;
15655 }
15656 break;
15657 case 0x1d:
15658 switch (minor) {
15659 case DI:
15660 check_cp0_enabled(ctx);
15661 {
15662 TCGv t0 = tcg_temp_new();
15663
15664 save_cpu_state(ctx, 1);
15665 gen_helper_di(t0, cpu_env);
15666 gen_store_gpr(t0, rs);
15667 /* Stop translation as we may have switched the execution mode */
15668 ctx->base.is_jmp = DISAS_STOP;
15669 tcg_temp_free(t0);
15670 }
15671 break;
15672 case EI:
15673 check_cp0_enabled(ctx);
15674 {
15675 TCGv t0 = tcg_temp_new();
15676
15677 save_cpu_state(ctx, 1);
15678 gen_helper_ei(t0, cpu_env);
15679 gen_store_gpr(t0, rs);
15680 /*
15681 * DISAS_STOP isn't sufficient, we need to ensure we break out
15682 * of translated code to check for pending interrupts.
15683 */
15684 gen_save_pc(ctx->base.pc_next + 4);
15685 ctx->base.is_jmp = DISAS_EXIT;
15686 tcg_temp_free(t0);
15687 }
15688 break;
15689 default:
15690 goto pool32axf_invalid;
15691 }
15692 break;
15693 #endif
15694 case 0x2d:
15695 switch (minor) {
15696 case SYNC:
15697 gen_sync(extract32(ctx->opcode, 16, 5));
15698 break;
15699 case SYSCALL:
15700 generate_exception_end(ctx, EXCP_SYSCALL);
15701 break;
15702 case SDBBP:
15703 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15704 gen_helper_do_semihosting(cpu_env);
15705 } else {
15706 check_insn(ctx, ISA_MIPS32);
15707 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15708 generate_exception_end(ctx, EXCP_RI);
15709 } else {
15710 generate_exception_end(ctx, EXCP_DBp);
15711 }
15712 }
15713 break;
15714 default:
15715 goto pool32axf_invalid;
15716 }
15717 break;
15718 case 0x01:
15719 switch (minor & 3) {
15720 case MFHI_ACC:
15721 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15722 break;
15723 case MFLO_ACC:
15724 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15725 break;
15726 case MTHI_ACC:
15727 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15728 break;
15729 case MTLO_ACC:
15730 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15731 break;
15732 default:
15733 goto pool32axf_invalid;
15734 }
15735 break;
15736 case 0x35:
15737 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15738 switch (minor) {
15739 case MFHI32:
15740 gen_HILO(ctx, OPC_MFHI, 0, rs);
15741 break;
15742 case MFLO32:
15743 gen_HILO(ctx, OPC_MFLO, 0, rs);
15744 break;
15745 case MTHI32:
15746 gen_HILO(ctx, OPC_MTHI, 0, rs);
15747 break;
15748 case MTLO32:
15749 gen_HILO(ctx, OPC_MTLO, 0, rs);
15750 break;
15751 default:
15752 goto pool32axf_invalid;
15753 }
15754 break;
15755 default:
15756 pool32axf_invalid:
15757 MIPS_INVAL("pool32axf");
15758 generate_exception_end(ctx, EXCP_RI);
15759 break;
15760 }
15761 }
15762
15763 /*
15764 * Values for microMIPS fmt field. Variable-width, depending on which
15765 * formats the instruction supports.
15766 */
15767 enum {
15768 FMT_SD_S = 0,
15769 FMT_SD_D = 1,
15770
15771 FMT_SDPS_S = 0,
15772 FMT_SDPS_D = 1,
15773 FMT_SDPS_PS = 2,
15774
15775 FMT_SWL_S = 0,
15776 FMT_SWL_W = 1,
15777 FMT_SWL_L = 2,
15778
15779 FMT_DWL_D = 0,
15780 FMT_DWL_W = 1,
15781 FMT_DWL_L = 2
15782 };
15783
15784 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15785 {
15786 int extension = (ctx->opcode >> 6) & 0x3ff;
15787 uint32_t mips32_op;
15788
15789 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15790 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15791 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15792
15793 switch (extension) {
15794 case FLOAT_1BIT_FMT(CFC1, 0):
15795 mips32_op = OPC_CFC1;
15796 goto do_cp1;
15797 case FLOAT_1BIT_FMT(CTC1, 0):
15798 mips32_op = OPC_CTC1;
15799 goto do_cp1;
15800 case FLOAT_1BIT_FMT(MFC1, 0):
15801 mips32_op = OPC_MFC1;
15802 goto do_cp1;
15803 case FLOAT_1BIT_FMT(MTC1, 0):
15804 mips32_op = OPC_MTC1;
15805 goto do_cp1;
15806 case FLOAT_1BIT_FMT(MFHC1, 0):
15807 mips32_op = OPC_MFHC1;
15808 goto do_cp1;
15809 case FLOAT_1BIT_FMT(MTHC1, 0):
15810 mips32_op = OPC_MTHC1;
15811 do_cp1:
15812 gen_cp1(ctx, mips32_op, rt, rs);
15813 break;
15814
15815 /* Reciprocal square root */
15816 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15817 mips32_op = OPC_RSQRT_S;
15818 goto do_unaryfp;
15819 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15820 mips32_op = OPC_RSQRT_D;
15821 goto do_unaryfp;
15822
15823 /* Square root */
15824 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15825 mips32_op = OPC_SQRT_S;
15826 goto do_unaryfp;
15827 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15828 mips32_op = OPC_SQRT_D;
15829 goto do_unaryfp;
15830
15831 /* Reciprocal */
15832 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15833 mips32_op = OPC_RECIP_S;
15834 goto do_unaryfp;
15835 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15836 mips32_op = OPC_RECIP_D;
15837 goto do_unaryfp;
15838
15839 /* Floor */
15840 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15841 mips32_op = OPC_FLOOR_L_S;
15842 goto do_unaryfp;
15843 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15844 mips32_op = OPC_FLOOR_L_D;
15845 goto do_unaryfp;
15846 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15847 mips32_op = OPC_FLOOR_W_S;
15848 goto do_unaryfp;
15849 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15850 mips32_op = OPC_FLOOR_W_D;
15851 goto do_unaryfp;
15852
15853 /* Ceiling */
15854 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15855 mips32_op = OPC_CEIL_L_S;
15856 goto do_unaryfp;
15857 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15858 mips32_op = OPC_CEIL_L_D;
15859 goto do_unaryfp;
15860 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15861 mips32_op = OPC_CEIL_W_S;
15862 goto do_unaryfp;
15863 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15864 mips32_op = OPC_CEIL_W_D;
15865 goto do_unaryfp;
15866
15867 /* Truncation */
15868 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15869 mips32_op = OPC_TRUNC_L_S;
15870 goto do_unaryfp;
15871 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15872 mips32_op = OPC_TRUNC_L_D;
15873 goto do_unaryfp;
15874 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15875 mips32_op = OPC_TRUNC_W_S;
15876 goto do_unaryfp;
15877 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15878 mips32_op = OPC_TRUNC_W_D;
15879 goto do_unaryfp;
15880
15881 /* Round */
15882 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15883 mips32_op = OPC_ROUND_L_S;
15884 goto do_unaryfp;
15885 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15886 mips32_op = OPC_ROUND_L_D;
15887 goto do_unaryfp;
15888 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15889 mips32_op = OPC_ROUND_W_S;
15890 goto do_unaryfp;
15891 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15892 mips32_op = OPC_ROUND_W_D;
15893 goto do_unaryfp;
15894
15895 /* Integer to floating-point conversion */
15896 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15897 mips32_op = OPC_CVT_L_S;
15898 goto do_unaryfp;
15899 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15900 mips32_op = OPC_CVT_L_D;
15901 goto do_unaryfp;
15902 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15903 mips32_op = OPC_CVT_W_S;
15904 goto do_unaryfp;
15905 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15906 mips32_op = OPC_CVT_W_D;
15907 goto do_unaryfp;
15908
15909 /* Paired-foo conversions */
15910 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15911 mips32_op = OPC_CVT_S_PL;
15912 goto do_unaryfp;
15913 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15914 mips32_op = OPC_CVT_S_PU;
15915 goto do_unaryfp;
15916 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15917 mips32_op = OPC_CVT_PW_PS;
15918 goto do_unaryfp;
15919 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15920 mips32_op = OPC_CVT_PS_PW;
15921 goto do_unaryfp;
15922
15923 /* Floating-point moves */
15924 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15925 mips32_op = OPC_MOV_S;
15926 goto do_unaryfp;
15927 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15928 mips32_op = OPC_MOV_D;
15929 goto do_unaryfp;
15930 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15931 mips32_op = OPC_MOV_PS;
15932 goto do_unaryfp;
15933
15934 /* Absolute value */
15935 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15936 mips32_op = OPC_ABS_S;
15937 goto do_unaryfp;
15938 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15939 mips32_op = OPC_ABS_D;
15940 goto do_unaryfp;
15941 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15942 mips32_op = OPC_ABS_PS;
15943 goto do_unaryfp;
15944
15945 /* Negation */
15946 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15947 mips32_op = OPC_NEG_S;
15948 goto do_unaryfp;
15949 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15950 mips32_op = OPC_NEG_D;
15951 goto do_unaryfp;
15952 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15953 mips32_op = OPC_NEG_PS;
15954 goto do_unaryfp;
15955
15956 /* Reciprocal square root step */
15957 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15958 mips32_op = OPC_RSQRT1_S;
15959 goto do_unaryfp;
15960 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15961 mips32_op = OPC_RSQRT1_D;
15962 goto do_unaryfp;
15963 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15964 mips32_op = OPC_RSQRT1_PS;
15965 goto do_unaryfp;
15966
15967 /* Reciprocal step */
15968 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15969 mips32_op = OPC_RECIP1_S;
15970 goto do_unaryfp;
15971 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15972 mips32_op = OPC_RECIP1_S;
15973 goto do_unaryfp;
15974 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15975 mips32_op = OPC_RECIP1_PS;
15976 goto do_unaryfp;
15977
15978 /* Conversions from double */
15979 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15980 mips32_op = OPC_CVT_D_S;
15981 goto do_unaryfp;
15982 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15983 mips32_op = OPC_CVT_D_W;
15984 goto do_unaryfp;
15985 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15986 mips32_op = OPC_CVT_D_L;
15987 goto do_unaryfp;
15988
15989 /* Conversions from single */
15990 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15991 mips32_op = OPC_CVT_S_D;
15992 goto do_unaryfp;
15993 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15994 mips32_op = OPC_CVT_S_W;
15995 goto do_unaryfp;
15996 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15997 mips32_op = OPC_CVT_S_L;
15998 do_unaryfp:
15999 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
16000 break;
16001
16002 /* Conditional moves on floating-point codes */
16003 case COND_FLOAT_MOV(MOVT, 0):
16004 case COND_FLOAT_MOV(MOVT, 1):
16005 case COND_FLOAT_MOV(MOVT, 2):
16006 case COND_FLOAT_MOV(MOVT, 3):
16007 case COND_FLOAT_MOV(MOVT, 4):
16008 case COND_FLOAT_MOV(MOVT, 5):
16009 case COND_FLOAT_MOV(MOVT, 6):
16010 case COND_FLOAT_MOV(MOVT, 7):
16011 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16012 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
16013 break;
16014 case COND_FLOAT_MOV(MOVF, 0):
16015 case COND_FLOAT_MOV(MOVF, 1):
16016 case COND_FLOAT_MOV(MOVF, 2):
16017 case COND_FLOAT_MOV(MOVF, 3):
16018 case COND_FLOAT_MOV(MOVF, 4):
16019 case COND_FLOAT_MOV(MOVF, 5):
16020 case COND_FLOAT_MOV(MOVF, 6):
16021 case COND_FLOAT_MOV(MOVF, 7):
16022 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16023 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
16024 break;
16025 default:
16026 MIPS_INVAL("pool32fxf");
16027 generate_exception_end(ctx, EXCP_RI);
16028 break;
16029 }
16030 }
16031
16032 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
16033 {
16034 int32_t offset;
16035 uint16_t insn;
16036 int rt, rs, rd, rr;
16037 int16_t imm;
16038 uint32_t op, minor, minor2, mips32_op;
16039 uint32_t cond, fmt, cc;
16040
16041 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
16042 ctx->opcode = (ctx->opcode << 16) | insn;
16043
16044 rt = (ctx->opcode >> 21) & 0x1f;
16045 rs = (ctx->opcode >> 16) & 0x1f;
16046 rd = (ctx->opcode >> 11) & 0x1f;
16047 rr = (ctx->opcode >> 6) & 0x1f;
16048 imm = (int16_t) ctx->opcode;
16049
16050 op = (ctx->opcode >> 26) & 0x3f;
16051 switch (op) {
16052 case POOL32A:
16053 minor = ctx->opcode & 0x3f;
16054 switch (minor) {
16055 case 0x00:
16056 minor = (ctx->opcode >> 6) & 0xf;
16057 switch (minor) {
16058 case SLL32:
16059 mips32_op = OPC_SLL;
16060 goto do_shifti;
16061 case SRA:
16062 mips32_op = OPC_SRA;
16063 goto do_shifti;
16064 case SRL32:
16065 mips32_op = OPC_SRL;
16066 goto do_shifti;
16067 case ROTR:
16068 mips32_op = OPC_ROTR;
16069 do_shifti:
16070 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
16071 break;
16072 case SELEQZ:
16073 check_insn(ctx, ISA_MIPS32R6);
16074 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
16075 break;
16076 case SELNEZ:
16077 check_insn(ctx, ISA_MIPS32R6);
16078 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
16079 break;
16080 case R6_RDHWR:
16081 check_insn(ctx, ISA_MIPS32R6);
16082 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
16083 break;
16084 default:
16085 goto pool32a_invalid;
16086 }
16087 break;
16088 case 0x10:
16089 minor = (ctx->opcode >> 6) & 0xf;
16090 switch (minor) {
16091 /* Arithmetic */
16092 case ADD:
16093 mips32_op = OPC_ADD;
16094 goto do_arith;
16095 case ADDU32:
16096 mips32_op = OPC_ADDU;
16097 goto do_arith;
16098 case SUB:
16099 mips32_op = OPC_SUB;
16100 goto do_arith;
16101 case SUBU32:
16102 mips32_op = OPC_SUBU;
16103 goto do_arith;
16104 case MUL:
16105 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16106 mips32_op = OPC_MUL;
16107 do_arith:
16108 gen_arith(ctx, mips32_op, rd, rs, rt);
16109 break;
16110 /* Shifts */
16111 case SLLV:
16112 mips32_op = OPC_SLLV;
16113 goto do_shift;
16114 case SRLV:
16115 mips32_op = OPC_SRLV;
16116 goto do_shift;
16117 case SRAV:
16118 mips32_op = OPC_SRAV;
16119 goto do_shift;
16120 case ROTRV:
16121 mips32_op = OPC_ROTRV;
16122 do_shift:
16123 gen_shift(ctx, mips32_op, rd, rs, rt);
16124 break;
16125 /* Logical operations */
16126 case AND:
16127 mips32_op = OPC_AND;
16128 goto do_logic;
16129 case OR32:
16130 mips32_op = OPC_OR;
16131 goto do_logic;
16132 case NOR:
16133 mips32_op = OPC_NOR;
16134 goto do_logic;
16135 case XOR32:
16136 mips32_op = OPC_XOR;
16137 do_logic:
16138 gen_logic(ctx, mips32_op, rd, rs, rt);
16139 break;
16140 /* Set less than */
16141 case SLT:
16142 mips32_op = OPC_SLT;
16143 goto do_slt;
16144 case SLTU:
16145 mips32_op = OPC_SLTU;
16146 do_slt:
16147 gen_slt(ctx, mips32_op, rd, rs, rt);
16148 break;
16149 default:
16150 goto pool32a_invalid;
16151 }
16152 break;
16153 case 0x18:
16154 minor = (ctx->opcode >> 6) & 0xf;
16155 switch (minor) {
16156 /* Conditional moves */
16157 case MOVN: /* MUL */
16158 if (ctx->insn_flags & ISA_MIPS32R6) {
16159 /* MUL */
16160 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16161 } else {
16162 /* MOVN */
16163 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16164 }
16165 break;
16166 case MOVZ: /* MUH */
16167 if (ctx->insn_flags & ISA_MIPS32R6) {
16168 /* MUH */
16169 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16170 } else {
16171 /* MOVZ */
16172 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16173 }
16174 break;
16175 case MULU:
16176 check_insn(ctx, ISA_MIPS32R6);
16177 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16178 break;
16179 case MUHU:
16180 check_insn(ctx, ISA_MIPS32R6);
16181 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16182 break;
16183 case LWXS: /* DIV */
16184 if (ctx->insn_flags & ISA_MIPS32R6) {
16185 /* DIV */
16186 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16187 } else {
16188 /* LWXS */
16189 gen_ldxs(ctx, rs, rt, rd);
16190 }
16191 break;
16192 case MOD:
16193 check_insn(ctx, ISA_MIPS32R6);
16194 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16195 break;
16196 case R6_DIVU:
16197 check_insn(ctx, ISA_MIPS32R6);
16198 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16199 break;
16200 case MODU:
16201 check_insn(ctx, ISA_MIPS32R6);
16202 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16203 break;
16204 default:
16205 goto pool32a_invalid;
16206 }
16207 break;
16208 case INS:
16209 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16210 return;
16211 case LSA:
16212 check_insn(ctx, ISA_MIPS32R6);
16213 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16214 extract32(ctx->opcode, 9, 2));
16215 break;
16216 case ALIGN:
16217 check_insn(ctx, ISA_MIPS32R6);
16218 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16219 break;
16220 case EXT:
16221 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16222 return;
16223 case POOL32AXF:
16224 gen_pool32axf(env, ctx, rt, rs);
16225 break;
16226 case BREAK32:
16227 generate_exception_end(ctx, EXCP_BREAK);
16228 break;
16229 case SIGRIE:
16230 check_insn(ctx, ISA_MIPS32R6);
16231 generate_exception_end(ctx, EXCP_RI);
16232 break;
16233 default:
16234 pool32a_invalid:
16235 MIPS_INVAL("pool32a");
16236 generate_exception_end(ctx, EXCP_RI);
16237 break;
16238 }
16239 break;
16240 case POOL32B:
16241 minor = (ctx->opcode >> 12) & 0xf;
16242 switch (minor) {
16243 case CACHE:
16244 check_cp0_enabled(ctx);
16245 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16246 gen_cache_operation(ctx, rt, rs, imm);
16247 }
16248 break;
16249 case LWC2:
16250 case SWC2:
16251 /* COP2: Not implemented. */
16252 generate_exception_err(ctx, EXCP_CpU, 2);
16253 break;
16254 #ifdef TARGET_MIPS64
16255 case LDP:
16256 case SDP:
16257 check_insn(ctx, ISA_MIPS3);
16258 check_mips_64(ctx);
16259 #endif
16260 /* fall through */
16261 case LWP:
16262 case SWP:
16263 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16264 break;
16265 #ifdef TARGET_MIPS64
16266 case LDM:
16267 case SDM:
16268 check_insn(ctx, ISA_MIPS3);
16269 check_mips_64(ctx);
16270 #endif
16271 /* fall through */
16272 case LWM32:
16273 case SWM32:
16274 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16275 break;
16276 default:
16277 MIPS_INVAL("pool32b");
16278 generate_exception_end(ctx, EXCP_RI);
16279 break;
16280 }
16281 break;
16282 case POOL32F:
16283 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16284 minor = ctx->opcode & 0x3f;
16285 check_cp1_enabled(ctx);
16286 switch (minor) {
16287 case ALNV_PS:
16288 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16289 mips32_op = OPC_ALNV_PS;
16290 goto do_madd;
16291 case MADD_S:
16292 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16293 mips32_op = OPC_MADD_S;
16294 goto do_madd;
16295 case MADD_D:
16296 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16297 mips32_op = OPC_MADD_D;
16298 goto do_madd;
16299 case MADD_PS:
16300 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16301 mips32_op = OPC_MADD_PS;
16302 goto do_madd;
16303 case MSUB_S:
16304 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16305 mips32_op = OPC_MSUB_S;
16306 goto do_madd;
16307 case MSUB_D:
16308 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16309 mips32_op = OPC_MSUB_D;
16310 goto do_madd;
16311 case MSUB_PS:
16312 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16313 mips32_op = OPC_MSUB_PS;
16314 goto do_madd;
16315 case NMADD_S:
16316 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16317 mips32_op = OPC_NMADD_S;
16318 goto do_madd;
16319 case NMADD_D:
16320 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16321 mips32_op = OPC_NMADD_D;
16322 goto do_madd;
16323 case NMADD_PS:
16324 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16325 mips32_op = OPC_NMADD_PS;
16326 goto do_madd;
16327 case NMSUB_S:
16328 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16329 mips32_op = OPC_NMSUB_S;
16330 goto do_madd;
16331 case NMSUB_D:
16332 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16333 mips32_op = OPC_NMSUB_D;
16334 goto do_madd;
16335 case NMSUB_PS:
16336 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16337 mips32_op = OPC_NMSUB_PS;
16338 do_madd:
16339 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16340 break;
16341 case CABS_COND_FMT:
16342 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16343 cond = (ctx->opcode >> 6) & 0xf;
16344 cc = (ctx->opcode >> 13) & 0x7;
16345 fmt = (ctx->opcode >> 10) & 0x3;
16346 switch (fmt) {
16347 case 0x0:
16348 gen_cmpabs_s(ctx, cond, rt, rs, cc);
16349 break;
16350 case 0x1:
16351 gen_cmpabs_d(ctx, cond, rt, rs, cc);
16352 break;
16353 case 0x2:
16354 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16355 break;
16356 default:
16357 goto pool32f_invalid;
16358 }
16359 break;
16360 case C_COND_FMT:
16361 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16362 cond = (ctx->opcode >> 6) & 0xf;
16363 cc = (ctx->opcode >> 13) & 0x7;
16364 fmt = (ctx->opcode >> 10) & 0x3;
16365 switch (fmt) {
16366 case 0x0:
16367 gen_cmp_s(ctx, cond, rt, rs, cc);
16368 break;
16369 case 0x1:
16370 gen_cmp_d(ctx, cond, rt, rs, cc);
16371 break;
16372 case 0x2:
16373 gen_cmp_ps(ctx, cond, rt, rs, cc);
16374 break;
16375 default:
16376 goto pool32f_invalid;
16377 }
16378 break;
16379 case CMP_CONDN_S:
16380 check_insn(ctx, ISA_MIPS32R6);
16381 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16382 break;
16383 case CMP_CONDN_D:
16384 check_insn(ctx, ISA_MIPS32R6);
16385 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16386 break;
16387 case POOL32FXF:
16388 gen_pool32fxf(ctx, rt, rs);
16389 break;
16390 case 0x00:
16391 /* PLL foo */
16392 switch ((ctx->opcode >> 6) & 0x7) {
16393 case PLL_PS:
16394 mips32_op = OPC_PLL_PS;
16395 goto do_ps;
16396 case PLU_PS:
16397 mips32_op = OPC_PLU_PS;
16398 goto do_ps;
16399 case PUL_PS:
16400 mips32_op = OPC_PUL_PS;
16401 goto do_ps;
16402 case PUU_PS:
16403 mips32_op = OPC_PUU_PS;
16404 goto do_ps;
16405 case CVT_PS_S:
16406 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16407 mips32_op = OPC_CVT_PS_S;
16408 do_ps:
16409 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16410 break;
16411 default:
16412 goto pool32f_invalid;
16413 }
16414 break;
16415 case MIN_FMT:
16416 check_insn(ctx, ISA_MIPS32R6);
16417 switch ((ctx->opcode >> 9) & 0x3) {
16418 case FMT_SDPS_S:
16419 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16420 break;
16421 case FMT_SDPS_D:
16422 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16423 break;
16424 default:
16425 goto pool32f_invalid;
16426 }
16427 break;
16428 case 0x08:
16429 /* [LS][WDU]XC1 */
16430 switch ((ctx->opcode >> 6) & 0x7) {
16431 case LWXC1:
16432 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16433 mips32_op = OPC_LWXC1;
16434 goto do_ldst_cp1;
16435 case SWXC1:
16436 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16437 mips32_op = OPC_SWXC1;
16438 goto do_ldst_cp1;
16439 case LDXC1:
16440 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16441 mips32_op = OPC_LDXC1;
16442 goto do_ldst_cp1;
16443 case SDXC1:
16444 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16445 mips32_op = OPC_SDXC1;
16446 goto do_ldst_cp1;
16447 case LUXC1:
16448 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16449 mips32_op = OPC_LUXC1;
16450 goto do_ldst_cp1;
16451 case SUXC1:
16452 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16453 mips32_op = OPC_SUXC1;
16454 do_ldst_cp1:
16455 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16456 break;
16457 default:
16458 goto pool32f_invalid;
16459 }
16460 break;
16461 case MAX_FMT:
16462 check_insn(ctx, ISA_MIPS32R6);
16463 switch ((ctx->opcode >> 9) & 0x3) {
16464 case FMT_SDPS_S:
16465 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16466 break;
16467 case FMT_SDPS_D:
16468 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16469 break;
16470 default:
16471 goto pool32f_invalid;
16472 }
16473 break;
16474 case 0x18:
16475 /* 3D insns */
16476 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16477 fmt = (ctx->opcode >> 9) & 0x3;
16478 switch ((ctx->opcode >> 6) & 0x7) {
16479 case RSQRT2_FMT:
16480 switch (fmt) {
16481 case FMT_SDPS_S:
16482 mips32_op = OPC_RSQRT2_S;
16483 goto do_3d;
16484 case FMT_SDPS_D:
16485 mips32_op = OPC_RSQRT2_D;
16486 goto do_3d;
16487 case FMT_SDPS_PS:
16488 mips32_op = OPC_RSQRT2_PS;
16489 goto do_3d;
16490 default:
16491 goto pool32f_invalid;
16492 }
16493 break;
16494 case RECIP2_FMT:
16495 switch (fmt) {
16496 case FMT_SDPS_S:
16497 mips32_op = OPC_RECIP2_S;
16498 goto do_3d;
16499 case FMT_SDPS_D:
16500 mips32_op = OPC_RECIP2_D;
16501 goto do_3d;
16502 case FMT_SDPS_PS:
16503 mips32_op = OPC_RECIP2_PS;
16504 goto do_3d;
16505 default:
16506 goto pool32f_invalid;
16507 }
16508 break;
16509 case ADDR_PS:
16510 mips32_op = OPC_ADDR_PS;
16511 goto do_3d;
16512 case MULR_PS:
16513 mips32_op = OPC_MULR_PS;
16514 do_3d:
16515 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16516 break;
16517 default:
16518 goto pool32f_invalid;
16519 }
16520 break;
16521 case 0x20:
16522 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16523 cc = (ctx->opcode >> 13) & 0x7;
16524 fmt = (ctx->opcode >> 9) & 0x3;
16525 switch ((ctx->opcode >> 6) & 0x7) {
16526 case MOVF_FMT: /* RINT_FMT */
16527 if (ctx->insn_flags & ISA_MIPS32R6) {
16528 /* RINT_FMT */
16529 switch (fmt) {
16530 case FMT_SDPS_S:
16531 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16532 break;
16533 case FMT_SDPS_D:
16534 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16535 break;
16536 default:
16537 goto pool32f_invalid;
16538 }
16539 } else {
16540 /* MOVF_FMT */
16541 switch (fmt) {
16542 case FMT_SDPS_S:
16543 gen_movcf_s(ctx, rs, rt, cc, 0);
16544 break;
16545 case FMT_SDPS_D:
16546 gen_movcf_d(ctx, rs, rt, cc, 0);
16547 break;
16548 case FMT_SDPS_PS:
16549 check_ps(ctx);
16550 gen_movcf_ps(ctx, rs, rt, cc, 0);
16551 break;
16552 default:
16553 goto pool32f_invalid;
16554 }
16555 }
16556 break;
16557 case MOVT_FMT: /* CLASS_FMT */
16558 if (ctx->insn_flags & ISA_MIPS32R6) {
16559 /* CLASS_FMT */
16560 switch (fmt) {
16561 case FMT_SDPS_S:
16562 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16563 break;
16564 case FMT_SDPS_D:
16565 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16566 break;
16567 default:
16568 goto pool32f_invalid;
16569 }
16570 } else {
16571 /* MOVT_FMT */
16572 switch (fmt) {
16573 case FMT_SDPS_S:
16574 gen_movcf_s(ctx, rs, rt, cc, 1);
16575 break;
16576 case FMT_SDPS_D:
16577 gen_movcf_d(ctx, rs, rt, cc, 1);
16578 break;
16579 case FMT_SDPS_PS:
16580 check_ps(ctx);
16581 gen_movcf_ps(ctx, rs, rt, cc, 1);
16582 break;
16583 default:
16584 goto pool32f_invalid;
16585 }
16586 }
16587 break;
16588 case PREFX:
16589 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16590 break;
16591 default:
16592 goto pool32f_invalid;
16593 }
16594 break;
16595 #define FINSN_3ARG_SDPS(prfx) \
16596 switch ((ctx->opcode >> 8) & 0x3) { \
16597 case FMT_SDPS_S: \
16598 mips32_op = OPC_##prfx##_S; \
16599 goto do_fpop; \
16600 case FMT_SDPS_D: \
16601 mips32_op = OPC_##prfx##_D; \
16602 goto do_fpop; \
16603 case FMT_SDPS_PS: \
16604 check_ps(ctx); \
16605 mips32_op = OPC_##prfx##_PS; \
16606 goto do_fpop; \
16607 default: \
16608 goto pool32f_invalid; \
16609 }
16610 case MINA_FMT:
16611 check_insn(ctx, ISA_MIPS32R6);
16612 switch ((ctx->opcode >> 9) & 0x3) {
16613 case FMT_SDPS_S:
16614 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16615 break;
16616 case FMT_SDPS_D:
16617 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16618 break;
16619 default:
16620 goto pool32f_invalid;
16621 }
16622 break;
16623 case MAXA_FMT:
16624 check_insn(ctx, ISA_MIPS32R6);
16625 switch ((ctx->opcode >> 9) & 0x3) {
16626 case FMT_SDPS_S:
16627 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16628 break;
16629 case FMT_SDPS_D:
16630 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16631 break;
16632 default:
16633 goto pool32f_invalid;
16634 }
16635 break;
16636 case 0x30:
16637 /* regular FP ops */
16638 switch ((ctx->opcode >> 6) & 0x3) {
16639 case ADD_FMT:
16640 FINSN_3ARG_SDPS(ADD);
16641 break;
16642 case SUB_FMT:
16643 FINSN_3ARG_SDPS(SUB);
16644 break;
16645 case MUL_FMT:
16646 FINSN_3ARG_SDPS(MUL);
16647 break;
16648 case DIV_FMT:
16649 fmt = (ctx->opcode >> 8) & 0x3;
16650 if (fmt == 1) {
16651 mips32_op = OPC_DIV_D;
16652 } else if (fmt == 0) {
16653 mips32_op = OPC_DIV_S;
16654 } else {
16655 goto pool32f_invalid;
16656 }
16657 goto do_fpop;
16658 default:
16659 goto pool32f_invalid;
16660 }
16661 break;
16662 case 0x38:
16663 /* cmovs */
16664 switch ((ctx->opcode >> 6) & 0x7) {
16665 case MOVN_FMT: /* SELEQZ_FMT */
16666 if (ctx->insn_flags & ISA_MIPS32R6) {
16667 /* SELEQZ_FMT */
16668 switch ((ctx->opcode >> 9) & 0x3) {
16669 case FMT_SDPS_S:
16670 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16671 break;
16672 case FMT_SDPS_D:
16673 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16674 break;
16675 default:
16676 goto pool32f_invalid;
16677 }
16678 } else {
16679 /* MOVN_FMT */
16680 FINSN_3ARG_SDPS(MOVN);
16681 }
16682 break;
16683 case MOVN_FMT_04:
16684 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16685 FINSN_3ARG_SDPS(MOVN);
16686 break;
16687 case MOVZ_FMT: /* SELNEZ_FMT */
16688 if (ctx->insn_flags & ISA_MIPS32R6) {
16689 /* SELNEZ_FMT */
16690 switch ((ctx->opcode >> 9) & 0x3) {
16691 case FMT_SDPS_S:
16692 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16693 break;
16694 case FMT_SDPS_D:
16695 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16696 break;
16697 default:
16698 goto pool32f_invalid;
16699 }
16700 } else {
16701 /* MOVZ_FMT */
16702 FINSN_3ARG_SDPS(MOVZ);
16703 }
16704 break;
16705 case MOVZ_FMT_05:
16706 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16707 FINSN_3ARG_SDPS(MOVZ);
16708 break;
16709 case SEL_FMT:
16710 check_insn(ctx, ISA_MIPS32R6);
16711 switch ((ctx->opcode >> 9) & 0x3) {
16712 case FMT_SDPS_S:
16713 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16714 break;
16715 case FMT_SDPS_D:
16716 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16717 break;
16718 default:
16719 goto pool32f_invalid;
16720 }
16721 break;
16722 case MADDF_FMT:
16723 check_insn(ctx, ISA_MIPS32R6);
16724 switch ((ctx->opcode >> 9) & 0x3) {
16725 case FMT_SDPS_S:
16726 mips32_op = OPC_MADDF_S;
16727 goto do_fpop;
16728 case FMT_SDPS_D:
16729 mips32_op = OPC_MADDF_D;
16730 goto do_fpop;
16731 default:
16732 goto pool32f_invalid;
16733 }
16734 break;
16735 case MSUBF_FMT:
16736 check_insn(ctx, ISA_MIPS32R6);
16737 switch ((ctx->opcode >> 9) & 0x3) {
16738 case FMT_SDPS_S:
16739 mips32_op = OPC_MSUBF_S;
16740 goto do_fpop;
16741 case FMT_SDPS_D:
16742 mips32_op = OPC_MSUBF_D;
16743 goto do_fpop;
16744 default:
16745 goto pool32f_invalid;
16746 }
16747 break;
16748 default:
16749 goto pool32f_invalid;
16750 }
16751 break;
16752 do_fpop:
16753 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16754 break;
16755 default:
16756 pool32f_invalid:
16757 MIPS_INVAL("pool32f");
16758 generate_exception_end(ctx, EXCP_RI);
16759 break;
16760 }
16761 } else {
16762 generate_exception_err(ctx, EXCP_CpU, 1);
16763 }
16764 break;
16765 case POOL32I:
16766 minor = (ctx->opcode >> 21) & 0x1f;
16767 switch (minor) {
16768 case BLTZ:
16769 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16770 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16771 break;
16772 case BLTZAL:
16773 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16774 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16775 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16776 break;
16777 case BLTZALS:
16778 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16779 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16780 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16781 break;
16782 case BGEZ:
16783 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16784 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16785 break;
16786 case BGEZAL:
16787 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16788 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16789 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16790 break;
16791 case BGEZALS:
16792 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16793 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16794 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16795 break;
16796 case BLEZ:
16797 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16798 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16799 break;
16800 case BGTZ:
16801 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16802 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16803 break;
16804
16805 /* Traps */
16806 case TLTI: /* BC1EQZC */
16807 if (ctx->insn_flags & ISA_MIPS32R6) {
16808 /* BC1EQZC */
16809 check_cp1_enabled(ctx);
16810 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16811 } else {
16812 /* TLTI */
16813 mips32_op = OPC_TLTI;
16814 goto do_trapi;
16815 }
16816 break;
16817 case TGEI: /* BC1NEZC */
16818 if (ctx->insn_flags & ISA_MIPS32R6) {
16819 /* BC1NEZC */
16820 check_cp1_enabled(ctx);
16821 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16822 } else {
16823 /* TGEI */
16824 mips32_op = OPC_TGEI;
16825 goto do_trapi;
16826 }
16827 break;
16828 case TLTIU:
16829 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16830 mips32_op = OPC_TLTIU;
16831 goto do_trapi;
16832 case TGEIU:
16833 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16834 mips32_op = OPC_TGEIU;
16835 goto do_trapi;
16836 case TNEI: /* SYNCI */
16837 if (ctx->insn_flags & ISA_MIPS32R6) {
16838 /* SYNCI */
16839 /*
16840 * Break the TB to be able to sync copied instructions
16841 * immediately.
16842 */
16843 ctx->base.is_jmp = DISAS_STOP;
16844 } else {
16845 /* TNEI */
16846 mips32_op = OPC_TNEI;
16847 goto do_trapi;
16848 }
16849 break;
16850 case TEQI:
16851 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16852 mips32_op = OPC_TEQI;
16853 do_trapi:
16854 gen_trap(ctx, mips32_op, rs, -1, imm);
16855 break;
16856
16857 case BNEZC:
16858 case BEQZC:
16859 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16860 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16861 4, rs, 0, imm << 1, 0);
16862 /*
16863 * Compact branches don't have a delay slot, so just let
16864 * the normal delay slot handling take us to the branch
16865 * target.
16866 */
16867 break;
16868 case LUI:
16869 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16870 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16871 break;
16872 case SYNCI:
16873 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16874 /*
16875 * Break the TB to be able to sync copied instructions
16876 * immediately.
16877 */
16878 ctx->base.is_jmp = DISAS_STOP;
16879 break;
16880 case BC2F:
16881 case BC2T:
16882 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16883 /* COP2: Not implemented. */
16884 generate_exception_err(ctx, EXCP_CpU, 2);
16885 break;
16886 case BC1F:
16887 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16888 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16889 goto do_cp1branch;
16890 case BC1T:
16891 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16892 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16893 goto do_cp1branch;
16894 case BC1ANY4F:
16895 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16896 mips32_op = OPC_BC1FANY4;
16897 goto do_cp1mips3d;
16898 case BC1ANY4T:
16899 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16900 mips32_op = OPC_BC1TANY4;
16901 do_cp1mips3d:
16902 check_cop1x(ctx);
16903 check_insn(ctx, ASE_MIPS3D);
16904 /* Fall through */
16905 do_cp1branch:
16906 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16907 check_cp1_enabled(ctx);
16908 gen_compute_branch1(ctx, mips32_op,
16909 (ctx->opcode >> 18) & 0x7, imm << 1);
16910 } else {
16911 generate_exception_err(ctx, EXCP_CpU, 1);
16912 }
16913 break;
16914 case BPOSGE64:
16915 case BPOSGE32:
16916 /* MIPS DSP: not implemented */
16917 /* Fall through */
16918 default:
16919 MIPS_INVAL("pool32i");
16920 generate_exception_end(ctx, EXCP_RI);
16921 break;
16922 }
16923 break;
16924 case POOL32C:
16925 minor = (ctx->opcode >> 12) & 0xf;
16926 offset = sextract32(ctx->opcode, 0,
16927 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16928 switch (minor) {
16929 case LWL:
16930 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16931 mips32_op = OPC_LWL;
16932 goto do_ld_lr;
16933 case SWL:
16934 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16935 mips32_op = OPC_SWL;
16936 goto do_st_lr;
16937 case LWR:
16938 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16939 mips32_op = OPC_LWR;
16940 goto do_ld_lr;
16941 case SWR:
16942 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16943 mips32_op = OPC_SWR;
16944 goto do_st_lr;
16945 #if defined(TARGET_MIPS64)
16946 case LDL:
16947 check_insn(ctx, ISA_MIPS3);
16948 check_mips_64(ctx);
16949 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16950 mips32_op = OPC_LDL;
16951 goto do_ld_lr;
16952 case SDL:
16953 check_insn(ctx, ISA_MIPS3);
16954 check_mips_64(ctx);
16955 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16956 mips32_op = OPC_SDL;
16957 goto do_st_lr;
16958 case LDR:
16959 check_insn(ctx, ISA_MIPS3);
16960 check_mips_64(ctx);
16961 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16962 mips32_op = OPC_LDR;
16963 goto do_ld_lr;
16964 case SDR:
16965 check_insn(ctx, ISA_MIPS3);
16966 check_mips_64(ctx);
16967 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16968 mips32_op = OPC_SDR;
16969 goto do_st_lr;
16970 case LWU:
16971 check_insn(ctx, ISA_MIPS3);
16972 check_mips_64(ctx);
16973 mips32_op = OPC_LWU;
16974 goto do_ld_lr;
16975 case LLD:
16976 check_insn(ctx, ISA_MIPS3);
16977 check_mips_64(ctx);
16978 mips32_op = OPC_LLD;
16979 goto do_ld_lr;
16980 #endif
16981 case LL:
16982 mips32_op = OPC_LL;
16983 goto do_ld_lr;
16984 do_ld_lr:
16985 gen_ld(ctx, mips32_op, rt, rs, offset);
16986 break;
16987 do_st_lr:
16988 gen_st(ctx, mips32_op, rt, rs, offset);
16989 break;
16990 case SC:
16991 gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
16992 break;
16993 #if defined(TARGET_MIPS64)
16994 case SCD:
16995 check_insn(ctx, ISA_MIPS3);
16996 check_mips_64(ctx);
16997 gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
16998 break;
16999 #endif
17000 case LD_EVA:
17001 if (!ctx->eva) {
17002 MIPS_INVAL("pool32c ld-eva");
17003 generate_exception_end(ctx, EXCP_RI);
17004 break;
17005 }
17006 check_cp0_enabled(ctx);
17007
17008 minor2 = (ctx->opcode >> 9) & 0x7;
17009 offset = sextract32(ctx->opcode, 0, 9);
17010 switch (minor2) {
17011 case LBUE:
17012 mips32_op = OPC_LBUE;
17013 goto do_ld_lr;
17014 case LHUE:
17015 mips32_op = OPC_LHUE;
17016 goto do_ld_lr;
17017 case LWLE:
17018 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17019 mips32_op = OPC_LWLE;
17020 goto do_ld_lr;
17021 case LWRE:
17022 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17023 mips32_op = OPC_LWRE;
17024 goto do_ld_lr;
17025 case LBE:
17026 mips32_op = OPC_LBE;
17027 goto do_ld_lr;
17028 case LHE:
17029 mips32_op = OPC_LHE;
17030 goto do_ld_lr;
17031 case LLE:
17032 mips32_op = OPC_LLE;
17033 goto do_ld_lr;
17034 case LWE:
17035 mips32_op = OPC_LWE;
17036 goto do_ld_lr;
17037 };
17038 break;
17039 case ST_EVA:
17040 if (!ctx->eva) {
17041 MIPS_INVAL("pool32c st-eva");
17042 generate_exception_end(ctx, EXCP_RI);
17043 break;
17044 }
17045 check_cp0_enabled(ctx);
17046
17047 minor2 = (ctx->opcode >> 9) & 0x7;
17048 offset = sextract32(ctx->opcode, 0, 9);
17049 switch (minor2) {
17050 case SWLE:
17051 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17052 mips32_op = OPC_SWLE;
17053 goto do_st_lr;
17054 case SWRE:
17055 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17056 mips32_op = OPC_SWRE;
17057 goto do_st_lr;
17058 case PREFE:
17059 /* Treat as no-op */
17060 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17061 /* hint codes 24-31 are reserved and signal RI */
17062 generate_exception(ctx, EXCP_RI);
17063 }
17064 break;
17065 case CACHEE:
17066 /* Treat as no-op */
17067 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17068 gen_cache_operation(ctx, rt, rs, offset);
17069 }
17070 break;
17071 case SBE:
17072 mips32_op = OPC_SBE;
17073 goto do_st_lr;
17074 case SHE:
17075 mips32_op = OPC_SHE;
17076 goto do_st_lr;
17077 case SCE:
17078 gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
17079 break;
17080 case SWE:
17081 mips32_op = OPC_SWE;
17082 goto do_st_lr;
17083 };
17084 break;
17085 case PREF:
17086 /* Treat as no-op */
17087 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17088 /* hint codes 24-31 are reserved and signal RI */
17089 generate_exception(ctx, EXCP_RI);
17090 }
17091 break;
17092 default:
17093 MIPS_INVAL("pool32c");
17094 generate_exception_end(ctx, EXCP_RI);
17095 break;
17096 }
17097 break;
17098 case ADDI32: /* AUI, LUI */
17099 if (ctx->insn_flags & ISA_MIPS32R6) {
17100 /* AUI, LUI */
17101 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
17102 } else {
17103 /* ADDI32 */
17104 mips32_op = OPC_ADDI;
17105 goto do_addi;
17106 }
17107 break;
17108 case ADDIU32:
17109 mips32_op = OPC_ADDIU;
17110 do_addi:
17111 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
17112 break;
17113
17114 /* Logical operations */
17115 case ORI32:
17116 mips32_op = OPC_ORI;
17117 goto do_logici;
17118 case XORI32:
17119 mips32_op = OPC_XORI;
17120 goto do_logici;
17121 case ANDI32:
17122 mips32_op = OPC_ANDI;
17123 do_logici:
17124 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
17125 break;
17126
17127 /* Set less than immediate */
17128 case SLTI32:
17129 mips32_op = OPC_SLTI;
17130 goto do_slti;
17131 case SLTIU32:
17132 mips32_op = OPC_SLTIU;
17133 do_slti:
17134 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
17135 break;
17136 case JALX32:
17137 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17138 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17139 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
17140 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17141 break;
17142 case JALS32: /* BOVC, BEQC, BEQZALC */
17143 if (ctx->insn_flags & ISA_MIPS32R6) {
17144 if (rs >= rt) {
17145 /* BOVC */
17146 mips32_op = OPC_BOVC;
17147 } else if (rs < rt && rs == 0) {
17148 /* BEQZALC */
17149 mips32_op = OPC_BEQZALC;
17150 } else {
17151 /* BEQC */
17152 mips32_op = OPC_BEQC;
17153 }
17154 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17155 } else {
17156 /* JALS32 */
17157 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17158 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17159 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17160 }
17161 break;
17162 case BEQ32: /* BC */
17163 if (ctx->insn_flags & ISA_MIPS32R6) {
17164 /* BC */
17165 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17166 sextract32(ctx->opcode << 1, 0, 27));
17167 } else {
17168 /* BEQ32 */
17169 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17170 }
17171 break;
17172 case BNE32: /* BALC */
17173 if (ctx->insn_flags & ISA_MIPS32R6) {
17174 /* BALC */
17175 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17176 sextract32(ctx->opcode << 1, 0, 27));
17177 } else {
17178 /* BNE32 */
17179 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17180 }
17181 break;
17182 case J32: /* BGTZC, BLTZC, BLTC */
17183 if (ctx->insn_flags & ISA_MIPS32R6) {
17184 if (rs == 0 && rt != 0) {
17185 /* BGTZC */
17186 mips32_op = OPC_BGTZC;
17187 } else if (rs != 0 && rt != 0 && rs == rt) {
17188 /* BLTZC */
17189 mips32_op = OPC_BLTZC;
17190 } else {
17191 /* BLTC */
17192 mips32_op = OPC_BLTC;
17193 }
17194 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17195 } else {
17196 /* J32 */
17197 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17198 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17199 }
17200 break;
17201 case JAL32: /* BLEZC, BGEZC, BGEC */
17202 if (ctx->insn_flags & ISA_MIPS32R6) {
17203 if (rs == 0 && rt != 0) {
17204 /* BLEZC */
17205 mips32_op = OPC_BLEZC;
17206 } else if (rs != 0 && rt != 0 && rs == rt) {
17207 /* BGEZC */
17208 mips32_op = OPC_BGEZC;
17209 } else {
17210 /* BGEC */
17211 mips32_op = OPC_BGEC;
17212 }
17213 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17214 } else {
17215 /* JAL32 */
17216 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17217 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17218 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17219 }
17220 break;
17221 /* Floating point (COP1) */
17222 case LWC132:
17223 mips32_op = OPC_LWC1;
17224 goto do_cop1;
17225 case LDC132:
17226 mips32_op = OPC_LDC1;
17227 goto do_cop1;
17228 case SWC132:
17229 mips32_op = OPC_SWC1;
17230 goto do_cop1;
17231 case SDC132:
17232 mips32_op = OPC_SDC1;
17233 do_cop1:
17234 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17235 break;
17236 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17237 if (ctx->insn_flags & ISA_MIPS32R6) {
17238 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17239 switch ((ctx->opcode >> 16) & 0x1f) {
17240 case ADDIUPC_00:
17241 case ADDIUPC_01:
17242 case ADDIUPC_02:
17243 case ADDIUPC_03:
17244 case ADDIUPC_04:
17245 case ADDIUPC_05:
17246 case ADDIUPC_06:
17247 case ADDIUPC_07:
17248 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17249 break;
17250 case AUIPC:
17251 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17252 break;
17253 case ALUIPC:
17254 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17255 break;
17256 case LWPC_08:
17257 case LWPC_09:
17258 case LWPC_0A:
17259 case LWPC_0B:
17260 case LWPC_0C:
17261 case LWPC_0D:
17262 case LWPC_0E:
17263 case LWPC_0F:
17264 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17265 break;
17266 default:
17267 generate_exception(ctx, EXCP_RI);
17268 break;
17269 }
17270 } else {
17271 /* ADDIUPC */
17272 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17273 offset = SIMM(ctx->opcode, 0, 23) << 2;
17274
17275 gen_addiupc(ctx, reg, offset, 0, 0);
17276 }
17277 break;
17278 case BNVC: /* BNEC, BNEZALC */
17279 check_insn(ctx, ISA_MIPS32R6);
17280 if (rs >= rt) {
17281 /* BNVC */
17282 mips32_op = OPC_BNVC;
17283 } else if (rs < rt && rs == 0) {
17284 /* BNEZALC */
17285 mips32_op = OPC_BNEZALC;
17286 } else {
17287 /* BNEC */
17288 mips32_op = OPC_BNEC;
17289 }
17290 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17291 break;
17292 case R6_BNEZC: /* JIALC */
17293 check_insn(ctx, ISA_MIPS32R6);
17294 if (rt != 0) {
17295 /* BNEZC */
17296 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17297 sextract32(ctx->opcode << 1, 0, 22));
17298 } else {
17299 /* JIALC */
17300 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17301 }
17302 break;
17303 case R6_BEQZC: /* JIC */
17304 check_insn(ctx, ISA_MIPS32R6);
17305 if (rt != 0) {
17306 /* BEQZC */
17307 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17308 sextract32(ctx->opcode << 1, 0, 22));
17309 } else {
17310 /* JIC */
17311 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17312 }
17313 break;
17314 case BLEZALC: /* BGEZALC, BGEUC */
17315 check_insn(ctx, ISA_MIPS32R6);
17316 if (rs == 0 && rt != 0) {
17317 /* BLEZALC */
17318 mips32_op = OPC_BLEZALC;
17319 } else if (rs != 0 && rt != 0 && rs == rt) {
17320 /* BGEZALC */
17321 mips32_op = OPC_BGEZALC;
17322 } else {
17323 /* BGEUC */
17324 mips32_op = OPC_BGEUC;
17325 }
17326 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17327 break;
17328 case BGTZALC: /* BLTZALC, BLTUC */
17329 check_insn(ctx, ISA_MIPS32R6);
17330 if (rs == 0 && rt != 0) {
17331 /* BGTZALC */
17332 mips32_op = OPC_BGTZALC;
17333 } else if (rs != 0 && rt != 0 && rs == rt) {
17334 /* BLTZALC */
17335 mips32_op = OPC_BLTZALC;
17336 } else {
17337 /* BLTUC */
17338 mips32_op = OPC_BLTUC;
17339 }
17340 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17341 break;
17342 /* Loads and stores */
17343 case LB32:
17344 mips32_op = OPC_LB;
17345 goto do_ld;
17346 case LBU32:
17347 mips32_op = OPC_LBU;
17348 goto do_ld;
17349 case LH32:
17350 mips32_op = OPC_LH;
17351 goto do_ld;
17352 case LHU32:
17353 mips32_op = OPC_LHU;
17354 goto do_ld;
17355 case LW32:
17356 mips32_op = OPC_LW;
17357 goto do_ld;
17358 #ifdef TARGET_MIPS64
17359 case LD32:
17360 check_insn(ctx, ISA_MIPS3);
17361 check_mips_64(ctx);
17362 mips32_op = OPC_LD;
17363 goto do_ld;
17364 case SD32:
17365 check_insn(ctx, ISA_MIPS3);
17366 check_mips_64(ctx);
17367 mips32_op = OPC_SD;
17368 goto do_st;
17369 #endif
17370 case SB32:
17371 mips32_op = OPC_SB;
17372 goto do_st;
17373 case SH32:
17374 mips32_op = OPC_SH;
17375 goto do_st;
17376 case SW32:
17377 mips32_op = OPC_SW;
17378 goto do_st;
17379 do_ld:
17380 gen_ld(ctx, mips32_op, rt, rs, imm);
17381 break;
17382 do_st:
17383 gen_st(ctx, mips32_op, rt, rs, imm);
17384 break;
17385 default:
17386 generate_exception_end(ctx, EXCP_RI);
17387 break;
17388 }
17389 }
17390
17391 static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx)
17392 {
17393 uint32_t op;
17394
17395 /* make sure instructions are on a halfword boundary */
17396 if (ctx->base.pc_next & 0x1) {
17397 env->CP0_BadVAddr = ctx->base.pc_next;
17398 generate_exception_end(ctx, EXCP_AdEL);
17399 return 2;
17400 }
17401
17402 op = (ctx->opcode >> 10) & 0x3f;
17403 /* Enforce properly-sized instructions in a delay slot */
17404 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17405 switch (op & 0x7) { /* MSB-3..MSB-5 */
17406 case 0:
17407 /* POOL32A, POOL32B, POOL32I, POOL32C */
17408 case 4:
17409 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17410 case 5:
17411 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17412 case 6:
17413 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17414 case 7:
17415 /* LB32, LH32, LWC132, LDC132, LW32 */
17416 if (ctx->hflags & MIPS_HFLAG_BDS16) {
17417 generate_exception_end(ctx, EXCP_RI);
17418 return 2;
17419 }
17420 break;
17421 case 1:
17422 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17423 case 2:
17424 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17425 case 3:
17426 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17427 if (ctx->hflags & MIPS_HFLAG_BDS32) {
17428 generate_exception_end(ctx, EXCP_RI);
17429 return 2;
17430 }
17431 break;
17432 }
17433 }
17434
17435 switch (op) {
17436 case POOL16A:
17437 {
17438 int rd = mmreg(uMIPS_RD(ctx->opcode));
17439 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17440 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17441 uint32_t opc = 0;
17442
17443 switch (ctx->opcode & 0x1) {
17444 case ADDU16:
17445 opc = OPC_ADDU;
17446 break;
17447 case SUBU16:
17448 opc = OPC_SUBU;
17449 break;
17450 }
17451 if (ctx->insn_flags & ISA_MIPS32R6) {
17452 /*
17453 * In the Release 6, the register number location in
17454 * the instruction encoding has changed.
17455 */
17456 gen_arith(ctx, opc, rs1, rd, rs2);
17457 } else {
17458 gen_arith(ctx, opc, rd, rs1, rs2);
17459 }
17460 }
17461 break;
17462 case POOL16B:
17463 {
17464 int rd = mmreg(uMIPS_RD(ctx->opcode));
17465 int rs = mmreg(uMIPS_RS(ctx->opcode));
17466 int amount = (ctx->opcode >> 1) & 0x7;
17467 uint32_t opc = 0;
17468 amount = amount == 0 ? 8 : amount;
17469
17470 switch (ctx->opcode & 0x1) {
17471 case SLL16:
17472 opc = OPC_SLL;
17473 break;
17474 case SRL16:
17475 opc = OPC_SRL;
17476 break;
17477 }
17478
17479 gen_shift_imm(ctx, opc, rd, rs, amount);
17480 }
17481 break;
17482 case POOL16C:
17483 if (ctx->insn_flags & ISA_MIPS32R6) {
17484 gen_pool16c_r6_insn(ctx);
17485 } else {
17486 gen_pool16c_insn(ctx);
17487 }
17488 break;
17489 case LWGP16:
17490 {
17491 int rd = mmreg(uMIPS_RD(ctx->opcode));
17492 int rb = 28; /* GP */
17493 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17494
17495 gen_ld(ctx, OPC_LW, rd, rb, offset);
17496 }
17497 break;
17498 case POOL16F:
17499 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17500 if (ctx->opcode & 1) {
17501 generate_exception_end(ctx, EXCP_RI);
17502 } else {
17503 /* MOVEP */
17504 int enc_dest = uMIPS_RD(ctx->opcode);
17505 int enc_rt = uMIPS_RS2(ctx->opcode);
17506 int enc_rs = uMIPS_RS1(ctx->opcode);
17507 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17508 }
17509 break;
17510 case LBU16:
17511 {
17512 int rd = mmreg(uMIPS_RD(ctx->opcode));
17513 int rb = mmreg(uMIPS_RS(ctx->opcode));
17514 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17515 offset = (offset == 0xf ? -1 : offset);
17516
17517 gen_ld(ctx, OPC_LBU, rd, rb, offset);
17518 }
17519 break;
17520 case LHU16:
17521 {
17522 int rd = mmreg(uMIPS_RD(ctx->opcode));
17523 int rb = mmreg(uMIPS_RS(ctx->opcode));
17524 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17525
17526 gen_ld(ctx, OPC_LHU, rd, rb, offset);
17527 }
17528 break;
17529 case LWSP16:
17530 {
17531 int rd = (ctx->opcode >> 5) & 0x1f;
17532 int rb = 29; /* SP */
17533 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17534
17535 gen_ld(ctx, OPC_LW, rd, rb, offset);
17536 }
17537 break;
17538 case LW16:
17539 {
17540 int rd = mmreg(uMIPS_RD(ctx->opcode));
17541 int rb = mmreg(uMIPS_RS(ctx->opcode));
17542 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17543
17544 gen_ld(ctx, OPC_LW, rd, rb, offset);
17545 }
17546 break;
17547 case SB16:
17548 {
17549 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17550 int rb = mmreg(uMIPS_RS(ctx->opcode));
17551 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17552
17553 gen_st(ctx, OPC_SB, rd, rb, offset);
17554 }
17555 break;
17556 case SH16:
17557 {
17558 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17559 int rb = mmreg(uMIPS_RS(ctx->opcode));
17560 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17561
17562 gen_st(ctx, OPC_SH, rd, rb, offset);
17563 }
17564 break;
17565 case SWSP16:
17566 {
17567 int rd = (ctx->opcode >> 5) & 0x1f;
17568 int rb = 29; /* SP */
17569 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17570
17571 gen_st(ctx, OPC_SW, rd, rb, offset);
17572 }
17573 break;
17574 case SW16:
17575 {
17576 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17577 int rb = mmreg(uMIPS_RS(ctx->opcode));
17578 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17579
17580 gen_st(ctx, OPC_SW, rd, rb, offset);
17581 }
17582 break;
17583 case MOVE16:
17584 {
17585 int rd = uMIPS_RD5(ctx->opcode);
17586 int rs = uMIPS_RS5(ctx->opcode);
17587
17588 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17589 }
17590 break;
17591 case ANDI16:
17592 gen_andi16(ctx);
17593 break;
17594 case POOL16D:
17595 switch (ctx->opcode & 0x1) {
17596 case ADDIUS5:
17597 gen_addius5(ctx);
17598 break;
17599 case ADDIUSP:
17600 gen_addiusp(ctx);
17601 break;
17602 }
17603 break;
17604 case POOL16E:
17605 switch (ctx->opcode & 0x1) {
17606 case ADDIUR2:
17607 gen_addiur2(ctx);
17608 break;
17609 case ADDIUR1SP:
17610 gen_addiur1sp(ctx);
17611 break;
17612 }
17613 break;
17614 case B16: /* BC16 */
17615 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17616 sextract32(ctx->opcode, 0, 10) << 1,
17617 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17618 break;
17619 case BNEZ16: /* BNEZC16 */
17620 case BEQZ16: /* BEQZC16 */
17621 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17622 mmreg(uMIPS_RD(ctx->opcode)),
17623 0, sextract32(ctx->opcode, 0, 7) << 1,
17624 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17625
17626 break;
17627 case LI16:
17628 {
17629 int reg = mmreg(uMIPS_RD(ctx->opcode));
17630 int imm = ZIMM(ctx->opcode, 0, 7);
17631
17632 imm = (imm == 0x7f ? -1 : imm);
17633 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17634 }
17635 break;
17636 case RES_29:
17637 case RES_31:
17638 case RES_39:
17639 generate_exception_end(ctx, EXCP_RI);
17640 break;
17641 default:
17642 decode_micromips32_opc(env, ctx);
17643 return 4;
17644 }
17645
17646 return 2;
17647 }
17648
17649 /*
17650 *
17651 * nanoMIPS opcodes
17652 *
17653 */
17654
17655 /* MAJOR, P16, and P32 pools opcodes */
17656 enum {
17657 NM_P_ADDIU = 0x00,
17658 NM_ADDIUPC = 0x01,
17659 NM_MOVE_BALC = 0x02,
17660 NM_P16_MV = 0x04,
17661 NM_LW16 = 0x05,
17662 NM_BC16 = 0x06,
17663 NM_P16_SR = 0x07,
17664
17665 NM_POOL32A = 0x08,
17666 NM_P_BAL = 0x0a,
17667 NM_P16_SHIFT = 0x0c,
17668 NM_LWSP16 = 0x0d,
17669 NM_BALC16 = 0x0e,
17670 NM_P16_4X4 = 0x0f,
17671
17672 NM_P_GP_W = 0x10,
17673 NM_P_GP_BH = 0x11,
17674 NM_P_J = 0x12,
17675 NM_P16C = 0x14,
17676 NM_LWGP16 = 0x15,
17677 NM_P16_LB = 0x17,
17678
17679 NM_P48I = 0x18,
17680 NM_P16_A1 = 0x1c,
17681 NM_LW4X4 = 0x1d,
17682 NM_P16_LH = 0x1f,
17683
17684 NM_P_U12 = 0x20,
17685 NM_P_LS_U12 = 0x21,
17686 NM_P_BR1 = 0x22,
17687 NM_P16_A2 = 0x24,
17688 NM_SW16 = 0x25,
17689 NM_BEQZC16 = 0x26,
17690
17691 NM_POOL32F = 0x28,
17692 NM_P_LS_S9 = 0x29,
17693 NM_P_BR2 = 0x2a,
17694
17695 NM_P16_ADDU = 0x2c,
17696 NM_SWSP16 = 0x2d,
17697 NM_BNEZC16 = 0x2e,
17698 NM_MOVEP = 0x2f,
17699
17700 NM_POOL32S = 0x30,
17701 NM_P_BRI = 0x32,
17702 NM_LI16 = 0x34,
17703 NM_SWGP16 = 0x35,
17704 NM_P16_BR = 0x36,
17705
17706 NM_P_LUI = 0x38,
17707 NM_ANDI16 = 0x3c,
17708 NM_SW4X4 = 0x3d,
17709 NM_MOVEPREV = 0x3f,
17710 };
17711
17712 /* POOL32A instruction pool */
17713 enum {
17714 NM_POOL32A0 = 0x00,
17715 NM_SPECIAL2 = 0x01,
17716 NM_COP2_1 = 0x02,
17717 NM_UDI = 0x03,
17718 NM_POOL32A5 = 0x05,
17719 NM_POOL32A7 = 0x07,
17720 };
17721
17722 /* P.GP.W instruction pool */
17723 enum {
17724 NM_ADDIUGP_W = 0x00,
17725 NM_LWGP = 0x02,
17726 NM_SWGP = 0x03,
17727 };
17728
17729 /* P48I instruction pool */
17730 enum {
17731 NM_LI48 = 0x00,
17732 NM_ADDIU48 = 0x01,
17733 NM_ADDIUGP48 = 0x02,
17734 NM_ADDIUPC48 = 0x03,
17735 NM_LWPC48 = 0x0b,
17736 NM_SWPC48 = 0x0f,
17737 };
17738
17739 /* P.U12 instruction pool */
17740 enum {
17741 NM_ORI = 0x00,
17742 NM_XORI = 0x01,
17743 NM_ANDI = 0x02,
17744 NM_P_SR = 0x03,
17745 NM_SLTI = 0x04,
17746 NM_SLTIU = 0x05,
17747 NM_SEQI = 0x06,
17748 NM_ADDIUNEG = 0x08,
17749 NM_P_SHIFT = 0x0c,
17750 NM_P_ROTX = 0x0d,
17751 NM_P_INS = 0x0e,
17752 NM_P_EXT = 0x0f,
17753 };
17754
17755 /* POOL32F instruction pool */
17756 enum {
17757 NM_POOL32F_0 = 0x00,
17758 NM_POOL32F_3 = 0x03,
17759 NM_POOL32F_5 = 0x05,
17760 };
17761
17762 /* POOL32S instruction pool */
17763 enum {
17764 NM_POOL32S_0 = 0x00,
17765 NM_POOL32S_4 = 0x04,
17766 };
17767
17768 /* P.LUI instruction pool */
17769 enum {
17770 NM_LUI = 0x00,
17771 NM_ALUIPC = 0x01,
17772 };
17773
17774 /* P.GP.BH instruction pool */
17775 enum {
17776 NM_LBGP = 0x00,
17777 NM_SBGP = 0x01,
17778 NM_LBUGP = 0x02,
17779 NM_ADDIUGP_B = 0x03,
17780 NM_P_GP_LH = 0x04,
17781 NM_P_GP_SH = 0x05,
17782 NM_P_GP_CP1 = 0x06,
17783 };
17784
17785 /* P.LS.U12 instruction pool */
17786 enum {
17787 NM_LB = 0x00,
17788 NM_SB = 0x01,
17789 NM_LBU = 0x02,
17790 NM_P_PREFU12 = 0x03,
17791 NM_LH = 0x04,
17792 NM_SH = 0x05,
17793 NM_LHU = 0x06,
17794 NM_LWU = 0x07,
17795 NM_LW = 0x08,
17796 NM_SW = 0x09,
17797 NM_LWC1 = 0x0a,
17798 NM_SWC1 = 0x0b,
17799 NM_LDC1 = 0x0e,
17800 NM_SDC1 = 0x0f,
17801 };
17802
17803 /* P.LS.S9 instruction pool */
17804 enum {
17805 NM_P_LS_S0 = 0x00,
17806 NM_P_LS_S1 = 0x01,
17807 NM_P_LS_E0 = 0x02,
17808 NM_P_LS_WM = 0x04,
17809 NM_P_LS_UAWM = 0x05,
17810 };
17811
17812 /* P.BAL instruction pool */
17813 enum {
17814 NM_BC = 0x00,
17815 NM_BALC = 0x01,
17816 };
17817
17818 /* P.J instruction pool */
17819 enum {
17820 NM_JALRC = 0x00,
17821 NM_JALRC_HB = 0x01,
17822 NM_P_BALRSC = 0x08,
17823 };
17824
17825 /* P.BR1 instruction pool */
17826 enum {
17827 NM_BEQC = 0x00,
17828 NM_P_BR3A = 0x01,
17829 NM_BGEC = 0x02,
17830 NM_BGEUC = 0x03,
17831 };
17832
17833 /* P.BR2 instruction pool */
17834 enum {
17835 NM_BNEC = 0x00,
17836 NM_BLTC = 0x02,
17837 NM_BLTUC = 0x03,
17838 };
17839
17840 /* P.BRI instruction pool */
17841 enum {
17842 NM_BEQIC = 0x00,
17843 NM_BBEQZC = 0x01,
17844 NM_BGEIC = 0x02,
17845 NM_BGEIUC = 0x03,
17846 NM_BNEIC = 0x04,
17847 NM_BBNEZC = 0x05,
17848 NM_BLTIC = 0x06,
17849 NM_BLTIUC = 0x07,
17850 };
17851
17852 /* P16.SHIFT instruction pool */
17853 enum {
17854 NM_SLL16 = 0x00,
17855 NM_SRL16 = 0x01,
17856 };
17857
17858 /* POOL16C instruction pool */
17859 enum {
17860 NM_POOL16C_0 = 0x00,
17861 NM_LWXS16 = 0x01,
17862 };
17863
17864 /* P16.A1 instruction pool */
17865 enum {
17866 NM_ADDIUR1SP = 0x01,
17867 };
17868
17869 /* P16.A2 instruction pool */
17870 enum {
17871 NM_ADDIUR2 = 0x00,
17872 NM_P_ADDIURS5 = 0x01,
17873 };
17874
17875 /* P16.ADDU instruction pool */
17876 enum {
17877 NM_ADDU16 = 0x00,
17878 NM_SUBU16 = 0x01,
17879 };
17880
17881 /* P16.SR instruction pool */
17882 enum {
17883 NM_SAVE16 = 0x00,
17884 NM_RESTORE_JRC16 = 0x01,
17885 };
17886
17887 /* P16.4X4 instruction pool */
17888 enum {
17889 NM_ADDU4X4 = 0x00,
17890 NM_MUL4X4 = 0x01,
17891 };
17892
17893 /* P16.LB instruction pool */
17894 enum {
17895 NM_LB16 = 0x00,
17896 NM_SB16 = 0x01,
17897 NM_LBU16 = 0x02,
17898 };
17899
17900 /* P16.LH instruction pool */
17901 enum {
17902 NM_LH16 = 0x00,
17903 NM_SH16 = 0x01,
17904 NM_LHU16 = 0x02,
17905 };
17906
17907 /* P.RI instruction pool */
17908 enum {
17909 NM_SIGRIE = 0x00,
17910 NM_P_SYSCALL = 0x01,
17911 NM_BREAK = 0x02,
17912 NM_SDBBP = 0x03,
17913 };
17914
17915 /* POOL32A0 instruction pool */
17916 enum {
17917 NM_P_TRAP = 0x00,
17918 NM_SEB = 0x01,
17919 NM_SLLV = 0x02,
17920 NM_MUL = 0x03,
17921 NM_MFC0 = 0x06,
17922 NM_MFHC0 = 0x07,
17923 NM_SEH = 0x09,
17924 NM_SRLV = 0x0a,
17925 NM_MUH = 0x0b,
17926 NM_MTC0 = 0x0e,
17927 NM_MTHC0 = 0x0f,
17928 NM_SRAV = 0x12,
17929 NM_MULU = 0x13,
17930 NM_ROTRV = 0x1a,
17931 NM_MUHU = 0x1b,
17932 NM_ADD = 0x22,
17933 NM_DIV = 0x23,
17934 NM_ADDU = 0x2a,
17935 NM_MOD = 0x2b,
17936 NM_SUB = 0x32,
17937 NM_DIVU = 0x33,
17938 NM_RDHWR = 0x38,
17939 NM_SUBU = 0x3a,
17940 NM_MODU = 0x3b,
17941 NM_P_CMOVE = 0x42,
17942 NM_FORK = 0x45,
17943 NM_MFTR = 0x46,
17944 NM_MFHTR = 0x47,
17945 NM_AND = 0x4a,
17946 NM_YIELD = 0x4d,
17947 NM_MTTR = 0x4e,
17948 NM_MTHTR = 0x4f,
17949 NM_OR = 0x52,
17950 NM_D_E_MT_VPE = 0x56,
17951 NM_NOR = 0x5a,
17952 NM_XOR = 0x62,
17953 NM_SLT = 0x6a,
17954 NM_P_SLTU = 0x72,
17955 NM_SOV = 0x7a,
17956 };
17957
17958 /* CRC32 instruction pool */
17959 enum {
17960 NM_CRC32B = 0x00,
17961 NM_CRC32H = 0x01,
17962 NM_CRC32W = 0x02,
17963 NM_CRC32CB = 0x04,
17964 NM_CRC32CH = 0x05,
17965 NM_CRC32CW = 0x06,
17966 };
17967
17968 /* POOL32A5 instruction pool */
17969 enum {
17970 NM_CMP_EQ_PH = 0x00,
17971 NM_CMP_LT_PH = 0x08,
17972 NM_CMP_LE_PH = 0x10,
17973 NM_CMPGU_EQ_QB = 0x18,
17974 NM_CMPGU_LT_QB = 0x20,
17975 NM_CMPGU_LE_QB = 0x28,
17976 NM_CMPGDU_EQ_QB = 0x30,
17977 NM_CMPGDU_LT_QB = 0x38,
17978 NM_CMPGDU_LE_QB = 0x40,
17979 NM_CMPU_EQ_QB = 0x48,
17980 NM_CMPU_LT_QB = 0x50,
17981 NM_CMPU_LE_QB = 0x58,
17982 NM_ADDQ_S_W = 0x60,
17983 NM_SUBQ_S_W = 0x68,
17984 NM_ADDSC = 0x70,
17985 NM_ADDWC = 0x78,
17986
17987 NM_ADDQ_S_PH = 0x01,
17988 NM_ADDQH_R_PH = 0x09,
17989 NM_ADDQH_R_W = 0x11,
17990 NM_ADDU_S_QB = 0x19,
17991 NM_ADDU_S_PH = 0x21,
17992 NM_ADDUH_R_QB = 0x29,
17993 NM_SHRAV_R_PH = 0x31,
17994 NM_SHRAV_R_QB = 0x39,
17995 NM_SUBQ_S_PH = 0x41,
17996 NM_SUBQH_R_PH = 0x49,
17997 NM_SUBQH_R_W = 0x51,
17998 NM_SUBU_S_QB = 0x59,
17999 NM_SUBU_S_PH = 0x61,
18000 NM_SUBUH_R_QB = 0x69,
18001 NM_SHLLV_S_PH = 0x71,
18002 NM_PRECR_SRA_R_PH_W = 0x79,
18003
18004 NM_MULEU_S_PH_QBL = 0x12,
18005 NM_MULEU_S_PH_QBR = 0x1a,
18006 NM_MULQ_RS_PH = 0x22,
18007 NM_MULQ_S_PH = 0x2a,
18008 NM_MULQ_RS_W = 0x32,
18009 NM_MULQ_S_W = 0x3a,
18010 NM_APPEND = 0x42,
18011 NM_MODSUB = 0x52,
18012 NM_SHRAV_R_W = 0x5a,
18013 NM_SHRLV_PH = 0x62,
18014 NM_SHRLV_QB = 0x6a,
18015 NM_SHLLV_QB = 0x72,
18016 NM_SHLLV_S_W = 0x7a,
18017
18018 NM_SHILO = 0x03,
18019
18020 NM_MULEQ_S_W_PHL = 0x04,
18021 NM_MULEQ_S_W_PHR = 0x0c,
18022
18023 NM_MUL_S_PH = 0x05,
18024 NM_PRECR_QB_PH = 0x0d,
18025 NM_PRECRQ_QB_PH = 0x15,
18026 NM_PRECRQ_PH_W = 0x1d,
18027 NM_PRECRQ_RS_PH_W = 0x25,
18028 NM_PRECRQU_S_QB_PH = 0x2d,
18029 NM_PACKRL_PH = 0x35,
18030 NM_PICK_QB = 0x3d,
18031 NM_PICK_PH = 0x45,
18032
18033 NM_SHRA_R_W = 0x5e,
18034 NM_SHRA_R_PH = 0x66,
18035 NM_SHLL_S_PH = 0x76,
18036 NM_SHLL_S_W = 0x7e,
18037
18038 NM_REPL_PH = 0x07
18039 };
18040
18041 /* POOL32A7 instruction pool */
18042 enum {
18043 NM_P_LSX = 0x00,
18044 NM_LSA = 0x01,
18045 NM_EXTW = 0x03,
18046 NM_POOL32AXF = 0x07,
18047 };
18048
18049 /* P.SR instruction pool */
18050 enum {
18051 NM_PP_SR = 0x00,
18052 NM_P_SR_F = 0x01,
18053 };
18054
18055 /* P.SHIFT instruction pool */
18056 enum {
18057 NM_P_SLL = 0x00,
18058 NM_SRL = 0x02,
18059 NM_SRA = 0x04,
18060 NM_ROTR = 0x06,
18061 };
18062
18063 /* P.ROTX instruction pool */
18064 enum {
18065 NM_ROTX = 0x00,
18066 };
18067
18068 /* P.INS instruction pool */
18069 enum {
18070 NM_INS = 0x00,
18071 };
18072
18073 /* P.EXT instruction pool */
18074 enum {
18075 NM_EXT = 0x00,
18076 };
18077
18078 /* POOL32F_0 (fmt) instruction pool */
18079 enum {
18080 NM_RINT_S = 0x04,
18081 NM_RINT_D = 0x44,
18082 NM_ADD_S = 0x06,
18083 NM_SELEQZ_S = 0x07,
18084 NM_SELEQZ_D = 0x47,
18085 NM_CLASS_S = 0x0c,
18086 NM_CLASS_D = 0x4c,
18087 NM_SUB_S = 0x0e,
18088 NM_SELNEZ_S = 0x0f,
18089 NM_SELNEZ_D = 0x4f,
18090 NM_MUL_S = 0x16,
18091 NM_SEL_S = 0x17,
18092 NM_SEL_D = 0x57,
18093 NM_DIV_S = 0x1e,
18094 NM_ADD_D = 0x26,
18095 NM_SUB_D = 0x2e,
18096 NM_MUL_D = 0x36,
18097 NM_MADDF_S = 0x37,
18098 NM_MADDF_D = 0x77,
18099 NM_DIV_D = 0x3e,
18100 NM_MSUBF_S = 0x3f,
18101 NM_MSUBF_D = 0x7f,
18102 };
18103
18104 /* POOL32F_3 instruction pool */
18105 enum {
18106 NM_MIN_FMT = 0x00,
18107 NM_MAX_FMT = 0x01,
18108 NM_MINA_FMT = 0x04,
18109 NM_MAXA_FMT = 0x05,
18110 NM_POOL32FXF = 0x07,
18111 };
18112
18113 /* POOL32F_5 instruction pool */
18114 enum {
18115 NM_CMP_CONDN_S = 0x00,
18116 NM_CMP_CONDN_D = 0x02,
18117 };
18118
18119 /* P.GP.LH instruction pool */
18120 enum {
18121 NM_LHGP = 0x00,
18122 NM_LHUGP = 0x01,
18123 };
18124
18125 /* P.GP.SH instruction pool */
18126 enum {
18127 NM_SHGP = 0x00,
18128 };
18129
18130 /* P.GP.CP1 instruction pool */
18131 enum {
18132 NM_LWC1GP = 0x00,
18133 NM_SWC1GP = 0x01,
18134 NM_LDC1GP = 0x02,
18135 NM_SDC1GP = 0x03,
18136 };
18137
18138 /* P.LS.S0 instruction pool */
18139 enum {
18140 NM_LBS9 = 0x00,
18141 NM_LHS9 = 0x04,
18142 NM_LWS9 = 0x08,
18143 NM_LDS9 = 0x0c,
18144
18145 NM_SBS9 = 0x01,
18146 NM_SHS9 = 0x05,
18147 NM_SWS9 = 0x09,
18148 NM_SDS9 = 0x0d,
18149
18150 NM_LBUS9 = 0x02,
18151 NM_LHUS9 = 0x06,
18152 NM_LWC1S9 = 0x0a,
18153 NM_LDC1S9 = 0x0e,
18154
18155 NM_P_PREFS9 = 0x03,
18156 NM_LWUS9 = 0x07,
18157 NM_SWC1S9 = 0x0b,
18158 NM_SDC1S9 = 0x0f,
18159 };
18160
18161 /* P.LS.S1 instruction pool */
18162 enum {
18163 NM_ASET_ACLR = 0x02,
18164 NM_UALH = 0x04,
18165 NM_UASH = 0x05,
18166 NM_CACHE = 0x07,
18167 NM_P_LL = 0x0a,
18168 NM_P_SC = 0x0b,
18169 };
18170
18171 /* P.LS.E0 instruction pool */
18172 enum {
18173 NM_LBE = 0x00,
18174 NM_SBE = 0x01,
18175 NM_LBUE = 0x02,
18176 NM_P_PREFE = 0x03,
18177 NM_LHE = 0x04,
18178 NM_SHE = 0x05,
18179 NM_LHUE = 0x06,
18180 NM_CACHEE = 0x07,
18181 NM_LWE = 0x08,
18182 NM_SWE = 0x09,
18183 NM_P_LLE = 0x0a,
18184 NM_P_SCE = 0x0b,
18185 };
18186
18187 /* P.PREFE instruction pool */
18188 enum {
18189 NM_SYNCIE = 0x00,
18190 NM_PREFE = 0x01,
18191 };
18192
18193 /* P.LLE instruction pool */
18194 enum {
18195 NM_LLE = 0x00,
18196 NM_LLWPE = 0x01,
18197 };
18198
18199 /* P.SCE instruction pool */
18200 enum {
18201 NM_SCE = 0x00,
18202 NM_SCWPE = 0x01,
18203 };
18204
18205 /* P.LS.WM instruction pool */
18206 enum {
18207 NM_LWM = 0x00,
18208 NM_SWM = 0x01,
18209 };
18210
18211 /* P.LS.UAWM instruction pool */
18212 enum {
18213 NM_UALWM = 0x00,
18214 NM_UASWM = 0x01,
18215 };
18216
18217 /* P.BR3A instruction pool */
18218 enum {
18219 NM_BC1EQZC = 0x00,
18220 NM_BC1NEZC = 0x01,
18221 NM_BC2EQZC = 0x02,
18222 NM_BC2NEZC = 0x03,
18223 NM_BPOSGE32C = 0x04,
18224 };
18225
18226 /* P16.RI instruction pool */
18227 enum {
18228 NM_P16_SYSCALL = 0x01,
18229 NM_BREAK16 = 0x02,
18230 NM_SDBBP16 = 0x03,
18231 };
18232
18233 /* POOL16C_0 instruction pool */
18234 enum {
18235 NM_POOL16C_00 = 0x00,
18236 };
18237
18238 /* P16.JRC instruction pool */
18239 enum {
18240 NM_JRC = 0x00,
18241 NM_JALRC16 = 0x01,
18242 };
18243
18244 /* P.SYSCALL instruction pool */
18245 enum {
18246 NM_SYSCALL = 0x00,
18247 NM_HYPCALL = 0x01,
18248 };
18249
18250 /* P.TRAP instruction pool */
18251 enum {
18252 NM_TEQ = 0x00,
18253 NM_TNE = 0x01,
18254 };
18255
18256 /* P.CMOVE instruction pool */
18257 enum {
18258 NM_MOVZ = 0x00,
18259 NM_MOVN = 0x01,
18260 };
18261
18262 /* POOL32Axf instruction pool */
18263 enum {
18264 NM_POOL32AXF_1 = 0x01,
18265 NM_POOL32AXF_2 = 0x02,
18266 NM_POOL32AXF_4 = 0x04,
18267 NM_POOL32AXF_5 = 0x05,
18268 NM_POOL32AXF_7 = 0x07,
18269 };
18270
18271 /* POOL32Axf_1 instruction pool */
18272 enum {
18273 NM_POOL32AXF_1_0 = 0x00,
18274 NM_POOL32AXF_1_1 = 0x01,
18275 NM_POOL32AXF_1_3 = 0x03,
18276 NM_POOL32AXF_1_4 = 0x04,
18277 NM_POOL32AXF_1_5 = 0x05,
18278 NM_POOL32AXF_1_7 = 0x07,
18279 };
18280
18281 /* POOL32Axf_2 instruction pool */
18282 enum {
18283 NM_POOL32AXF_2_0_7 = 0x00,
18284 NM_POOL32AXF_2_8_15 = 0x01,
18285 NM_POOL32AXF_2_16_23 = 0x02,
18286 NM_POOL32AXF_2_24_31 = 0x03,
18287 };
18288
18289 /* POOL32Axf_7 instruction pool */
18290 enum {
18291 NM_SHRA_R_QB = 0x0,
18292 NM_SHRL_PH = 0x1,
18293 NM_REPL_QB = 0x2,
18294 };
18295
18296 /* POOL32Axf_1_0 instruction pool */
18297 enum {
18298 NM_MFHI = 0x0,
18299 NM_MFLO = 0x1,
18300 NM_MTHI = 0x2,
18301 NM_MTLO = 0x3,
18302 };
18303
18304 /* POOL32Axf_1_1 instruction pool */
18305 enum {
18306 NM_MTHLIP = 0x0,
18307 NM_SHILOV = 0x1,
18308 };
18309
18310 /* POOL32Axf_1_3 instruction pool */
18311 enum {
18312 NM_RDDSP = 0x0,
18313 NM_WRDSP = 0x1,
18314 NM_EXTP = 0x2,
18315 NM_EXTPDP = 0x3,
18316 };
18317
18318 /* POOL32Axf_1_4 instruction pool */
18319 enum {
18320 NM_SHLL_QB = 0x0,
18321 NM_SHRL_QB = 0x1,
18322 };
18323
18324 /* POOL32Axf_1_5 instruction pool */
18325 enum {
18326 NM_MAQ_S_W_PHR = 0x0,
18327 NM_MAQ_S_W_PHL = 0x1,
18328 NM_MAQ_SA_W_PHR = 0x2,
18329 NM_MAQ_SA_W_PHL = 0x3,
18330 };
18331
18332 /* POOL32Axf_1_7 instruction pool */
18333 enum {
18334 NM_EXTR_W = 0x0,
18335 NM_EXTR_R_W = 0x1,
18336 NM_EXTR_RS_W = 0x2,
18337 NM_EXTR_S_H = 0x3,
18338 };
18339
18340 /* POOL32Axf_2_0_7 instruction pool */
18341 enum {
18342 NM_DPA_W_PH = 0x0,
18343 NM_DPAQ_S_W_PH = 0x1,
18344 NM_DPS_W_PH = 0x2,
18345 NM_DPSQ_S_W_PH = 0x3,
18346 NM_BALIGN = 0x4,
18347 NM_MADD = 0x5,
18348 NM_MULT = 0x6,
18349 NM_EXTRV_W = 0x7,
18350 };
18351
18352 /* POOL32Axf_2_8_15 instruction pool */
18353 enum {
18354 NM_DPAX_W_PH = 0x0,
18355 NM_DPAQ_SA_L_W = 0x1,
18356 NM_DPSX_W_PH = 0x2,
18357 NM_DPSQ_SA_L_W = 0x3,
18358 NM_MADDU = 0x5,
18359 NM_MULTU = 0x6,
18360 NM_EXTRV_R_W = 0x7,
18361 };
18362
18363 /* POOL32Axf_2_16_23 instruction pool */
18364 enum {
18365 NM_DPAU_H_QBL = 0x0,
18366 NM_DPAQX_S_W_PH = 0x1,
18367 NM_DPSU_H_QBL = 0x2,
18368 NM_DPSQX_S_W_PH = 0x3,
18369 NM_EXTPV = 0x4,
18370 NM_MSUB = 0x5,
18371 NM_MULSA_W_PH = 0x6,
18372 NM_EXTRV_RS_W = 0x7,
18373 };
18374
18375 /* POOL32Axf_2_24_31 instruction pool */
18376 enum {
18377 NM_DPAU_H_QBR = 0x0,
18378 NM_DPAQX_SA_W_PH = 0x1,
18379 NM_DPSU_H_QBR = 0x2,
18380 NM_DPSQX_SA_W_PH = 0x3,
18381 NM_EXTPDPV = 0x4,
18382 NM_MSUBU = 0x5,
18383 NM_MULSAQ_S_W_PH = 0x6,
18384 NM_EXTRV_S_H = 0x7,
18385 };
18386
18387 /* POOL32Axf_{4, 5} instruction pool */
18388 enum {
18389 NM_CLO = 0x25,
18390 NM_CLZ = 0x2d,
18391
18392 NM_TLBP = 0x01,
18393 NM_TLBR = 0x09,
18394 NM_TLBWI = 0x11,
18395 NM_TLBWR = 0x19,
18396 NM_TLBINV = 0x03,
18397 NM_TLBINVF = 0x0b,
18398 NM_DI = 0x23,
18399 NM_EI = 0x2b,
18400 NM_RDPGPR = 0x70,
18401 NM_WRPGPR = 0x78,
18402 NM_WAIT = 0x61,
18403 NM_DERET = 0x71,
18404 NM_ERETX = 0x79,
18405
18406 /* nanoMIPS DSP instructions */
18407 NM_ABSQ_S_QB = 0x00,
18408 NM_ABSQ_S_PH = 0x08,
18409 NM_ABSQ_S_W = 0x10,
18410 NM_PRECEQ_W_PHL = 0x28,
18411 NM_PRECEQ_W_PHR = 0x30,
18412 NM_PRECEQU_PH_QBL = 0x38,
18413 NM_PRECEQU_PH_QBR = 0x48,
18414 NM_PRECEU_PH_QBL = 0x58,
18415 NM_PRECEU_PH_QBR = 0x68,
18416 NM_PRECEQU_PH_QBLA = 0x39,
18417 NM_PRECEQU_PH_QBRA = 0x49,
18418 NM_PRECEU_PH_QBLA = 0x59,
18419 NM_PRECEU_PH_QBRA = 0x69,
18420 NM_REPLV_PH = 0x01,
18421 NM_REPLV_QB = 0x09,
18422 NM_BITREV = 0x18,
18423 NM_INSV = 0x20,
18424 NM_RADDU_W_QB = 0x78,
18425
18426 NM_BITSWAP = 0x05,
18427 NM_WSBH = 0x3d,
18428 };
18429
18430 /* PP.SR instruction pool */
18431 enum {
18432 NM_SAVE = 0x00,
18433 NM_RESTORE = 0x02,
18434 NM_RESTORE_JRC = 0x03,
18435 };
18436
18437 /* P.SR.F instruction pool */
18438 enum {
18439 NM_SAVEF = 0x00,
18440 NM_RESTOREF = 0x01,
18441 };
18442
18443 /* P16.SYSCALL instruction pool */
18444 enum {
18445 NM_SYSCALL16 = 0x00,
18446 NM_HYPCALL16 = 0x01,
18447 };
18448
18449 /* POOL16C_00 instruction pool */
18450 enum {
18451 NM_NOT16 = 0x00,
18452 NM_XOR16 = 0x01,
18453 NM_AND16 = 0x02,
18454 NM_OR16 = 0x03,
18455 };
18456
18457 /* PP.LSX and PP.LSXS instruction pool */
18458 enum {
18459 NM_LBX = 0x00,
18460 NM_LHX = 0x04,
18461 NM_LWX = 0x08,
18462 NM_LDX = 0x0c,
18463
18464 NM_SBX = 0x01,
18465 NM_SHX = 0x05,
18466 NM_SWX = 0x09,
18467 NM_SDX = 0x0d,
18468
18469 NM_LBUX = 0x02,
18470 NM_LHUX = 0x06,
18471 NM_LWC1X = 0x0a,
18472 NM_LDC1X = 0x0e,
18473
18474 NM_LWUX = 0x07,
18475 NM_SWC1X = 0x0b,
18476 NM_SDC1X = 0x0f,
18477
18478 NM_LHXS = 0x04,
18479 NM_LWXS = 0x08,
18480 NM_LDXS = 0x0c,
18481
18482 NM_SHXS = 0x05,
18483 NM_SWXS = 0x09,
18484 NM_SDXS = 0x0d,
18485
18486 NM_LHUXS = 0x06,
18487 NM_LWC1XS = 0x0a,
18488 NM_LDC1XS = 0x0e,
18489
18490 NM_LWUXS = 0x07,
18491 NM_SWC1XS = 0x0b,
18492 NM_SDC1XS = 0x0f,
18493 };
18494
18495 /* ERETx instruction pool */
18496 enum {
18497 NM_ERET = 0x00,
18498 NM_ERETNC = 0x01,
18499 };
18500
18501 /* POOL32FxF_{0, 1} insturction pool */
18502 enum {
18503 NM_CFC1 = 0x40,
18504 NM_CTC1 = 0x60,
18505 NM_MFC1 = 0x80,
18506 NM_MTC1 = 0xa0,
18507 NM_MFHC1 = 0xc0,
18508 NM_MTHC1 = 0xe0,
18509
18510 NM_CVT_S_PL = 0x84,
18511 NM_CVT_S_PU = 0xa4,
18512
18513 NM_CVT_L_S = 0x004,
18514 NM_CVT_L_D = 0x104,
18515 NM_CVT_W_S = 0x024,
18516 NM_CVT_W_D = 0x124,
18517
18518 NM_RSQRT_S = 0x008,
18519 NM_RSQRT_D = 0x108,
18520
18521 NM_SQRT_S = 0x028,
18522 NM_SQRT_D = 0x128,
18523
18524 NM_RECIP_S = 0x048,
18525 NM_RECIP_D = 0x148,
18526
18527 NM_FLOOR_L_S = 0x00c,
18528 NM_FLOOR_L_D = 0x10c,
18529
18530 NM_FLOOR_W_S = 0x02c,
18531 NM_FLOOR_W_D = 0x12c,
18532
18533 NM_CEIL_L_S = 0x04c,
18534 NM_CEIL_L_D = 0x14c,
18535 NM_CEIL_W_S = 0x06c,
18536 NM_CEIL_W_D = 0x16c,
18537 NM_TRUNC_L_S = 0x08c,
18538 NM_TRUNC_L_D = 0x18c,
18539 NM_TRUNC_W_S = 0x0ac,
18540 NM_TRUNC_W_D = 0x1ac,
18541 NM_ROUND_L_S = 0x0cc,
18542 NM_ROUND_L_D = 0x1cc,
18543 NM_ROUND_W_S = 0x0ec,
18544 NM_ROUND_W_D = 0x1ec,
18545
18546 NM_MOV_S = 0x01,
18547 NM_MOV_D = 0x81,
18548 NM_ABS_S = 0x0d,
18549 NM_ABS_D = 0x8d,
18550 NM_NEG_S = 0x2d,
18551 NM_NEG_D = 0xad,
18552 NM_CVT_D_S = 0x04d,
18553 NM_CVT_D_W = 0x0cd,
18554 NM_CVT_D_L = 0x14d,
18555 NM_CVT_S_D = 0x06d,
18556 NM_CVT_S_W = 0x0ed,
18557 NM_CVT_S_L = 0x16d,
18558 };
18559
18560 /* P.LL instruction pool */
18561 enum {
18562 NM_LL = 0x00,
18563 NM_LLWP = 0x01,
18564 };
18565
18566 /* P.SC instruction pool */
18567 enum {
18568 NM_SC = 0x00,
18569 NM_SCWP = 0x01,
18570 };
18571
18572 /* P.DVP instruction pool */
18573 enum {
18574 NM_DVP = 0x00,
18575 NM_EVP = 0x01,
18576 };
18577
18578
18579 /*
18580 *
18581 * nanoMIPS decoding engine
18582 *
18583 */
18584
18585
18586 /* extraction utilities */
18587
18588 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18589 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18590 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18591 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18592 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18593
18594 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18595 static inline int decode_gpr_gpr3(int r)
18596 {
18597 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18598
18599 return map[r & 0x7];
18600 }
18601
18602 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18603 static inline int decode_gpr_gpr3_src_store(int r)
18604 {
18605 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18606
18607 return map[r & 0x7];
18608 }
18609
18610 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18611 static inline int decode_gpr_gpr4(int r)
18612 {
18613 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18614 16, 17, 18, 19, 20, 21, 22, 23 };
18615
18616 return map[r & 0xf];
18617 }
18618
18619 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18620 static inline int decode_gpr_gpr4_zero(int r)
18621 {
18622 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18623 16, 17, 18, 19, 20, 21, 22, 23 };
18624
18625 return map[r & 0xf];
18626 }
18627
18628
18629 static void gen_adjust_sp(DisasContext *ctx, int u)
18630 {
18631 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18632 }
18633
18634 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18635 uint8_t gp, uint16_t u)
18636 {
18637 int counter = 0;
18638 TCGv va = tcg_temp_new();
18639 TCGv t0 = tcg_temp_new();
18640
18641 while (counter != count) {
18642 bool use_gp = gp && (counter == count - 1);
18643 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18644 int this_offset = -((counter + 1) << 2);
18645 gen_base_offset_addr(ctx, va, 29, this_offset);
18646 gen_load_gpr(t0, this_rt);
18647 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18648 (MO_TEUL | ctx->default_tcg_memop_mask));
18649 counter++;
18650 }
18651
18652 /* adjust stack pointer */
18653 gen_adjust_sp(ctx, -u);
18654
18655 tcg_temp_free(t0);
18656 tcg_temp_free(va);
18657 }
18658
18659 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18660 uint8_t gp, uint16_t u)
18661 {
18662 int counter = 0;
18663 TCGv va = tcg_temp_new();
18664 TCGv t0 = tcg_temp_new();
18665
18666 while (counter != count) {
18667 bool use_gp = gp && (counter == count - 1);
18668 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18669 int this_offset = u - ((counter + 1) << 2);
18670 gen_base_offset_addr(ctx, va, 29, this_offset);
18671 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18672 ctx->default_tcg_memop_mask);
18673 tcg_gen_ext32s_tl(t0, t0);
18674 gen_store_gpr(t0, this_rt);
18675 counter++;
18676 }
18677
18678 /* adjust stack pointer */
18679 gen_adjust_sp(ctx, u);
18680
18681 tcg_temp_free(t0);
18682 tcg_temp_free(va);
18683 }
18684
18685 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18686 {
18687 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18688 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
18689
18690 switch (extract32(ctx->opcode, 2, 2)) {
18691 case NM_NOT16:
18692 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18693 break;
18694 case NM_AND16:
18695 gen_logic(ctx, OPC_AND, rt, rt, rs);
18696 break;
18697 case NM_XOR16:
18698 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18699 break;
18700 case NM_OR16:
18701 gen_logic(ctx, OPC_OR, rt, rt, rs);
18702 break;
18703 }
18704 }
18705
18706 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18707 {
18708 int rt = extract32(ctx->opcode, 21, 5);
18709 int rs = extract32(ctx->opcode, 16, 5);
18710 int rd = extract32(ctx->opcode, 11, 5);
18711
18712 switch (extract32(ctx->opcode, 3, 7)) {
18713 case NM_P_TRAP:
18714 switch (extract32(ctx->opcode, 10, 1)) {
18715 case NM_TEQ:
18716 check_nms(ctx);
18717 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18718 break;
18719 case NM_TNE:
18720 check_nms(ctx);
18721 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18722 break;
18723 }
18724 break;
18725 case NM_RDHWR:
18726 check_nms(ctx);
18727 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18728 break;
18729 case NM_SEB:
18730 check_nms(ctx);
18731 gen_bshfl(ctx, OPC_SEB, rs, rt);
18732 break;
18733 case NM_SEH:
18734 gen_bshfl(ctx, OPC_SEH, rs, rt);
18735 break;
18736 case NM_SLLV:
18737 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18738 break;
18739 case NM_SRLV:
18740 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18741 break;
18742 case NM_SRAV:
18743 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18744 break;
18745 case NM_ROTRV:
18746 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18747 break;
18748 case NM_ADD:
18749 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18750 break;
18751 case NM_ADDU:
18752 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18753 break;
18754 case NM_SUB:
18755 check_nms(ctx);
18756 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18757 break;
18758 case NM_SUBU:
18759 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18760 break;
18761 case NM_P_CMOVE:
18762 switch (extract32(ctx->opcode, 10, 1)) {
18763 case NM_MOVZ:
18764 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18765 break;
18766 case NM_MOVN:
18767 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18768 break;
18769 }
18770 break;
18771 case NM_AND:
18772 gen_logic(ctx, OPC_AND, rd, rs, rt);
18773 break;
18774 case NM_OR:
18775 gen_logic(ctx, OPC_OR, rd, rs, rt);
18776 break;
18777 case NM_NOR:
18778 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18779 break;
18780 case NM_XOR:
18781 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18782 break;
18783 case NM_SLT:
18784 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18785 break;
18786 case NM_P_SLTU:
18787 if (rd == 0) {
18788 /* P_DVP */
18789 #ifndef CONFIG_USER_ONLY
18790 TCGv t0 = tcg_temp_new();
18791 switch (extract32(ctx->opcode, 10, 1)) {
18792 case NM_DVP:
18793 if (ctx->vp) {
18794 check_cp0_enabled(ctx);
18795 gen_helper_dvp(t0, cpu_env);
18796 gen_store_gpr(t0, rt);
18797 }
18798 break;
18799 case NM_EVP:
18800 if (ctx->vp) {
18801 check_cp0_enabled(ctx);
18802 gen_helper_evp(t0, cpu_env);
18803 gen_store_gpr(t0, rt);
18804 }
18805 break;
18806 }
18807 tcg_temp_free(t0);
18808 #endif
18809 } else {
18810 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18811 }
18812 break;
18813 case NM_SOV:
18814 {
18815 TCGv t0 = tcg_temp_new();
18816 TCGv t1 = tcg_temp_new();
18817 TCGv t2 = tcg_temp_new();
18818
18819 gen_load_gpr(t1, rs);
18820 gen_load_gpr(t2, rt);
18821 tcg_gen_add_tl(t0, t1, t2);
18822 tcg_gen_ext32s_tl(t0, t0);
18823 tcg_gen_xor_tl(t1, t1, t2);
18824 tcg_gen_xor_tl(t2, t0, t2);
18825 tcg_gen_andc_tl(t1, t2, t1);
18826
18827 /* operands of same sign, result different sign */
18828 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18829 gen_store_gpr(t0, rd);
18830
18831 tcg_temp_free(t0);
18832 tcg_temp_free(t1);
18833 tcg_temp_free(t2);
18834 }
18835 break;
18836 case NM_MUL:
18837 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18838 break;
18839 case NM_MUH:
18840 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18841 break;
18842 case NM_MULU:
18843 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18844 break;
18845 case NM_MUHU:
18846 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18847 break;
18848 case NM_DIV:
18849 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18850 break;
18851 case NM_MOD:
18852 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18853 break;
18854 case NM_DIVU:
18855 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18856 break;
18857 case NM_MODU:
18858 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18859 break;
18860 #ifndef CONFIG_USER_ONLY
18861 case NM_MFC0:
18862 check_cp0_enabled(ctx);
18863 if (rt == 0) {
18864 /* Treat as NOP. */
18865 break;
18866 }
18867 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18868 break;
18869 case NM_MTC0:
18870 check_cp0_enabled(ctx);
18871 {
18872 TCGv t0 = tcg_temp_new();
18873
18874 gen_load_gpr(t0, rt);
18875 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18876 tcg_temp_free(t0);
18877 }
18878 break;
18879 case NM_D_E_MT_VPE:
18880 {
18881 uint8_t sc = extract32(ctx->opcode, 10, 1);
18882 TCGv t0 = tcg_temp_new();
18883
18884 switch (sc) {
18885 case 0:
18886 if (rs == 1) {
18887 /* DMT */
18888 check_cp0_mt(ctx);
18889 gen_helper_dmt(t0);
18890 gen_store_gpr(t0, rt);
18891 } else if (rs == 0) {
18892 /* DVPE */
18893 check_cp0_mt(ctx);
18894 gen_helper_dvpe(t0, cpu_env);
18895 gen_store_gpr(t0, rt);
18896 } else {
18897 generate_exception_end(ctx, EXCP_RI);
18898 }
18899 break;
18900 case 1:
18901 if (rs == 1) {
18902 /* EMT */
18903 check_cp0_mt(ctx);
18904 gen_helper_emt(t0);
18905 gen_store_gpr(t0, rt);
18906 } else if (rs == 0) {
18907 /* EVPE */
18908 check_cp0_mt(ctx);
18909 gen_helper_evpe(t0, cpu_env);
18910 gen_store_gpr(t0, rt);
18911 } else {
18912 generate_exception_end(ctx, EXCP_RI);
18913 }
18914 break;
18915 }
18916
18917 tcg_temp_free(t0);
18918 }
18919 break;
18920 case NM_FORK:
18921 check_mt(ctx);
18922 {
18923 TCGv t0 = tcg_temp_new();
18924 TCGv t1 = tcg_temp_new();
18925
18926 gen_load_gpr(t0, rt);
18927 gen_load_gpr(t1, rs);
18928 gen_helper_fork(t0, t1);
18929 tcg_temp_free(t0);
18930 tcg_temp_free(t1);
18931 }
18932 break;
18933 case NM_MFTR:
18934 case NM_MFHTR:
18935 check_cp0_enabled(ctx);
18936 if (rd == 0) {
18937 /* Treat as NOP. */
18938 return;
18939 }
18940 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18941 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18942 break;
18943 case NM_MTTR:
18944 case NM_MTHTR:
18945 check_cp0_enabled(ctx);
18946 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18947 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18948 break;
18949 case NM_YIELD:
18950 check_mt(ctx);
18951 {
18952 TCGv t0 = tcg_temp_new();
18953
18954 gen_load_gpr(t0, rs);
18955 gen_helper_yield(t0, cpu_env, t0);
18956 gen_store_gpr(t0, rt);
18957 tcg_temp_free(t0);
18958 }
18959 break;
18960 #endif
18961 default:
18962 generate_exception_end(ctx, EXCP_RI);
18963 break;
18964 }
18965 }
18966
18967 /* dsp */
18968 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18969 int ret, int v1, int v2)
18970 {
18971 TCGv_i32 t0;
18972 TCGv v0_t;
18973 TCGv v1_t;
18974
18975 t0 = tcg_temp_new_i32();
18976
18977 v0_t = tcg_temp_new();
18978 v1_t = tcg_temp_new();
18979
18980 tcg_gen_movi_i32(t0, v2 >> 3);
18981
18982 gen_load_gpr(v0_t, ret);
18983 gen_load_gpr(v1_t, v1);
18984
18985 switch (opc) {
18986 case NM_MAQ_S_W_PHR:
18987 check_dsp(ctx);
18988 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18989 break;
18990 case NM_MAQ_S_W_PHL:
18991 check_dsp(ctx);
18992 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18993 break;
18994 case NM_MAQ_SA_W_PHR:
18995 check_dsp(ctx);
18996 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18997 break;
18998 case NM_MAQ_SA_W_PHL:
18999 check_dsp(ctx);
19000 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
19001 break;
19002 default:
19003 generate_exception_end(ctx, EXCP_RI);
19004 break;
19005 }
19006
19007 tcg_temp_free_i32(t0);
19008
19009 tcg_temp_free(v0_t);
19010 tcg_temp_free(v1_t);
19011 }
19012
19013
19014 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
19015 int ret, int v1, int v2)
19016 {
19017 int16_t imm;
19018 TCGv t0 = tcg_temp_new();
19019 TCGv t1 = tcg_temp_new();
19020 TCGv v0_t = tcg_temp_new();
19021
19022 gen_load_gpr(v0_t, v1);
19023
19024 switch (opc) {
19025 case NM_POOL32AXF_1_0:
19026 check_dsp(ctx);
19027 switch (extract32(ctx->opcode, 12, 2)) {
19028 case NM_MFHI:
19029 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
19030 break;
19031 case NM_MFLO:
19032 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
19033 break;
19034 case NM_MTHI:
19035 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
19036 break;
19037 case NM_MTLO:
19038 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
19039 break;
19040 }
19041 break;
19042 case NM_POOL32AXF_1_1:
19043 check_dsp(ctx);
19044 switch (extract32(ctx->opcode, 12, 2)) {
19045 case NM_MTHLIP:
19046 tcg_gen_movi_tl(t0, v2);
19047 gen_helper_mthlip(t0, v0_t, cpu_env);
19048 break;
19049 case NM_SHILOV:
19050 tcg_gen_movi_tl(t0, v2 >> 3);
19051 gen_helper_shilo(t0, v0_t, cpu_env);
19052 break;
19053 default:
19054 generate_exception_end(ctx, EXCP_RI);
19055 break;
19056 }
19057 break;
19058 case NM_POOL32AXF_1_3:
19059 check_dsp(ctx);
19060 imm = extract32(ctx->opcode, 14, 7);
19061 switch (extract32(ctx->opcode, 12, 2)) {
19062 case NM_RDDSP:
19063 tcg_gen_movi_tl(t0, imm);
19064 gen_helper_rddsp(t0, t0, cpu_env);
19065 gen_store_gpr(t0, ret);
19066 break;
19067 case NM_WRDSP:
19068 gen_load_gpr(t0, ret);
19069 tcg_gen_movi_tl(t1, imm);
19070 gen_helper_wrdsp(t0, t1, cpu_env);
19071 break;
19072 case NM_EXTP:
19073 tcg_gen_movi_tl(t0, v2 >> 3);
19074 tcg_gen_movi_tl(t1, v1);
19075 gen_helper_extp(t0, t0, t1, cpu_env);
19076 gen_store_gpr(t0, ret);
19077 break;
19078 case NM_EXTPDP:
19079 tcg_gen_movi_tl(t0, v2 >> 3);
19080 tcg_gen_movi_tl(t1, v1);
19081 gen_helper_extpdp(t0, t0, t1, cpu_env);
19082 gen_store_gpr(t0, ret);
19083 break;
19084 }
19085 break;
19086 case NM_POOL32AXF_1_4:
19087 check_dsp(ctx);
19088 tcg_gen_movi_tl(t0, v2 >> 2);
19089 switch (extract32(ctx->opcode, 12, 1)) {
19090 case NM_SHLL_QB:
19091 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
19092 gen_store_gpr(t0, ret);
19093 break;
19094 case NM_SHRL_QB:
19095 gen_helper_shrl_qb(t0, t0, v0_t);
19096 gen_store_gpr(t0, ret);
19097 break;
19098 }
19099 break;
19100 case NM_POOL32AXF_1_5:
19101 opc = extract32(ctx->opcode, 12, 2);
19102 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
19103 break;
19104 case NM_POOL32AXF_1_7:
19105 check_dsp(ctx);
19106 tcg_gen_movi_tl(t0, v2 >> 3);
19107 tcg_gen_movi_tl(t1, v1);
19108 switch (extract32(ctx->opcode, 12, 2)) {
19109 case NM_EXTR_W:
19110 gen_helper_extr_w(t0, t0, t1, cpu_env);
19111 gen_store_gpr(t0, ret);
19112 break;
19113 case NM_EXTR_R_W:
19114 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
19115 gen_store_gpr(t0, ret);
19116 break;
19117 case NM_EXTR_RS_W:
19118 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
19119 gen_store_gpr(t0, ret);
19120 break;
19121 case NM_EXTR_S_H:
19122 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
19123 gen_store_gpr(t0, ret);
19124 break;
19125 }
19126 break;
19127 default:
19128 generate_exception_end(ctx, EXCP_RI);
19129 break;
19130 }
19131
19132 tcg_temp_free(t0);
19133 tcg_temp_free(t1);
19134 tcg_temp_free(v0_t);
19135 }
19136
19137 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
19138 TCGv v0, TCGv v1, int rd)
19139 {
19140 TCGv_i32 t0;
19141
19142 t0 = tcg_temp_new_i32();
19143
19144 tcg_gen_movi_i32(t0, rd >> 3);
19145
19146 switch (opc) {
19147 case NM_POOL32AXF_2_0_7:
19148 switch (extract32(ctx->opcode, 9, 3)) {
19149 case NM_DPA_W_PH:
19150 check_dsp_r2(ctx);
19151 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
19152 break;
19153 case NM_DPAQ_S_W_PH:
19154 check_dsp(ctx);
19155 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19156 break;
19157 case NM_DPS_W_PH:
19158 check_dsp_r2(ctx);
19159 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19160 break;
19161 case NM_DPSQ_S_W_PH:
19162 check_dsp(ctx);
19163 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19164 break;
19165 default:
19166 generate_exception_end(ctx, EXCP_RI);
19167 break;
19168 }
19169 break;
19170 case NM_POOL32AXF_2_8_15:
19171 switch (extract32(ctx->opcode, 9, 3)) {
19172 case NM_DPAX_W_PH:
19173 check_dsp_r2(ctx);
19174 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19175 break;
19176 case NM_DPAQ_SA_L_W:
19177 check_dsp(ctx);
19178 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19179 break;
19180 case NM_DPSX_W_PH:
19181 check_dsp_r2(ctx);
19182 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19183 break;
19184 case NM_DPSQ_SA_L_W:
19185 check_dsp(ctx);
19186 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19187 break;
19188 default:
19189 generate_exception_end(ctx, EXCP_RI);
19190 break;
19191 }
19192 break;
19193 case NM_POOL32AXF_2_16_23:
19194 switch (extract32(ctx->opcode, 9, 3)) {
19195 case NM_DPAU_H_QBL:
19196 check_dsp(ctx);
19197 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19198 break;
19199 case NM_DPAQX_S_W_PH:
19200 check_dsp_r2(ctx);
19201 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19202 break;
19203 case NM_DPSU_H_QBL:
19204 check_dsp(ctx);
19205 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19206 break;
19207 case NM_DPSQX_S_W_PH:
19208 check_dsp_r2(ctx);
19209 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19210 break;
19211 case NM_MULSA_W_PH:
19212 check_dsp_r2(ctx);
19213 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19214 break;
19215 default:
19216 generate_exception_end(ctx, EXCP_RI);
19217 break;
19218 }
19219 break;
19220 case NM_POOL32AXF_2_24_31:
19221 switch (extract32(ctx->opcode, 9, 3)) {
19222 case NM_DPAU_H_QBR:
19223 check_dsp(ctx);
19224 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19225 break;
19226 case NM_DPAQX_SA_W_PH:
19227 check_dsp_r2(ctx);
19228 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19229 break;
19230 case NM_DPSU_H_QBR:
19231 check_dsp(ctx);
19232 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19233 break;
19234 case NM_DPSQX_SA_W_PH:
19235 check_dsp_r2(ctx);
19236 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19237 break;
19238 case NM_MULSAQ_S_W_PH:
19239 check_dsp(ctx);
19240 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19241 break;
19242 default:
19243 generate_exception_end(ctx, EXCP_RI);
19244 break;
19245 }
19246 break;
19247 default:
19248 generate_exception_end(ctx, EXCP_RI);
19249 break;
19250 }
19251
19252 tcg_temp_free_i32(t0);
19253 }
19254
19255 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19256 int rt, int rs, int rd)
19257 {
19258 int ret = rt;
19259 TCGv t0 = tcg_temp_new();
19260 TCGv t1 = tcg_temp_new();
19261 TCGv v0_t = tcg_temp_new();
19262 TCGv v1_t = tcg_temp_new();
19263
19264 gen_load_gpr(v0_t, rt);
19265 gen_load_gpr(v1_t, rs);
19266
19267 switch (opc) {
19268 case NM_POOL32AXF_2_0_7:
19269 switch (extract32(ctx->opcode, 9, 3)) {
19270 case NM_DPA_W_PH:
19271 case NM_DPAQ_S_W_PH:
19272 case NM_DPS_W_PH:
19273 case NM_DPSQ_S_W_PH:
19274 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19275 break;
19276 case NM_BALIGN:
19277 check_dsp_r2(ctx);
19278 if (rt != 0) {
19279 gen_load_gpr(t0, rs);
19280 rd &= 3;
19281 if (rd != 0 && rd != 2) {
19282 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19283 tcg_gen_ext32u_tl(t0, t0);
19284 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19285 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19286 }
19287 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19288 }
19289 break;
19290 case NM_MADD:
19291 check_dsp(ctx);
19292 {
19293 int acc = extract32(ctx->opcode, 14, 2);
19294 TCGv_i64 t2 = tcg_temp_new_i64();
19295 TCGv_i64 t3 = tcg_temp_new_i64();
19296
19297 gen_load_gpr(t0, rt);
19298 gen_load_gpr(t1, rs);
19299 tcg_gen_ext_tl_i64(t2, t0);
19300 tcg_gen_ext_tl_i64(t3, t1);
19301 tcg_gen_mul_i64(t2, t2, t3);
19302 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19303 tcg_gen_add_i64(t2, t2, t3);
19304 tcg_temp_free_i64(t3);
19305 gen_move_low32(cpu_LO[acc], t2);
19306 gen_move_high32(cpu_HI[acc], t2);
19307 tcg_temp_free_i64(t2);
19308 }
19309 break;
19310 case NM_MULT:
19311 check_dsp(ctx);
19312 {
19313 int acc = extract32(ctx->opcode, 14, 2);
19314 TCGv_i32 t2 = tcg_temp_new_i32();
19315 TCGv_i32 t3 = tcg_temp_new_i32();
19316
19317 gen_load_gpr(t0, rs);
19318 gen_load_gpr(t1, rt);
19319 tcg_gen_trunc_tl_i32(t2, t0);
19320 tcg_gen_trunc_tl_i32(t3, t1);
19321 tcg_gen_muls2_i32(t2, t3, t2, t3);
19322 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19323 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19324 tcg_temp_free_i32(t2);
19325 tcg_temp_free_i32(t3);
19326 }
19327 break;
19328 case NM_EXTRV_W:
19329 check_dsp(ctx);
19330 gen_load_gpr(v1_t, rs);
19331 tcg_gen_movi_tl(t0, rd >> 3);
19332 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19333 gen_store_gpr(t0, ret);
19334 break;
19335 }
19336 break;
19337 case NM_POOL32AXF_2_8_15:
19338 switch (extract32(ctx->opcode, 9, 3)) {
19339 case NM_DPAX_W_PH:
19340 case NM_DPAQ_SA_L_W:
19341 case NM_DPSX_W_PH:
19342 case NM_DPSQ_SA_L_W:
19343 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19344 break;
19345 case NM_MADDU:
19346 check_dsp(ctx);
19347 {
19348 int acc = extract32(ctx->opcode, 14, 2);
19349 TCGv_i64 t2 = tcg_temp_new_i64();
19350 TCGv_i64 t3 = tcg_temp_new_i64();
19351
19352 gen_load_gpr(t0, rs);
19353 gen_load_gpr(t1, rt);
19354 tcg_gen_ext32u_tl(t0, t0);
19355 tcg_gen_ext32u_tl(t1, t1);
19356 tcg_gen_extu_tl_i64(t2, t0);
19357 tcg_gen_extu_tl_i64(t3, t1);
19358 tcg_gen_mul_i64(t2, t2, t3);
19359 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19360 tcg_gen_add_i64(t2, t2, t3);
19361 tcg_temp_free_i64(t3);
19362 gen_move_low32(cpu_LO[acc], t2);
19363 gen_move_high32(cpu_HI[acc], t2);
19364 tcg_temp_free_i64(t2);
19365 }
19366 break;
19367 case NM_MULTU:
19368 check_dsp(ctx);
19369 {
19370 int acc = extract32(ctx->opcode, 14, 2);
19371 TCGv_i32 t2 = tcg_temp_new_i32();
19372 TCGv_i32 t3 = tcg_temp_new_i32();
19373
19374 gen_load_gpr(t0, rs);
19375 gen_load_gpr(t1, rt);
19376 tcg_gen_trunc_tl_i32(t2, t0);
19377 tcg_gen_trunc_tl_i32(t3, t1);
19378 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19379 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19380 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19381 tcg_temp_free_i32(t2);
19382 tcg_temp_free_i32(t3);
19383 }
19384 break;
19385 case NM_EXTRV_R_W:
19386 check_dsp(ctx);
19387 tcg_gen_movi_tl(t0, rd >> 3);
19388 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19389 gen_store_gpr(t0, ret);
19390 break;
19391 default:
19392 generate_exception_end(ctx, EXCP_RI);
19393 break;
19394 }
19395 break;
19396 case NM_POOL32AXF_2_16_23:
19397 switch (extract32(ctx->opcode, 9, 3)) {
19398 case NM_DPAU_H_QBL:
19399 case NM_DPAQX_S_W_PH:
19400 case NM_DPSU_H_QBL:
19401 case NM_DPSQX_S_W_PH:
19402 case NM_MULSA_W_PH:
19403 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19404 break;
19405 case NM_EXTPV:
19406 check_dsp(ctx);
19407 tcg_gen_movi_tl(t0, rd >> 3);
19408 gen_helper_extp(t0, t0, v1_t, cpu_env);
19409 gen_store_gpr(t0, ret);
19410 break;
19411 case NM_MSUB:
19412 check_dsp(ctx);
19413 {
19414 int acc = extract32(ctx->opcode, 14, 2);
19415 TCGv_i64 t2 = tcg_temp_new_i64();
19416 TCGv_i64 t3 = tcg_temp_new_i64();
19417
19418 gen_load_gpr(t0, rs);
19419 gen_load_gpr(t1, rt);
19420 tcg_gen_ext_tl_i64(t2, t0);
19421 tcg_gen_ext_tl_i64(t3, t1);
19422 tcg_gen_mul_i64(t2, t2, t3);
19423 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19424 tcg_gen_sub_i64(t2, t3, t2);
19425 tcg_temp_free_i64(t3);
19426 gen_move_low32(cpu_LO[acc], t2);
19427 gen_move_high32(cpu_HI[acc], t2);
19428 tcg_temp_free_i64(t2);
19429 }
19430 break;
19431 case NM_EXTRV_RS_W:
19432 check_dsp(ctx);
19433 tcg_gen_movi_tl(t0, rd >> 3);
19434 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19435 gen_store_gpr(t0, ret);
19436 break;
19437 }
19438 break;
19439 case NM_POOL32AXF_2_24_31:
19440 switch (extract32(ctx->opcode, 9, 3)) {
19441 case NM_DPAU_H_QBR:
19442 case NM_DPAQX_SA_W_PH:
19443 case NM_DPSU_H_QBR:
19444 case NM_DPSQX_SA_W_PH:
19445 case NM_MULSAQ_S_W_PH:
19446 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19447 break;
19448 case NM_EXTPDPV:
19449 check_dsp(ctx);
19450 tcg_gen_movi_tl(t0, rd >> 3);
19451 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19452 gen_store_gpr(t0, ret);
19453 break;
19454 case NM_MSUBU:
19455 check_dsp(ctx);
19456 {
19457 int acc = extract32(ctx->opcode, 14, 2);
19458 TCGv_i64 t2 = tcg_temp_new_i64();
19459 TCGv_i64 t3 = tcg_temp_new_i64();
19460
19461 gen_load_gpr(t0, rs);
19462 gen_load_gpr(t1, rt);
19463 tcg_gen_ext32u_tl(t0, t0);
19464 tcg_gen_ext32u_tl(t1, t1);
19465 tcg_gen_extu_tl_i64(t2, t0);
19466 tcg_gen_extu_tl_i64(t3, t1);
19467 tcg_gen_mul_i64(t2, t2, t3);
19468 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19469 tcg_gen_sub_i64(t2, t3, t2);
19470 tcg_temp_free_i64(t3);
19471 gen_move_low32(cpu_LO[acc], t2);
19472 gen_move_high32(cpu_HI[acc], t2);
19473 tcg_temp_free_i64(t2);
19474 }
19475 break;
19476 case NM_EXTRV_S_H:
19477 check_dsp(ctx);
19478 tcg_gen_movi_tl(t0, rd >> 3);
19479 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19480 gen_store_gpr(t0, ret);
19481 break;
19482 }
19483 break;
19484 default:
19485 generate_exception_end(ctx, EXCP_RI);
19486 break;
19487 }
19488
19489 tcg_temp_free(t0);
19490 tcg_temp_free(t1);
19491
19492 tcg_temp_free(v0_t);
19493 tcg_temp_free(v1_t);
19494 }
19495
19496 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19497 int rt, int rs)
19498 {
19499 int ret = rt;
19500 TCGv t0 = tcg_temp_new();
19501 TCGv v0_t = tcg_temp_new();
19502
19503 gen_load_gpr(v0_t, rs);
19504
19505 switch (opc) {
19506 case NM_ABSQ_S_QB:
19507 check_dsp_r2(ctx);
19508 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19509 gen_store_gpr(v0_t, ret);
19510 break;
19511 case NM_ABSQ_S_PH:
19512 check_dsp(ctx);
19513 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19514 gen_store_gpr(v0_t, ret);
19515 break;
19516 case NM_ABSQ_S_W:
19517 check_dsp(ctx);
19518 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19519 gen_store_gpr(v0_t, ret);
19520 break;
19521 case NM_PRECEQ_W_PHL:
19522 check_dsp(ctx);
19523 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19524 tcg_gen_ext32s_tl(v0_t, v0_t);
19525 gen_store_gpr(v0_t, ret);
19526 break;
19527 case NM_PRECEQ_W_PHR:
19528 check_dsp(ctx);
19529 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19530 tcg_gen_shli_tl(v0_t, v0_t, 16);
19531 tcg_gen_ext32s_tl(v0_t, v0_t);
19532 gen_store_gpr(v0_t, ret);
19533 break;
19534 case NM_PRECEQU_PH_QBL:
19535 check_dsp(ctx);
19536 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19537 gen_store_gpr(v0_t, ret);
19538 break;
19539 case NM_PRECEQU_PH_QBR:
19540 check_dsp(ctx);
19541 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19542 gen_store_gpr(v0_t, ret);
19543 break;
19544 case NM_PRECEQU_PH_QBLA:
19545 check_dsp(ctx);
19546 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19547 gen_store_gpr(v0_t, ret);
19548 break;
19549 case NM_PRECEQU_PH_QBRA:
19550 check_dsp(ctx);
19551 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19552 gen_store_gpr(v0_t, ret);
19553 break;
19554 case NM_PRECEU_PH_QBL:
19555 check_dsp(ctx);
19556 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19557 gen_store_gpr(v0_t, ret);
19558 break;
19559 case NM_PRECEU_PH_QBR:
19560 check_dsp(ctx);
19561 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19562 gen_store_gpr(v0_t, ret);
19563 break;
19564 case NM_PRECEU_PH_QBLA:
19565 check_dsp(ctx);
19566 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19567 gen_store_gpr(v0_t, ret);
19568 break;
19569 case NM_PRECEU_PH_QBRA:
19570 check_dsp(ctx);
19571 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19572 gen_store_gpr(v0_t, ret);
19573 break;
19574 case NM_REPLV_PH:
19575 check_dsp(ctx);
19576 tcg_gen_ext16u_tl(v0_t, v0_t);
19577 tcg_gen_shli_tl(t0, v0_t, 16);
19578 tcg_gen_or_tl(v0_t, v0_t, t0);
19579 tcg_gen_ext32s_tl(v0_t, v0_t);
19580 gen_store_gpr(v0_t, ret);
19581 break;
19582 case NM_REPLV_QB:
19583 check_dsp(ctx);
19584 tcg_gen_ext8u_tl(v0_t, v0_t);
19585 tcg_gen_shli_tl(t0, v0_t, 8);
19586 tcg_gen_or_tl(v0_t, v0_t, t0);
19587 tcg_gen_shli_tl(t0, v0_t, 16);
19588 tcg_gen_or_tl(v0_t, v0_t, t0);
19589 tcg_gen_ext32s_tl(v0_t, v0_t);
19590 gen_store_gpr(v0_t, ret);
19591 break;
19592 case NM_BITREV:
19593 check_dsp(ctx);
19594 gen_helper_bitrev(v0_t, v0_t);
19595 gen_store_gpr(v0_t, ret);
19596 break;
19597 case NM_INSV:
19598 check_dsp(ctx);
19599 {
19600 TCGv tv0 = tcg_temp_new();
19601
19602 gen_load_gpr(tv0, rt);
19603 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19604 gen_store_gpr(v0_t, ret);
19605 tcg_temp_free(tv0);
19606 }
19607 break;
19608 case NM_RADDU_W_QB:
19609 check_dsp(ctx);
19610 gen_helper_raddu_w_qb(v0_t, v0_t);
19611 gen_store_gpr(v0_t, ret);
19612 break;
19613 case NM_BITSWAP:
19614 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19615 break;
19616 case NM_CLO:
19617 check_nms(ctx);
19618 gen_cl(ctx, OPC_CLO, ret, rs);
19619 break;
19620 case NM_CLZ:
19621 check_nms(ctx);
19622 gen_cl(ctx, OPC_CLZ, ret, rs);
19623 break;
19624 case NM_WSBH:
19625 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19626 break;
19627 default:
19628 generate_exception_end(ctx, EXCP_RI);
19629 break;
19630 }
19631
19632 tcg_temp_free(v0_t);
19633 tcg_temp_free(t0);
19634 }
19635
19636 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19637 int rt, int rs, int rd)
19638 {
19639 TCGv t0 = tcg_temp_new();
19640 TCGv rs_t = tcg_temp_new();
19641
19642 gen_load_gpr(rs_t, rs);
19643
19644 switch (opc) {
19645 case NM_SHRA_R_QB:
19646 check_dsp_r2(ctx);
19647 tcg_gen_movi_tl(t0, rd >> 2);
19648 switch (extract32(ctx->opcode, 12, 1)) {
19649 case 0:
19650 /* NM_SHRA_QB */
19651 gen_helper_shra_qb(t0, t0, rs_t);
19652 gen_store_gpr(t0, rt);
19653 break;
19654 case 1:
19655 /* NM_SHRA_R_QB */
19656 gen_helper_shra_r_qb(t0, t0, rs_t);
19657 gen_store_gpr(t0, rt);
19658 break;
19659 }
19660 break;
19661 case NM_SHRL_PH:
19662 check_dsp_r2(ctx);
19663 tcg_gen_movi_tl(t0, rd >> 1);
19664 gen_helper_shrl_ph(t0, t0, rs_t);
19665 gen_store_gpr(t0, rt);
19666 break;
19667 case NM_REPL_QB:
19668 check_dsp(ctx);
19669 {
19670 int16_t imm;
19671 target_long result;
19672 imm = extract32(ctx->opcode, 13, 8);
19673 result = (uint32_t)imm << 24 |
19674 (uint32_t)imm << 16 |
19675 (uint32_t)imm << 8 |
19676 (uint32_t)imm;
19677 result = (int32_t)result;
19678 tcg_gen_movi_tl(t0, result);
19679 gen_store_gpr(t0, rt);
19680 }
19681 break;
19682 default:
19683 generate_exception_end(ctx, EXCP_RI);
19684 break;
19685 }
19686 tcg_temp_free(t0);
19687 tcg_temp_free(rs_t);
19688 }
19689
19690
19691 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19692 {
19693 int rt = extract32(ctx->opcode, 21, 5);
19694 int rs = extract32(ctx->opcode, 16, 5);
19695 int rd = extract32(ctx->opcode, 11, 5);
19696
19697 switch (extract32(ctx->opcode, 6, 3)) {
19698 case NM_POOL32AXF_1:
19699 {
19700 int32_t op1 = extract32(ctx->opcode, 9, 3);
19701 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19702 }
19703 break;
19704 case NM_POOL32AXF_2:
19705 {
19706 int32_t op1 = extract32(ctx->opcode, 12, 2);
19707 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19708 }
19709 break;
19710 case NM_POOL32AXF_4:
19711 {
19712 int32_t op1 = extract32(ctx->opcode, 9, 7);
19713 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19714 }
19715 break;
19716 case NM_POOL32AXF_5:
19717 switch (extract32(ctx->opcode, 9, 7)) {
19718 #ifndef CONFIG_USER_ONLY
19719 case NM_TLBP:
19720 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19721 break;
19722 case NM_TLBR:
19723 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19724 break;
19725 case NM_TLBWI:
19726 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19727 break;
19728 case NM_TLBWR:
19729 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19730 break;
19731 case NM_TLBINV:
19732 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19733 break;
19734 case NM_TLBINVF:
19735 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19736 break;
19737 case NM_DI:
19738 check_cp0_enabled(ctx);
19739 {
19740 TCGv t0 = tcg_temp_new();
19741
19742 save_cpu_state(ctx, 1);
19743 gen_helper_di(t0, cpu_env);
19744 gen_store_gpr(t0, rt);
19745 /* Stop translation as we may have switched the execution mode */
19746 ctx->base.is_jmp = DISAS_STOP;
19747 tcg_temp_free(t0);
19748 }
19749 break;
19750 case NM_EI:
19751 check_cp0_enabled(ctx);
19752 {
19753 TCGv t0 = tcg_temp_new();
19754
19755 save_cpu_state(ctx, 1);
19756 gen_helper_ei(t0, cpu_env);
19757 gen_store_gpr(t0, rt);
19758 /* Stop translation as we may have switched the execution mode */
19759 ctx->base.is_jmp = DISAS_STOP;
19760 tcg_temp_free(t0);
19761 }
19762 break;
19763 case NM_RDPGPR:
19764 gen_load_srsgpr(rs, rt);
19765 break;
19766 case NM_WRPGPR:
19767 gen_store_srsgpr(rs, rt);
19768 break;
19769 case NM_WAIT:
19770 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19771 break;
19772 case NM_DERET:
19773 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19774 break;
19775 case NM_ERETX:
19776 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19777 break;
19778 #endif
19779 default:
19780 generate_exception_end(ctx, EXCP_RI);
19781 break;
19782 }
19783 break;
19784 case NM_POOL32AXF_7:
19785 {
19786 int32_t op1 = extract32(ctx->opcode, 9, 3);
19787 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19788 }
19789 break;
19790 default:
19791 generate_exception_end(ctx, EXCP_RI);
19792 break;
19793 }
19794 }
19795
19796 /* Immediate Value Compact Branches */
19797 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19798 int rt, int32_t imm, int32_t offset)
19799 {
19800 TCGCond cond;
19801 int bcond_compute = 0;
19802 TCGv t0 = tcg_temp_new();
19803 TCGv t1 = tcg_temp_new();
19804
19805 gen_load_gpr(t0, rt);
19806 tcg_gen_movi_tl(t1, imm);
19807 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19808
19809 /* Load needed operands and calculate btarget */
19810 switch (opc) {
19811 case NM_BEQIC:
19812 if (rt == 0 && imm == 0) {
19813 /* Unconditional branch */
19814 } else if (rt == 0 && imm != 0) {
19815 /* Treat as NOP */
19816 goto out;
19817 } else {
19818 bcond_compute = 1;
19819 cond = TCG_COND_EQ;
19820 }
19821 break;
19822 case NM_BBEQZC:
19823 case NM_BBNEZC:
19824 check_nms(ctx);
19825 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19826 generate_exception_end(ctx, EXCP_RI);
19827 goto out;
19828 } else if (rt == 0 && opc == NM_BBEQZC) {
19829 /* Unconditional branch */
19830 } else if (rt == 0 && opc == NM_BBNEZC) {
19831 /* Treat as NOP */
19832 goto out;
19833 } else {
19834 tcg_gen_shri_tl(t0, t0, imm);
19835 tcg_gen_andi_tl(t0, t0, 1);
19836 tcg_gen_movi_tl(t1, 0);
19837 bcond_compute = 1;
19838 if (opc == NM_BBEQZC) {
19839 cond = TCG_COND_EQ;
19840 } else {
19841 cond = TCG_COND_NE;
19842 }
19843 }
19844 break;
19845 case NM_BNEIC:
19846 if (rt == 0 && imm == 0) {
19847 /* Treat as NOP */
19848 goto out;
19849 } else if (rt == 0 && imm != 0) {
19850 /* Unconditional branch */
19851 } else {
19852 bcond_compute = 1;
19853 cond = TCG_COND_NE;
19854 }
19855 break;
19856 case NM_BGEIC:
19857 if (rt == 0 && imm == 0) {
19858 /* Unconditional branch */
19859 } else {
19860 bcond_compute = 1;
19861 cond = TCG_COND_GE;
19862 }
19863 break;
19864 case NM_BLTIC:
19865 bcond_compute = 1;
19866 cond = TCG_COND_LT;
19867 break;
19868 case NM_BGEIUC:
19869 if (rt == 0 && imm == 0) {
19870 /* Unconditional branch */
19871 } else {
19872 bcond_compute = 1;
19873 cond = TCG_COND_GEU;
19874 }
19875 break;
19876 case NM_BLTIUC:
19877 bcond_compute = 1;
19878 cond = TCG_COND_LTU;
19879 break;
19880 default:
19881 MIPS_INVAL("Immediate Value Compact branch");
19882 generate_exception_end(ctx, EXCP_RI);
19883 goto out;
19884 }
19885
19886 /* branch completion */
19887 clear_branch_hflags(ctx);
19888 ctx->base.is_jmp = DISAS_NORETURN;
19889
19890 if (bcond_compute == 0) {
19891 /* Uncoditional compact branch */
19892 gen_goto_tb(ctx, 0, ctx->btarget);
19893 } else {
19894 /* Conditional compact branch */
19895 TCGLabel *fs = gen_new_label();
19896
19897 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19898
19899 gen_goto_tb(ctx, 1, ctx->btarget);
19900 gen_set_label(fs);
19901
19902 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19903 }
19904
19905 out:
19906 tcg_temp_free(t0);
19907 tcg_temp_free(t1);
19908 }
19909
19910 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19911 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19912 int rt)
19913 {
19914 TCGv t0 = tcg_temp_new();
19915 TCGv t1 = tcg_temp_new();
19916
19917 /* load rs */
19918 gen_load_gpr(t0, rs);
19919
19920 /* link */
19921 if (rt != 0) {
19922 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19923 }
19924
19925 /* calculate btarget */
19926 tcg_gen_shli_tl(t0, t0, 1);
19927 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19928 gen_op_addr_add(ctx, btarget, t1, t0);
19929
19930 /* branch completion */
19931 clear_branch_hflags(ctx);
19932 ctx->base.is_jmp = DISAS_NORETURN;
19933
19934 /* unconditional branch to register */
19935 tcg_gen_mov_tl(cpu_PC, btarget);
19936 tcg_gen_lookup_and_goto_ptr();
19937
19938 tcg_temp_free(t0);
19939 tcg_temp_free(t1);
19940 }
19941
19942 /* nanoMIPS Branches */
19943 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19944 int rs, int rt, int32_t offset)
19945 {
19946 int bcond_compute = 0;
19947 TCGv t0 = tcg_temp_new();
19948 TCGv t1 = tcg_temp_new();
19949
19950 /* Load needed operands and calculate btarget */
19951 switch (opc) {
19952 /* compact branch */
19953 case OPC_BGEC:
19954 case OPC_BLTC:
19955 gen_load_gpr(t0, rs);
19956 gen_load_gpr(t1, rt);
19957 bcond_compute = 1;
19958 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19959 break;
19960 case OPC_BGEUC:
19961 case OPC_BLTUC:
19962 if (rs == 0 || rs == rt) {
19963 /* OPC_BLEZALC, OPC_BGEZALC */
19964 /* OPC_BGTZALC, OPC_BLTZALC */
19965 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19966 }
19967 gen_load_gpr(t0, rs);
19968 gen_load_gpr(t1, rt);
19969 bcond_compute = 1;
19970 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19971 break;
19972 case OPC_BC:
19973 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19974 break;
19975 case OPC_BEQZC:
19976 if (rs != 0) {
19977 /* OPC_BEQZC, OPC_BNEZC */
19978 gen_load_gpr(t0, rs);
19979 bcond_compute = 1;
19980 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19981 } else {
19982 /* OPC_JIC, OPC_JIALC */
19983 TCGv tbase = tcg_temp_new();
19984 TCGv toffset = tcg_temp_new();
19985
19986 gen_load_gpr(tbase, rt);
19987 tcg_gen_movi_tl(toffset, offset);
19988 gen_op_addr_add(ctx, btarget, tbase, toffset);
19989 tcg_temp_free(tbase);
19990 tcg_temp_free(toffset);
19991 }
19992 break;
19993 default:
19994 MIPS_INVAL("Compact branch/jump");
19995 generate_exception_end(ctx, EXCP_RI);
19996 goto out;
19997 }
19998
19999 if (bcond_compute == 0) {
20000 /* Uncoditional compact branch */
20001 switch (opc) {
20002 case OPC_BC:
20003 gen_goto_tb(ctx, 0, ctx->btarget);
20004 break;
20005 default:
20006 MIPS_INVAL("Compact branch/jump");
20007 generate_exception_end(ctx, EXCP_RI);
20008 goto out;
20009 }
20010 } else {
20011 /* Conditional compact branch */
20012 TCGLabel *fs = gen_new_label();
20013
20014 switch (opc) {
20015 case OPC_BGEUC:
20016 if (rs == 0 && rt != 0) {
20017 /* OPC_BLEZALC */
20018 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20019 } else if (rs != 0 && rt != 0 && rs == rt) {
20020 /* OPC_BGEZALC */
20021 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20022 } else {
20023 /* OPC_BGEUC */
20024 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
20025 }
20026 break;
20027 case OPC_BLTUC:
20028 if (rs == 0 && rt != 0) {
20029 /* OPC_BGTZALC */
20030 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20031 } else if (rs != 0 && rt != 0 && rs == rt) {
20032 /* OPC_BLTZALC */
20033 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20034 } else {
20035 /* OPC_BLTUC */
20036 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
20037 }
20038 break;
20039 case OPC_BGEC:
20040 if (rs == 0 && rt != 0) {
20041 /* OPC_BLEZC */
20042 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20043 } else if (rs != 0 && rt != 0 && rs == rt) {
20044 /* OPC_BGEZC */
20045 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20046 } else {
20047 /* OPC_BGEC */
20048 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
20049 }
20050 break;
20051 case OPC_BLTC:
20052 if (rs == 0 && rt != 0) {
20053 /* OPC_BGTZC */
20054 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20055 } else if (rs != 0 && rt != 0 && rs == rt) {
20056 /* OPC_BLTZC */
20057 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20058 } else {
20059 /* OPC_BLTC */
20060 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
20061 }
20062 break;
20063 case OPC_BEQZC:
20064 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
20065 break;
20066 default:
20067 MIPS_INVAL("Compact conditional branch/jump");
20068 generate_exception_end(ctx, EXCP_RI);
20069 goto out;
20070 }
20071
20072 /* branch completion */
20073 clear_branch_hflags(ctx);
20074 ctx->base.is_jmp = DISAS_NORETURN;
20075
20076 /* Generating branch here as compact branches don't have delay slot */
20077 gen_goto_tb(ctx, 1, ctx->btarget);
20078 gen_set_label(fs);
20079
20080 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20081 }
20082
20083 out:
20084 tcg_temp_free(t0);
20085 tcg_temp_free(t1);
20086 }
20087
20088
20089 /* nanoMIPS CP1 Branches */
20090 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
20091 int32_t ft, int32_t offset)
20092 {
20093 target_ulong btarget;
20094 TCGv_i64 t0 = tcg_temp_new_i64();
20095
20096 gen_load_fpr64(ctx, t0, ft);
20097 tcg_gen_andi_i64(t0, t0, 1);
20098
20099 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20100
20101 switch (op) {
20102 case NM_BC1EQZC:
20103 tcg_gen_xori_i64(t0, t0, 1);
20104 ctx->hflags |= MIPS_HFLAG_BC;
20105 break;
20106 case NM_BC1NEZC:
20107 /* t0 already set */
20108 ctx->hflags |= MIPS_HFLAG_BC;
20109 break;
20110 default:
20111 MIPS_INVAL("cp1 cond branch");
20112 generate_exception_end(ctx, EXCP_RI);
20113 goto out;
20114 }
20115
20116 tcg_gen_trunc_i64_tl(bcond, t0);
20117
20118 ctx->btarget = btarget;
20119
20120 out:
20121 tcg_temp_free_i64(t0);
20122 }
20123
20124
20125 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
20126 {
20127 TCGv t0, t1;
20128 t0 = tcg_temp_new();
20129 t1 = tcg_temp_new();
20130
20131 gen_load_gpr(t0, rs);
20132 gen_load_gpr(t1, rt);
20133
20134 if ((extract32(ctx->opcode, 6, 1)) == 1) {
20135 /* PP.LSXS instructions require shifting */
20136 switch (extract32(ctx->opcode, 7, 4)) {
20137 case NM_SHXS:
20138 check_nms(ctx);
20139 case NM_LHXS:
20140 case NM_LHUXS:
20141 tcg_gen_shli_tl(t0, t0, 1);
20142 break;
20143 case NM_SWXS:
20144 check_nms(ctx);
20145 case NM_LWXS:
20146 case NM_LWC1XS:
20147 case NM_SWC1XS:
20148 tcg_gen_shli_tl(t0, t0, 2);
20149 break;
20150 case NM_LDC1XS:
20151 case NM_SDC1XS:
20152 tcg_gen_shli_tl(t0, t0, 3);
20153 break;
20154 }
20155 }
20156 gen_op_addr_add(ctx, t0, t0, t1);
20157
20158 switch (extract32(ctx->opcode, 7, 4)) {
20159 case NM_LBX:
20160 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20161 MO_SB);
20162 gen_store_gpr(t0, rd);
20163 break;
20164 case NM_LHX:
20165 /*case NM_LHXS:*/
20166 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20167 MO_TESW);
20168 gen_store_gpr(t0, rd);
20169 break;
20170 case NM_LWX:
20171 /*case NM_LWXS:*/
20172 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20173 MO_TESL);
20174 gen_store_gpr(t0, rd);
20175 break;
20176 case NM_LBUX:
20177 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20178 MO_UB);
20179 gen_store_gpr(t0, rd);
20180 break;
20181 case NM_LHUX:
20182 /*case NM_LHUXS:*/
20183 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20184 MO_TEUW);
20185 gen_store_gpr(t0, rd);
20186 break;
20187 case NM_SBX:
20188 check_nms(ctx);
20189 gen_load_gpr(t1, rd);
20190 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20191 MO_8);
20192 break;
20193 case NM_SHX:
20194 /*case NM_SHXS:*/
20195 check_nms(ctx);
20196 gen_load_gpr(t1, rd);
20197 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20198 MO_TEUW);
20199 break;
20200 case NM_SWX:
20201 /*case NM_SWXS:*/
20202 check_nms(ctx);
20203 gen_load_gpr(t1, rd);
20204 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20205 MO_TEUL);
20206 break;
20207 case NM_LWC1X:
20208 /*case NM_LWC1XS:*/
20209 case NM_LDC1X:
20210 /*case NM_LDC1XS:*/
20211 case NM_SWC1X:
20212 /*case NM_SWC1XS:*/
20213 case NM_SDC1X:
20214 /*case NM_SDC1XS:*/
20215 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20216 check_cp1_enabled(ctx);
20217 switch (extract32(ctx->opcode, 7, 4)) {
20218 case NM_LWC1X:
20219 /*case NM_LWC1XS:*/
20220 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20221 break;
20222 case NM_LDC1X:
20223 /*case NM_LDC1XS:*/
20224 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20225 break;
20226 case NM_SWC1X:
20227 /*case NM_SWC1XS:*/
20228 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20229 break;
20230 case NM_SDC1X:
20231 /*case NM_SDC1XS:*/
20232 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20233 break;
20234 }
20235 } else {
20236 generate_exception_err(ctx, EXCP_CpU, 1);
20237 }
20238 break;
20239 default:
20240 generate_exception_end(ctx, EXCP_RI);
20241 break;
20242 }
20243
20244 tcg_temp_free(t0);
20245 tcg_temp_free(t1);
20246 }
20247
20248 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20249 {
20250 int rt, rs, rd;
20251
20252 rt = extract32(ctx->opcode, 21, 5);
20253 rs = extract32(ctx->opcode, 16, 5);
20254 rd = extract32(ctx->opcode, 11, 5);
20255
20256 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20257 generate_exception_end(ctx, EXCP_RI);
20258 return;
20259 }
20260 check_cp1_enabled(ctx);
20261 switch (extract32(ctx->opcode, 0, 3)) {
20262 case NM_POOL32F_0:
20263 switch (extract32(ctx->opcode, 3, 7)) {
20264 case NM_RINT_S:
20265 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20266 break;
20267 case NM_RINT_D:
20268 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20269 break;
20270 case NM_CLASS_S:
20271 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20272 break;
20273 case NM_CLASS_D:
20274 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20275 break;
20276 case NM_ADD_S:
20277 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20278 break;
20279 case NM_ADD_D:
20280 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20281 break;
20282 case NM_SUB_S:
20283 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20284 break;
20285 case NM_SUB_D:
20286 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20287 break;
20288 case NM_MUL_S:
20289 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20290 break;
20291 case NM_MUL_D:
20292 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20293 break;
20294 case NM_DIV_S:
20295 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20296 break;
20297 case NM_DIV_D:
20298 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20299 break;
20300 case NM_SELEQZ_S:
20301 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20302 break;
20303 case NM_SELEQZ_D:
20304 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20305 break;
20306 case NM_SELNEZ_S:
20307 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20308 break;
20309 case NM_SELNEZ_D:
20310 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20311 break;
20312 case NM_SEL_S:
20313 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20314 break;
20315 case NM_SEL_D:
20316 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20317 break;
20318 case NM_MADDF_S:
20319 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20320 break;
20321 case NM_MADDF_D:
20322 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20323 break;
20324 case NM_MSUBF_S:
20325 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20326 break;
20327 case NM_MSUBF_D:
20328 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20329 break;
20330 default:
20331 generate_exception_end(ctx, EXCP_RI);
20332 break;
20333 }
20334 break;
20335 case NM_POOL32F_3:
20336 switch (extract32(ctx->opcode, 3, 3)) {
20337 case NM_MIN_FMT:
20338 switch (extract32(ctx->opcode, 9, 1)) {
20339 case FMT_SDPS_S:
20340 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20341 break;
20342 case FMT_SDPS_D:
20343 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20344 break;
20345 }
20346 break;
20347 case NM_MAX_FMT:
20348 switch (extract32(ctx->opcode, 9, 1)) {
20349 case FMT_SDPS_S:
20350 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20351 break;
20352 case FMT_SDPS_D:
20353 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20354 break;
20355 }
20356 break;
20357 case NM_MINA_FMT:
20358 switch (extract32(ctx->opcode, 9, 1)) {
20359 case FMT_SDPS_S:
20360 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20361 break;
20362 case FMT_SDPS_D:
20363 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20364 break;
20365 }
20366 break;
20367 case NM_MAXA_FMT:
20368 switch (extract32(ctx->opcode, 9, 1)) {
20369 case FMT_SDPS_S:
20370 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20371 break;
20372 case FMT_SDPS_D:
20373 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20374 break;
20375 }
20376 break;
20377 case NM_POOL32FXF:
20378 switch (extract32(ctx->opcode, 6, 8)) {
20379 case NM_CFC1:
20380 gen_cp1(ctx, OPC_CFC1, rt, rs);
20381 break;
20382 case NM_CTC1:
20383 gen_cp1(ctx, OPC_CTC1, rt, rs);
20384 break;
20385 case NM_MFC1:
20386 gen_cp1(ctx, OPC_MFC1, rt, rs);
20387 break;
20388 case NM_MTC1:
20389 gen_cp1(ctx, OPC_MTC1, rt, rs);
20390 break;
20391 case NM_MFHC1:
20392 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20393 break;
20394 case NM_MTHC1:
20395 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20396 break;
20397 case NM_CVT_S_PL:
20398 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20399 break;
20400 case NM_CVT_S_PU:
20401 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20402 break;
20403 default:
20404 switch (extract32(ctx->opcode, 6, 9)) {
20405 case NM_CVT_L_S:
20406 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20407 break;
20408 case NM_CVT_L_D:
20409 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20410 break;
20411 case NM_CVT_W_S:
20412 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20413 break;
20414 case NM_CVT_W_D:
20415 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20416 break;
20417 case NM_RSQRT_S:
20418 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20419 break;
20420 case NM_RSQRT_D:
20421 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20422 break;
20423 case NM_SQRT_S:
20424 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20425 break;
20426 case NM_SQRT_D:
20427 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20428 break;
20429 case NM_RECIP_S:
20430 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20431 break;
20432 case NM_RECIP_D:
20433 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20434 break;
20435 case NM_FLOOR_L_S:
20436 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20437 break;
20438 case NM_FLOOR_L_D:
20439 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20440 break;
20441 case NM_FLOOR_W_S:
20442 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20443 break;
20444 case NM_FLOOR_W_D:
20445 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20446 break;
20447 case NM_CEIL_L_S:
20448 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20449 break;
20450 case NM_CEIL_L_D:
20451 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20452 break;
20453 case NM_CEIL_W_S:
20454 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20455 break;
20456 case NM_CEIL_W_D:
20457 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20458 break;
20459 case NM_TRUNC_L_S:
20460 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20461 break;
20462 case NM_TRUNC_L_D:
20463 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20464 break;
20465 case NM_TRUNC_W_S:
20466 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20467 break;
20468 case NM_TRUNC_W_D:
20469 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20470 break;
20471 case NM_ROUND_L_S:
20472 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20473 break;
20474 case NM_ROUND_L_D:
20475 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20476 break;
20477 case NM_ROUND_W_S:
20478 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20479 break;
20480 case NM_ROUND_W_D:
20481 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20482 break;
20483 case NM_MOV_S:
20484 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20485 break;
20486 case NM_MOV_D:
20487 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20488 break;
20489 case NM_ABS_S:
20490 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20491 break;
20492 case NM_ABS_D:
20493 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20494 break;
20495 case NM_NEG_S:
20496 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20497 break;
20498 case NM_NEG_D:
20499 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20500 break;
20501 case NM_CVT_D_S:
20502 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20503 break;
20504 case NM_CVT_D_W:
20505 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20506 break;
20507 case NM_CVT_D_L:
20508 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20509 break;
20510 case NM_CVT_S_D:
20511 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20512 break;
20513 case NM_CVT_S_W:
20514 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20515 break;
20516 case NM_CVT_S_L:
20517 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20518 break;
20519 default:
20520 generate_exception_end(ctx, EXCP_RI);
20521 break;
20522 }
20523 break;
20524 }
20525 break;
20526 }
20527 break;
20528 case NM_POOL32F_5:
20529 switch (extract32(ctx->opcode, 3, 3)) {
20530 case NM_CMP_CONDN_S:
20531 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20532 break;
20533 case NM_CMP_CONDN_D:
20534 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20535 break;
20536 default:
20537 generate_exception_end(ctx, EXCP_RI);
20538 break;
20539 }
20540 break;
20541 default:
20542 generate_exception_end(ctx, EXCP_RI);
20543 break;
20544 }
20545 }
20546
20547 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20548 int rd, int rs, int rt)
20549 {
20550 int ret = rd;
20551 TCGv t0 = tcg_temp_new();
20552 TCGv v1_t = tcg_temp_new();
20553 TCGv v2_t = tcg_temp_new();
20554
20555 gen_load_gpr(v1_t, rs);
20556 gen_load_gpr(v2_t, rt);
20557
20558 switch (opc) {
20559 case NM_CMP_EQ_PH:
20560 check_dsp(ctx);
20561 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20562 break;
20563 case NM_CMP_LT_PH:
20564 check_dsp(ctx);
20565 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20566 break;
20567 case NM_CMP_LE_PH:
20568 check_dsp(ctx);
20569 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20570 break;
20571 case NM_CMPU_EQ_QB:
20572 check_dsp(ctx);
20573 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20574 break;
20575 case NM_CMPU_LT_QB:
20576 check_dsp(ctx);
20577 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20578 break;
20579 case NM_CMPU_LE_QB:
20580 check_dsp(ctx);
20581 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20582 break;
20583 case NM_CMPGU_EQ_QB:
20584 check_dsp(ctx);
20585 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20586 gen_store_gpr(v1_t, ret);
20587 break;
20588 case NM_CMPGU_LT_QB:
20589 check_dsp(ctx);
20590 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20591 gen_store_gpr(v1_t, ret);
20592 break;
20593 case NM_CMPGU_LE_QB:
20594 check_dsp(ctx);
20595 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20596 gen_store_gpr(v1_t, ret);
20597 break;
20598 case NM_CMPGDU_EQ_QB:
20599 check_dsp_r2(ctx);
20600 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20601 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20602 gen_store_gpr(v1_t, ret);
20603 break;
20604 case NM_CMPGDU_LT_QB:
20605 check_dsp_r2(ctx);
20606 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20607 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20608 gen_store_gpr(v1_t, ret);
20609 break;
20610 case NM_CMPGDU_LE_QB:
20611 check_dsp_r2(ctx);
20612 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20613 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20614 gen_store_gpr(v1_t, ret);
20615 break;
20616 case NM_PACKRL_PH:
20617 check_dsp(ctx);
20618 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20619 gen_store_gpr(v1_t, ret);
20620 break;
20621 case NM_PICK_QB:
20622 check_dsp(ctx);
20623 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20624 gen_store_gpr(v1_t, ret);
20625 break;
20626 case NM_PICK_PH:
20627 check_dsp(ctx);
20628 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20629 gen_store_gpr(v1_t, ret);
20630 break;
20631 case NM_ADDQ_S_W:
20632 check_dsp(ctx);
20633 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20634 gen_store_gpr(v1_t, ret);
20635 break;
20636 case NM_SUBQ_S_W:
20637 check_dsp(ctx);
20638 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20639 gen_store_gpr(v1_t, ret);
20640 break;
20641 case NM_ADDSC:
20642 check_dsp(ctx);
20643 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20644 gen_store_gpr(v1_t, ret);
20645 break;
20646 case NM_ADDWC:
20647 check_dsp(ctx);
20648 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20649 gen_store_gpr(v1_t, ret);
20650 break;
20651 case NM_ADDQ_S_PH:
20652 check_dsp(ctx);
20653 switch (extract32(ctx->opcode, 10, 1)) {
20654 case 0:
20655 /* ADDQ_PH */
20656 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20657 gen_store_gpr(v1_t, ret);
20658 break;
20659 case 1:
20660 /* ADDQ_S_PH */
20661 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20662 gen_store_gpr(v1_t, ret);
20663 break;
20664 }
20665 break;
20666 case NM_ADDQH_R_PH:
20667 check_dsp_r2(ctx);
20668 switch (extract32(ctx->opcode, 10, 1)) {
20669 case 0:
20670 /* ADDQH_PH */
20671 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20672 gen_store_gpr(v1_t, ret);
20673 break;
20674 case 1:
20675 /* ADDQH_R_PH */
20676 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20677 gen_store_gpr(v1_t, ret);
20678 break;
20679 }
20680 break;
20681 case NM_ADDQH_R_W:
20682 check_dsp_r2(ctx);
20683 switch (extract32(ctx->opcode, 10, 1)) {
20684 case 0:
20685 /* ADDQH_W */
20686 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20687 gen_store_gpr(v1_t, ret);
20688 break;
20689 case 1:
20690 /* ADDQH_R_W */
20691 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20692 gen_store_gpr(v1_t, ret);
20693 break;
20694 }
20695 break;
20696 case NM_ADDU_S_QB:
20697 check_dsp(ctx);
20698 switch (extract32(ctx->opcode, 10, 1)) {
20699 case 0:
20700 /* ADDU_QB */
20701 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20702 gen_store_gpr(v1_t, ret);
20703 break;
20704 case 1:
20705 /* ADDU_S_QB */
20706 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20707 gen_store_gpr(v1_t, ret);
20708 break;
20709 }
20710 break;
20711 case NM_ADDU_S_PH:
20712 check_dsp_r2(ctx);
20713 switch (extract32(ctx->opcode, 10, 1)) {
20714 case 0:
20715 /* ADDU_PH */
20716 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20717 gen_store_gpr(v1_t, ret);
20718 break;
20719 case 1:
20720 /* ADDU_S_PH */
20721 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20722 gen_store_gpr(v1_t, ret);
20723 break;
20724 }
20725 break;
20726 case NM_ADDUH_R_QB:
20727 check_dsp_r2(ctx);
20728 switch (extract32(ctx->opcode, 10, 1)) {
20729 case 0:
20730 /* ADDUH_QB */
20731 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20732 gen_store_gpr(v1_t, ret);
20733 break;
20734 case 1:
20735 /* ADDUH_R_QB */
20736 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20737 gen_store_gpr(v1_t, ret);
20738 break;
20739 }
20740 break;
20741 case NM_SHRAV_R_PH:
20742 check_dsp(ctx);
20743 switch (extract32(ctx->opcode, 10, 1)) {
20744 case 0:
20745 /* SHRAV_PH */
20746 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20747 gen_store_gpr(v1_t, ret);
20748 break;
20749 case 1:
20750 /* SHRAV_R_PH */
20751 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20752 gen_store_gpr(v1_t, ret);
20753 break;
20754 }
20755 break;
20756 case NM_SHRAV_R_QB:
20757 check_dsp_r2(ctx);
20758 switch (extract32(ctx->opcode, 10, 1)) {
20759 case 0:
20760 /* SHRAV_QB */
20761 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20762 gen_store_gpr(v1_t, ret);
20763 break;
20764 case 1:
20765 /* SHRAV_R_QB */
20766 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20767 gen_store_gpr(v1_t, ret);
20768 break;
20769 }
20770 break;
20771 case NM_SUBQ_S_PH:
20772 check_dsp(ctx);
20773 switch (extract32(ctx->opcode, 10, 1)) {
20774 case 0:
20775 /* SUBQ_PH */
20776 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20777 gen_store_gpr(v1_t, ret);
20778 break;
20779 case 1:
20780 /* SUBQ_S_PH */
20781 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20782 gen_store_gpr(v1_t, ret);
20783 break;
20784 }
20785 break;
20786 case NM_SUBQH_R_PH:
20787 check_dsp_r2(ctx);
20788 switch (extract32(ctx->opcode, 10, 1)) {
20789 case 0:
20790 /* SUBQH_PH */
20791 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20792 gen_store_gpr(v1_t, ret);
20793 break;
20794 case 1:
20795 /* SUBQH_R_PH */
20796 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20797 gen_store_gpr(v1_t, ret);
20798 break;
20799 }
20800 break;
20801 case NM_SUBQH_R_W:
20802 check_dsp_r2(ctx);
20803 switch (extract32(ctx->opcode, 10, 1)) {
20804 case 0:
20805 /* SUBQH_W */
20806 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20807 gen_store_gpr(v1_t, ret);
20808 break;
20809 case 1:
20810 /* SUBQH_R_W */
20811 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20812 gen_store_gpr(v1_t, ret);
20813 break;
20814 }
20815 break;
20816 case NM_SUBU_S_QB:
20817 check_dsp(ctx);
20818 switch (extract32(ctx->opcode, 10, 1)) {
20819 case 0:
20820 /* SUBU_QB */
20821 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20822 gen_store_gpr(v1_t, ret);
20823 break;
20824 case 1:
20825 /* SUBU_S_QB */
20826 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20827 gen_store_gpr(v1_t, ret);
20828 break;
20829 }
20830 break;
20831 case NM_SUBU_S_PH:
20832 check_dsp_r2(ctx);
20833 switch (extract32(ctx->opcode, 10, 1)) {
20834 case 0:
20835 /* SUBU_PH */
20836 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20837 gen_store_gpr(v1_t, ret);
20838 break;
20839 case 1:
20840 /* SUBU_S_PH */
20841 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20842 gen_store_gpr(v1_t, ret);
20843 break;
20844 }
20845 break;
20846 case NM_SUBUH_R_QB:
20847 check_dsp_r2(ctx);
20848 switch (extract32(ctx->opcode, 10, 1)) {
20849 case 0:
20850 /* SUBUH_QB */
20851 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20852 gen_store_gpr(v1_t, ret);
20853 break;
20854 case 1:
20855 /* SUBUH_R_QB */
20856 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20857 gen_store_gpr(v1_t, ret);
20858 break;
20859 }
20860 break;
20861 case NM_SHLLV_S_PH:
20862 check_dsp(ctx);
20863 switch (extract32(ctx->opcode, 10, 1)) {
20864 case 0:
20865 /* SHLLV_PH */
20866 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20867 gen_store_gpr(v1_t, ret);
20868 break;
20869 case 1:
20870 /* SHLLV_S_PH */
20871 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20872 gen_store_gpr(v1_t, ret);
20873 break;
20874 }
20875 break;
20876 case NM_PRECR_SRA_R_PH_W:
20877 check_dsp_r2(ctx);
20878 switch (extract32(ctx->opcode, 10, 1)) {
20879 case 0:
20880 /* PRECR_SRA_PH_W */
20881 {
20882 TCGv_i32 sa_t = tcg_const_i32(rd);
20883 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20884 cpu_gpr[rt]);
20885 gen_store_gpr(v1_t, rt);
20886 tcg_temp_free_i32(sa_t);
20887 }
20888 break;
20889 case 1:
20890 /* PRECR_SRA_R_PH_W */
20891 {
20892 TCGv_i32 sa_t = tcg_const_i32(rd);
20893 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20894 cpu_gpr[rt]);
20895 gen_store_gpr(v1_t, rt);
20896 tcg_temp_free_i32(sa_t);
20897 }
20898 break;
20899 }
20900 break;
20901 case NM_MULEU_S_PH_QBL:
20902 check_dsp(ctx);
20903 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20904 gen_store_gpr(v1_t, ret);
20905 break;
20906 case NM_MULEU_S_PH_QBR:
20907 check_dsp(ctx);
20908 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20909 gen_store_gpr(v1_t, ret);
20910 break;
20911 case NM_MULQ_RS_PH:
20912 check_dsp(ctx);
20913 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20914 gen_store_gpr(v1_t, ret);
20915 break;
20916 case NM_MULQ_S_PH:
20917 check_dsp_r2(ctx);
20918 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20919 gen_store_gpr(v1_t, ret);
20920 break;
20921 case NM_MULQ_RS_W:
20922 check_dsp_r2(ctx);
20923 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20924 gen_store_gpr(v1_t, ret);
20925 break;
20926 case NM_MULQ_S_W:
20927 check_dsp_r2(ctx);
20928 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20929 gen_store_gpr(v1_t, ret);
20930 break;
20931 case NM_APPEND:
20932 check_dsp_r2(ctx);
20933 gen_load_gpr(t0, rs);
20934 if (rd != 0) {
20935 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20936 }
20937 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20938 break;
20939 case NM_MODSUB:
20940 check_dsp(ctx);
20941 gen_helper_modsub(v1_t, v1_t, v2_t);
20942 gen_store_gpr(v1_t, ret);
20943 break;
20944 case NM_SHRAV_R_W:
20945 check_dsp(ctx);
20946 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20947 gen_store_gpr(v1_t, ret);
20948 break;
20949 case NM_SHRLV_PH:
20950 check_dsp_r2(ctx);
20951 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20952 gen_store_gpr(v1_t, ret);
20953 break;
20954 case NM_SHRLV_QB:
20955 check_dsp(ctx);
20956 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20957 gen_store_gpr(v1_t, ret);
20958 break;
20959 case NM_SHLLV_QB:
20960 check_dsp(ctx);
20961 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20962 gen_store_gpr(v1_t, ret);
20963 break;
20964 case NM_SHLLV_S_W:
20965 check_dsp(ctx);
20966 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20967 gen_store_gpr(v1_t, ret);
20968 break;
20969 case NM_SHILO:
20970 check_dsp(ctx);
20971 {
20972 TCGv tv0 = tcg_temp_new();
20973 TCGv tv1 = tcg_temp_new();
20974 int16_t imm = extract32(ctx->opcode, 16, 7);
20975
20976 tcg_gen_movi_tl(tv0, rd >> 3);
20977 tcg_gen_movi_tl(tv1, imm);
20978 gen_helper_shilo(tv0, tv1, cpu_env);
20979 }
20980 break;
20981 case NM_MULEQ_S_W_PHL:
20982 check_dsp(ctx);
20983 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20984 gen_store_gpr(v1_t, ret);
20985 break;
20986 case NM_MULEQ_S_W_PHR:
20987 check_dsp(ctx);
20988 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20989 gen_store_gpr(v1_t, ret);
20990 break;
20991 case NM_MUL_S_PH:
20992 check_dsp_r2(ctx);
20993 switch (extract32(ctx->opcode, 10, 1)) {
20994 case 0:
20995 /* MUL_PH */
20996 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20997 gen_store_gpr(v1_t, ret);
20998 break;
20999 case 1:
21000 /* MUL_S_PH */
21001 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
21002 gen_store_gpr(v1_t, ret);
21003 break;
21004 }
21005 break;
21006 case NM_PRECR_QB_PH:
21007 check_dsp_r2(ctx);
21008 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
21009 gen_store_gpr(v1_t, ret);
21010 break;
21011 case NM_PRECRQ_QB_PH:
21012 check_dsp(ctx);
21013 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
21014 gen_store_gpr(v1_t, ret);
21015 break;
21016 case NM_PRECRQ_PH_W:
21017 check_dsp(ctx);
21018 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
21019 gen_store_gpr(v1_t, ret);
21020 break;
21021 case NM_PRECRQ_RS_PH_W:
21022 check_dsp(ctx);
21023 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
21024 gen_store_gpr(v1_t, ret);
21025 break;
21026 case NM_PRECRQU_S_QB_PH:
21027 check_dsp(ctx);
21028 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
21029 gen_store_gpr(v1_t, ret);
21030 break;
21031 case NM_SHRA_R_W:
21032 check_dsp(ctx);
21033 tcg_gen_movi_tl(t0, rd);
21034 gen_helper_shra_r_w(v1_t, t0, v1_t);
21035 gen_store_gpr(v1_t, rt);
21036 break;
21037 case NM_SHRA_R_PH:
21038 check_dsp(ctx);
21039 tcg_gen_movi_tl(t0, rd >> 1);
21040 switch (extract32(ctx->opcode, 10, 1)) {
21041 case 0:
21042 /* SHRA_PH */
21043 gen_helper_shra_ph(v1_t, t0, v1_t);
21044 gen_store_gpr(v1_t, rt);
21045 break;
21046 case 1:
21047 /* SHRA_R_PH */
21048 gen_helper_shra_r_ph(v1_t, t0, v1_t);
21049 gen_store_gpr(v1_t, rt);
21050 break;
21051 }
21052 break;
21053 case NM_SHLL_S_PH:
21054 check_dsp(ctx);
21055 tcg_gen_movi_tl(t0, rd >> 1);
21056 switch (extract32(ctx->opcode, 10, 2)) {
21057 case 0:
21058 /* SHLL_PH */
21059 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
21060 gen_store_gpr(v1_t, rt);
21061 break;
21062 case 2:
21063 /* SHLL_S_PH */
21064 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
21065 gen_store_gpr(v1_t, rt);
21066 break;
21067 default:
21068 generate_exception_end(ctx, EXCP_RI);
21069 break;
21070 }
21071 break;
21072 case NM_SHLL_S_W:
21073 check_dsp(ctx);
21074 tcg_gen_movi_tl(t0, rd);
21075 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
21076 gen_store_gpr(v1_t, rt);
21077 break;
21078 case NM_REPL_PH:
21079 check_dsp(ctx);
21080 {
21081 int16_t imm;
21082 imm = sextract32(ctx->opcode, 11, 11);
21083 imm = (int16_t)(imm << 6) >> 6;
21084 if (rt != 0) {
21085 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
21086 }
21087 }
21088 break;
21089 default:
21090 generate_exception_end(ctx, EXCP_RI);
21091 break;
21092 }
21093 }
21094
21095 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
21096 {
21097 uint16_t insn;
21098 uint32_t op;
21099 int rt, rs, rd;
21100 int offset;
21101 int imm;
21102
21103 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
21104 ctx->opcode = (ctx->opcode << 16) | insn;
21105
21106 rt = extract32(ctx->opcode, 21, 5);
21107 rs = extract32(ctx->opcode, 16, 5);
21108 rd = extract32(ctx->opcode, 11, 5);
21109
21110 op = extract32(ctx->opcode, 26, 6);
21111 switch (op) {
21112 case NM_P_ADDIU:
21113 if (rt == 0) {
21114 /* P.RI */
21115 switch (extract32(ctx->opcode, 19, 2)) {
21116 case NM_SIGRIE:
21117 default:
21118 generate_exception_end(ctx, EXCP_RI);
21119 break;
21120 case NM_P_SYSCALL:
21121 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
21122 generate_exception_end(ctx, EXCP_SYSCALL);
21123 } else {
21124 generate_exception_end(ctx, EXCP_RI);
21125 }
21126 break;
21127 case NM_BREAK:
21128 generate_exception_end(ctx, EXCP_BREAK);
21129 break;
21130 case NM_SDBBP:
21131 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
21132 gen_helper_do_semihosting(cpu_env);
21133 } else {
21134 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21135 generate_exception_end(ctx, EXCP_RI);
21136 } else {
21137 generate_exception_end(ctx, EXCP_DBp);
21138 }
21139 }
21140 break;
21141 }
21142 } else {
21143 /* NM_ADDIU */
21144 imm = extract32(ctx->opcode, 0, 16);
21145 if (rs != 0) {
21146 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
21147 } else {
21148 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21149 }
21150 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21151 }
21152 break;
21153 case NM_ADDIUPC:
21154 if (rt != 0) {
21155 offset = sextract32(ctx->opcode, 0, 1) << 21 |
21156 extract32(ctx->opcode, 1, 20) << 1;
21157 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21158 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21159 }
21160 break;
21161 case NM_POOL32A:
21162 switch (ctx->opcode & 0x07) {
21163 case NM_POOL32A0:
21164 gen_pool32a0_nanomips_insn(env, ctx);
21165 break;
21166 case NM_POOL32A5:
21167 {
21168 int32_t op1 = extract32(ctx->opcode, 3, 7);
21169 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21170 }
21171 break;
21172 case NM_POOL32A7:
21173 switch (extract32(ctx->opcode, 3, 3)) {
21174 case NM_P_LSX:
21175 gen_p_lsx(ctx, rd, rs, rt);
21176 break;
21177 case NM_LSA:
21178 /*
21179 * In nanoMIPS, the shift field directly encodes the shift
21180 * amount, meaning that the supported shift values are in
21181 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21182 */
21183 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21184 extract32(ctx->opcode, 9, 2) - 1);
21185 break;
21186 case NM_EXTW:
21187 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21188 break;
21189 case NM_POOL32AXF:
21190 gen_pool32axf_nanomips_insn(env, ctx);
21191 break;
21192 default:
21193 generate_exception_end(ctx, EXCP_RI);
21194 break;
21195 }
21196 break;
21197 default:
21198 generate_exception_end(ctx, EXCP_RI);
21199 break;
21200 }
21201 break;
21202 case NM_P_GP_W:
21203 switch (ctx->opcode & 0x03) {
21204 case NM_ADDIUGP_W:
21205 if (rt != 0) {
21206 offset = extract32(ctx->opcode, 0, 21);
21207 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21208 }
21209 break;
21210 case NM_LWGP:
21211 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21212 break;
21213 case NM_SWGP:
21214 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21215 break;
21216 default:
21217 generate_exception_end(ctx, EXCP_RI);
21218 break;
21219 }
21220 break;
21221 case NM_P48I:
21222 {
21223 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21224 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21225 switch (extract32(ctx->opcode, 16, 5)) {
21226 case NM_LI48:
21227 check_nms(ctx);
21228 if (rt != 0) {
21229 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21230 }
21231 break;
21232 case NM_ADDIU48:
21233 check_nms(ctx);
21234 if (rt != 0) {
21235 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21236 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21237 }
21238 break;
21239 case NM_ADDIUGP48:
21240 check_nms(ctx);
21241 if (rt != 0) {
21242 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21243 }
21244 break;
21245 case NM_ADDIUPC48:
21246 check_nms(ctx);
21247 if (rt != 0) {
21248 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21249 addr_off);
21250
21251 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21252 }
21253 break;
21254 case NM_LWPC48:
21255 check_nms(ctx);
21256 if (rt != 0) {
21257 TCGv t0;
21258 t0 = tcg_temp_new();
21259
21260 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21261 addr_off);
21262
21263 tcg_gen_movi_tl(t0, addr);
21264 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21265 tcg_temp_free(t0);
21266 }
21267 break;
21268 case NM_SWPC48:
21269 check_nms(ctx);
21270 {
21271 TCGv t0, t1;
21272 t0 = tcg_temp_new();
21273 t1 = tcg_temp_new();
21274
21275 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21276 addr_off);
21277
21278 tcg_gen_movi_tl(t0, addr);
21279 gen_load_gpr(t1, rt);
21280
21281 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21282
21283 tcg_temp_free(t0);
21284 tcg_temp_free(t1);
21285 }
21286 break;
21287 default:
21288 generate_exception_end(ctx, EXCP_RI);
21289 break;
21290 }
21291 return 6;
21292 }
21293 case NM_P_U12:
21294 switch (extract32(ctx->opcode, 12, 4)) {
21295 case NM_ORI:
21296 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21297 break;
21298 case NM_XORI:
21299 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21300 break;
21301 case NM_ANDI:
21302 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21303 break;
21304 case NM_P_SR:
21305 switch (extract32(ctx->opcode, 20, 1)) {
21306 case NM_PP_SR:
21307 switch (ctx->opcode & 3) {
21308 case NM_SAVE:
21309 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21310 extract32(ctx->opcode, 2, 1),
21311 extract32(ctx->opcode, 3, 9) << 3);
21312 break;
21313 case NM_RESTORE:
21314 case NM_RESTORE_JRC:
21315 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21316 extract32(ctx->opcode, 2, 1),
21317 extract32(ctx->opcode, 3, 9) << 3);
21318 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21319 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21320 }
21321 break;
21322 default:
21323 generate_exception_end(ctx, EXCP_RI);
21324 break;
21325 }
21326 break;
21327 case NM_P_SR_F:
21328 generate_exception_end(ctx, EXCP_RI);
21329 break;
21330 }
21331 break;
21332 case NM_SLTI:
21333 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21334 break;
21335 case NM_SLTIU:
21336 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21337 break;
21338 case NM_SEQI:
21339 {
21340 TCGv t0 = tcg_temp_new();
21341
21342 imm = extract32(ctx->opcode, 0, 12);
21343 gen_load_gpr(t0, rs);
21344 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21345 gen_store_gpr(t0, rt);
21346
21347 tcg_temp_free(t0);
21348 }
21349 break;
21350 case NM_ADDIUNEG:
21351 imm = (int16_t) extract32(ctx->opcode, 0, 12);
21352 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21353 break;
21354 case NM_P_SHIFT:
21355 {
21356 int shift = extract32(ctx->opcode, 0, 5);
21357 switch (extract32(ctx->opcode, 5, 4)) {
21358 case NM_P_SLL:
21359 if (rt == 0 && shift == 0) {
21360 /* NOP */
21361 } else if (rt == 0 && shift == 3) {
21362 /* EHB - treat as NOP */
21363 } else if (rt == 0 && shift == 5) {
21364 /* PAUSE - treat as NOP */
21365 } else if (rt == 0 && shift == 6) {
21366 /* SYNC */
21367 gen_sync(extract32(ctx->opcode, 16, 5));
21368 } else {
21369 /* SLL */
21370 gen_shift_imm(ctx, OPC_SLL, rt, rs,
21371 extract32(ctx->opcode, 0, 5));
21372 }
21373 break;
21374 case NM_SRL:
21375 gen_shift_imm(ctx, OPC_SRL, rt, rs,
21376 extract32(ctx->opcode, 0, 5));
21377 break;
21378 case NM_SRA:
21379 gen_shift_imm(ctx, OPC_SRA, rt, rs,
21380 extract32(ctx->opcode, 0, 5));
21381 break;
21382 case NM_ROTR:
21383 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21384 extract32(ctx->opcode, 0, 5));
21385 break;
21386 }
21387 }
21388 break;
21389 case NM_P_ROTX:
21390 check_nms(ctx);
21391 if (rt != 0) {
21392 TCGv t0 = tcg_temp_new();
21393 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21394 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21395 << 1);
21396 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21397
21398 gen_load_gpr(t0, rs);
21399 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21400 tcg_temp_free(t0);
21401
21402 tcg_temp_free_i32(shift);
21403 tcg_temp_free_i32(shiftx);
21404 tcg_temp_free_i32(stripe);
21405 }
21406 break;
21407 case NM_P_INS:
21408 switch (((ctx->opcode >> 10) & 2) |
21409 (extract32(ctx->opcode, 5, 1))) {
21410 case NM_INS:
21411 check_nms(ctx);
21412 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21413 extract32(ctx->opcode, 6, 5));
21414 break;
21415 default:
21416 generate_exception_end(ctx, EXCP_RI);
21417 break;
21418 }
21419 break;
21420 case NM_P_EXT:
21421 switch (((ctx->opcode >> 10) & 2) |
21422 (extract32(ctx->opcode, 5, 1))) {
21423 case NM_EXT:
21424 check_nms(ctx);
21425 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21426 extract32(ctx->opcode, 6, 5));
21427 break;
21428 default:
21429 generate_exception_end(ctx, EXCP_RI);
21430 break;
21431 }
21432 break;
21433 default:
21434 generate_exception_end(ctx, EXCP_RI);
21435 break;
21436 }
21437 break;
21438 case NM_POOL32F:
21439 gen_pool32f_nanomips_insn(ctx);
21440 break;
21441 case NM_POOL32S:
21442 break;
21443 case NM_P_LUI:
21444 switch (extract32(ctx->opcode, 1, 1)) {
21445 case NM_LUI:
21446 if (rt != 0) {
21447 tcg_gen_movi_tl(cpu_gpr[rt],
21448 sextract32(ctx->opcode, 0, 1) << 31 |
21449 extract32(ctx->opcode, 2, 10) << 21 |
21450 extract32(ctx->opcode, 12, 9) << 12);
21451 }
21452 break;
21453 case NM_ALUIPC:
21454 if (rt != 0) {
21455 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21456 extract32(ctx->opcode, 2, 10) << 21 |
21457 extract32(ctx->opcode, 12, 9) << 12;
21458 target_long addr;
21459 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21460 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21461 }
21462 break;
21463 }
21464 break;
21465 case NM_P_GP_BH:
21466 {
21467 uint32_t u = extract32(ctx->opcode, 0, 18);
21468
21469 switch (extract32(ctx->opcode, 18, 3)) {
21470 case NM_LBGP:
21471 gen_ld(ctx, OPC_LB, rt, 28, u);
21472 break;
21473 case NM_SBGP:
21474 gen_st(ctx, OPC_SB, rt, 28, u);
21475 break;
21476 case NM_LBUGP:
21477 gen_ld(ctx, OPC_LBU, rt, 28, u);
21478 break;
21479 case NM_ADDIUGP_B:
21480 if (rt != 0) {
21481 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21482 }
21483 break;
21484 case NM_P_GP_LH:
21485 u &= ~1;
21486 switch (ctx->opcode & 1) {
21487 case NM_LHGP:
21488 gen_ld(ctx, OPC_LH, rt, 28, u);
21489 break;
21490 case NM_LHUGP:
21491 gen_ld(ctx, OPC_LHU, rt, 28, u);
21492 break;
21493 }
21494 break;
21495 case NM_P_GP_SH:
21496 u &= ~1;
21497 switch (ctx->opcode & 1) {
21498 case NM_SHGP:
21499 gen_st(ctx, OPC_SH, rt, 28, u);
21500 break;
21501 default:
21502 generate_exception_end(ctx, EXCP_RI);
21503 break;
21504 }
21505 break;
21506 case NM_P_GP_CP1:
21507 u &= ~0x3;
21508 switch (ctx->opcode & 0x3) {
21509 case NM_LWC1GP:
21510 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21511 break;
21512 case NM_LDC1GP:
21513 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21514 break;
21515 case NM_SWC1GP:
21516 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21517 break;
21518 case NM_SDC1GP:
21519 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21520 break;
21521 }
21522 break;
21523 default:
21524 generate_exception_end(ctx, EXCP_RI);
21525 break;
21526 }
21527 }
21528 break;
21529 case NM_P_LS_U12:
21530 {
21531 uint32_t u = extract32(ctx->opcode, 0, 12);
21532
21533 switch (extract32(ctx->opcode, 12, 4)) {
21534 case NM_P_PREFU12:
21535 if (rt == 31) {
21536 /* SYNCI */
21537 /*
21538 * Break the TB to be able to sync copied instructions
21539 * immediately.
21540 */
21541 ctx->base.is_jmp = DISAS_STOP;
21542 } else {
21543 /* PREF */
21544 /* Treat as NOP. */
21545 }
21546 break;
21547 case NM_LB:
21548 gen_ld(ctx, OPC_LB, rt, rs, u);
21549 break;
21550 case NM_LH:
21551 gen_ld(ctx, OPC_LH, rt, rs, u);
21552 break;
21553 case NM_LW:
21554 gen_ld(ctx, OPC_LW, rt, rs, u);
21555 break;
21556 case NM_LBU:
21557 gen_ld(ctx, OPC_LBU, rt, rs, u);
21558 break;
21559 case NM_LHU:
21560 gen_ld(ctx, OPC_LHU, rt, rs, u);
21561 break;
21562 case NM_SB:
21563 gen_st(ctx, OPC_SB, rt, rs, u);
21564 break;
21565 case NM_SH:
21566 gen_st(ctx, OPC_SH, rt, rs, u);
21567 break;
21568 case NM_SW:
21569 gen_st(ctx, OPC_SW, rt, rs, u);
21570 break;
21571 case NM_LWC1:
21572 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21573 break;
21574 case NM_LDC1:
21575 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21576 break;
21577 case NM_SWC1:
21578 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21579 break;
21580 case NM_SDC1:
21581 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21582 break;
21583 default:
21584 generate_exception_end(ctx, EXCP_RI);
21585 break;
21586 }
21587 }
21588 break;
21589 case NM_P_LS_S9:
21590 {
21591 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21592 extract32(ctx->opcode, 0, 8);
21593
21594 switch (extract32(ctx->opcode, 8, 3)) {
21595 case NM_P_LS_S0:
21596 switch (extract32(ctx->opcode, 11, 4)) {
21597 case NM_LBS9:
21598 gen_ld(ctx, OPC_LB, rt, rs, s);
21599 break;
21600 case NM_LHS9:
21601 gen_ld(ctx, OPC_LH, rt, rs, s);
21602 break;
21603 case NM_LWS9:
21604 gen_ld(ctx, OPC_LW, rt, rs, s);
21605 break;
21606 case NM_LBUS9:
21607 gen_ld(ctx, OPC_LBU, rt, rs, s);
21608 break;
21609 case NM_LHUS9:
21610 gen_ld(ctx, OPC_LHU, rt, rs, s);
21611 break;
21612 case NM_SBS9:
21613 gen_st(ctx, OPC_SB, rt, rs, s);
21614 break;
21615 case NM_SHS9:
21616 gen_st(ctx, OPC_SH, rt, rs, s);
21617 break;
21618 case NM_SWS9:
21619 gen_st(ctx, OPC_SW, rt, rs, s);
21620 break;
21621 case NM_LWC1S9:
21622 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21623 break;
21624 case NM_LDC1S9:
21625 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21626 break;
21627 case NM_SWC1S9:
21628 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21629 break;
21630 case NM_SDC1S9:
21631 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21632 break;
21633 case NM_P_PREFS9:
21634 if (rt == 31) {
21635 /* SYNCI */
21636 /*
21637 * Break the TB to be able to sync copied instructions
21638 * immediately.
21639 */
21640 ctx->base.is_jmp = DISAS_STOP;
21641 } else {
21642 /* PREF */
21643 /* Treat as NOP. */
21644 }
21645 break;
21646 default:
21647 generate_exception_end(ctx, EXCP_RI);
21648 break;
21649 }
21650 break;
21651 case NM_P_LS_S1:
21652 switch (extract32(ctx->opcode, 11, 4)) {
21653 case NM_UALH:
21654 case NM_UASH:
21655 check_nms(ctx);
21656 {
21657 TCGv t0 = tcg_temp_new();
21658 TCGv t1 = tcg_temp_new();
21659
21660 gen_base_offset_addr(ctx, t0, rs, s);
21661
21662 switch (extract32(ctx->opcode, 11, 4)) {
21663 case NM_UALH:
21664 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21665 MO_UNALN);
21666 gen_store_gpr(t0, rt);
21667 break;
21668 case NM_UASH:
21669 gen_load_gpr(t1, rt);
21670 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21671 MO_UNALN);
21672 break;
21673 }
21674 tcg_temp_free(t0);
21675 tcg_temp_free(t1);
21676 }
21677 break;
21678 case NM_P_LL:
21679 switch (ctx->opcode & 0x03) {
21680 case NM_LL:
21681 gen_ld(ctx, OPC_LL, rt, rs, s);
21682 break;
21683 case NM_LLWP:
21684 check_xnp(ctx);
21685 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21686 break;
21687 }
21688 break;
21689 case NM_P_SC:
21690 switch (ctx->opcode & 0x03) {
21691 case NM_SC:
21692 gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
21693 break;
21694 case NM_SCWP:
21695 check_xnp(ctx);
21696 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21697 false);
21698 break;
21699 }
21700 break;
21701 case NM_CACHE:
21702 check_cp0_enabled(ctx);
21703 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21704 gen_cache_operation(ctx, rt, rs, s);
21705 }
21706 break;
21707 }
21708 break;
21709 case NM_P_LS_E0:
21710 switch (extract32(ctx->opcode, 11, 4)) {
21711 case NM_LBE:
21712 check_eva(ctx);
21713 check_cp0_enabled(ctx);
21714 gen_ld(ctx, OPC_LBE, rt, rs, s);
21715 break;
21716 case NM_SBE:
21717 check_eva(ctx);
21718 check_cp0_enabled(ctx);
21719 gen_st(ctx, OPC_SBE, rt, rs, s);
21720 break;
21721 case NM_LBUE:
21722 check_eva(ctx);
21723 check_cp0_enabled(ctx);
21724 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21725 break;
21726 case NM_P_PREFE:
21727 if (rt == 31) {
21728 /* case NM_SYNCIE */
21729 check_eva(ctx);
21730 check_cp0_enabled(ctx);
21731 /*
21732 * Break the TB to be able to sync copied instructions
21733 * immediately.
21734 */
21735 ctx->base.is_jmp = DISAS_STOP;
21736 } else {
21737 /* case NM_PREFE */
21738 check_eva(ctx);
21739 check_cp0_enabled(ctx);
21740 /* Treat as NOP. */
21741 }
21742 break;
21743 case NM_LHE:
21744 check_eva(ctx);
21745 check_cp0_enabled(ctx);
21746 gen_ld(ctx, OPC_LHE, rt, rs, s);
21747 break;
21748 case NM_SHE:
21749 check_eva(ctx);
21750 check_cp0_enabled(ctx);
21751 gen_st(ctx, OPC_SHE, rt, rs, s);
21752 break;
21753 case NM_LHUE:
21754 check_eva(ctx);
21755 check_cp0_enabled(ctx);
21756 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21757 break;
21758 case NM_CACHEE:
21759 check_nms_dl_il_sl_tl_l2c(ctx);
21760 gen_cache_operation(ctx, rt, rs, s);
21761 break;
21762 case NM_LWE:
21763 check_eva(ctx);
21764 check_cp0_enabled(ctx);
21765 gen_ld(ctx, OPC_LWE, rt, rs, s);
21766 break;
21767 case NM_SWE:
21768 check_eva(ctx);
21769 check_cp0_enabled(ctx);
21770 gen_st(ctx, OPC_SWE, rt, rs, s);
21771 break;
21772 case NM_P_LLE:
21773 switch (extract32(ctx->opcode, 2, 2)) {
21774 case NM_LLE:
21775 check_xnp(ctx);
21776 check_eva(ctx);
21777 check_cp0_enabled(ctx);
21778 gen_ld(ctx, OPC_LLE, rt, rs, s);
21779 break;
21780 case NM_LLWPE:
21781 check_xnp(ctx);
21782 check_eva(ctx);
21783 check_cp0_enabled(ctx);
21784 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21785 break;
21786 default:
21787 generate_exception_end(ctx, EXCP_RI);
21788 break;
21789 }
21790 break;
21791 case NM_P_SCE:
21792 switch (extract32(ctx->opcode, 2, 2)) {
21793 case NM_SCE:
21794 check_xnp(ctx);
21795 check_eva(ctx);
21796 check_cp0_enabled(ctx);
21797 gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
21798 break;
21799 case NM_SCWPE:
21800 check_xnp(ctx);
21801 check_eva(ctx);
21802 check_cp0_enabled(ctx);
21803 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21804 true);
21805 break;
21806 default:
21807 generate_exception_end(ctx, EXCP_RI);
21808 break;
21809 }
21810 break;
21811 }
21812 break;
21813 case NM_P_LS_WM:
21814 case NM_P_LS_UAWM:
21815 check_nms(ctx);
21816 {
21817 int count = extract32(ctx->opcode, 12, 3);
21818 int counter = 0;
21819
21820 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21821 extract32(ctx->opcode, 0, 8);
21822 TCGv va = tcg_temp_new();
21823 TCGv t1 = tcg_temp_new();
21824 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21825 NM_P_LS_UAWM ? MO_UNALN : 0;
21826
21827 count = (count == 0) ? 8 : count;
21828 while (counter != count) {
21829 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21830 int this_offset = offset + (counter << 2);
21831
21832 gen_base_offset_addr(ctx, va, rs, this_offset);
21833
21834 switch (extract32(ctx->opcode, 11, 1)) {
21835 case NM_LWM:
21836 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21837 memop | MO_TESL);
21838 gen_store_gpr(t1, this_rt);
21839 if ((this_rt == rs) &&
21840 (counter != (count - 1))) {
21841 /* UNPREDICTABLE */
21842 }
21843 break;
21844 case NM_SWM:
21845 this_rt = (rt == 0) ? 0 : this_rt;
21846 gen_load_gpr(t1, this_rt);
21847 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21848 memop | MO_TEUL);
21849 break;
21850 }
21851 counter++;
21852 }
21853 tcg_temp_free(va);
21854 tcg_temp_free(t1);
21855 }
21856 break;
21857 default:
21858 generate_exception_end(ctx, EXCP_RI);
21859 break;
21860 }
21861 }
21862 break;
21863 case NM_MOVE_BALC:
21864 check_nms(ctx);
21865 {
21866 TCGv t0 = tcg_temp_new();
21867 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21868 extract32(ctx->opcode, 1, 20) << 1;
21869 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21870 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21871 extract32(ctx->opcode, 21, 3));
21872 gen_load_gpr(t0, rt);
21873 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21874 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21875 tcg_temp_free(t0);
21876 }
21877 break;
21878 case NM_P_BAL:
21879 {
21880 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21881 extract32(ctx->opcode, 1, 24) << 1;
21882
21883 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21884 /* BC */
21885 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21886 } else {
21887 /* BALC */
21888 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21889 }
21890 }
21891 break;
21892 case NM_P_J:
21893 switch (extract32(ctx->opcode, 12, 4)) {
21894 case NM_JALRC:
21895 case NM_JALRC_HB:
21896 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21897 break;
21898 case NM_P_BALRSC:
21899 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21900 break;
21901 default:
21902 generate_exception_end(ctx, EXCP_RI);
21903 break;
21904 }
21905 break;
21906 case NM_P_BR1:
21907 {
21908 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21909 extract32(ctx->opcode, 1, 13) << 1;
21910 switch (extract32(ctx->opcode, 14, 2)) {
21911 case NM_BEQC:
21912 check_nms(ctx);
21913 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21914 break;
21915 case NM_P_BR3A:
21916 s = sextract32(ctx->opcode, 0, 1) << 14 |
21917 extract32(ctx->opcode, 1, 13) << 1;
21918 check_cp1_enabled(ctx);
21919 switch (extract32(ctx->opcode, 16, 5)) {
21920 case NM_BC1EQZC:
21921 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21922 break;
21923 case NM_BC1NEZC:
21924 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21925 break;
21926 case NM_BPOSGE32C:
21927 check_dsp_r3(ctx);
21928 {
21929 int32_t imm = extract32(ctx->opcode, 1, 13) |
21930 extract32(ctx->opcode, 0, 1) << 13;
21931
21932 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21933 imm);
21934 }
21935 break;
21936 default:
21937 generate_exception_end(ctx, EXCP_RI);
21938 break;
21939 }
21940 break;
21941 case NM_BGEC:
21942 if (rs == rt) {
21943 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21944 } else {
21945 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21946 }
21947 break;
21948 case NM_BGEUC:
21949 if (rs == rt || rt == 0) {
21950 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21951 } else if (rs == 0) {
21952 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21953 } else {
21954 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21955 }
21956 break;
21957 }
21958 }
21959 break;
21960 case NM_P_BR2:
21961 {
21962 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21963 extract32(ctx->opcode, 1, 13) << 1;
21964 switch (extract32(ctx->opcode, 14, 2)) {
21965 case NM_BNEC:
21966 check_nms(ctx);
21967 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21968 break;
21969 case NM_BLTC:
21970 if (rs != 0 && rt != 0 && rs == rt) {
21971 /* NOP */
21972 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21973 } else {
21974 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21975 }
21976 break;
21977 case NM_BLTUC:
21978 if (rs == 0 || rs == rt) {
21979 /* NOP */
21980 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21981 } else {
21982 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21983 }
21984 break;
21985 default:
21986 generate_exception_end(ctx, EXCP_RI);
21987 break;
21988 }
21989 }
21990 break;
21991 case NM_P_BRI:
21992 {
21993 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21994 extract32(ctx->opcode, 1, 10) << 1;
21995 uint32_t u = extract32(ctx->opcode, 11, 7);
21996
21997 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21998 rt, u, s);
21999 }
22000 break;
22001 default:
22002 generate_exception_end(ctx, EXCP_RI);
22003 break;
22004 }
22005 return 4;
22006 }
22007
22008 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
22009 {
22010 uint32_t op;
22011 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
22012 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22013 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
22014 int offset;
22015 int imm;
22016
22017 /* make sure instructions are on a halfword boundary */
22018 if (ctx->base.pc_next & 0x1) {
22019 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
22020 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
22021 tcg_temp_free(tmp);
22022 generate_exception_end(ctx, EXCP_AdEL);
22023 return 2;
22024 }
22025
22026 op = extract32(ctx->opcode, 10, 6);
22027 switch (op) {
22028 case NM_P16_MV:
22029 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22030 if (rt != 0) {
22031 /* MOVE */
22032 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
22033 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
22034 } else {
22035 /* P16.RI */
22036 switch (extract32(ctx->opcode, 3, 2)) {
22037 case NM_P16_SYSCALL:
22038 if (extract32(ctx->opcode, 2, 1) == 0) {
22039 generate_exception_end(ctx, EXCP_SYSCALL);
22040 } else {
22041 generate_exception_end(ctx, EXCP_RI);
22042 }
22043 break;
22044 case NM_BREAK16:
22045 generate_exception_end(ctx, EXCP_BREAK);
22046 break;
22047 case NM_SDBBP16:
22048 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
22049 gen_helper_do_semihosting(cpu_env);
22050 } else {
22051 if (ctx->hflags & MIPS_HFLAG_SBRI) {
22052 generate_exception_end(ctx, EXCP_RI);
22053 } else {
22054 generate_exception_end(ctx, EXCP_DBp);
22055 }
22056 }
22057 break;
22058 default:
22059 generate_exception_end(ctx, EXCP_RI);
22060 break;
22061 }
22062 }
22063 break;
22064 case NM_P16_SHIFT:
22065 {
22066 int shift = extract32(ctx->opcode, 0, 3);
22067 uint32_t opc = 0;
22068 shift = (shift == 0) ? 8 : shift;
22069
22070 switch (extract32(ctx->opcode, 3, 1)) {
22071 case NM_SLL16:
22072 opc = OPC_SLL;
22073 break;
22074 case NM_SRL16:
22075 opc = OPC_SRL;
22076 break;
22077 }
22078 gen_shift_imm(ctx, opc, rt, rs, shift);
22079 }
22080 break;
22081 case NM_P16C:
22082 switch (ctx->opcode & 1) {
22083 case NM_POOL16C_0:
22084 gen_pool16c_nanomips_insn(ctx);
22085 break;
22086 case NM_LWXS16:
22087 gen_ldxs(ctx, rt, rs, rd);
22088 break;
22089 }
22090 break;
22091 case NM_P16_A1:
22092 switch (extract32(ctx->opcode, 6, 1)) {
22093 case NM_ADDIUR1SP:
22094 imm = extract32(ctx->opcode, 0, 6) << 2;
22095 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
22096 break;
22097 default:
22098 generate_exception_end(ctx, EXCP_RI);
22099 break;
22100 }
22101 break;
22102 case NM_P16_A2:
22103 switch (extract32(ctx->opcode, 3, 1)) {
22104 case NM_ADDIUR2:
22105 imm = extract32(ctx->opcode, 0, 3) << 2;
22106 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
22107 break;
22108 case NM_P_ADDIURS5:
22109 rt = extract32(ctx->opcode, 5, 5);
22110 if (rt != 0) {
22111 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22112 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
22113 (extract32(ctx->opcode, 0, 3));
22114 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
22115 }
22116 break;
22117 }
22118 break;
22119 case NM_P16_ADDU:
22120 switch (ctx->opcode & 0x1) {
22121 case NM_ADDU16:
22122 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
22123 break;
22124 case NM_SUBU16:
22125 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
22126 break;
22127 }
22128 break;
22129 case NM_P16_4X4:
22130 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22131 extract32(ctx->opcode, 5, 3);
22132 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22133 extract32(ctx->opcode, 0, 3);
22134 rt = decode_gpr_gpr4(rt);
22135 rs = decode_gpr_gpr4(rs);
22136 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
22137 (extract32(ctx->opcode, 3, 1))) {
22138 case NM_ADDU4X4:
22139 check_nms(ctx);
22140 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
22141 break;
22142 case NM_MUL4X4:
22143 check_nms(ctx);
22144 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
22145 break;
22146 default:
22147 generate_exception_end(ctx, EXCP_RI);
22148 break;
22149 }
22150 break;
22151 case NM_LI16:
22152 {
22153 int imm = extract32(ctx->opcode, 0, 7);
22154 imm = (imm == 0x7f ? -1 : imm);
22155 if (rt != 0) {
22156 tcg_gen_movi_tl(cpu_gpr[rt], imm);
22157 }
22158 }
22159 break;
22160 case NM_ANDI16:
22161 {
22162 uint32_t u = extract32(ctx->opcode, 0, 4);
22163 u = (u == 12) ? 0xff :
22164 (u == 13) ? 0xffff : u;
22165 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22166 }
22167 break;
22168 case NM_P16_LB:
22169 offset = extract32(ctx->opcode, 0, 2);
22170 switch (extract32(ctx->opcode, 2, 2)) {
22171 case NM_LB16:
22172 gen_ld(ctx, OPC_LB, rt, rs, offset);
22173 break;
22174 case NM_SB16:
22175 rt = decode_gpr_gpr3_src_store(
22176 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22177 gen_st(ctx, OPC_SB, rt, rs, offset);
22178 break;
22179 case NM_LBU16:
22180 gen_ld(ctx, OPC_LBU, rt, rs, offset);
22181 break;
22182 default:
22183 generate_exception_end(ctx, EXCP_RI);
22184 break;
22185 }
22186 break;
22187 case NM_P16_LH:
22188 offset = extract32(ctx->opcode, 1, 2) << 1;
22189 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22190 case NM_LH16:
22191 gen_ld(ctx, OPC_LH, rt, rs, offset);
22192 break;
22193 case NM_SH16:
22194 rt = decode_gpr_gpr3_src_store(
22195 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22196 gen_st(ctx, OPC_SH, rt, rs, offset);
22197 break;
22198 case NM_LHU16:
22199 gen_ld(ctx, OPC_LHU, rt, rs, offset);
22200 break;
22201 default:
22202 generate_exception_end(ctx, EXCP_RI);
22203 break;
22204 }
22205 break;
22206 case NM_LW16:
22207 offset = extract32(ctx->opcode, 0, 4) << 2;
22208 gen_ld(ctx, OPC_LW, rt, rs, offset);
22209 break;
22210 case NM_LWSP16:
22211 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22212 offset = extract32(ctx->opcode, 0, 5) << 2;
22213 gen_ld(ctx, OPC_LW, rt, 29, offset);
22214 break;
22215 case NM_LW4X4:
22216 check_nms(ctx);
22217 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22218 extract32(ctx->opcode, 5, 3);
22219 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22220 extract32(ctx->opcode, 0, 3);
22221 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22222 (extract32(ctx->opcode, 8, 1) << 2);
22223 rt = decode_gpr_gpr4(rt);
22224 rs = decode_gpr_gpr4(rs);
22225 gen_ld(ctx, OPC_LW, rt, rs, offset);
22226 break;
22227 case NM_SW4X4:
22228 check_nms(ctx);
22229 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22230 extract32(ctx->opcode, 5, 3);
22231 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22232 extract32(ctx->opcode, 0, 3);
22233 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22234 (extract32(ctx->opcode, 8, 1) << 2);
22235 rt = decode_gpr_gpr4_zero(rt);
22236 rs = decode_gpr_gpr4(rs);
22237 gen_st(ctx, OPC_SW, rt, rs, offset);
22238 break;
22239 case NM_LWGP16:
22240 offset = extract32(ctx->opcode, 0, 7) << 2;
22241 gen_ld(ctx, OPC_LW, rt, 28, offset);
22242 break;
22243 case NM_SWSP16:
22244 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22245 offset = extract32(ctx->opcode, 0, 5) << 2;
22246 gen_st(ctx, OPC_SW, rt, 29, offset);
22247 break;
22248 case NM_SW16:
22249 rt = decode_gpr_gpr3_src_store(
22250 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22251 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22252 offset = extract32(ctx->opcode, 0, 4) << 2;
22253 gen_st(ctx, OPC_SW, rt, rs, offset);
22254 break;
22255 case NM_SWGP16:
22256 rt = decode_gpr_gpr3_src_store(
22257 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22258 offset = extract32(ctx->opcode, 0, 7) << 2;
22259 gen_st(ctx, OPC_SW, rt, 28, offset);
22260 break;
22261 case NM_BC16:
22262 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22263 (sextract32(ctx->opcode, 0, 1) << 10) |
22264 (extract32(ctx->opcode, 1, 9) << 1));
22265 break;
22266 case NM_BALC16:
22267 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22268 (sextract32(ctx->opcode, 0, 1) << 10) |
22269 (extract32(ctx->opcode, 1, 9) << 1));
22270 break;
22271 case NM_BEQZC16:
22272 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22273 (sextract32(ctx->opcode, 0, 1) << 7) |
22274 (extract32(ctx->opcode, 1, 6) << 1));
22275 break;
22276 case NM_BNEZC16:
22277 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22278 (sextract32(ctx->opcode, 0, 1) << 7) |
22279 (extract32(ctx->opcode, 1, 6) << 1));
22280 break;
22281 case NM_P16_BR:
22282 switch (ctx->opcode & 0xf) {
22283 case 0:
22284 /* P16.JRC */
22285 switch (extract32(ctx->opcode, 4, 1)) {
22286 case NM_JRC:
22287 gen_compute_branch_nm(ctx, OPC_JR, 2,
22288 extract32(ctx->opcode, 5, 5), 0, 0);
22289 break;
22290 case NM_JALRC16:
22291 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22292 extract32(ctx->opcode, 5, 5), 31, 0);
22293 break;
22294 }
22295 break;
22296 default:
22297 {
22298 /* P16.BRI */
22299 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22300 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22301 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22302 extract32(ctx->opcode, 0, 4) << 1);
22303 }
22304 break;
22305 }
22306 break;
22307 case NM_P16_SR:
22308 {
22309 int count = extract32(ctx->opcode, 0, 4);
22310 int u = extract32(ctx->opcode, 4, 4) << 4;
22311
22312 rt = 30 + extract32(ctx->opcode, 9, 1);
22313 switch (extract32(ctx->opcode, 8, 1)) {
22314 case NM_SAVE16:
22315 gen_save(ctx, rt, count, 0, u);
22316 break;
22317 case NM_RESTORE_JRC16:
22318 gen_restore(ctx, rt, count, 0, u);
22319 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22320 break;
22321 }
22322 }
22323 break;
22324 case NM_MOVEP:
22325 case NM_MOVEPREV:
22326 check_nms(ctx);
22327 {
22328 static const int gpr2reg1[] = {4, 5, 6, 7};
22329 static const int gpr2reg2[] = {5, 6, 7, 8};
22330 int re;
22331 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22332 extract32(ctx->opcode, 8, 1);
22333 int r1 = gpr2reg1[rd2];
22334 int r2 = gpr2reg2[rd2];
22335 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22336 extract32(ctx->opcode, 0, 3);
22337 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22338 extract32(ctx->opcode, 5, 3);
22339 TCGv t0 = tcg_temp_new();
22340 TCGv t1 = tcg_temp_new();
22341 if (op == NM_MOVEP) {
22342 rd = r1;
22343 re = r2;
22344 rs = decode_gpr_gpr4_zero(r3);
22345 rt = decode_gpr_gpr4_zero(r4);
22346 } else {
22347 rd = decode_gpr_gpr4(r3);
22348 re = decode_gpr_gpr4(r4);
22349 rs = r1;
22350 rt = r2;
22351 }
22352 gen_load_gpr(t0, rs);
22353 gen_load_gpr(t1, rt);
22354 tcg_gen_mov_tl(cpu_gpr[rd], t0);
22355 tcg_gen_mov_tl(cpu_gpr[re], t1);
22356 tcg_temp_free(t0);
22357 tcg_temp_free(t1);
22358 }
22359 break;
22360 default:
22361 return decode_nanomips_32_48_opc(env, ctx);
22362 }
22363
22364 return 2;
22365 }
22366
22367
22368 /* SmartMIPS extension to MIPS32 */
22369
22370 #if defined(TARGET_MIPS64)
22371
22372 /* MDMX extension to MIPS64 */
22373
22374 #endif
22375
22376 /* MIPSDSP functions. */
22377 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22378 int rd, int base, int offset)
22379 {
22380 TCGv t0;
22381
22382 check_dsp(ctx);
22383 t0 = tcg_temp_new();
22384
22385 if (base == 0) {
22386 gen_load_gpr(t0, offset);
22387 } else if (offset == 0) {
22388 gen_load_gpr(t0, base);
22389 } else {
22390 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22391 }
22392
22393 switch (opc) {
22394 case OPC_LBUX:
22395 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22396 gen_store_gpr(t0, rd);
22397 break;
22398 case OPC_LHX:
22399 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22400 gen_store_gpr(t0, rd);
22401 break;
22402 case OPC_LWX:
22403 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22404 gen_store_gpr(t0, rd);
22405 break;
22406 #if defined(TARGET_MIPS64)
22407 case OPC_LDX:
22408 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22409 gen_store_gpr(t0, rd);
22410 break;
22411 #endif
22412 }
22413 tcg_temp_free(t0);
22414 }
22415
22416 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22417 int ret, int v1, int v2)
22418 {
22419 TCGv v1_t;
22420 TCGv v2_t;
22421
22422 if (ret == 0) {
22423 /* Treat as NOP. */
22424 return;
22425 }
22426
22427 v1_t = tcg_temp_new();
22428 v2_t = tcg_temp_new();
22429
22430 gen_load_gpr(v1_t, v1);
22431 gen_load_gpr(v2_t, v2);
22432
22433 switch (op1) {
22434 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22435 case OPC_MULT_G_2E:
22436 check_dsp_r2(ctx);
22437 switch (op2) {
22438 case OPC_ADDUH_QB:
22439 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22440 break;
22441 case OPC_ADDUH_R_QB:
22442 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22443 break;
22444 case OPC_ADDQH_PH:
22445 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22446 break;
22447 case OPC_ADDQH_R_PH:
22448 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22449 break;
22450 case OPC_ADDQH_W:
22451 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22452 break;
22453 case OPC_ADDQH_R_W:
22454 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22455 break;
22456 case OPC_SUBUH_QB:
22457 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22458 break;
22459 case OPC_SUBUH_R_QB:
22460 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22461 break;
22462 case OPC_SUBQH_PH:
22463 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22464 break;
22465 case OPC_SUBQH_R_PH:
22466 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22467 break;
22468 case OPC_SUBQH_W:
22469 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22470 break;
22471 case OPC_SUBQH_R_W:
22472 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22473 break;
22474 }
22475 break;
22476 case OPC_ABSQ_S_PH_DSP:
22477 switch (op2) {
22478 case OPC_ABSQ_S_QB:
22479 check_dsp_r2(ctx);
22480 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22481 break;
22482 case OPC_ABSQ_S_PH:
22483 check_dsp(ctx);
22484 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22485 break;
22486 case OPC_ABSQ_S_W:
22487 check_dsp(ctx);
22488 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22489 break;
22490 case OPC_PRECEQ_W_PHL:
22491 check_dsp(ctx);
22492 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22493 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22494 break;
22495 case OPC_PRECEQ_W_PHR:
22496 check_dsp(ctx);
22497 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22498 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22499 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22500 break;
22501 case OPC_PRECEQU_PH_QBL:
22502 check_dsp(ctx);
22503 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22504 break;
22505 case OPC_PRECEQU_PH_QBR:
22506 check_dsp(ctx);
22507 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22508 break;
22509 case OPC_PRECEQU_PH_QBLA:
22510 check_dsp(ctx);
22511 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22512 break;
22513 case OPC_PRECEQU_PH_QBRA:
22514 check_dsp(ctx);
22515 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22516 break;
22517 case OPC_PRECEU_PH_QBL:
22518 check_dsp(ctx);
22519 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22520 break;
22521 case OPC_PRECEU_PH_QBR:
22522 check_dsp(ctx);
22523 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22524 break;
22525 case OPC_PRECEU_PH_QBLA:
22526 check_dsp(ctx);
22527 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22528 break;
22529 case OPC_PRECEU_PH_QBRA:
22530 check_dsp(ctx);
22531 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22532 break;
22533 }
22534 break;
22535 case OPC_ADDU_QB_DSP:
22536 switch (op2) {
22537 case OPC_ADDQ_PH:
22538 check_dsp(ctx);
22539 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22540 break;
22541 case OPC_ADDQ_S_PH:
22542 check_dsp(ctx);
22543 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22544 break;
22545 case OPC_ADDQ_S_W:
22546 check_dsp(ctx);
22547 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22548 break;
22549 case OPC_ADDU_QB:
22550 check_dsp(ctx);
22551 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22552 break;
22553 case OPC_ADDU_S_QB:
22554 check_dsp(ctx);
22555 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22556 break;
22557 case OPC_ADDU_PH:
22558 check_dsp_r2(ctx);
22559 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22560 break;
22561 case OPC_ADDU_S_PH:
22562 check_dsp_r2(ctx);
22563 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22564 break;
22565 case OPC_SUBQ_PH:
22566 check_dsp(ctx);
22567 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22568 break;
22569 case OPC_SUBQ_S_PH:
22570 check_dsp(ctx);
22571 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22572 break;
22573 case OPC_SUBQ_S_W:
22574 check_dsp(ctx);
22575 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22576 break;
22577 case OPC_SUBU_QB:
22578 check_dsp(ctx);
22579 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22580 break;
22581 case OPC_SUBU_S_QB:
22582 check_dsp(ctx);
22583 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22584 break;
22585 case OPC_SUBU_PH:
22586 check_dsp_r2(ctx);
22587 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22588 break;
22589 case OPC_SUBU_S_PH:
22590 check_dsp_r2(ctx);
22591 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22592 break;
22593 case OPC_ADDSC:
22594 check_dsp(ctx);
22595 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22596 break;
22597 case OPC_ADDWC:
22598 check_dsp(ctx);
22599 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22600 break;
22601 case OPC_MODSUB:
22602 check_dsp(ctx);
22603 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22604 break;
22605 case OPC_RADDU_W_QB:
22606 check_dsp(ctx);
22607 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22608 break;
22609 }
22610 break;
22611 case OPC_CMPU_EQ_QB_DSP:
22612 switch (op2) {
22613 case OPC_PRECR_QB_PH:
22614 check_dsp_r2(ctx);
22615 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22616 break;
22617 case OPC_PRECRQ_QB_PH:
22618 check_dsp(ctx);
22619 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22620 break;
22621 case OPC_PRECR_SRA_PH_W:
22622 check_dsp_r2(ctx);
22623 {
22624 TCGv_i32 sa_t = tcg_const_i32(v2);
22625 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22626 cpu_gpr[ret]);
22627 tcg_temp_free_i32(sa_t);
22628 break;
22629 }
22630 case OPC_PRECR_SRA_R_PH_W:
22631 check_dsp_r2(ctx);
22632 {
22633 TCGv_i32 sa_t = tcg_const_i32(v2);
22634 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22635 cpu_gpr[ret]);
22636 tcg_temp_free_i32(sa_t);
22637 break;
22638 }
22639 case OPC_PRECRQ_PH_W:
22640 check_dsp(ctx);
22641 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22642 break;
22643 case OPC_PRECRQ_RS_PH_W:
22644 check_dsp(ctx);
22645 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22646 break;
22647 case OPC_PRECRQU_S_QB_PH:
22648 check_dsp(ctx);
22649 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22650 break;
22651 }
22652 break;
22653 #ifdef TARGET_MIPS64
22654 case OPC_ABSQ_S_QH_DSP:
22655 switch (op2) {
22656 case OPC_PRECEQ_L_PWL:
22657 check_dsp(ctx);
22658 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22659 break;
22660 case OPC_PRECEQ_L_PWR:
22661 check_dsp(ctx);
22662 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22663 break;
22664 case OPC_PRECEQ_PW_QHL:
22665 check_dsp(ctx);
22666 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22667 break;
22668 case OPC_PRECEQ_PW_QHR:
22669 check_dsp(ctx);
22670 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22671 break;
22672 case OPC_PRECEQ_PW_QHLA:
22673 check_dsp(ctx);
22674 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22675 break;
22676 case OPC_PRECEQ_PW_QHRA:
22677 check_dsp(ctx);
22678 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22679 break;
22680 case OPC_PRECEQU_QH_OBL:
22681 check_dsp(ctx);
22682 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22683 break;
22684 case OPC_PRECEQU_QH_OBR:
22685 check_dsp(ctx);
22686 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22687 break;
22688 case OPC_PRECEQU_QH_OBLA:
22689 check_dsp(ctx);
22690 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22691 break;
22692 case OPC_PRECEQU_QH_OBRA:
22693 check_dsp(ctx);
22694 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22695 break;
22696 case OPC_PRECEU_QH_OBL:
22697 check_dsp(ctx);
22698 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22699 break;
22700 case OPC_PRECEU_QH_OBR:
22701 check_dsp(ctx);
22702 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22703 break;
22704 case OPC_PRECEU_QH_OBLA:
22705 check_dsp(ctx);
22706 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22707 break;
22708 case OPC_PRECEU_QH_OBRA:
22709 check_dsp(ctx);
22710 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22711 break;
22712 case OPC_ABSQ_S_OB:
22713 check_dsp_r2(ctx);
22714 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22715 break;
22716 case OPC_ABSQ_S_PW:
22717 check_dsp(ctx);
22718 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22719 break;
22720 case OPC_ABSQ_S_QH:
22721 check_dsp(ctx);
22722 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22723 break;
22724 }
22725 break;
22726 case OPC_ADDU_OB_DSP:
22727 switch (op2) {
22728 case OPC_RADDU_L_OB:
22729 check_dsp(ctx);
22730 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22731 break;
22732 case OPC_SUBQ_PW:
22733 check_dsp(ctx);
22734 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22735 break;
22736 case OPC_SUBQ_S_PW:
22737 check_dsp(ctx);
22738 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22739 break;
22740 case OPC_SUBQ_QH:
22741 check_dsp(ctx);
22742 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22743 break;
22744 case OPC_SUBQ_S_QH:
22745 check_dsp(ctx);
22746 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22747 break;
22748 case OPC_SUBU_OB:
22749 check_dsp(ctx);
22750 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22751 break;
22752 case OPC_SUBU_S_OB:
22753 check_dsp(ctx);
22754 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22755 break;
22756 case OPC_SUBU_QH:
22757 check_dsp_r2(ctx);
22758 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22759 break;
22760 case OPC_SUBU_S_QH:
22761 check_dsp_r2(ctx);
22762 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22763 break;
22764 case OPC_SUBUH_OB:
22765 check_dsp_r2(ctx);
22766 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22767 break;
22768 case OPC_SUBUH_R_OB:
22769 check_dsp_r2(ctx);
22770 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22771 break;
22772 case OPC_ADDQ_PW:
22773 check_dsp(ctx);
22774 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22775 break;
22776 case OPC_ADDQ_S_PW:
22777 check_dsp(ctx);
22778 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22779 break;
22780 case OPC_ADDQ_QH:
22781 check_dsp(ctx);
22782 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22783 break;
22784 case OPC_ADDQ_S_QH:
22785 check_dsp(ctx);
22786 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22787 break;
22788 case OPC_ADDU_OB:
22789 check_dsp(ctx);
22790 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22791 break;
22792 case OPC_ADDU_S_OB:
22793 check_dsp(ctx);
22794 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22795 break;
22796 case OPC_ADDU_QH:
22797 check_dsp_r2(ctx);
22798 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22799 break;
22800 case OPC_ADDU_S_QH:
22801 check_dsp_r2(ctx);
22802 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22803 break;
22804 case OPC_ADDUH_OB:
22805 check_dsp_r2(ctx);
22806 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22807 break;
22808 case OPC_ADDUH_R_OB:
22809 check_dsp_r2(ctx);
22810 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22811 break;
22812 }
22813 break;
22814 case OPC_CMPU_EQ_OB_DSP:
22815 switch (op2) {
22816 case OPC_PRECR_OB_QH:
22817 check_dsp_r2(ctx);
22818 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22819 break;
22820 case OPC_PRECR_SRA_QH_PW:
22821 check_dsp_r2(ctx);
22822 {
22823 TCGv_i32 ret_t = tcg_const_i32(ret);
22824 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22825 tcg_temp_free_i32(ret_t);
22826 break;
22827 }
22828 case OPC_PRECR_SRA_R_QH_PW:
22829 check_dsp_r2(ctx);
22830 {
22831 TCGv_i32 sa_v = tcg_const_i32(ret);
22832 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22833 tcg_temp_free_i32(sa_v);
22834 break;
22835 }
22836 case OPC_PRECRQ_OB_QH:
22837 check_dsp(ctx);
22838 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22839 break;
22840 case OPC_PRECRQ_PW_L:
22841 check_dsp(ctx);
22842 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22843 break;
22844 case OPC_PRECRQ_QH_PW:
22845 check_dsp(ctx);
22846 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22847 break;
22848 case OPC_PRECRQ_RS_QH_PW:
22849 check_dsp(ctx);
22850 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22851 break;
22852 case OPC_PRECRQU_S_OB_QH:
22853 check_dsp(ctx);
22854 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22855 break;
22856 }
22857 break;
22858 #endif
22859 }
22860
22861 tcg_temp_free(v1_t);
22862 tcg_temp_free(v2_t);
22863 }
22864
22865 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22866 int ret, int v1, int v2)
22867 {
22868 uint32_t op2;
22869 TCGv t0;
22870 TCGv v1_t;
22871 TCGv v2_t;
22872
22873 if (ret == 0) {
22874 /* Treat as NOP. */
22875 return;
22876 }
22877
22878 t0 = tcg_temp_new();
22879 v1_t = tcg_temp_new();
22880 v2_t = tcg_temp_new();
22881
22882 tcg_gen_movi_tl(t0, v1);
22883 gen_load_gpr(v1_t, v1);
22884 gen_load_gpr(v2_t, v2);
22885
22886 switch (opc) {
22887 case OPC_SHLL_QB_DSP:
22888 {
22889 op2 = MASK_SHLL_QB(ctx->opcode);
22890 switch (op2) {
22891 case OPC_SHLL_QB:
22892 check_dsp(ctx);
22893 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22894 break;
22895 case OPC_SHLLV_QB:
22896 check_dsp(ctx);
22897 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22898 break;
22899 case OPC_SHLL_PH:
22900 check_dsp(ctx);
22901 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22902 break;
22903 case OPC_SHLLV_PH:
22904 check_dsp(ctx);
22905 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22906 break;
22907 case OPC_SHLL_S_PH:
22908 check_dsp(ctx);
22909 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22910 break;
22911 case OPC_SHLLV_S_PH:
22912 check_dsp(ctx);
22913 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22914 break;
22915 case OPC_SHLL_S_W:
22916 check_dsp(ctx);
22917 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22918 break;
22919 case OPC_SHLLV_S_W:
22920 check_dsp(ctx);
22921 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22922 break;
22923 case OPC_SHRL_QB:
22924 check_dsp(ctx);
22925 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22926 break;
22927 case OPC_SHRLV_QB:
22928 check_dsp(ctx);
22929 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22930 break;
22931 case OPC_SHRL_PH:
22932 check_dsp_r2(ctx);
22933 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22934 break;
22935 case OPC_SHRLV_PH:
22936 check_dsp_r2(ctx);
22937 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22938 break;
22939 case OPC_SHRA_QB:
22940 check_dsp_r2(ctx);
22941 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22942 break;
22943 case OPC_SHRA_R_QB:
22944 check_dsp_r2(ctx);
22945 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22946 break;
22947 case OPC_SHRAV_QB:
22948 check_dsp_r2(ctx);
22949 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22950 break;
22951 case OPC_SHRAV_R_QB:
22952 check_dsp_r2(ctx);
22953 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22954 break;
22955 case OPC_SHRA_PH:
22956 check_dsp(ctx);
22957 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22958 break;
22959 case OPC_SHRA_R_PH:
22960 check_dsp(ctx);
22961 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22962 break;
22963 case OPC_SHRAV_PH:
22964 check_dsp(ctx);
22965 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22966 break;
22967 case OPC_SHRAV_R_PH:
22968 check_dsp(ctx);
22969 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22970 break;
22971 case OPC_SHRA_R_W:
22972 check_dsp(ctx);
22973 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22974 break;
22975 case OPC_SHRAV_R_W:
22976 check_dsp(ctx);
22977 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22978 break;
22979 default: /* Invalid */
22980 MIPS_INVAL("MASK SHLL.QB");
22981 generate_exception_end(ctx, EXCP_RI);
22982 break;
22983 }
22984 break;
22985 }
22986 #ifdef TARGET_MIPS64
22987 case OPC_SHLL_OB_DSP:
22988 op2 = MASK_SHLL_OB(ctx->opcode);
22989 switch (op2) {
22990 case OPC_SHLL_PW:
22991 check_dsp(ctx);
22992 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22993 break;
22994 case OPC_SHLLV_PW:
22995 check_dsp(ctx);
22996 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22997 break;
22998 case OPC_SHLL_S_PW:
22999 check_dsp(ctx);
23000 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23001 break;
23002 case OPC_SHLLV_S_PW:
23003 check_dsp(ctx);
23004 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23005 break;
23006 case OPC_SHLL_OB:
23007 check_dsp(ctx);
23008 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
23009 break;
23010 case OPC_SHLLV_OB:
23011 check_dsp(ctx);
23012 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23013 break;
23014 case OPC_SHLL_QH:
23015 check_dsp(ctx);
23016 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23017 break;
23018 case OPC_SHLLV_QH:
23019 check_dsp(ctx);
23020 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23021 break;
23022 case OPC_SHLL_S_QH:
23023 check_dsp(ctx);
23024 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23025 break;
23026 case OPC_SHLLV_S_QH:
23027 check_dsp(ctx);
23028 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23029 break;
23030 case OPC_SHRA_OB:
23031 check_dsp_r2(ctx);
23032 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
23033 break;
23034 case OPC_SHRAV_OB:
23035 check_dsp_r2(ctx);
23036 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
23037 break;
23038 case OPC_SHRA_R_OB:
23039 check_dsp_r2(ctx);
23040 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
23041 break;
23042 case OPC_SHRAV_R_OB:
23043 check_dsp_r2(ctx);
23044 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
23045 break;
23046 case OPC_SHRA_PW:
23047 check_dsp(ctx);
23048 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
23049 break;
23050 case OPC_SHRAV_PW:
23051 check_dsp(ctx);
23052 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
23053 break;
23054 case OPC_SHRA_R_PW:
23055 check_dsp(ctx);
23056 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
23057 break;
23058 case OPC_SHRAV_R_PW:
23059 check_dsp(ctx);
23060 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
23061 break;
23062 case OPC_SHRA_QH:
23063 check_dsp(ctx);
23064 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
23065 break;
23066 case OPC_SHRAV_QH:
23067 check_dsp(ctx);
23068 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
23069 break;
23070 case OPC_SHRA_R_QH:
23071 check_dsp(ctx);
23072 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
23073 break;
23074 case OPC_SHRAV_R_QH:
23075 check_dsp(ctx);
23076 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
23077 break;
23078 case OPC_SHRL_OB:
23079 check_dsp(ctx);
23080 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
23081 break;
23082 case OPC_SHRLV_OB:
23083 check_dsp(ctx);
23084 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
23085 break;
23086 case OPC_SHRL_QH:
23087 check_dsp_r2(ctx);
23088 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
23089 break;
23090 case OPC_SHRLV_QH:
23091 check_dsp_r2(ctx);
23092 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
23093 break;
23094 default: /* Invalid */
23095 MIPS_INVAL("MASK SHLL.OB");
23096 generate_exception_end(ctx, EXCP_RI);
23097 break;
23098 }
23099 break;
23100 #endif
23101 }
23102
23103 tcg_temp_free(t0);
23104 tcg_temp_free(v1_t);
23105 tcg_temp_free(v2_t);
23106 }
23107
23108 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
23109 int ret, int v1, int v2, int check_ret)
23110 {
23111 TCGv_i32 t0;
23112 TCGv v1_t;
23113 TCGv v2_t;
23114
23115 if ((ret == 0) && (check_ret == 1)) {
23116 /* Treat as NOP. */
23117 return;
23118 }
23119
23120 t0 = tcg_temp_new_i32();
23121 v1_t = tcg_temp_new();
23122 v2_t = tcg_temp_new();
23123
23124 tcg_gen_movi_i32(t0, ret);
23125 gen_load_gpr(v1_t, v1);
23126 gen_load_gpr(v2_t, v2);
23127
23128 switch (op1) {
23129 /*
23130 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23131 * the same mask and op1.
23132 */
23133 case OPC_MULT_G_2E:
23134 check_dsp_r2(ctx);
23135 switch (op2) {
23136 case OPC_MUL_PH:
23137 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23138 break;
23139 case OPC_MUL_S_PH:
23140 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23141 break;
23142 case OPC_MULQ_S_W:
23143 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23144 break;
23145 case OPC_MULQ_RS_W:
23146 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23147 break;
23148 }
23149 break;
23150 case OPC_DPA_W_PH_DSP:
23151 switch (op2) {
23152 case OPC_DPAU_H_QBL:
23153 check_dsp(ctx);
23154 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
23155 break;
23156 case OPC_DPAU_H_QBR:
23157 check_dsp(ctx);
23158 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
23159 break;
23160 case OPC_DPSU_H_QBL:
23161 check_dsp(ctx);
23162 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
23163 break;
23164 case OPC_DPSU_H_QBR:
23165 check_dsp(ctx);
23166 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23167 break;
23168 case OPC_DPA_W_PH:
23169 check_dsp_r2(ctx);
23170 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23171 break;
23172 case OPC_DPAX_W_PH:
23173 check_dsp_r2(ctx);
23174 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23175 break;
23176 case OPC_DPAQ_S_W_PH:
23177 check_dsp(ctx);
23178 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23179 break;
23180 case OPC_DPAQX_S_W_PH:
23181 check_dsp_r2(ctx);
23182 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23183 break;
23184 case OPC_DPAQX_SA_W_PH:
23185 check_dsp_r2(ctx);
23186 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23187 break;
23188 case OPC_DPS_W_PH:
23189 check_dsp_r2(ctx);
23190 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23191 break;
23192 case OPC_DPSX_W_PH:
23193 check_dsp_r2(ctx);
23194 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23195 break;
23196 case OPC_DPSQ_S_W_PH:
23197 check_dsp(ctx);
23198 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23199 break;
23200 case OPC_DPSQX_S_W_PH:
23201 check_dsp_r2(ctx);
23202 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23203 break;
23204 case OPC_DPSQX_SA_W_PH:
23205 check_dsp_r2(ctx);
23206 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23207 break;
23208 case OPC_MULSAQ_S_W_PH:
23209 check_dsp(ctx);
23210 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23211 break;
23212 case OPC_DPAQ_SA_L_W:
23213 check_dsp(ctx);
23214 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23215 break;
23216 case OPC_DPSQ_SA_L_W:
23217 check_dsp(ctx);
23218 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23219 break;
23220 case OPC_MAQ_S_W_PHL:
23221 check_dsp(ctx);
23222 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23223 break;
23224 case OPC_MAQ_S_W_PHR:
23225 check_dsp(ctx);
23226 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23227 break;
23228 case OPC_MAQ_SA_W_PHL:
23229 check_dsp(ctx);
23230 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23231 break;
23232 case OPC_MAQ_SA_W_PHR:
23233 check_dsp(ctx);
23234 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23235 break;
23236 case OPC_MULSA_W_PH:
23237 check_dsp_r2(ctx);
23238 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23239 break;
23240 }
23241 break;
23242 #ifdef TARGET_MIPS64
23243 case OPC_DPAQ_W_QH_DSP:
23244 {
23245 int ac = ret & 0x03;
23246 tcg_gen_movi_i32(t0, ac);
23247
23248 switch (op2) {
23249 case OPC_DMADD:
23250 check_dsp(ctx);
23251 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23252 break;
23253 case OPC_DMADDU:
23254 check_dsp(ctx);
23255 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23256 break;
23257 case OPC_DMSUB:
23258 check_dsp(ctx);
23259 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23260 break;
23261 case OPC_DMSUBU:
23262 check_dsp(ctx);
23263 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23264 break;
23265 case OPC_DPA_W_QH:
23266 check_dsp_r2(ctx);
23267 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23268 break;
23269 case OPC_DPAQ_S_W_QH:
23270 check_dsp(ctx);
23271 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23272 break;
23273 case OPC_DPAQ_SA_L_PW:
23274 check_dsp(ctx);
23275 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23276 break;
23277 case OPC_DPAU_H_OBL:
23278 check_dsp(ctx);
23279 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23280 break;
23281 case OPC_DPAU_H_OBR:
23282 check_dsp(ctx);
23283 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23284 break;
23285 case OPC_DPS_W_QH:
23286 check_dsp_r2(ctx);
23287 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23288 break;
23289 case OPC_DPSQ_S_W_QH:
23290 check_dsp(ctx);
23291 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23292 break;
23293 case OPC_DPSQ_SA_L_PW:
23294 check_dsp(ctx);
23295 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23296 break;
23297 case OPC_DPSU_H_OBL:
23298 check_dsp(ctx);
23299 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23300 break;
23301 case OPC_DPSU_H_OBR:
23302 check_dsp(ctx);
23303 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23304 break;
23305 case OPC_MAQ_S_L_PWL:
23306 check_dsp(ctx);
23307 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23308 break;
23309 case OPC_MAQ_S_L_PWR:
23310 check_dsp(ctx);
23311 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23312 break;
23313 case OPC_MAQ_S_W_QHLL:
23314 check_dsp(ctx);
23315 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23316 break;
23317 case OPC_MAQ_SA_W_QHLL:
23318 check_dsp(ctx);
23319 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23320 break;
23321 case OPC_MAQ_S_W_QHLR:
23322 check_dsp(ctx);
23323 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23324 break;
23325 case OPC_MAQ_SA_W_QHLR:
23326 check_dsp(ctx);
23327 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23328 break;
23329 case OPC_MAQ_S_W_QHRL:
23330 check_dsp(ctx);
23331 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23332 break;
23333 case OPC_MAQ_SA_W_QHRL:
23334 check_dsp(ctx);
23335 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23336 break;
23337 case OPC_MAQ_S_W_QHRR:
23338 check_dsp(ctx);
23339 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23340 break;
23341 case OPC_MAQ_SA_W_QHRR:
23342 check_dsp(ctx);
23343 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23344 break;
23345 case OPC_MULSAQ_S_L_PW:
23346 check_dsp(ctx);
23347 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23348 break;
23349 case OPC_MULSAQ_S_W_QH:
23350 check_dsp(ctx);
23351 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23352 break;
23353 }
23354 }
23355 break;
23356 #endif
23357 case OPC_ADDU_QB_DSP:
23358 switch (op2) {
23359 case OPC_MULEU_S_PH_QBL:
23360 check_dsp(ctx);
23361 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23362 break;
23363 case OPC_MULEU_S_PH_QBR:
23364 check_dsp(ctx);
23365 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23366 break;
23367 case OPC_MULQ_RS_PH:
23368 check_dsp(ctx);
23369 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23370 break;
23371 case OPC_MULEQ_S_W_PHL:
23372 check_dsp(ctx);
23373 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23374 break;
23375 case OPC_MULEQ_S_W_PHR:
23376 check_dsp(ctx);
23377 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23378 break;
23379 case OPC_MULQ_S_PH:
23380 check_dsp_r2(ctx);
23381 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23382 break;
23383 }
23384 break;
23385 #ifdef TARGET_MIPS64
23386 case OPC_ADDU_OB_DSP:
23387 switch (op2) {
23388 case OPC_MULEQ_S_PW_QHL:
23389 check_dsp(ctx);
23390 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23391 break;
23392 case OPC_MULEQ_S_PW_QHR:
23393 check_dsp(ctx);
23394 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23395 break;
23396 case OPC_MULEU_S_QH_OBL:
23397 check_dsp(ctx);
23398 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23399 break;
23400 case OPC_MULEU_S_QH_OBR:
23401 check_dsp(ctx);
23402 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23403 break;
23404 case OPC_MULQ_RS_QH:
23405 check_dsp(ctx);
23406 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23407 break;
23408 }
23409 break;
23410 #endif
23411 }
23412
23413 tcg_temp_free_i32(t0);
23414 tcg_temp_free(v1_t);
23415 tcg_temp_free(v2_t);
23416 }
23417
23418 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23419 int ret, int val)
23420 {
23421 int16_t imm;
23422 TCGv t0;
23423 TCGv val_t;
23424
23425 if (ret == 0) {
23426 /* Treat as NOP. */
23427 return;
23428 }
23429
23430 t0 = tcg_temp_new();
23431 val_t = tcg_temp_new();
23432 gen_load_gpr(val_t, val);
23433
23434 switch (op1) {
23435 case OPC_ABSQ_S_PH_DSP:
23436 switch (op2) {
23437 case OPC_BITREV:
23438 check_dsp(ctx);
23439 gen_helper_bitrev(cpu_gpr[ret], val_t);
23440 break;
23441 case OPC_REPL_QB:
23442 check_dsp(ctx);
23443 {
23444 target_long result;
23445 imm = (ctx->opcode >> 16) & 0xFF;
23446 result = (uint32_t)imm << 24 |
23447 (uint32_t)imm << 16 |
23448 (uint32_t)imm << 8 |
23449 (uint32_t)imm;
23450 result = (int32_t)result;
23451 tcg_gen_movi_tl(cpu_gpr[ret], result);
23452 }
23453 break;
23454 case OPC_REPLV_QB:
23455 check_dsp(ctx);
23456 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23457 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23458 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23459 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23460 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23461 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23462 break;
23463 case OPC_REPL_PH:
23464 check_dsp(ctx);
23465 {
23466 imm = (ctx->opcode >> 16) & 0x03FF;
23467 imm = (int16_t)(imm << 6) >> 6;
23468 tcg_gen_movi_tl(cpu_gpr[ret], \
23469 (target_long)((int32_t)imm << 16 | \
23470 (uint16_t)imm));
23471 }
23472 break;
23473 case OPC_REPLV_PH:
23474 check_dsp(ctx);
23475 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23476 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23477 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23478 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23479 break;
23480 }
23481 break;
23482 #ifdef TARGET_MIPS64
23483 case OPC_ABSQ_S_QH_DSP:
23484 switch (op2) {
23485 case OPC_REPL_OB:
23486 check_dsp(ctx);
23487 {
23488 target_long temp;
23489
23490 imm = (ctx->opcode >> 16) & 0xFF;
23491 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23492 temp = (temp << 16) | temp;
23493 temp = (temp << 32) | temp;
23494 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23495 break;
23496 }
23497 case OPC_REPL_PW:
23498 check_dsp(ctx);
23499 {
23500 target_long temp;
23501
23502 imm = (ctx->opcode >> 16) & 0x03FF;
23503 imm = (int16_t)(imm << 6) >> 6;
23504 temp = ((target_long)imm << 32) \
23505 | ((target_long)imm & 0xFFFFFFFF);
23506 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23507 break;
23508 }
23509 case OPC_REPL_QH:
23510 check_dsp(ctx);
23511 {
23512 target_long temp;
23513
23514 imm = (ctx->opcode >> 16) & 0x03FF;
23515 imm = (int16_t)(imm << 6) >> 6;
23516
23517 temp = ((uint64_t)(uint16_t)imm << 48) |
23518 ((uint64_t)(uint16_t)imm << 32) |
23519 ((uint64_t)(uint16_t)imm << 16) |
23520 (uint64_t)(uint16_t)imm;
23521 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23522 break;
23523 }
23524 case OPC_REPLV_OB:
23525 check_dsp(ctx);
23526 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23527 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23528 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23529 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23530 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23531 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23532 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23533 break;
23534 case OPC_REPLV_PW:
23535 check_dsp(ctx);
23536 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23537 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23538 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23539 break;
23540 case OPC_REPLV_QH:
23541 check_dsp(ctx);
23542 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23543 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23544 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23545 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23546 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23547 break;
23548 }
23549 break;
23550 #endif
23551 }
23552 tcg_temp_free(t0);
23553 tcg_temp_free(val_t);
23554 }
23555
23556 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23557 uint32_t op1, uint32_t op2,
23558 int ret, int v1, int v2, int check_ret)
23559 {
23560 TCGv t1;
23561 TCGv v1_t;
23562 TCGv v2_t;
23563
23564 if ((ret == 0) && (check_ret == 1)) {
23565 /* Treat as NOP. */
23566 return;
23567 }
23568
23569 t1 = tcg_temp_new();
23570 v1_t = tcg_temp_new();
23571 v2_t = tcg_temp_new();
23572
23573 gen_load_gpr(v1_t, v1);
23574 gen_load_gpr(v2_t, v2);
23575
23576 switch (op1) {
23577 case OPC_CMPU_EQ_QB_DSP:
23578 switch (op2) {
23579 case OPC_CMPU_EQ_QB:
23580 check_dsp(ctx);
23581 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23582 break;
23583 case OPC_CMPU_LT_QB:
23584 check_dsp(ctx);
23585 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23586 break;
23587 case OPC_CMPU_LE_QB:
23588 check_dsp(ctx);
23589 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23590 break;
23591 case OPC_CMPGU_EQ_QB:
23592 check_dsp(ctx);
23593 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23594 break;
23595 case OPC_CMPGU_LT_QB:
23596 check_dsp(ctx);
23597 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23598 break;
23599 case OPC_CMPGU_LE_QB:
23600 check_dsp(ctx);
23601 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23602 break;
23603 case OPC_CMPGDU_EQ_QB:
23604 check_dsp_r2(ctx);
23605 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23606 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23607 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23608 tcg_gen_shli_tl(t1, t1, 24);
23609 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23610 break;
23611 case OPC_CMPGDU_LT_QB:
23612 check_dsp_r2(ctx);
23613 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23614 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23615 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23616 tcg_gen_shli_tl(t1, t1, 24);
23617 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23618 break;
23619 case OPC_CMPGDU_LE_QB:
23620 check_dsp_r2(ctx);
23621 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23622 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23623 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23624 tcg_gen_shli_tl(t1, t1, 24);
23625 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23626 break;
23627 case OPC_CMP_EQ_PH:
23628 check_dsp(ctx);
23629 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23630 break;
23631 case OPC_CMP_LT_PH:
23632 check_dsp(ctx);
23633 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23634 break;
23635 case OPC_CMP_LE_PH:
23636 check_dsp(ctx);
23637 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23638 break;
23639 case OPC_PICK_QB:
23640 check_dsp(ctx);
23641 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23642 break;
23643 case OPC_PICK_PH:
23644 check_dsp(ctx);
23645 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23646 break;
23647 case OPC_PACKRL_PH:
23648 check_dsp(ctx);
23649 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23650 break;
23651 }
23652 break;
23653 #ifdef TARGET_MIPS64
23654 case OPC_CMPU_EQ_OB_DSP:
23655 switch (op2) {
23656 case OPC_CMP_EQ_PW:
23657 check_dsp(ctx);
23658 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23659 break;
23660 case OPC_CMP_LT_PW:
23661 check_dsp(ctx);
23662 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23663 break;
23664 case OPC_CMP_LE_PW:
23665 check_dsp(ctx);
23666 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23667 break;
23668 case OPC_CMP_EQ_QH:
23669 check_dsp(ctx);
23670 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23671 break;
23672 case OPC_CMP_LT_QH:
23673 check_dsp(ctx);
23674 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23675 break;
23676 case OPC_CMP_LE_QH:
23677 check_dsp(ctx);
23678 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23679 break;
23680 case OPC_CMPGDU_EQ_OB:
23681 check_dsp_r2(ctx);
23682 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23683 break;
23684 case OPC_CMPGDU_LT_OB:
23685 check_dsp_r2(ctx);
23686 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23687 break;
23688 case OPC_CMPGDU_LE_OB:
23689 check_dsp_r2(ctx);
23690 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23691 break;
23692 case OPC_CMPGU_EQ_OB:
23693 check_dsp(ctx);
23694 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23695 break;
23696 case OPC_CMPGU_LT_OB:
23697 check_dsp(ctx);
23698 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23699 break;
23700 case OPC_CMPGU_LE_OB:
23701 check_dsp(ctx);
23702 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23703 break;
23704 case OPC_CMPU_EQ_OB:
23705 check_dsp(ctx);
23706 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23707 break;
23708 case OPC_CMPU_LT_OB:
23709 check_dsp(ctx);
23710 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23711 break;
23712 case OPC_CMPU_LE_OB:
23713 check_dsp(ctx);
23714 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23715 break;
23716 case OPC_PACKRL_PW:
23717 check_dsp(ctx);
23718 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23719 break;
23720 case OPC_PICK_OB:
23721 check_dsp(ctx);
23722 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23723 break;
23724 case OPC_PICK_PW:
23725 check_dsp(ctx);
23726 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23727 break;
23728 case OPC_PICK_QH:
23729 check_dsp(ctx);
23730 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23731 break;
23732 }
23733 break;
23734 #endif
23735 }
23736
23737 tcg_temp_free(t1);
23738 tcg_temp_free(v1_t);
23739 tcg_temp_free(v2_t);
23740 }
23741
23742 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23743 uint32_t op1, int rt, int rs, int sa)
23744 {
23745 TCGv t0;
23746
23747 check_dsp_r2(ctx);
23748
23749 if (rt == 0) {
23750 /* Treat as NOP. */
23751 return;
23752 }
23753
23754 t0 = tcg_temp_new();
23755 gen_load_gpr(t0, rs);
23756
23757 switch (op1) {
23758 case OPC_APPEND_DSP:
23759 switch (MASK_APPEND(ctx->opcode)) {
23760 case OPC_APPEND:
23761 if (sa != 0) {
23762 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23763 }
23764 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23765 break;
23766 case OPC_PREPEND:
23767 if (sa != 0) {
23768 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23769 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23770 tcg_gen_shli_tl(t0, t0, 32 - sa);
23771 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23772 }
23773 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23774 break;
23775 case OPC_BALIGN:
23776 sa &= 3;
23777 if (sa != 0 && sa != 2) {
23778 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23779 tcg_gen_ext32u_tl(t0, t0);
23780 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23781 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23782 }
23783 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23784 break;
23785 default: /* Invalid */
23786 MIPS_INVAL("MASK APPEND");
23787 generate_exception_end(ctx, EXCP_RI);
23788 break;
23789 }
23790 break;
23791 #ifdef TARGET_MIPS64
23792 case OPC_DAPPEND_DSP:
23793 switch (MASK_DAPPEND(ctx->opcode)) {
23794 case OPC_DAPPEND:
23795 if (sa != 0) {
23796 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23797 }
23798 break;
23799 case OPC_PREPENDD:
23800 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23801 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23802 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23803 break;
23804 case OPC_PREPENDW:
23805 if (sa != 0) {
23806 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23807 tcg_gen_shli_tl(t0, t0, 64 - sa);
23808 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23809 }
23810 break;
23811 case OPC_DBALIGN:
23812 sa &= 7;
23813 if (sa != 0 && sa != 2 && sa != 4) {
23814 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23815 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23816 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23817 }
23818 break;
23819 default: /* Invalid */
23820 MIPS_INVAL("MASK DAPPEND");
23821 generate_exception_end(ctx, EXCP_RI);
23822 break;
23823 }
23824 break;
23825 #endif
23826 }
23827 tcg_temp_free(t0);
23828 }
23829
23830 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23831 int ret, int v1, int v2, int check_ret)
23832
23833 {
23834 TCGv t0;
23835 TCGv t1;
23836 TCGv v1_t;
23837 TCGv v2_t;
23838 int16_t imm;
23839
23840 if ((ret == 0) && (check_ret == 1)) {
23841 /* Treat as NOP. */
23842 return;
23843 }
23844
23845 t0 = tcg_temp_new();
23846 t1 = tcg_temp_new();
23847 v1_t = tcg_temp_new();
23848 v2_t = tcg_temp_new();
23849
23850 gen_load_gpr(v1_t, v1);
23851 gen_load_gpr(v2_t, v2);
23852
23853 switch (op1) {
23854 case OPC_EXTR_W_DSP:
23855 check_dsp(ctx);
23856 switch (op2) {
23857 case OPC_EXTR_W:
23858 tcg_gen_movi_tl(t0, v2);
23859 tcg_gen_movi_tl(t1, v1);
23860 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23861 break;
23862 case OPC_EXTR_R_W:
23863 tcg_gen_movi_tl(t0, v2);
23864 tcg_gen_movi_tl(t1, v1);
23865 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23866 break;
23867 case OPC_EXTR_RS_W:
23868 tcg_gen_movi_tl(t0, v2);
23869 tcg_gen_movi_tl(t1, v1);
23870 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23871 break;
23872 case OPC_EXTR_S_H:
23873 tcg_gen_movi_tl(t0, v2);
23874 tcg_gen_movi_tl(t1, v1);
23875 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23876 break;
23877 case OPC_EXTRV_S_H:
23878 tcg_gen_movi_tl(t0, v2);
23879 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23880 break;
23881 case OPC_EXTRV_W:
23882 tcg_gen_movi_tl(t0, v2);
23883 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23884 break;
23885 case OPC_EXTRV_R_W:
23886 tcg_gen_movi_tl(t0, v2);
23887 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23888 break;
23889 case OPC_EXTRV_RS_W:
23890 tcg_gen_movi_tl(t0, v2);
23891 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23892 break;
23893 case OPC_EXTP:
23894 tcg_gen_movi_tl(t0, v2);
23895 tcg_gen_movi_tl(t1, v1);
23896 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23897 break;
23898 case OPC_EXTPV:
23899 tcg_gen_movi_tl(t0, v2);
23900 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23901 break;
23902 case OPC_EXTPDP:
23903 tcg_gen_movi_tl(t0, v2);
23904 tcg_gen_movi_tl(t1, v1);
23905 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23906 break;
23907 case OPC_EXTPDPV:
23908 tcg_gen_movi_tl(t0, v2);
23909 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23910 break;
23911 case OPC_SHILO:
23912 imm = (ctx->opcode >> 20) & 0x3F;
23913 tcg_gen_movi_tl(t0, ret);
23914 tcg_gen_movi_tl(t1, imm);
23915 gen_helper_shilo(t0, t1, cpu_env);
23916 break;
23917 case OPC_SHILOV:
23918 tcg_gen_movi_tl(t0, ret);
23919 gen_helper_shilo(t0, v1_t, cpu_env);
23920 break;
23921 case OPC_MTHLIP:
23922 tcg_gen_movi_tl(t0, ret);
23923 gen_helper_mthlip(t0, v1_t, cpu_env);
23924 break;
23925 case OPC_WRDSP:
23926 imm = (ctx->opcode >> 11) & 0x3FF;
23927 tcg_gen_movi_tl(t0, imm);
23928 gen_helper_wrdsp(v1_t, t0, cpu_env);
23929 break;
23930 case OPC_RDDSP:
23931 imm = (ctx->opcode >> 16) & 0x03FF;
23932 tcg_gen_movi_tl(t0, imm);
23933 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23934 break;
23935 }
23936 break;
23937 #ifdef TARGET_MIPS64
23938 case OPC_DEXTR_W_DSP:
23939 check_dsp(ctx);
23940 switch (op2) {
23941 case OPC_DMTHLIP:
23942 tcg_gen_movi_tl(t0, ret);
23943 gen_helper_dmthlip(v1_t, t0, cpu_env);
23944 break;
23945 case OPC_DSHILO:
23946 {
23947 int shift = (ctx->opcode >> 19) & 0x7F;
23948 int ac = (ctx->opcode >> 11) & 0x03;
23949 tcg_gen_movi_tl(t0, shift);
23950 tcg_gen_movi_tl(t1, ac);
23951 gen_helper_dshilo(t0, t1, cpu_env);
23952 break;
23953 }
23954 case OPC_DSHILOV:
23955 {
23956 int ac = (ctx->opcode >> 11) & 0x03;
23957 tcg_gen_movi_tl(t0, ac);
23958 gen_helper_dshilo(v1_t, t0, cpu_env);
23959 break;
23960 }
23961 case OPC_DEXTP:
23962 tcg_gen_movi_tl(t0, v2);
23963 tcg_gen_movi_tl(t1, v1);
23964
23965 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23966 break;
23967 case OPC_DEXTPV:
23968 tcg_gen_movi_tl(t0, v2);
23969 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23970 break;
23971 case OPC_DEXTPDP:
23972 tcg_gen_movi_tl(t0, v2);
23973 tcg_gen_movi_tl(t1, v1);
23974 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23975 break;
23976 case OPC_DEXTPDPV:
23977 tcg_gen_movi_tl(t0, v2);
23978 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23979 break;
23980 case OPC_DEXTR_L:
23981 tcg_gen_movi_tl(t0, v2);
23982 tcg_gen_movi_tl(t1, v1);
23983 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23984 break;
23985 case OPC_DEXTR_R_L:
23986 tcg_gen_movi_tl(t0, v2);
23987 tcg_gen_movi_tl(t1, v1);
23988 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23989 break;
23990 case OPC_DEXTR_RS_L:
23991 tcg_gen_movi_tl(t0, v2);
23992 tcg_gen_movi_tl(t1, v1);
23993 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23994 break;
23995 case OPC_DEXTR_W:
23996 tcg_gen_movi_tl(t0, v2);
23997 tcg_gen_movi_tl(t1, v1);
23998 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23999 break;
24000 case OPC_DEXTR_R_W:
24001 tcg_gen_movi_tl(t0, v2);
24002 tcg_gen_movi_tl(t1, v1);
24003 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24004 break;
24005 case OPC_DEXTR_RS_W:
24006 tcg_gen_movi_tl(t0, v2);
24007 tcg_gen_movi_tl(t1, v1);
24008 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24009 break;
24010 case OPC_DEXTR_S_H:
24011 tcg_gen_movi_tl(t0, v2);
24012 tcg_gen_movi_tl(t1, v1);
24013 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24014 break;
24015 case OPC_DEXTRV_S_H:
24016 tcg_gen_movi_tl(t0, v2);
24017 tcg_gen_movi_tl(t1, v1);
24018 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24019 break;
24020 case OPC_DEXTRV_L:
24021 tcg_gen_movi_tl(t0, v2);
24022 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24023 break;
24024 case OPC_DEXTRV_R_L:
24025 tcg_gen_movi_tl(t0, v2);
24026 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24027 break;
24028 case OPC_DEXTRV_RS_L:
24029 tcg_gen_movi_tl(t0, v2);
24030 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24031 break;
24032 case OPC_DEXTRV_W:
24033 tcg_gen_movi_tl(t0, v2);
24034 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24035 break;
24036 case OPC_DEXTRV_R_W:
24037 tcg_gen_movi_tl(t0, v2);
24038 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24039 break;
24040 case OPC_DEXTRV_RS_W:
24041 tcg_gen_movi_tl(t0, v2);
24042 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24043 break;
24044 }
24045 break;
24046 #endif
24047 }
24048
24049 tcg_temp_free(t0);
24050 tcg_temp_free(t1);
24051 tcg_temp_free(v1_t);
24052 tcg_temp_free(v2_t);
24053 }
24054
24055 /* End MIPSDSP functions. */
24056
24057 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
24058 {
24059 int rs, rt, rd, sa;
24060 uint32_t op1, op2;
24061
24062 rs = (ctx->opcode >> 21) & 0x1f;
24063 rt = (ctx->opcode >> 16) & 0x1f;
24064 rd = (ctx->opcode >> 11) & 0x1f;
24065 sa = (ctx->opcode >> 6) & 0x1f;
24066
24067 op1 = MASK_SPECIAL(ctx->opcode);
24068 switch (op1) {
24069 case OPC_LSA:
24070 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24071 break;
24072 case OPC_MULT:
24073 case OPC_MULTU:
24074 case OPC_DIV:
24075 case OPC_DIVU:
24076 op2 = MASK_R6_MULDIV(ctx->opcode);
24077 switch (op2) {
24078 case R6_OPC_MUL:
24079 case R6_OPC_MUH:
24080 case R6_OPC_MULU:
24081 case R6_OPC_MUHU:
24082 case R6_OPC_DIV:
24083 case R6_OPC_MOD:
24084 case R6_OPC_DIVU:
24085 case R6_OPC_MODU:
24086 gen_r6_muldiv(ctx, op2, rd, rs, rt);
24087 break;
24088 default:
24089 MIPS_INVAL("special_r6 muldiv");
24090 generate_exception_end(ctx, EXCP_RI);
24091 break;
24092 }
24093 break;
24094 case OPC_SELEQZ:
24095 case OPC_SELNEZ:
24096 gen_cond_move(ctx, op1, rd, rs, rt);
24097 break;
24098 case R6_OPC_CLO:
24099 case R6_OPC_CLZ:
24100 if (rt == 0 && sa == 1) {
24101 /*
24102 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24103 * We need additionally to check other fields.
24104 */
24105 gen_cl(ctx, op1, rd, rs);
24106 } else {
24107 generate_exception_end(ctx, EXCP_RI);
24108 }
24109 break;
24110 case R6_OPC_SDBBP:
24111 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
24112 gen_helper_do_semihosting(cpu_env);
24113 } else {
24114 if (ctx->hflags & MIPS_HFLAG_SBRI) {
24115 generate_exception_end(ctx, EXCP_RI);
24116 } else {
24117 generate_exception_end(ctx, EXCP_DBp);
24118 }
24119 }
24120 break;
24121 #if defined(TARGET_MIPS64)
24122 case OPC_DLSA:
24123 check_mips_64(ctx);
24124 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24125 break;
24126 case R6_OPC_DCLO:
24127 case R6_OPC_DCLZ:
24128 if (rt == 0 && sa == 1) {
24129 /*
24130 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24131 * We need additionally to check other fields.
24132 */
24133 check_mips_64(ctx);
24134 gen_cl(ctx, op1, rd, rs);
24135 } else {
24136 generate_exception_end(ctx, EXCP_RI);
24137 }
24138 break;
24139 case OPC_DMULT:
24140 case OPC_DMULTU:
24141 case OPC_DDIV:
24142 case OPC_DDIVU:
24143
24144 op2 = MASK_R6_MULDIV(ctx->opcode);
24145 switch (op2) {
24146 case R6_OPC_DMUL:
24147 case R6_OPC_DMUH:
24148 case R6_OPC_DMULU:
24149 case R6_OPC_DMUHU:
24150 case R6_OPC_DDIV:
24151 case R6_OPC_DMOD:
24152 case R6_OPC_DDIVU:
24153 case R6_OPC_DMODU:
24154 check_mips_64(ctx);
24155 gen_r6_muldiv(ctx, op2, rd, rs, rt);
24156 break;
24157 default:
24158 MIPS_INVAL("special_r6 muldiv");
24159 generate_exception_end(ctx, EXCP_RI);
24160 break;
24161 }
24162 break;
24163 #endif
24164 default: /* Invalid */
24165 MIPS_INVAL("special_r6");
24166 generate_exception_end(ctx, EXCP_RI);
24167 break;
24168 }
24169 }
24170
24171 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24172 {
24173 int rs = extract32(ctx->opcode, 21, 5);
24174 int rt = extract32(ctx->opcode, 16, 5);
24175 int rd = extract32(ctx->opcode, 11, 5);
24176 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24177
24178 switch (op1) {
24179 case OPC_MOVN: /* Conditional move */
24180 case OPC_MOVZ:
24181 gen_cond_move(ctx, op1, rd, rs, rt);
24182 break;
24183 case OPC_MFHI: /* Move from HI/LO */
24184 case OPC_MFLO:
24185 gen_HILO(ctx, op1, 0, rd);
24186 break;
24187 case OPC_MTHI:
24188 case OPC_MTLO: /* Move to HI/LO */
24189 gen_HILO(ctx, op1, 0, rs);
24190 break;
24191 case OPC_MULT:
24192 case OPC_MULTU:
24193 gen_mul_txx9(ctx, op1, rd, rs, rt);
24194 break;
24195 case OPC_DIV:
24196 case OPC_DIVU:
24197 gen_muldiv(ctx, op1, 0, rs, rt);
24198 break;
24199 #if defined(TARGET_MIPS64)
24200 case OPC_DMULT:
24201 case OPC_DMULTU:
24202 case OPC_DDIV:
24203 case OPC_DDIVU:
24204 check_insn_opc_user_only(ctx, INSN_R5900);
24205 gen_muldiv(ctx, op1, 0, rs, rt);
24206 break;
24207 #endif
24208 case OPC_JR:
24209 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24210 break;
24211 default: /* Invalid */
24212 MIPS_INVAL("special_tx79");
24213 generate_exception_end(ctx, EXCP_RI);
24214 break;
24215 }
24216 }
24217
24218 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24219 {
24220 int rs, rt, rd, sa;
24221 uint32_t op1;
24222
24223 rs = (ctx->opcode >> 21) & 0x1f;
24224 rt = (ctx->opcode >> 16) & 0x1f;
24225 rd = (ctx->opcode >> 11) & 0x1f;
24226 sa = (ctx->opcode >> 6) & 0x1f;
24227
24228 op1 = MASK_SPECIAL(ctx->opcode);
24229 switch (op1) {
24230 case OPC_MOVN: /* Conditional move */
24231 case OPC_MOVZ:
24232 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24233 INSN_LOONGSON2E | INSN_LOONGSON2F);
24234 gen_cond_move(ctx, op1, rd, rs, rt);
24235 break;
24236 case OPC_MFHI: /* Move from HI/LO */
24237 case OPC_MFLO:
24238 gen_HILO(ctx, op1, rs & 3, rd);
24239 break;
24240 case OPC_MTHI:
24241 case OPC_MTLO: /* Move to HI/LO */
24242 gen_HILO(ctx, op1, rd & 3, rs);
24243 break;
24244 case OPC_MOVCI:
24245 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24246 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24247 check_cp1_enabled(ctx);
24248 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24249 (ctx->opcode >> 16) & 1);
24250 } else {
24251 generate_exception_err(ctx, EXCP_CpU, 1);
24252 }
24253 break;
24254 case OPC_MULT:
24255 case OPC_MULTU:
24256 if (sa) {
24257 check_insn(ctx, INSN_VR54XX);
24258 op1 = MASK_MUL_VR54XX(ctx->opcode);
24259 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24260 } else {
24261 gen_muldiv(ctx, op1, rd & 3, rs, rt);
24262 }
24263 break;
24264 case OPC_DIV:
24265 case OPC_DIVU:
24266 gen_muldiv(ctx, op1, 0, rs, rt);
24267 break;
24268 #if defined(TARGET_MIPS64)
24269 case OPC_DMULT:
24270 case OPC_DMULTU:
24271 case OPC_DDIV:
24272 case OPC_DDIVU:
24273 check_insn(ctx, ISA_MIPS3);
24274 check_mips_64(ctx);
24275 gen_muldiv(ctx, op1, 0, rs, rt);
24276 break;
24277 #endif
24278 case OPC_JR:
24279 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24280 break;
24281 case OPC_SPIM:
24282 #ifdef MIPS_STRICT_STANDARD
24283 MIPS_INVAL("SPIM");
24284 generate_exception_end(ctx, EXCP_RI);
24285 #else
24286 /* Implemented as RI exception for now. */
24287 MIPS_INVAL("spim (unofficial)");
24288 generate_exception_end(ctx, EXCP_RI);
24289 #endif
24290 break;
24291 default: /* Invalid */
24292 MIPS_INVAL("special_legacy");
24293 generate_exception_end(ctx, EXCP_RI);
24294 break;
24295 }
24296 }
24297
24298 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24299 {
24300 int rs, rt, rd, sa;
24301 uint32_t op1;
24302
24303 rs = (ctx->opcode >> 21) & 0x1f;
24304 rt = (ctx->opcode >> 16) & 0x1f;
24305 rd = (ctx->opcode >> 11) & 0x1f;
24306 sa = (ctx->opcode >> 6) & 0x1f;
24307
24308 op1 = MASK_SPECIAL(ctx->opcode);
24309 switch (op1) {
24310 case OPC_SLL: /* Shift with immediate */
24311 if (sa == 5 && rd == 0 &&
24312 rs == 0 && rt == 0) { /* PAUSE */
24313 if ((ctx->insn_flags & ISA_MIPS32R6) &&
24314 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24315 generate_exception_end(ctx, EXCP_RI);
24316 break;
24317 }
24318 }
24319 /* Fallthrough */
24320 case OPC_SRA:
24321 gen_shift_imm(ctx, op1, rd, rt, sa);
24322 break;
24323 case OPC_SRL:
24324 switch ((ctx->opcode >> 21) & 0x1f) {
24325 case 1:
24326 /* rotr is decoded as srl on non-R2 CPUs */
24327 if (ctx->insn_flags & ISA_MIPS32R2) {
24328 op1 = OPC_ROTR;
24329 }
24330 /* Fallthrough */
24331 case 0:
24332 gen_shift_imm(ctx, op1, rd, rt, sa);
24333 break;
24334 default:
24335 generate_exception_end(ctx, EXCP_RI);
24336 break;
24337 }
24338 break;
24339 case OPC_ADD:
24340 case OPC_ADDU:
24341 case OPC_SUB:
24342 case OPC_SUBU:
24343 gen_arith(ctx, op1, rd, rs, rt);
24344 break;
24345 case OPC_SLLV: /* Shifts */
24346 case OPC_SRAV:
24347 gen_shift(ctx, op1, rd, rs, rt);
24348 break;
24349 case OPC_SRLV:
24350 switch ((ctx->opcode >> 6) & 0x1f) {
24351 case 1:
24352 /* rotrv is decoded as srlv on non-R2 CPUs */
24353 if (ctx->insn_flags & ISA_MIPS32R2) {
24354 op1 = OPC_ROTRV;
24355 }
24356 /* Fallthrough */
24357 case 0:
24358 gen_shift(ctx, op1, rd, rs, rt);
24359 break;
24360 default:
24361 generate_exception_end(ctx, EXCP_RI);
24362 break;
24363 }
24364 break;
24365 case OPC_SLT: /* Set on less than */
24366 case OPC_SLTU:
24367 gen_slt(ctx, op1, rd, rs, rt);
24368 break;
24369 case OPC_AND: /* Logic*/
24370 case OPC_OR:
24371 case OPC_NOR:
24372 case OPC_XOR:
24373 gen_logic(ctx, op1, rd, rs, rt);
24374 break;
24375 case OPC_JALR:
24376 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24377 break;
24378 case OPC_TGE: /* Traps */
24379 case OPC_TGEU:
24380 case OPC_TLT:
24381 case OPC_TLTU:
24382 case OPC_TEQ:
24383 case OPC_TNE:
24384 check_insn(ctx, ISA_MIPS2);
24385 gen_trap(ctx, op1, rs, rt, -1);
24386 break;
24387 case OPC_LSA: /* OPC_PMON */
24388 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24389 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24390 decode_opc_special_r6(env, ctx);
24391 } else {
24392 /* Pmon entry point, also R4010 selsl */
24393 #ifdef MIPS_STRICT_STANDARD
24394 MIPS_INVAL("PMON / selsl");
24395 generate_exception_end(ctx, EXCP_RI);
24396 #else
24397 gen_helper_0e0i(pmon, sa);
24398 #endif
24399 }
24400 break;
24401 case OPC_SYSCALL:
24402 generate_exception_end(ctx, EXCP_SYSCALL);
24403 break;
24404 case OPC_BREAK:
24405 generate_exception_end(ctx, EXCP_BREAK);
24406 break;
24407 case OPC_SYNC:
24408 check_insn(ctx, ISA_MIPS2);
24409 gen_sync(extract32(ctx->opcode, 6, 5));
24410 break;
24411
24412 #if defined(TARGET_MIPS64)
24413 /* MIPS64 specific opcodes */
24414 case OPC_DSLL:
24415 case OPC_DSRA:
24416 case OPC_DSLL32:
24417 case OPC_DSRA32:
24418 check_insn(ctx, ISA_MIPS3);
24419 check_mips_64(ctx);
24420 gen_shift_imm(ctx, op1, rd, rt, sa);
24421 break;
24422 case OPC_DSRL:
24423 switch ((ctx->opcode >> 21) & 0x1f) {
24424 case 1:
24425 /* drotr is decoded as dsrl on non-R2 CPUs */
24426 if (ctx->insn_flags & ISA_MIPS32R2) {
24427 op1 = OPC_DROTR;
24428 }
24429 /* Fallthrough */
24430 case 0:
24431 check_insn(ctx, ISA_MIPS3);
24432 check_mips_64(ctx);
24433 gen_shift_imm(ctx, op1, rd, rt, sa);
24434 break;
24435 default:
24436 generate_exception_end(ctx, EXCP_RI);
24437 break;
24438 }
24439 break;
24440 case OPC_DSRL32:
24441 switch ((ctx->opcode >> 21) & 0x1f) {
24442 case 1:
24443 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24444 if (ctx->insn_flags & ISA_MIPS32R2) {
24445 op1 = OPC_DROTR32;
24446 }
24447 /* Fallthrough */
24448 case 0:
24449 check_insn(ctx, ISA_MIPS3);
24450 check_mips_64(ctx);
24451 gen_shift_imm(ctx, op1, rd, rt, sa);
24452 break;
24453 default:
24454 generate_exception_end(ctx, EXCP_RI);
24455 break;
24456 }
24457 break;
24458 case OPC_DADD:
24459 case OPC_DADDU:
24460 case OPC_DSUB:
24461 case OPC_DSUBU:
24462 check_insn(ctx, ISA_MIPS3);
24463 check_mips_64(ctx);
24464 gen_arith(ctx, op1, rd, rs, rt);
24465 break;
24466 case OPC_DSLLV:
24467 case OPC_DSRAV:
24468 check_insn(ctx, ISA_MIPS3);
24469 check_mips_64(ctx);
24470 gen_shift(ctx, op1, rd, rs, rt);
24471 break;
24472 case OPC_DSRLV:
24473 switch ((ctx->opcode >> 6) & 0x1f) {
24474 case 1:
24475 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24476 if (ctx->insn_flags & ISA_MIPS32R2) {
24477 op1 = OPC_DROTRV;
24478 }
24479 /* Fallthrough */
24480 case 0:
24481 check_insn(ctx, ISA_MIPS3);
24482 check_mips_64(ctx);
24483 gen_shift(ctx, op1, rd, rs, rt);
24484 break;
24485 default:
24486 generate_exception_end(ctx, EXCP_RI);
24487 break;
24488 }
24489 break;
24490 case OPC_DLSA:
24491 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24492 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24493 decode_opc_special_r6(env, ctx);
24494 }
24495 break;
24496 #endif
24497 default:
24498 if (ctx->insn_flags & ISA_MIPS32R6) {
24499 decode_opc_special_r6(env, ctx);
24500 } else if (ctx->insn_flags & INSN_R5900) {
24501 decode_opc_special_tx79(env, ctx);
24502 } else {
24503 decode_opc_special_legacy(env, ctx);
24504 }
24505 }
24506 }
24507
24508
24509 #if defined(TARGET_MIPS64)
24510
24511 /*
24512 *
24513 * MMI (MultiMedia Interface) ASE instructions
24514 * ===========================================
24515 */
24516
24517 /*
24518 * MMI instructions category: data communication
24519 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24520 *
24521 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24522 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24523 * PCPYUD PEXEH PEXTLW PPACW
24524 * PEXEW PEXTUB
24525 * PEXTUH
24526 * PEXTUW
24527 */
24528
24529 /*
24530 * PCPYH rd, rt
24531 *
24532 * Parallel Copy Halfword
24533 *
24534 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24535 * +-----------+---------+---------+---------+---------+-----------+
24536 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
24537 * +-----------+---------+---------+---------+---------+-----------+
24538 */
24539 static void gen_mmi_pcpyh(DisasContext *ctx)
24540 {
24541 uint32_t pd, rt, rd;
24542 uint32_t opcode;
24543
24544 opcode = ctx->opcode;
24545
24546 pd = extract32(opcode, 21, 5);
24547 rt = extract32(opcode, 16, 5);
24548 rd = extract32(opcode, 11, 5);
24549
24550 if (unlikely(pd != 0)) {
24551 generate_exception_end(ctx, EXCP_RI);
24552 } else if (rd == 0) {
24553 /* nop */
24554 } else if (rt == 0) {
24555 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24556 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24557 } else {
24558 TCGv_i64 t0 = tcg_temp_new();
24559 TCGv_i64 t1 = tcg_temp_new();
24560 uint64_t mask = (1ULL << 16) - 1;
24561
24562 tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
24563 tcg_gen_movi_i64(t1, 0);
24564 tcg_gen_or_i64(t1, t0, t1);
24565 tcg_gen_shli_i64(t0, t0, 16);
24566 tcg_gen_or_i64(t1, t0, t1);
24567 tcg_gen_shli_i64(t0, t0, 16);
24568 tcg_gen_or_i64(t1, t0, t1);
24569 tcg_gen_shli_i64(t0, t0, 16);
24570 tcg_gen_or_i64(t1, t0, t1);
24571
24572 tcg_gen_mov_i64(cpu_gpr[rd], t1);
24573
24574 tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
24575 tcg_gen_movi_i64(t1, 0);
24576 tcg_gen_or_i64(t1, t0, t1);
24577 tcg_gen_shli_i64(t0, t0, 16);
24578 tcg_gen_or_i64(t1, t0, t1);
24579 tcg_gen_shli_i64(t0, t0, 16);
24580 tcg_gen_or_i64(t1, t0, t1);
24581 tcg_gen_shli_i64(t0, t0, 16);
24582 tcg_gen_or_i64(t1, t0, t1);
24583
24584 tcg_gen_mov_i64(cpu_mmr[rd], t1);
24585
24586 tcg_temp_free(t0);
24587 tcg_temp_free(t1);
24588 }
24589 }
24590
24591 /*
24592 * PCPYLD rd, rs, rt
24593 *
24594 * Parallel Copy Lower Doubleword
24595 *
24596 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24597 * +-----------+---------+---------+---------+---------+-----------+
24598 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
24599 * +-----------+---------+---------+---------+---------+-----------+
24600 */
24601 static void gen_mmi_pcpyld(DisasContext *ctx)
24602 {
24603 uint32_t rs, rt, rd;
24604 uint32_t opcode;
24605
24606 opcode = ctx->opcode;
24607
24608 rs = extract32(opcode, 21, 5);
24609 rt = extract32(opcode, 16, 5);
24610 rd = extract32(opcode, 11, 5);
24611
24612 if (rd == 0) {
24613 /* nop */
24614 } else {
24615 if (rs == 0) {
24616 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24617 } else {
24618 tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
24619 }
24620 if (rt == 0) {
24621 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24622 } else {
24623 if (rd != rt) {
24624 tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
24625 }
24626 }
24627 }
24628 }
24629
24630 /*
24631 * PCPYUD rd, rs, rt
24632 *
24633 * Parallel Copy Upper Doubleword
24634 *
24635 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24636 * +-----------+---------+---------+---------+---------+-----------+
24637 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
24638 * +-----------+---------+---------+---------+---------+-----------+
24639 */
24640 static void gen_mmi_pcpyud(DisasContext *ctx)
24641 {
24642 uint32_t rs, rt, rd;
24643 uint32_t opcode;
24644
24645 opcode = ctx->opcode;
24646
24647 rs = extract32(opcode, 21, 5);
24648 rt = extract32(opcode, 16, 5);
24649 rd = extract32(opcode, 11, 5);
24650
24651 if (rd == 0) {
24652 /* nop */
24653 } else {
24654 if (rs == 0) {
24655 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24656 } else {
24657 tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
24658 }
24659 if (rt == 0) {
24660 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24661 } else {
24662 if (rd != rt) {
24663 tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
24664 }
24665 }
24666 }
24667 }
24668
24669 #endif
24670
24671
24672 #if !defined(TARGET_MIPS64)
24673
24674 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24675 #define MXU_APTN1_A 0
24676 #define MXU_APTN1_S 1
24677
24678 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24679 #define MXU_APTN2_AA 0
24680 #define MXU_APTN2_AS 1
24681 #define MXU_APTN2_SA 2
24682 #define MXU_APTN2_SS 3
24683
24684 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24685 #define MXU_EPTN2_AA 0
24686 #define MXU_EPTN2_AS 1
24687 #define MXU_EPTN2_SA 2
24688 #define MXU_EPTN2_SS 3
24689
24690 /* MXU operand getting pattern 'optn2' */
24691 #define MXU_OPTN2_PTN0 0
24692 #define MXU_OPTN2_PTN1 1
24693 #define MXU_OPTN2_PTN2 2
24694 #define MXU_OPTN2_PTN3 3
24695 /* alternative naming scheme for 'optn2' */
24696 #define MXU_OPTN2_WW 0
24697 #define MXU_OPTN2_LW 1
24698 #define MXU_OPTN2_HW 2
24699 #define MXU_OPTN2_XW 3
24700
24701 /* MXU operand getting pattern 'optn3' */
24702 #define MXU_OPTN3_PTN0 0
24703 #define MXU_OPTN3_PTN1 1
24704 #define MXU_OPTN3_PTN2 2
24705 #define MXU_OPTN3_PTN3 3
24706 #define MXU_OPTN3_PTN4 4
24707 #define MXU_OPTN3_PTN5 5
24708 #define MXU_OPTN3_PTN6 6
24709 #define MXU_OPTN3_PTN7 7
24710
24711
24712 /*
24713 * S32I2M XRa, rb - Register move from GRF to XRF
24714 */
24715 static void gen_mxu_s32i2m(DisasContext *ctx)
24716 {
24717 TCGv t0;
24718 uint32_t XRa, Rb;
24719
24720 t0 = tcg_temp_new();
24721
24722 XRa = extract32(ctx->opcode, 6, 5);
24723 Rb = extract32(ctx->opcode, 16, 5);
24724
24725 gen_load_gpr(t0, Rb);
24726 if (XRa <= 15) {
24727 gen_store_mxu_gpr(t0, XRa);
24728 } else if (XRa == 16) {
24729 gen_store_mxu_cr(t0);
24730 }
24731
24732 tcg_temp_free(t0);
24733 }
24734
24735 /*
24736 * S32M2I XRa, rb - Register move from XRF to GRF
24737 */
24738 static void gen_mxu_s32m2i(DisasContext *ctx)
24739 {
24740 TCGv t0;
24741 uint32_t XRa, Rb;
24742
24743 t0 = tcg_temp_new();
24744
24745 XRa = extract32(ctx->opcode, 6, 5);
24746 Rb = extract32(ctx->opcode, 16, 5);
24747
24748 if (XRa <= 15) {
24749 gen_load_mxu_gpr(t0, XRa);
24750 } else if (XRa == 16) {
24751 gen_load_mxu_cr(t0);
24752 }
24753
24754 gen_store_gpr(t0, Rb);
24755
24756 tcg_temp_free(t0);
24757 }
24758
24759 /*
24760 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24761 */
24762 static void gen_mxu_s8ldd(DisasContext *ctx)
24763 {
24764 TCGv t0, t1;
24765 uint32_t XRa, Rb, s8, optn3;
24766
24767 t0 = tcg_temp_new();
24768 t1 = tcg_temp_new();
24769
24770 XRa = extract32(ctx->opcode, 6, 4);
24771 s8 = extract32(ctx->opcode, 10, 8);
24772 optn3 = extract32(ctx->opcode, 18, 3);
24773 Rb = extract32(ctx->opcode, 21, 5);
24774
24775 gen_load_gpr(t0, Rb);
24776 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24777
24778 switch (optn3) {
24779 /* XRa[7:0] = tmp8 */
24780 case MXU_OPTN3_PTN0:
24781 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24782 gen_load_mxu_gpr(t0, XRa);
24783 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24784 break;
24785 /* XRa[15:8] = tmp8 */
24786 case MXU_OPTN3_PTN1:
24787 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24788 gen_load_mxu_gpr(t0, XRa);
24789 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24790 break;
24791 /* XRa[23:16] = tmp8 */
24792 case MXU_OPTN3_PTN2:
24793 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24794 gen_load_mxu_gpr(t0, XRa);
24795 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24796 break;
24797 /* XRa[31:24] = tmp8 */
24798 case MXU_OPTN3_PTN3:
24799 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24800 gen_load_mxu_gpr(t0, XRa);
24801 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24802 break;
24803 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24804 case MXU_OPTN3_PTN4:
24805 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24806 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24807 break;
24808 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24809 case MXU_OPTN3_PTN5:
24810 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24811 tcg_gen_shli_tl(t1, t1, 8);
24812 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24813 break;
24814 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24815 case MXU_OPTN3_PTN6:
24816 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24817 tcg_gen_mov_tl(t0, t1);
24818 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24819 tcg_gen_shli_tl(t1, t1, 16);
24820 tcg_gen_or_tl(t0, t0, t1);
24821 break;
24822 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24823 case MXU_OPTN3_PTN7:
24824 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24825 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24826 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24827 break;
24828 }
24829
24830 gen_store_mxu_gpr(t0, XRa);
24831
24832 tcg_temp_free(t0);
24833 tcg_temp_free(t1);
24834 }
24835
24836 /*
24837 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24838 */
24839 static void gen_mxu_d16mul(DisasContext *ctx)
24840 {
24841 TCGv t0, t1, t2, t3;
24842 uint32_t XRa, XRb, XRc, XRd, optn2;
24843
24844 t0 = tcg_temp_new();
24845 t1 = tcg_temp_new();
24846 t2 = tcg_temp_new();
24847 t3 = tcg_temp_new();
24848
24849 XRa = extract32(ctx->opcode, 6, 4);
24850 XRb = extract32(ctx->opcode, 10, 4);
24851 XRc = extract32(ctx->opcode, 14, 4);
24852 XRd = extract32(ctx->opcode, 18, 4);
24853 optn2 = extract32(ctx->opcode, 22, 2);
24854
24855 gen_load_mxu_gpr(t1, XRb);
24856 tcg_gen_sextract_tl(t0, t1, 0, 16);
24857 tcg_gen_sextract_tl(t1, t1, 16, 16);
24858 gen_load_mxu_gpr(t3, XRc);
24859 tcg_gen_sextract_tl(t2, t3, 0, 16);
24860 tcg_gen_sextract_tl(t3, t3, 16, 16);
24861
24862 switch (optn2) {
24863 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24864 tcg_gen_mul_tl(t3, t1, t3);
24865 tcg_gen_mul_tl(t2, t0, t2);
24866 break;
24867 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24868 tcg_gen_mul_tl(t3, t0, t3);
24869 tcg_gen_mul_tl(t2, t0, t2);
24870 break;
24871 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24872 tcg_gen_mul_tl(t3, t1, t3);
24873 tcg_gen_mul_tl(t2, t1, t2);
24874 break;
24875 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24876 tcg_gen_mul_tl(t3, t0, t3);
24877 tcg_gen_mul_tl(t2, t1, t2);
24878 break;
24879 }
24880 gen_store_mxu_gpr(t3, XRa);
24881 gen_store_mxu_gpr(t2, XRd);
24882
24883 tcg_temp_free(t0);
24884 tcg_temp_free(t1);
24885 tcg_temp_free(t2);
24886 tcg_temp_free(t3);
24887 }
24888
24889 /*
24890 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24891 * and accumulate
24892 */
24893 static void gen_mxu_d16mac(DisasContext *ctx)
24894 {
24895 TCGv t0, t1, t2, t3;
24896 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24897
24898 t0 = tcg_temp_new();
24899 t1 = tcg_temp_new();
24900 t2 = tcg_temp_new();
24901 t3 = tcg_temp_new();
24902
24903 XRa = extract32(ctx->opcode, 6, 4);
24904 XRb = extract32(ctx->opcode, 10, 4);
24905 XRc = extract32(ctx->opcode, 14, 4);
24906 XRd = extract32(ctx->opcode, 18, 4);
24907 optn2 = extract32(ctx->opcode, 22, 2);
24908 aptn2 = extract32(ctx->opcode, 24, 2);
24909
24910 gen_load_mxu_gpr(t1, XRb);
24911 tcg_gen_sextract_tl(t0, t1, 0, 16);
24912 tcg_gen_sextract_tl(t1, t1, 16, 16);
24913
24914 gen_load_mxu_gpr(t3, XRc);
24915 tcg_gen_sextract_tl(t2, t3, 0, 16);
24916 tcg_gen_sextract_tl(t3, t3, 16, 16);
24917
24918 switch (optn2) {
24919 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24920 tcg_gen_mul_tl(t3, t1, t3);
24921 tcg_gen_mul_tl(t2, t0, t2);
24922 break;
24923 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24924 tcg_gen_mul_tl(t3, t0, t3);
24925 tcg_gen_mul_tl(t2, t0, t2);
24926 break;
24927 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24928 tcg_gen_mul_tl(t3, t1, t3);
24929 tcg_gen_mul_tl(t2, t1, t2);
24930 break;
24931 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24932 tcg_gen_mul_tl(t3, t0, t3);
24933 tcg_gen_mul_tl(t2, t1, t2);
24934 break;
24935 }
24936 gen_load_mxu_gpr(t0, XRa);
24937 gen_load_mxu_gpr(t1, XRd);
24938
24939 switch (aptn2) {
24940 case MXU_APTN2_AA:
24941 tcg_gen_add_tl(t3, t0, t3);
24942 tcg_gen_add_tl(t2, t1, t2);
24943 break;
24944 case MXU_APTN2_AS:
24945 tcg_gen_add_tl(t3, t0, t3);
24946 tcg_gen_sub_tl(t2, t1, t2);
24947 break;
24948 case MXU_APTN2_SA:
24949 tcg_gen_sub_tl(t3, t0, t3);
24950 tcg_gen_add_tl(t2, t1, t2);
24951 break;
24952 case MXU_APTN2_SS:
24953 tcg_gen_sub_tl(t3, t0, t3);
24954 tcg_gen_sub_tl(t2, t1, t2);
24955 break;
24956 }
24957 gen_store_mxu_gpr(t3, XRa);
24958 gen_store_mxu_gpr(t2, XRd);
24959
24960 tcg_temp_free(t0);
24961 tcg_temp_free(t1);
24962 tcg_temp_free(t2);
24963 tcg_temp_free(t3);
24964 }
24965
24966 /*
24967 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24968 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24969 */
24970 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24971 {
24972 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24973 uint32_t XRa, XRb, XRc, XRd, sel;
24974
24975 t0 = tcg_temp_new();
24976 t1 = tcg_temp_new();
24977 t2 = tcg_temp_new();
24978 t3 = tcg_temp_new();
24979 t4 = tcg_temp_new();
24980 t5 = tcg_temp_new();
24981 t6 = tcg_temp_new();
24982 t7 = tcg_temp_new();
24983
24984 XRa = extract32(ctx->opcode, 6, 4);
24985 XRb = extract32(ctx->opcode, 10, 4);
24986 XRc = extract32(ctx->opcode, 14, 4);
24987 XRd = extract32(ctx->opcode, 18, 4);
24988 sel = extract32(ctx->opcode, 22, 2);
24989
24990 gen_load_mxu_gpr(t3, XRb);
24991 gen_load_mxu_gpr(t7, XRc);
24992
24993 if (sel == 0x2) {
24994 /* Q8MULSU */
24995 tcg_gen_ext8s_tl(t0, t3);
24996 tcg_gen_shri_tl(t3, t3, 8);
24997 tcg_gen_ext8s_tl(t1, t3);
24998 tcg_gen_shri_tl(t3, t3, 8);
24999 tcg_gen_ext8s_tl(t2, t3);
25000 tcg_gen_shri_tl(t3, t3, 8);
25001 tcg_gen_ext8s_tl(t3, t3);
25002 } else {
25003 /* Q8MUL */
25004 tcg_gen_ext8u_tl(t0, t3);
25005 tcg_gen_shri_tl(t3, t3, 8);
25006 tcg_gen_ext8u_tl(t1, t3);
25007 tcg_gen_shri_tl(t3, t3, 8);
25008 tcg_gen_ext8u_tl(t2, t3);
25009 tcg_gen_shri_tl(t3, t3, 8);
25010 tcg_gen_ext8u_tl(t3, t3);
25011 }
25012
25013 tcg_gen_ext8u_tl(t4, t7);
25014 tcg_gen_shri_tl(t7, t7, 8);
25015 tcg_gen_ext8u_tl(t5, t7);
25016 tcg_gen_shri_tl(t7, t7, 8);
25017 tcg_gen_ext8u_tl(t6, t7);
25018 tcg_gen_shri_tl(t7, t7, 8);
25019 tcg_gen_ext8u_tl(t7, t7);
25020
25021 tcg_gen_mul_tl(t0, t0, t4);
25022 tcg_gen_mul_tl(t1, t1, t5);
25023 tcg_gen_mul_tl(t2, t2, t6);
25024 tcg_gen_mul_tl(t3, t3, t7);
25025
25026 tcg_gen_andi_tl(t0, t0, 0xFFFF);
25027 tcg_gen_andi_tl(t1, t1, 0xFFFF);
25028 tcg_gen_andi_tl(t2, t2, 0xFFFF);
25029 tcg_gen_andi_tl(t3, t3, 0xFFFF);
25030
25031 tcg_gen_shli_tl(t1, t1, 16);
25032 tcg_gen_shli_tl(t3, t3, 16);
25033
25034 tcg_gen_or_tl(t0, t0, t1);
25035 tcg_gen_or_tl(t1, t2, t3);
25036
25037 gen_store_mxu_gpr(t0, XRd);
25038 gen_store_mxu_gpr(t1, XRa);
25039
25040 tcg_temp_free(t0);
25041 tcg_temp_free(t1);
25042 tcg_temp_free(t2);
25043 tcg_temp_free(t3);
25044 tcg_temp_free(t4);
25045 tcg_temp_free(t5);
25046 tcg_temp_free(t6);
25047 tcg_temp_free(t7);
25048 }
25049
25050 /*
25051 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25052 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25053 */
25054 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
25055 {
25056 TCGv t0, t1;
25057 uint32_t XRa, Rb, s12, sel;
25058
25059 t0 = tcg_temp_new();
25060 t1 = tcg_temp_new();
25061
25062 XRa = extract32(ctx->opcode, 6, 4);
25063 s12 = extract32(ctx->opcode, 10, 10);
25064 sel = extract32(ctx->opcode, 20, 1);
25065 Rb = extract32(ctx->opcode, 21, 5);
25066
25067 gen_load_gpr(t0, Rb);
25068
25069 tcg_gen_movi_tl(t1, s12);
25070 tcg_gen_shli_tl(t1, t1, 2);
25071 if (s12 & 0x200) {
25072 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
25073 }
25074 tcg_gen_add_tl(t1, t0, t1);
25075 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
25076
25077 if (sel == 1) {
25078 /* S32LDDR */
25079 tcg_gen_bswap32_tl(t1, t1);
25080 }
25081 gen_store_mxu_gpr(t1, XRa);
25082
25083 tcg_temp_free(t0);
25084 tcg_temp_free(t1);
25085 }
25086
25087
25088 /*
25089 * MXU instruction category: logic
25090 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25091 *
25092 * S32NOR S32AND S32OR S32XOR
25093 */
25094
25095 /*
25096 * S32NOR XRa, XRb, XRc
25097 * Update XRa with the result of logical bitwise 'nor' operation
25098 * applied to the content of XRb and XRc.
25099 *
25100 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25101 * +-----------+---------+-----+-------+-------+-------+-----------+
25102 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25103 * +-----------+---------+-----+-------+-------+-------+-----------+
25104 */
25105 static void gen_mxu_S32NOR(DisasContext *ctx)
25106 {
25107 uint32_t pad, XRc, XRb, XRa;
25108
25109 pad = extract32(ctx->opcode, 21, 5);
25110 XRc = extract32(ctx->opcode, 14, 4);
25111 XRb = extract32(ctx->opcode, 10, 4);
25112 XRa = extract32(ctx->opcode, 6, 4);
25113
25114 if (unlikely(pad != 0)) {
25115 /* opcode padding incorrect -> do nothing */
25116 } else if (unlikely(XRa == 0)) {
25117 /* destination is zero register -> do nothing */
25118 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25119 /* both operands zero registers -> just set destination to all 1s */
25120 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
25121 } else if (unlikely(XRb == 0)) {
25122 /* XRb zero register -> just set destination to the negation of XRc */
25123 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25124 } else if (unlikely(XRc == 0)) {
25125 /* XRa zero register -> just set destination to the negation of XRb */
25126 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25127 } else if (unlikely(XRb == XRc)) {
25128 /* both operands same -> just set destination to the negation of XRb */
25129 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25130 } else {
25131 /* the most general case */
25132 tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25133 }
25134 }
25135
25136 /*
25137 * S32AND XRa, XRb, XRc
25138 * Update XRa with the result of logical bitwise 'and' operation
25139 * applied to the content of XRb and XRc.
25140 *
25141 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25142 * +-----------+---------+-----+-------+-------+-------+-----------+
25143 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25144 * +-----------+---------+-----+-------+-------+-------+-----------+
25145 */
25146 static void gen_mxu_S32AND(DisasContext *ctx)
25147 {
25148 uint32_t pad, XRc, XRb, XRa;
25149
25150 pad = extract32(ctx->opcode, 21, 5);
25151 XRc = extract32(ctx->opcode, 14, 4);
25152 XRb = extract32(ctx->opcode, 10, 4);
25153 XRa = extract32(ctx->opcode, 6, 4);
25154
25155 if (unlikely(pad != 0)) {
25156 /* opcode padding incorrect -> do nothing */
25157 } else if (unlikely(XRa == 0)) {
25158 /* destination is zero register -> do nothing */
25159 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25160 /* one of operands zero register -> just set destination to all 0s */
25161 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25162 } else if (unlikely(XRb == XRc)) {
25163 /* both operands same -> just set destination to one of them */
25164 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25165 } else {
25166 /* the most general case */
25167 tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25168 }
25169 }
25170
25171 /*
25172 * S32OR XRa, XRb, XRc
25173 * Update XRa with the result of logical bitwise 'or' operation
25174 * applied to the content of XRb and XRc.
25175 *
25176 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25177 * +-----------+---------+-----+-------+-------+-------+-----------+
25178 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25179 * +-----------+---------+-----+-------+-------+-------+-----------+
25180 */
25181 static void gen_mxu_S32OR(DisasContext *ctx)
25182 {
25183 uint32_t pad, XRc, XRb, XRa;
25184
25185 pad = extract32(ctx->opcode, 21, 5);
25186 XRc = extract32(ctx->opcode, 14, 4);
25187 XRb = extract32(ctx->opcode, 10, 4);
25188 XRa = extract32(ctx->opcode, 6, 4);
25189
25190 if (unlikely(pad != 0)) {
25191 /* opcode padding incorrect -> do nothing */
25192 } else if (unlikely(XRa == 0)) {
25193 /* destination is zero register -> do nothing */
25194 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25195 /* both operands zero registers -> just set destination to all 0s */
25196 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25197 } else if (unlikely(XRb == 0)) {
25198 /* XRb zero register -> just set destination to the content of XRc */
25199 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25200 } else if (unlikely(XRc == 0)) {
25201 /* XRc zero register -> just set destination to the content of XRb */
25202 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25203 } else if (unlikely(XRb == XRc)) {
25204 /* both operands same -> just set destination to one of them */
25205 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25206 } else {
25207 /* the most general case */
25208 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25209 }
25210 }
25211
25212 /*
25213 * S32XOR XRa, XRb, XRc
25214 * Update XRa with the result of logical bitwise 'xor' operation
25215 * applied to the content of XRb and XRc.
25216 *
25217 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25218 * +-----------+---------+-----+-------+-------+-------+-----------+
25219 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25220 * +-----------+---------+-----+-------+-------+-------+-----------+
25221 */
25222 static void gen_mxu_S32XOR(DisasContext *ctx)
25223 {
25224 uint32_t pad, XRc, XRb, XRa;
25225
25226 pad = extract32(ctx->opcode, 21, 5);
25227 XRc = extract32(ctx->opcode, 14, 4);
25228 XRb = extract32(ctx->opcode, 10, 4);
25229 XRa = extract32(ctx->opcode, 6, 4);
25230
25231 if (unlikely(pad != 0)) {
25232 /* opcode padding incorrect -> do nothing */
25233 } else if (unlikely(XRa == 0)) {
25234 /* destination is zero register -> do nothing */
25235 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25236 /* both operands zero registers -> just set destination to all 0s */
25237 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25238 } else if (unlikely(XRb == 0)) {
25239 /* XRb zero register -> just set destination to the content of XRc */
25240 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25241 } else if (unlikely(XRc == 0)) {
25242 /* XRc zero register -> just set destination to the content of XRb */
25243 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25244 } else if (unlikely(XRb == XRc)) {
25245 /* both operands same -> just set destination to all 0s */
25246 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25247 } else {
25248 /* the most general case */
25249 tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25250 }
25251 }
25252
25253
25254 /*
25255 * MXU instruction category max/min
25256 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25257 *
25258 * S32MAX D16MAX Q8MAX
25259 * S32MIN D16MIN Q8MIN
25260 */
25261
25262 /*
25263 * S32MAX XRa, XRb, XRc
25264 * Update XRa with the maximum of signed 32-bit integers contained
25265 * in XRb and XRc.
25266 *
25267 * S32MIN XRa, XRb, XRc
25268 * Update XRa with the minimum of signed 32-bit integers contained
25269 * in XRb and XRc.
25270 *
25271 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25272 * +-----------+---------+-----+-------+-------+-------+-----------+
25273 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25274 * +-----------+---------+-----+-------+-------+-------+-----------+
25275 */
25276 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
25277 {
25278 uint32_t pad, opc, XRc, XRb, XRa;
25279
25280 pad = extract32(ctx->opcode, 21, 5);
25281 opc = extract32(ctx->opcode, 18, 3);
25282 XRc = extract32(ctx->opcode, 14, 4);
25283 XRb = extract32(ctx->opcode, 10, 4);
25284 XRa = extract32(ctx->opcode, 6, 4);
25285
25286 if (unlikely(pad != 0)) {
25287 /* opcode padding incorrect -> do nothing */
25288 } else if (unlikely(XRa == 0)) {
25289 /* destination is zero register -> do nothing */
25290 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25291 /* both operands zero registers -> just set destination to zero */
25292 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25293 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25294 /* exactly one operand is zero register - find which one is not...*/
25295 uint32_t XRx = XRb ? XRb : XRc;
25296 /* ...and do max/min operation with one operand 0 */
25297 if (opc == OPC_MXU_S32MAX) {
25298 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25299 } else {
25300 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25301 }
25302 } else if (unlikely(XRb == XRc)) {
25303 /* both operands same -> just set destination to one of them */
25304 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25305 } else {
25306 /* the most general case */
25307 if (opc == OPC_MXU_S32MAX) {
25308 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25309 mxu_gpr[XRc - 1]);
25310 } else {
25311 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25312 mxu_gpr[XRc - 1]);
25313 }
25314 }
25315 }
25316
25317 /*
25318 * D16MAX
25319 * Update XRa with the 16-bit-wise maximums of signed integers
25320 * contained in XRb and XRc.
25321 *
25322 * D16MIN
25323 * Update XRa with the 16-bit-wise minimums of signed integers
25324 * contained in XRb and XRc.
25325 *
25326 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25327 * +-----------+---------+-----+-------+-------+-------+-----------+
25328 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25329 * +-----------+---------+-----+-------+-------+-------+-----------+
25330 */
25331 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25332 {
25333 uint32_t pad, opc, XRc, XRb, XRa;
25334
25335 pad = extract32(ctx->opcode, 21, 5);
25336 opc = extract32(ctx->opcode, 18, 3);
25337 XRc = extract32(ctx->opcode, 14, 4);
25338 XRb = extract32(ctx->opcode, 10, 4);
25339 XRa = extract32(ctx->opcode, 6, 4);
25340
25341 if (unlikely(pad != 0)) {
25342 /* opcode padding incorrect -> do nothing */
25343 } else if (unlikely(XRc == 0)) {
25344 /* destination is zero register -> do nothing */
25345 } else if (unlikely((XRb == 0) && (XRa == 0))) {
25346 /* both operands zero registers -> just set destination to zero */
25347 tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25348 } else if (unlikely((XRb == 0) || (XRa == 0))) {
25349 /* exactly one operand is zero register - find which one is not...*/
25350 uint32_t XRx = XRb ? XRb : XRc;
25351 /* ...and do half-word-wise max/min with one operand 0 */
25352 TCGv_i32 t0 = tcg_temp_new();
25353 TCGv_i32 t1 = tcg_const_i32(0);
25354
25355 /* the left half-word first */
25356 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25357 if (opc == OPC_MXU_D16MAX) {
25358 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25359 } else {
25360 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25361 }
25362
25363 /* the right half-word */
25364 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25365 /* move half-words to the leftmost position */
25366 tcg_gen_shli_i32(t0, t0, 16);
25367 /* t0 will be max/min of t0 and t1 */
25368 if (opc == OPC_MXU_D16MAX) {
25369 tcg_gen_smax_i32(t0, t0, t1);
25370 } else {
25371 tcg_gen_smin_i32(t0, t0, t1);
25372 }
25373 /* return resulting half-words to its original position */
25374 tcg_gen_shri_i32(t0, t0, 16);
25375 /* finaly update the destination */
25376 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25377
25378 tcg_temp_free(t1);
25379 tcg_temp_free(t0);
25380 } else if (unlikely(XRb == XRc)) {
25381 /* both operands same -> just set destination to one of them */
25382 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25383 } else {
25384 /* the most general case */
25385 TCGv_i32 t0 = tcg_temp_new();
25386 TCGv_i32 t1 = tcg_temp_new();
25387
25388 /* the left half-word first */
25389 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25390 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25391 if (opc == OPC_MXU_D16MAX) {
25392 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25393 } else {
25394 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25395 }
25396
25397 /* the right half-word */
25398 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25399 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25400 /* move half-words to the leftmost position */
25401 tcg_gen_shli_i32(t0, t0, 16);
25402 tcg_gen_shli_i32(t1, t1, 16);
25403 /* t0 will be max/min of t0 and t1 */
25404 if (opc == OPC_MXU_D16MAX) {
25405 tcg_gen_smax_i32(t0, t0, t1);
25406 } else {
25407 tcg_gen_smin_i32(t0, t0, t1);
25408 }
25409 /* return resulting half-words to its original position */
25410 tcg_gen_shri_i32(t0, t0, 16);
25411 /* finaly update the destination */
25412 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25413
25414 tcg_temp_free(t1);
25415 tcg_temp_free(t0);
25416 }
25417 }
25418
25419 /*
25420 * Q8MAX
25421 * Update XRa with the 8-bit-wise maximums of signed integers
25422 * contained in XRb and XRc.
25423 *
25424 * Q8MIN
25425 * Update XRa with the 8-bit-wise minimums of signed integers
25426 * contained in XRb and XRc.
25427 *
25428 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25429 * +-----------+---------+-----+-------+-------+-------+-----------+
25430 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25431 * +-----------+---------+-----+-------+-------+-------+-----------+
25432 */
25433 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25434 {
25435 uint32_t pad, opc, XRc, XRb, XRa;
25436
25437 pad = extract32(ctx->opcode, 21, 5);
25438 opc = extract32(ctx->opcode, 18, 3);
25439 XRc = extract32(ctx->opcode, 14, 4);
25440 XRb = extract32(ctx->opcode, 10, 4);
25441 XRa = extract32(ctx->opcode, 6, 4);
25442
25443 if (unlikely(pad != 0)) {
25444 /* opcode padding incorrect -> do nothing */
25445 } else if (unlikely(XRa == 0)) {
25446 /* destination is zero register -> do nothing */
25447 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25448 /* both operands zero registers -> just set destination to zero */
25449 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25450 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25451 /* exactly one operand is zero register - make it be the first...*/
25452 uint32_t XRx = XRb ? XRb : XRc;
25453 /* ...and do byte-wise max/min with one operand 0 */
25454 TCGv_i32 t0 = tcg_temp_new();
25455 TCGv_i32 t1 = tcg_const_i32(0);
25456 int32_t i;
25457
25458 /* the leftmost byte (byte 3) first */
25459 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25460 if (opc == OPC_MXU_Q8MAX) {
25461 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25462 } else {
25463 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25464 }
25465
25466 /* bytes 2, 1, 0 */
25467 for (i = 2; i >= 0; i--) {
25468 /* extract the byte */
25469 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25470 /* move the byte to the leftmost position */
25471 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25472 /* t0 will be max/min of t0 and t1 */
25473 if (opc == OPC_MXU_Q8MAX) {
25474 tcg_gen_smax_i32(t0, t0, t1);
25475 } else {
25476 tcg_gen_smin_i32(t0, t0, t1);
25477 }
25478 /* return resulting byte to its original position */
25479 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25480 /* finaly update the destination */
25481 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25482 }
25483
25484 tcg_temp_free(t1);
25485 tcg_temp_free(t0);
25486 } else if (unlikely(XRb == XRc)) {
25487 /* both operands same -> just set destination to one of them */
25488 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25489 } else {
25490 /* the most general case */
25491 TCGv_i32 t0 = tcg_temp_new();
25492 TCGv_i32 t1 = tcg_temp_new();
25493 int32_t i;
25494
25495 /* the leftmost bytes (bytes 3) first */
25496 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25497 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25498 if (opc == OPC_MXU_Q8MAX) {
25499 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25500 } else {
25501 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25502 }
25503
25504 /* bytes 2, 1, 0 */
25505 for (i = 2; i >= 0; i--) {
25506 /* extract corresponding bytes */
25507 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25508 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25509 /* move the bytes to the leftmost position */
25510 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25511 tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25512 /* t0 will be max/min of t0 and t1 */
25513 if (opc == OPC_MXU_Q8MAX) {
25514 tcg_gen_smax_i32(t0, t0, t1);
25515 } else {
25516 tcg_gen_smin_i32(t0, t0, t1);
25517 }
25518 /* return resulting byte to its original position */
25519 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25520 /* finaly update the destination */
25521 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25522 }
25523
25524 tcg_temp_free(t1);
25525 tcg_temp_free(t0);
25526 }
25527 }
25528
25529
25530 /*
25531 * MXU instruction category: align
25532 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25533 *
25534 * S32ALN S32ALNI
25535 */
25536
25537 /*
25538 * S32ALNI XRc, XRb, XRa, optn3
25539 * Arrange bytes from XRb and XRc according to one of five sets of
25540 * rules determined by optn3, and place the result in XRa.
25541 *
25542 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25543 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25544 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25545 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25546 *
25547 */
25548 static void gen_mxu_S32ALNI(DisasContext *ctx)
25549 {
25550 uint32_t optn3, pad, XRc, XRb, XRa;
25551
25552 optn3 = extract32(ctx->opcode, 23, 3);
25553 pad = extract32(ctx->opcode, 21, 2);
25554 XRc = extract32(ctx->opcode, 14, 4);
25555 XRb = extract32(ctx->opcode, 10, 4);
25556 XRa = extract32(ctx->opcode, 6, 4);
25557
25558 if (unlikely(pad != 0)) {
25559 /* opcode padding incorrect -> do nothing */
25560 } else if (unlikely(XRa == 0)) {
25561 /* destination is zero register -> do nothing */
25562 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25563 /* both operands zero registers -> just set destination to all 0s */
25564 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25565 } else if (unlikely(XRb == 0)) {
25566 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25567 switch (optn3) {
25568 case MXU_OPTN3_PTN0:
25569 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25570 break;
25571 case MXU_OPTN3_PTN1:
25572 case MXU_OPTN3_PTN2:
25573 case MXU_OPTN3_PTN3:
25574 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25575 8 * (4 - optn3));
25576 break;
25577 case MXU_OPTN3_PTN4:
25578 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25579 break;
25580 }
25581 } else if (unlikely(XRc == 0)) {
25582 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25583 switch (optn3) {
25584 case MXU_OPTN3_PTN0:
25585 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25586 break;
25587 case MXU_OPTN3_PTN1:
25588 case MXU_OPTN3_PTN2:
25589 case MXU_OPTN3_PTN3:
25590 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25591 break;
25592 case MXU_OPTN3_PTN4:
25593 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25594 break;
25595 }
25596 } else if (unlikely(XRb == XRc)) {
25597 /* both operands same -> just rotation or moving from any of them */
25598 switch (optn3) {
25599 case MXU_OPTN3_PTN0:
25600 case MXU_OPTN3_PTN4:
25601 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25602 break;
25603 case MXU_OPTN3_PTN1:
25604 case MXU_OPTN3_PTN2:
25605 case MXU_OPTN3_PTN3:
25606 tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25607 break;
25608 }
25609 } else {
25610 /* the most general case */
25611 switch (optn3) {
25612 case MXU_OPTN3_PTN0:
25613 {
25614 /* */
25615 /* XRb XRc */
25616 /* +---------------+ */
25617 /* | A B C D | E F G H */
25618 /* +-------+-------+ */
25619 /* | */
25620 /* XRa */
25621 /* */
25622
25623 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25624 }
25625 break;
25626 case MXU_OPTN3_PTN1:
25627 {
25628 /* */
25629 /* XRb XRc */
25630 /* +-------------------+ */
25631 /* A | B C D E | F G H */
25632 /* +---------+---------+ */
25633 /* | */
25634 /* XRa */
25635 /* */
25636
25637 TCGv_i32 t0 = tcg_temp_new();
25638 TCGv_i32 t1 = tcg_temp_new();
25639
25640 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25641 tcg_gen_shli_i32(t0, t0, 8);
25642
25643 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25644 tcg_gen_shri_i32(t1, t1, 24);
25645
25646 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25647
25648 tcg_temp_free(t1);
25649 tcg_temp_free(t0);
25650 }
25651 break;
25652 case MXU_OPTN3_PTN2:
25653 {
25654 /* */
25655 /* XRb XRc */
25656 /* +-------------------+ */
25657 /* A B | C D E F | G H */
25658 /* +---------+---------+ */
25659 /* | */
25660 /* XRa */
25661 /* */
25662
25663 TCGv_i32 t0 = tcg_temp_new();
25664 TCGv_i32 t1 = tcg_temp_new();
25665
25666 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25667 tcg_gen_shli_i32(t0, t0, 16);
25668
25669 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25670 tcg_gen_shri_i32(t1, t1, 16);
25671
25672 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25673
25674 tcg_temp_free(t1);
25675 tcg_temp_free(t0);
25676 }
25677 break;
25678 case MXU_OPTN3_PTN3:
25679 {
25680 /* */
25681 /* XRb XRc */
25682 /* +-------------------+ */
25683 /* A B C | D E F G | H */
25684 /* +---------+---------+ */
25685 /* | */
25686 /* XRa */
25687 /* */
25688
25689 TCGv_i32 t0 = tcg_temp_new();
25690 TCGv_i32 t1 = tcg_temp_new();
25691
25692 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25693 tcg_gen_shli_i32(t0, t0, 24);
25694
25695 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25696 tcg_gen_shri_i32(t1, t1, 8);
25697
25698 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25699
25700 tcg_temp_free(t1);
25701 tcg_temp_free(t0);
25702 }
25703 break;
25704 case MXU_OPTN3_PTN4:
25705 {
25706 /* */
25707 /* XRb XRc */
25708 /* +---------------+ */
25709 /* A B C D | E F G H | */
25710 /* +-------+-------+ */
25711 /* | */
25712 /* XRa */
25713 /* */
25714
25715 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25716 }
25717 break;
25718 }
25719 }
25720 }
25721
25722
25723 /*
25724 * Decoding engine for MXU
25725 * =======================
25726 */
25727
25728 /*
25729 *
25730 * Decode MXU pool00
25731 *
25732 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25733 * +-----------+---------+-----+-------+-------+-------+-----------+
25734 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25735 * +-----------+---------+-----+-------+-------+-------+-----------+
25736 *
25737 */
25738 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25739 {
25740 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25741
25742 switch (opcode) {
25743 case OPC_MXU_S32MAX:
25744 case OPC_MXU_S32MIN:
25745 gen_mxu_S32MAX_S32MIN(ctx);
25746 break;
25747 case OPC_MXU_D16MAX:
25748 case OPC_MXU_D16MIN:
25749 gen_mxu_D16MAX_D16MIN(ctx);
25750 break;
25751 case OPC_MXU_Q8MAX:
25752 case OPC_MXU_Q8MIN:
25753 gen_mxu_Q8MAX_Q8MIN(ctx);
25754 break;
25755 case OPC_MXU_Q8SLT:
25756 /* TODO: Implement emulation of Q8SLT instruction. */
25757 MIPS_INVAL("OPC_MXU_Q8SLT");
25758 generate_exception_end(ctx, EXCP_RI);
25759 break;
25760 case OPC_MXU_Q8SLTU:
25761 /* TODO: Implement emulation of Q8SLTU instruction. */
25762 MIPS_INVAL("OPC_MXU_Q8SLTU");
25763 generate_exception_end(ctx, EXCP_RI);
25764 break;
25765 default:
25766 MIPS_INVAL("decode_opc_mxu");
25767 generate_exception_end(ctx, EXCP_RI);
25768 break;
25769 }
25770 }
25771
25772 /*
25773 *
25774 * Decode MXU pool01
25775 *
25776 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25777 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25778 * +-----------+---------+-----+-------+-------+-------+-----------+
25779 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25780 * +-----------+---------+-----+-------+-------+-------+-----------+
25781 *
25782 * Q8ADD:
25783 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25784 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25785 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25786 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25787 *
25788 */
25789 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25790 {
25791 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25792
25793 switch (opcode) {
25794 case OPC_MXU_S32SLT:
25795 /* TODO: Implement emulation of S32SLT instruction. */
25796 MIPS_INVAL("OPC_MXU_S32SLT");
25797 generate_exception_end(ctx, EXCP_RI);
25798 break;
25799 case OPC_MXU_D16SLT:
25800 /* TODO: Implement emulation of D16SLT instruction. */
25801 MIPS_INVAL("OPC_MXU_D16SLT");
25802 generate_exception_end(ctx, EXCP_RI);
25803 break;
25804 case OPC_MXU_D16AVG:
25805 /* TODO: Implement emulation of D16AVG instruction. */
25806 MIPS_INVAL("OPC_MXU_D16AVG");
25807 generate_exception_end(ctx, EXCP_RI);
25808 break;
25809 case OPC_MXU_D16AVGR:
25810 /* TODO: Implement emulation of D16AVGR instruction. */
25811 MIPS_INVAL("OPC_MXU_D16AVGR");
25812 generate_exception_end(ctx, EXCP_RI);
25813 break;
25814 case OPC_MXU_Q8AVG:
25815 /* TODO: Implement emulation of Q8AVG instruction. */
25816 MIPS_INVAL("OPC_MXU_Q8AVG");
25817 generate_exception_end(ctx, EXCP_RI);
25818 break;
25819 case OPC_MXU_Q8AVGR:
25820 /* TODO: Implement emulation of Q8AVGR instruction. */
25821 MIPS_INVAL("OPC_MXU_Q8AVGR");
25822 generate_exception_end(ctx, EXCP_RI);
25823 break;
25824 case OPC_MXU_Q8ADD:
25825 /* TODO: Implement emulation of Q8ADD instruction. */
25826 MIPS_INVAL("OPC_MXU_Q8ADD");
25827 generate_exception_end(ctx, EXCP_RI);
25828 break;
25829 default:
25830 MIPS_INVAL("decode_opc_mxu");
25831 generate_exception_end(ctx, EXCP_RI);
25832 break;
25833 }
25834 }
25835
25836 /*
25837 *
25838 * Decode MXU pool02
25839 *
25840 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25841 * +-----------+---------+-----+-------+-------+-------+-----------+
25842 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
25843 * +-----------+---------+-----+-------+-------+-------+-----------+
25844 *
25845 */
25846 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25847 {
25848 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25849
25850 switch (opcode) {
25851 case OPC_MXU_S32CPS:
25852 /* TODO: Implement emulation of S32CPS instruction. */
25853 MIPS_INVAL("OPC_MXU_S32CPS");
25854 generate_exception_end(ctx, EXCP_RI);
25855 break;
25856 case OPC_MXU_D16CPS:
25857 /* TODO: Implement emulation of D16CPS instruction. */
25858 MIPS_INVAL("OPC_MXU_D16CPS");
25859 generate_exception_end(ctx, EXCP_RI);
25860 break;
25861 case OPC_MXU_Q8ABD:
25862 /* TODO: Implement emulation of Q8ABD instruction. */
25863 MIPS_INVAL("OPC_MXU_Q8ABD");
25864 generate_exception_end(ctx, EXCP_RI);
25865 break;
25866 case OPC_MXU_Q16SAT:
25867 /* TODO: Implement emulation of Q16SAT instruction. */
25868 MIPS_INVAL("OPC_MXU_Q16SAT");
25869 generate_exception_end(ctx, EXCP_RI);
25870 break;
25871 default:
25872 MIPS_INVAL("decode_opc_mxu");
25873 generate_exception_end(ctx, EXCP_RI);
25874 break;
25875 }
25876 }
25877
25878 /*
25879 *
25880 * Decode MXU pool03
25881 *
25882 * D16MULF:
25883 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25884 * +-----------+---+---+-------+-------+-------+-------+-----------+
25885 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
25886 * +-----------+---+---+-------+-------+-------+-------+-----------+
25887 *
25888 * D16MULE:
25889 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25890 * +-----------+---+---+-------+-------+-------+-------+-----------+
25891 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
25892 * +-----------+---+---+-------+-------+-------+-------+-----------+
25893 *
25894 */
25895 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25896 {
25897 uint32_t opcode = extract32(ctx->opcode, 24, 2);
25898
25899 switch (opcode) {
25900 case OPC_MXU_D16MULF:
25901 /* TODO: Implement emulation of D16MULF instruction. */
25902 MIPS_INVAL("OPC_MXU_D16MULF");
25903 generate_exception_end(ctx, EXCP_RI);
25904 break;
25905 case OPC_MXU_D16MULE:
25906 /* TODO: Implement emulation of D16MULE instruction. */
25907 MIPS_INVAL("OPC_MXU_D16MULE");
25908 generate_exception_end(ctx, EXCP_RI);
25909 break;
25910 default:
25911 MIPS_INVAL("decode_opc_mxu");
25912 generate_exception_end(ctx, EXCP_RI);
25913 break;
25914 }
25915 }
25916
25917 /*
25918 *
25919 * Decode MXU pool04
25920 *
25921 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25922 * +-----------+---------+-+-------------------+-------+-----------+
25923 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
25924 * +-----------+---------+-+-------------------+-------+-----------+
25925 *
25926 */
25927 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25928 {
25929 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25930
25931 switch (opcode) {
25932 case OPC_MXU_S32LDD:
25933 case OPC_MXU_S32LDDR:
25934 gen_mxu_s32ldd_s32lddr(ctx);
25935 break;
25936 default:
25937 MIPS_INVAL("decode_opc_mxu");
25938 generate_exception_end(ctx, EXCP_RI);
25939 break;
25940 }
25941 }
25942
25943 /*
25944 *
25945 * Decode MXU pool05
25946 *
25947 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25948 * +-----------+---------+-+-------------------+-------+-----------+
25949 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
25950 * +-----------+---------+-+-------------------+-------+-----------+
25951 *
25952 */
25953 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25954 {
25955 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25956
25957 switch (opcode) {
25958 case OPC_MXU_S32STD:
25959 /* TODO: Implement emulation of S32STD instruction. */
25960 MIPS_INVAL("OPC_MXU_S32STD");
25961 generate_exception_end(ctx, EXCP_RI);
25962 break;
25963 case OPC_MXU_S32STDR:
25964 /* TODO: Implement emulation of S32STDR instruction. */
25965 MIPS_INVAL("OPC_MXU_S32STDR");
25966 generate_exception_end(ctx, EXCP_RI);
25967 break;
25968 default:
25969 MIPS_INVAL("decode_opc_mxu");
25970 generate_exception_end(ctx, EXCP_RI);
25971 break;
25972 }
25973 }
25974
25975 /*
25976 *
25977 * Decode MXU pool06
25978 *
25979 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25980 * +-----------+---------+---------+---+-------+-------+-----------+
25981 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
25982 * +-----------+---------+---------+---+-------+-------+-----------+
25983 *
25984 */
25985 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25986 {
25987 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25988
25989 switch (opcode) {
25990 case OPC_MXU_S32LDDV:
25991 /* TODO: Implement emulation of S32LDDV instruction. */
25992 MIPS_INVAL("OPC_MXU_S32LDDV");
25993 generate_exception_end(ctx, EXCP_RI);
25994 break;
25995 case OPC_MXU_S32LDDVR:
25996 /* TODO: Implement emulation of S32LDDVR instruction. */
25997 MIPS_INVAL("OPC_MXU_S32LDDVR");
25998 generate_exception_end(ctx, EXCP_RI);
25999 break;
26000 default:
26001 MIPS_INVAL("decode_opc_mxu");
26002 generate_exception_end(ctx, EXCP_RI);
26003 break;
26004 }
26005 }
26006
26007 /*
26008 *
26009 * Decode MXU pool07
26010 *
26011 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26012 * +-----------+---------+---------+---+-------+-------+-----------+
26013 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26014 * +-----------+---------+---------+---+-------+-------+-----------+
26015 *
26016 */
26017 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
26018 {
26019 uint32_t opcode = extract32(ctx->opcode, 10, 4);
26020
26021 switch (opcode) {
26022 case OPC_MXU_S32STDV:
26023 /* TODO: Implement emulation of S32TDV instruction. */
26024 MIPS_INVAL("OPC_MXU_S32TDV");
26025 generate_exception_end(ctx, EXCP_RI);
26026 break;
26027 case OPC_MXU_S32STDVR:
26028 /* TODO: Implement emulation of S32TDVR instruction. */
26029 MIPS_INVAL("OPC_MXU_S32TDVR");
26030 generate_exception_end(ctx, EXCP_RI);
26031 break;
26032 default:
26033 MIPS_INVAL("decode_opc_mxu");
26034 generate_exception_end(ctx, EXCP_RI);
26035 break;
26036 }
26037 }
26038
26039 /*
26040 *
26041 * Decode MXU pool08
26042 *
26043 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26044 * +-----------+---------+-+-------------------+-------+-----------+
26045 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26046 * +-----------+---------+-+-------------------+-------+-----------+
26047 *
26048 */
26049 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
26050 {
26051 uint32_t opcode = extract32(ctx->opcode, 20, 1);
26052
26053 switch (opcode) {
26054 case OPC_MXU_S32LDI:
26055 /* TODO: Implement emulation of S32LDI instruction. */
26056 MIPS_INVAL("OPC_MXU_S32LDI");
26057 generate_exception_end(ctx, EXCP_RI);
26058 break;
26059 case OPC_MXU_S32LDIR:
26060 /* TODO: Implement emulation of S32LDIR instruction. */
26061 MIPS_INVAL("OPC_MXU_S32LDIR");
26062 generate_exception_end(ctx, EXCP_RI);
26063 break;
26064 default:
26065 MIPS_INVAL("decode_opc_mxu");
26066 generate_exception_end(ctx, EXCP_RI);
26067 break;
26068 }
26069 }
26070
26071 /*
26072 *
26073 * Decode MXU pool09
26074 *
26075 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26076 * +-----------+---------+-+-------------------+-------+-----------+
26077 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26078 * +-----------+---------+-+-------------------+-------+-----------+
26079 *
26080 */
26081 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
26082 {
26083 uint32_t opcode = extract32(ctx->opcode, 5, 0);
26084
26085 switch (opcode) {
26086 case OPC_MXU_S32SDI:
26087 /* TODO: Implement emulation of S32SDI instruction. */
26088 MIPS_INVAL("OPC_MXU_S32SDI");
26089 generate_exception_end(ctx, EXCP_RI);
26090 break;
26091 case OPC_MXU_S32SDIR:
26092 /* TODO: Implement emulation of S32SDIR instruction. */
26093 MIPS_INVAL("OPC_MXU_S32SDIR");
26094 generate_exception_end(ctx, EXCP_RI);
26095 break;
26096 default:
26097 MIPS_INVAL("decode_opc_mxu");
26098 generate_exception_end(ctx, EXCP_RI);
26099 break;
26100 }
26101 }
26102
26103 /*
26104 *
26105 * Decode MXU pool10
26106 *
26107 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26108 * +-----------+---------+---------+---+-------+-------+-----------+
26109 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26110 * +-----------+---------+---------+---+-------+-------+-----------+
26111 *
26112 */
26113 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
26114 {
26115 uint32_t opcode = extract32(ctx->opcode, 5, 0);
26116
26117 switch (opcode) {
26118 case OPC_MXU_S32LDIV:
26119 /* TODO: Implement emulation of S32LDIV instruction. */
26120 MIPS_INVAL("OPC_MXU_S32LDIV");
26121 generate_exception_end(ctx, EXCP_RI);
26122 break;
26123 case OPC_MXU_S32LDIVR:
26124 /* TODO: Implement emulation of S32LDIVR instruction. */
26125 MIPS_INVAL("OPC_MXU_S32LDIVR");
26126 generate_exception_end(ctx, EXCP_RI);
26127 break;
26128 default:
26129 MIPS_INVAL("decode_opc_mxu");
26130 generate_exception_end(ctx, EXCP_RI);
26131 break;
26132 }
26133 }
26134
26135 /*
26136 *
26137 * Decode MXU pool11
26138 *
26139 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26140 * +-----------+---------+---------+---+-------+-------+-----------+
26141 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26142 * +-----------+---------+---------+---+-------+-------+-----------+
26143 *
26144 */
26145 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
26146 {
26147 uint32_t opcode = extract32(ctx->opcode, 10, 4);
26148
26149 switch (opcode) {
26150 case OPC_MXU_S32SDIV:
26151 /* TODO: Implement emulation of S32SDIV instruction. */
26152 MIPS_INVAL("OPC_MXU_S32SDIV");
26153 generate_exception_end(ctx, EXCP_RI);
26154 break;
26155 case OPC_MXU_S32SDIVR:
26156 /* TODO: Implement emulation of S32SDIVR instruction. */
26157 MIPS_INVAL("OPC_MXU_S32SDIVR");
26158 generate_exception_end(ctx, EXCP_RI);
26159 break;
26160 default:
26161 MIPS_INVAL("decode_opc_mxu");
26162 generate_exception_end(ctx, EXCP_RI);
26163 break;
26164 }
26165 }
26166
26167 /*
26168 *
26169 * Decode MXU pool12
26170 *
26171 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26172 * +-----------+---+---+-------+-------+-------+-------+-----------+
26173 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26174 * +-----------+---+---+-------+-------+-------+-------+-----------+
26175 *
26176 */
26177 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
26178 {
26179 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26180
26181 switch (opcode) {
26182 case OPC_MXU_D32ACC:
26183 /* TODO: Implement emulation of D32ACC instruction. */
26184 MIPS_INVAL("OPC_MXU_D32ACC");
26185 generate_exception_end(ctx, EXCP_RI);
26186 break;
26187 case OPC_MXU_D32ACCM:
26188 /* TODO: Implement emulation of D32ACCM instruction. */
26189 MIPS_INVAL("OPC_MXU_D32ACCM");
26190 generate_exception_end(ctx, EXCP_RI);
26191 break;
26192 case OPC_MXU_D32ASUM:
26193 /* TODO: Implement emulation of D32ASUM instruction. */
26194 MIPS_INVAL("OPC_MXU_D32ASUM");
26195 generate_exception_end(ctx, EXCP_RI);
26196 break;
26197 default:
26198 MIPS_INVAL("decode_opc_mxu");
26199 generate_exception_end(ctx, EXCP_RI);
26200 break;
26201 }
26202 }
26203
26204 /*
26205 *
26206 * Decode MXU pool13
26207 *
26208 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26209 * +-----------+---+---+-------+-------+-------+-------+-----------+
26210 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26211 * +-----------+---+---+-------+-------+-------+-------+-----------+
26212 *
26213 */
26214 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
26215 {
26216 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26217
26218 switch (opcode) {
26219 case OPC_MXU_Q16ACC:
26220 /* TODO: Implement emulation of Q16ACC instruction. */
26221 MIPS_INVAL("OPC_MXU_Q16ACC");
26222 generate_exception_end(ctx, EXCP_RI);
26223 break;
26224 case OPC_MXU_Q16ACCM:
26225 /* TODO: Implement emulation of Q16ACCM instruction. */
26226 MIPS_INVAL("OPC_MXU_Q16ACCM");
26227 generate_exception_end(ctx, EXCP_RI);
26228 break;
26229 case OPC_MXU_Q16ASUM:
26230 /* TODO: Implement emulation of Q16ASUM instruction. */
26231 MIPS_INVAL("OPC_MXU_Q16ASUM");
26232 generate_exception_end(ctx, EXCP_RI);
26233 break;
26234 default:
26235 MIPS_INVAL("decode_opc_mxu");
26236 generate_exception_end(ctx, EXCP_RI);
26237 break;
26238 }
26239 }
26240
26241 /*
26242 *
26243 * Decode MXU pool14
26244 *
26245 * Q8ADDE, Q8ACCE:
26246 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26247 * +-----------+---+---+-------+-------+-------+-------+-----------+
26248 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26249 * +-----------+---+---+-------+-------+-------+-------+-----------+
26250 *
26251 * D8SUM, D8SUMC:
26252 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26253 * +-----------+---+---+-------+-------+-------+-------+-----------+
26254 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26255 * +-----------+---+---+-------+-------+-------+-------+-----------+
26256 *
26257 */
26258 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
26259 {
26260 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26261
26262 switch (opcode) {
26263 case OPC_MXU_Q8ADDE:
26264 /* TODO: Implement emulation of Q8ADDE instruction. */
26265 MIPS_INVAL("OPC_MXU_Q8ADDE");
26266 generate_exception_end(ctx, EXCP_RI);
26267 break;
26268 case OPC_MXU_D8SUM:
26269 /* TODO: Implement emulation of D8SUM instruction. */
26270 MIPS_INVAL("OPC_MXU_D8SUM");
26271 generate_exception_end(ctx, EXCP_RI);
26272 break;
26273 case OPC_MXU_D8SUMC:
26274 /* TODO: Implement emulation of D8SUMC instruction. */
26275 MIPS_INVAL("OPC_MXU_D8SUMC");
26276 generate_exception_end(ctx, EXCP_RI);
26277 break;
26278 default:
26279 MIPS_INVAL("decode_opc_mxu");
26280 generate_exception_end(ctx, EXCP_RI);
26281 break;
26282 }
26283 }
26284
26285 /*
26286 *
26287 * Decode MXU pool15
26288 *
26289 * S32MUL, S32MULU, S32EXTRV:
26290 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26291 * +-----------+---------+---------+---+-------+-------+-----------+
26292 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26293 * +-----------+---------+---------+---+-------+-------+-----------+
26294 *
26295 * S32EXTR:
26296 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26297 * +-----------+---------+---------+---+-------+-------+-----------+
26298 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26299 * +-----------+---------+---------+---+-------+-------+-----------+
26300 *
26301 */
26302 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
26303 {
26304 uint32_t opcode = extract32(ctx->opcode, 14, 2);
26305
26306 switch (opcode) {
26307 case OPC_MXU_S32MUL:
26308 /* TODO: Implement emulation of S32MUL instruction. */
26309 MIPS_INVAL("OPC_MXU_S32MUL");
26310 generate_exception_end(ctx, EXCP_RI);
26311 break;
26312 case OPC_MXU_S32MULU:
26313 /* TODO: Implement emulation of S32MULU instruction. */
26314 MIPS_INVAL("OPC_MXU_S32MULU");
26315 generate_exception_end(ctx, EXCP_RI);
26316 break;
26317 case OPC_MXU_S32EXTR:
26318 /* TODO: Implement emulation of S32EXTR instruction. */
26319 MIPS_INVAL("OPC_MXU_S32EXTR");
26320 generate_exception_end(ctx, EXCP_RI);
26321 break;
26322 case OPC_MXU_S32EXTRV:
26323 /* TODO: Implement emulation of S32EXTRV instruction. */
26324 MIPS_INVAL("OPC_MXU_S32EXTRV");
26325 generate_exception_end(ctx, EXCP_RI);
26326 break;
26327 default:
26328 MIPS_INVAL("decode_opc_mxu");
26329 generate_exception_end(ctx, EXCP_RI);
26330 break;
26331 }
26332 }
26333
26334 /*
26335 *
26336 * Decode MXU pool16
26337 *
26338 * D32SARW:
26339 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26340 * +-----------+---------+-----+-------+-------+-------+-----------+
26341 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26342 * +-----------+---------+-----+-------+-------+-------+-----------+
26343 *
26344 * S32ALN:
26345 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26346 * +-----------+---------+-----+-------+-------+-------+-----------+
26347 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26348 * +-----------+---------+-----+-------+-------+-------+-----------+
26349 *
26350 * S32ALNI:
26351 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26352 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26353 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26354 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26355 *
26356 * S32LUI:
26357 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26358 * +-----------+-----+---+-----+-------+---------------+-----------+
26359 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26360 * +-----------+-----+---+-----+-------+---------------+-----------+
26361 *
26362 * S32NOR, S32AND, S32OR, S32XOR:
26363 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26364 * +-----------+---------+-----+-------+-------+-------+-----------+
26365 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26366 * +-----------+---------+-----+-------+-------+-------+-----------+
26367 *
26368 */
26369 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26370 {
26371 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26372
26373 switch (opcode) {
26374 case OPC_MXU_D32SARW:
26375 /* TODO: Implement emulation of D32SARW instruction. */
26376 MIPS_INVAL("OPC_MXU_D32SARW");
26377 generate_exception_end(ctx, EXCP_RI);
26378 break;
26379 case OPC_MXU_S32ALN:
26380 /* TODO: Implement emulation of S32ALN instruction. */
26381 MIPS_INVAL("OPC_MXU_S32ALN");
26382 generate_exception_end(ctx, EXCP_RI);
26383 break;
26384 case OPC_MXU_S32ALNI:
26385 gen_mxu_S32ALNI(ctx);
26386 break;
26387 case OPC_MXU_S32LUI:
26388 /* TODO: Implement emulation of S32LUI instruction. */
26389 MIPS_INVAL("OPC_MXU_S32LUI");
26390 generate_exception_end(ctx, EXCP_RI);
26391 break;
26392 case OPC_MXU_S32NOR:
26393 gen_mxu_S32NOR(ctx);
26394 break;
26395 case OPC_MXU_S32AND:
26396 gen_mxu_S32AND(ctx);
26397 break;
26398 case OPC_MXU_S32OR:
26399 gen_mxu_S32OR(ctx);
26400 break;
26401 case OPC_MXU_S32XOR:
26402 gen_mxu_S32XOR(ctx);
26403 break;
26404 default:
26405 MIPS_INVAL("decode_opc_mxu");
26406 generate_exception_end(ctx, EXCP_RI);
26407 break;
26408 }
26409 }
26410
26411 /*
26412 *
26413 * Decode MXU pool17
26414 *
26415 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26416 * +-----------+---------+---------+---+---------+-----+-----------+
26417 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26418 * +-----------+---------+---------+---+---------+-----+-----------+
26419 *
26420 */
26421 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26422 {
26423 uint32_t opcode = extract32(ctx->opcode, 6, 2);
26424
26425 switch (opcode) {
26426 case OPC_MXU_LXW:
26427 /* TODO: Implement emulation of LXW instruction. */
26428 MIPS_INVAL("OPC_MXU_LXW");
26429 generate_exception_end(ctx, EXCP_RI);
26430 break;
26431 case OPC_MXU_LXH:
26432 /* TODO: Implement emulation of LXH instruction. */
26433 MIPS_INVAL("OPC_MXU_LXH");
26434 generate_exception_end(ctx, EXCP_RI);
26435 break;
26436 case OPC_MXU_LXHU:
26437 /* TODO: Implement emulation of LXHU instruction. */
26438 MIPS_INVAL("OPC_MXU_LXHU");
26439 generate_exception_end(ctx, EXCP_RI);
26440 break;
26441 case OPC_MXU_LXB:
26442 /* TODO: Implement emulation of LXB instruction. */
26443 MIPS_INVAL("OPC_MXU_LXB");
26444 generate_exception_end(ctx, EXCP_RI);
26445 break;
26446 case OPC_MXU_LXBU:
26447 /* TODO: Implement emulation of LXBU instruction. */
26448 MIPS_INVAL("OPC_MXU_LXBU");
26449 generate_exception_end(ctx, EXCP_RI);
26450 break;
26451 default:
26452 MIPS_INVAL("decode_opc_mxu");
26453 generate_exception_end(ctx, EXCP_RI);
26454 break;
26455 }
26456 }
26457 /*
26458 *
26459 * Decode MXU pool18
26460 *
26461 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26462 * +-----------+---------+-----+-------+-------+-------+-----------+
26463 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26464 * +-----------+---------+-----+-------+-------+-------+-----------+
26465 *
26466 */
26467 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26468 {
26469 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26470
26471 switch (opcode) {
26472 case OPC_MXU_D32SLLV:
26473 /* TODO: Implement emulation of D32SLLV instruction. */
26474 MIPS_INVAL("OPC_MXU_D32SLLV");
26475 generate_exception_end(ctx, EXCP_RI);
26476 break;
26477 case OPC_MXU_D32SLRV:
26478 /* TODO: Implement emulation of D32SLRV instruction. */
26479 MIPS_INVAL("OPC_MXU_D32SLRV");
26480 generate_exception_end(ctx, EXCP_RI);
26481 break;
26482 case OPC_MXU_D32SARV:
26483 /* TODO: Implement emulation of D32SARV instruction. */
26484 MIPS_INVAL("OPC_MXU_D32SARV");
26485 generate_exception_end(ctx, EXCP_RI);
26486 break;
26487 case OPC_MXU_Q16SLLV:
26488 /* TODO: Implement emulation of Q16SLLV instruction. */
26489 MIPS_INVAL("OPC_MXU_Q16SLLV");
26490 generate_exception_end(ctx, EXCP_RI);
26491 break;
26492 case OPC_MXU_Q16SLRV:
26493 /* TODO: Implement emulation of Q16SLRV instruction. */
26494 MIPS_INVAL("OPC_MXU_Q16SLRV");
26495 generate_exception_end(ctx, EXCP_RI);
26496 break;
26497 case OPC_MXU_Q16SARV:
26498 /* TODO: Implement emulation of Q16SARV instruction. */
26499 MIPS_INVAL("OPC_MXU_Q16SARV");
26500 generate_exception_end(ctx, EXCP_RI);
26501 break;
26502 default:
26503 MIPS_INVAL("decode_opc_mxu");
26504 generate_exception_end(ctx, EXCP_RI);
26505 break;
26506 }
26507 }
26508
26509 /*
26510 *
26511 * Decode MXU pool19
26512 *
26513 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26514 * +-----------+---+---+-------+-------+-------+-------+-----------+
26515 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
26516 * +-----------+---+---+-------+-------+-------+-------+-----------+
26517 *
26518 */
26519 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26520 {
26521 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26522
26523 switch (opcode) {
26524 case OPC_MXU_Q8MUL:
26525 case OPC_MXU_Q8MULSU:
26526 gen_mxu_q8mul_q8mulsu(ctx);
26527 break;
26528 default:
26529 MIPS_INVAL("decode_opc_mxu");
26530 generate_exception_end(ctx, EXCP_RI);
26531 break;
26532 }
26533 }
26534
26535 /*
26536 *
26537 * Decode MXU pool20
26538 *
26539 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26540 * +-----------+---------+-----+-------+-------+-------+-----------+
26541 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
26542 * +-----------+---------+-----+-------+-------+-------+-----------+
26543 *
26544 */
26545 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26546 {
26547 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26548
26549 switch (opcode) {
26550 case OPC_MXU_Q8MOVZ:
26551 /* TODO: Implement emulation of Q8MOVZ instruction. */
26552 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26553 generate_exception_end(ctx, EXCP_RI);
26554 break;
26555 case OPC_MXU_Q8MOVN:
26556 /* TODO: Implement emulation of Q8MOVN instruction. */
26557 MIPS_INVAL("OPC_MXU_Q8MOVN");
26558 generate_exception_end(ctx, EXCP_RI);
26559 break;
26560 case OPC_MXU_D16MOVZ:
26561 /* TODO: Implement emulation of D16MOVZ instruction. */
26562 MIPS_INVAL("OPC_MXU_D16MOVZ");
26563 generate_exception_end(ctx, EXCP_RI);
26564 break;
26565 case OPC_MXU_D16MOVN:
26566 /* TODO: Implement emulation of D16MOVN instruction. */
26567 MIPS_INVAL("OPC_MXU_D16MOVN");
26568 generate_exception_end(ctx, EXCP_RI);
26569 break;
26570 case OPC_MXU_S32MOVZ:
26571 /* TODO: Implement emulation of S32MOVZ instruction. */
26572 MIPS_INVAL("OPC_MXU_S32MOVZ");
26573 generate_exception_end(ctx, EXCP_RI);
26574 break;
26575 case OPC_MXU_S32MOVN:
26576 /* TODO: Implement emulation of S32MOVN instruction. */
26577 MIPS_INVAL("OPC_MXU_S32MOVN");
26578 generate_exception_end(ctx, EXCP_RI);
26579 break;
26580 default:
26581 MIPS_INVAL("decode_opc_mxu");
26582 generate_exception_end(ctx, EXCP_RI);
26583 break;
26584 }
26585 }
26586
26587 /*
26588 *
26589 * Decode MXU pool21
26590 *
26591 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26592 * +-----------+---+---+-------+-------+-------+-------+-----------+
26593 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
26594 * +-----------+---+---+-------+-------+-------+-------+-----------+
26595 *
26596 */
26597 static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26598 {
26599 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26600
26601 switch (opcode) {
26602 case OPC_MXU_Q8MAC:
26603 /* TODO: Implement emulation of Q8MAC instruction. */
26604 MIPS_INVAL("OPC_MXU_Q8MAC");
26605 generate_exception_end(ctx, EXCP_RI);
26606 break;
26607 case OPC_MXU_Q8MACSU:
26608 /* TODO: Implement emulation of Q8MACSU instruction. */
26609 MIPS_INVAL("OPC_MXU_Q8MACSU");
26610 generate_exception_end(ctx, EXCP_RI);
26611 break;
26612 default:
26613 MIPS_INVAL("decode_opc_mxu");
26614 generate_exception_end(ctx, EXCP_RI);
26615 break;
26616 }
26617 }
26618
26619
26620 /*
26621 * Main MXU decoding function
26622 *
26623 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26624 * +-----------+---------------------------------------+-----------+
26625 * | SPECIAL2 | |x x x x x x|
26626 * +-----------+---------------------------------------+-----------+
26627 *
26628 */
26629 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26630 {
26631 /*
26632 * TODO: Investigate necessity of including handling of
26633 * CLZ, CLO, SDBB in this function, as they belong to
26634 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26635 */
26636 uint32_t opcode = extract32(ctx->opcode, 0, 6);
26637
26638 if (opcode == OPC__MXU_MUL) {
26639 uint32_t rs, rt, rd, op1;
26640
26641 rs = extract32(ctx->opcode, 21, 5);
26642 rt = extract32(ctx->opcode, 16, 5);
26643 rd = extract32(ctx->opcode, 11, 5);
26644 op1 = MASK_SPECIAL2(ctx->opcode);
26645
26646 gen_arith(ctx, op1, rd, rs, rt);
26647
26648 return;
26649 }
26650
26651 if (opcode == OPC_MXU_S32M2I) {
26652 gen_mxu_s32m2i(ctx);
26653 return;
26654 }
26655
26656 if (opcode == OPC_MXU_S32I2M) {
26657 gen_mxu_s32i2m(ctx);
26658 return;
26659 }
26660
26661 {
26662 TCGv t_mxu_cr = tcg_temp_new();
26663 TCGLabel *l_exit = gen_new_label();
26664
26665 gen_load_mxu_cr(t_mxu_cr);
26666 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26667 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26668
26669 switch (opcode) {
26670 case OPC_MXU_S32MADD:
26671 /* TODO: Implement emulation of S32MADD instruction. */
26672 MIPS_INVAL("OPC_MXU_S32MADD");
26673 generate_exception_end(ctx, EXCP_RI);
26674 break;
26675 case OPC_MXU_S32MADDU:
26676 /* TODO: Implement emulation of S32MADDU instruction. */
26677 MIPS_INVAL("OPC_MXU_S32MADDU");
26678 generate_exception_end(ctx, EXCP_RI);
26679 break;
26680 case OPC_MXU__POOL00:
26681 decode_opc_mxu__pool00(env, ctx);
26682 break;
26683 case OPC_MXU_S32MSUB:
26684 /* TODO: Implement emulation of S32MSUB instruction. */
26685 MIPS_INVAL("OPC_MXU_S32MSUB");
26686 generate_exception_end(ctx, EXCP_RI);
26687 break;
26688 case OPC_MXU_S32MSUBU:
26689 /* TODO: Implement emulation of S32MSUBU instruction. */
26690 MIPS_INVAL("OPC_MXU_S32MSUBU");
26691 generate_exception_end(ctx, EXCP_RI);
26692 break;
26693 case OPC_MXU__POOL01:
26694 decode_opc_mxu__pool01(env, ctx);
26695 break;
26696 case OPC_MXU__POOL02:
26697 decode_opc_mxu__pool02(env, ctx);
26698 break;
26699 case OPC_MXU_D16MUL:
26700 gen_mxu_d16mul(ctx);
26701 break;
26702 case OPC_MXU__POOL03:
26703 decode_opc_mxu__pool03(env, ctx);
26704 break;
26705 case OPC_MXU_D16MAC:
26706 gen_mxu_d16mac(ctx);
26707 break;
26708 case OPC_MXU_D16MACF:
26709 /* TODO: Implement emulation of D16MACF instruction. */
26710 MIPS_INVAL("OPC_MXU_D16MACF");
26711 generate_exception_end(ctx, EXCP_RI);
26712 break;
26713 case OPC_MXU_D16MADL:
26714 /* TODO: Implement emulation of D16MADL instruction. */
26715 MIPS_INVAL("OPC_MXU_D16MADL");
26716 generate_exception_end(ctx, EXCP_RI);
26717 break;
26718 case OPC_MXU_S16MAD:
26719 /* TODO: Implement emulation of S16MAD instruction. */
26720 MIPS_INVAL("OPC_MXU_S16MAD");
26721 generate_exception_end(ctx, EXCP_RI);
26722 break;
26723 case OPC_MXU_Q16ADD:
26724 /* TODO: Implement emulation of Q16ADD instruction. */
26725 MIPS_INVAL("OPC_MXU_Q16ADD");
26726 generate_exception_end(ctx, EXCP_RI);
26727 break;
26728 case OPC_MXU_D16MACE:
26729 /* TODO: Implement emulation of D16MACE instruction. */
26730 MIPS_INVAL("OPC_MXU_D16MACE");
26731 generate_exception_end(ctx, EXCP_RI);
26732 break;
26733 case OPC_MXU__POOL04:
26734 decode_opc_mxu__pool04(env, ctx);
26735 break;
26736 case OPC_MXU__POOL05:
26737 decode_opc_mxu__pool05(env, ctx);
26738 break;
26739 case OPC_MXU__POOL06:
26740 decode_opc_mxu__pool06(env, ctx);
26741 break;
26742 case OPC_MXU__POOL07:
26743 decode_opc_mxu__pool07(env, ctx);
26744 break;
26745 case OPC_MXU__POOL08:
26746 decode_opc_mxu__pool08(env, ctx);
26747 break;
26748 case OPC_MXU__POOL09:
26749 decode_opc_mxu__pool09(env, ctx);
26750 break;
26751 case OPC_MXU__POOL10:
26752 decode_opc_mxu__pool10(env, ctx);
26753 break;
26754 case OPC_MXU__POOL11:
26755 decode_opc_mxu__pool11(env, ctx);
26756 break;
26757 case OPC_MXU_D32ADD:
26758 /* TODO: Implement emulation of D32ADD instruction. */
26759 MIPS_INVAL("OPC_MXU_D32ADD");
26760 generate_exception_end(ctx, EXCP_RI);
26761 break;
26762 case OPC_MXU__POOL12:
26763 decode_opc_mxu__pool12(env, ctx);
26764 break;
26765 case OPC_MXU__POOL13:
26766 decode_opc_mxu__pool13(env, ctx);
26767 break;
26768 case OPC_MXU__POOL14:
26769 decode_opc_mxu__pool14(env, ctx);
26770 break;
26771 case OPC_MXU_Q8ACCE:
26772 /* TODO: Implement emulation of Q8ACCE instruction. */
26773 MIPS_INVAL("OPC_MXU_Q8ACCE");
26774 generate_exception_end(ctx, EXCP_RI);
26775 break;
26776 case OPC_MXU_S8LDD:
26777 gen_mxu_s8ldd(ctx);
26778 break;
26779 case OPC_MXU_S8STD:
26780 /* TODO: Implement emulation of S8STD instruction. */
26781 MIPS_INVAL("OPC_MXU_S8STD");
26782 generate_exception_end(ctx, EXCP_RI);
26783 break;
26784 case OPC_MXU_S8LDI:
26785 /* TODO: Implement emulation of S8LDI instruction. */
26786 MIPS_INVAL("OPC_MXU_S8LDI");
26787 generate_exception_end(ctx, EXCP_RI);
26788 break;
26789 case OPC_MXU_S8SDI:
26790 /* TODO: Implement emulation of S8SDI instruction. */
26791 MIPS_INVAL("OPC_MXU_S8SDI");
26792 generate_exception_end(ctx, EXCP_RI);
26793 break;
26794 case OPC_MXU__POOL15:
26795 decode_opc_mxu__pool15(env, ctx);
26796 break;
26797 case OPC_MXU__POOL16:
26798 decode_opc_mxu__pool16(env, ctx);
26799 break;
26800 case OPC_MXU__POOL17:
26801 decode_opc_mxu__pool17(env, ctx);
26802 break;
26803 case OPC_MXU_S16LDD:
26804 /* TODO: Implement emulation of S16LDD instruction. */
26805 MIPS_INVAL("OPC_MXU_S16LDD");
26806 generate_exception_end(ctx, EXCP_RI);
26807 break;
26808 case OPC_MXU_S16STD:
26809 /* TODO: Implement emulation of S16STD instruction. */
26810 MIPS_INVAL("OPC_MXU_S16STD");
26811 generate_exception_end(ctx, EXCP_RI);
26812 break;
26813 case OPC_MXU_S16LDI:
26814 /* TODO: Implement emulation of S16LDI instruction. */
26815 MIPS_INVAL("OPC_MXU_S16LDI");
26816 generate_exception_end(ctx, EXCP_RI);
26817 break;
26818 case OPC_MXU_S16SDI:
26819 /* TODO: Implement emulation of S16SDI instruction. */
26820 MIPS_INVAL("OPC_MXU_S16SDI");
26821 generate_exception_end(ctx, EXCP_RI);
26822 break;
26823 case OPC_MXU_D32SLL:
26824 /* TODO: Implement emulation of D32SLL instruction. */
26825 MIPS_INVAL("OPC_MXU_D32SLL");
26826 generate_exception_end(ctx, EXCP_RI);
26827 break;
26828 case OPC_MXU_D32SLR:
26829 /* TODO: Implement emulation of D32SLR instruction. */
26830 MIPS_INVAL("OPC_MXU_D32SLR");
26831 generate_exception_end(ctx, EXCP_RI);
26832 break;
26833 case OPC_MXU_D32SARL:
26834 /* TODO: Implement emulation of D32SARL instruction. */
26835 MIPS_INVAL("OPC_MXU_D32SARL");
26836 generate_exception_end(ctx, EXCP_RI);
26837 break;
26838 case OPC_MXU_D32SAR:
26839 /* TODO: Implement emulation of D32SAR instruction. */
26840 MIPS_INVAL("OPC_MXU_D32SAR");
26841 generate_exception_end(ctx, EXCP_RI);
26842 break;
26843 case OPC_MXU_Q16SLL:
26844 /* TODO: Implement emulation of Q16SLL instruction. */
26845 MIPS_INVAL("OPC_MXU_Q16SLL");
26846 generate_exception_end(ctx, EXCP_RI);
26847 break;
26848 case OPC_MXU_Q16SLR:
26849 /* TODO: Implement emulation of Q16SLR instruction. */
26850 MIPS_INVAL("OPC_MXU_Q16SLR");
26851 generate_exception_end(ctx, EXCP_RI);
26852 break;
26853 case OPC_MXU__POOL18:
26854 decode_opc_mxu__pool18(env, ctx);
26855 break;
26856 case OPC_MXU_Q16SAR:
26857 /* TODO: Implement emulation of Q16SAR instruction. */
26858 MIPS_INVAL("OPC_MXU_Q16SAR");
26859 generate_exception_end(ctx, EXCP_RI);
26860 break;
26861 case OPC_MXU__POOL19:
26862 decode_opc_mxu__pool19(env, ctx);
26863 break;
26864 case OPC_MXU__POOL20:
26865 decode_opc_mxu__pool20(env, ctx);
26866 break;
26867 case OPC_MXU__POOL21:
26868 decode_opc_mxu__pool21(env, ctx);
26869 break;
26870 case OPC_MXU_Q16SCOP:
26871 /* TODO: Implement emulation of Q16SCOP instruction. */
26872 MIPS_INVAL("OPC_MXU_Q16SCOP");
26873 generate_exception_end(ctx, EXCP_RI);
26874 break;
26875 case OPC_MXU_Q8MADL:
26876 /* TODO: Implement emulation of Q8MADL instruction. */
26877 MIPS_INVAL("OPC_MXU_Q8MADL");
26878 generate_exception_end(ctx, EXCP_RI);
26879 break;
26880 case OPC_MXU_S32SFL:
26881 /* TODO: Implement emulation of S32SFL instruction. */
26882 MIPS_INVAL("OPC_MXU_S32SFL");
26883 generate_exception_end(ctx, EXCP_RI);
26884 break;
26885 case OPC_MXU_Q8SAD:
26886 /* TODO: Implement emulation of Q8SAD instruction. */
26887 MIPS_INVAL("OPC_MXU_Q8SAD");
26888 generate_exception_end(ctx, EXCP_RI);
26889 break;
26890 default:
26891 MIPS_INVAL("decode_opc_mxu");
26892 generate_exception_end(ctx, EXCP_RI);
26893 }
26894
26895 gen_set_label(l_exit);
26896 tcg_temp_free(t_mxu_cr);
26897 }
26898 }
26899
26900 #endif /* !defined(TARGET_MIPS64) */
26901
26902
26903 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26904 {
26905 int rs, rt, rd;
26906 uint32_t op1;
26907
26908 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26909
26910 rs = (ctx->opcode >> 21) & 0x1f;
26911 rt = (ctx->opcode >> 16) & 0x1f;
26912 rd = (ctx->opcode >> 11) & 0x1f;
26913
26914 op1 = MASK_SPECIAL2(ctx->opcode);
26915 switch (op1) {
26916 case OPC_MADD: /* Multiply and add/sub */
26917 case OPC_MADDU:
26918 case OPC_MSUB:
26919 case OPC_MSUBU:
26920 check_insn(ctx, ISA_MIPS32);
26921 gen_muldiv(ctx, op1, rd & 3, rs, rt);
26922 break;
26923 case OPC_MUL:
26924 gen_arith(ctx, op1, rd, rs, rt);
26925 break;
26926 case OPC_DIV_G_2F:
26927 case OPC_DIVU_G_2F:
26928 case OPC_MULT_G_2F:
26929 case OPC_MULTU_G_2F:
26930 case OPC_MOD_G_2F:
26931 case OPC_MODU_G_2F:
26932 check_insn(ctx, INSN_LOONGSON2F);
26933 gen_loongson_integer(ctx, op1, rd, rs, rt);
26934 break;
26935 case OPC_CLO:
26936 case OPC_CLZ:
26937 check_insn(ctx, ISA_MIPS32);
26938 gen_cl(ctx, op1, rd, rs);
26939 break;
26940 case OPC_SDBBP:
26941 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26942 gen_helper_do_semihosting(cpu_env);
26943 } else {
26944 /*
26945 * XXX: not clear which exception should be raised
26946 * when in debug mode...
26947 */
26948 check_insn(ctx, ISA_MIPS32);
26949 generate_exception_end(ctx, EXCP_DBp);
26950 }
26951 break;
26952 #if defined(TARGET_MIPS64)
26953 case OPC_DCLO:
26954 case OPC_DCLZ:
26955 check_insn(ctx, ISA_MIPS64);
26956 check_mips_64(ctx);
26957 gen_cl(ctx, op1, rd, rs);
26958 break;
26959 case OPC_DMULT_G_2F:
26960 case OPC_DMULTU_G_2F:
26961 case OPC_DDIV_G_2F:
26962 case OPC_DDIVU_G_2F:
26963 case OPC_DMOD_G_2F:
26964 case OPC_DMODU_G_2F:
26965 check_insn(ctx, INSN_LOONGSON2F);
26966 gen_loongson_integer(ctx, op1, rd, rs, rt);
26967 break;
26968 #endif
26969 default: /* Invalid */
26970 MIPS_INVAL("special2_legacy");
26971 generate_exception_end(ctx, EXCP_RI);
26972 break;
26973 }
26974 }
26975
26976 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26977 {
26978 int rs, rt, rd, sa;
26979 uint32_t op1, op2;
26980 int16_t imm;
26981
26982 rs = (ctx->opcode >> 21) & 0x1f;
26983 rt = (ctx->opcode >> 16) & 0x1f;
26984 rd = (ctx->opcode >> 11) & 0x1f;
26985 sa = (ctx->opcode >> 6) & 0x1f;
26986 imm = (int16_t)ctx->opcode >> 7;
26987
26988 op1 = MASK_SPECIAL3(ctx->opcode);
26989 switch (op1) {
26990 case R6_OPC_PREF:
26991 if (rt >= 24) {
26992 /* hint codes 24-31 are reserved and signal RI */
26993 generate_exception_end(ctx, EXCP_RI);
26994 }
26995 /* Treat as NOP. */
26996 break;
26997 case R6_OPC_CACHE:
26998 check_cp0_enabled(ctx);
26999 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27000 gen_cache_operation(ctx, rt, rs, imm);
27001 }
27002 break;
27003 case R6_OPC_SC:
27004 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
27005 break;
27006 case R6_OPC_LL:
27007 gen_ld(ctx, op1, rt, rs, imm);
27008 break;
27009 case OPC_BSHFL:
27010 {
27011 if (rd == 0) {
27012 /* Treat as NOP. */
27013 break;
27014 }
27015 op2 = MASK_BSHFL(ctx->opcode);
27016 switch (op2) {
27017 case OPC_ALIGN:
27018 case OPC_ALIGN_1:
27019 case OPC_ALIGN_2:
27020 case OPC_ALIGN_3:
27021 gen_align(ctx, 32, rd, rs, rt, sa & 3);
27022 break;
27023 case OPC_BITSWAP:
27024 gen_bitswap(ctx, op2, rd, rt);
27025 break;
27026 }
27027 }
27028 break;
27029 #if defined(TARGET_MIPS64)
27030 case R6_OPC_SCD:
27031 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
27032 break;
27033 case R6_OPC_LLD:
27034 gen_ld(ctx, op1, rt, rs, imm);
27035 break;
27036 case OPC_DBSHFL:
27037 check_mips_64(ctx);
27038 {
27039 if (rd == 0) {
27040 /* Treat as NOP. */
27041 break;
27042 }
27043 op2 = MASK_DBSHFL(ctx->opcode);
27044 switch (op2) {
27045 case OPC_DALIGN:
27046 case OPC_DALIGN_1:
27047 case OPC_DALIGN_2:
27048 case OPC_DALIGN_3:
27049 case OPC_DALIGN_4:
27050 case OPC_DALIGN_5:
27051 case OPC_DALIGN_6:
27052 case OPC_DALIGN_7:
27053 gen_align(ctx, 64, rd, rs, rt, sa & 7);
27054 break;
27055 case OPC_DBITSWAP:
27056 gen_bitswap(ctx, op2, rd, rt);
27057 break;
27058 }
27059
27060 }
27061 break;
27062 #endif
27063 default: /* Invalid */
27064 MIPS_INVAL("special3_r6");
27065 generate_exception_end(ctx, EXCP_RI);
27066 break;
27067 }
27068 }
27069
27070 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
27071 {
27072 int rs, rt, rd;
27073 uint32_t op1, op2;
27074
27075 rs = (ctx->opcode >> 21) & 0x1f;
27076 rt = (ctx->opcode >> 16) & 0x1f;
27077 rd = (ctx->opcode >> 11) & 0x1f;
27078
27079 op1 = MASK_SPECIAL3(ctx->opcode);
27080 switch (op1) {
27081 case OPC_DIV_G_2E:
27082 case OPC_DIVU_G_2E:
27083 case OPC_MOD_G_2E:
27084 case OPC_MODU_G_2E:
27085 case OPC_MULT_G_2E:
27086 case OPC_MULTU_G_2E:
27087 /*
27088 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27089 * the same mask and op1.
27090 */
27091 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
27092 op2 = MASK_ADDUH_QB(ctx->opcode);
27093 switch (op2) {
27094 case OPC_ADDUH_QB:
27095 case OPC_ADDUH_R_QB:
27096 case OPC_ADDQH_PH:
27097 case OPC_ADDQH_R_PH:
27098 case OPC_ADDQH_W:
27099 case OPC_ADDQH_R_W:
27100 case OPC_SUBUH_QB:
27101 case OPC_SUBUH_R_QB:
27102 case OPC_SUBQH_PH:
27103 case OPC_SUBQH_R_PH:
27104 case OPC_SUBQH_W:
27105 case OPC_SUBQH_R_W:
27106 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27107 break;
27108 case OPC_MUL_PH:
27109 case OPC_MUL_S_PH:
27110 case OPC_MULQ_S_W:
27111 case OPC_MULQ_RS_W:
27112 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27113 break;
27114 default:
27115 MIPS_INVAL("MASK ADDUH.QB");
27116 generate_exception_end(ctx, EXCP_RI);
27117 break;
27118 }
27119 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
27120 gen_loongson_integer(ctx, op1, rd, rs, rt);
27121 } else {
27122 generate_exception_end(ctx, EXCP_RI);
27123 }
27124 break;
27125 case OPC_LX_DSP:
27126 op2 = MASK_LX(ctx->opcode);
27127 switch (op2) {
27128 #if defined(TARGET_MIPS64)
27129 case OPC_LDX:
27130 #endif
27131 case OPC_LBUX:
27132 case OPC_LHX:
27133 case OPC_LWX:
27134 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
27135 break;
27136 default: /* Invalid */
27137 MIPS_INVAL("MASK LX");
27138 generate_exception_end(ctx, EXCP_RI);
27139 break;
27140 }
27141 break;
27142 case OPC_ABSQ_S_PH_DSP:
27143 op2 = MASK_ABSQ_S_PH(ctx->opcode);
27144 switch (op2) {
27145 case OPC_ABSQ_S_QB:
27146 case OPC_ABSQ_S_PH:
27147 case OPC_ABSQ_S_W:
27148 case OPC_PRECEQ_W_PHL:
27149 case OPC_PRECEQ_W_PHR:
27150 case OPC_PRECEQU_PH_QBL:
27151 case OPC_PRECEQU_PH_QBR:
27152 case OPC_PRECEQU_PH_QBLA:
27153 case OPC_PRECEQU_PH_QBRA:
27154 case OPC_PRECEU_PH_QBL:
27155 case OPC_PRECEU_PH_QBR:
27156 case OPC_PRECEU_PH_QBLA:
27157 case OPC_PRECEU_PH_QBRA:
27158 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27159 break;
27160 case OPC_BITREV:
27161 case OPC_REPL_QB:
27162 case OPC_REPLV_QB:
27163 case OPC_REPL_PH:
27164 case OPC_REPLV_PH:
27165 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27166 break;
27167 default:
27168 MIPS_INVAL("MASK ABSQ_S.PH");
27169 generate_exception_end(ctx, EXCP_RI);
27170 break;
27171 }
27172 break;
27173 case OPC_ADDU_QB_DSP:
27174 op2 = MASK_ADDU_QB(ctx->opcode);
27175 switch (op2) {
27176 case OPC_ADDQ_PH:
27177 case OPC_ADDQ_S_PH:
27178 case OPC_ADDQ_S_W:
27179 case OPC_ADDU_QB:
27180 case OPC_ADDU_S_QB:
27181 case OPC_ADDU_PH:
27182 case OPC_ADDU_S_PH:
27183 case OPC_SUBQ_PH:
27184 case OPC_SUBQ_S_PH:
27185 case OPC_SUBQ_S_W:
27186 case OPC_SUBU_QB:
27187 case OPC_SUBU_S_QB:
27188 case OPC_SUBU_PH:
27189 case OPC_SUBU_S_PH:
27190 case OPC_ADDSC:
27191 case OPC_ADDWC:
27192 case OPC_MODSUB:
27193 case OPC_RADDU_W_QB:
27194 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27195 break;
27196 case OPC_MULEU_S_PH_QBL:
27197 case OPC_MULEU_S_PH_QBR:
27198 case OPC_MULQ_RS_PH:
27199 case OPC_MULEQ_S_W_PHL:
27200 case OPC_MULEQ_S_W_PHR:
27201 case OPC_MULQ_S_PH:
27202 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27203 break;
27204 default: /* Invalid */
27205 MIPS_INVAL("MASK ADDU.QB");
27206 generate_exception_end(ctx, EXCP_RI);
27207 break;
27208
27209 }
27210 break;
27211 case OPC_CMPU_EQ_QB_DSP:
27212 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
27213 switch (op2) {
27214 case OPC_PRECR_SRA_PH_W:
27215 case OPC_PRECR_SRA_R_PH_W:
27216 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27217 break;
27218 case OPC_PRECR_QB_PH:
27219 case OPC_PRECRQ_QB_PH:
27220 case OPC_PRECRQ_PH_W:
27221 case OPC_PRECRQ_RS_PH_W:
27222 case OPC_PRECRQU_S_QB_PH:
27223 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27224 break;
27225 case OPC_CMPU_EQ_QB:
27226 case OPC_CMPU_LT_QB:
27227 case OPC_CMPU_LE_QB:
27228 case OPC_CMP_EQ_PH:
27229 case OPC_CMP_LT_PH:
27230 case OPC_CMP_LE_PH:
27231 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27232 break;
27233 case OPC_CMPGU_EQ_QB:
27234 case OPC_CMPGU_LT_QB:
27235 case OPC_CMPGU_LE_QB:
27236 case OPC_CMPGDU_EQ_QB:
27237 case OPC_CMPGDU_LT_QB:
27238 case OPC_CMPGDU_LE_QB:
27239 case OPC_PICK_QB:
27240 case OPC_PICK_PH:
27241 case OPC_PACKRL_PH:
27242 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27243 break;
27244 default: /* Invalid */
27245 MIPS_INVAL("MASK CMPU.EQ.QB");
27246 generate_exception_end(ctx, EXCP_RI);
27247 break;
27248 }
27249 break;
27250 case OPC_SHLL_QB_DSP:
27251 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27252 break;
27253 case OPC_DPA_W_PH_DSP:
27254 op2 = MASK_DPA_W_PH(ctx->opcode);
27255 switch (op2) {
27256 case OPC_DPAU_H_QBL:
27257 case OPC_DPAU_H_QBR:
27258 case OPC_DPSU_H_QBL:
27259 case OPC_DPSU_H_QBR:
27260 case OPC_DPA_W_PH:
27261 case OPC_DPAX_W_PH:
27262 case OPC_DPAQ_S_W_PH:
27263 case OPC_DPAQX_S_W_PH:
27264 case OPC_DPAQX_SA_W_PH:
27265 case OPC_DPS_W_PH:
27266 case OPC_DPSX_W_PH:
27267 case OPC_DPSQ_S_W_PH:
27268 case OPC_DPSQX_S_W_PH:
27269 case OPC_DPSQX_SA_W_PH:
27270 case OPC_MULSAQ_S_W_PH:
27271 case OPC_DPAQ_SA_L_W:
27272 case OPC_DPSQ_SA_L_W:
27273 case OPC_MAQ_S_W_PHL:
27274 case OPC_MAQ_S_W_PHR:
27275 case OPC_MAQ_SA_W_PHL:
27276 case OPC_MAQ_SA_W_PHR:
27277 case OPC_MULSA_W_PH:
27278 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27279 break;
27280 default: /* Invalid */
27281 MIPS_INVAL("MASK DPAW.PH");
27282 generate_exception_end(ctx, EXCP_RI);
27283 break;
27284 }
27285 break;
27286 case OPC_INSV_DSP:
27287 op2 = MASK_INSV(ctx->opcode);
27288 switch (op2) {
27289 case OPC_INSV:
27290 check_dsp(ctx);
27291 {
27292 TCGv t0, t1;
27293
27294 if (rt == 0) {
27295 break;
27296 }
27297
27298 t0 = tcg_temp_new();
27299 t1 = tcg_temp_new();
27300
27301 gen_load_gpr(t0, rt);
27302 gen_load_gpr(t1, rs);
27303
27304 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
27305
27306 tcg_temp_free(t0);
27307 tcg_temp_free(t1);
27308 break;
27309 }
27310 default: /* Invalid */
27311 MIPS_INVAL("MASK INSV");
27312 generate_exception_end(ctx, EXCP_RI);
27313 break;
27314 }
27315 break;
27316 case OPC_APPEND_DSP:
27317 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27318 break;
27319 case OPC_EXTR_W_DSP:
27320 op2 = MASK_EXTR_W(ctx->opcode);
27321 switch (op2) {
27322 case OPC_EXTR_W:
27323 case OPC_EXTR_R_W:
27324 case OPC_EXTR_RS_W:
27325 case OPC_EXTR_S_H:
27326 case OPC_EXTRV_S_H:
27327 case OPC_EXTRV_W:
27328 case OPC_EXTRV_R_W:
27329 case OPC_EXTRV_RS_W:
27330 case OPC_EXTP:
27331 case OPC_EXTPV:
27332 case OPC_EXTPDP:
27333 case OPC_EXTPDPV:
27334 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27335 break;
27336 case OPC_RDDSP:
27337 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27338 break;
27339 case OPC_SHILO:
27340 case OPC_SHILOV:
27341 case OPC_MTHLIP:
27342 case OPC_WRDSP:
27343 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27344 break;
27345 default: /* Invalid */
27346 MIPS_INVAL("MASK EXTR.W");
27347 generate_exception_end(ctx, EXCP_RI);
27348 break;
27349 }
27350 break;
27351 #if defined(TARGET_MIPS64)
27352 case OPC_DDIV_G_2E:
27353 case OPC_DDIVU_G_2E:
27354 case OPC_DMULT_G_2E:
27355 case OPC_DMULTU_G_2E:
27356 case OPC_DMOD_G_2E:
27357 case OPC_DMODU_G_2E:
27358 check_insn(ctx, INSN_LOONGSON2E);
27359 gen_loongson_integer(ctx, op1, rd, rs, rt);
27360 break;
27361 case OPC_ABSQ_S_QH_DSP:
27362 op2 = MASK_ABSQ_S_QH(ctx->opcode);
27363 switch (op2) {
27364 case OPC_PRECEQ_L_PWL:
27365 case OPC_PRECEQ_L_PWR:
27366 case OPC_PRECEQ_PW_QHL:
27367 case OPC_PRECEQ_PW_QHR:
27368 case OPC_PRECEQ_PW_QHLA:
27369 case OPC_PRECEQ_PW_QHRA:
27370 case OPC_PRECEQU_QH_OBL:
27371 case OPC_PRECEQU_QH_OBR:
27372 case OPC_PRECEQU_QH_OBLA:
27373 case OPC_PRECEQU_QH_OBRA:
27374 case OPC_PRECEU_QH_OBL:
27375 case OPC_PRECEU_QH_OBR:
27376 case OPC_PRECEU_QH_OBLA:
27377 case OPC_PRECEU_QH_OBRA:
27378 case OPC_ABSQ_S_OB:
27379 case OPC_ABSQ_S_PW:
27380 case OPC_ABSQ_S_QH:
27381 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27382 break;
27383 case OPC_REPL_OB:
27384 case OPC_REPL_PW:
27385 case OPC_REPL_QH:
27386 case OPC_REPLV_OB:
27387 case OPC_REPLV_PW:
27388 case OPC_REPLV_QH:
27389 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27390 break;
27391 default: /* Invalid */
27392 MIPS_INVAL("MASK ABSQ_S.QH");
27393 generate_exception_end(ctx, EXCP_RI);
27394 break;
27395 }
27396 break;
27397 case OPC_ADDU_OB_DSP:
27398 op2 = MASK_ADDU_OB(ctx->opcode);
27399 switch (op2) {
27400 case OPC_RADDU_L_OB:
27401 case OPC_SUBQ_PW:
27402 case OPC_SUBQ_S_PW:
27403 case OPC_SUBQ_QH:
27404 case OPC_SUBQ_S_QH:
27405 case OPC_SUBU_OB:
27406 case OPC_SUBU_S_OB:
27407 case OPC_SUBU_QH:
27408 case OPC_SUBU_S_QH:
27409 case OPC_SUBUH_OB:
27410 case OPC_SUBUH_R_OB:
27411 case OPC_ADDQ_PW:
27412 case OPC_ADDQ_S_PW:
27413 case OPC_ADDQ_QH:
27414 case OPC_ADDQ_S_QH:
27415 case OPC_ADDU_OB:
27416 case OPC_ADDU_S_OB:
27417 case OPC_ADDU_QH:
27418 case OPC_ADDU_S_QH:
27419 case OPC_ADDUH_OB:
27420 case OPC_ADDUH_R_OB:
27421 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27422 break;
27423 case OPC_MULEQ_S_PW_QHL:
27424 case OPC_MULEQ_S_PW_QHR:
27425 case OPC_MULEU_S_QH_OBL:
27426 case OPC_MULEU_S_QH_OBR:
27427 case OPC_MULQ_RS_QH:
27428 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27429 break;
27430 default: /* Invalid */
27431 MIPS_INVAL("MASK ADDU.OB");
27432 generate_exception_end(ctx, EXCP_RI);
27433 break;
27434 }
27435 break;
27436 case OPC_CMPU_EQ_OB_DSP:
27437 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27438 switch (op2) {
27439 case OPC_PRECR_SRA_QH_PW:
27440 case OPC_PRECR_SRA_R_QH_PW:
27441 /* Return value is rt. */
27442 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27443 break;
27444 case OPC_PRECR_OB_QH:
27445 case OPC_PRECRQ_OB_QH:
27446 case OPC_PRECRQ_PW_L:
27447 case OPC_PRECRQ_QH_PW:
27448 case OPC_PRECRQ_RS_QH_PW:
27449 case OPC_PRECRQU_S_OB_QH:
27450 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27451 break;
27452 case OPC_CMPU_EQ_OB:
27453 case OPC_CMPU_LT_OB:
27454 case OPC_CMPU_LE_OB:
27455 case OPC_CMP_EQ_QH:
27456 case OPC_CMP_LT_QH:
27457 case OPC_CMP_LE_QH:
27458 case OPC_CMP_EQ_PW:
27459 case OPC_CMP_LT_PW:
27460 case OPC_CMP_LE_PW:
27461 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27462 break;
27463 case OPC_CMPGDU_EQ_OB:
27464 case OPC_CMPGDU_LT_OB:
27465 case OPC_CMPGDU_LE_OB:
27466 case OPC_CMPGU_EQ_OB:
27467 case OPC_CMPGU_LT_OB:
27468 case OPC_CMPGU_LE_OB:
27469 case OPC_PACKRL_PW:
27470 case OPC_PICK_OB:
27471 case OPC_PICK_PW:
27472 case OPC_PICK_QH:
27473 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27474 break;
27475 default: /* Invalid */
27476 MIPS_INVAL("MASK CMPU_EQ.OB");
27477 generate_exception_end(ctx, EXCP_RI);
27478 break;
27479 }
27480 break;
27481 case OPC_DAPPEND_DSP:
27482 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27483 break;
27484 case OPC_DEXTR_W_DSP:
27485 op2 = MASK_DEXTR_W(ctx->opcode);
27486 switch (op2) {
27487 case OPC_DEXTP:
27488 case OPC_DEXTPDP:
27489 case OPC_DEXTPDPV:
27490 case OPC_DEXTPV:
27491 case OPC_DEXTR_L:
27492 case OPC_DEXTR_R_L:
27493 case OPC_DEXTR_RS_L:
27494 case OPC_DEXTR_W:
27495 case OPC_DEXTR_R_W:
27496 case OPC_DEXTR_RS_W:
27497 case OPC_DEXTR_S_H:
27498 case OPC_DEXTRV_L:
27499 case OPC_DEXTRV_R_L:
27500 case OPC_DEXTRV_RS_L:
27501 case OPC_DEXTRV_S_H:
27502 case OPC_DEXTRV_W:
27503 case OPC_DEXTRV_R_W:
27504 case OPC_DEXTRV_RS_W:
27505 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27506 break;
27507 case OPC_DMTHLIP:
27508 case OPC_DSHILO:
27509 case OPC_DSHILOV:
27510 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27511 break;
27512 default: /* Invalid */
27513 MIPS_INVAL("MASK EXTR.W");
27514 generate_exception_end(ctx, EXCP_RI);
27515 break;
27516 }
27517 break;
27518 case OPC_DPAQ_W_QH_DSP:
27519 op2 = MASK_DPAQ_W_QH(ctx->opcode);
27520 switch (op2) {
27521 case OPC_DPAU_H_OBL:
27522 case OPC_DPAU_H_OBR:
27523 case OPC_DPSU_H_OBL:
27524 case OPC_DPSU_H_OBR:
27525 case OPC_DPA_W_QH:
27526 case OPC_DPAQ_S_W_QH:
27527 case OPC_DPS_W_QH:
27528 case OPC_DPSQ_S_W_QH:
27529 case OPC_MULSAQ_S_W_QH:
27530 case OPC_DPAQ_SA_L_PW:
27531 case OPC_DPSQ_SA_L_PW:
27532 case OPC_MULSAQ_S_L_PW:
27533 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27534 break;
27535 case OPC_MAQ_S_W_QHLL:
27536 case OPC_MAQ_S_W_QHLR:
27537 case OPC_MAQ_S_W_QHRL:
27538 case OPC_MAQ_S_W_QHRR:
27539 case OPC_MAQ_SA_W_QHLL:
27540 case OPC_MAQ_SA_W_QHLR:
27541 case OPC_MAQ_SA_W_QHRL:
27542 case OPC_MAQ_SA_W_QHRR:
27543 case OPC_MAQ_S_L_PWL:
27544 case OPC_MAQ_S_L_PWR:
27545 case OPC_DMADD:
27546 case OPC_DMADDU:
27547 case OPC_DMSUB:
27548 case OPC_DMSUBU:
27549 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27550 break;
27551 default: /* Invalid */
27552 MIPS_INVAL("MASK DPAQ.W.QH");
27553 generate_exception_end(ctx, EXCP_RI);
27554 break;
27555 }
27556 break;
27557 case OPC_DINSV_DSP:
27558 op2 = MASK_INSV(ctx->opcode);
27559 switch (op2) {
27560 case OPC_DINSV:
27561 {
27562 TCGv t0, t1;
27563
27564 if (rt == 0) {
27565 break;
27566 }
27567 check_dsp(ctx);
27568
27569 t0 = tcg_temp_new();
27570 t1 = tcg_temp_new();
27571
27572 gen_load_gpr(t0, rt);
27573 gen_load_gpr(t1, rs);
27574
27575 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27576
27577 tcg_temp_free(t0);
27578 tcg_temp_free(t1);
27579 break;
27580 }
27581 default: /* Invalid */
27582 MIPS_INVAL("MASK DINSV");
27583 generate_exception_end(ctx, EXCP_RI);
27584 break;
27585 }
27586 break;
27587 case OPC_SHLL_OB_DSP:
27588 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27589 break;
27590 #endif
27591 default: /* Invalid */
27592 MIPS_INVAL("special3_legacy");
27593 generate_exception_end(ctx, EXCP_RI);
27594 break;
27595 }
27596 }
27597
27598
27599 #if defined(TARGET_MIPS64)
27600
27601 static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27602 {
27603 uint32_t opc = MASK_MMI0(ctx->opcode);
27604
27605 switch (opc) {
27606 case MMI_OPC_0_PADDW: /* TODO: MMI_OPC_0_PADDW */
27607 case MMI_OPC_0_PSUBW: /* TODO: MMI_OPC_0_PSUBW */
27608 case MMI_OPC_0_PCGTW: /* TODO: MMI_OPC_0_PCGTW */
27609 case MMI_OPC_0_PMAXW: /* TODO: MMI_OPC_0_PMAXW */
27610 case MMI_OPC_0_PADDH: /* TODO: MMI_OPC_0_PADDH */
27611 case MMI_OPC_0_PSUBH: /* TODO: MMI_OPC_0_PSUBH */
27612 case MMI_OPC_0_PCGTH: /* TODO: MMI_OPC_0_PCGTH */
27613 case MMI_OPC_0_PMAXH: /* TODO: MMI_OPC_0_PMAXH */
27614 case MMI_OPC_0_PADDB: /* TODO: MMI_OPC_0_PADDB */
27615 case MMI_OPC_0_PSUBB: /* TODO: MMI_OPC_0_PSUBB */
27616 case MMI_OPC_0_PCGTB: /* TODO: MMI_OPC_0_PCGTB */
27617 case MMI_OPC_0_PADDSW: /* TODO: MMI_OPC_0_PADDSW */
27618 case MMI_OPC_0_PSUBSW: /* TODO: MMI_OPC_0_PSUBSW */
27619 case MMI_OPC_0_PEXTLW: /* TODO: MMI_OPC_0_PEXTLW */
27620 case MMI_OPC_0_PPACW: /* TODO: MMI_OPC_0_PPACW */
27621 case MMI_OPC_0_PADDSH: /* TODO: MMI_OPC_0_PADDSH */
27622 case MMI_OPC_0_PSUBSH: /* TODO: MMI_OPC_0_PSUBSH */
27623 case MMI_OPC_0_PEXTLH: /* TODO: MMI_OPC_0_PEXTLH */
27624 case MMI_OPC_0_PPACH: /* TODO: MMI_OPC_0_PPACH */
27625 case MMI_OPC_0_PADDSB: /* TODO: MMI_OPC_0_PADDSB */
27626 case MMI_OPC_0_PSUBSB: /* TODO: MMI_OPC_0_PSUBSB */
27627 case MMI_OPC_0_PEXTLB: /* TODO: MMI_OPC_0_PEXTLB */
27628 case MMI_OPC_0_PPACB: /* TODO: MMI_OPC_0_PPACB */
27629 case MMI_OPC_0_PEXT5: /* TODO: MMI_OPC_0_PEXT5 */
27630 case MMI_OPC_0_PPAC5: /* TODO: MMI_OPC_0_PPAC5 */
27631 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27632 break;
27633 default:
27634 MIPS_INVAL("TX79 MMI class MMI0");
27635 generate_exception_end(ctx, EXCP_RI);
27636 break;
27637 }
27638 }
27639
27640 static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27641 {
27642 uint32_t opc = MASK_MMI1(ctx->opcode);
27643
27644 switch (opc) {
27645 case MMI_OPC_1_PABSW: /* TODO: MMI_OPC_1_PABSW */
27646 case MMI_OPC_1_PCEQW: /* TODO: MMI_OPC_1_PCEQW */
27647 case MMI_OPC_1_PMINW: /* TODO: MMI_OPC_1_PMINW */
27648 case MMI_OPC_1_PADSBH: /* TODO: MMI_OPC_1_PADSBH */
27649 case MMI_OPC_1_PABSH: /* TODO: MMI_OPC_1_PABSH */
27650 case MMI_OPC_1_PCEQH: /* TODO: MMI_OPC_1_PCEQH */
27651 case MMI_OPC_1_PMINH: /* TODO: MMI_OPC_1_PMINH */
27652 case MMI_OPC_1_PCEQB: /* TODO: MMI_OPC_1_PCEQB */
27653 case MMI_OPC_1_PADDUW: /* TODO: MMI_OPC_1_PADDUW */
27654 case MMI_OPC_1_PSUBUW: /* TODO: MMI_OPC_1_PSUBUW */
27655 case MMI_OPC_1_PEXTUW: /* TODO: MMI_OPC_1_PEXTUW */
27656 case MMI_OPC_1_PADDUH: /* TODO: MMI_OPC_1_PADDUH */
27657 case MMI_OPC_1_PSUBUH: /* TODO: MMI_OPC_1_PSUBUH */
27658 case MMI_OPC_1_PEXTUH: /* TODO: MMI_OPC_1_PEXTUH */
27659 case MMI_OPC_1_PADDUB: /* TODO: MMI_OPC_1_PADDUB */
27660 case MMI_OPC_1_PSUBUB: /* TODO: MMI_OPC_1_PSUBUB */
27661 case MMI_OPC_1_PEXTUB: /* TODO: MMI_OPC_1_PEXTUB */
27662 case MMI_OPC_1_QFSRV: /* TODO: MMI_OPC_1_QFSRV */
27663 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27664 break;
27665 default:
27666 MIPS_INVAL("TX79 MMI class MMI1");
27667 generate_exception_end(ctx, EXCP_RI);
27668 break;
27669 }
27670 }
27671
27672 static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27673 {
27674 uint32_t opc = MASK_MMI2(ctx->opcode);
27675
27676 switch (opc) {
27677 case MMI_OPC_2_PMADDW: /* TODO: MMI_OPC_2_PMADDW */
27678 case MMI_OPC_2_PSLLVW: /* TODO: MMI_OPC_2_PSLLVW */
27679 case MMI_OPC_2_PSRLVW: /* TODO: MMI_OPC_2_PSRLVW */
27680 case MMI_OPC_2_PMSUBW: /* TODO: MMI_OPC_2_PMSUBW */
27681 case MMI_OPC_2_PMFHI: /* TODO: MMI_OPC_2_PMFHI */
27682 case MMI_OPC_2_PMFLO: /* TODO: MMI_OPC_2_PMFLO */
27683 case MMI_OPC_2_PINTH: /* TODO: MMI_OPC_2_PINTH */
27684 case MMI_OPC_2_PMULTW: /* TODO: MMI_OPC_2_PMULTW */
27685 case MMI_OPC_2_PDIVW: /* TODO: MMI_OPC_2_PDIVW */
27686 case MMI_OPC_2_PMADDH: /* TODO: MMI_OPC_2_PMADDH */
27687 case MMI_OPC_2_PHMADH: /* TODO: MMI_OPC_2_PHMADH */
27688 case MMI_OPC_2_PAND: /* TODO: MMI_OPC_2_PAND */
27689 case MMI_OPC_2_PXOR: /* TODO: MMI_OPC_2_PXOR */
27690 case MMI_OPC_2_PMSUBH: /* TODO: MMI_OPC_2_PMSUBH */
27691 case MMI_OPC_2_PHMSBH: /* TODO: MMI_OPC_2_PHMSBH */
27692 case MMI_OPC_2_PEXEH: /* TODO: MMI_OPC_2_PEXEH */
27693 case MMI_OPC_2_PREVH: /* TODO: MMI_OPC_2_PREVH */
27694 case MMI_OPC_2_PMULTH: /* TODO: MMI_OPC_2_PMULTH */
27695 case MMI_OPC_2_PDIVBW: /* TODO: MMI_OPC_2_PDIVBW */
27696 case MMI_OPC_2_PEXEW: /* TODO: MMI_OPC_2_PEXEW */
27697 case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */
27698 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27699 break;
27700 case MMI_OPC_2_PCPYLD:
27701 gen_mmi_pcpyld(ctx);
27702 break;
27703 default:
27704 MIPS_INVAL("TX79 MMI class MMI2");
27705 generate_exception_end(ctx, EXCP_RI);
27706 break;
27707 }
27708 }
27709
27710 static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27711 {
27712 uint32_t opc = MASK_MMI3(ctx->opcode);
27713
27714 switch (opc) {
27715 case MMI_OPC_3_PMADDUW: /* TODO: MMI_OPC_3_PMADDUW */
27716 case MMI_OPC_3_PSRAVW: /* TODO: MMI_OPC_3_PSRAVW */
27717 case MMI_OPC_3_PMTHI: /* TODO: MMI_OPC_3_PMTHI */
27718 case MMI_OPC_3_PMTLO: /* TODO: MMI_OPC_3_PMTLO */
27719 case MMI_OPC_3_PINTEH: /* TODO: MMI_OPC_3_PINTEH */
27720 case MMI_OPC_3_PMULTUW: /* TODO: MMI_OPC_3_PMULTUW */
27721 case MMI_OPC_3_PDIVUW: /* TODO: MMI_OPC_3_PDIVUW */
27722 case MMI_OPC_3_POR: /* TODO: MMI_OPC_3_POR */
27723 case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */
27724 case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */
27725 case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */
27726 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27727 break;
27728 case MMI_OPC_3_PCPYH:
27729 gen_mmi_pcpyh(ctx);
27730 break;
27731 case MMI_OPC_3_PCPYUD:
27732 gen_mmi_pcpyud(ctx);
27733 break;
27734 default:
27735 MIPS_INVAL("TX79 MMI class MMI3");
27736 generate_exception_end(ctx, EXCP_RI);
27737 break;
27738 }
27739 }
27740
27741 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27742 {
27743 uint32_t opc = MASK_MMI(ctx->opcode);
27744 int rs = extract32(ctx->opcode, 21, 5);
27745 int rt = extract32(ctx->opcode, 16, 5);
27746 int rd = extract32(ctx->opcode, 11, 5);
27747
27748 switch (opc) {
27749 case MMI_OPC_CLASS_MMI0:
27750 decode_mmi0(env, ctx);
27751 break;
27752 case MMI_OPC_CLASS_MMI1:
27753 decode_mmi1(env, ctx);
27754 break;
27755 case MMI_OPC_CLASS_MMI2:
27756 decode_mmi2(env, ctx);
27757 break;
27758 case MMI_OPC_CLASS_MMI3:
27759 decode_mmi3(env, ctx);
27760 break;
27761 case MMI_OPC_MULT1:
27762 case MMI_OPC_MULTU1:
27763 case MMI_OPC_MADD:
27764 case MMI_OPC_MADDU:
27765 case MMI_OPC_MADD1:
27766 case MMI_OPC_MADDU1:
27767 gen_mul_txx9(ctx, opc, rd, rs, rt);
27768 break;
27769 case MMI_OPC_DIV1:
27770 case MMI_OPC_DIVU1:
27771 gen_div1_tx79(ctx, opc, rs, rt);
27772 break;
27773 case MMI_OPC_MTLO1:
27774 case MMI_OPC_MTHI1:
27775 gen_HILO1_tx79(ctx, opc, rs);
27776 break;
27777 case MMI_OPC_MFLO1:
27778 case MMI_OPC_MFHI1:
27779 gen_HILO1_tx79(ctx, opc, rd);
27780 break;
27781 case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */
27782 case MMI_OPC_PMFHL: /* TODO: MMI_OPC_PMFHL */
27783 case MMI_OPC_PMTHL: /* TODO: MMI_OPC_PMTHL */
27784 case MMI_OPC_PSLLH: /* TODO: MMI_OPC_PSLLH */
27785 case MMI_OPC_PSRLH: /* TODO: MMI_OPC_PSRLH */
27786 case MMI_OPC_PSRAH: /* TODO: MMI_OPC_PSRAH */
27787 case MMI_OPC_PSLLW: /* TODO: MMI_OPC_PSLLW */
27788 case MMI_OPC_PSRLW: /* TODO: MMI_OPC_PSRLW */
27789 case MMI_OPC_PSRAW: /* TODO: MMI_OPC_PSRAW */
27790 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI */
27791 break;
27792 default:
27793 MIPS_INVAL("TX79 MMI class");
27794 generate_exception_end(ctx, EXCP_RI);
27795 break;
27796 }
27797 }
27798
27799 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27800 {
27801 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_LQ */
27802 }
27803
27804 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27805 {
27806 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_SQ */
27807 }
27808
27809 /*
27810 * The TX79-specific instruction Store Quadword
27811 *
27812 * +--------+-------+-------+------------------------+
27813 * | 011111 | base | rt | offset | SQ
27814 * +--------+-------+-------+------------------------+
27815 * 6 5 5 16
27816 *
27817 * has the same opcode as the Read Hardware Register instruction
27818 *
27819 * +--------+-------+-------+-------+-------+--------+
27820 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
27821 * +--------+-------+-------+-------+-------+--------+
27822 * 6 5 5 5 5 6
27823 *
27824 * that is required, trapped and emulated by the Linux kernel. However, all
27825 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27826 * offset is odd. Therefore all valid SQ instructions can execute normally.
27827 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27828 * between SQ and RDHWR, as the Linux kernel does.
27829 */
27830 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27831 {
27832 int base = extract32(ctx->opcode, 21, 5);
27833 int rt = extract32(ctx->opcode, 16, 5);
27834 int offset = extract32(ctx->opcode, 0, 16);
27835
27836 #ifdef CONFIG_USER_ONLY
27837 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27838 uint32_t op2 = extract32(ctx->opcode, 6, 5);
27839
27840 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27841 int rd = extract32(ctx->opcode, 11, 5);
27842
27843 gen_rdhwr(ctx, rt, rd, 0);
27844 return;
27845 }
27846 #endif
27847
27848 gen_mmi_sq(ctx, base, rt, offset);
27849 }
27850
27851 #endif
27852
27853 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27854 {
27855 int rs, rt, rd, sa;
27856 uint32_t op1, op2;
27857 int16_t imm;
27858
27859 rs = (ctx->opcode >> 21) & 0x1f;
27860 rt = (ctx->opcode >> 16) & 0x1f;
27861 rd = (ctx->opcode >> 11) & 0x1f;
27862 sa = (ctx->opcode >> 6) & 0x1f;
27863 imm = sextract32(ctx->opcode, 7, 9);
27864
27865 op1 = MASK_SPECIAL3(ctx->opcode);
27866
27867 /*
27868 * EVA loads and stores overlap Loongson 2E instructions decoded by
27869 * decode_opc_special3_legacy(), so be careful to allow their decoding when
27870 * EVA is absent.
27871 */
27872 if (ctx->eva) {
27873 switch (op1) {
27874 case OPC_LWLE:
27875 case OPC_LWRE:
27876 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27877 /* fall through */
27878 case OPC_LBUE:
27879 case OPC_LHUE:
27880 case OPC_LBE:
27881 case OPC_LHE:
27882 case OPC_LLE:
27883 case OPC_LWE:
27884 check_cp0_enabled(ctx);
27885 gen_ld(ctx, op1, rt, rs, imm);
27886 return;
27887 case OPC_SWLE:
27888 case OPC_SWRE:
27889 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27890 /* fall through */
27891 case OPC_SBE:
27892 case OPC_SHE:
27893 case OPC_SWE:
27894 check_cp0_enabled(ctx);
27895 gen_st(ctx, op1, rt, rs, imm);
27896 return;
27897 case OPC_SCE:
27898 check_cp0_enabled(ctx);
27899 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
27900 return;
27901 case OPC_CACHEE:
27902 check_cp0_enabled(ctx);
27903 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27904 gen_cache_operation(ctx, rt, rs, imm);
27905 }
27906 /* Treat as NOP. */
27907 return;
27908 case OPC_PREFE:
27909 check_cp0_enabled(ctx);
27910 /* Treat as NOP. */
27911 return;
27912 }
27913 }
27914
27915 switch (op1) {
27916 case OPC_EXT:
27917 case OPC_INS:
27918 check_insn(ctx, ISA_MIPS32R2);
27919 gen_bitops(ctx, op1, rt, rs, sa, rd);
27920 break;
27921 case OPC_BSHFL:
27922 op2 = MASK_BSHFL(ctx->opcode);
27923 switch (op2) {
27924 case OPC_ALIGN:
27925 case OPC_ALIGN_1:
27926 case OPC_ALIGN_2:
27927 case OPC_ALIGN_3:
27928 case OPC_BITSWAP:
27929 check_insn(ctx, ISA_MIPS32R6);
27930 decode_opc_special3_r6(env, ctx);
27931 break;
27932 default:
27933 check_insn(ctx, ISA_MIPS32R2);
27934 gen_bshfl(ctx, op2, rt, rd);
27935 break;
27936 }
27937 break;
27938 #if defined(TARGET_MIPS64)
27939 case OPC_DEXTM:
27940 case OPC_DEXTU:
27941 case OPC_DEXT:
27942 case OPC_DINSM:
27943 case OPC_DINSU:
27944 case OPC_DINS:
27945 check_insn(ctx, ISA_MIPS64R2);
27946 check_mips_64(ctx);
27947 gen_bitops(ctx, op1, rt, rs, sa, rd);
27948 break;
27949 case OPC_DBSHFL:
27950 op2 = MASK_DBSHFL(ctx->opcode);
27951 switch (op2) {
27952 case OPC_DALIGN:
27953 case OPC_DALIGN_1:
27954 case OPC_DALIGN_2:
27955 case OPC_DALIGN_3:
27956 case OPC_DALIGN_4:
27957 case OPC_DALIGN_5:
27958 case OPC_DALIGN_6:
27959 case OPC_DALIGN_7:
27960 case OPC_DBITSWAP:
27961 check_insn(ctx, ISA_MIPS32R6);
27962 decode_opc_special3_r6(env, ctx);
27963 break;
27964 default:
27965 check_insn(ctx, ISA_MIPS64R2);
27966 check_mips_64(ctx);
27967 op2 = MASK_DBSHFL(ctx->opcode);
27968 gen_bshfl(ctx, op2, rt, rd);
27969 break;
27970 }
27971 break;
27972 #endif
27973 case OPC_RDHWR:
27974 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27975 break;
27976 case OPC_FORK:
27977 check_mt(ctx);
27978 {
27979 TCGv t0 = tcg_temp_new();
27980 TCGv t1 = tcg_temp_new();
27981
27982 gen_load_gpr(t0, rt);
27983 gen_load_gpr(t1, rs);
27984 gen_helper_fork(t0, t1);
27985 tcg_temp_free(t0);
27986 tcg_temp_free(t1);
27987 }
27988 break;
27989 case OPC_YIELD:
27990 check_mt(ctx);
27991 {
27992 TCGv t0 = tcg_temp_new();
27993
27994 gen_load_gpr(t0, rs);
27995 gen_helper_yield(t0, cpu_env, t0);
27996 gen_store_gpr(t0, rd);
27997 tcg_temp_free(t0);
27998 }
27999 break;
28000 default:
28001 if (ctx->insn_flags & ISA_MIPS32R6) {
28002 decode_opc_special3_r6(env, ctx);
28003 } else {
28004 decode_opc_special3_legacy(env, ctx);
28005 }
28006 }
28007 }
28008
28009 /* MIPS SIMD Architecture (MSA) */
28010 static inline int check_msa_access(DisasContext *ctx)
28011 {
28012 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
28013 !(ctx->hflags & MIPS_HFLAG_F64))) {
28014 generate_exception_end(ctx, EXCP_RI);
28015 return 0;
28016 }
28017
28018 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
28019 if (ctx->insn_flags & ASE_MSA) {
28020 generate_exception_end(ctx, EXCP_MSADIS);
28021 return 0;
28022 } else {
28023 generate_exception_end(ctx, EXCP_RI);
28024 return 0;
28025 }
28026 }
28027 return 1;
28028 }
28029
28030 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
28031 {
28032 /* generates tcg ops to check if any element is 0 */
28033 /* Note this function only works with MSA_WRLEN = 128 */
28034 uint64_t eval_zero_or_big = 0;
28035 uint64_t eval_big = 0;
28036 TCGv_i64 t0 = tcg_temp_new_i64();
28037 TCGv_i64 t1 = tcg_temp_new_i64();
28038 switch (df) {
28039 case DF_BYTE:
28040 eval_zero_or_big = 0x0101010101010101ULL;
28041 eval_big = 0x8080808080808080ULL;
28042 break;
28043 case DF_HALF:
28044 eval_zero_or_big = 0x0001000100010001ULL;
28045 eval_big = 0x8000800080008000ULL;
28046 break;
28047 case DF_WORD:
28048 eval_zero_or_big = 0x0000000100000001ULL;
28049 eval_big = 0x8000000080000000ULL;
28050 break;
28051 case DF_DOUBLE:
28052 eval_zero_or_big = 0x0000000000000001ULL;
28053 eval_big = 0x8000000000000000ULL;
28054 break;
28055 }
28056 tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big);
28057 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]);
28058 tcg_gen_andi_i64(t0, t0, eval_big);
28059 tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big);
28060 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]);
28061 tcg_gen_andi_i64(t1, t1, eval_big);
28062 tcg_gen_or_i64(t0, t0, t1);
28063 /* if all bits are zero then all elements are not zero */
28064 /* if some bit is non-zero then some element is zero */
28065 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
28066 tcg_gen_trunc_i64_tl(tresult, t0);
28067 tcg_temp_free_i64(t0);
28068 tcg_temp_free_i64(t1);
28069 }
28070
28071 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
28072 {
28073 uint8_t df = (ctx->opcode >> 21) & 0x3;
28074 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28075 int64_t s16 = (int16_t)ctx->opcode;
28076
28077 check_msa_access(ctx);
28078
28079 if (ctx->hflags & MIPS_HFLAG_BMASK) {
28080 generate_exception_end(ctx, EXCP_RI);
28081 return;
28082 }
28083 switch (op1) {
28084 case OPC_BZ_V:
28085 case OPC_BNZ_V:
28086 {
28087 TCGv_i64 t0 = tcg_temp_new_i64();
28088 tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]);
28089 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
28090 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
28091 tcg_gen_trunc_i64_tl(bcond, t0);
28092 tcg_temp_free_i64(t0);
28093 }
28094 break;
28095 case OPC_BZ_B:
28096 case OPC_BZ_H:
28097 case OPC_BZ_W:
28098 case OPC_BZ_D:
28099 gen_check_zero_element(bcond, df, wt);
28100 break;
28101 case OPC_BNZ_B:
28102 case OPC_BNZ_H:
28103 case OPC_BNZ_W:
28104 case OPC_BNZ_D:
28105 gen_check_zero_element(bcond, df, wt);
28106 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
28107 break;
28108 }
28109
28110 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
28111
28112 ctx->hflags |= MIPS_HFLAG_BC;
28113 ctx->hflags |= MIPS_HFLAG_BDS32;
28114 }
28115
28116 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
28117 {
28118 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28119 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
28120 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28121 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28122
28123 TCGv_i32 twd = tcg_const_i32(wd);
28124 TCGv_i32 tws = tcg_const_i32(ws);
28125 TCGv_i32 ti8 = tcg_const_i32(i8);
28126
28127 switch (MASK_MSA_I8(ctx->opcode)) {
28128 case OPC_ANDI_B:
28129 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
28130 break;
28131 case OPC_ORI_B:
28132 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
28133 break;
28134 case OPC_NORI_B:
28135 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
28136 break;
28137 case OPC_XORI_B:
28138 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
28139 break;
28140 case OPC_BMNZI_B:
28141 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
28142 break;
28143 case OPC_BMZI_B:
28144 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
28145 break;
28146 case OPC_BSELI_B:
28147 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
28148 break;
28149 case OPC_SHF_B:
28150 case OPC_SHF_H:
28151 case OPC_SHF_W:
28152 {
28153 uint8_t df = (ctx->opcode >> 24) & 0x3;
28154 if (df == DF_DOUBLE) {
28155 generate_exception_end(ctx, EXCP_RI);
28156 } else {
28157 TCGv_i32 tdf = tcg_const_i32(df);
28158 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
28159 tcg_temp_free_i32(tdf);
28160 }
28161 }
28162 break;
28163 default:
28164 MIPS_INVAL("MSA instruction");
28165 generate_exception_end(ctx, EXCP_RI);
28166 break;
28167 }
28168
28169 tcg_temp_free_i32(twd);
28170 tcg_temp_free_i32(tws);
28171 tcg_temp_free_i32(ti8);
28172 }
28173
28174 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
28175 {
28176 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28177 uint8_t df = (ctx->opcode >> 21) & 0x3;
28178 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
28179 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
28180 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28181 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28182
28183 TCGv_i32 tdf = tcg_const_i32(df);
28184 TCGv_i32 twd = tcg_const_i32(wd);
28185 TCGv_i32 tws = tcg_const_i32(ws);
28186 TCGv_i32 timm = tcg_temp_new_i32();
28187 tcg_gen_movi_i32(timm, u5);
28188
28189 switch (MASK_MSA_I5(ctx->opcode)) {
28190 case OPC_ADDVI_df:
28191 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
28192 break;
28193 case OPC_SUBVI_df:
28194 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
28195 break;
28196 case OPC_MAXI_S_df:
28197 tcg_gen_movi_i32(timm, s5);
28198 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
28199 break;
28200 case OPC_MAXI_U_df:
28201 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
28202 break;
28203 case OPC_MINI_S_df:
28204 tcg_gen_movi_i32(timm, s5);
28205 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
28206 break;
28207 case OPC_MINI_U_df:
28208 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
28209 break;
28210 case OPC_CEQI_df:
28211 tcg_gen_movi_i32(timm, s5);
28212 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
28213 break;
28214 case OPC_CLTI_S_df:
28215 tcg_gen_movi_i32(timm, s5);
28216 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
28217 break;
28218 case OPC_CLTI_U_df:
28219 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
28220 break;
28221 case OPC_CLEI_S_df:
28222 tcg_gen_movi_i32(timm, s5);
28223 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
28224 break;
28225 case OPC_CLEI_U_df:
28226 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
28227 break;
28228 case OPC_LDI_df:
28229 {
28230 int32_t s10 = sextract32(ctx->opcode, 11, 10);
28231 tcg_gen_movi_i32(timm, s10);
28232 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
28233 }
28234 break;
28235 default:
28236 MIPS_INVAL("MSA instruction");
28237 generate_exception_end(ctx, EXCP_RI);
28238 break;
28239 }
28240
28241 tcg_temp_free_i32(tdf);
28242 tcg_temp_free_i32(twd);
28243 tcg_temp_free_i32(tws);
28244 tcg_temp_free_i32(timm);
28245 }
28246
28247 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
28248 {
28249 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28250 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
28251 uint32_t df = 0, m = 0;
28252 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28253 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28254
28255 TCGv_i32 tdf;
28256 TCGv_i32 tm;
28257 TCGv_i32 twd;
28258 TCGv_i32 tws;
28259
28260 if ((dfm & 0x40) == 0x00) {
28261 m = dfm & 0x3f;
28262 df = DF_DOUBLE;
28263 } else if ((dfm & 0x60) == 0x40) {
28264 m = dfm & 0x1f;
28265 df = DF_WORD;
28266 } else if ((dfm & 0x70) == 0x60) {
28267 m = dfm & 0x0f;
28268 df = DF_HALF;
28269 } else if ((dfm & 0x78) == 0x70) {
28270 m = dfm & 0x7;
28271 df = DF_BYTE;
28272 } else {
28273 generate_exception_end(ctx, EXCP_RI);
28274 return;
28275 }
28276
28277 tdf = tcg_const_i32(df);
28278 tm = tcg_const_i32(m);
28279 twd = tcg_const_i32(wd);
28280 tws = tcg_const_i32(ws);
28281
28282 switch (MASK_MSA_BIT(ctx->opcode)) {
28283 case OPC_SLLI_df:
28284 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
28285 break;
28286 case OPC_SRAI_df:
28287 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
28288 break;
28289 case OPC_SRLI_df:
28290 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
28291 break;
28292 case OPC_BCLRI_df:
28293 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
28294 break;
28295 case OPC_BSETI_df:
28296 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
28297 break;
28298 case OPC_BNEGI_df:
28299 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
28300 break;
28301 case OPC_BINSLI_df:
28302 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
28303 break;
28304 case OPC_BINSRI_df:
28305 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
28306 break;
28307 case OPC_SAT_S_df:
28308 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
28309 break;
28310 case OPC_SAT_U_df:
28311 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
28312 break;
28313 case OPC_SRARI_df:
28314 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
28315 break;
28316 case OPC_SRLRI_df:
28317 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
28318 break;
28319 default:
28320 MIPS_INVAL("MSA instruction");
28321 generate_exception_end(ctx, EXCP_RI);
28322 break;
28323 }
28324
28325 tcg_temp_free_i32(tdf);
28326 tcg_temp_free_i32(tm);
28327 tcg_temp_free_i32(twd);
28328 tcg_temp_free_i32(tws);
28329 }
28330
28331 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28332 {
28333 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28334 uint8_t df = (ctx->opcode >> 21) & 0x3;
28335 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28336 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28337 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28338
28339 TCGv_i32 tdf = tcg_const_i32(df);
28340 TCGv_i32 twd = tcg_const_i32(wd);
28341 TCGv_i32 tws = tcg_const_i32(ws);
28342 TCGv_i32 twt = tcg_const_i32(wt);
28343
28344 switch (MASK_MSA_3R(ctx->opcode)) {
28345 case OPC_SLL_df:
28346 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28347 break;
28348 case OPC_ADDV_df:
28349 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28350 break;
28351 case OPC_CEQ_df:
28352 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28353 break;
28354 case OPC_ADD_A_df:
28355 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28356 break;
28357 case OPC_SUBS_S_df:
28358 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28359 break;
28360 case OPC_MULV_df:
28361 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28362 break;
28363 case OPC_SLD_df:
28364 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28365 break;
28366 case OPC_VSHF_df:
28367 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28368 break;
28369 case OPC_SRA_df:
28370 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28371 break;
28372 case OPC_SUBV_df:
28373 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28374 break;
28375 case OPC_ADDS_A_df:
28376 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28377 break;
28378 case OPC_SUBS_U_df:
28379 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28380 break;
28381 case OPC_MADDV_df:
28382 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28383 break;
28384 case OPC_SPLAT_df:
28385 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28386 break;
28387 case OPC_SRAR_df:
28388 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28389 break;
28390 case OPC_SRL_df:
28391 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28392 break;
28393 case OPC_MAX_S_df:
28394 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28395 break;
28396 case OPC_CLT_S_df:
28397 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28398 break;
28399 case OPC_ADDS_S_df:
28400 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28401 break;
28402 case OPC_SUBSUS_U_df:
28403 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28404 break;
28405 case OPC_MSUBV_df:
28406 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28407 break;
28408 case OPC_PCKEV_df:
28409 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28410 break;
28411 case OPC_SRLR_df:
28412 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28413 break;
28414 case OPC_BCLR_df:
28415 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28416 break;
28417 case OPC_MAX_U_df:
28418 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28419 break;
28420 case OPC_CLT_U_df:
28421 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28422 break;
28423 case OPC_ADDS_U_df:
28424 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28425 break;
28426 case OPC_SUBSUU_S_df:
28427 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28428 break;
28429 case OPC_PCKOD_df:
28430 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28431 break;
28432 case OPC_BSET_df:
28433 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28434 break;
28435 case OPC_MIN_S_df:
28436 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28437 break;
28438 case OPC_CLE_S_df:
28439 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28440 break;
28441 case OPC_AVE_S_df:
28442 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28443 break;
28444 case OPC_ASUB_S_df:
28445 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28446 break;
28447 case OPC_DIV_S_df:
28448 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28449 break;
28450 case OPC_ILVL_df:
28451 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28452 break;
28453 case OPC_BNEG_df:
28454 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28455 break;
28456 case OPC_MIN_U_df:
28457 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28458 break;
28459 case OPC_CLE_U_df:
28460 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28461 break;
28462 case OPC_AVE_U_df:
28463 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28464 break;
28465 case OPC_ASUB_U_df:
28466 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28467 break;
28468 case OPC_DIV_U_df:
28469 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28470 break;
28471 case OPC_ILVR_df:
28472 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28473 break;
28474 case OPC_BINSL_df:
28475 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28476 break;
28477 case OPC_MAX_A_df:
28478 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28479 break;
28480 case OPC_AVER_S_df:
28481 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28482 break;
28483 case OPC_MOD_S_df:
28484 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28485 break;
28486 case OPC_ILVEV_df:
28487 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28488 break;
28489 case OPC_BINSR_df:
28490 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28491 break;
28492 case OPC_MIN_A_df:
28493 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28494 break;
28495 case OPC_AVER_U_df:
28496 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28497 break;
28498 case OPC_MOD_U_df:
28499 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28500 break;
28501 case OPC_ILVOD_df:
28502 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28503 break;
28504
28505 case OPC_DOTP_S_df:
28506 case OPC_DOTP_U_df:
28507 case OPC_DPADD_S_df:
28508 case OPC_DPADD_U_df:
28509 case OPC_DPSUB_S_df:
28510 case OPC_HADD_S_df:
28511 case OPC_DPSUB_U_df:
28512 case OPC_HADD_U_df:
28513 case OPC_HSUB_S_df:
28514 case OPC_HSUB_U_df:
28515 if (df == DF_BYTE) {
28516 generate_exception_end(ctx, EXCP_RI);
28517 break;
28518 }
28519 switch (MASK_MSA_3R(ctx->opcode)) {
28520 case OPC_DOTP_S_df:
28521 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28522 break;
28523 case OPC_DOTP_U_df:
28524 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28525 break;
28526 case OPC_DPADD_S_df:
28527 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28528 break;
28529 case OPC_DPADD_U_df:
28530 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28531 break;
28532 case OPC_DPSUB_S_df:
28533 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28534 break;
28535 case OPC_HADD_S_df:
28536 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28537 break;
28538 case OPC_DPSUB_U_df:
28539 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28540 break;
28541 case OPC_HADD_U_df:
28542 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28543 break;
28544 case OPC_HSUB_S_df:
28545 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28546 break;
28547 case OPC_HSUB_U_df:
28548 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28549 break;
28550 }
28551 break;
28552 default:
28553 MIPS_INVAL("MSA instruction");
28554 generate_exception_end(ctx, EXCP_RI);
28555 break;
28556 }
28557 tcg_temp_free_i32(twd);
28558 tcg_temp_free_i32(tws);
28559 tcg_temp_free_i32(twt);
28560 tcg_temp_free_i32(tdf);
28561 }
28562
28563 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28564 {
28565 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28566 uint8_t source = (ctx->opcode >> 11) & 0x1f;
28567 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28568 TCGv telm = tcg_temp_new();
28569 TCGv_i32 tsr = tcg_const_i32(source);
28570 TCGv_i32 tdt = tcg_const_i32(dest);
28571
28572 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28573 case OPC_CTCMSA:
28574 gen_load_gpr(telm, source);
28575 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28576 break;
28577 case OPC_CFCMSA:
28578 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28579 gen_store_gpr(telm, dest);
28580 break;
28581 case OPC_MOVE_V:
28582 gen_helper_msa_move_v(cpu_env, tdt, tsr);
28583 break;
28584 default:
28585 MIPS_INVAL("MSA instruction");
28586 generate_exception_end(ctx, EXCP_RI);
28587 break;
28588 }
28589
28590 tcg_temp_free(telm);
28591 tcg_temp_free_i32(tdt);
28592 tcg_temp_free_i32(tsr);
28593 }
28594
28595 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28596 uint32_t n)
28597 {
28598 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28599 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28600 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28601
28602 TCGv_i32 tws = tcg_const_i32(ws);
28603 TCGv_i32 twd = tcg_const_i32(wd);
28604 TCGv_i32 tn = tcg_const_i32(n);
28605 TCGv_i32 tdf = tcg_const_i32(df);
28606
28607 switch (MASK_MSA_ELM(ctx->opcode)) {
28608 case OPC_SLDI_df:
28609 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28610 break;
28611 case OPC_SPLATI_df:
28612 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28613 break;
28614 case OPC_INSVE_df:
28615 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28616 break;
28617 case OPC_COPY_S_df:
28618 case OPC_COPY_U_df:
28619 case OPC_INSERT_df:
28620 #if !defined(TARGET_MIPS64)
28621 /* Double format valid only for MIPS64 */
28622 if (df == DF_DOUBLE) {
28623 generate_exception_end(ctx, EXCP_RI);
28624 break;
28625 }
28626 if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
28627 (df == DF_WORD)) {
28628 generate_exception_end(ctx, EXCP_RI);
28629 break;
28630 }
28631 #endif
28632 switch (MASK_MSA_ELM(ctx->opcode)) {
28633 case OPC_COPY_S_df:
28634 if (likely(wd != 0)) {
28635 switch (df) {
28636 case DF_BYTE:
28637 gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
28638 break;
28639 case DF_HALF:
28640 gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
28641 break;
28642 case DF_WORD:
28643 gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
28644 break;
28645 #if defined(TARGET_MIPS64)
28646 case DF_DOUBLE:
28647 gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
28648 break;
28649 #endif
28650 default:
28651 assert(0);
28652 }
28653 }
28654 break;
28655 case OPC_COPY_U_df:
28656 if (likely(wd != 0)) {
28657 switch (df) {
28658 case DF_BYTE:
28659 gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
28660 break;
28661 case DF_HALF:
28662 gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
28663 break;
28664 #if defined(TARGET_MIPS64)
28665 case DF_WORD:
28666 gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
28667 break;
28668 #endif
28669 default:
28670 assert(0);
28671 }
28672 }
28673 break;
28674 case OPC_INSERT_df:
28675 switch (df) {
28676 case DF_BYTE:
28677 gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
28678 break;
28679 case DF_HALF:
28680 gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
28681 break;
28682 case DF_WORD:
28683 gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
28684 break;
28685 #if defined(TARGET_MIPS64)
28686 case DF_DOUBLE:
28687 gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
28688 break;
28689 #endif
28690 default:
28691 assert(0);
28692 }
28693 break;
28694 }
28695 break;
28696 default:
28697 MIPS_INVAL("MSA instruction");
28698 generate_exception_end(ctx, EXCP_RI);
28699 }
28700 tcg_temp_free_i32(twd);
28701 tcg_temp_free_i32(tws);
28702 tcg_temp_free_i32(tn);
28703 tcg_temp_free_i32(tdf);
28704 }
28705
28706 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28707 {
28708 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28709 uint32_t df = 0, n = 0;
28710
28711 if ((dfn & 0x30) == 0x00) {
28712 n = dfn & 0x0f;
28713 df = DF_BYTE;
28714 } else if ((dfn & 0x38) == 0x20) {
28715 n = dfn & 0x07;
28716 df = DF_HALF;
28717 } else if ((dfn & 0x3c) == 0x30) {
28718 n = dfn & 0x03;
28719 df = DF_WORD;
28720 } else if ((dfn & 0x3e) == 0x38) {
28721 n = dfn & 0x01;
28722 df = DF_DOUBLE;
28723 } else if (dfn == 0x3E) {
28724 /* CTCMSA, CFCMSA, MOVE.V */
28725 gen_msa_elm_3e(env, ctx);
28726 return;
28727 } else {
28728 generate_exception_end(ctx, EXCP_RI);
28729 return;
28730 }
28731
28732 gen_msa_elm_df(env, ctx, df, n);
28733 }
28734
28735 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28736 {
28737 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28738 uint8_t df = (ctx->opcode >> 21) & 0x1;
28739 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28740 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28741 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28742
28743 TCGv_i32 twd = tcg_const_i32(wd);
28744 TCGv_i32 tws = tcg_const_i32(ws);
28745 TCGv_i32 twt = tcg_const_i32(wt);
28746 TCGv_i32 tdf = tcg_temp_new_i32();
28747
28748 /* adjust df value for floating-point instruction */
28749 tcg_gen_movi_i32(tdf, df + 2);
28750
28751 switch (MASK_MSA_3RF(ctx->opcode)) {
28752 case OPC_FCAF_df:
28753 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28754 break;
28755 case OPC_FADD_df:
28756 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28757 break;
28758 case OPC_FCUN_df:
28759 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28760 break;
28761 case OPC_FSUB_df:
28762 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28763 break;
28764 case OPC_FCOR_df:
28765 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28766 break;
28767 case OPC_FCEQ_df:
28768 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28769 break;
28770 case OPC_FMUL_df:
28771 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28772 break;
28773 case OPC_FCUNE_df:
28774 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28775 break;
28776 case OPC_FCUEQ_df:
28777 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28778 break;
28779 case OPC_FDIV_df:
28780 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28781 break;
28782 case OPC_FCNE_df:
28783 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28784 break;
28785 case OPC_FCLT_df:
28786 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28787 break;
28788 case OPC_FMADD_df:
28789 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28790 break;
28791 case OPC_MUL_Q_df:
28792 tcg_gen_movi_i32(tdf, df + 1);
28793 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28794 break;
28795 case OPC_FCULT_df:
28796 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28797 break;
28798 case OPC_FMSUB_df:
28799 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28800 break;
28801 case OPC_MADD_Q_df:
28802 tcg_gen_movi_i32(tdf, df + 1);
28803 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28804 break;
28805 case OPC_FCLE_df:
28806 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28807 break;
28808 case OPC_MSUB_Q_df:
28809 tcg_gen_movi_i32(tdf, df + 1);
28810 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28811 break;
28812 case OPC_FCULE_df:
28813 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28814 break;
28815 case OPC_FEXP2_df:
28816 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28817 break;
28818 case OPC_FSAF_df:
28819 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28820 break;
28821 case OPC_FEXDO_df:
28822 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28823 break;
28824 case OPC_FSUN_df:
28825 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28826 break;
28827 case OPC_FSOR_df:
28828 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28829 break;
28830 case OPC_FSEQ_df:
28831 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28832 break;
28833 case OPC_FTQ_df:
28834 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28835 break;
28836 case OPC_FSUNE_df:
28837 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28838 break;
28839 case OPC_FSUEQ_df:
28840 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28841 break;
28842 case OPC_FSNE_df:
28843 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28844 break;
28845 case OPC_FSLT_df:
28846 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28847 break;
28848 case OPC_FMIN_df:
28849 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28850 break;
28851 case OPC_MULR_Q_df:
28852 tcg_gen_movi_i32(tdf, df + 1);
28853 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28854 break;
28855 case OPC_FSULT_df:
28856 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28857 break;
28858 case OPC_FMIN_A_df:
28859 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28860 break;
28861 case OPC_MADDR_Q_df:
28862 tcg_gen_movi_i32(tdf, df + 1);
28863 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28864 break;
28865 case OPC_FSLE_df:
28866 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28867 break;
28868 case OPC_FMAX_df:
28869 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28870 break;
28871 case OPC_MSUBR_Q_df:
28872 tcg_gen_movi_i32(tdf, df + 1);
28873 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28874 break;
28875 case OPC_FSULE_df:
28876 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28877 break;
28878 case OPC_FMAX_A_df:
28879 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28880 break;
28881 default:
28882 MIPS_INVAL("MSA instruction");
28883 generate_exception_end(ctx, EXCP_RI);
28884 break;
28885 }
28886
28887 tcg_temp_free_i32(twd);
28888 tcg_temp_free_i32(tws);
28889 tcg_temp_free_i32(twt);
28890 tcg_temp_free_i32(tdf);
28891 }
28892
28893 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28894 {
28895 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28896 (op & (0x7 << 18)))
28897 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28898 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28899 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28900 uint8_t df = (ctx->opcode >> 16) & 0x3;
28901 TCGv_i32 twd = tcg_const_i32(wd);
28902 TCGv_i32 tws = tcg_const_i32(ws);
28903 TCGv_i32 twt = tcg_const_i32(wt);
28904 TCGv_i32 tdf = tcg_const_i32(df);
28905
28906 switch (MASK_MSA_2R(ctx->opcode)) {
28907 case OPC_FILL_df:
28908 #if !defined(TARGET_MIPS64)
28909 /* Double format valid only for MIPS64 */
28910 if (df == DF_DOUBLE) {
28911 generate_exception_end(ctx, EXCP_RI);
28912 break;
28913 }
28914 #endif
28915 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28916 break;
28917 case OPC_PCNT_df:
28918 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28919 break;
28920 case OPC_NLOC_df:
28921 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28922 break;
28923 case OPC_NLZC_df:
28924 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28925 break;
28926 default:
28927 MIPS_INVAL("MSA instruction");
28928 generate_exception_end(ctx, EXCP_RI);
28929 break;
28930 }
28931
28932 tcg_temp_free_i32(twd);
28933 tcg_temp_free_i32(tws);
28934 tcg_temp_free_i32(twt);
28935 tcg_temp_free_i32(tdf);
28936 }
28937
28938 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28939 {
28940 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28941 (op & (0xf << 17)))
28942 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28943 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28944 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28945 uint8_t df = (ctx->opcode >> 16) & 0x1;
28946 TCGv_i32 twd = tcg_const_i32(wd);
28947 TCGv_i32 tws = tcg_const_i32(ws);
28948 TCGv_i32 twt = tcg_const_i32(wt);
28949 /* adjust df value for floating-point instruction */
28950 TCGv_i32 tdf = tcg_const_i32(df + 2);
28951
28952 switch (MASK_MSA_2RF(ctx->opcode)) {
28953 case OPC_FCLASS_df:
28954 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28955 break;
28956 case OPC_FTRUNC_S_df:
28957 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28958 break;
28959 case OPC_FTRUNC_U_df:
28960 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28961 break;
28962 case OPC_FSQRT_df:
28963 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28964 break;
28965 case OPC_FRSQRT_df:
28966 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28967 break;
28968 case OPC_FRCP_df:
28969 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28970 break;
28971 case OPC_FRINT_df:
28972 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28973 break;
28974 case OPC_FLOG2_df:
28975 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28976 break;
28977 case OPC_FEXUPL_df:
28978 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28979 break;
28980 case OPC_FEXUPR_df:
28981 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28982 break;
28983 case OPC_FFQL_df:
28984 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28985 break;
28986 case OPC_FFQR_df:
28987 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28988 break;
28989 case OPC_FTINT_S_df:
28990 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28991 break;
28992 case OPC_FTINT_U_df:
28993 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
28994 break;
28995 case OPC_FFINT_S_df:
28996 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
28997 break;
28998 case OPC_FFINT_U_df:
28999 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
29000 break;
29001 }
29002
29003 tcg_temp_free_i32(twd);
29004 tcg_temp_free_i32(tws);
29005 tcg_temp_free_i32(twt);
29006 tcg_temp_free_i32(tdf);
29007 }
29008
29009 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
29010 {
29011 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
29012 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29013 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29014 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29015 TCGv_i32 twd = tcg_const_i32(wd);
29016 TCGv_i32 tws = tcg_const_i32(ws);
29017 TCGv_i32 twt = tcg_const_i32(wt);
29018
29019 switch (MASK_MSA_VEC(ctx->opcode)) {
29020 case OPC_AND_V:
29021 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
29022 break;
29023 case OPC_OR_V:
29024 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
29025 break;
29026 case OPC_NOR_V:
29027 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
29028 break;
29029 case OPC_XOR_V:
29030 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
29031 break;
29032 case OPC_BMNZ_V:
29033 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
29034 break;
29035 case OPC_BMZ_V:
29036 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
29037 break;
29038 case OPC_BSEL_V:
29039 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
29040 break;
29041 default:
29042 MIPS_INVAL("MSA instruction");
29043 generate_exception_end(ctx, EXCP_RI);
29044 break;
29045 }
29046
29047 tcg_temp_free_i32(twd);
29048 tcg_temp_free_i32(tws);
29049 tcg_temp_free_i32(twt);
29050 }
29051
29052 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
29053 {
29054 switch (MASK_MSA_VEC(ctx->opcode)) {
29055 case OPC_AND_V:
29056 case OPC_OR_V:
29057 case OPC_NOR_V:
29058 case OPC_XOR_V:
29059 case OPC_BMNZ_V:
29060 case OPC_BMZ_V:
29061 case OPC_BSEL_V:
29062 gen_msa_vec_v(env, ctx);
29063 break;
29064 case OPC_MSA_2R:
29065 gen_msa_2r(env, ctx);
29066 break;
29067 case OPC_MSA_2RF:
29068 gen_msa_2rf(env, ctx);
29069 break;
29070 default:
29071 MIPS_INVAL("MSA instruction");
29072 generate_exception_end(ctx, EXCP_RI);
29073 break;
29074 }
29075 }
29076
29077 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
29078 {
29079 uint32_t opcode = ctx->opcode;
29080 check_insn(ctx, ASE_MSA);
29081 check_msa_access(ctx);
29082
29083 switch (MASK_MSA_MINOR(opcode)) {
29084 case OPC_MSA_I8_00:
29085 case OPC_MSA_I8_01:
29086 case OPC_MSA_I8_02:
29087 gen_msa_i8(env, ctx);
29088 break;
29089 case OPC_MSA_I5_06:
29090 case OPC_MSA_I5_07:
29091 gen_msa_i5(env, ctx);
29092 break;
29093 case OPC_MSA_BIT_09:
29094 case OPC_MSA_BIT_0A:
29095 gen_msa_bit(env, ctx);
29096 break;
29097 case OPC_MSA_3R_0D:
29098 case OPC_MSA_3R_0E:
29099 case OPC_MSA_3R_0F:
29100 case OPC_MSA_3R_10:
29101 case OPC_MSA_3R_11:
29102 case OPC_MSA_3R_12:
29103 case OPC_MSA_3R_13:
29104 case OPC_MSA_3R_14:
29105 case OPC_MSA_3R_15:
29106 gen_msa_3r(env, ctx);
29107 break;
29108 case OPC_MSA_ELM:
29109 gen_msa_elm(env, ctx);
29110 break;
29111 case OPC_MSA_3RF_1A:
29112 case OPC_MSA_3RF_1B:
29113 case OPC_MSA_3RF_1C:
29114 gen_msa_3rf(env, ctx);
29115 break;
29116 case OPC_MSA_VEC:
29117 gen_msa_vec(env, ctx);
29118 break;
29119 case OPC_LD_B:
29120 case OPC_LD_H:
29121 case OPC_LD_W:
29122 case OPC_LD_D:
29123 case OPC_ST_B:
29124 case OPC_ST_H:
29125 case OPC_ST_W:
29126 case OPC_ST_D:
29127 {
29128 int32_t s10 = sextract32(ctx->opcode, 16, 10);
29129 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
29130 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29131 uint8_t df = (ctx->opcode >> 0) & 0x3;
29132
29133 TCGv_i32 twd = tcg_const_i32(wd);
29134 TCGv taddr = tcg_temp_new();
29135 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
29136
29137 switch (MASK_MSA_MINOR(opcode)) {
29138 case OPC_LD_B:
29139 gen_helper_msa_ld_b(cpu_env, twd, taddr);
29140 break;
29141 case OPC_LD_H:
29142 gen_helper_msa_ld_h(cpu_env, twd, taddr);
29143 break;
29144 case OPC_LD_W:
29145 gen_helper_msa_ld_w(cpu_env, twd, taddr);
29146 break;
29147 case OPC_LD_D:
29148 gen_helper_msa_ld_d(cpu_env, twd, taddr);
29149 break;
29150 case OPC_ST_B:
29151 gen_helper_msa_st_b(cpu_env, twd, taddr);
29152 break;
29153 case OPC_ST_H:
29154 gen_helper_msa_st_h(cpu_env, twd, taddr);
29155 break;
29156 case OPC_ST_W:
29157 gen_helper_msa_st_w(cpu_env, twd, taddr);
29158 break;
29159 case OPC_ST_D:
29160 gen_helper_msa_st_d(cpu_env, twd, taddr);
29161 break;
29162 }
29163
29164 tcg_temp_free_i32(twd);
29165 tcg_temp_free(taddr);
29166 }
29167 break;
29168 default:
29169 MIPS_INVAL("MSA instruction");
29170 generate_exception_end(ctx, EXCP_RI);
29171 break;
29172 }
29173
29174 }
29175
29176 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
29177 {
29178 int32_t offset;
29179 int rs, rt, rd, sa;
29180 uint32_t op, op1;
29181 int16_t imm;
29182
29183 /* make sure instructions are on a word boundary */
29184 if (ctx->base.pc_next & 0x3) {
29185 env->CP0_BadVAddr = ctx->base.pc_next;
29186 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
29187 return;
29188 }
29189
29190 /* Handle blikely not taken case */
29191 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
29192 TCGLabel *l1 = gen_new_label();
29193
29194 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
29195 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
29196 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
29197 gen_set_label(l1);
29198 }
29199
29200 op = MASK_OP_MAJOR(ctx->opcode);
29201 rs = (ctx->opcode >> 21) & 0x1f;
29202 rt = (ctx->opcode >> 16) & 0x1f;
29203 rd = (ctx->opcode >> 11) & 0x1f;
29204 sa = (ctx->opcode >> 6) & 0x1f;
29205 imm = (int16_t)ctx->opcode;
29206 switch (op) {
29207 case OPC_SPECIAL:
29208 decode_opc_special(env, ctx);
29209 break;
29210 case OPC_SPECIAL2:
29211 #if defined(TARGET_MIPS64)
29212 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
29213 decode_mmi(env, ctx);
29214 #else
29215 if (ctx->insn_flags & ASE_MXU) {
29216 decode_opc_mxu(env, ctx);
29217 #endif
29218 } else {
29219 decode_opc_special2_legacy(env, ctx);
29220 }
29221 break;
29222 case OPC_SPECIAL3:
29223 #if defined(TARGET_MIPS64)
29224 if (ctx->insn_flags & INSN_R5900) {
29225 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
29226 } else {
29227 decode_opc_special3(env, ctx);
29228 }
29229 #else
29230 decode_opc_special3(env, ctx);
29231 #endif
29232 break;
29233 case OPC_REGIMM:
29234 op1 = MASK_REGIMM(ctx->opcode);
29235 switch (op1) {
29236 case OPC_BLTZL: /* REGIMM branches */
29237 case OPC_BGEZL:
29238 case OPC_BLTZALL:
29239 case OPC_BGEZALL:
29240 check_insn(ctx, ISA_MIPS2);
29241 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29242 /* Fallthrough */
29243 case OPC_BLTZ:
29244 case OPC_BGEZ:
29245 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
29246 break;
29247 case OPC_BLTZAL:
29248 case OPC_BGEZAL:
29249 if (ctx->insn_flags & ISA_MIPS32R6) {
29250 if (rs == 0) {
29251 /* OPC_NAL, OPC_BAL */
29252 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
29253 } else {
29254 generate_exception_end(ctx, EXCP_RI);
29255 }
29256 } else {
29257 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
29258 }
29259 break;
29260 case OPC_TGEI: /* REGIMM traps */
29261 case OPC_TGEIU:
29262 case OPC_TLTI:
29263 case OPC_TLTIU:
29264 case OPC_TEQI:
29265
29266 case OPC_TNEI:
29267 check_insn(ctx, ISA_MIPS2);
29268 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29269 gen_trap(ctx, op1, rs, -1, imm);
29270 break;
29271 case OPC_SIGRIE:
29272 check_insn(ctx, ISA_MIPS32R6);
29273 generate_exception_end(ctx, EXCP_RI);
29274 break;
29275 case OPC_SYNCI:
29276 check_insn(ctx, ISA_MIPS32R2);
29277 /*
29278 * Break the TB to be able to sync copied instructions
29279 * immediately.
29280 */
29281 ctx->base.is_jmp = DISAS_STOP;
29282 break;
29283 case OPC_BPOSGE32: /* MIPS DSP branch */
29284 #if defined(TARGET_MIPS64)
29285 case OPC_BPOSGE64:
29286 #endif
29287 check_dsp(ctx);
29288 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
29289 break;
29290 #if defined(TARGET_MIPS64)
29291 case OPC_DAHI:
29292 check_insn(ctx, ISA_MIPS32R6);
29293 check_mips_64(ctx);
29294 if (rs != 0) {
29295 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
29296 }
29297 break;
29298 case OPC_DATI:
29299 check_insn(ctx, ISA_MIPS32R6);
29300 check_mips_64(ctx);
29301 if (rs != 0) {
29302 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
29303 }
29304 break;
29305 #endif
29306 default: /* Invalid */
29307 MIPS_INVAL("regimm");
29308 generate_exception_end(ctx, EXCP_RI);
29309 break;
29310 }
29311 break;
29312 case OPC_CP0:
29313 check_cp0_enabled(ctx);
29314 op1 = MASK_CP0(ctx->opcode);
29315 switch (op1) {
29316 case OPC_MFC0:
29317 case OPC_MTC0:
29318 case OPC_MFTR:
29319 case OPC_MTTR:
29320 case OPC_MFHC0:
29321 case OPC_MTHC0:
29322 #if defined(TARGET_MIPS64)
29323 case OPC_DMFC0:
29324 case OPC_DMTC0:
29325 #endif
29326 #ifndef CONFIG_USER_ONLY
29327 gen_cp0(env, ctx, op1, rt, rd);
29328 #endif /* !CONFIG_USER_ONLY */
29329 break;
29330 case OPC_C0:
29331 case OPC_C0_1:
29332 case OPC_C0_2:
29333 case OPC_C0_3:
29334 case OPC_C0_4:
29335 case OPC_C0_5:
29336 case OPC_C0_6:
29337 case OPC_C0_7:
29338 case OPC_C0_8:
29339 case OPC_C0_9:
29340 case OPC_C0_A:
29341 case OPC_C0_B:
29342 case OPC_C0_C:
29343 case OPC_C0_D:
29344 case OPC_C0_E:
29345 case OPC_C0_F:
29346 #ifndef CONFIG_USER_ONLY
29347 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
29348 #endif /* !CONFIG_USER_ONLY */
29349 break;
29350 case OPC_MFMC0:
29351 #ifndef CONFIG_USER_ONLY
29352 {
29353 uint32_t op2;
29354 TCGv t0 = tcg_temp_new();
29355
29356 op2 = MASK_MFMC0(ctx->opcode);
29357 switch (op2) {
29358 case OPC_DMT:
29359 check_cp0_mt(ctx);
29360 gen_helper_dmt(t0);
29361 gen_store_gpr(t0, rt);
29362 break;
29363 case OPC_EMT:
29364 check_cp0_mt(ctx);
29365 gen_helper_emt(t0);
29366 gen_store_gpr(t0, rt);
29367 break;
29368 case OPC_DVPE:
29369 check_cp0_mt(ctx);
29370 gen_helper_dvpe(t0, cpu_env);
29371 gen_store_gpr(t0, rt);
29372 break;
29373 case OPC_EVPE:
29374 check_cp0_mt(ctx);
29375 gen_helper_evpe(t0, cpu_env);
29376 gen_store_gpr(t0, rt);
29377 break;
29378 case OPC_DVP:
29379 check_insn(ctx, ISA_MIPS32R6);
29380 if (ctx->vp) {
29381 gen_helper_dvp(t0, cpu_env);
29382 gen_store_gpr(t0, rt);
29383 }
29384 break;
29385 case OPC_EVP:
29386 check_insn(ctx, ISA_MIPS32R6);
29387 if (ctx->vp) {
29388 gen_helper_evp(t0, cpu_env);
29389 gen_store_gpr(t0, rt);
29390 }
29391 break;
29392 case OPC_DI:
29393 check_insn(ctx, ISA_MIPS32R2);
29394 save_cpu_state(ctx, 1);
29395 gen_helper_di(t0, cpu_env);
29396 gen_store_gpr(t0, rt);
29397 /*
29398 * Stop translation as we may have switched
29399 * the execution mode.
29400 */
29401 ctx->base.is_jmp = DISAS_STOP;
29402 break;
29403 case OPC_EI:
29404 check_insn(ctx, ISA_MIPS32R2);
29405 save_cpu_state(ctx, 1);
29406 gen_helper_ei(t0, cpu_env);
29407 gen_store_gpr(t0, rt);
29408 /*
29409 * DISAS_STOP isn't sufficient, we need to ensure we break
29410 * out of translated code to check for pending interrupts.
29411 */
29412 gen_save_pc(ctx->base.pc_next + 4);
29413 ctx->base.is_jmp = DISAS_EXIT;
29414 break;
29415 default: /* Invalid */
29416 MIPS_INVAL("mfmc0");
29417 generate_exception_end(ctx, EXCP_RI);
29418 break;
29419 }
29420 tcg_temp_free(t0);
29421 }
29422 #endif /* !CONFIG_USER_ONLY */
29423 break;
29424 case OPC_RDPGPR:
29425 check_insn(ctx, ISA_MIPS32R2);
29426 gen_load_srsgpr(rt, rd);
29427 break;
29428 case OPC_WRPGPR:
29429 check_insn(ctx, ISA_MIPS32R2);
29430 gen_store_srsgpr(rt, rd);
29431 break;
29432 default:
29433 MIPS_INVAL("cp0");
29434 generate_exception_end(ctx, EXCP_RI);
29435 break;
29436 }
29437 break;
29438 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29439 if (ctx->insn_flags & ISA_MIPS32R6) {
29440 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29441 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29442 } else {
29443 /* OPC_ADDI */
29444 /* Arithmetic with immediate opcode */
29445 gen_arith_imm(ctx, op, rt, rs, imm);
29446 }
29447 break;
29448 case OPC_ADDIU:
29449 gen_arith_imm(ctx, op, rt, rs, imm);
29450 break;
29451 case OPC_SLTI: /* Set on less than with immediate opcode */
29452 case OPC_SLTIU:
29453 gen_slt_imm(ctx, op, rt, rs, imm);
29454 break;
29455 case OPC_ANDI: /* Arithmetic with immediate opcode */
29456 case OPC_LUI: /* OPC_AUI */
29457 case OPC_ORI:
29458 case OPC_XORI:
29459 gen_logic_imm(ctx, op, rt, rs, imm);
29460 break;
29461 case OPC_J: /* Jump */
29462 case OPC_JAL:
29463 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29464 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29465 break;
29466 /* Branch */
29467 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29468 if (ctx->insn_flags & ISA_MIPS32R6) {
29469 if (rt == 0) {
29470 generate_exception_end(ctx, EXCP_RI);
29471 break;
29472 }
29473 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29474 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29475 } else {
29476 /* OPC_BLEZL */
29477 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29478 }
29479 break;
29480 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29481 if (ctx->insn_flags & ISA_MIPS32R6) {
29482 if (rt == 0) {
29483 generate_exception_end(ctx, EXCP_RI);
29484 break;
29485 }
29486 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29487 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29488 } else {
29489 /* OPC_BGTZL */
29490 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29491 }
29492 break;
29493 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29494 if (rt == 0) {
29495 /* OPC_BLEZ */
29496 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29497 } else {
29498 check_insn(ctx, ISA_MIPS32R6);
29499 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29500 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29501 }
29502 break;
29503 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29504 if (rt == 0) {
29505 /* OPC_BGTZ */
29506 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29507 } else {
29508 check_insn(ctx, ISA_MIPS32R6);
29509 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29510 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29511 }
29512 break;
29513 case OPC_BEQL:
29514 case OPC_BNEL:
29515 check_insn(ctx, ISA_MIPS2);
29516 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29517 /* Fallthrough */
29518 case OPC_BEQ:
29519 case OPC_BNE:
29520 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29521 break;
29522 case OPC_LL: /* Load and stores */
29523 check_insn(ctx, ISA_MIPS2);
29524 if (ctx->insn_flags & INSN_R5900) {
29525 check_insn_opc_user_only(ctx, INSN_R5900);
29526 }
29527 /* Fallthrough */
29528 case OPC_LWL:
29529 case OPC_LWR:
29530 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29531 /* Fallthrough */
29532 case OPC_LB:
29533 case OPC_LH:
29534 case OPC_LW:
29535 case OPC_LWPC:
29536 case OPC_LBU:
29537 case OPC_LHU:
29538 gen_ld(ctx, op, rt, rs, imm);
29539 break;
29540 case OPC_SWL:
29541 case OPC_SWR:
29542 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29543 /* fall through */
29544 case OPC_SB:
29545 case OPC_SH:
29546 case OPC_SW:
29547 gen_st(ctx, op, rt, rs, imm);
29548 break;
29549 case OPC_SC:
29550 check_insn(ctx, ISA_MIPS2);
29551 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29552 if (ctx->insn_flags & INSN_R5900) {
29553 check_insn_opc_user_only(ctx, INSN_R5900);
29554 }
29555 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
29556 break;
29557 case OPC_CACHE:
29558 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29559 check_cp0_enabled(ctx);
29560 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29561 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29562 gen_cache_operation(ctx, rt, rs, imm);
29563 }
29564 /* Treat as NOP. */
29565 break;
29566 case OPC_PREF:
29567 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29568 if (ctx->insn_flags & INSN_R5900) {
29569 /* Treat as NOP. */
29570 } else {
29571 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29572 /* Treat as NOP. */
29573 }
29574 break;
29575
29576 /* Floating point (COP1). */
29577 case OPC_LWC1:
29578 case OPC_LDC1:
29579 case OPC_SWC1:
29580 case OPC_SDC1:
29581 gen_cop1_ldst(ctx, op, rt, rs, imm);
29582 break;
29583
29584 case OPC_CP1:
29585 op1 = MASK_CP1(ctx->opcode);
29586
29587 switch (op1) {
29588 case OPC_MFHC1:
29589 case OPC_MTHC1:
29590 check_cp1_enabled(ctx);
29591 check_insn(ctx, ISA_MIPS32R2);
29592 /* fall through */
29593 case OPC_MFC1:
29594 case OPC_CFC1:
29595 case OPC_MTC1:
29596 case OPC_CTC1:
29597 check_cp1_enabled(ctx);
29598 gen_cp1(ctx, op1, rt, rd);
29599 break;
29600 #if defined(TARGET_MIPS64)
29601 case OPC_DMFC1:
29602 case OPC_DMTC1:
29603 check_cp1_enabled(ctx);
29604 check_insn(ctx, ISA_MIPS3);
29605 check_mips_64(ctx);
29606 gen_cp1(ctx, op1, rt, rd);
29607 break;
29608 #endif
29609 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29610 check_cp1_enabled(ctx);
29611 if (ctx->insn_flags & ISA_MIPS32R6) {
29612 /* OPC_BC1EQZ */
29613 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29614 rt, imm << 2, 4);
29615 } else {
29616 /* OPC_BC1ANY2 */
29617 check_cop1x(ctx);
29618 check_insn(ctx, ASE_MIPS3D);
29619 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29620 (rt >> 2) & 0x7, imm << 2);
29621 }
29622 break;
29623 case OPC_BC1NEZ:
29624 check_cp1_enabled(ctx);
29625 check_insn(ctx, ISA_MIPS32R6);
29626 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29627 rt, imm << 2, 4);
29628 break;
29629 case OPC_BC1ANY4:
29630 check_cp1_enabled(ctx);
29631 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29632 check_cop1x(ctx);
29633 check_insn(ctx, ASE_MIPS3D);
29634 /* fall through */
29635 case OPC_BC1:
29636 check_cp1_enabled(ctx);
29637 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29638 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29639 (rt >> 2) & 0x7, imm << 2);
29640 break;
29641 case OPC_PS_FMT:
29642 check_ps(ctx);
29643 /* fall through */
29644 case OPC_S_FMT:
29645 case OPC_D_FMT:
29646 check_cp1_enabled(ctx);
29647 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29648 (imm >> 8) & 0x7);
29649 break;
29650 case OPC_W_FMT:
29651 case OPC_L_FMT:
29652 {
29653 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29654 check_cp1_enabled(ctx);
29655 if (ctx->insn_flags & ISA_MIPS32R6) {
29656 switch (r6_op) {
29657 case R6_OPC_CMP_AF_S:
29658 case R6_OPC_CMP_UN_S:
29659 case R6_OPC_CMP_EQ_S:
29660 case R6_OPC_CMP_UEQ_S:
29661 case R6_OPC_CMP_LT_S:
29662 case R6_OPC_CMP_ULT_S:
29663 case R6_OPC_CMP_LE_S:
29664 case R6_OPC_CMP_ULE_S:
29665 case R6_OPC_CMP_SAF_S:
29666 case R6_OPC_CMP_SUN_S:
29667 case R6_OPC_CMP_SEQ_S:
29668 case R6_OPC_CMP_SEUQ_S:
29669 case R6_OPC_CMP_SLT_S:
29670 case R6_OPC_CMP_SULT_S:
29671 case R6_OPC_CMP_SLE_S:
29672 case R6_OPC_CMP_SULE_S:
29673 case R6_OPC_CMP_OR_S:
29674 case R6_OPC_CMP_UNE_S:
29675 case R6_OPC_CMP_NE_S:
29676 case R6_OPC_CMP_SOR_S:
29677 case R6_OPC_CMP_SUNE_S:
29678 case R6_OPC_CMP_SNE_S:
29679 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29680 break;
29681 case R6_OPC_CMP_AF_D:
29682 case R6_OPC_CMP_UN_D:
29683 case R6_OPC_CMP_EQ_D:
29684 case R6_OPC_CMP_UEQ_D:
29685 case R6_OPC_CMP_LT_D:
29686 case R6_OPC_CMP_ULT_D:
29687 case R6_OPC_CMP_LE_D:
29688 case R6_OPC_CMP_ULE_D:
29689 case R6_OPC_CMP_SAF_D:
29690 case R6_OPC_CMP_SUN_D:
29691 case R6_OPC_CMP_SEQ_D:
29692 case R6_OPC_CMP_SEUQ_D:
29693 case R6_OPC_CMP_SLT_D:
29694 case R6_OPC_CMP_SULT_D:
29695 case R6_OPC_CMP_SLE_D:
29696 case R6_OPC_CMP_SULE_D:
29697 case R6_OPC_CMP_OR_D:
29698 case R6_OPC_CMP_UNE_D:
29699 case R6_OPC_CMP_NE_D:
29700 case R6_OPC_CMP_SOR_D:
29701 case R6_OPC_CMP_SUNE_D:
29702 case R6_OPC_CMP_SNE_D:
29703 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29704 break;
29705 default:
29706 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29707 rt, rd, sa, (imm >> 8) & 0x7);
29708
29709 break;
29710 }
29711 } else {
29712 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29713 (imm >> 8) & 0x7);
29714 }
29715 break;
29716 }
29717 case OPC_BZ_V:
29718 case OPC_BNZ_V:
29719 case OPC_BZ_B:
29720 case OPC_BZ_H:
29721 case OPC_BZ_W:
29722 case OPC_BZ_D:
29723 case OPC_BNZ_B:
29724 case OPC_BNZ_H:
29725 case OPC_BNZ_W:
29726 case OPC_BNZ_D:
29727 check_insn(ctx, ASE_MSA);
29728 gen_msa_branch(env, ctx, op1);
29729 break;
29730 default:
29731 MIPS_INVAL("cp1");
29732 generate_exception_end(ctx, EXCP_RI);
29733 break;
29734 }
29735 break;
29736
29737 /* Compact branches [R6] and COP2 [non-R6] */
29738 case OPC_BC: /* OPC_LWC2 */
29739 case OPC_BALC: /* OPC_SWC2 */
29740 if (ctx->insn_flags & ISA_MIPS32R6) {
29741 /* OPC_BC, OPC_BALC */
29742 gen_compute_compact_branch(ctx, op, 0, 0,
29743 sextract32(ctx->opcode << 2, 0, 28));
29744 } else {
29745 /* OPC_LWC2, OPC_SWC2 */
29746 /* COP2: Not implemented. */
29747 generate_exception_err(ctx, EXCP_CpU, 2);
29748 }
29749 break;
29750 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29751 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29752 if (ctx->insn_flags & ISA_MIPS32R6) {
29753 if (rs != 0) {
29754 /* OPC_BEQZC, OPC_BNEZC */
29755 gen_compute_compact_branch(ctx, op, rs, 0,
29756 sextract32(ctx->opcode << 2, 0, 23));
29757 } else {
29758 /* OPC_JIC, OPC_JIALC */
29759 gen_compute_compact_branch(ctx, op, 0, rt, imm);
29760 }
29761 } else {
29762 /* OPC_LWC2, OPC_SWC2 */
29763 /* COP2: Not implemented. */
29764 generate_exception_err(ctx, EXCP_CpU, 2);
29765 }
29766 break;
29767 case OPC_CP2:
29768 check_insn(ctx, INSN_LOONGSON2F);
29769 /* Note that these instructions use different fields. */
29770 gen_loongson_multimedia(ctx, sa, rd, rt);
29771 break;
29772
29773 case OPC_CP3:
29774 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29775 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29776 check_cp1_enabled(ctx);
29777 op1 = MASK_CP3(ctx->opcode);
29778 switch (op1) {
29779 case OPC_LUXC1:
29780 case OPC_SUXC1:
29781 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29782 /* Fallthrough */
29783 case OPC_LWXC1:
29784 case OPC_LDXC1:
29785 case OPC_SWXC1:
29786 case OPC_SDXC1:
29787 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29788 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29789 break;
29790 case OPC_PREFX:
29791 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29792 /* Treat as NOP. */
29793 break;
29794 case OPC_ALNV_PS:
29795 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29796 /* Fallthrough */
29797 case OPC_MADD_S:
29798 case OPC_MADD_D:
29799 case OPC_MADD_PS:
29800 case OPC_MSUB_S:
29801 case OPC_MSUB_D:
29802 case OPC_MSUB_PS:
29803 case OPC_NMADD_S:
29804 case OPC_NMADD_D:
29805 case OPC_NMADD_PS:
29806 case OPC_NMSUB_S:
29807 case OPC_NMSUB_D:
29808 case OPC_NMSUB_PS:
29809 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29810 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29811 break;
29812 default:
29813 MIPS_INVAL("cp3");
29814 generate_exception_end(ctx, EXCP_RI);
29815 break;
29816 }
29817 } else {
29818 generate_exception_err(ctx, EXCP_CpU, 1);
29819 }
29820 break;
29821
29822 #if defined(TARGET_MIPS64)
29823 /* MIPS64 opcodes */
29824 case OPC_LLD:
29825 if (ctx->insn_flags & INSN_R5900) {
29826 check_insn_opc_user_only(ctx, INSN_R5900);
29827 }
29828 /* fall through */
29829 case OPC_LDL:
29830 case OPC_LDR:
29831 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29832 /* fall through */
29833 case OPC_LWU:
29834 case OPC_LD:
29835 check_insn(ctx, ISA_MIPS3);
29836 check_mips_64(ctx);
29837 gen_ld(ctx, op, rt, rs, imm);
29838 break;
29839 case OPC_SDL:
29840 case OPC_SDR:
29841 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29842 /* fall through */
29843 case OPC_SD:
29844 check_insn(ctx, ISA_MIPS3);
29845 check_mips_64(ctx);
29846 gen_st(ctx, op, rt, rs, imm);
29847 break;
29848 case OPC_SCD:
29849 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29850 check_insn(ctx, ISA_MIPS3);
29851 if (ctx->insn_flags & INSN_R5900) {
29852 check_insn_opc_user_only(ctx, INSN_R5900);
29853 }
29854 check_mips_64(ctx);
29855 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
29856 break;
29857 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29858 if (ctx->insn_flags & ISA_MIPS32R6) {
29859 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29860 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29861 } else {
29862 /* OPC_DADDI */
29863 check_insn(ctx, ISA_MIPS3);
29864 check_mips_64(ctx);
29865 gen_arith_imm(ctx, op, rt, rs, imm);
29866 }
29867 break;
29868 case OPC_DADDIU:
29869 check_insn(ctx, ISA_MIPS3);
29870 check_mips_64(ctx);
29871 gen_arith_imm(ctx, op, rt, rs, imm);
29872 break;
29873 #else
29874 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29875 if (ctx->insn_flags & ISA_MIPS32R6) {
29876 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29877 } else {
29878 MIPS_INVAL("major opcode");
29879 generate_exception_end(ctx, EXCP_RI);
29880 }
29881 break;
29882 #endif
29883 case OPC_DAUI: /* OPC_JALX */
29884 if (ctx->insn_flags & ISA_MIPS32R6) {
29885 #if defined(TARGET_MIPS64)
29886 /* OPC_DAUI */
29887 check_mips_64(ctx);
29888 if (rs == 0) {
29889 generate_exception(ctx, EXCP_RI);
29890 } else if (rt != 0) {
29891 TCGv t0 = tcg_temp_new();
29892 gen_load_gpr(t0, rs);
29893 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29894 tcg_temp_free(t0);
29895 }
29896 #else
29897 generate_exception_end(ctx, EXCP_RI);
29898 MIPS_INVAL("major opcode");
29899 #endif
29900 } else {
29901 /* OPC_JALX */
29902 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29903 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29904 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29905 }
29906 break;
29907 case OPC_MSA: /* OPC_MDMX */
29908 if (ctx->insn_flags & INSN_R5900) {
29909 #if defined(TARGET_MIPS64)
29910 gen_mmi_lq(env, ctx); /* MMI_OPC_LQ */
29911 #endif
29912 } else {
29913 /* MDMX: Not implemented. */
29914 gen_msa(env, ctx);
29915 }
29916 break;
29917 case OPC_PCREL:
29918 check_insn(ctx, ISA_MIPS32R6);
29919 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29920 break;
29921 default: /* Invalid */
29922 MIPS_INVAL("major opcode");
29923 generate_exception_end(ctx, EXCP_RI);
29924 break;
29925 }
29926 }
29927
29928 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29929 {
29930 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29931 CPUMIPSState *env = cs->env_ptr;
29932
29933 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29934 ctx->saved_pc = -1;
29935 ctx->insn_flags = env->insn_flags;
29936 ctx->CP0_Config1 = env->CP0_Config1;
29937 ctx->CP0_Config2 = env->CP0_Config2;
29938 ctx->CP0_Config3 = env->CP0_Config3;
29939 ctx->CP0_Config5 = env->CP0_Config5;
29940 ctx->btarget = 0;
29941 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29942 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29943 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29944 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29945 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29946 ctx->PAMask = env->PAMask;
29947 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29948 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29949 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29950 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29951 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29952 /* Restore delay slot state from the tb context. */
29953 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29954 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29955 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29956 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29957 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29958 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29959 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29960 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29961 restore_cpu_state(env, ctx);
29962 #ifdef CONFIG_USER_ONLY
29963 ctx->mem_idx = MIPS_HFLAG_UM;
29964 #else
29965 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29966 #endif
29967 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29968 MO_UNALN : MO_ALIGN;
29969
29970 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29971 ctx->hflags);
29972 }
29973
29974 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29975 {
29976 }
29977
29978 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29979 {
29980 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29981
29982 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29983 ctx->btarget);
29984 }
29985
29986 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29987 const CPUBreakpoint *bp)
29988 {
29989 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29990
29991 save_cpu_state(ctx, 1);
29992 ctx->base.is_jmp = DISAS_NORETURN;
29993 gen_helper_raise_exception_debug(cpu_env);
29994 /*
29995 * The address covered by the breakpoint must be included in
29996 * [tb->pc, tb->pc + tb->size) in order to for it to be
29997 * properly cleared -- thus we increment the PC here so that
29998 * the logic setting tb->size below does the right thing.
29999 */
30000 ctx->base.pc_next += 4;
30001 return true;
30002 }
30003
30004 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
30005 {
30006 CPUMIPSState *env = cs->env_ptr;
30007 DisasContext *ctx = container_of(dcbase, DisasContext, base);
30008 int insn_bytes;
30009 int is_slot;
30010
30011 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
30012 if (ctx->insn_flags & ISA_NANOMIPS32) {
30013 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30014 insn_bytes = decode_nanomips_opc(env, ctx);
30015 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
30016 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
30017 insn_bytes = 4;
30018 decode_opc(env, ctx);
30019 } else if (ctx->insn_flags & ASE_MICROMIPS) {
30020 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30021 insn_bytes = decode_micromips_opc(env, ctx);
30022 } else if (ctx->insn_flags & ASE_MIPS16) {
30023 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30024 insn_bytes = decode_mips16_opc(env, ctx);
30025 } else {
30026 generate_exception_end(ctx, EXCP_RI);
30027 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
30028 return;
30029 }
30030
30031 if (ctx->hflags & MIPS_HFLAG_BMASK) {
30032 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
30033 MIPS_HFLAG_FBNSLOT))) {
30034 /*
30035 * Force to generate branch as there is neither delay nor
30036 * forbidden slot.
30037 */
30038 is_slot = 1;
30039 }
30040 if ((ctx->hflags & MIPS_HFLAG_M16) &&
30041 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
30042 /*
30043 * Force to generate branch as microMIPS R6 doesn't restrict
30044 * branches in the forbidden slot.
30045 */
30046 is_slot = 1;
30047 }
30048 }
30049 if (is_slot) {
30050 gen_branch(ctx, insn_bytes);
30051 }
30052 ctx->base.pc_next += insn_bytes;
30053
30054 if (ctx->base.is_jmp != DISAS_NEXT) {
30055 return;
30056 }
30057 /*
30058 * Execute a branch and its delay slot as a single instruction.
30059 * This is what GDB expects and is consistent with what the
30060 * hardware does (e.g. if a delay slot instruction faults, the
30061 * reported PC is the PC of the branch).
30062 */
30063 if (ctx->base.singlestep_enabled &&
30064 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
30065 ctx->base.is_jmp = DISAS_TOO_MANY;
30066 }
30067 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
30068 ctx->base.is_jmp = DISAS_TOO_MANY;
30069 }
30070 }
30071
30072 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
30073 {
30074 DisasContext *ctx = container_of(dcbase, DisasContext, base);
30075
30076 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
30077 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
30078 gen_helper_raise_exception_debug(cpu_env);
30079 } else {
30080 switch (ctx->base.is_jmp) {
30081 case DISAS_STOP:
30082 gen_save_pc(ctx->base.pc_next);
30083 tcg_gen_lookup_and_goto_ptr();
30084 break;
30085 case DISAS_NEXT:
30086 case DISAS_TOO_MANY:
30087 save_cpu_state(ctx, 0);
30088 gen_goto_tb(ctx, 0, ctx->base.pc_next);
30089 break;
30090 case DISAS_EXIT:
30091 tcg_gen_exit_tb(NULL, 0);
30092 break;
30093 case DISAS_NORETURN:
30094 break;
30095 default:
30096 g_assert_not_reached();
30097 }
30098 }
30099 }
30100
30101 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
30102 {
30103 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
30104 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
30105 }
30106
30107 static const TranslatorOps mips_tr_ops = {
30108 .init_disas_context = mips_tr_init_disas_context,
30109 .tb_start = mips_tr_tb_start,
30110 .insn_start = mips_tr_insn_start,
30111 .breakpoint_check = mips_tr_breakpoint_check,
30112 .translate_insn = mips_tr_translate_insn,
30113 .tb_stop = mips_tr_tb_stop,
30114 .disas_log = mips_tr_disas_log,
30115 };
30116
30117 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
30118 {
30119 DisasContext ctx;
30120
30121 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
30122 }
30123
30124 static void fpu_dump_state(CPUMIPSState *env, FILE *f, int flags)
30125 {
30126 int i;
30127 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
30128
30129 #define printfpr(fp) \
30130 do { \
30131 if (is_fpu64) \
30132 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
30133 " fd:%13g fs:%13g psu: %13g\n", \
30134 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
30135 (double)(fp)->fd, \
30136 (double)(fp)->fs[FP_ENDIAN_IDX], \
30137 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
30138 else { \
30139 fpr_t tmp; \
30140 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
30141 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
30142 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
30143 " fd:%13g fs:%13g psu:%13g\n", \
30144 tmp.w[FP_ENDIAN_IDX], tmp.d, \
30145 (double)tmp.fd, \
30146 (double)tmp.fs[FP_ENDIAN_IDX], \
30147 (double)tmp.fs[!FP_ENDIAN_IDX]); \
30148 } \
30149 } while(0)
30150
30151
30152 qemu_fprintf(f,
30153 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
30154 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
30155 get_float_exception_flags(&env->active_fpu.fp_status));
30156 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
30157 qemu_fprintf(f, "%3s: ", fregnames[i]);
30158 printfpr(&env->active_fpu.fpr[i]);
30159 }
30160
30161 #undef printfpr
30162 }
30163
30164 void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
30165 {
30166 MIPSCPU *cpu = MIPS_CPU(cs);
30167 CPUMIPSState *env = &cpu->env;
30168 int i;
30169
30170 qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
30171 " LO=0x" TARGET_FMT_lx " ds %04x "
30172 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
30173 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
30174 env->hflags, env->btarget, env->bcond);
30175 for (i = 0; i < 32; i++) {
30176 if ((i & 3) == 0) {
30177 qemu_fprintf(f, "GPR%02d:", i);
30178 }
30179 qemu_fprintf(f, " %s " TARGET_FMT_lx,
30180 regnames[i], env->active_tc.gpr[i]);
30181 if ((i & 3) == 3) {
30182 qemu_fprintf(f, "\n");
30183 }
30184 }
30185
30186 qemu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
30187 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
30188 qemu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
30189 PRIx64 "\n",
30190 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
30191 qemu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
30192 env->CP0_Config2, env->CP0_Config3);
30193 qemu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
30194 env->CP0_Config4, env->CP0_Config5);
30195 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
30196 fpu_dump_state(env, f, flags);
30197 }
30198 }
30199
30200 void mips_tcg_init(void)
30201 {
30202 int i;
30203
30204 cpu_gpr[0] = NULL;
30205 for (i = 1; i < 32; i++)
30206 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
30207 offsetof(CPUMIPSState, active_tc.gpr[i]),
30208 regnames[i]);
30209
30210 for (i = 0; i < 32; i++) {
30211 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
30212 msa_wr_d[i * 2] =
30213 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
30214 /*
30215 * The scalar floating-point unit (FPU) registers are mapped on
30216 * the MSA vector registers.
30217 */
30218 fpu_f64[i] = msa_wr_d[i * 2];
30219 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
30220 msa_wr_d[i * 2 + 1] =
30221 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
30222 }
30223
30224 cpu_PC = tcg_global_mem_new(cpu_env,
30225 offsetof(CPUMIPSState, active_tc.PC), "PC");
30226 for (i = 0; i < MIPS_DSP_ACC; i++) {
30227 cpu_HI[i] = tcg_global_mem_new(cpu_env,
30228 offsetof(CPUMIPSState, active_tc.HI[i]),
30229 regnames_HI[i]);
30230 cpu_LO[i] = tcg_global_mem_new(cpu_env,
30231 offsetof(CPUMIPSState, active_tc.LO[i]),
30232 regnames_LO[i]);
30233 }
30234 cpu_dspctrl = tcg_global_mem_new(cpu_env,
30235 offsetof(CPUMIPSState, active_tc.DSPControl),
30236 "DSPControl");
30237 bcond = tcg_global_mem_new(cpu_env,
30238 offsetof(CPUMIPSState, bcond), "bcond");
30239 btarget = tcg_global_mem_new(cpu_env,
30240 offsetof(CPUMIPSState, btarget), "btarget");
30241 hflags = tcg_global_mem_new_i32(cpu_env,
30242 offsetof(CPUMIPSState, hflags), "hflags");
30243
30244 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
30245 offsetof(CPUMIPSState, active_fpu.fcr0),
30246 "fcr0");
30247 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
30248 offsetof(CPUMIPSState, active_fpu.fcr31),
30249 "fcr31");
30250 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
30251 "lladdr");
30252 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
30253 "llval");
30254
30255 #if defined(TARGET_MIPS64)
30256 cpu_mmr[0] = NULL;
30257 for (i = 1; i < 32; i++) {
30258 cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
30259 offsetof(CPUMIPSState,
30260 active_tc.mmr[i]),
30261 regnames[i]);
30262 }
30263 #endif
30264
30265 #if !defined(TARGET_MIPS64)
30266 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
30267 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
30268 offsetof(CPUMIPSState,
30269 active_tc.mxu_gpr[i]),
30270 mxuregnames[i]);
30271 }
30272
30273 mxu_CR = tcg_global_mem_new(cpu_env,
30274 offsetof(CPUMIPSState, active_tc.mxu_cr),
30275 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
30276 #endif
30277 }
30278
30279 #include "translate_init.inc.c"
30280
30281 void cpu_mips_realize_env(CPUMIPSState *env)
30282 {
30283 env->exception_base = (int32_t)0xBFC00000;
30284
30285 #ifndef CONFIG_USER_ONLY
30286 mmu_init(env, env->cpu_model);
30287 #endif
30288 fpu_init(env, env->cpu_model);
30289 mvp_init(env, env->cpu_model);
30290 }
30291
30292 bool cpu_supports_cps_smp(const char *cpu_type)
30293 {
30294 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
30295 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
30296 }
30297
30298 bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
30299 {
30300 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
30301 return (mcc->cpu_def->insn_flags & isa) != 0;
30302 }
30303
30304 void cpu_set_exception_base(int vp_index, target_ulong address)
30305 {
30306 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
30307 vp->env.exception_base = address;
30308 }
30309
30310 void cpu_state_reset(CPUMIPSState *env)
30311 {
30312 CPUState *cs = env_cpu(env);
30313
30314 /* Reset registers to their default values */
30315 env->CP0_PRid = env->cpu_model->CP0_PRid;
30316 env->CP0_Config0 = env->cpu_model->CP0_Config0;
30317 #ifdef TARGET_WORDS_BIGENDIAN
30318 env->CP0_Config0 |= (1 << CP0C0_BE);
30319 #endif
30320 env->CP0_Config1 = env->cpu_model->CP0_Config1;
30321 env->CP0_Config2 = env->cpu_model->CP0_Config2;
30322 env->CP0_Config3 = env->cpu_model->CP0_Config3;
30323 env->CP0_Config4 = env->cpu_model->CP0_Config4;
30324 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
30325 env->CP0_Config5 = env->cpu_model->CP0_Config5;
30326 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
30327 env->CP0_Config6 = env->cpu_model->CP0_Config6;
30328 env->CP0_Config7 = env->cpu_model->CP0_Config7;
30329 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
30330 << env->cpu_model->CP0_LLAddr_shift;
30331 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
30332 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
30333 env->CCRes = env->cpu_model->CCRes;
30334 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
30335 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
30336 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
30337 env->current_tc = 0;
30338 env->SEGBITS = env->cpu_model->SEGBITS;
30339 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
30340 #if defined(TARGET_MIPS64)
30341 if (env->cpu_model->insn_flags & ISA_MIPS3) {
30342 env->SEGMask |= 3ULL << 62;
30343 }
30344 #endif
30345 env->PABITS = env->cpu_model->PABITS;
30346 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
30347 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
30348 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
30349 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
30350 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
30351 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
30352 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
30353 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
30354 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
30355 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
30356 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
30357 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
30358 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
30359 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
30360 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
30361 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
30362 env->msair = env->cpu_model->MSAIR;
30363 env->insn_flags = env->cpu_model->insn_flags;
30364
30365 #if defined(CONFIG_USER_ONLY)
30366 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
30367 # ifdef TARGET_MIPS64
30368 /* Enable 64-bit register mode. */
30369 env->CP0_Status |= (1 << CP0St_PX);
30370 # endif
30371 # ifdef TARGET_ABI_MIPSN64
30372 /* Enable 64-bit address mode. */
30373 env->CP0_Status |= (1 << CP0St_UX);
30374 # endif
30375 /*
30376 * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
30377 * hardware registers.
30378 */
30379 env->CP0_HWREna |= 0x0000000F;
30380 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
30381 env->CP0_Status |= (1 << CP0St_CU1);
30382 }
30383 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
30384 env->CP0_Status |= (1 << CP0St_MX);
30385 }
30386 # if defined(TARGET_MIPS64)
30387 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
30388 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
30389 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
30390 env->CP0_Status |= (1 << CP0St_FR);
30391 }
30392 # endif
30393 #else
30394 if (env->hflags & MIPS_HFLAG_BMASK) {
30395 /*
30396 * If the exception was raised from a delay slot,
30397 * come back to the jump.
30398 */
30399 env->CP0_ErrorEPC = (env->active_tc.PC
30400 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
30401 } else {
30402 env->CP0_ErrorEPC = env->active_tc.PC;
30403 }
30404 env->active_tc.PC = env->exception_base;
30405 env->CP0_Random = env->tlb->nb_tlb - 1;
30406 env->tlb->tlb_in_use = env->tlb->nb_tlb;
30407 env->CP0_Wired = 0;
30408 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
30409 env->CP0_EBase = (cs->cpu_index & 0x3FF);
30410 if (mips_um_ksegs_enabled()) {
30411 env->CP0_EBase |= 0x40000000;
30412 } else {
30413 env->CP0_EBase |= (int32_t)0x80000000;
30414 }
30415 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
30416 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
30417 }
30418 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
30419 0x3ff : 0xff;
30420 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30421 /*
30422 * Vectored interrupts not implemented, timer on int 7,
30423 * no performance counters.
30424 */
30425 env->CP0_IntCtl = 0xe0000000;
30426 {
30427 int i;
30428
30429 for (i = 0; i < 7; i++) {
30430 env->CP0_WatchLo[i] = 0;
30431 env->CP0_WatchHi[i] = 0x80000000;
30432 }
30433 env->CP0_WatchLo[7] = 0;
30434 env->CP0_WatchHi[7] = 0;
30435 }
30436 /* Count register increments in debug mode, EJTAG version 1 */
30437 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30438
30439 cpu_mips_store_count(env, 1);
30440
30441 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30442 int i;
30443
30444 /* Only TC0 on VPE 0 starts as active. */
30445 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30446 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30447 env->tcs[i].CP0_TCHalt = 1;
30448 }
30449 env->active_tc.CP0_TCHalt = 1;
30450 cs->halted = 1;
30451
30452 if (cs->cpu_index == 0) {
30453 /* VPE0 starts up enabled. */
30454 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30455 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30456
30457 /* TC0 starts up unhalted. */
30458 cs->halted = 0;
30459 env->active_tc.CP0_TCHalt = 0;
30460 env->tcs[0].CP0_TCHalt = 0;
30461 /* With thread 0 active. */
30462 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30463 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30464 }
30465 }
30466
30467 /*
30468 * Configure default legacy segmentation control. We use this regardless of
30469 * whether segmentation control is presented to the guest.
30470 */
30471 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30472 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
30473 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30474 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30475 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30476 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30477 (2 << CP0SC_C);
30478 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30479 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30480 (3 << CP0SC_C)) << 16;
30481 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30482 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30483 (1 << CP0SC_EU) | (2 << CP0SC_C);
30484 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30485 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30486 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30487 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30488 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30489 #endif
30490 if ((env->insn_flags & ISA_MIPS32R6) &&
30491 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30492 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30493 env->CP0_Status |= (1 << CP0St_FR);
30494 }
30495
30496 if (env->insn_flags & ISA_MIPS32R6) {
30497 /* PTW = 1 */
30498 env->CP0_PWSize = 0x40;
30499 /* GDI = 12 */
30500 /* UDI = 12 */
30501 /* MDI = 12 */
30502 /* PRI = 12 */
30503 /* PTEI = 2 */
30504 env->CP0_PWField = 0x0C30C302;
30505 } else {
30506 /* GDI = 0 */
30507 /* UDI = 0 */
30508 /* MDI = 0 */
30509 /* PRI = 0 */
30510 /* PTEI = 2 */
30511 env->CP0_PWField = 0x02;
30512 }
30513
30514 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30515 /* microMIPS on reset when Config3.ISA is 3 */
30516 env->hflags |= MIPS_HFLAG_M16;
30517 }
30518
30519 /* MSA */
30520 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30521 msa_reset(env);
30522 }
30523
30524 compute_hflags(env);
30525 restore_fp_status(env);
30526 restore_pamask(env);
30527 cs->exception_index = EXCP_NONE;
30528
30529 if (semihosting_get_argc()) {
30530 /* UHI interface can be used to obtain argc and argv */
30531 env->active_tc.gpr[4] = -1;
30532 }
30533 }
30534
30535 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30536 target_ulong *data)
30537 {
30538 env->active_tc.PC = data[0];
30539 env->hflags &= ~MIPS_HFLAG_BMASK;
30540 env->hflags |= data[1];
30541 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30542 case MIPS_HFLAG_BR:
30543 break;
30544 case MIPS_HFLAG_BC:
30545 case MIPS_HFLAG_BL:
30546 case MIPS_HFLAG_B:
30547 env->btarget = data[2];
30548 break;
30549 }
30550 }