2 * MIPS emulation for QEMU - main translation routines
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)
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.
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.
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/>.
24 #include "qemu/osdep.h"
27 #include "disas/disas.h"
28 #include "exec/exec-all.h"
29 #include "tcg/tcg-op.h"
30 #include "exec/cpu_ldst.h"
31 #include "hw/mips/cpudevs.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
35 #include "hw/semihosting/semihost.h"
37 #include "target/mips/trace.h"
38 #include "trace-tcg.h"
39 #include "exec/translator.h"
41 #include "qemu/qemu-print.h"
43 #define MIPS_DEBUG_DISAS 0
45 /* MIPS major opcodes */
46 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
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 */
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),
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 */
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),
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)))
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),
164 /* Instructions determined by bits 16 ... 20 */
165 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
166 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
169 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
172 /* MIPS special opcodes */
173 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
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
,
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
,
226 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
227 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
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
,
244 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
245 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
247 OPC_MOVCI
= 0x01 | OPC_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
,
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
,
263 * R6 Multiply and Divide instructions have the same opcode
264 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
266 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
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),
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),
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
,
293 OPC_LSA
= 0x05 | OPC_SPECIAL
,
294 OPC_DLSA
= 0x15 | OPC_SPECIAL
,
297 /* Multiplication variants of the vr54xx. */
298 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
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
,
317 /* REGIMM (rt field) opcodes */
318 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
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
,
338 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
339 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
342 /* Special2 opcodes */
343 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
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
,
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
,
366 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
367 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
368 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
369 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
371 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
374 /* Special3 opcodes */
375 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
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 OPC_GINV
= 0x3D | OPC_SPECIAL3
,
394 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
395 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
396 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
397 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
398 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
399 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
400 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
401 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
402 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
403 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
404 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
405 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
408 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
409 /* MIPS DSP Arithmetic */
410 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
411 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
412 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
413 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
414 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
415 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
416 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
417 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
418 /* MIPS DSP GPR-Based Shift Sub-class */
419 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
420 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
421 /* MIPS DSP Multiply Sub-class insns */
422 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
423 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
424 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
425 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
426 /* DSP Bit/Manipulation Sub-class */
427 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
428 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
429 /* MIPS DSP Append Sub-class */
430 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
431 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
432 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
433 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
434 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
437 OPC_LWLE
= 0x19 | OPC_SPECIAL3
,
438 OPC_LWRE
= 0x1A | OPC_SPECIAL3
,
439 OPC_CACHEE
= 0x1B | OPC_SPECIAL3
,
440 OPC_SBE
= 0x1C | OPC_SPECIAL3
,
441 OPC_SHE
= 0x1D | OPC_SPECIAL3
,
442 OPC_SCE
= 0x1E | OPC_SPECIAL3
,
443 OPC_SWE
= 0x1F | OPC_SPECIAL3
,
444 OPC_SWLE
= 0x21 | OPC_SPECIAL3
,
445 OPC_SWRE
= 0x22 | OPC_SPECIAL3
,
446 OPC_PREFE
= 0x23 | OPC_SPECIAL3
,
447 OPC_LBUE
= 0x28 | OPC_SPECIAL3
,
448 OPC_LHUE
= 0x29 | OPC_SPECIAL3
,
449 OPC_LBE
= 0x2C | OPC_SPECIAL3
,
450 OPC_LHE
= 0x2D | OPC_SPECIAL3
,
451 OPC_LLE
= 0x2E | OPC_SPECIAL3
,
452 OPC_LWE
= 0x2F | OPC_SPECIAL3
,
455 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
456 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
457 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
458 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
459 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
460 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
464 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
467 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
468 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
469 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
470 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp (010.00 to 010.11) */
471 OPC_ALIGN_1
= (0x09 << 6) | OPC_BSHFL
,
472 OPC_ALIGN_2
= (0x0A << 6) | OPC_BSHFL
,
473 OPC_ALIGN_3
= (0x0B << 6) | OPC_BSHFL
,
474 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
478 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
481 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
482 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
483 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp (01.000 to 01.111) */
484 OPC_DALIGN_1
= (0x09 << 6) | OPC_DBSHFL
,
485 OPC_DALIGN_2
= (0x0A << 6) | OPC_DBSHFL
,
486 OPC_DALIGN_3
= (0x0B << 6) | OPC_DBSHFL
,
487 OPC_DALIGN_4
= (0x0C << 6) | OPC_DBSHFL
,
488 OPC_DALIGN_5
= (0x0D << 6) | OPC_DBSHFL
,
489 OPC_DALIGN_6
= (0x0E << 6) | OPC_DBSHFL
,
490 OPC_DALIGN_7
= (0x0F << 6) | OPC_DBSHFL
,
491 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
494 /* MIPS DSP REGIMM opcodes */
496 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
497 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
500 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
503 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
504 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
505 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
506 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
509 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
511 /* MIPS DSP Arithmetic Sub-class */
512 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
513 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
514 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
515 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
516 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
517 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
518 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
519 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
520 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
521 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
522 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
523 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
524 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
525 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
526 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
527 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
528 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
529 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
530 /* MIPS DSP Multiply Sub-class insns */
531 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
532 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
533 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
534 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
535 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
536 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
539 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
540 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
542 /* MIPS DSP Arithmetic Sub-class */
543 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
544 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
545 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
546 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
547 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
548 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
549 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
550 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
551 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
552 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
553 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
554 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
555 /* MIPS DSP Multiply Sub-class insns */
556 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
557 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
558 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
559 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
562 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
564 /* MIPS DSP Arithmetic Sub-class */
565 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
566 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
567 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
568 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
569 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
570 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
571 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
572 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
573 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
574 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
575 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
576 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
577 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
578 /* DSP Bit/Manipulation Sub-class */
579 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
580 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
581 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
582 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
583 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
586 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
588 /* MIPS DSP Arithmetic Sub-class */
589 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
590 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
591 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
592 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
593 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
594 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
595 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
596 /* DSP Compare-Pick Sub-class */
597 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
598 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
599 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
600 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
601 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
602 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
603 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
604 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
605 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
606 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
607 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
608 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
609 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
610 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
611 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
614 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
616 /* MIPS DSP GPR-Based Shift Sub-class */
617 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
618 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
619 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
620 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
621 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
622 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
623 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
624 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
625 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
626 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
627 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
628 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
629 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
630 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
631 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
632 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
633 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
634 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
635 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
636 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
637 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
638 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
641 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
643 /* MIPS DSP Multiply Sub-class insns */
644 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
645 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
646 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
647 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
648 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
649 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
650 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
651 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
652 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
653 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
654 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
655 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
656 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
657 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
658 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
659 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
660 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
661 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
662 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
663 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
664 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
665 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
668 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Bit/Manipulation Sub-class */
671 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
674 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
676 /* MIPS DSP Append Sub-class */
677 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
678 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
679 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
682 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
684 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
685 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
686 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
687 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
688 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
689 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
690 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
691 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
692 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
693 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
694 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
695 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
696 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
697 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
698 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
699 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
700 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
701 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
704 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
706 /* MIPS DSP Arithmetic Sub-class */
707 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
708 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
709 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
710 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
711 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
712 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
713 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
714 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
715 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
716 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
717 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
718 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
719 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
720 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
721 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
722 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
723 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
724 /* DSP Bit/Manipulation Sub-class */
725 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
726 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
727 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
728 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
729 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
730 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
733 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
735 /* MIPS DSP Multiply Sub-class insns */
736 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
737 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
738 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
739 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
740 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
741 /* MIPS DSP Arithmetic Sub-class */
742 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
743 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
744 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
745 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
746 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
747 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
748 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
749 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
750 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
751 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
752 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
753 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
754 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
755 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
756 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
757 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
758 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
759 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
760 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
761 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
762 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
765 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
767 /* DSP Compare-Pick Sub-class */
768 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
769 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
770 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
771 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
772 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
773 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
774 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
775 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
776 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
777 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
778 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
779 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
780 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
781 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
782 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
783 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
784 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
785 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
786 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
787 /* MIPS DSP Arithmetic Sub-class */
788 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
789 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
790 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
791 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
792 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
793 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
794 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
795 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
798 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
800 /* DSP Append Sub-class */
801 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
802 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
803 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
804 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
807 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
809 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
810 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
811 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
812 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
813 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
814 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
815 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
816 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
817 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
818 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
819 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
820 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
821 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
822 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
823 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
824 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
825 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
826 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
827 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
828 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
829 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
830 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
833 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
835 /* DSP Bit/Manipulation Sub-class */
836 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
839 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
841 /* MIPS DSP Multiply Sub-class insns */
842 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
843 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
844 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
845 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
846 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
847 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
848 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
849 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
850 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
851 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
852 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
853 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
854 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
855 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
856 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
857 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
858 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
859 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
860 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
861 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
862 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
863 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
864 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
865 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
866 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
867 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
870 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
872 /* MIPS DSP GPR-Based Shift Sub-class */
873 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
874 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
875 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
876 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
877 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
878 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
879 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
880 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
881 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
882 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
883 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
884 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
885 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
886 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
887 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
888 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
889 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
890 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
891 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
892 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
893 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
894 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
895 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
896 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
897 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
898 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
901 /* Coprocessor 0 (rs field) */
902 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
905 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
906 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
907 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
908 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
909 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
910 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
911 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
912 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
913 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
914 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
915 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
916 OPC_C0
= (0x10 << 21) | OPC_CP0
,
917 OPC_C0_1
= (0x11 << 21) | OPC_CP0
,
918 OPC_C0_2
= (0x12 << 21) | OPC_CP0
,
919 OPC_C0_3
= (0x13 << 21) | OPC_CP0
,
920 OPC_C0_4
= (0x14 << 21) | OPC_CP0
,
921 OPC_C0_5
= (0x15 << 21) | OPC_CP0
,
922 OPC_C0_6
= (0x16 << 21) | OPC_CP0
,
923 OPC_C0_7
= (0x17 << 21) | OPC_CP0
,
924 OPC_C0_8
= (0x18 << 21) | OPC_CP0
,
925 OPC_C0_9
= (0x19 << 21) | OPC_CP0
,
926 OPC_C0_A
= (0x1A << 21) | OPC_CP0
,
927 OPC_C0_B
= (0x1B << 21) | OPC_CP0
,
928 OPC_C0_C
= (0x1C << 21) | OPC_CP0
,
929 OPC_C0_D
= (0x1D << 21) | OPC_CP0
,
930 OPC_C0_E
= (0x1E << 21) | OPC_CP0
,
931 OPC_C0_F
= (0x1F << 21) | OPC_CP0
,
935 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
938 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
939 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
940 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
941 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
942 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
943 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
944 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
945 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
948 /* Coprocessor 0 (with rs == C0) */
949 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
952 OPC_TLBR
= 0x01 | OPC_C0
,
953 OPC_TLBWI
= 0x02 | OPC_C0
,
954 OPC_TLBINV
= 0x03 | OPC_C0
,
955 OPC_TLBINVF
= 0x04 | OPC_C0
,
956 OPC_TLBWR
= 0x06 | OPC_C0
,
957 OPC_TLBP
= 0x08 | OPC_C0
,
958 OPC_RFE
= 0x10 | OPC_C0
,
959 OPC_ERET
= 0x18 | OPC_C0
,
960 OPC_DERET
= 0x1F | OPC_C0
,
961 OPC_WAIT
= 0x20 | OPC_C0
,
964 /* Coprocessor 1 (rs field) */
965 #define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
967 /* Values for the fmt field in FP instructions */
969 /* 0 - 15 are reserved */
970 FMT_S
= 16, /* single fp */
971 FMT_D
= 17, /* double fp */
972 FMT_E
= 18, /* extended fp */
973 FMT_Q
= 19, /* quad fp */
974 FMT_W
= 20, /* 32-bit fixed */
975 FMT_L
= 21, /* 64-bit fixed */
976 FMT_PS
= 22, /* paired single fp */
977 /* 23 - 31 are reserved */
981 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
982 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
983 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
984 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
985 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
986 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
987 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
988 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
989 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
990 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
991 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
992 OPC_BZ_V
= (0x0B << 21) | OPC_CP1
,
993 OPC_BNZ_V
= (0x0F << 21) | OPC_CP1
,
994 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
995 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
996 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
997 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
998 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
999 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
1000 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
1001 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
1002 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
1003 OPC_BZ_B
= (0x18 << 21) | OPC_CP1
,
1004 OPC_BZ_H
= (0x19 << 21) | OPC_CP1
,
1005 OPC_BZ_W
= (0x1A << 21) | OPC_CP1
,
1006 OPC_BZ_D
= (0x1B << 21) | OPC_CP1
,
1007 OPC_BNZ_B
= (0x1C << 21) | OPC_CP1
,
1008 OPC_BNZ_H
= (0x1D << 21) | OPC_CP1
,
1009 OPC_BNZ_W
= (0x1E << 21) | OPC_CP1
,
1010 OPC_BNZ_D
= (0x1F << 21) | OPC_CP1
,
1013 #define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F))
1014 #define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16)))
1017 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
1018 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
1019 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
1020 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
1024 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
1025 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
1029 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
1030 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
1033 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1036 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
1037 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
1038 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
1039 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
1040 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
1041 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
1042 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
1043 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
1044 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
1045 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1046 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1049 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1052 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1053 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1054 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1055 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1056 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1057 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1058 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1059 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1061 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1062 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1063 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1064 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1065 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1066 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1067 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1068 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1070 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1071 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1072 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1073 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1074 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1075 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1076 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1077 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1079 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1080 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1081 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1082 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1083 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1084 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1085 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1086 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1088 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1089 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1090 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1091 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1092 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1093 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1095 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1096 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1097 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1098 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1099 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1100 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1102 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1103 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1104 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1105 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1106 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1107 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1109 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1110 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1111 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1112 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1113 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1114 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1116 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1117 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1118 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1119 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1120 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1121 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1123 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1124 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1125 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1126 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1127 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1128 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1130 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1131 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1132 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1133 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1134 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1135 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1137 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1138 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1139 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1140 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1141 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1142 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1146 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1149 OPC_LWXC1
= 0x00 | OPC_CP3
,
1150 OPC_LDXC1
= 0x01 | OPC_CP3
,
1151 OPC_LUXC1
= 0x05 | OPC_CP3
,
1152 OPC_SWXC1
= 0x08 | OPC_CP3
,
1153 OPC_SDXC1
= 0x09 | OPC_CP3
,
1154 OPC_SUXC1
= 0x0D | OPC_CP3
,
1155 OPC_PREFX
= 0x0F | OPC_CP3
,
1156 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1157 OPC_MADD_S
= 0x20 | OPC_CP3
,
1158 OPC_MADD_D
= 0x21 | OPC_CP3
,
1159 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1160 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1161 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1162 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1163 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1164 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1165 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1166 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1167 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1168 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1172 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1174 OPC_MSA_I8_00
= 0x00 | OPC_MSA
,
1175 OPC_MSA_I8_01
= 0x01 | OPC_MSA
,
1176 OPC_MSA_I8_02
= 0x02 | OPC_MSA
,
1177 OPC_MSA_I5_06
= 0x06 | OPC_MSA
,
1178 OPC_MSA_I5_07
= 0x07 | OPC_MSA
,
1179 OPC_MSA_BIT_09
= 0x09 | OPC_MSA
,
1180 OPC_MSA_BIT_0A
= 0x0A | OPC_MSA
,
1181 OPC_MSA_3R_0D
= 0x0D | OPC_MSA
,
1182 OPC_MSA_3R_0E
= 0x0E | OPC_MSA
,
1183 OPC_MSA_3R_0F
= 0x0F | OPC_MSA
,
1184 OPC_MSA_3R_10
= 0x10 | OPC_MSA
,
1185 OPC_MSA_3R_11
= 0x11 | OPC_MSA
,
1186 OPC_MSA_3R_12
= 0x12 | OPC_MSA
,
1187 OPC_MSA_3R_13
= 0x13 | OPC_MSA
,
1188 OPC_MSA_3R_14
= 0x14 | OPC_MSA
,
1189 OPC_MSA_3R_15
= 0x15 | OPC_MSA
,
1190 OPC_MSA_ELM
= 0x19 | OPC_MSA
,
1191 OPC_MSA_3RF_1A
= 0x1A | OPC_MSA
,
1192 OPC_MSA_3RF_1B
= 0x1B | OPC_MSA
,
1193 OPC_MSA_3RF_1C
= 0x1C | OPC_MSA
,
1194 OPC_MSA_VEC
= 0x1E | OPC_MSA
,
1196 /* MI10 instruction */
1197 OPC_LD_B
= (0x20) | OPC_MSA
,
1198 OPC_LD_H
= (0x21) | OPC_MSA
,
1199 OPC_LD_W
= (0x22) | OPC_MSA
,
1200 OPC_LD_D
= (0x23) | OPC_MSA
,
1201 OPC_ST_B
= (0x24) | OPC_MSA
,
1202 OPC_ST_H
= (0x25) | OPC_MSA
,
1203 OPC_ST_W
= (0x26) | OPC_MSA
,
1204 OPC_ST_D
= (0x27) | OPC_MSA
,
1208 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1209 OPC_ADDVI_df
= (0x0 << 23) | OPC_MSA_I5_06
,
1210 OPC_CEQI_df
= (0x0 << 23) | OPC_MSA_I5_07
,
1211 OPC_SUBVI_df
= (0x1 << 23) | OPC_MSA_I5_06
,
1212 OPC_MAXI_S_df
= (0x2 << 23) | OPC_MSA_I5_06
,
1213 OPC_CLTI_S_df
= (0x2 << 23) | OPC_MSA_I5_07
,
1214 OPC_MAXI_U_df
= (0x3 << 23) | OPC_MSA_I5_06
,
1215 OPC_CLTI_U_df
= (0x3 << 23) | OPC_MSA_I5_07
,
1216 OPC_MINI_S_df
= (0x4 << 23) | OPC_MSA_I5_06
,
1217 OPC_CLEI_S_df
= (0x4 << 23) | OPC_MSA_I5_07
,
1218 OPC_MINI_U_df
= (0x5 << 23) | OPC_MSA_I5_06
,
1219 OPC_CLEI_U_df
= (0x5 << 23) | OPC_MSA_I5_07
,
1220 OPC_LDI_df
= (0x6 << 23) | OPC_MSA_I5_07
,
1222 /* I8 instruction */
1223 OPC_ANDI_B
= (0x0 << 24) | OPC_MSA_I8_00
,
1224 OPC_BMNZI_B
= (0x0 << 24) | OPC_MSA_I8_01
,
1225 OPC_SHF_B
= (0x0 << 24) | OPC_MSA_I8_02
,
1226 OPC_ORI_B
= (0x1 << 24) | OPC_MSA_I8_00
,
1227 OPC_BMZI_B
= (0x1 << 24) | OPC_MSA_I8_01
,
1228 OPC_SHF_H
= (0x1 << 24) | OPC_MSA_I8_02
,
1229 OPC_NORI_B
= (0x2 << 24) | OPC_MSA_I8_00
,
1230 OPC_BSELI_B
= (0x2 << 24) | OPC_MSA_I8_01
,
1231 OPC_SHF_W
= (0x2 << 24) | OPC_MSA_I8_02
,
1232 OPC_XORI_B
= (0x3 << 24) | OPC_MSA_I8_00
,
1234 /* VEC/2R/2RF instruction */
1235 OPC_AND_V
= (0x00 << 21) | OPC_MSA_VEC
,
1236 OPC_OR_V
= (0x01 << 21) | OPC_MSA_VEC
,
1237 OPC_NOR_V
= (0x02 << 21) | OPC_MSA_VEC
,
1238 OPC_XOR_V
= (0x03 << 21) | OPC_MSA_VEC
,
1239 OPC_BMNZ_V
= (0x04 << 21) | OPC_MSA_VEC
,
1240 OPC_BMZ_V
= (0x05 << 21) | OPC_MSA_VEC
,
1241 OPC_BSEL_V
= (0x06 << 21) | OPC_MSA_VEC
,
1243 OPC_MSA_2R
= (0x18 << 21) | OPC_MSA_VEC
,
1244 OPC_MSA_2RF
= (0x19 << 21) | OPC_MSA_VEC
,
1246 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1247 OPC_FILL_df
= (0x00 << 18) | OPC_MSA_2R
,
1248 OPC_PCNT_df
= (0x01 << 18) | OPC_MSA_2R
,
1249 OPC_NLOC_df
= (0x02 << 18) | OPC_MSA_2R
,
1250 OPC_NLZC_df
= (0x03 << 18) | OPC_MSA_2R
,
1252 /* 2RF instruction df(bit 16) = _w, _d */
1253 OPC_FCLASS_df
= (0x00 << 17) | OPC_MSA_2RF
,
1254 OPC_FTRUNC_S_df
= (0x01 << 17) | OPC_MSA_2RF
,
1255 OPC_FTRUNC_U_df
= (0x02 << 17) | OPC_MSA_2RF
,
1256 OPC_FSQRT_df
= (0x03 << 17) | OPC_MSA_2RF
,
1257 OPC_FRSQRT_df
= (0x04 << 17) | OPC_MSA_2RF
,
1258 OPC_FRCP_df
= (0x05 << 17) | OPC_MSA_2RF
,
1259 OPC_FRINT_df
= (0x06 << 17) | OPC_MSA_2RF
,
1260 OPC_FLOG2_df
= (0x07 << 17) | OPC_MSA_2RF
,
1261 OPC_FEXUPL_df
= (0x08 << 17) | OPC_MSA_2RF
,
1262 OPC_FEXUPR_df
= (0x09 << 17) | OPC_MSA_2RF
,
1263 OPC_FFQL_df
= (0x0A << 17) | OPC_MSA_2RF
,
1264 OPC_FFQR_df
= (0x0B << 17) | OPC_MSA_2RF
,
1265 OPC_FTINT_S_df
= (0x0C << 17) | OPC_MSA_2RF
,
1266 OPC_FTINT_U_df
= (0x0D << 17) | OPC_MSA_2RF
,
1267 OPC_FFINT_S_df
= (0x0E << 17) | OPC_MSA_2RF
,
1268 OPC_FFINT_U_df
= (0x0F << 17) | OPC_MSA_2RF
,
1270 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1271 OPC_SLL_df
= (0x0 << 23) | OPC_MSA_3R_0D
,
1272 OPC_ADDV_df
= (0x0 << 23) | OPC_MSA_3R_0E
,
1273 OPC_CEQ_df
= (0x0 << 23) | OPC_MSA_3R_0F
,
1274 OPC_ADD_A_df
= (0x0 << 23) | OPC_MSA_3R_10
,
1275 OPC_SUBS_S_df
= (0x0 << 23) | OPC_MSA_3R_11
,
1276 OPC_MULV_df
= (0x0 << 23) | OPC_MSA_3R_12
,
1277 OPC_DOTP_S_df
= (0x0 << 23) | OPC_MSA_3R_13
,
1278 OPC_SLD_df
= (0x0 << 23) | OPC_MSA_3R_14
,
1279 OPC_VSHF_df
= (0x0 << 23) | OPC_MSA_3R_15
,
1280 OPC_SRA_df
= (0x1 << 23) | OPC_MSA_3R_0D
,
1281 OPC_SUBV_df
= (0x1 << 23) | OPC_MSA_3R_0E
,
1282 OPC_ADDS_A_df
= (0x1 << 23) | OPC_MSA_3R_10
,
1283 OPC_SUBS_U_df
= (0x1 << 23) | OPC_MSA_3R_11
,
1284 OPC_MADDV_df
= (0x1 << 23) | OPC_MSA_3R_12
,
1285 OPC_DOTP_U_df
= (0x1 << 23) | OPC_MSA_3R_13
,
1286 OPC_SPLAT_df
= (0x1 << 23) | OPC_MSA_3R_14
,
1287 OPC_SRAR_df
= (0x1 << 23) | OPC_MSA_3R_15
,
1288 OPC_SRL_df
= (0x2 << 23) | OPC_MSA_3R_0D
,
1289 OPC_MAX_S_df
= (0x2 << 23) | OPC_MSA_3R_0E
,
1290 OPC_CLT_S_df
= (0x2 << 23) | OPC_MSA_3R_0F
,
1291 OPC_ADDS_S_df
= (0x2 << 23) | OPC_MSA_3R_10
,
1292 OPC_SUBSUS_U_df
= (0x2 << 23) | OPC_MSA_3R_11
,
1293 OPC_MSUBV_df
= (0x2 << 23) | OPC_MSA_3R_12
,
1294 OPC_DPADD_S_df
= (0x2 << 23) | OPC_MSA_3R_13
,
1295 OPC_PCKEV_df
= (0x2 << 23) | OPC_MSA_3R_14
,
1296 OPC_SRLR_df
= (0x2 << 23) | OPC_MSA_3R_15
,
1297 OPC_BCLR_df
= (0x3 << 23) | OPC_MSA_3R_0D
,
1298 OPC_MAX_U_df
= (0x3 << 23) | OPC_MSA_3R_0E
,
1299 OPC_CLT_U_df
= (0x3 << 23) | OPC_MSA_3R_0F
,
1300 OPC_ADDS_U_df
= (0x3 << 23) | OPC_MSA_3R_10
,
1301 OPC_SUBSUU_S_df
= (0x3 << 23) | OPC_MSA_3R_11
,
1302 OPC_DPADD_U_df
= (0x3 << 23) | OPC_MSA_3R_13
,
1303 OPC_PCKOD_df
= (0x3 << 23) | OPC_MSA_3R_14
,
1304 OPC_BSET_df
= (0x4 << 23) | OPC_MSA_3R_0D
,
1305 OPC_MIN_S_df
= (0x4 << 23) | OPC_MSA_3R_0E
,
1306 OPC_CLE_S_df
= (0x4 << 23) | OPC_MSA_3R_0F
,
1307 OPC_AVE_S_df
= (0x4 << 23) | OPC_MSA_3R_10
,
1308 OPC_ASUB_S_df
= (0x4 << 23) | OPC_MSA_3R_11
,
1309 OPC_DIV_S_df
= (0x4 << 23) | OPC_MSA_3R_12
,
1310 OPC_DPSUB_S_df
= (0x4 << 23) | OPC_MSA_3R_13
,
1311 OPC_ILVL_df
= (0x4 << 23) | OPC_MSA_3R_14
,
1312 OPC_HADD_S_df
= (0x4 << 23) | OPC_MSA_3R_15
,
1313 OPC_BNEG_df
= (0x5 << 23) | OPC_MSA_3R_0D
,
1314 OPC_MIN_U_df
= (0x5 << 23) | OPC_MSA_3R_0E
,
1315 OPC_CLE_U_df
= (0x5 << 23) | OPC_MSA_3R_0F
,
1316 OPC_AVE_U_df
= (0x5 << 23) | OPC_MSA_3R_10
,
1317 OPC_ASUB_U_df
= (0x5 << 23) | OPC_MSA_3R_11
,
1318 OPC_DIV_U_df
= (0x5 << 23) | OPC_MSA_3R_12
,
1319 OPC_DPSUB_U_df
= (0x5 << 23) | OPC_MSA_3R_13
,
1320 OPC_ILVR_df
= (0x5 << 23) | OPC_MSA_3R_14
,
1321 OPC_HADD_U_df
= (0x5 << 23) | OPC_MSA_3R_15
,
1322 OPC_BINSL_df
= (0x6 << 23) | OPC_MSA_3R_0D
,
1323 OPC_MAX_A_df
= (0x6 << 23) | OPC_MSA_3R_0E
,
1324 OPC_AVER_S_df
= (0x6 << 23) | OPC_MSA_3R_10
,
1325 OPC_MOD_S_df
= (0x6 << 23) | OPC_MSA_3R_12
,
1326 OPC_ILVEV_df
= (0x6 << 23) | OPC_MSA_3R_14
,
1327 OPC_HSUB_S_df
= (0x6 << 23) | OPC_MSA_3R_15
,
1328 OPC_BINSR_df
= (0x7 << 23) | OPC_MSA_3R_0D
,
1329 OPC_MIN_A_df
= (0x7 << 23) | OPC_MSA_3R_0E
,
1330 OPC_AVER_U_df
= (0x7 << 23) | OPC_MSA_3R_10
,
1331 OPC_MOD_U_df
= (0x7 << 23) | OPC_MSA_3R_12
,
1332 OPC_ILVOD_df
= (0x7 << 23) | OPC_MSA_3R_14
,
1333 OPC_HSUB_U_df
= (0x7 << 23) | OPC_MSA_3R_15
,
1335 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1336 OPC_SLDI_df
= (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1337 OPC_CTCMSA
= (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1338 OPC_SPLATI_df
= (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1339 OPC_CFCMSA
= (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1340 OPC_COPY_S_df
= (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1341 OPC_MOVE_V
= (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1342 OPC_COPY_U_df
= (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1343 OPC_INSERT_df
= (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1344 OPC_INSVE_df
= (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1346 /* 3RF instruction _df(bit 21) = _w, _d */
1347 OPC_FCAF_df
= (0x0 << 22) | OPC_MSA_3RF_1A
,
1348 OPC_FADD_df
= (0x0 << 22) | OPC_MSA_3RF_1B
,
1349 OPC_FCUN_df
= (0x1 << 22) | OPC_MSA_3RF_1A
,
1350 OPC_FSUB_df
= (0x1 << 22) | OPC_MSA_3RF_1B
,
1351 OPC_FCOR_df
= (0x1 << 22) | OPC_MSA_3RF_1C
,
1352 OPC_FCEQ_df
= (0x2 << 22) | OPC_MSA_3RF_1A
,
1353 OPC_FMUL_df
= (0x2 << 22) | OPC_MSA_3RF_1B
,
1354 OPC_FCUNE_df
= (0x2 << 22) | OPC_MSA_3RF_1C
,
1355 OPC_FCUEQ_df
= (0x3 << 22) | OPC_MSA_3RF_1A
,
1356 OPC_FDIV_df
= (0x3 << 22) | OPC_MSA_3RF_1B
,
1357 OPC_FCNE_df
= (0x3 << 22) | OPC_MSA_3RF_1C
,
1358 OPC_FCLT_df
= (0x4 << 22) | OPC_MSA_3RF_1A
,
1359 OPC_FMADD_df
= (0x4 << 22) | OPC_MSA_3RF_1B
,
1360 OPC_MUL_Q_df
= (0x4 << 22) | OPC_MSA_3RF_1C
,
1361 OPC_FCULT_df
= (0x5 << 22) | OPC_MSA_3RF_1A
,
1362 OPC_FMSUB_df
= (0x5 << 22) | OPC_MSA_3RF_1B
,
1363 OPC_MADD_Q_df
= (0x5 << 22) | OPC_MSA_3RF_1C
,
1364 OPC_FCLE_df
= (0x6 << 22) | OPC_MSA_3RF_1A
,
1365 OPC_MSUB_Q_df
= (0x6 << 22) | OPC_MSA_3RF_1C
,
1366 OPC_FCULE_df
= (0x7 << 22) | OPC_MSA_3RF_1A
,
1367 OPC_FEXP2_df
= (0x7 << 22) | OPC_MSA_3RF_1B
,
1368 OPC_FSAF_df
= (0x8 << 22) | OPC_MSA_3RF_1A
,
1369 OPC_FEXDO_df
= (0x8 << 22) | OPC_MSA_3RF_1B
,
1370 OPC_FSUN_df
= (0x9 << 22) | OPC_MSA_3RF_1A
,
1371 OPC_FSOR_df
= (0x9 << 22) | OPC_MSA_3RF_1C
,
1372 OPC_FSEQ_df
= (0xA << 22) | OPC_MSA_3RF_1A
,
1373 OPC_FTQ_df
= (0xA << 22) | OPC_MSA_3RF_1B
,
1374 OPC_FSUNE_df
= (0xA << 22) | OPC_MSA_3RF_1C
,
1375 OPC_FSUEQ_df
= (0xB << 22) | OPC_MSA_3RF_1A
,
1376 OPC_FSNE_df
= (0xB << 22) | OPC_MSA_3RF_1C
,
1377 OPC_FSLT_df
= (0xC << 22) | OPC_MSA_3RF_1A
,
1378 OPC_FMIN_df
= (0xC << 22) | OPC_MSA_3RF_1B
,
1379 OPC_MULR_Q_df
= (0xC << 22) | OPC_MSA_3RF_1C
,
1380 OPC_FSULT_df
= (0xD << 22) | OPC_MSA_3RF_1A
,
1381 OPC_FMIN_A_df
= (0xD << 22) | OPC_MSA_3RF_1B
,
1382 OPC_MADDR_Q_df
= (0xD << 22) | OPC_MSA_3RF_1C
,
1383 OPC_FSLE_df
= (0xE << 22) | OPC_MSA_3RF_1A
,
1384 OPC_FMAX_df
= (0xE << 22) | OPC_MSA_3RF_1B
,
1385 OPC_MSUBR_Q_df
= (0xE << 22) | OPC_MSA_3RF_1C
,
1386 OPC_FSULE_df
= (0xF << 22) | OPC_MSA_3RF_1A
,
1387 OPC_FMAX_A_df
= (0xF << 22) | OPC_MSA_3RF_1B
,
1389 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1390 OPC_SLLI_df
= (0x0 << 23) | OPC_MSA_BIT_09
,
1391 OPC_SAT_S_df
= (0x0 << 23) | OPC_MSA_BIT_0A
,
1392 OPC_SRAI_df
= (0x1 << 23) | OPC_MSA_BIT_09
,
1393 OPC_SAT_U_df
= (0x1 << 23) | OPC_MSA_BIT_0A
,
1394 OPC_SRLI_df
= (0x2 << 23) | OPC_MSA_BIT_09
,
1395 OPC_SRARI_df
= (0x2 << 23) | OPC_MSA_BIT_0A
,
1396 OPC_BCLRI_df
= (0x3 << 23) | OPC_MSA_BIT_09
,
1397 OPC_SRLRI_df
= (0x3 << 23) | OPC_MSA_BIT_0A
,
1398 OPC_BSETI_df
= (0x4 << 23) | OPC_MSA_BIT_09
,
1399 OPC_BNEGI_df
= (0x5 << 23) | OPC_MSA_BIT_09
,
1400 OPC_BINSLI_df
= (0x6 << 23) | OPC_MSA_BIT_09
,
1401 OPC_BINSRI_df
= (0x7 << 23) | OPC_MSA_BIT_09
,
1407 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1408 * ============================================
1411 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1412 * instructions set. It is designed to fit the needs of signal, graphical and
1413 * video processing applications. MXU instruction set is used in Xburst family
1414 * of microprocessors by Ingenic.
1416 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1417 * the control register.
1420 * The notation used in MXU assembler mnemonics
1421 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1423 * Register operands:
1425 * XRa, XRb, XRc, XRd - MXU registers
1426 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1428 * Non-register operands:
1430 * aptn1 - 1-bit accumulate add/subtract pattern
1431 * aptn2 - 2-bit accumulate add/subtract pattern
1432 * eptn2 - 2-bit execute add/subtract pattern
1433 * optn2 - 2-bit operand pattern
1434 * optn3 - 3-bit operand pattern
1435 * sft4 - 4-bit shift amount
1436 * strd2 - 2-bit stride amount
1440 * Level of parallelism: Operand size:
1441 * S - single operation at a time 32 - word
1442 * D - two operations in parallel 16 - half word
1443 * Q - four operations in parallel 8 - byte
1447 * ADD - Add or subtract
1448 * ADDC - Add with carry-in
1450 * ASUM - Sum together then accumulate (add or subtract)
1451 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1452 * AVG - Average between 2 operands
1453 * ABD - Absolute difference
1455 * AND - Logical bitwise 'and' operation
1457 * EXTR - Extract bits
1458 * I2M - Move from GPR register to MXU register
1459 * LDD - Load data from memory to XRF
1460 * LDI - Load data from memory to XRF (and increase the address base)
1461 * LUI - Load unsigned immediate
1463 * MULU - Unsigned multiply
1464 * MADD - 64-bit operand add 32x32 product
1465 * MSUB - 64-bit operand subtract 32x32 product
1466 * MAC - Multiply and accumulate (add or subtract)
1467 * MAD - Multiply and add or subtract
1468 * MAX - Maximum between 2 operands
1469 * MIN - Minimum between 2 operands
1470 * M2I - Move from MXU register to GPR register
1471 * MOVZ - Move if zero
1472 * MOVN - Move if non-zero
1473 * NOR - Logical bitwise 'nor' operation
1474 * OR - Logical bitwise 'or' operation
1475 * STD - Store data from XRF to memory
1476 * SDI - Store data from XRF to memory (and increase the address base)
1477 * SLT - Set of less than comparison
1478 * SAD - Sum of absolute differences
1479 * SLL - Logical shift left
1480 * SLR - Logical shift right
1481 * SAR - Arithmetic shift right
1484 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1485 * XOR - Logical bitwise 'exclusive or' operation
1489 * E - Expand results
1490 * F - Fixed point multiplication
1491 * L - Low part result
1492 * R - Doing rounding
1493 * V - Variable instead of immediate
1494 * W - Combine above L and V
1497 * The list of MXU instructions grouped by functionality
1498 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1500 * Load/Store instructions Multiplication instructions
1501 * ----------------------- ---------------------------
1503 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1504 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1505 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1506 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1507 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1508 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1509 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1510 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1511 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1512 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1513 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1514 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1515 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1516 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1517 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1518 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1519 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1520 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1521 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1522 * S16SDI XRa, Rb, s10, eptn2
1523 * S8LDD XRa, Rb, s8, eptn3
1524 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1525 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1526 * S8SDI XRa, Rb, s8, eptn3
1527 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1528 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1529 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1530 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1531 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1532 * S32CPS XRa, XRb, XRc
1533 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1534 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1535 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1536 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1537 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1538 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1539 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1540 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1541 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1542 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1543 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1544 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1545 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1546 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1547 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1548 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1549 * Q8SLT XRa, XRb, XRc
1550 * Q8SLTU XRa, XRb, XRc
1551 * Q8MOVZ XRa, XRb, XRc Shift instructions
1552 * Q8MOVN XRa, XRb, XRc ------------------
1554 * D32SLL XRa, XRb, XRc, XRd, sft4
1555 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1556 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1557 * D32SARL XRa, XRb, XRc, sft4
1558 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1559 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1560 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1561 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1562 * Q16SLL XRa, XRb, XRc, XRd, sft4
1563 * Q16SLR XRa, XRb, XRc, XRd, sft4
1564 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1565 * ------------------------- Q16SLLV XRa, XRb, Rb
1566 * Q16SLRV XRa, XRb, Rb
1567 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1568 * S32ALN XRa, XRb, XRc, Rb
1569 * S32ALNI XRa, XRb, XRc, s3
1570 * S32LUI XRa, s8, optn3 Move instructions
1571 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1572 * S32EXTRV XRa, XRb, Rs, Rt
1573 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1574 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1577 * The opcode organization of MXU instructions
1578 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1580 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1581 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1582 * other bits up to the instruction level is as follows:
1587 * ┌─ 000000 ─ OPC_MXU_S32MADD
1588 * ├─ 000001 ─ OPC_MXU_S32MADDU
1589 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1592 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1593 * │ ├─ 001 ─ OPC_MXU_S32MIN
1594 * │ ├─ 010 ─ OPC_MXU_D16MAX
1595 * │ ├─ 011 ─ OPC_MXU_D16MIN
1596 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1597 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1598 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1599 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1600 * ├─ 000100 ─ OPC_MXU_S32MSUB
1601 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1602 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1603 * │ ├─ 001 ─ OPC_MXU_D16SLT
1604 * │ ├─ 010 ─ OPC_MXU_D16AVG
1605 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1606 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1607 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1608 * │ └─ 111 ─ OPC_MXU_Q8ADD
1611 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1612 * │ ├─ 010 ─ OPC_MXU_D16CPS
1613 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1614 * │ └─ 110 ─ OPC_MXU_Q16SAT
1615 * ├─ 001000 ─ OPC_MXU_D16MUL
1617 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1618 * │ └─ 01 ─ OPC_MXU_D16MULE
1619 * ├─ 001010 ─ OPC_MXU_D16MAC
1620 * ├─ 001011 ─ OPC_MXU_D16MACF
1621 * ├─ 001100 ─ OPC_MXU_D16MADL
1622 * ├─ 001101 ─ OPC_MXU_S16MAD
1623 * ├─ 001110 ─ OPC_MXU_Q16ADD
1624 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1625 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1626 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1629 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1630 * │ └─ 1 ─ OPC_MXU_S32STDR
1633 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1634 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1637 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1638 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1641 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1642 * │ └─ 1 ─ OPC_MXU_S32LDIR
1645 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1646 * │ └─ 1 ─ OPC_MXU_S32SDIR
1649 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1650 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1653 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1654 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1655 * ├─ 011000 ─ OPC_MXU_D32ADD
1657 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1658 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1659 * │ └─ 10 ─ OPC_MXU_D32ASUM
1660 * ├─ 011010 ─ <not assigned>
1662 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1663 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1664 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1667 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1668 * │ ├─ 01 ─ OPC_MXU_D8SUM
1669 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1670 * ├─ 011110 ─ <not assigned>
1671 * ├─ 011111 ─ <not assigned>
1672 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1673 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1674 * ├─ 100010 ─ OPC_MXU_S8LDD
1675 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1676 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1677 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1678 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1679 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1682 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1683 * │ ├─ 001 ─ OPC_MXU_S32ALN
1684 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1685 * │ ├─ 011 ─ OPC_MXU_S32LUI
1686 * │ ├─ 100 ─ OPC_MXU_S32NOR
1687 * │ ├─ 101 ─ OPC_MXU_S32AND
1688 * │ ├─ 110 ─ OPC_MXU_S32OR
1689 * │ └─ 111 ─ OPC_MXU_S32XOR
1692 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1693 * │ ├─ 001 ─ OPC_MXU_LXH
1694 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1695 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1696 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1697 * ├─ 101100 ─ OPC_MXU_S16LDI
1698 * ├─ 101101 ─ OPC_MXU_S16SDI
1699 * ├─ 101110 ─ OPC_MXU_S32M2I
1700 * ├─ 101111 ─ OPC_MXU_S32I2M
1701 * ├─ 110000 ─ OPC_MXU_D32SLL
1702 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1703 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1704 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1705 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1706 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1707 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1708 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1710 * ├─ 110111 ─ OPC_MXU_Q16SAR
1712 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1713 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1716 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1717 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1718 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1719 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1720 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1721 * │ └─ 101 ─ OPC_MXU_S32MOVN
1724 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1725 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1726 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1727 * ├─ 111100 ─ OPC_MXU_Q8MADL
1728 * ├─ 111101 ─ OPC_MXU_S32SFL
1729 * ├─ 111110 ─ OPC_MXU_Q8SAD
1730 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1735 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1736 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1740 OPC_MXU_S32MADD
= 0x00,
1741 OPC_MXU_S32MADDU
= 0x01,
1742 OPC__MXU_MUL
= 0x02,
1743 OPC_MXU__POOL00
= 0x03,
1744 OPC_MXU_S32MSUB
= 0x04,
1745 OPC_MXU_S32MSUBU
= 0x05,
1746 OPC_MXU__POOL01
= 0x06,
1747 OPC_MXU__POOL02
= 0x07,
1748 OPC_MXU_D16MUL
= 0x08,
1749 OPC_MXU__POOL03
= 0x09,
1750 OPC_MXU_D16MAC
= 0x0A,
1751 OPC_MXU_D16MACF
= 0x0B,
1752 OPC_MXU_D16MADL
= 0x0C,
1753 OPC_MXU_S16MAD
= 0x0D,
1754 OPC_MXU_Q16ADD
= 0x0E,
1755 OPC_MXU_D16MACE
= 0x0F,
1756 OPC_MXU__POOL04
= 0x10,
1757 OPC_MXU__POOL05
= 0x11,
1758 OPC_MXU__POOL06
= 0x12,
1759 OPC_MXU__POOL07
= 0x13,
1760 OPC_MXU__POOL08
= 0x14,
1761 OPC_MXU__POOL09
= 0x15,
1762 OPC_MXU__POOL10
= 0x16,
1763 OPC_MXU__POOL11
= 0x17,
1764 OPC_MXU_D32ADD
= 0x18,
1765 OPC_MXU__POOL12
= 0x19,
1766 /* not assigned 0x1A */
1767 OPC_MXU__POOL13
= 0x1B,
1768 OPC_MXU__POOL14
= 0x1C,
1769 OPC_MXU_Q8ACCE
= 0x1D,
1770 /* not assigned 0x1E */
1771 /* not assigned 0x1F */
1772 /* not assigned 0x20 */
1773 /* not assigned 0x21 */
1774 OPC_MXU_S8LDD
= 0x22,
1775 OPC_MXU_S8STD
= 0x23,
1776 OPC_MXU_S8LDI
= 0x24,
1777 OPC_MXU_S8SDI
= 0x25,
1778 OPC_MXU__POOL15
= 0x26,
1779 OPC_MXU__POOL16
= 0x27,
1780 OPC_MXU__POOL17
= 0x28,
1781 /* not assigned 0x29 */
1782 OPC_MXU_S16LDD
= 0x2A,
1783 OPC_MXU_S16STD
= 0x2B,
1784 OPC_MXU_S16LDI
= 0x2C,
1785 OPC_MXU_S16SDI
= 0x2D,
1786 OPC_MXU_S32M2I
= 0x2E,
1787 OPC_MXU_S32I2M
= 0x2F,
1788 OPC_MXU_D32SLL
= 0x30,
1789 OPC_MXU_D32SLR
= 0x31,
1790 OPC_MXU_D32SARL
= 0x32,
1791 OPC_MXU_D32SAR
= 0x33,
1792 OPC_MXU_Q16SLL
= 0x34,
1793 OPC_MXU_Q16SLR
= 0x35,
1794 OPC_MXU__POOL18
= 0x36,
1795 OPC_MXU_Q16SAR
= 0x37,
1796 OPC_MXU__POOL19
= 0x38,
1797 OPC_MXU__POOL20
= 0x39,
1798 OPC_MXU__POOL21
= 0x3A,
1799 OPC_MXU_Q16SCOP
= 0x3B,
1800 OPC_MXU_Q8MADL
= 0x3C,
1801 OPC_MXU_S32SFL
= 0x3D,
1802 OPC_MXU_Q8SAD
= 0x3E,
1803 /* not assigned 0x3F */
1811 OPC_MXU_S32MAX
= 0x00,
1812 OPC_MXU_S32MIN
= 0x01,
1813 OPC_MXU_D16MAX
= 0x02,
1814 OPC_MXU_D16MIN
= 0x03,
1815 OPC_MXU_Q8MAX
= 0x04,
1816 OPC_MXU_Q8MIN
= 0x05,
1817 OPC_MXU_Q8SLT
= 0x06,
1818 OPC_MXU_Q8SLTU
= 0x07,
1825 OPC_MXU_S32SLT
= 0x00,
1826 OPC_MXU_D16SLT
= 0x01,
1827 OPC_MXU_D16AVG
= 0x02,
1828 OPC_MXU_D16AVGR
= 0x03,
1829 OPC_MXU_Q8AVG
= 0x04,
1830 OPC_MXU_Q8AVGR
= 0x05,
1831 OPC_MXU_Q8ADD
= 0x07,
1838 OPC_MXU_S32CPS
= 0x00,
1839 OPC_MXU_D16CPS
= 0x02,
1840 OPC_MXU_Q8ABD
= 0x04,
1841 OPC_MXU_Q16SAT
= 0x06,
1848 OPC_MXU_D16MULF
= 0x00,
1849 OPC_MXU_D16MULE
= 0x01,
1856 OPC_MXU_S32LDD
= 0x00,
1857 OPC_MXU_S32LDDR
= 0x01,
1864 OPC_MXU_S32STD
= 0x00,
1865 OPC_MXU_S32STDR
= 0x01,
1872 OPC_MXU_S32LDDV
= 0x00,
1873 OPC_MXU_S32LDDVR
= 0x01,
1880 OPC_MXU_S32STDV
= 0x00,
1881 OPC_MXU_S32STDVR
= 0x01,
1888 OPC_MXU_S32LDI
= 0x00,
1889 OPC_MXU_S32LDIR
= 0x01,
1896 OPC_MXU_S32SDI
= 0x00,
1897 OPC_MXU_S32SDIR
= 0x01,
1904 OPC_MXU_S32LDIV
= 0x00,
1905 OPC_MXU_S32LDIVR
= 0x01,
1912 OPC_MXU_S32SDIV
= 0x00,
1913 OPC_MXU_S32SDIVR
= 0x01,
1920 OPC_MXU_D32ACC
= 0x00,
1921 OPC_MXU_D32ACCM
= 0x01,
1922 OPC_MXU_D32ASUM
= 0x02,
1929 OPC_MXU_Q16ACC
= 0x00,
1930 OPC_MXU_Q16ACCM
= 0x01,
1931 OPC_MXU_Q16ASUM
= 0x02,
1938 OPC_MXU_Q8ADDE
= 0x00,
1939 OPC_MXU_D8SUM
= 0x01,
1940 OPC_MXU_D8SUMC
= 0x02,
1947 OPC_MXU_S32MUL
= 0x00,
1948 OPC_MXU_S32MULU
= 0x01,
1949 OPC_MXU_S32EXTR
= 0x02,
1950 OPC_MXU_S32EXTRV
= 0x03,
1957 OPC_MXU_D32SARW
= 0x00,
1958 OPC_MXU_S32ALN
= 0x01,
1959 OPC_MXU_S32ALNI
= 0x02,
1960 OPC_MXU_S32LUI
= 0x03,
1961 OPC_MXU_S32NOR
= 0x04,
1962 OPC_MXU_S32AND
= 0x05,
1963 OPC_MXU_S32OR
= 0x06,
1964 OPC_MXU_S32XOR
= 0x07,
1974 OPC_MXU_LXBU
= 0x04,
1975 OPC_MXU_LXHU
= 0x05,
1982 OPC_MXU_D32SLLV
= 0x00,
1983 OPC_MXU_D32SLRV
= 0x01,
1984 OPC_MXU_D32SARV
= 0x03,
1985 OPC_MXU_Q16SLLV
= 0x04,
1986 OPC_MXU_Q16SLRV
= 0x05,
1987 OPC_MXU_Q16SARV
= 0x07,
1994 OPC_MXU_Q8MUL
= 0x00,
1995 OPC_MXU_Q8MULSU
= 0x01,
2002 OPC_MXU_Q8MOVZ
= 0x00,
2003 OPC_MXU_Q8MOVN
= 0x01,
2004 OPC_MXU_D16MOVZ
= 0x02,
2005 OPC_MXU_D16MOVN
= 0x03,
2006 OPC_MXU_S32MOVZ
= 0x04,
2007 OPC_MXU_S32MOVN
= 0x05,
2014 OPC_MXU_Q8MAC
= 0x00,
2015 OPC_MXU_Q8MACSU
= 0x01,
2019 * Overview of the TX79-specific instruction set
2020 * =============================================
2022 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2023 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2024 * instructions and certain multimedia instructions (MMIs). These MMIs
2025 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2026 * or sixteen 8-bit paths.
2030 * The Toshiba TX System RISC TX79 Core Architecture manual,
2031 * https://wiki.qemu.org/File:C790.pdf
2033 * Three-Operand Multiply and Multiply-Add (4 instructions)
2034 * --------------------------------------------------------
2035 * MADD [rd,] rs, rt Multiply/Add
2036 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2037 * MULT [rd,] rs, rt Multiply (3-operand)
2038 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2040 * Multiply Instructions for Pipeline 1 (10 instructions)
2041 * ------------------------------------------------------
2042 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2043 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2044 * DIV1 rs, rt Divide Pipeline 1
2045 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2046 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2047 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2048 * MFHI1 rd Move From HI1 Register
2049 * MFLO1 rd Move From LO1 Register
2050 * MTHI1 rs Move To HI1 Register
2051 * MTLO1 rs Move To LO1 Register
2053 * Arithmetic (19 instructions)
2054 * ----------------------------
2055 * PADDB rd, rs, rt Parallel Add Byte
2056 * PSUBB rd, rs, rt Parallel Subtract Byte
2057 * PADDH rd, rs, rt Parallel Add Halfword
2058 * PSUBH rd, rs, rt Parallel Subtract Halfword
2059 * PADDW rd, rs, rt Parallel Add Word
2060 * PSUBW rd, rs, rt Parallel Subtract Word
2061 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2062 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2063 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2064 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2065 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2066 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2067 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2068 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2069 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2070 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2071 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2072 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2073 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2075 * Min/Max (4 instructions)
2076 * ------------------------
2077 * PMAXH rd, rs, rt Parallel Maximum Halfword
2078 * PMINH rd, rs, rt Parallel Minimum Halfword
2079 * PMAXW rd, rs, rt Parallel Maximum Word
2080 * PMINW rd, rs, rt Parallel Minimum Word
2082 * Absolute (2 instructions)
2083 * -------------------------
2084 * PABSH rd, rt Parallel Absolute Halfword
2085 * PABSW rd, rt Parallel Absolute Word
2087 * Logical (4 instructions)
2088 * ------------------------
2089 * PAND rd, rs, rt Parallel AND
2090 * POR rd, rs, rt Parallel OR
2091 * PXOR rd, rs, rt Parallel XOR
2092 * PNOR rd, rs, rt Parallel NOR
2094 * Shift (9 instructions)
2095 * ----------------------
2096 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2097 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2098 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2099 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2100 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2101 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2102 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2103 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2104 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2106 * Compare (6 instructions)
2107 * ------------------------
2108 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2109 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2110 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2111 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2112 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2113 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2115 * LZC (1 instruction)
2116 * -------------------
2117 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2119 * Quadword Load and Store (2 instructions)
2120 * ----------------------------------------
2121 * LQ rt, offset(base) Load Quadword
2122 * SQ rt, offset(base) Store Quadword
2124 * Multiply and Divide (19 instructions)
2125 * -------------------------------------
2126 * PMULTW rd, rs, rt Parallel Multiply Word
2127 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2128 * PDIVW rs, rt Parallel Divide Word
2129 * PDIVUW rs, rt Parallel Divide Unsigned Word
2130 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2131 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2132 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2133 * PMULTH rd, rs, rt Parallel Multiply Halfword
2134 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2135 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2136 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2137 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2138 * PDIVBW rs, rt Parallel Divide Broadcast Word
2139 * PMFHI rd Parallel Move From HI Register
2140 * PMFLO rd Parallel Move From LO Register
2141 * PMTHI rs Parallel Move To HI Register
2142 * PMTLO rs Parallel Move To LO Register
2143 * PMFHL rd Parallel Move From HI/LO Register
2144 * PMTHL rs Parallel Move To HI/LO Register
2146 * Pack/Extend (11 instructions)
2147 * -----------------------------
2148 * PPAC5 rd, rt Parallel Pack to 5 bits
2149 * PPACB rd, rs, rt Parallel Pack to Byte
2150 * PPACH rd, rs, rt Parallel Pack to Halfword
2151 * PPACW rd, rs, rt Parallel Pack to Word
2152 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2153 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2154 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2155 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2156 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2157 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2158 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2160 * Others (16 instructions)
2161 * ------------------------
2162 * PCPYH rd, rt Parallel Copy Halfword
2163 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2164 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2165 * PREVH rd, rt Parallel Reverse Halfword
2166 * PINTH rd, rs, rt Parallel Interleave Halfword
2167 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2168 * PEXEH rd, rt Parallel Exchange Even Halfword
2169 * PEXCH rd, rt Parallel Exchange Center Halfword
2170 * PEXEW rd, rt Parallel Exchange Even Word
2171 * PEXCW rd, rt Parallel Exchange Center Word
2172 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2173 * MFSA rd Move from Shift Amount Register
2174 * MTSA rs Move to Shift Amount Register
2175 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2176 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2177 * PROT3W rd, rt Parallel Rotate 3 Words
2179 * MMI (MultiMedia Instruction) encodings
2180 * ======================================
2182 * MMI instructions encoding table keys:
2184 * * This code is reserved for future use. An attempt to execute it
2185 * causes a Reserved Instruction exception.
2186 * % This code indicates an instruction class. The instruction word
2187 * must be further decoded by examining additional tables that show
2188 * the values for other instruction fields.
2189 * # This code is reserved for the unsupported instructions DMULT,
2190 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2191 * to execute it causes a Reserved Instruction exception.
2193 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2196 * +--------+----------------------------------------+
2198 * +--------+----------------------------------------+
2200 * opcode bits 28..26
2201 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2202 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2203 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2204 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2205 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2206 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2207 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2208 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2209 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2210 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2211 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2215 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
2216 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
2217 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
2221 * MMI instructions with opcode field = MMI:
2224 * +--------+-------------------------------+--------+
2225 * | MMI | |function|
2226 * +--------+-------------------------------+--------+
2228 * function bits 2..0
2229 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2230 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2231 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2232 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2233 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2234 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2235 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2236 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2237 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2238 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2239 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2242 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2244 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
2245 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
2246 MMI_OPC_PLZCW
= 0x04 | MMI_OPC_CLASS_MMI
,
2247 MMI_OPC_CLASS_MMI0
= 0x08 | MMI_OPC_CLASS_MMI
,
2248 MMI_OPC_CLASS_MMI2
= 0x09 | MMI_OPC_CLASS_MMI
,
2249 MMI_OPC_MFHI1
= 0x10 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFHI */
2250 MMI_OPC_MTHI1
= 0x11 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTHI */
2251 MMI_OPC_MFLO1
= 0x12 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFLO */
2252 MMI_OPC_MTLO1
= 0x13 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTLO */
2253 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
2254 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
2255 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
2256 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
2257 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
2258 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
2259 MMI_OPC_CLASS_MMI1
= 0x28 | MMI_OPC_CLASS_MMI
,
2260 MMI_OPC_CLASS_MMI3
= 0x29 | MMI_OPC_CLASS_MMI
,
2261 MMI_OPC_PMFHL
= 0x30 | MMI_OPC_CLASS_MMI
,
2262 MMI_OPC_PMTHL
= 0x31 | MMI_OPC_CLASS_MMI
,
2263 MMI_OPC_PSLLH
= 0x34 | MMI_OPC_CLASS_MMI
,
2264 MMI_OPC_PSRLH
= 0x36 | MMI_OPC_CLASS_MMI
,
2265 MMI_OPC_PSRAH
= 0x37 | MMI_OPC_CLASS_MMI
,
2266 MMI_OPC_PSLLW
= 0x3C | MMI_OPC_CLASS_MMI
,
2267 MMI_OPC_PSRLW
= 0x3E | MMI_OPC_CLASS_MMI
,
2268 MMI_OPC_PSRAW
= 0x3F | MMI_OPC_CLASS_MMI
,
2272 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2275 * +--------+----------------------+--------+--------+
2276 * | MMI | |function| MMI0 |
2277 * +--------+----------------------+--------+--------+
2279 * function bits 7..6
2280 * bits | 0 | 1 | 2 | 3
2281 * 10..8 | 00 | 01 | 10 | 11
2282 * -------+-------+-------+-------+-------
2283 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2284 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2285 * 2 010 | PADDB | PSUBB | PCGTB | *
2286 * 3 011 | * | * | * | *
2287 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2288 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2289 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2290 * 7 111 | * | * | PEXT5 | PPAC5
2293 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2295 MMI_OPC_0_PADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI0
,
2296 MMI_OPC_0_PSUBW
= (0x01 << 6) | MMI_OPC_CLASS_MMI0
,
2297 MMI_OPC_0_PCGTW
= (0x02 << 6) | MMI_OPC_CLASS_MMI0
,
2298 MMI_OPC_0_PMAXW
= (0x03 << 6) | MMI_OPC_CLASS_MMI0
,
2299 MMI_OPC_0_PADDH
= (0x04 << 6) | MMI_OPC_CLASS_MMI0
,
2300 MMI_OPC_0_PSUBH
= (0x05 << 6) | MMI_OPC_CLASS_MMI0
,
2301 MMI_OPC_0_PCGTH
= (0x06 << 6) | MMI_OPC_CLASS_MMI0
,
2302 MMI_OPC_0_PMAXH
= (0x07 << 6) | MMI_OPC_CLASS_MMI0
,
2303 MMI_OPC_0_PADDB
= (0x08 << 6) | MMI_OPC_CLASS_MMI0
,
2304 MMI_OPC_0_PSUBB
= (0x09 << 6) | MMI_OPC_CLASS_MMI0
,
2305 MMI_OPC_0_PCGTB
= (0x0A << 6) | MMI_OPC_CLASS_MMI0
,
2306 MMI_OPC_0_PADDSW
= (0x10 << 6) | MMI_OPC_CLASS_MMI0
,
2307 MMI_OPC_0_PSUBSW
= (0x11 << 6) | MMI_OPC_CLASS_MMI0
,
2308 MMI_OPC_0_PEXTLW
= (0x12 << 6) | MMI_OPC_CLASS_MMI0
,
2309 MMI_OPC_0_PPACW
= (0x13 << 6) | MMI_OPC_CLASS_MMI0
,
2310 MMI_OPC_0_PADDSH
= (0x14 << 6) | MMI_OPC_CLASS_MMI0
,
2311 MMI_OPC_0_PSUBSH
= (0x15 << 6) | MMI_OPC_CLASS_MMI0
,
2312 MMI_OPC_0_PEXTLH
= (0x16 << 6) | MMI_OPC_CLASS_MMI0
,
2313 MMI_OPC_0_PPACH
= (0x17 << 6) | MMI_OPC_CLASS_MMI0
,
2314 MMI_OPC_0_PADDSB
= (0x18 << 6) | MMI_OPC_CLASS_MMI0
,
2315 MMI_OPC_0_PSUBSB
= (0x19 << 6) | MMI_OPC_CLASS_MMI0
,
2316 MMI_OPC_0_PEXTLB
= (0x1A << 6) | MMI_OPC_CLASS_MMI0
,
2317 MMI_OPC_0_PPACB
= (0x1B << 6) | MMI_OPC_CLASS_MMI0
,
2318 MMI_OPC_0_PEXT5
= (0x1E << 6) | MMI_OPC_CLASS_MMI0
,
2319 MMI_OPC_0_PPAC5
= (0x1F << 6) | MMI_OPC_CLASS_MMI0
,
2323 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2326 * +--------+----------------------+--------+--------+
2327 * | MMI | |function| MMI1 |
2328 * +--------+----------------------+--------+--------+
2330 * function bits 7..6
2331 * bits | 0 | 1 | 2 | 3
2332 * 10..8 | 00 | 01 | 10 | 11
2333 * -------+-------+-------+-------+-------
2334 * 0 000 | * | PABSW | PCEQW | PMINW
2335 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2336 * 2 010 | * | * | PCEQB | *
2337 * 3 011 | * | * | * | *
2338 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2339 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2340 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2341 * 7 111 | * | * | * | *
2344 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2346 MMI_OPC_1_PABSW
= (0x01 << 6) | MMI_OPC_CLASS_MMI1
,
2347 MMI_OPC_1_PCEQW
= (0x02 << 6) | MMI_OPC_CLASS_MMI1
,
2348 MMI_OPC_1_PMINW
= (0x03 << 6) | MMI_OPC_CLASS_MMI1
,
2349 MMI_OPC_1_PADSBH
= (0x04 << 6) | MMI_OPC_CLASS_MMI1
,
2350 MMI_OPC_1_PABSH
= (0x05 << 6) | MMI_OPC_CLASS_MMI1
,
2351 MMI_OPC_1_PCEQH
= (0x06 << 6) | MMI_OPC_CLASS_MMI1
,
2352 MMI_OPC_1_PMINH
= (0x07 << 6) | MMI_OPC_CLASS_MMI1
,
2353 MMI_OPC_1_PCEQB
= (0x0A << 6) | MMI_OPC_CLASS_MMI1
,
2354 MMI_OPC_1_PADDUW
= (0x10 << 6) | MMI_OPC_CLASS_MMI1
,
2355 MMI_OPC_1_PSUBUW
= (0x11 << 6) | MMI_OPC_CLASS_MMI1
,
2356 MMI_OPC_1_PEXTUW
= (0x12 << 6) | MMI_OPC_CLASS_MMI1
,
2357 MMI_OPC_1_PADDUH
= (0x14 << 6) | MMI_OPC_CLASS_MMI1
,
2358 MMI_OPC_1_PSUBUH
= (0x15 << 6) | MMI_OPC_CLASS_MMI1
,
2359 MMI_OPC_1_PEXTUH
= (0x16 << 6) | MMI_OPC_CLASS_MMI1
,
2360 MMI_OPC_1_PADDUB
= (0x18 << 6) | MMI_OPC_CLASS_MMI1
,
2361 MMI_OPC_1_PSUBUB
= (0x19 << 6) | MMI_OPC_CLASS_MMI1
,
2362 MMI_OPC_1_PEXTUB
= (0x1A << 6) | MMI_OPC_CLASS_MMI1
,
2363 MMI_OPC_1_QFSRV
= (0x1B << 6) | MMI_OPC_CLASS_MMI1
,
2367 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2370 * +--------+----------------------+--------+--------+
2371 * | MMI | |function| MMI2 |
2372 * +--------+----------------------+--------+--------+
2374 * function bits 7..6
2375 * bits | 0 | 1 | 2 | 3
2376 * 10..8 | 00 | 01 | 10 | 11
2377 * -------+-------+-------+-------+-------
2378 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2379 * 1 001 | PMSUBW| * | * | *
2380 * 2 010 | PMFHI | PMFLO | PINTH | *
2381 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2382 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2383 * 5 101 | PMSUBH| PHMSBH| * | *
2384 * 6 110 | * | * | PEXEH | PREVH
2385 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2388 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2390 MMI_OPC_2_PMADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI2
,
2391 MMI_OPC_2_PSLLVW
= (0x02 << 6) | MMI_OPC_CLASS_MMI2
,
2392 MMI_OPC_2_PSRLVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI2
,
2393 MMI_OPC_2_PMSUBW
= (0x04 << 6) | MMI_OPC_CLASS_MMI2
,
2394 MMI_OPC_2_PMFHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI2
,
2395 MMI_OPC_2_PMFLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI2
,
2396 MMI_OPC_2_PINTH
= (0x0A << 6) | MMI_OPC_CLASS_MMI2
,
2397 MMI_OPC_2_PMULTW
= (0x0C << 6) | MMI_OPC_CLASS_MMI2
,
2398 MMI_OPC_2_PDIVW
= (0x0D << 6) | MMI_OPC_CLASS_MMI2
,
2399 MMI_OPC_2_PCPYLD
= (0x0E << 6) | MMI_OPC_CLASS_MMI2
,
2400 MMI_OPC_2_PMADDH
= (0x10 << 6) | MMI_OPC_CLASS_MMI2
,
2401 MMI_OPC_2_PHMADH
= (0x11 << 6) | MMI_OPC_CLASS_MMI2
,
2402 MMI_OPC_2_PAND
= (0x12 << 6) | MMI_OPC_CLASS_MMI2
,
2403 MMI_OPC_2_PXOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI2
,
2404 MMI_OPC_2_PMSUBH
= (0x14 << 6) | MMI_OPC_CLASS_MMI2
,
2405 MMI_OPC_2_PHMSBH
= (0x15 << 6) | MMI_OPC_CLASS_MMI2
,
2406 MMI_OPC_2_PEXEH
= (0x1A << 6) | MMI_OPC_CLASS_MMI2
,
2407 MMI_OPC_2_PREVH
= (0x1B << 6) | MMI_OPC_CLASS_MMI2
,
2408 MMI_OPC_2_PMULTH
= (0x1C << 6) | MMI_OPC_CLASS_MMI2
,
2409 MMI_OPC_2_PDIVBW
= (0x1D << 6) | MMI_OPC_CLASS_MMI2
,
2410 MMI_OPC_2_PEXEW
= (0x1E << 6) | MMI_OPC_CLASS_MMI2
,
2411 MMI_OPC_2_PROT3W
= (0x1F << 6) | MMI_OPC_CLASS_MMI2
,
2415 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2418 * +--------+----------------------+--------+--------+
2419 * | MMI | |function| MMI3 |
2420 * +--------+----------------------+--------+--------+
2422 * function bits 7..6
2423 * bits | 0 | 1 | 2 | 3
2424 * 10..8 | 00 | 01 | 10 | 11
2425 * -------+-------+-------+-------+-------
2426 * 0 000 |PMADDUW| * | * | PSRAVW
2427 * 1 001 | * | * | * | *
2428 * 2 010 | PMTHI | PMTLO | PINTEH| *
2429 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2430 * 4 100 | * | * | POR | PNOR
2431 * 5 101 | * | * | * | *
2432 * 6 110 | * | * | PEXCH | PCPYH
2433 * 7 111 | * | * | PEXCW | *
2436 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2438 MMI_OPC_3_PMADDUW
= (0x00 << 6) | MMI_OPC_CLASS_MMI3
,
2439 MMI_OPC_3_PSRAVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI3
,
2440 MMI_OPC_3_PMTHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI3
,
2441 MMI_OPC_3_PMTLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI3
,
2442 MMI_OPC_3_PINTEH
= (0x0A << 6) | MMI_OPC_CLASS_MMI3
,
2443 MMI_OPC_3_PMULTUW
= (0x0C << 6) | MMI_OPC_CLASS_MMI3
,
2444 MMI_OPC_3_PDIVUW
= (0x0D << 6) | MMI_OPC_CLASS_MMI3
,
2445 MMI_OPC_3_PCPYUD
= (0x0E << 6) | MMI_OPC_CLASS_MMI3
,
2446 MMI_OPC_3_POR
= (0x12 << 6) | MMI_OPC_CLASS_MMI3
,
2447 MMI_OPC_3_PNOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI3
,
2448 MMI_OPC_3_PEXCH
= (0x1A << 6) | MMI_OPC_CLASS_MMI3
,
2449 MMI_OPC_3_PCPYH
= (0x1B << 6) | MMI_OPC_CLASS_MMI3
,
2450 MMI_OPC_3_PEXCW
= (0x1E << 6) | MMI_OPC_CLASS_MMI3
,
2453 /* global register indices */
2454 static TCGv cpu_gpr
[32], cpu_PC
;
2455 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
2456 static TCGv cpu_dspctrl
, btarget
, bcond
;
2457 static TCGv cpu_lladdr
, cpu_llval
;
2458 static TCGv_i32 hflags
;
2459 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
2460 static TCGv_i64 fpu_f64
[32];
2461 static TCGv_i64 msa_wr_d
[64];
2463 #if defined(TARGET_MIPS64)
2464 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2465 static TCGv_i64 cpu_mmr
[32];
2468 #if !defined(TARGET_MIPS64)
2470 static TCGv mxu_gpr
[NUMBER_OF_MXU_REGISTERS
- 1];
2474 #include "exec/gen-icount.h"
2476 #define gen_helper_0e0i(name, arg) do { \
2477 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2478 gen_helper_##name(cpu_env, helper_tmp); \
2479 tcg_temp_free_i32(helper_tmp); \
2482 #define gen_helper_0e1i(name, arg1, arg2) do { \
2483 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2484 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2485 tcg_temp_free_i32(helper_tmp); \
2488 #define gen_helper_1e0i(name, ret, arg1) do { \
2489 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2490 gen_helper_##name(ret, cpu_env, helper_tmp); \
2491 tcg_temp_free_i32(helper_tmp); \
2494 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2495 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2496 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2497 tcg_temp_free_i32(helper_tmp); \
2500 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2501 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2502 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2503 tcg_temp_free_i32(helper_tmp); \
2506 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2507 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2508 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2509 tcg_temp_free_i32(helper_tmp); \
2512 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2513 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2514 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2515 tcg_temp_free_i32(helper_tmp); \
2518 typedef struct DisasContext
{
2519 DisasContextBase base
;
2520 target_ulong saved_pc
;
2521 target_ulong page_start
;
2523 uint64_t insn_flags
;
2524 int32_t CP0_Config1
;
2525 int32_t CP0_Config2
;
2526 int32_t CP0_Config3
;
2527 int32_t CP0_Config5
;
2528 /* Routine used to access memory */
2530 MemOp default_tcg_memop_mask
;
2531 uint32_t hflags
, saved_hflags
;
2532 target_ulong btarget
;
2543 int CP0_LLAddr_shift
;
2555 #define DISAS_STOP DISAS_TARGET_0
2556 #define DISAS_EXIT DISAS_TARGET_1
2558 static const char * const regnames
[] = {
2559 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2560 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2561 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2562 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2565 static const char * const regnames_HI
[] = {
2566 "HI0", "HI1", "HI2", "HI3",
2569 static const char * const regnames_LO
[] = {
2570 "LO0", "LO1", "LO2", "LO3",
2573 static const char * const fregnames
[] = {
2574 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2575 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2576 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2577 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2580 static const char * const msaregnames
[] = {
2581 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2582 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2583 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2584 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2585 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2586 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2587 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2588 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2589 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2590 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2591 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2592 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2593 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2594 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2595 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2596 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2599 #if !defined(TARGET_MIPS64)
2600 static const char * const mxuregnames
[] = {
2601 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2602 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2606 #define LOG_DISAS(...) \
2608 if (MIPS_DEBUG_DISAS) { \
2609 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2613 #define MIPS_INVAL(op) \
2615 if (MIPS_DEBUG_DISAS) { \
2616 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2617 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2618 ctx->base.pc_next, ctx->opcode, op, \
2619 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2620 ((ctx->opcode >> 16) & 0x1F)); \
2624 /* General purpose registers moves. */
2625 static inline void gen_load_gpr(TCGv t
, int reg
)
2628 tcg_gen_movi_tl(t
, 0);
2630 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
2634 static inline void gen_store_gpr(TCGv t
, int reg
)
2637 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
2641 /* Moves to/from shadow registers. */
2642 static inline void gen_load_srsgpr(int from
, int to
)
2644 TCGv t0
= tcg_temp_new();
2647 tcg_gen_movi_tl(t0
, 0);
2649 TCGv_i32 t2
= tcg_temp_new_i32();
2650 TCGv_ptr addr
= tcg_temp_new_ptr();
2652 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2653 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2654 tcg_gen_andi_i32(t2
, t2
, 0xf);
2655 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2656 tcg_gen_ext_i32_ptr(addr
, t2
);
2657 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2659 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
2660 tcg_temp_free_ptr(addr
);
2661 tcg_temp_free_i32(t2
);
2663 gen_store_gpr(t0
, to
);
2667 static inline void gen_store_srsgpr(int from
, int to
)
2670 TCGv t0
= tcg_temp_new();
2671 TCGv_i32 t2
= tcg_temp_new_i32();
2672 TCGv_ptr addr
= tcg_temp_new_ptr();
2674 gen_load_gpr(t0
, from
);
2675 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2676 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2677 tcg_gen_andi_i32(t2
, t2
, 0xf);
2678 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2679 tcg_gen_ext_i32_ptr(addr
, t2
);
2680 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2682 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
2683 tcg_temp_free_ptr(addr
);
2684 tcg_temp_free_i32(t2
);
2689 #if !defined(TARGET_MIPS64)
2690 /* MXU General purpose registers moves. */
2691 static inline void gen_load_mxu_gpr(TCGv t
, unsigned int reg
)
2694 tcg_gen_movi_tl(t
, 0);
2695 } else if (reg
<= 15) {
2696 tcg_gen_mov_tl(t
, mxu_gpr
[reg
- 1]);
2700 static inline void gen_store_mxu_gpr(TCGv t
, unsigned int reg
)
2702 if (reg
> 0 && reg
<= 15) {
2703 tcg_gen_mov_tl(mxu_gpr
[reg
- 1], t
);
2707 /* MXU control register moves. */
2708 static inline void gen_load_mxu_cr(TCGv t
)
2710 tcg_gen_mov_tl(t
, mxu_CR
);
2713 static inline void gen_store_mxu_cr(TCGv t
)
2715 /* TODO: Add handling of RW rules for MXU_CR. */
2716 tcg_gen_mov_tl(mxu_CR
, t
);
2722 static inline void gen_save_pc(target_ulong pc
)
2724 tcg_gen_movi_tl(cpu_PC
, pc
);
2727 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
2729 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
2730 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
2731 gen_save_pc(ctx
->base
.pc_next
);
2732 ctx
->saved_pc
= ctx
->base
.pc_next
;
2734 if (ctx
->hflags
!= ctx
->saved_hflags
) {
2735 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
2736 ctx
->saved_hflags
= ctx
->hflags
;
2737 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2743 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
2749 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
2751 ctx
->saved_hflags
= ctx
->hflags
;
2752 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2758 ctx
->btarget
= env
->btarget
;
2763 static inline void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
2765 TCGv_i32 texcp
= tcg_const_i32(excp
);
2766 TCGv_i32 terr
= tcg_const_i32(err
);
2767 save_cpu_state(ctx
, 1);
2768 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
2769 tcg_temp_free_i32(terr
);
2770 tcg_temp_free_i32(texcp
);
2771 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2774 static inline void generate_exception(DisasContext
*ctx
, int excp
)
2776 gen_helper_0e0i(raise_exception
, excp
);
2779 static inline void generate_exception_end(DisasContext
*ctx
, int excp
)
2781 generate_exception_err(ctx
, excp
, 0);
2784 /* Floating point register moves. */
2785 static void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2787 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2788 generate_exception(ctx
, EXCP_RI
);
2790 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
2793 static void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2796 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2797 generate_exception(ctx
, EXCP_RI
);
2799 t64
= tcg_temp_new_i64();
2800 tcg_gen_extu_i32_i64(t64
, t
);
2801 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
2802 tcg_temp_free_i64(t64
);
2805 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2807 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2808 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
2810 gen_load_fpr32(ctx
, t
, reg
| 1);
2814 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2816 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2817 TCGv_i64 t64
= tcg_temp_new_i64();
2818 tcg_gen_extu_i32_i64(t64
, t
);
2819 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
2820 tcg_temp_free_i64(t64
);
2822 gen_store_fpr32(ctx
, t
, reg
| 1);
2826 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2828 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2829 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
2831 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
2835 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2837 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2838 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
2841 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
2842 t0
= tcg_temp_new_i64();
2843 tcg_gen_shri_i64(t0
, t
, 32);
2844 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
2845 tcg_temp_free_i64(t0
);
2849 static inline int get_fp_bit(int cc
)
2858 /* Addresses computation */
2859 static inline void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
,
2862 tcg_gen_add_tl(ret
, arg0
, arg1
);
2864 #if defined(TARGET_MIPS64)
2865 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2866 tcg_gen_ext32s_i64(ret
, ret
);
2871 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
2874 tcg_gen_addi_tl(ret
, base
, ofs
);
2876 #if defined(TARGET_MIPS64)
2877 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2878 tcg_gen_ext32s_i64(ret
, ret
);
2883 /* Addresses computation (translation time) */
2884 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
2887 target_long sum
= base
+ offset
;
2889 #if defined(TARGET_MIPS64)
2890 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2897 /* Sign-extract the low 32-bits to a target_long. */
2898 static inline void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
2900 #if defined(TARGET_MIPS64)
2901 tcg_gen_ext32s_i64(ret
, arg
);
2903 tcg_gen_extrl_i64_i32(ret
, arg
);
2907 /* Sign-extract the high 32-bits to a target_long. */
2908 static inline void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
2910 #if defined(TARGET_MIPS64)
2911 tcg_gen_sari_i64(ret
, arg
, 32);
2913 tcg_gen_extrh_i64_i32(ret
, arg
);
2917 static inline void check_cp0_enabled(DisasContext
*ctx
)
2919 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2920 generate_exception_err(ctx
, EXCP_CpU
, 0);
2924 static inline void check_cp1_enabled(DisasContext
*ctx
)
2926 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
2927 generate_exception_err(ctx
, EXCP_CpU
, 1);
2932 * Verify that the processor is running with COP1X instructions enabled.
2933 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2936 static inline void check_cop1x(DisasContext
*ctx
)
2938 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
2939 generate_exception_end(ctx
, EXCP_RI
);
2944 * Verify that the processor is running with 64-bit floating-point
2945 * operations enabled.
2947 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
2949 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
2950 generate_exception_end(ctx
, EXCP_RI
);
2955 * Verify if floating point register is valid; an operation is not defined
2956 * if bit 0 of any register specification is set and the FR bit in the
2957 * Status register equals zero, since the register numbers specify an
2958 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2959 * in the Status register equals one, both even and odd register numbers
2960 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2962 * Multiple 64 bit wide registers can be checked by calling
2963 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2965 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
2967 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
2968 generate_exception_end(ctx
, EXCP_RI
);
2973 * Verify that the processor is running with DSP instructions enabled.
2974 * This is enabled by CP0 Status register MX(24) bit.
2976 static inline void check_dsp(DisasContext
*ctx
)
2978 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
2979 if (ctx
->insn_flags
& ASE_DSP
) {
2980 generate_exception_end(ctx
, EXCP_DSPDIS
);
2982 generate_exception_end(ctx
, EXCP_RI
);
2987 static inline void check_dsp_r2(DisasContext
*ctx
)
2989 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
2990 if (ctx
->insn_flags
& ASE_DSP
) {
2991 generate_exception_end(ctx
, EXCP_DSPDIS
);
2993 generate_exception_end(ctx
, EXCP_RI
);
2998 static inline void check_dsp_r3(DisasContext
*ctx
)
3000 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
3001 if (ctx
->insn_flags
& ASE_DSP
) {
3002 generate_exception_end(ctx
, EXCP_DSPDIS
);
3004 generate_exception_end(ctx
, EXCP_RI
);
3010 * This code generates a "reserved instruction" exception if the
3011 * CPU does not support the instruction set corresponding to flags.
3013 static inline void check_insn(DisasContext
*ctx
, uint64_t flags
)
3015 if (unlikely(!(ctx
->insn_flags
& flags
))) {
3016 generate_exception_end(ctx
, EXCP_RI
);
3021 * This code generates a "reserved instruction" exception if the
3022 * CPU has corresponding flag set which indicates that the instruction
3025 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
3027 if (unlikely(ctx
->insn_flags
& flags
)) {
3028 generate_exception_end(ctx
, EXCP_RI
);
3033 * The Linux kernel traps certain reserved instruction exceptions to
3034 * emulate the corresponding instructions. QEMU is the kernel in user
3035 * mode, so those traps are emulated by accepting the instructions.
3037 * A reserved instruction exception is generated for flagged CPUs if
3038 * QEMU runs in system mode.
3040 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
3042 #ifndef CONFIG_USER_ONLY
3043 check_insn_opc_removed(ctx
, flags
);
3048 * This code generates a "reserved instruction" exception if the
3049 * CPU does not support 64-bit paired-single (PS) floating point data type.
3051 static inline void check_ps(DisasContext
*ctx
)
3053 if (unlikely(!ctx
->ps
)) {
3054 generate_exception(ctx
, EXCP_RI
);
3056 check_cp1_64bitmode(ctx
);
3059 #ifdef TARGET_MIPS64
3061 * This code generates a "reserved instruction" exception if 64-bit
3062 * instructions are not enabled.
3064 static inline void check_mips_64(DisasContext
*ctx
)
3066 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
))) {
3067 generate_exception_end(ctx
, EXCP_RI
);
3072 #ifndef CONFIG_USER_ONLY
3073 static inline void check_mvh(DisasContext
*ctx
)
3075 if (unlikely(!ctx
->mvh
)) {
3076 generate_exception(ctx
, EXCP_RI
);
3082 * This code generates a "reserved instruction" exception if the
3083 * Config5 XNP bit is set.
3085 static inline void check_xnp(DisasContext
*ctx
)
3087 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
3088 generate_exception_end(ctx
, EXCP_RI
);
3092 #ifndef CONFIG_USER_ONLY
3094 * This code generates a "reserved instruction" exception if the
3095 * Config3 PW bit is NOT set.
3097 static inline void check_pw(DisasContext
*ctx
)
3099 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
3100 generate_exception_end(ctx
, EXCP_RI
);
3106 * This code generates a "reserved instruction" exception if the
3107 * Config3 MT bit is NOT set.
3109 static inline void check_mt(DisasContext
*ctx
)
3111 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3112 generate_exception_end(ctx
, EXCP_RI
);
3116 #ifndef CONFIG_USER_ONLY
3118 * This code generates a "coprocessor unusable" exception if CP0 is not
3119 * available, and, if that is not the case, generates a "reserved instruction"
3120 * exception if the Config5 MT bit is NOT set. This is needed for availability
3121 * control of some of MT ASE instructions.
3123 static inline void check_cp0_mt(DisasContext
*ctx
)
3125 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
3126 generate_exception_err(ctx
, EXCP_CpU
, 0);
3128 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3129 generate_exception_err(ctx
, EXCP_RI
, 0);
3136 * This code generates a "reserved instruction" exception if the
3137 * Config5 NMS bit is set.
3139 static inline void check_nms(DisasContext
*ctx
)
3141 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
3142 generate_exception_end(ctx
, EXCP_RI
);
3147 * This code generates a "reserved instruction" exception if the
3148 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3149 * Config2 TL, and Config5 L2C are unset.
3151 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
3153 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
3154 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
3155 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
3156 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
3157 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
3158 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
3159 generate_exception_end(ctx
, EXCP_RI
);
3164 * This code generates a "reserved instruction" exception if the
3165 * Config5 EVA bit is NOT set.
3167 static inline void check_eva(DisasContext
*ctx
)
3169 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
3170 generate_exception_end(ctx
, EXCP_RI
);
3176 * Define small wrappers for gen_load_fpr* so that we have a uniform
3177 * calling interface for 32 and 64-bit FPRs. No sense in changing
3178 * all callers for gen_load_fpr32 when we need the CTX parameter for
3181 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3182 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3183 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3184 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3185 int ft, int fs, int cc) \
3187 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
3188 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
3197 check_cp1_registers(ctx, fs | ft); \
3205 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
3206 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
3209 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
3212 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
3215 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
3218 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
3221 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
3224 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
3227 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
3230 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
3233 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
3236 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
3239 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
3242 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
3245 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
3248 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
3251 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
3254 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
3259 tcg_temp_free_i##bits(fp0); \
3260 tcg_temp_free_i##bits(fp1); \
3263 FOP_CONDS(, 0, d
, FMT_D
, 64)
3264 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
3265 FOP_CONDS(, 0, s
, FMT_S
, 32)
3266 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
3267 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
3268 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
3271 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3272 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
3273 int ft, int fs, int fd) \
3275 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3276 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3277 if (ifmt == FMT_D) { \
3278 check_cp1_registers(ctx, fs | ft | fd); \
3280 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3281 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3284 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3287 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3290 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3293 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3296 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3299 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3302 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3305 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3308 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3311 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3314 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3317 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3320 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3323 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3326 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3329 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3332 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3335 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3338 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3341 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3344 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3347 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3353 tcg_temp_free_i ## bits(fp0); \
3354 tcg_temp_free_i ## bits(fp1); \
3357 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
3358 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
3360 #undef gen_ldcmp_fpr32
3361 #undef gen_ldcmp_fpr64
3363 /* load/store instructions. */
3364 #ifdef CONFIG_USER_ONLY
3365 #define OP_LD_ATOMIC(insn, fname) \
3366 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3367 DisasContext *ctx) \
3369 TCGv t0 = tcg_temp_new(); \
3370 tcg_gen_mov_tl(t0, arg1); \
3371 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3372 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3373 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3374 tcg_temp_free(t0); \
3377 #define OP_LD_ATOMIC(insn, fname) \
3378 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3379 DisasContext *ctx) \
3381 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3384 OP_LD_ATOMIC(ll
, ld32s
);
3385 #if defined(TARGET_MIPS64)
3386 OP_LD_ATOMIC(lld
, ld64
);
3390 static void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
,
3391 int base
, int offset
)
3394 tcg_gen_movi_tl(addr
, offset
);
3395 } else if (offset
== 0) {
3396 gen_load_gpr(addr
, base
);
3398 tcg_gen_movi_tl(addr
, offset
);
3399 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
3403 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
3405 target_ulong pc
= ctx
->base
.pc_next
;
3407 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3408 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
3413 pc
&= ~(target_ulong
)3;
3418 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
3419 int rt
, int base
, int offset
)
3422 int mem_idx
= ctx
->mem_idx
;
3424 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
3426 * Loongson CPU uses a load to zero register for prefetch.
3427 * We emulate it as a NOP. On other CPU we must perform the
3428 * actual memory access.
3433 t0
= tcg_temp_new();
3434 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3437 #if defined(TARGET_MIPS64)
3439 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
3440 ctx
->default_tcg_memop_mask
);
3441 gen_store_gpr(t0
, rt
);
3444 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
3445 ctx
->default_tcg_memop_mask
);
3446 gen_store_gpr(t0
, rt
);
3450 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
3451 gen_store_gpr(t0
, rt
);
3454 t1
= tcg_temp_new();
3456 * Do a byte access to possibly trigger a page
3457 * fault with the unaligned address.
3459 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3460 tcg_gen_andi_tl(t1
, t0
, 7);
3461 #ifndef TARGET_WORDS_BIGENDIAN
3462 tcg_gen_xori_tl(t1
, t1
, 7);
3464 tcg_gen_shli_tl(t1
, t1
, 3);
3465 tcg_gen_andi_tl(t0
, t0
, ~7);
3466 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3467 tcg_gen_shl_tl(t0
, t0
, t1
);
3468 t2
= tcg_const_tl(-1);
3469 tcg_gen_shl_tl(t2
, t2
, t1
);
3470 gen_load_gpr(t1
, rt
);
3471 tcg_gen_andc_tl(t1
, t1
, t2
);
3473 tcg_gen_or_tl(t0
, t0
, t1
);
3475 gen_store_gpr(t0
, rt
);
3478 t1
= tcg_temp_new();
3480 * Do a byte access to possibly trigger a page
3481 * fault with the unaligned address.
3483 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3484 tcg_gen_andi_tl(t1
, t0
, 7);
3485 #ifdef TARGET_WORDS_BIGENDIAN
3486 tcg_gen_xori_tl(t1
, t1
, 7);
3488 tcg_gen_shli_tl(t1
, t1
, 3);
3489 tcg_gen_andi_tl(t0
, t0
, ~7);
3490 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3491 tcg_gen_shr_tl(t0
, t0
, t1
);
3492 tcg_gen_xori_tl(t1
, t1
, 63);
3493 t2
= tcg_const_tl(0xfffffffffffffffeull
);
3494 tcg_gen_shl_tl(t2
, t2
, t1
);
3495 gen_load_gpr(t1
, rt
);
3496 tcg_gen_and_tl(t1
, t1
, t2
);
3498 tcg_gen_or_tl(t0
, t0
, t1
);
3500 gen_store_gpr(t0
, rt
);
3503 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3504 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3506 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3507 gen_store_gpr(t0
, rt
);
3511 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3512 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3514 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
3515 gen_store_gpr(t0
, rt
);
3518 mem_idx
= MIPS_HFLAG_UM
;
3521 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
3522 ctx
->default_tcg_memop_mask
);
3523 gen_store_gpr(t0
, rt
);
3526 mem_idx
= MIPS_HFLAG_UM
;
3529 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
3530 ctx
->default_tcg_memop_mask
);
3531 gen_store_gpr(t0
, rt
);
3534 mem_idx
= MIPS_HFLAG_UM
;
3537 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
3538 ctx
->default_tcg_memop_mask
);
3539 gen_store_gpr(t0
, rt
);
3542 mem_idx
= MIPS_HFLAG_UM
;
3545 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3546 gen_store_gpr(t0
, rt
);
3549 mem_idx
= MIPS_HFLAG_UM
;
3552 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3553 gen_store_gpr(t0
, rt
);
3556 mem_idx
= MIPS_HFLAG_UM
;
3559 t1
= tcg_temp_new();
3561 * Do a byte access to possibly trigger a page
3562 * fault with the unaligned address.
3564 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3565 tcg_gen_andi_tl(t1
, t0
, 3);
3566 #ifndef TARGET_WORDS_BIGENDIAN
3567 tcg_gen_xori_tl(t1
, t1
, 3);
3569 tcg_gen_shli_tl(t1
, t1
, 3);
3570 tcg_gen_andi_tl(t0
, t0
, ~3);
3571 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3572 tcg_gen_shl_tl(t0
, t0
, t1
);
3573 t2
= tcg_const_tl(-1);
3574 tcg_gen_shl_tl(t2
, t2
, t1
);
3575 gen_load_gpr(t1
, rt
);
3576 tcg_gen_andc_tl(t1
, t1
, t2
);
3578 tcg_gen_or_tl(t0
, t0
, t1
);
3580 tcg_gen_ext32s_tl(t0
, t0
);
3581 gen_store_gpr(t0
, rt
);
3584 mem_idx
= MIPS_HFLAG_UM
;
3587 t1
= tcg_temp_new();
3589 * Do a byte access to possibly trigger a page
3590 * fault with the unaligned address.
3592 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3593 tcg_gen_andi_tl(t1
, t0
, 3);
3594 #ifdef TARGET_WORDS_BIGENDIAN
3595 tcg_gen_xori_tl(t1
, t1
, 3);
3597 tcg_gen_shli_tl(t1
, t1
, 3);
3598 tcg_gen_andi_tl(t0
, t0
, ~3);
3599 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3600 tcg_gen_shr_tl(t0
, t0
, t1
);
3601 tcg_gen_xori_tl(t1
, t1
, 31);
3602 t2
= tcg_const_tl(0xfffffffeull
);
3603 tcg_gen_shl_tl(t2
, t2
, t1
);
3604 gen_load_gpr(t1
, rt
);
3605 tcg_gen_and_tl(t1
, t1
, t2
);
3607 tcg_gen_or_tl(t0
, t0
, t1
);
3609 tcg_gen_ext32s_tl(t0
, t0
);
3610 gen_store_gpr(t0
, rt
);
3613 mem_idx
= MIPS_HFLAG_UM
;
3617 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3618 gen_store_gpr(t0
, rt
);
3624 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3625 uint32_t reg1
, uint32_t reg2
)
3627 TCGv taddr
= tcg_temp_new();
3628 TCGv_i64 tval
= tcg_temp_new_i64();
3629 TCGv tmp1
= tcg_temp_new();
3630 TCGv tmp2
= tcg_temp_new();
3632 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3633 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3634 #ifdef TARGET_WORDS_BIGENDIAN
3635 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3637 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3639 gen_store_gpr(tmp1
, reg1
);
3640 tcg_temp_free(tmp1
);
3641 gen_store_gpr(tmp2
, reg2
);
3642 tcg_temp_free(tmp2
);
3643 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3644 tcg_temp_free_i64(tval
);
3645 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3646 tcg_temp_free(taddr
);
3650 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3651 int base
, int offset
)
3653 TCGv t0
= tcg_temp_new();
3654 TCGv t1
= tcg_temp_new();
3655 int mem_idx
= ctx
->mem_idx
;
3657 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3658 gen_load_gpr(t1
, rt
);
3660 #if defined(TARGET_MIPS64)
3662 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3663 ctx
->default_tcg_memop_mask
);
3666 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3669 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3673 mem_idx
= MIPS_HFLAG_UM
;
3676 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3677 ctx
->default_tcg_memop_mask
);
3680 mem_idx
= MIPS_HFLAG_UM
;
3683 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3684 ctx
->default_tcg_memop_mask
);
3687 mem_idx
= MIPS_HFLAG_UM
;
3690 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3693 mem_idx
= MIPS_HFLAG_UM
;
3696 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3699 mem_idx
= MIPS_HFLAG_UM
;
3702 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3710 /* Store conditional */
3711 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3712 MemOp tcg_mo
, bool eva
)
3715 TCGLabel
*l1
= gen_new_label();
3716 TCGLabel
*done
= gen_new_label();
3718 t0
= tcg_temp_new();
3719 addr
= tcg_temp_new();
3720 /* compare the address against that of the preceeding LL */
3721 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3722 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3723 tcg_temp_free(addr
);
3724 tcg_gen_movi_tl(t0
, 0);
3725 gen_store_gpr(t0
, rt
);
3729 /* generate cmpxchg */
3730 val
= tcg_temp_new();
3731 gen_load_gpr(val
, rt
);
3732 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3733 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3734 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3735 gen_store_gpr(t0
, rt
);
3738 gen_set_label(done
);
3743 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3744 uint32_t reg1
, uint32_t reg2
, bool eva
)
3746 TCGv taddr
= tcg_temp_local_new();
3747 TCGv lladdr
= tcg_temp_local_new();
3748 TCGv_i64 tval
= tcg_temp_new_i64();
3749 TCGv_i64 llval
= tcg_temp_new_i64();
3750 TCGv_i64 val
= tcg_temp_new_i64();
3751 TCGv tmp1
= tcg_temp_new();
3752 TCGv tmp2
= tcg_temp_new();
3753 TCGLabel
*lab_fail
= gen_new_label();
3754 TCGLabel
*lab_done
= gen_new_label();
3756 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3758 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3759 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3761 gen_load_gpr(tmp1
, reg1
);
3762 gen_load_gpr(tmp2
, reg2
);
3764 #ifdef TARGET_WORDS_BIGENDIAN
3765 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3767 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3770 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3771 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3772 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3774 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3776 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3778 gen_set_label(lab_fail
);
3781 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3783 gen_set_label(lab_done
);
3784 tcg_gen_movi_tl(lladdr
, -1);
3785 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3788 /* Load and store */
3789 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3793 * Don't do NOP if destination is zero: we must perform the actual
3799 TCGv_i32 fp0
= tcg_temp_new_i32();
3800 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3801 ctx
->default_tcg_memop_mask
);
3802 gen_store_fpr32(ctx
, fp0
, ft
);
3803 tcg_temp_free_i32(fp0
);
3808 TCGv_i32 fp0
= tcg_temp_new_i32();
3809 gen_load_fpr32(ctx
, fp0
, ft
);
3810 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3811 ctx
->default_tcg_memop_mask
);
3812 tcg_temp_free_i32(fp0
);
3817 TCGv_i64 fp0
= tcg_temp_new_i64();
3818 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3819 ctx
->default_tcg_memop_mask
);
3820 gen_store_fpr64(ctx
, fp0
, ft
);
3821 tcg_temp_free_i64(fp0
);
3826 TCGv_i64 fp0
= tcg_temp_new_i64();
3827 gen_load_fpr64(ctx
, fp0
, ft
);
3828 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3829 ctx
->default_tcg_memop_mask
);
3830 tcg_temp_free_i64(fp0
);
3834 MIPS_INVAL("flt_ldst");
3835 generate_exception_end(ctx
, EXCP_RI
);
3840 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3841 int rs
, int16_t imm
)
3843 TCGv t0
= tcg_temp_new();
3845 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3846 check_cp1_enabled(ctx
);
3850 check_insn(ctx
, ISA_MIPS2
);
3853 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3854 gen_flt_ldst(ctx
, op
, rt
, t0
);
3857 generate_exception_err(ctx
, EXCP_CpU
, 1);
3862 /* Arithmetic with immediate operand */
3863 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3864 int rt
, int rs
, int imm
)
3866 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3868 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3870 * If no destination, treat it as a NOP.
3871 * For addi, we must generate the overflow exception when needed.
3878 TCGv t0
= tcg_temp_local_new();
3879 TCGv t1
= tcg_temp_new();
3880 TCGv t2
= tcg_temp_new();
3881 TCGLabel
*l1
= gen_new_label();
3883 gen_load_gpr(t1
, rs
);
3884 tcg_gen_addi_tl(t0
, t1
, uimm
);
3885 tcg_gen_ext32s_tl(t0
, t0
);
3887 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3888 tcg_gen_xori_tl(t2
, t0
, uimm
);
3889 tcg_gen_and_tl(t1
, t1
, t2
);
3891 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3893 /* operands of same sign, result different sign */
3894 generate_exception(ctx
, EXCP_OVERFLOW
);
3896 tcg_gen_ext32s_tl(t0
, t0
);
3897 gen_store_gpr(t0
, rt
);
3903 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3904 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3906 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3909 #if defined(TARGET_MIPS64)
3912 TCGv t0
= tcg_temp_local_new();
3913 TCGv t1
= tcg_temp_new();
3914 TCGv t2
= tcg_temp_new();
3915 TCGLabel
*l1
= gen_new_label();
3917 gen_load_gpr(t1
, rs
);
3918 tcg_gen_addi_tl(t0
, t1
, uimm
);
3920 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3921 tcg_gen_xori_tl(t2
, t0
, uimm
);
3922 tcg_gen_and_tl(t1
, t1
, t2
);
3924 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3926 /* operands of same sign, result different sign */
3927 generate_exception(ctx
, EXCP_OVERFLOW
);
3929 gen_store_gpr(t0
, rt
);
3935 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3937 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3944 /* Logic with immediate operand */
3945 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3946 int rt
, int rs
, int16_t imm
)
3951 /* If no destination, treat it as a NOP. */
3954 uimm
= (uint16_t)imm
;
3957 if (likely(rs
!= 0)) {
3958 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3960 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
3965 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3967 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3971 if (likely(rs
!= 0)) {
3972 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3974 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3978 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
3980 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
3981 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3983 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
3992 /* Set on less than with immediate operand */
3993 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
3994 int rt
, int rs
, int16_t imm
)
3996 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
4000 /* If no destination, treat it as a NOP. */
4003 t0
= tcg_temp_new();
4004 gen_load_gpr(t0
, rs
);
4007 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
4010 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
4016 /* Shifts with immediate operand */
4017 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
4018 int rt
, int rs
, int16_t imm
)
4020 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
4024 /* If no destination, treat it as a NOP. */
4028 t0
= tcg_temp_new();
4029 gen_load_gpr(t0
, rs
);
4032 tcg_gen_shli_tl(t0
, t0
, uimm
);
4033 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4036 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4040 tcg_gen_ext32u_tl(t0
, t0
);
4041 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4043 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4048 TCGv_i32 t1
= tcg_temp_new_i32();
4050 tcg_gen_trunc_tl_i32(t1
, t0
);
4051 tcg_gen_rotri_i32(t1
, t1
, uimm
);
4052 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
4053 tcg_temp_free_i32(t1
);
4055 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4058 #if defined(TARGET_MIPS64)
4060 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
4063 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4066 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4070 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
4072 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
4076 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4079 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4082 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4085 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4093 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
4094 int rd
, int rs
, int rt
)
4096 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
4097 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
4099 * If no destination, treat it as a NOP.
4100 * For add & sub, we must generate the overflow exception when needed.
4108 TCGv t0
= tcg_temp_local_new();
4109 TCGv t1
= tcg_temp_new();
4110 TCGv t2
= tcg_temp_new();
4111 TCGLabel
*l1
= gen_new_label();
4113 gen_load_gpr(t1
, rs
);
4114 gen_load_gpr(t2
, rt
);
4115 tcg_gen_add_tl(t0
, t1
, t2
);
4116 tcg_gen_ext32s_tl(t0
, t0
);
4117 tcg_gen_xor_tl(t1
, t1
, t2
);
4118 tcg_gen_xor_tl(t2
, t0
, t2
);
4119 tcg_gen_andc_tl(t1
, t2
, t1
);
4121 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4123 /* operands of same sign, result different sign */
4124 generate_exception(ctx
, EXCP_OVERFLOW
);
4126 gen_store_gpr(t0
, rd
);
4131 if (rs
!= 0 && rt
!= 0) {
4132 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4133 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4134 } else if (rs
== 0 && rt
!= 0) {
4135 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4136 } else if (rs
!= 0 && rt
== 0) {
4137 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4139 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4144 TCGv t0
= tcg_temp_local_new();
4145 TCGv t1
= tcg_temp_new();
4146 TCGv t2
= tcg_temp_new();
4147 TCGLabel
*l1
= gen_new_label();
4149 gen_load_gpr(t1
, rs
);
4150 gen_load_gpr(t2
, rt
);
4151 tcg_gen_sub_tl(t0
, t1
, t2
);
4152 tcg_gen_ext32s_tl(t0
, t0
);
4153 tcg_gen_xor_tl(t2
, t1
, t2
);
4154 tcg_gen_xor_tl(t1
, t0
, t1
);
4155 tcg_gen_and_tl(t1
, t1
, t2
);
4157 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4160 * operands of different sign, first operand and the result
4163 generate_exception(ctx
, EXCP_OVERFLOW
);
4165 gen_store_gpr(t0
, rd
);
4170 if (rs
!= 0 && rt
!= 0) {
4171 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4172 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4173 } else if (rs
== 0 && rt
!= 0) {
4174 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4175 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4176 } else if (rs
!= 0 && rt
== 0) {
4177 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4179 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4182 #if defined(TARGET_MIPS64)
4185 TCGv t0
= tcg_temp_local_new();
4186 TCGv t1
= tcg_temp_new();
4187 TCGv t2
= tcg_temp_new();
4188 TCGLabel
*l1
= gen_new_label();
4190 gen_load_gpr(t1
, rs
);
4191 gen_load_gpr(t2
, rt
);
4192 tcg_gen_add_tl(t0
, t1
, t2
);
4193 tcg_gen_xor_tl(t1
, t1
, t2
);
4194 tcg_gen_xor_tl(t2
, t0
, t2
);
4195 tcg_gen_andc_tl(t1
, t2
, t1
);
4197 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4199 /* operands of same sign, result different sign */
4200 generate_exception(ctx
, EXCP_OVERFLOW
);
4202 gen_store_gpr(t0
, rd
);
4207 if (rs
!= 0 && rt
!= 0) {
4208 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4209 } else if (rs
== 0 && rt
!= 0) {
4210 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4211 } else if (rs
!= 0 && rt
== 0) {
4212 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4214 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4219 TCGv t0
= tcg_temp_local_new();
4220 TCGv t1
= tcg_temp_new();
4221 TCGv t2
= tcg_temp_new();
4222 TCGLabel
*l1
= gen_new_label();
4224 gen_load_gpr(t1
, rs
);
4225 gen_load_gpr(t2
, rt
);
4226 tcg_gen_sub_tl(t0
, t1
, t2
);
4227 tcg_gen_xor_tl(t2
, t1
, t2
);
4228 tcg_gen_xor_tl(t1
, t0
, t1
);
4229 tcg_gen_and_tl(t1
, t1
, t2
);
4231 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4234 * Operands of different sign, first operand and result different
4237 generate_exception(ctx
, EXCP_OVERFLOW
);
4239 gen_store_gpr(t0
, rd
);
4244 if (rs
!= 0 && rt
!= 0) {
4245 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4246 } else if (rs
== 0 && rt
!= 0) {
4247 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4248 } else if (rs
!= 0 && rt
== 0) {
4249 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4251 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4256 if (likely(rs
!= 0 && rt
!= 0)) {
4257 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4258 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4260 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4266 /* Conditional move */
4267 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
4268 int rd
, int rs
, int rt
)
4273 /* If no destination, treat it as a NOP. */
4277 t0
= tcg_temp_new();
4278 gen_load_gpr(t0
, rt
);
4279 t1
= tcg_const_tl(0);
4280 t2
= tcg_temp_new();
4281 gen_load_gpr(t2
, rs
);
4284 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4287 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4290 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4293 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4302 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
4303 int rd
, int rs
, int rt
)
4306 /* If no destination, treat it as a NOP. */
4312 if (likely(rs
!= 0 && rt
!= 0)) {
4313 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4315 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4319 if (rs
!= 0 && rt
!= 0) {
4320 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4321 } else if (rs
== 0 && rt
!= 0) {
4322 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4323 } else if (rs
!= 0 && rt
== 0) {
4324 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4326 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
4330 if (likely(rs
!= 0 && rt
!= 0)) {
4331 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4332 } else if (rs
== 0 && rt
!= 0) {
4333 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4334 } else if (rs
!= 0 && rt
== 0) {
4335 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4337 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4341 if (likely(rs
!= 0 && rt
!= 0)) {
4342 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4343 } else if (rs
== 0 && rt
!= 0) {
4344 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4345 } else if (rs
!= 0 && rt
== 0) {
4346 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4348 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4354 /* Set on lower than */
4355 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
4356 int rd
, int rs
, int rt
)
4361 /* If no destination, treat it as a NOP. */
4365 t0
= tcg_temp_new();
4366 t1
= tcg_temp_new();
4367 gen_load_gpr(t0
, rs
);
4368 gen_load_gpr(t1
, rt
);
4371 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
4374 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
4382 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
4383 int rd
, int rs
, int rt
)
4389 * If no destination, treat it as a NOP.
4390 * For add & sub, we must generate the overflow exception when needed.
4395 t0
= tcg_temp_new();
4396 t1
= tcg_temp_new();
4397 gen_load_gpr(t0
, rs
);
4398 gen_load_gpr(t1
, rt
);
4401 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4402 tcg_gen_shl_tl(t0
, t1
, t0
);
4403 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4406 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4407 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4410 tcg_gen_ext32u_tl(t1
, t1
);
4411 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4412 tcg_gen_shr_tl(t0
, t1
, t0
);
4413 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4417 TCGv_i32 t2
= tcg_temp_new_i32();
4418 TCGv_i32 t3
= tcg_temp_new_i32();
4420 tcg_gen_trunc_tl_i32(t2
, t0
);
4421 tcg_gen_trunc_tl_i32(t3
, t1
);
4422 tcg_gen_andi_i32(t2
, t2
, 0x1f);
4423 tcg_gen_rotr_i32(t2
, t3
, t2
);
4424 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4425 tcg_temp_free_i32(t2
);
4426 tcg_temp_free_i32(t3
);
4429 #if defined(TARGET_MIPS64)
4431 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4432 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
4435 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4436 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4439 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4440 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
4443 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4444 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
4452 #if defined(TARGET_MIPS64)
4453 /* Copy GPR to and from TX79 HI1/LO1 register. */
4454 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
4456 if (reg
== 0 && (opc
== MMI_OPC_MFHI1
|| opc
== MMI_OPC_MFLO1
)) {
4463 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[1]);
4466 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[1]);
4470 tcg_gen_mov_tl(cpu_HI
[1], cpu_gpr
[reg
]);
4472 tcg_gen_movi_tl(cpu_HI
[1], 0);
4477 tcg_gen_mov_tl(cpu_LO
[1], cpu_gpr
[reg
]);
4479 tcg_gen_movi_tl(cpu_LO
[1], 0);
4483 MIPS_INVAL("mfthilo1 TX79");
4484 generate_exception_end(ctx
, EXCP_RI
);
4490 /* Arithmetic on HI/LO registers */
4491 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
4493 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
4504 #if defined(TARGET_MIPS64)
4506 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4510 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4514 #if defined(TARGET_MIPS64)
4516 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4520 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4525 #if defined(TARGET_MIPS64)
4527 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4531 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4534 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
4539 #if defined(TARGET_MIPS64)
4541 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4545 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4548 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4554 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4557 TCGv t0
= tcg_const_tl(addr
);
4558 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4559 gen_store_gpr(t0
, reg
);
4563 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4569 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4572 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4573 addr
= addr_add(ctx
, pc
, offset
);
4574 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4578 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4579 addr
= addr_add(ctx
, pc
, offset
);
4580 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4582 #if defined(TARGET_MIPS64)
4585 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4586 addr
= addr_add(ctx
, pc
, offset
);
4587 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4591 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4594 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4595 addr
= addr_add(ctx
, pc
, offset
);
4596 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4601 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4602 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4603 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4606 #if defined(TARGET_MIPS64)
4607 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4608 case R6_OPC_LDPC
+ (1 << 16):
4609 case R6_OPC_LDPC
+ (2 << 16):
4610 case R6_OPC_LDPC
+ (3 << 16):
4612 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4613 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4614 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4618 MIPS_INVAL("OPC_PCREL");
4619 generate_exception_end(ctx
, EXCP_RI
);
4626 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4635 t0
= tcg_temp_new();
4636 t1
= tcg_temp_new();
4638 gen_load_gpr(t0
, rs
);
4639 gen_load_gpr(t1
, rt
);
4644 TCGv t2
= tcg_temp_new();
4645 TCGv t3
= tcg_temp_new();
4646 tcg_gen_ext32s_tl(t0
, t0
);
4647 tcg_gen_ext32s_tl(t1
, t1
);
4648 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4649 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4650 tcg_gen_and_tl(t2
, t2
, t3
);
4651 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4652 tcg_gen_or_tl(t2
, t2
, t3
);
4653 tcg_gen_movi_tl(t3
, 0);
4654 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4655 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4656 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4663 TCGv t2
= tcg_temp_new();
4664 TCGv t3
= tcg_temp_new();
4665 tcg_gen_ext32s_tl(t0
, t0
);
4666 tcg_gen_ext32s_tl(t1
, t1
);
4667 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4668 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4669 tcg_gen_and_tl(t2
, t2
, t3
);
4670 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4671 tcg_gen_or_tl(t2
, t2
, t3
);
4672 tcg_gen_movi_tl(t3
, 0);
4673 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4674 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4675 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4682 TCGv t2
= tcg_const_tl(0);
4683 TCGv t3
= tcg_const_tl(1);
4684 tcg_gen_ext32u_tl(t0
, t0
);
4685 tcg_gen_ext32u_tl(t1
, t1
);
4686 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4687 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4688 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4695 TCGv t2
= tcg_const_tl(0);
4696 TCGv t3
= tcg_const_tl(1);
4697 tcg_gen_ext32u_tl(t0
, t0
);
4698 tcg_gen_ext32u_tl(t1
, t1
);
4699 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4700 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4701 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4708 TCGv_i32 t2
= tcg_temp_new_i32();
4709 TCGv_i32 t3
= tcg_temp_new_i32();
4710 tcg_gen_trunc_tl_i32(t2
, t0
);
4711 tcg_gen_trunc_tl_i32(t3
, t1
);
4712 tcg_gen_mul_i32(t2
, t2
, t3
);
4713 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4714 tcg_temp_free_i32(t2
);
4715 tcg_temp_free_i32(t3
);
4720 TCGv_i32 t2
= tcg_temp_new_i32();
4721 TCGv_i32 t3
= tcg_temp_new_i32();
4722 tcg_gen_trunc_tl_i32(t2
, t0
);
4723 tcg_gen_trunc_tl_i32(t3
, t1
);
4724 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4725 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4726 tcg_temp_free_i32(t2
);
4727 tcg_temp_free_i32(t3
);
4732 TCGv_i32 t2
= tcg_temp_new_i32();
4733 TCGv_i32 t3
= tcg_temp_new_i32();
4734 tcg_gen_trunc_tl_i32(t2
, t0
);
4735 tcg_gen_trunc_tl_i32(t3
, t1
);
4736 tcg_gen_mul_i32(t2
, t2
, t3
);
4737 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4738 tcg_temp_free_i32(t2
);
4739 tcg_temp_free_i32(t3
);
4744 TCGv_i32 t2
= tcg_temp_new_i32();
4745 TCGv_i32 t3
= tcg_temp_new_i32();
4746 tcg_gen_trunc_tl_i32(t2
, t0
);
4747 tcg_gen_trunc_tl_i32(t3
, t1
);
4748 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4749 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4750 tcg_temp_free_i32(t2
);
4751 tcg_temp_free_i32(t3
);
4754 #if defined(TARGET_MIPS64)
4757 TCGv t2
= tcg_temp_new();
4758 TCGv t3
= tcg_temp_new();
4759 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4760 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4761 tcg_gen_and_tl(t2
, t2
, t3
);
4762 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4763 tcg_gen_or_tl(t2
, t2
, t3
);
4764 tcg_gen_movi_tl(t3
, 0);
4765 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4766 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4773 TCGv t2
= tcg_temp_new();
4774 TCGv t3
= tcg_temp_new();
4775 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4776 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4777 tcg_gen_and_tl(t2
, t2
, t3
);
4778 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4779 tcg_gen_or_tl(t2
, t2
, t3
);
4780 tcg_gen_movi_tl(t3
, 0);
4781 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4782 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4789 TCGv t2
= tcg_const_tl(0);
4790 TCGv t3
= tcg_const_tl(1);
4791 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4792 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4799 TCGv t2
= tcg_const_tl(0);
4800 TCGv t3
= tcg_const_tl(1);
4801 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4802 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4808 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4812 TCGv t2
= tcg_temp_new();
4813 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4818 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4822 TCGv t2
= tcg_temp_new();
4823 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4829 MIPS_INVAL("r6 mul/div");
4830 generate_exception_end(ctx
, EXCP_RI
);
4838 #if defined(TARGET_MIPS64)
4839 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4843 t0
= tcg_temp_new();
4844 t1
= tcg_temp_new();
4846 gen_load_gpr(t0
, rs
);
4847 gen_load_gpr(t1
, rt
);
4852 TCGv t2
= tcg_temp_new();
4853 TCGv t3
= tcg_temp_new();
4854 tcg_gen_ext32s_tl(t0
, t0
);
4855 tcg_gen_ext32s_tl(t1
, t1
);
4856 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4857 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4858 tcg_gen_and_tl(t2
, t2
, t3
);
4859 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4860 tcg_gen_or_tl(t2
, t2
, t3
);
4861 tcg_gen_movi_tl(t3
, 0);
4862 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4863 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4864 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4865 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4866 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4873 TCGv t2
= tcg_const_tl(0);
4874 TCGv t3
= tcg_const_tl(1);
4875 tcg_gen_ext32u_tl(t0
, t0
);
4876 tcg_gen_ext32u_tl(t1
, t1
);
4877 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4878 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4879 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4880 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4881 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4887 MIPS_INVAL("div1 TX79");
4888 generate_exception_end(ctx
, EXCP_RI
);
4897 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4898 int acc
, int rs
, int rt
)
4902 t0
= tcg_temp_new();
4903 t1
= tcg_temp_new();
4905 gen_load_gpr(t0
, rs
);
4906 gen_load_gpr(t1
, rt
);
4915 TCGv t2
= tcg_temp_new();
4916 TCGv t3
= tcg_temp_new();
4917 tcg_gen_ext32s_tl(t0
, t0
);
4918 tcg_gen_ext32s_tl(t1
, t1
);
4919 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4920 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4921 tcg_gen_and_tl(t2
, t2
, t3
);
4922 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4923 tcg_gen_or_tl(t2
, t2
, t3
);
4924 tcg_gen_movi_tl(t3
, 0);
4925 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4926 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4927 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4928 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4929 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4936 TCGv t2
= tcg_const_tl(0);
4937 TCGv t3
= tcg_const_tl(1);
4938 tcg_gen_ext32u_tl(t0
, t0
);
4939 tcg_gen_ext32u_tl(t1
, t1
);
4940 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4941 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4942 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4943 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4944 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4951 TCGv_i32 t2
= tcg_temp_new_i32();
4952 TCGv_i32 t3
= tcg_temp_new_i32();
4953 tcg_gen_trunc_tl_i32(t2
, t0
);
4954 tcg_gen_trunc_tl_i32(t3
, t1
);
4955 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4956 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4957 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4958 tcg_temp_free_i32(t2
);
4959 tcg_temp_free_i32(t3
);
4964 TCGv_i32 t2
= tcg_temp_new_i32();
4965 TCGv_i32 t3
= tcg_temp_new_i32();
4966 tcg_gen_trunc_tl_i32(t2
, t0
);
4967 tcg_gen_trunc_tl_i32(t3
, t1
);
4968 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4969 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4970 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4971 tcg_temp_free_i32(t2
);
4972 tcg_temp_free_i32(t3
);
4975 #if defined(TARGET_MIPS64)
4978 TCGv t2
= tcg_temp_new();
4979 TCGv t3
= tcg_temp_new();
4980 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4981 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4982 tcg_gen_and_tl(t2
, t2
, t3
);
4983 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4984 tcg_gen_or_tl(t2
, t2
, t3
);
4985 tcg_gen_movi_tl(t3
, 0);
4986 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4987 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4988 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4995 TCGv t2
= tcg_const_tl(0);
4996 TCGv t3
= tcg_const_tl(1);
4997 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4998 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
4999 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
5005 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
5008 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
5013 TCGv_i64 t2
= tcg_temp_new_i64();
5014 TCGv_i64 t3
= tcg_temp_new_i64();
5016 tcg_gen_ext_tl_i64(t2
, t0
);
5017 tcg_gen_ext_tl_i64(t3
, t1
);
5018 tcg_gen_mul_i64(t2
, t2
, t3
);
5019 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5020 tcg_gen_add_i64(t2
, t2
, t3
);
5021 tcg_temp_free_i64(t3
);
5022 gen_move_low32(cpu_LO
[acc
], t2
);
5023 gen_move_high32(cpu_HI
[acc
], t2
);
5024 tcg_temp_free_i64(t2
);
5029 TCGv_i64 t2
= tcg_temp_new_i64();
5030 TCGv_i64 t3
= tcg_temp_new_i64();
5032 tcg_gen_ext32u_tl(t0
, t0
);
5033 tcg_gen_ext32u_tl(t1
, t1
);
5034 tcg_gen_extu_tl_i64(t2
, t0
);
5035 tcg_gen_extu_tl_i64(t3
, t1
);
5036 tcg_gen_mul_i64(t2
, t2
, t3
);
5037 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5038 tcg_gen_add_i64(t2
, t2
, t3
);
5039 tcg_temp_free_i64(t3
);
5040 gen_move_low32(cpu_LO
[acc
], t2
);
5041 gen_move_high32(cpu_HI
[acc
], t2
);
5042 tcg_temp_free_i64(t2
);
5047 TCGv_i64 t2
= tcg_temp_new_i64();
5048 TCGv_i64 t3
= tcg_temp_new_i64();
5050 tcg_gen_ext_tl_i64(t2
, t0
);
5051 tcg_gen_ext_tl_i64(t3
, t1
);
5052 tcg_gen_mul_i64(t2
, t2
, t3
);
5053 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5054 tcg_gen_sub_i64(t2
, t3
, t2
);
5055 tcg_temp_free_i64(t3
);
5056 gen_move_low32(cpu_LO
[acc
], t2
);
5057 gen_move_high32(cpu_HI
[acc
], t2
);
5058 tcg_temp_free_i64(t2
);
5063 TCGv_i64 t2
= tcg_temp_new_i64();
5064 TCGv_i64 t3
= tcg_temp_new_i64();
5066 tcg_gen_ext32u_tl(t0
, t0
);
5067 tcg_gen_ext32u_tl(t1
, t1
);
5068 tcg_gen_extu_tl_i64(t2
, t0
);
5069 tcg_gen_extu_tl_i64(t3
, t1
);
5070 tcg_gen_mul_i64(t2
, t2
, t3
);
5071 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5072 tcg_gen_sub_i64(t2
, t3
, t2
);
5073 tcg_temp_free_i64(t3
);
5074 gen_move_low32(cpu_LO
[acc
], t2
);
5075 gen_move_high32(cpu_HI
[acc
], t2
);
5076 tcg_temp_free_i64(t2
);
5080 MIPS_INVAL("mul/div");
5081 generate_exception_end(ctx
, EXCP_RI
);
5090 * These MULT[U] and MADD[U] instructions implemented in for example
5091 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5092 * architectures are special three-operand variants with the syntax
5094 * MULT[U][1] rd, rs, rt
5098 * (rd, LO, HI) <- rs * rt
5102 * MADD[U][1] rd, rs, rt
5106 * (rd, LO, HI) <- (LO, HI) + rs * rt
5108 * where the low-order 32-bits of the result is placed into both the
5109 * GPR rd and the special register LO. The high-order 32-bits of the
5110 * result is placed into the special register HI.
5112 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5113 * which is the zero register that always reads as 0.
5115 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
5116 int rd
, int rs
, int rt
)
5118 TCGv t0
= tcg_temp_new();
5119 TCGv t1
= tcg_temp_new();
5122 gen_load_gpr(t0
, rs
);
5123 gen_load_gpr(t1
, rt
);
5131 TCGv_i32 t2
= tcg_temp_new_i32();
5132 TCGv_i32 t3
= tcg_temp_new_i32();
5133 tcg_gen_trunc_tl_i32(t2
, t0
);
5134 tcg_gen_trunc_tl_i32(t3
, t1
);
5135 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
5137 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5139 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5140 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5141 tcg_temp_free_i32(t2
);
5142 tcg_temp_free_i32(t3
);
5145 case MMI_OPC_MULTU1
:
5150 TCGv_i32 t2
= tcg_temp_new_i32();
5151 TCGv_i32 t3
= tcg_temp_new_i32();
5152 tcg_gen_trunc_tl_i32(t2
, t0
);
5153 tcg_gen_trunc_tl_i32(t3
, t1
);
5154 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
5156 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5158 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5159 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5160 tcg_temp_free_i32(t2
);
5161 tcg_temp_free_i32(t3
);
5169 TCGv_i64 t2
= tcg_temp_new_i64();
5170 TCGv_i64 t3
= tcg_temp_new_i64();
5172 tcg_gen_ext_tl_i64(t2
, t0
);
5173 tcg_gen_ext_tl_i64(t3
, t1
);
5174 tcg_gen_mul_i64(t2
, t2
, t3
);
5175 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5176 tcg_gen_add_i64(t2
, t2
, t3
);
5177 tcg_temp_free_i64(t3
);
5178 gen_move_low32(cpu_LO
[acc
], t2
);
5179 gen_move_high32(cpu_HI
[acc
], t2
);
5181 gen_move_low32(cpu_gpr
[rd
], t2
);
5183 tcg_temp_free_i64(t2
);
5186 case MMI_OPC_MADDU1
:
5191 TCGv_i64 t2
= tcg_temp_new_i64();
5192 TCGv_i64 t3
= tcg_temp_new_i64();
5194 tcg_gen_ext32u_tl(t0
, t0
);
5195 tcg_gen_ext32u_tl(t1
, t1
);
5196 tcg_gen_extu_tl_i64(t2
, t0
);
5197 tcg_gen_extu_tl_i64(t3
, t1
);
5198 tcg_gen_mul_i64(t2
, t2
, t3
);
5199 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5200 tcg_gen_add_i64(t2
, t2
, t3
);
5201 tcg_temp_free_i64(t3
);
5202 gen_move_low32(cpu_LO
[acc
], t2
);
5203 gen_move_high32(cpu_HI
[acc
], t2
);
5205 gen_move_low32(cpu_gpr
[rd
], t2
);
5207 tcg_temp_free_i64(t2
);
5211 MIPS_INVAL("mul/madd TXx9");
5212 generate_exception_end(ctx
, EXCP_RI
);
5221 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
5222 int rd
, int rs
, int rt
)
5224 TCGv t0
= tcg_temp_new();
5225 TCGv t1
= tcg_temp_new();
5227 gen_load_gpr(t0
, rs
);
5228 gen_load_gpr(t1
, rt
);
5231 case OPC_VR54XX_MULS
:
5232 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
5234 case OPC_VR54XX_MULSU
:
5235 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
5237 case OPC_VR54XX_MACC
:
5238 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
5240 case OPC_VR54XX_MACCU
:
5241 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
5243 case OPC_VR54XX_MSAC
:
5244 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
5246 case OPC_VR54XX_MSACU
:
5247 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
5249 case OPC_VR54XX_MULHI
:
5250 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
5252 case OPC_VR54XX_MULHIU
:
5253 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
5255 case OPC_VR54XX_MULSHI
:
5256 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
5258 case OPC_VR54XX_MULSHIU
:
5259 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
5261 case OPC_VR54XX_MACCHI
:
5262 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
5264 case OPC_VR54XX_MACCHIU
:
5265 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
5267 case OPC_VR54XX_MSACHI
:
5268 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
5270 case OPC_VR54XX_MSACHIU
:
5271 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
5274 MIPS_INVAL("mul vr54xx");
5275 generate_exception_end(ctx
, EXCP_RI
);
5278 gen_store_gpr(t0
, rd
);
5285 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
5295 gen_load_gpr(t0
, rs
);
5300 #if defined(TARGET_MIPS64)
5304 tcg_gen_not_tl(t0
, t0
);
5313 tcg_gen_ext32u_tl(t0
, t0
);
5314 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
5315 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
5317 #if defined(TARGET_MIPS64)
5322 tcg_gen_clzi_i64(t0
, t0
, 64);
5328 /* Godson integer instructions */
5329 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
5330 int rd
, int rs
, int rt
)
5342 case OPC_MULTU_G_2E
:
5343 case OPC_MULTU_G_2F
:
5344 #if defined(TARGET_MIPS64)
5345 case OPC_DMULT_G_2E
:
5346 case OPC_DMULT_G_2F
:
5347 case OPC_DMULTU_G_2E
:
5348 case OPC_DMULTU_G_2F
:
5350 t0
= tcg_temp_new();
5351 t1
= tcg_temp_new();
5354 t0
= tcg_temp_local_new();
5355 t1
= tcg_temp_local_new();
5359 gen_load_gpr(t0
, rs
);
5360 gen_load_gpr(t1
, rt
);
5365 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5366 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5368 case OPC_MULTU_G_2E
:
5369 case OPC_MULTU_G_2F
:
5370 tcg_gen_ext32u_tl(t0
, t0
);
5371 tcg_gen_ext32u_tl(t1
, t1
);
5372 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5373 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5378 TCGLabel
*l1
= gen_new_label();
5379 TCGLabel
*l2
= gen_new_label();
5380 TCGLabel
*l3
= gen_new_label();
5381 tcg_gen_ext32s_tl(t0
, t0
);
5382 tcg_gen_ext32s_tl(t1
, t1
);
5383 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5384 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5387 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5388 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5389 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5392 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5393 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5400 TCGLabel
*l1
= gen_new_label();
5401 TCGLabel
*l2
= gen_new_label();
5402 tcg_gen_ext32u_tl(t0
, t0
);
5403 tcg_gen_ext32u_tl(t1
, t1
);
5404 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5405 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5408 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5409 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5416 TCGLabel
*l1
= gen_new_label();
5417 TCGLabel
*l2
= gen_new_label();
5418 TCGLabel
*l3
= gen_new_label();
5419 tcg_gen_ext32u_tl(t0
, t0
);
5420 tcg_gen_ext32u_tl(t1
, t1
);
5421 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5422 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5423 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5425 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5428 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5429 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5436 TCGLabel
*l1
= gen_new_label();
5437 TCGLabel
*l2
= gen_new_label();
5438 tcg_gen_ext32u_tl(t0
, t0
);
5439 tcg_gen_ext32u_tl(t1
, t1
);
5440 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5441 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5444 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5445 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5449 #if defined(TARGET_MIPS64)
5450 case OPC_DMULT_G_2E
:
5451 case OPC_DMULT_G_2F
:
5452 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5454 case OPC_DMULTU_G_2E
:
5455 case OPC_DMULTU_G_2F
:
5456 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5461 TCGLabel
*l1
= gen_new_label();
5462 TCGLabel
*l2
= gen_new_label();
5463 TCGLabel
*l3
= gen_new_label();
5464 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5465 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5468 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5469 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5470 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5473 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5477 case OPC_DDIVU_G_2E
:
5478 case OPC_DDIVU_G_2F
:
5480 TCGLabel
*l1
= gen_new_label();
5481 TCGLabel
*l2
= gen_new_label();
5482 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5483 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5486 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5493 TCGLabel
*l1
= gen_new_label();
5494 TCGLabel
*l2
= gen_new_label();
5495 TCGLabel
*l3
= gen_new_label();
5496 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5497 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5498 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5500 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5503 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5507 case OPC_DMODU_G_2E
:
5508 case OPC_DMODU_G_2F
:
5510 TCGLabel
*l1
= gen_new_label();
5511 TCGLabel
*l2
= gen_new_label();
5512 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5513 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5516 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5527 /* Loongson multimedia instructions */
5528 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
5530 uint32_t opc
, shift_max
;
5533 opc
= MASK_LMI(ctx
->opcode
);
5539 t0
= tcg_temp_local_new_i64();
5540 t1
= tcg_temp_local_new_i64();
5543 t0
= tcg_temp_new_i64();
5544 t1
= tcg_temp_new_i64();
5548 check_cp1_enabled(ctx
);
5549 gen_load_fpr64(ctx
, t0
, rs
);
5550 gen_load_fpr64(ctx
, t1
, rt
);
5554 gen_helper_paddsh(t0
, t0
, t1
);
5557 gen_helper_paddush(t0
, t0
, t1
);
5560 gen_helper_paddh(t0
, t0
, t1
);
5563 gen_helper_paddw(t0
, t0
, t1
);
5566 gen_helper_paddsb(t0
, t0
, t1
);
5569 gen_helper_paddusb(t0
, t0
, t1
);
5572 gen_helper_paddb(t0
, t0
, t1
);
5576 gen_helper_psubsh(t0
, t0
, t1
);
5579 gen_helper_psubush(t0
, t0
, t1
);
5582 gen_helper_psubh(t0
, t0
, t1
);
5585 gen_helper_psubw(t0
, t0
, t1
);
5588 gen_helper_psubsb(t0
, t0
, t1
);
5591 gen_helper_psubusb(t0
, t0
, t1
);
5594 gen_helper_psubb(t0
, t0
, t1
);
5598 gen_helper_pshufh(t0
, t0
, t1
);
5601 gen_helper_packsswh(t0
, t0
, t1
);
5604 gen_helper_packsshb(t0
, t0
, t1
);
5607 gen_helper_packushb(t0
, t0
, t1
);
5611 gen_helper_punpcklhw(t0
, t0
, t1
);
5614 gen_helper_punpckhhw(t0
, t0
, t1
);
5617 gen_helper_punpcklbh(t0
, t0
, t1
);
5620 gen_helper_punpckhbh(t0
, t0
, t1
);
5623 gen_helper_punpcklwd(t0
, t0
, t1
);
5626 gen_helper_punpckhwd(t0
, t0
, t1
);
5630 gen_helper_pavgh(t0
, t0
, t1
);
5633 gen_helper_pavgb(t0
, t0
, t1
);
5636 gen_helper_pmaxsh(t0
, t0
, t1
);
5639 gen_helper_pminsh(t0
, t0
, t1
);
5642 gen_helper_pmaxub(t0
, t0
, t1
);
5645 gen_helper_pminub(t0
, t0
, t1
);
5649 gen_helper_pcmpeqw(t0
, t0
, t1
);
5652 gen_helper_pcmpgtw(t0
, t0
, t1
);
5655 gen_helper_pcmpeqh(t0
, t0
, t1
);
5658 gen_helper_pcmpgth(t0
, t0
, t1
);
5661 gen_helper_pcmpeqb(t0
, t0
, t1
);
5664 gen_helper_pcmpgtb(t0
, t0
, t1
);
5668 gen_helper_psllw(t0
, t0
, t1
);
5671 gen_helper_psllh(t0
, t0
, t1
);
5674 gen_helper_psrlw(t0
, t0
, t1
);
5677 gen_helper_psrlh(t0
, t0
, t1
);
5680 gen_helper_psraw(t0
, t0
, t1
);
5683 gen_helper_psrah(t0
, t0
, t1
);
5687 gen_helper_pmullh(t0
, t0
, t1
);
5690 gen_helper_pmulhh(t0
, t0
, t1
);
5693 gen_helper_pmulhuh(t0
, t0
, t1
);
5696 gen_helper_pmaddhw(t0
, t0
, t1
);
5700 gen_helper_pasubub(t0
, t0
, t1
);
5703 gen_helper_biadd(t0
, t0
);
5706 gen_helper_pmovmskb(t0
, t0
);
5710 tcg_gen_add_i64(t0
, t0
, t1
);
5713 tcg_gen_sub_i64(t0
, t0
, t1
);
5716 tcg_gen_xor_i64(t0
, t0
, t1
);
5719 tcg_gen_nor_i64(t0
, t0
, t1
);
5722 tcg_gen_and_i64(t0
, t0
, t1
);
5725 tcg_gen_or_i64(t0
, t0
, t1
);
5729 tcg_gen_andc_i64(t0
, t1
, t0
);
5733 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5736 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5739 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5742 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5746 tcg_gen_andi_i64(t1
, t1
, 3);
5747 tcg_gen_shli_i64(t1
, t1
, 4);
5748 tcg_gen_shr_i64(t0
, t0
, t1
);
5749 tcg_gen_ext16u_i64(t0
, t0
);
5753 tcg_gen_add_i64(t0
, t0
, t1
);
5754 tcg_gen_ext32s_i64(t0
, t0
);
5757 tcg_gen_sub_i64(t0
, t0
, t1
);
5758 tcg_gen_ext32s_i64(t0
, t0
);
5780 /* Make sure shift count isn't TCG undefined behaviour. */
5781 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5786 tcg_gen_shl_i64(t0
, t0
, t1
);
5791 * Since SRA is UndefinedResult without sign-extended inputs,
5792 * we can treat SRA and DSRA the same.
5794 tcg_gen_sar_i64(t0
, t0
, t1
);
5797 /* We want to shift in zeros for SRL; zero-extend first. */
5798 tcg_gen_ext32u_i64(t0
, t0
);
5801 tcg_gen_shr_i64(t0
, t0
, t1
);
5805 if (shift_max
== 32) {
5806 tcg_gen_ext32s_i64(t0
, t0
);
5809 /* Shifts larger than MAX produce zero. */
5810 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5811 tcg_gen_neg_i64(t1
, t1
);
5812 tcg_gen_and_i64(t0
, t0
, t1
);
5818 TCGv_i64 t2
= tcg_temp_new_i64();
5819 TCGLabel
*lab
= gen_new_label();
5821 tcg_gen_mov_i64(t2
, t0
);
5822 tcg_gen_add_i64(t0
, t1
, t2
);
5823 if (opc
== OPC_ADD_CP2
) {
5824 tcg_gen_ext32s_i64(t0
, t0
);
5826 tcg_gen_xor_i64(t1
, t1
, t2
);
5827 tcg_gen_xor_i64(t2
, t2
, t0
);
5828 tcg_gen_andc_i64(t1
, t2
, t1
);
5829 tcg_temp_free_i64(t2
);
5830 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5831 generate_exception(ctx
, EXCP_OVERFLOW
);
5839 TCGv_i64 t2
= tcg_temp_new_i64();
5840 TCGLabel
*lab
= gen_new_label();
5842 tcg_gen_mov_i64(t2
, t0
);
5843 tcg_gen_sub_i64(t0
, t1
, t2
);
5844 if (opc
== OPC_SUB_CP2
) {
5845 tcg_gen_ext32s_i64(t0
, t0
);
5847 tcg_gen_xor_i64(t1
, t1
, t2
);
5848 tcg_gen_xor_i64(t2
, t2
, t0
);
5849 tcg_gen_and_i64(t1
, t1
, t2
);
5850 tcg_temp_free_i64(t2
);
5851 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5852 generate_exception(ctx
, EXCP_OVERFLOW
);
5858 tcg_gen_ext32u_i64(t0
, t0
);
5859 tcg_gen_ext32u_i64(t1
, t1
);
5860 tcg_gen_mul_i64(t0
, t0
, t1
);
5870 * ??? Document is unclear: Set FCC[CC]. Does that mean the
5871 * FD field is the CC field?
5874 MIPS_INVAL("loongson_cp2");
5875 generate_exception_end(ctx
, EXCP_RI
);
5879 gen_store_fpr64(ctx
, t0
, rd
);
5881 tcg_temp_free_i64(t0
);
5882 tcg_temp_free_i64(t1
);
5886 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
5887 int rs
, int rt
, int16_t imm
)
5890 TCGv t0
= tcg_temp_new();
5891 TCGv t1
= tcg_temp_new();
5894 /* Load needed operands */
5902 /* Compare two registers */
5904 gen_load_gpr(t0
, rs
);
5905 gen_load_gpr(t1
, rt
);
5915 /* Compare register to immediate */
5916 if (rs
!= 0 || imm
!= 0) {
5917 gen_load_gpr(t0
, rs
);
5918 tcg_gen_movi_tl(t1
, (int32_t)imm
);
5925 case OPC_TEQ
: /* rs == rs */
5926 case OPC_TEQI
: /* r0 == 0 */
5927 case OPC_TGE
: /* rs >= rs */
5928 case OPC_TGEI
: /* r0 >= 0 */
5929 case OPC_TGEU
: /* rs >= rs unsigned */
5930 case OPC_TGEIU
: /* r0 >= 0 unsigned */
5932 generate_exception_end(ctx
, EXCP_TRAP
);
5934 case OPC_TLT
: /* rs < rs */
5935 case OPC_TLTI
: /* r0 < 0 */
5936 case OPC_TLTU
: /* rs < rs unsigned */
5937 case OPC_TLTIU
: /* r0 < 0 unsigned */
5938 case OPC_TNE
: /* rs != rs */
5939 case OPC_TNEI
: /* r0 != 0 */
5940 /* Never trap: treat as NOP. */
5944 TCGLabel
*l1
= gen_new_label();
5949 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
5953 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
5957 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
5961 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
5965 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
5969 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
5972 generate_exception(ctx
, EXCP_TRAP
);
5979 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
5981 if (unlikely(ctx
->base
.singlestep_enabled
)) {
5985 #ifndef CONFIG_USER_ONLY
5986 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
5992 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
5994 if (use_goto_tb(ctx
, dest
)) {
5997 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
6000 if (ctx
->base
.singlestep_enabled
) {
6001 save_cpu_state(ctx
, 0);
6002 gen_helper_raise_exception_debug(cpu_env
);
6004 tcg_gen_lookup_and_goto_ptr();
6008 /* Branches (before delay slot) */
6009 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
6011 int rs
, int rt
, int32_t offset
,
6014 target_ulong btgt
= -1;
6016 int bcond_compute
= 0;
6017 TCGv t0
= tcg_temp_new();
6018 TCGv t1
= tcg_temp_new();
6020 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
6021 #ifdef MIPS_DEBUG_DISAS
6022 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6023 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
6025 generate_exception_end(ctx
, EXCP_RI
);
6029 /* Load needed operands */
6035 /* Compare two registers */
6037 gen_load_gpr(t0
, rs
);
6038 gen_load_gpr(t1
, rt
);
6041 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6055 /* Compare to zero */
6057 gen_load_gpr(t0
, rs
);
6060 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6063 #if defined(TARGET_MIPS64)
6065 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
6067 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6070 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6075 /* Jump to immediate */
6076 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
6081 /* Jump to register */
6082 if (offset
!= 0 && offset
!= 16) {
6084 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6085 * others are reserved.
6087 MIPS_INVAL("jump hint");
6088 generate_exception_end(ctx
, EXCP_RI
);
6091 gen_load_gpr(btarget
, rs
);
6094 MIPS_INVAL("branch/jump");
6095 generate_exception_end(ctx
, EXCP_RI
);
6098 if (bcond_compute
== 0) {
6099 /* No condition to be computed */
6101 case OPC_BEQ
: /* rx == rx */
6102 case OPC_BEQL
: /* rx == rx likely */
6103 case OPC_BGEZ
: /* 0 >= 0 */
6104 case OPC_BGEZL
: /* 0 >= 0 likely */
6105 case OPC_BLEZ
: /* 0 <= 0 */
6106 case OPC_BLEZL
: /* 0 <= 0 likely */
6108 ctx
->hflags
|= MIPS_HFLAG_B
;
6110 case OPC_BGEZAL
: /* 0 >= 0 */
6111 case OPC_BGEZALL
: /* 0 >= 0 likely */
6112 /* Always take and link */
6114 ctx
->hflags
|= MIPS_HFLAG_B
;
6116 case OPC_BNE
: /* rx != rx */
6117 case OPC_BGTZ
: /* 0 > 0 */
6118 case OPC_BLTZ
: /* 0 < 0 */
6121 case OPC_BLTZAL
: /* 0 < 0 */
6123 * Handle as an unconditional branch to get correct delay
6127 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6128 ctx
->hflags
|= MIPS_HFLAG_B
;
6130 case OPC_BLTZALL
: /* 0 < 0 likely */
6131 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6132 /* Skip the instruction in the delay slot */
6133 ctx
->base
.pc_next
+= 4;
6135 case OPC_BNEL
: /* rx != rx likely */
6136 case OPC_BGTZL
: /* 0 > 0 likely */
6137 case OPC_BLTZL
: /* 0 < 0 likely */
6138 /* Skip the instruction in the delay slot */
6139 ctx
->base
.pc_next
+= 4;
6142 ctx
->hflags
|= MIPS_HFLAG_B
;
6145 ctx
->hflags
|= MIPS_HFLAG_BX
;
6149 ctx
->hflags
|= MIPS_HFLAG_B
;
6152 ctx
->hflags
|= MIPS_HFLAG_BR
;
6156 ctx
->hflags
|= MIPS_HFLAG_BR
;
6159 MIPS_INVAL("branch/jump");
6160 generate_exception_end(ctx
, EXCP_RI
);
6166 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6169 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6172 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6175 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6178 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6181 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6184 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6188 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6192 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6195 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6198 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6201 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6204 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6207 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6210 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6212 #if defined(TARGET_MIPS64)
6214 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6218 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6221 ctx
->hflags
|= MIPS_HFLAG_BC
;
6224 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6227 ctx
->hflags
|= MIPS_HFLAG_BL
;
6230 MIPS_INVAL("conditional branch/jump");
6231 generate_exception_end(ctx
, EXCP_RI
);
6236 ctx
->btarget
= btgt
;
6238 switch (delayslot_size
) {
6240 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6243 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6248 int post_delay
= insn_bytes
+ delayslot_size
;
6249 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6251 tcg_gen_movi_tl(cpu_gpr
[blink
],
6252 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6256 if (insn_bytes
== 2) {
6257 ctx
->hflags
|= MIPS_HFLAG_B16
;
6264 /* nanoMIPS Branches */
6265 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6267 int rs
, int rt
, int32_t offset
)
6269 target_ulong btgt
= -1;
6270 int bcond_compute
= 0;
6271 TCGv t0
= tcg_temp_new();
6272 TCGv t1
= tcg_temp_new();
6274 /* Load needed operands */
6278 /* Compare two registers */
6280 gen_load_gpr(t0
, rs
);
6281 gen_load_gpr(t1
, rt
);
6284 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6287 /* Compare to zero */
6289 gen_load_gpr(t0
, rs
);
6292 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6295 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6297 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6301 /* Jump to register */
6302 if (offset
!= 0 && offset
!= 16) {
6304 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6305 * others are reserved.
6307 MIPS_INVAL("jump hint");
6308 generate_exception_end(ctx
, EXCP_RI
);
6311 gen_load_gpr(btarget
, rs
);
6314 MIPS_INVAL("branch/jump");
6315 generate_exception_end(ctx
, EXCP_RI
);
6318 if (bcond_compute
== 0) {
6319 /* No condition to be computed */
6321 case OPC_BEQ
: /* rx == rx */
6323 ctx
->hflags
|= MIPS_HFLAG_B
;
6325 case OPC_BGEZAL
: /* 0 >= 0 */
6326 /* Always take and link */
6327 tcg_gen_movi_tl(cpu_gpr
[31],
6328 ctx
->base
.pc_next
+ insn_bytes
);
6329 ctx
->hflags
|= MIPS_HFLAG_B
;
6331 case OPC_BNE
: /* rx != rx */
6332 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6333 /* Skip the instruction in the delay slot */
6334 ctx
->base
.pc_next
+= 4;
6337 ctx
->hflags
|= MIPS_HFLAG_BR
;
6341 tcg_gen_movi_tl(cpu_gpr
[rt
],
6342 ctx
->base
.pc_next
+ insn_bytes
);
6344 ctx
->hflags
|= MIPS_HFLAG_BR
;
6347 MIPS_INVAL("branch/jump");
6348 generate_exception_end(ctx
, EXCP_RI
);
6354 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6357 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6360 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6361 tcg_gen_movi_tl(cpu_gpr
[31],
6362 ctx
->base
.pc_next
+ insn_bytes
);
6365 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6367 ctx
->hflags
|= MIPS_HFLAG_BC
;
6370 MIPS_INVAL("conditional branch/jump");
6371 generate_exception_end(ctx
, EXCP_RI
);
6376 ctx
->btarget
= btgt
;
6379 if (insn_bytes
== 2) {
6380 ctx
->hflags
|= MIPS_HFLAG_B16
;
6387 /* special3 bitfield operations */
6388 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6389 int rs
, int lsb
, int msb
)
6391 TCGv t0
= tcg_temp_new();
6392 TCGv t1
= tcg_temp_new();
6394 gen_load_gpr(t1
, rs
);
6397 if (lsb
+ msb
> 31) {
6401 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6404 * The two checks together imply that lsb == 0,
6405 * so this is a simple sign-extension.
6407 tcg_gen_ext32s_tl(t0
, t1
);
6410 #if defined(TARGET_MIPS64)
6419 if (lsb
+ msb
> 63) {
6422 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6429 gen_load_gpr(t0
, rt
);
6430 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6431 tcg_gen_ext32s_tl(t0
, t0
);
6433 #if defined(TARGET_MIPS64)
6444 gen_load_gpr(t0
, rt
);
6445 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6450 MIPS_INVAL("bitops");
6451 generate_exception_end(ctx
, EXCP_RI
);
6456 gen_store_gpr(t0
, rt
);
6461 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6466 /* If no destination, treat it as a NOP. */
6470 t0
= tcg_temp_new();
6471 gen_load_gpr(t0
, rt
);
6475 TCGv t1
= tcg_temp_new();
6476 TCGv t2
= tcg_const_tl(0x00FF00FF);
6478 tcg_gen_shri_tl(t1
, t0
, 8);
6479 tcg_gen_and_tl(t1
, t1
, t2
);
6480 tcg_gen_and_tl(t0
, t0
, t2
);
6481 tcg_gen_shli_tl(t0
, t0
, 8);
6482 tcg_gen_or_tl(t0
, t0
, t1
);
6485 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6489 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6492 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6494 #if defined(TARGET_MIPS64)
6497 TCGv t1
= tcg_temp_new();
6498 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6500 tcg_gen_shri_tl(t1
, t0
, 8);
6501 tcg_gen_and_tl(t1
, t1
, t2
);
6502 tcg_gen_and_tl(t0
, t0
, t2
);
6503 tcg_gen_shli_tl(t0
, t0
, 8);
6504 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6511 TCGv t1
= tcg_temp_new();
6512 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6514 tcg_gen_shri_tl(t1
, t0
, 16);
6515 tcg_gen_and_tl(t1
, t1
, t2
);
6516 tcg_gen_and_tl(t0
, t0
, t2
);
6517 tcg_gen_shli_tl(t0
, t0
, 16);
6518 tcg_gen_or_tl(t0
, t0
, t1
);
6519 tcg_gen_shri_tl(t1
, t0
, 32);
6520 tcg_gen_shli_tl(t0
, t0
, 32);
6521 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6528 MIPS_INVAL("bsfhl");
6529 generate_exception_end(ctx
, EXCP_RI
);
6536 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
6545 t0
= tcg_temp_new();
6546 t1
= tcg_temp_new();
6547 gen_load_gpr(t0
, rs
);
6548 gen_load_gpr(t1
, rt
);
6549 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
6550 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
6551 if (opc
== OPC_LSA
) {
6552 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
6561 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
6569 t0
= tcg_temp_new();
6570 if (bits
== 0 || bits
== wordsz
) {
6572 gen_load_gpr(t0
, rt
);
6574 gen_load_gpr(t0
, rs
);
6578 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6580 #if defined(TARGET_MIPS64)
6582 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
6587 TCGv t1
= tcg_temp_new();
6588 gen_load_gpr(t0
, rt
);
6589 gen_load_gpr(t1
, rs
);
6593 TCGv_i64 t2
= tcg_temp_new_i64();
6594 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
6595 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
6596 gen_move_low32(cpu_gpr
[rd
], t2
);
6597 tcg_temp_free_i64(t2
);
6600 #if defined(TARGET_MIPS64)
6602 tcg_gen_shli_tl(t0
, t0
, bits
);
6603 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
6604 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
6614 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6617 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
6620 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6623 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
6626 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
6633 t0
= tcg_temp_new();
6634 gen_load_gpr(t0
, rt
);
6637 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
6639 #if defined(TARGET_MIPS64)
6641 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
6648 #ifndef CONFIG_USER_ONLY
6649 /* CP0 (MMU and control) */
6650 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
6652 TCGv_i64 t0
= tcg_temp_new_i64();
6653 TCGv_i64 t1
= tcg_temp_new_i64();
6655 tcg_gen_ext_tl_i64(t0
, arg
);
6656 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6657 #if defined(TARGET_MIPS64)
6658 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
6660 tcg_gen_concat32_i64(t1
, t1
, t0
);
6662 tcg_gen_st_i64(t1
, cpu_env
, off
);
6663 tcg_temp_free_i64(t1
);
6664 tcg_temp_free_i64(t0
);
6667 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
6669 TCGv_i64 t0
= tcg_temp_new_i64();
6670 TCGv_i64 t1
= tcg_temp_new_i64();
6672 tcg_gen_ext_tl_i64(t0
, arg
);
6673 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6674 tcg_gen_concat32_i64(t1
, t1
, t0
);
6675 tcg_gen_st_i64(t1
, cpu_env
, off
);
6676 tcg_temp_free_i64(t1
);
6677 tcg_temp_free_i64(t0
);
6680 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
6682 TCGv_i64 t0
= tcg_temp_new_i64();
6684 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6685 #if defined(TARGET_MIPS64)
6686 tcg_gen_shri_i64(t0
, t0
, 30);
6688 tcg_gen_shri_i64(t0
, t0
, 32);
6690 gen_move_low32(arg
, t0
);
6691 tcg_temp_free_i64(t0
);
6694 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
6696 TCGv_i64 t0
= tcg_temp_new_i64();
6698 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6699 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
6700 gen_move_low32(arg
, t0
);
6701 tcg_temp_free_i64(t0
);
6704 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
6706 TCGv_i32 t0
= tcg_temp_new_i32();
6708 tcg_gen_ld_i32(t0
, cpu_env
, off
);
6709 tcg_gen_ext_i32_tl(arg
, t0
);
6710 tcg_temp_free_i32(t0
);
6713 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
6715 tcg_gen_ld_tl(arg
, cpu_env
, off
);
6716 tcg_gen_ext32s_tl(arg
, arg
);
6719 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
6721 TCGv_i32 t0
= tcg_temp_new_i32();
6723 tcg_gen_trunc_tl_i32(t0
, arg
);
6724 tcg_gen_st_i32(t0
, cpu_env
, off
);
6725 tcg_temp_free_i32(t0
);
6728 #define CP0_CHECK(c) \
6731 goto cp0_unimplemented; \
6735 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6737 const char *register_name
= "invalid";
6740 case CP0_REGISTER_02
:
6743 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6744 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6745 register_name
= "EntryLo0";
6748 goto cp0_unimplemented
;
6751 case CP0_REGISTER_03
:
6753 case CP0_REG03__ENTRYLO1
:
6754 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6755 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6756 register_name
= "EntryLo1";
6759 goto cp0_unimplemented
;
6762 case CP0_REGISTER_09
:
6764 case CP0_REG09__SAAR
:
6765 CP0_CHECK(ctx
->saar
);
6766 gen_helper_mfhc0_saar(arg
, cpu_env
);
6767 register_name
= "SAAR";
6770 goto cp0_unimplemented
;
6773 case CP0_REGISTER_17
:
6775 case CP0_REG17__LLADDR
:
6776 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
6777 ctx
->CP0_LLAddr_shift
);
6778 register_name
= "LLAddr";
6780 case CP0_REG17__MAAR
:
6781 CP0_CHECK(ctx
->mrp
);
6782 gen_helper_mfhc0_maar(arg
, cpu_env
);
6783 register_name
= "MAAR";
6786 goto cp0_unimplemented
;
6789 case CP0_REGISTER_19
:
6791 case CP0_REG19__WATCHHI0
:
6792 case CP0_REG19__WATCHHI1
:
6793 case CP0_REG19__WATCHHI2
:
6794 case CP0_REG19__WATCHHI3
:
6795 case CP0_REG19__WATCHHI4
:
6796 case CP0_REG19__WATCHHI5
:
6797 case CP0_REG19__WATCHHI6
:
6798 case CP0_REG19__WATCHHI7
:
6799 /* upper 32 bits are only available when Config5MI != 0 */
6801 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
6802 register_name
= "WatchHi";
6805 goto cp0_unimplemented
;
6808 case CP0_REGISTER_28
:
6814 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
6815 register_name
= "TagLo";
6818 goto cp0_unimplemented
;
6822 goto cp0_unimplemented
;
6824 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
6828 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
6829 register_name
, reg
, sel
);
6830 tcg_gen_movi_tl(arg
, 0);
6833 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6835 const char *register_name
= "invalid";
6836 uint64_t mask
= ctx
->PAMask
>> 36;
6839 case CP0_REGISTER_02
:
6842 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6843 tcg_gen_andi_tl(arg
, arg
, mask
);
6844 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6845 register_name
= "EntryLo0";
6848 goto cp0_unimplemented
;
6851 case CP0_REGISTER_03
:
6853 case CP0_REG03__ENTRYLO1
:
6854 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6855 tcg_gen_andi_tl(arg
, arg
, mask
);
6856 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6857 register_name
= "EntryLo1";
6860 goto cp0_unimplemented
;
6863 case CP0_REGISTER_09
:
6865 case CP0_REG09__SAAR
:
6866 CP0_CHECK(ctx
->saar
);
6867 gen_helper_mthc0_saar(cpu_env
, arg
);
6868 register_name
= "SAAR";
6871 goto cp0_unimplemented
;
6874 case CP0_REGISTER_17
:
6876 case CP0_REG17__LLADDR
:
6878 * LLAddr is read-only (the only exception is bit 0 if LLB is
6879 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6880 * relevant for modern MIPS cores supporting MTHC0, therefore
6881 * treating MTHC0 to LLAddr as NOP.
6883 register_name
= "LLAddr";
6885 case CP0_REG17__MAAR
:
6886 CP0_CHECK(ctx
->mrp
);
6887 gen_helper_mthc0_maar(cpu_env
, arg
);
6888 register_name
= "MAAR";
6891 goto cp0_unimplemented
;
6894 case CP0_REGISTER_19
:
6896 case CP0_REG19__WATCHHI0
:
6897 case CP0_REG19__WATCHHI1
:
6898 case CP0_REG19__WATCHHI2
:
6899 case CP0_REG19__WATCHHI3
:
6900 case CP0_REG19__WATCHHI4
:
6901 case CP0_REG19__WATCHHI5
:
6902 case CP0_REG19__WATCHHI6
:
6903 case CP0_REG19__WATCHHI7
:
6904 /* upper 32 bits are only available when Config5MI != 0 */
6906 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
6907 register_name
= "WatchHi";
6910 goto cp0_unimplemented
;
6913 case CP0_REGISTER_28
:
6919 tcg_gen_andi_tl(arg
, arg
, mask
);
6920 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6921 register_name
= "TagLo";
6924 goto cp0_unimplemented
;
6928 goto cp0_unimplemented
;
6930 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
6933 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
6934 register_name
, reg
, sel
);
6937 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
6939 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
6940 tcg_gen_movi_tl(arg
, 0);
6942 tcg_gen_movi_tl(arg
, ~0);
6946 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6948 const char *register_name
= "invalid";
6951 check_insn(ctx
, ISA_MIPS32
);
6955 case CP0_REGISTER_00
:
6957 case CP0_REG00__INDEX
:
6958 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6959 register_name
= "Index";
6961 case CP0_REG00__MVPCONTROL
:
6962 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6963 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6964 register_name
= "MVPControl";
6966 case CP0_REG00__MVPCONF0
:
6967 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6968 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6969 register_name
= "MVPConf0";
6971 case CP0_REG00__MVPCONF1
:
6972 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6973 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6974 register_name
= "MVPConf1";
6976 case CP0_REG00__VPCONTROL
:
6978 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
6979 register_name
= "VPControl";
6982 goto cp0_unimplemented
;
6985 case CP0_REGISTER_01
:
6987 case CP0_REG01__RANDOM
:
6988 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6989 gen_helper_mfc0_random(arg
, cpu_env
);
6990 register_name
= "Random";
6992 case CP0_REG01__VPECONTROL
:
6993 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6994 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6995 register_name
= "VPEControl";
6997 case CP0_REG01__VPECONF0
:
6998 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6999 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7000 register_name
= "VPEConf0";
7002 case CP0_REG01__VPECONF1
:
7003 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7004 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7005 register_name
= "VPEConf1";
7007 case CP0_REG01__YQMASK
:
7008 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7009 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
7010 register_name
= "YQMask";
7012 case CP0_REG01__VPESCHEDULE
:
7013 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7014 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7015 register_name
= "VPESchedule";
7017 case CP0_REG01__VPESCHEFBACK
:
7018 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7019 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7020 register_name
= "VPEScheFBack";
7022 case CP0_REG01__VPEOPT
:
7023 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7024 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7025 register_name
= "VPEOpt";
7028 goto cp0_unimplemented
;
7031 case CP0_REGISTER_02
:
7033 case CP0_REG02__ENTRYLO0
:
7035 TCGv_i64 tmp
= tcg_temp_new_i64();
7036 tcg_gen_ld_i64(tmp
, cpu_env
,
7037 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7038 #if defined(TARGET_MIPS64)
7040 /* Move RI/XI fields to bits 31:30 */
7041 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7042 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7045 gen_move_low32(arg
, tmp
);
7046 tcg_temp_free_i64(tmp
);
7048 register_name
= "EntryLo0";
7050 case CP0_REG02__TCSTATUS
:
7051 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7052 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7053 register_name
= "TCStatus";
7055 case CP0_REG02__TCBIND
:
7056 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7057 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7058 register_name
= "TCBind";
7060 case CP0_REG02__TCRESTART
:
7061 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7062 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
7063 register_name
= "TCRestart";
7065 case CP0_REG02__TCHALT
:
7066 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7067 gen_helper_mfc0_tchalt(arg
, cpu_env
);
7068 register_name
= "TCHalt";
7070 case CP0_REG02__TCCONTEXT
:
7071 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7072 gen_helper_mfc0_tccontext(arg
, cpu_env
);
7073 register_name
= "TCContext";
7075 case CP0_REG02__TCSCHEDULE
:
7076 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7077 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
7078 register_name
= "TCSchedule";
7080 case CP0_REG02__TCSCHEFBACK
:
7081 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7082 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
7083 register_name
= "TCScheFBack";
7086 goto cp0_unimplemented
;
7089 case CP0_REGISTER_03
:
7091 case CP0_REG03__ENTRYLO1
:
7093 TCGv_i64 tmp
= tcg_temp_new_i64();
7094 tcg_gen_ld_i64(tmp
, cpu_env
,
7095 offsetof(CPUMIPSState
, CP0_EntryLo1
));
7096 #if defined(TARGET_MIPS64)
7098 /* Move RI/XI fields to bits 31:30 */
7099 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7100 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7103 gen_move_low32(arg
, tmp
);
7104 tcg_temp_free_i64(tmp
);
7106 register_name
= "EntryLo1";
7108 case CP0_REG03__GLOBALNUM
:
7110 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7111 register_name
= "GlobalNumber";
7114 goto cp0_unimplemented
;
7117 case CP0_REGISTER_04
:
7119 case CP0_REG04__CONTEXT
:
7120 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7121 tcg_gen_ext32s_tl(arg
, arg
);
7122 register_name
= "Context";
7124 case CP0_REG04__CONTEXTCONFIG
:
7126 /* gen_helper_mfc0_contextconfig(arg); */
7127 register_name
= "ContextConfig";
7128 goto cp0_unimplemented
;
7129 case CP0_REG04__USERLOCAL
:
7130 CP0_CHECK(ctx
->ulri
);
7131 tcg_gen_ld_tl(arg
, cpu_env
,
7132 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7133 tcg_gen_ext32s_tl(arg
, arg
);
7134 register_name
= "UserLocal";
7136 case CP0_REG04__MMID
:
7138 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7139 register_name
= "MMID";
7142 goto cp0_unimplemented
;
7145 case CP0_REGISTER_05
:
7147 case CP0_REG05__PAGEMASK
:
7148 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7149 register_name
= "PageMask";
7151 case CP0_REG05__PAGEGRAIN
:
7152 check_insn(ctx
, ISA_MIPS32R2
);
7153 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7154 register_name
= "PageGrain";
7156 case CP0_REG05__SEGCTL0
:
7158 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7159 tcg_gen_ext32s_tl(arg
, arg
);
7160 register_name
= "SegCtl0";
7162 case CP0_REG05__SEGCTL1
:
7164 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7165 tcg_gen_ext32s_tl(arg
, arg
);
7166 register_name
= "SegCtl1";
7168 case CP0_REG05__SEGCTL2
:
7170 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7171 tcg_gen_ext32s_tl(arg
, arg
);
7172 register_name
= "SegCtl2";
7174 case CP0_REG05__PWBASE
:
7176 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7177 register_name
= "PWBase";
7179 case CP0_REG05__PWFIELD
:
7181 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7182 register_name
= "PWField";
7184 case CP0_REG05__PWSIZE
:
7186 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7187 register_name
= "PWSize";
7190 goto cp0_unimplemented
;
7193 case CP0_REGISTER_06
:
7195 case CP0_REG06__WIRED
:
7196 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7197 register_name
= "Wired";
7199 case CP0_REG06__SRSCONF0
:
7200 check_insn(ctx
, ISA_MIPS32R2
);
7201 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7202 register_name
= "SRSConf0";
7204 case CP0_REG06__SRSCONF1
:
7205 check_insn(ctx
, ISA_MIPS32R2
);
7206 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7207 register_name
= "SRSConf1";
7209 case CP0_REG06__SRSCONF2
:
7210 check_insn(ctx
, ISA_MIPS32R2
);
7211 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7212 register_name
= "SRSConf2";
7214 case CP0_REG06__SRSCONF3
:
7215 check_insn(ctx
, ISA_MIPS32R2
);
7216 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7217 register_name
= "SRSConf3";
7219 case CP0_REG06__SRSCONF4
:
7220 check_insn(ctx
, ISA_MIPS32R2
);
7221 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7222 register_name
= "SRSConf4";
7224 case CP0_REG06__PWCTL
:
7226 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7227 register_name
= "PWCtl";
7230 goto cp0_unimplemented
;
7233 case CP0_REGISTER_07
:
7235 case CP0_REG07__HWRENA
:
7236 check_insn(ctx
, ISA_MIPS32R2
);
7237 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7238 register_name
= "HWREna";
7241 goto cp0_unimplemented
;
7244 case CP0_REGISTER_08
:
7246 case CP0_REG08__BADVADDR
:
7247 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7248 tcg_gen_ext32s_tl(arg
, arg
);
7249 register_name
= "BadVAddr";
7251 case CP0_REG08__BADINSTR
:
7253 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7254 register_name
= "BadInstr";
7256 case CP0_REG08__BADINSTRP
:
7258 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7259 register_name
= "BadInstrP";
7261 case CP0_REG08__BADINSTRX
:
7263 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7264 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7265 register_name
= "BadInstrX";
7268 goto cp0_unimplemented
;
7271 case CP0_REGISTER_09
:
7273 case CP0_REG09__COUNT
:
7274 /* Mark as an IO operation because we read the time. */
7275 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7278 gen_helper_mfc0_count(arg
, cpu_env
);
7280 * Break the TB to be able to take timer interrupts immediately
7281 * after reading count. DISAS_STOP isn't sufficient, we need to
7282 * ensure we break completely out of translated code.
7284 gen_save_pc(ctx
->base
.pc_next
+ 4);
7285 ctx
->base
.is_jmp
= DISAS_EXIT
;
7286 register_name
= "Count";
7288 case CP0_REG09__SAARI
:
7289 CP0_CHECK(ctx
->saar
);
7290 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7291 register_name
= "SAARI";
7293 case CP0_REG09__SAAR
:
7294 CP0_CHECK(ctx
->saar
);
7295 gen_helper_mfc0_saar(arg
, cpu_env
);
7296 register_name
= "SAAR";
7299 goto cp0_unimplemented
;
7302 case CP0_REGISTER_10
:
7304 case CP0_REG10__ENTRYHI
:
7305 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7306 tcg_gen_ext32s_tl(arg
, arg
);
7307 register_name
= "EntryHi";
7310 goto cp0_unimplemented
;
7313 case CP0_REGISTER_11
:
7315 case CP0_REG11__COMPARE
:
7316 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7317 register_name
= "Compare";
7319 /* 6,7 are implementation dependent */
7321 goto cp0_unimplemented
;
7324 case CP0_REGISTER_12
:
7326 case CP0_REG12__STATUS
:
7327 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7328 register_name
= "Status";
7330 case CP0_REG12__INTCTL
:
7331 check_insn(ctx
, ISA_MIPS32R2
);
7332 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7333 register_name
= "IntCtl";
7335 case CP0_REG12__SRSCTL
:
7336 check_insn(ctx
, ISA_MIPS32R2
);
7337 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7338 register_name
= "SRSCtl";
7340 case CP0_REG12__SRSMAP
:
7341 check_insn(ctx
, ISA_MIPS32R2
);
7342 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7343 register_name
= "SRSMap";
7346 goto cp0_unimplemented
;
7349 case CP0_REGISTER_13
:
7351 case CP0_REG13__CAUSE
:
7352 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7353 register_name
= "Cause";
7356 goto cp0_unimplemented
;
7359 case CP0_REGISTER_14
:
7361 case CP0_REG14__EPC
:
7362 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7363 tcg_gen_ext32s_tl(arg
, arg
);
7364 register_name
= "EPC";
7367 goto cp0_unimplemented
;
7370 case CP0_REGISTER_15
:
7372 case CP0_REG15__PRID
:
7373 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7374 register_name
= "PRid";
7376 case CP0_REG15__EBASE
:
7377 check_insn(ctx
, ISA_MIPS32R2
);
7378 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7379 tcg_gen_ext32s_tl(arg
, arg
);
7380 register_name
= "EBase";
7382 case CP0_REG15__CMGCRBASE
:
7383 check_insn(ctx
, ISA_MIPS32R2
);
7384 CP0_CHECK(ctx
->cmgcr
);
7385 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7386 tcg_gen_ext32s_tl(arg
, arg
);
7387 register_name
= "CMGCRBase";
7390 goto cp0_unimplemented
;
7393 case CP0_REGISTER_16
:
7395 case CP0_REG16__CONFIG
:
7396 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7397 register_name
= "Config";
7399 case CP0_REG16__CONFIG1
:
7400 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7401 register_name
= "Config1";
7403 case CP0_REG16__CONFIG2
:
7404 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7405 register_name
= "Config2";
7407 case CP0_REG16__CONFIG3
:
7408 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7409 register_name
= "Config3";
7411 case CP0_REG16__CONFIG4
:
7412 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7413 register_name
= "Config4";
7415 case CP0_REG16__CONFIG5
:
7416 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7417 register_name
= "Config5";
7419 /* 6,7 are implementation dependent */
7420 case CP0_REG16__CONFIG6
:
7421 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7422 register_name
= "Config6";
7424 case CP0_REG16__CONFIG7
:
7425 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7426 register_name
= "Config7";
7429 goto cp0_unimplemented
;
7432 case CP0_REGISTER_17
:
7434 case CP0_REG17__LLADDR
:
7435 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7436 register_name
= "LLAddr";
7438 case CP0_REG17__MAAR
:
7439 CP0_CHECK(ctx
->mrp
);
7440 gen_helper_mfc0_maar(arg
, cpu_env
);
7441 register_name
= "MAAR";
7443 case CP0_REG17__MAARI
:
7444 CP0_CHECK(ctx
->mrp
);
7445 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7446 register_name
= "MAARI";
7449 goto cp0_unimplemented
;
7452 case CP0_REGISTER_18
:
7454 case CP0_REG18__WATCHLO0
:
7455 case CP0_REG18__WATCHLO1
:
7456 case CP0_REG18__WATCHLO2
:
7457 case CP0_REG18__WATCHLO3
:
7458 case CP0_REG18__WATCHLO4
:
7459 case CP0_REG18__WATCHLO5
:
7460 case CP0_REG18__WATCHLO6
:
7461 case CP0_REG18__WATCHLO7
:
7462 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7463 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7464 register_name
= "WatchLo";
7467 goto cp0_unimplemented
;
7470 case CP0_REGISTER_19
:
7472 case CP0_REG19__WATCHHI0
:
7473 case CP0_REG19__WATCHHI1
:
7474 case CP0_REG19__WATCHHI2
:
7475 case CP0_REG19__WATCHHI3
:
7476 case CP0_REG19__WATCHHI4
:
7477 case CP0_REG19__WATCHHI5
:
7478 case CP0_REG19__WATCHHI6
:
7479 case CP0_REG19__WATCHHI7
:
7480 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7481 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7482 register_name
= "WatchHi";
7485 goto cp0_unimplemented
;
7488 case CP0_REGISTER_20
:
7490 case CP0_REG20__XCONTEXT
:
7491 #if defined(TARGET_MIPS64)
7492 check_insn(ctx
, ISA_MIPS3
);
7493 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7494 tcg_gen_ext32s_tl(arg
, arg
);
7495 register_name
= "XContext";
7499 goto cp0_unimplemented
;
7502 case CP0_REGISTER_21
:
7503 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7504 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7507 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7508 register_name
= "Framemask";
7511 goto cp0_unimplemented
;
7514 case CP0_REGISTER_22
:
7515 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7516 register_name
= "'Diagnostic"; /* implementation dependent */
7518 case CP0_REGISTER_23
:
7520 case CP0_REG23__DEBUG
:
7521 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7522 register_name
= "Debug";
7524 case CP0_REG23__TRACECONTROL
:
7525 /* PDtrace support */
7526 /* gen_helper_mfc0_tracecontrol(arg); */
7527 register_name
= "TraceControl";
7528 goto cp0_unimplemented
;
7529 case CP0_REG23__TRACECONTROL2
:
7530 /* PDtrace support */
7531 /* gen_helper_mfc0_tracecontrol2(arg); */
7532 register_name
= "TraceControl2";
7533 goto cp0_unimplemented
;
7534 case CP0_REG23__USERTRACEDATA1
:
7535 /* PDtrace support */
7536 /* gen_helper_mfc0_usertracedata1(arg);*/
7537 register_name
= "UserTraceData1";
7538 goto cp0_unimplemented
;
7539 case CP0_REG23__TRACEIBPC
:
7540 /* PDtrace support */
7541 /* gen_helper_mfc0_traceibpc(arg); */
7542 register_name
= "TraceIBPC";
7543 goto cp0_unimplemented
;
7544 case CP0_REG23__TRACEDBPC
:
7545 /* PDtrace support */
7546 /* gen_helper_mfc0_tracedbpc(arg); */
7547 register_name
= "TraceDBPC";
7548 goto cp0_unimplemented
;
7550 goto cp0_unimplemented
;
7553 case CP0_REGISTER_24
:
7555 case CP0_REG24__DEPC
:
7557 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7558 tcg_gen_ext32s_tl(arg
, arg
);
7559 register_name
= "DEPC";
7562 goto cp0_unimplemented
;
7565 case CP0_REGISTER_25
:
7567 case CP0_REG25__PERFCTL0
:
7568 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
7569 register_name
= "Performance0";
7571 case CP0_REG25__PERFCNT0
:
7572 /* gen_helper_mfc0_performance1(arg); */
7573 register_name
= "Performance1";
7574 goto cp0_unimplemented
;
7575 case CP0_REG25__PERFCTL1
:
7576 /* gen_helper_mfc0_performance2(arg); */
7577 register_name
= "Performance2";
7578 goto cp0_unimplemented
;
7579 case CP0_REG25__PERFCNT1
:
7580 /* gen_helper_mfc0_performance3(arg); */
7581 register_name
= "Performance3";
7582 goto cp0_unimplemented
;
7583 case CP0_REG25__PERFCTL2
:
7584 /* gen_helper_mfc0_performance4(arg); */
7585 register_name
= "Performance4";
7586 goto cp0_unimplemented
;
7587 case CP0_REG25__PERFCNT2
:
7588 /* gen_helper_mfc0_performance5(arg); */
7589 register_name
= "Performance5";
7590 goto cp0_unimplemented
;
7591 case CP0_REG25__PERFCTL3
:
7592 /* gen_helper_mfc0_performance6(arg); */
7593 register_name
= "Performance6";
7594 goto cp0_unimplemented
;
7595 case CP0_REG25__PERFCNT3
:
7596 /* gen_helper_mfc0_performance7(arg); */
7597 register_name
= "Performance7";
7598 goto cp0_unimplemented
;
7600 goto cp0_unimplemented
;
7603 case CP0_REGISTER_26
:
7605 case CP0_REG26__ERRCTL
:
7606 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
7607 register_name
= "ErrCtl";
7610 goto cp0_unimplemented
;
7613 case CP0_REGISTER_27
:
7615 case CP0_REG27__CACHERR
:
7616 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7617 register_name
= "CacheErr";
7620 goto cp0_unimplemented
;
7623 case CP0_REGISTER_28
:
7625 case CP0_REG28__TAGLO
:
7626 case CP0_REG28__TAGLO1
:
7627 case CP0_REG28__TAGLO2
:
7628 case CP0_REG28__TAGLO3
:
7630 TCGv_i64 tmp
= tcg_temp_new_i64();
7631 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
7632 gen_move_low32(arg
, tmp
);
7633 tcg_temp_free_i64(tmp
);
7635 register_name
= "TagLo";
7637 case CP0_REG28__DATALO
:
7638 case CP0_REG28__DATALO1
:
7639 case CP0_REG28__DATALO2
:
7640 case CP0_REG28__DATALO3
:
7641 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7642 register_name
= "DataLo";
7645 goto cp0_unimplemented
;
7648 case CP0_REGISTER_29
:
7650 case CP0_REG29__TAGHI
:
7651 case CP0_REG29__TAGHI1
:
7652 case CP0_REG29__TAGHI2
:
7653 case CP0_REG29__TAGHI3
:
7654 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7655 register_name
= "TagHi";
7657 case CP0_REG29__DATAHI
:
7658 case CP0_REG29__DATAHI1
:
7659 case CP0_REG29__DATAHI2
:
7660 case CP0_REG29__DATAHI3
:
7661 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7662 register_name
= "DataHi";
7665 goto cp0_unimplemented
;
7668 case CP0_REGISTER_30
:
7670 case CP0_REG30__ERROREPC
:
7671 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7672 tcg_gen_ext32s_tl(arg
, arg
);
7673 register_name
= "ErrorEPC";
7676 goto cp0_unimplemented
;
7679 case CP0_REGISTER_31
:
7681 case CP0_REG31__DESAVE
:
7683 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7684 register_name
= "DESAVE";
7686 case CP0_REG31__KSCRATCH1
:
7687 case CP0_REG31__KSCRATCH2
:
7688 case CP0_REG31__KSCRATCH3
:
7689 case CP0_REG31__KSCRATCH4
:
7690 case CP0_REG31__KSCRATCH5
:
7691 case CP0_REG31__KSCRATCH6
:
7692 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7693 tcg_gen_ld_tl(arg
, cpu_env
,
7694 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7695 tcg_gen_ext32s_tl(arg
, arg
);
7696 register_name
= "KScratch";
7699 goto cp0_unimplemented
;
7703 goto cp0_unimplemented
;
7705 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
7709 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
7710 register_name
, reg
, sel
);
7711 gen_mfc0_unimplemented(ctx
, arg
);
7714 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7716 const char *register_name
= "invalid";
7719 check_insn(ctx
, ISA_MIPS32
);
7722 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7727 case CP0_REGISTER_00
:
7729 case CP0_REG00__INDEX
:
7730 gen_helper_mtc0_index(cpu_env
, arg
);
7731 register_name
= "Index";
7733 case CP0_REG00__MVPCONTROL
:
7734 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7735 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7736 register_name
= "MVPControl";
7738 case CP0_REG00__MVPCONF0
:
7739 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7741 register_name
= "MVPConf0";
7743 case CP0_REG00__MVPCONF1
:
7744 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7746 register_name
= "MVPConf1";
7748 case CP0_REG00__VPCONTROL
:
7751 register_name
= "VPControl";
7754 goto cp0_unimplemented
;
7757 case CP0_REGISTER_01
:
7759 case CP0_REG01__RANDOM
:
7761 register_name
= "Random";
7763 case CP0_REG01__VPECONTROL
:
7764 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7765 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7766 register_name
= "VPEControl";
7768 case CP0_REG01__VPECONF0
:
7769 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7770 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7771 register_name
= "VPEConf0";
7773 case CP0_REG01__VPECONF1
:
7774 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7775 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7776 register_name
= "VPEConf1";
7778 case CP0_REG01__YQMASK
:
7779 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7780 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7781 register_name
= "YQMask";
7783 case CP0_REG01__VPESCHEDULE
:
7784 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7785 tcg_gen_st_tl(arg
, cpu_env
,
7786 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7787 register_name
= "VPESchedule";
7789 case CP0_REG01__VPESCHEFBACK
:
7790 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7791 tcg_gen_st_tl(arg
, cpu_env
,
7792 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7793 register_name
= "VPEScheFBack";
7795 case CP0_REG01__VPEOPT
:
7796 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7797 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7798 register_name
= "VPEOpt";
7801 goto cp0_unimplemented
;
7804 case CP0_REGISTER_02
:
7806 case CP0_REG02__ENTRYLO0
:
7807 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
7808 register_name
= "EntryLo0";
7810 case CP0_REG02__TCSTATUS
:
7811 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7812 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7813 register_name
= "TCStatus";
7815 case CP0_REG02__TCBIND
:
7816 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7817 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7818 register_name
= "TCBind";
7820 case CP0_REG02__TCRESTART
:
7821 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7822 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7823 register_name
= "TCRestart";
7825 case CP0_REG02__TCHALT
:
7826 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7827 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7828 register_name
= "TCHalt";
7830 case CP0_REG02__TCCONTEXT
:
7831 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7832 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7833 register_name
= "TCContext";
7835 case CP0_REG02__TCSCHEDULE
:
7836 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7837 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7838 register_name
= "TCSchedule";
7840 case CP0_REG02__TCSCHEFBACK
:
7841 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7842 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7843 register_name
= "TCScheFBack";
7846 goto cp0_unimplemented
;
7849 case CP0_REGISTER_03
:
7851 case CP0_REG03__ENTRYLO1
:
7852 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
7853 register_name
= "EntryLo1";
7855 case CP0_REG03__GLOBALNUM
:
7858 register_name
= "GlobalNumber";
7861 goto cp0_unimplemented
;
7864 case CP0_REGISTER_04
:
7866 case CP0_REG04__CONTEXT
:
7867 gen_helper_mtc0_context(cpu_env
, arg
);
7868 register_name
= "Context";
7870 case CP0_REG04__CONTEXTCONFIG
:
7872 /* gen_helper_mtc0_contextconfig(arg); */
7873 register_name
= "ContextConfig";
7874 goto cp0_unimplemented
;
7875 case CP0_REG04__USERLOCAL
:
7876 CP0_CHECK(ctx
->ulri
);
7877 tcg_gen_st_tl(arg
, cpu_env
,
7878 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7879 register_name
= "UserLocal";
7881 case CP0_REG04__MMID
:
7883 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
7884 register_name
= "MMID";
7887 goto cp0_unimplemented
;
7890 case CP0_REGISTER_05
:
7892 case CP0_REG05__PAGEMASK
:
7893 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7894 register_name
= "PageMask";
7896 case CP0_REG05__PAGEGRAIN
:
7897 check_insn(ctx
, ISA_MIPS32R2
);
7898 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7899 register_name
= "PageGrain";
7900 ctx
->base
.is_jmp
= DISAS_STOP
;
7902 case CP0_REG05__SEGCTL0
:
7904 gen_helper_mtc0_segctl0(cpu_env
, arg
);
7905 register_name
= "SegCtl0";
7907 case CP0_REG05__SEGCTL1
:
7909 gen_helper_mtc0_segctl1(cpu_env
, arg
);
7910 register_name
= "SegCtl1";
7912 case CP0_REG05__SEGCTL2
:
7914 gen_helper_mtc0_segctl2(cpu_env
, arg
);
7915 register_name
= "SegCtl2";
7917 case CP0_REG05__PWBASE
:
7919 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7920 register_name
= "PWBase";
7922 case CP0_REG05__PWFIELD
:
7924 gen_helper_mtc0_pwfield(cpu_env
, arg
);
7925 register_name
= "PWField";
7927 case CP0_REG05__PWSIZE
:
7929 gen_helper_mtc0_pwsize(cpu_env
, arg
);
7930 register_name
= "PWSize";
7933 goto cp0_unimplemented
;
7936 case CP0_REGISTER_06
:
7938 case CP0_REG06__WIRED
:
7939 gen_helper_mtc0_wired(cpu_env
, arg
);
7940 register_name
= "Wired";
7942 case CP0_REG06__SRSCONF0
:
7943 check_insn(ctx
, ISA_MIPS32R2
);
7944 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7945 register_name
= "SRSConf0";
7947 case CP0_REG06__SRSCONF1
:
7948 check_insn(ctx
, ISA_MIPS32R2
);
7949 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7950 register_name
= "SRSConf1";
7952 case CP0_REG06__SRSCONF2
:
7953 check_insn(ctx
, ISA_MIPS32R2
);
7954 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7955 register_name
= "SRSConf2";
7957 case CP0_REG06__SRSCONF3
:
7958 check_insn(ctx
, ISA_MIPS32R2
);
7959 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7960 register_name
= "SRSConf3";
7962 case CP0_REG06__SRSCONF4
:
7963 check_insn(ctx
, ISA_MIPS32R2
);
7964 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7965 register_name
= "SRSConf4";
7967 case CP0_REG06__PWCTL
:
7969 gen_helper_mtc0_pwctl(cpu_env
, arg
);
7970 register_name
= "PWCtl";
7973 goto cp0_unimplemented
;
7976 case CP0_REGISTER_07
:
7978 case CP0_REG07__HWRENA
:
7979 check_insn(ctx
, ISA_MIPS32R2
);
7980 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7981 ctx
->base
.is_jmp
= DISAS_STOP
;
7982 register_name
= "HWREna";
7985 goto cp0_unimplemented
;
7988 case CP0_REGISTER_08
:
7990 case CP0_REG08__BADVADDR
:
7992 register_name
= "BadVAddr";
7994 case CP0_REG08__BADINSTR
:
7996 register_name
= "BadInstr";
7998 case CP0_REG08__BADINSTRP
:
8000 register_name
= "BadInstrP";
8002 case CP0_REG08__BADINSTRX
:
8004 register_name
= "BadInstrX";
8007 goto cp0_unimplemented
;
8010 case CP0_REGISTER_09
:
8012 case CP0_REG09__COUNT
:
8013 gen_helper_mtc0_count(cpu_env
, arg
);
8014 register_name
= "Count";
8016 case CP0_REG09__SAARI
:
8017 CP0_CHECK(ctx
->saar
);
8018 gen_helper_mtc0_saari(cpu_env
, arg
);
8019 register_name
= "SAARI";
8021 case CP0_REG09__SAAR
:
8022 CP0_CHECK(ctx
->saar
);
8023 gen_helper_mtc0_saar(cpu_env
, arg
);
8024 register_name
= "SAAR";
8027 goto cp0_unimplemented
;
8030 case CP0_REGISTER_10
:
8032 case CP0_REG10__ENTRYHI
:
8033 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8034 register_name
= "EntryHi";
8037 goto cp0_unimplemented
;
8040 case CP0_REGISTER_11
:
8042 case CP0_REG11__COMPARE
:
8043 gen_helper_mtc0_compare(cpu_env
, arg
);
8044 register_name
= "Compare";
8046 /* 6,7 are implementation dependent */
8048 goto cp0_unimplemented
;
8051 case CP0_REGISTER_12
:
8053 case CP0_REG12__STATUS
:
8054 save_cpu_state(ctx
, 1);
8055 gen_helper_mtc0_status(cpu_env
, arg
);
8056 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8057 gen_save_pc(ctx
->base
.pc_next
+ 4);
8058 ctx
->base
.is_jmp
= DISAS_EXIT
;
8059 register_name
= "Status";
8061 case CP0_REG12__INTCTL
:
8062 check_insn(ctx
, ISA_MIPS32R2
);
8063 gen_helper_mtc0_intctl(cpu_env
, arg
);
8064 /* Stop translation as we may have switched the execution mode */
8065 ctx
->base
.is_jmp
= DISAS_STOP
;
8066 register_name
= "IntCtl";
8068 case CP0_REG12__SRSCTL
:
8069 check_insn(ctx
, ISA_MIPS32R2
);
8070 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8071 /* Stop translation as we may have switched the execution mode */
8072 ctx
->base
.is_jmp
= DISAS_STOP
;
8073 register_name
= "SRSCtl";
8075 case CP0_REG12__SRSMAP
:
8076 check_insn(ctx
, ISA_MIPS32R2
);
8077 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8078 /* Stop translation as we may have switched the execution mode */
8079 ctx
->base
.is_jmp
= DISAS_STOP
;
8080 register_name
= "SRSMap";
8083 goto cp0_unimplemented
;
8086 case CP0_REGISTER_13
:
8088 case CP0_REG13__CAUSE
:
8089 save_cpu_state(ctx
, 1);
8090 gen_helper_mtc0_cause(cpu_env
, arg
);
8092 * Stop translation as we may have triggered an interrupt.
8093 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8094 * translated code to check for pending interrupts.
8096 gen_save_pc(ctx
->base
.pc_next
+ 4);
8097 ctx
->base
.is_jmp
= DISAS_EXIT
;
8098 register_name
= "Cause";
8101 goto cp0_unimplemented
;
8104 case CP0_REGISTER_14
:
8106 case CP0_REG14__EPC
:
8107 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8108 register_name
= "EPC";
8111 goto cp0_unimplemented
;
8114 case CP0_REGISTER_15
:
8116 case CP0_REG15__PRID
:
8118 register_name
= "PRid";
8120 case CP0_REG15__EBASE
:
8121 check_insn(ctx
, ISA_MIPS32R2
);
8122 gen_helper_mtc0_ebase(cpu_env
, arg
);
8123 register_name
= "EBase";
8126 goto cp0_unimplemented
;
8129 case CP0_REGISTER_16
:
8131 case CP0_REG16__CONFIG
:
8132 gen_helper_mtc0_config0(cpu_env
, arg
);
8133 register_name
= "Config";
8134 /* Stop translation as we may have switched the execution mode */
8135 ctx
->base
.is_jmp
= DISAS_STOP
;
8137 case CP0_REG16__CONFIG1
:
8138 /* ignored, read only */
8139 register_name
= "Config1";
8141 case CP0_REG16__CONFIG2
:
8142 gen_helper_mtc0_config2(cpu_env
, arg
);
8143 register_name
= "Config2";
8144 /* Stop translation as we may have switched the execution mode */
8145 ctx
->base
.is_jmp
= DISAS_STOP
;
8147 case CP0_REG16__CONFIG3
:
8148 gen_helper_mtc0_config3(cpu_env
, arg
);
8149 register_name
= "Config3";
8150 /* Stop translation as we may have switched the execution mode */
8151 ctx
->base
.is_jmp
= DISAS_STOP
;
8153 case CP0_REG16__CONFIG4
:
8154 gen_helper_mtc0_config4(cpu_env
, arg
);
8155 register_name
= "Config4";
8156 ctx
->base
.is_jmp
= DISAS_STOP
;
8158 case CP0_REG16__CONFIG5
:
8159 gen_helper_mtc0_config5(cpu_env
, arg
);
8160 register_name
= "Config5";
8161 /* Stop translation as we may have switched the execution mode */
8162 ctx
->base
.is_jmp
= DISAS_STOP
;
8164 /* 6,7 are implementation dependent */
8165 case CP0_REG16__CONFIG6
:
8167 register_name
= "Config6";
8169 case CP0_REG16__CONFIG7
:
8171 register_name
= "Config7";
8174 register_name
= "Invalid config selector";
8175 goto cp0_unimplemented
;
8178 case CP0_REGISTER_17
:
8180 case CP0_REG17__LLADDR
:
8181 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8182 register_name
= "LLAddr";
8184 case CP0_REG17__MAAR
:
8185 CP0_CHECK(ctx
->mrp
);
8186 gen_helper_mtc0_maar(cpu_env
, arg
);
8187 register_name
= "MAAR";
8189 case CP0_REG17__MAARI
:
8190 CP0_CHECK(ctx
->mrp
);
8191 gen_helper_mtc0_maari(cpu_env
, arg
);
8192 register_name
= "MAARI";
8195 goto cp0_unimplemented
;
8198 case CP0_REGISTER_18
:
8200 case CP0_REG18__WATCHLO0
:
8201 case CP0_REG18__WATCHLO1
:
8202 case CP0_REG18__WATCHLO2
:
8203 case CP0_REG18__WATCHLO3
:
8204 case CP0_REG18__WATCHLO4
:
8205 case CP0_REG18__WATCHLO5
:
8206 case CP0_REG18__WATCHLO6
:
8207 case CP0_REG18__WATCHLO7
:
8208 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8209 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8210 register_name
= "WatchLo";
8213 goto cp0_unimplemented
;
8216 case CP0_REGISTER_19
:
8218 case CP0_REG19__WATCHHI0
:
8219 case CP0_REG19__WATCHHI1
:
8220 case CP0_REG19__WATCHHI2
:
8221 case CP0_REG19__WATCHHI3
:
8222 case CP0_REG19__WATCHHI4
:
8223 case CP0_REG19__WATCHHI5
:
8224 case CP0_REG19__WATCHHI6
:
8225 case CP0_REG19__WATCHHI7
:
8226 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8227 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8228 register_name
= "WatchHi";
8231 goto cp0_unimplemented
;
8234 case CP0_REGISTER_20
:
8236 case CP0_REG20__XCONTEXT
:
8237 #if defined(TARGET_MIPS64)
8238 check_insn(ctx
, ISA_MIPS3
);
8239 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8240 register_name
= "XContext";
8244 goto cp0_unimplemented
;
8247 case CP0_REGISTER_21
:
8248 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8249 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8252 gen_helper_mtc0_framemask(cpu_env
, arg
);
8253 register_name
= "Framemask";
8256 goto cp0_unimplemented
;
8259 case CP0_REGISTER_22
:
8261 register_name
= "Diagnostic"; /* implementation dependent */
8263 case CP0_REGISTER_23
:
8265 case CP0_REG23__DEBUG
:
8266 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8267 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8268 gen_save_pc(ctx
->base
.pc_next
+ 4);
8269 ctx
->base
.is_jmp
= DISAS_EXIT
;
8270 register_name
= "Debug";
8272 case CP0_REG23__TRACECONTROL
:
8273 /* PDtrace support */
8274 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8275 register_name
= "TraceControl";
8276 /* Stop translation as we may have switched the execution mode */
8277 ctx
->base
.is_jmp
= DISAS_STOP
;
8278 goto cp0_unimplemented
;
8279 case CP0_REG23__TRACECONTROL2
:
8280 /* PDtrace support */
8281 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8282 register_name
= "TraceControl2";
8283 /* Stop translation as we may have switched the execution mode */
8284 ctx
->base
.is_jmp
= DISAS_STOP
;
8285 goto cp0_unimplemented
;
8286 case CP0_REG23__USERTRACEDATA1
:
8287 /* Stop translation as we may have switched the execution mode */
8288 ctx
->base
.is_jmp
= DISAS_STOP
;
8289 /* PDtrace support */
8290 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8291 register_name
= "UserTraceData";
8292 /* Stop translation as we may have switched the execution mode */
8293 ctx
->base
.is_jmp
= DISAS_STOP
;
8294 goto cp0_unimplemented
;
8295 case CP0_REG23__TRACEIBPC
:
8296 /* PDtrace support */
8297 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8298 /* Stop translation as we may have switched the execution mode */
8299 ctx
->base
.is_jmp
= DISAS_STOP
;
8300 register_name
= "TraceIBPC";
8301 goto cp0_unimplemented
;
8302 case CP0_REG23__TRACEDBPC
:
8303 /* PDtrace support */
8304 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8305 /* Stop translation as we may have switched the execution mode */
8306 ctx
->base
.is_jmp
= DISAS_STOP
;
8307 register_name
= "TraceDBPC";
8308 goto cp0_unimplemented
;
8310 goto cp0_unimplemented
;
8313 case CP0_REGISTER_24
:
8315 case CP0_REG24__DEPC
:
8317 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8318 register_name
= "DEPC";
8321 goto cp0_unimplemented
;
8324 case CP0_REGISTER_25
:
8326 case CP0_REG25__PERFCTL0
:
8327 gen_helper_mtc0_performance0(cpu_env
, arg
);
8328 register_name
= "Performance0";
8330 case CP0_REG25__PERFCNT0
:
8331 /* gen_helper_mtc0_performance1(arg); */
8332 register_name
= "Performance1";
8333 goto cp0_unimplemented
;
8334 case CP0_REG25__PERFCTL1
:
8335 /* gen_helper_mtc0_performance2(arg); */
8336 register_name
= "Performance2";
8337 goto cp0_unimplemented
;
8338 case CP0_REG25__PERFCNT1
:
8339 /* gen_helper_mtc0_performance3(arg); */
8340 register_name
= "Performance3";
8341 goto cp0_unimplemented
;
8342 case CP0_REG25__PERFCTL2
:
8343 /* gen_helper_mtc0_performance4(arg); */
8344 register_name
= "Performance4";
8345 goto cp0_unimplemented
;
8346 case CP0_REG25__PERFCNT2
:
8347 /* gen_helper_mtc0_performance5(arg); */
8348 register_name
= "Performance5";
8349 goto cp0_unimplemented
;
8350 case CP0_REG25__PERFCTL3
:
8351 /* gen_helper_mtc0_performance6(arg); */
8352 register_name
= "Performance6";
8353 goto cp0_unimplemented
;
8354 case CP0_REG25__PERFCNT3
:
8355 /* gen_helper_mtc0_performance7(arg); */
8356 register_name
= "Performance7";
8357 goto cp0_unimplemented
;
8359 goto cp0_unimplemented
;
8362 case CP0_REGISTER_26
:
8364 case CP0_REG26__ERRCTL
:
8365 gen_helper_mtc0_errctl(cpu_env
, arg
);
8366 ctx
->base
.is_jmp
= DISAS_STOP
;
8367 register_name
= "ErrCtl";
8370 goto cp0_unimplemented
;
8373 case CP0_REGISTER_27
:
8375 case CP0_REG27__CACHERR
:
8377 register_name
= "CacheErr";
8380 goto cp0_unimplemented
;
8383 case CP0_REGISTER_28
:
8385 case CP0_REG28__TAGLO
:
8386 case CP0_REG28__TAGLO1
:
8387 case CP0_REG28__TAGLO2
:
8388 case CP0_REG28__TAGLO3
:
8389 gen_helper_mtc0_taglo(cpu_env
, arg
);
8390 register_name
= "TagLo";
8392 case CP0_REG28__DATALO
:
8393 case CP0_REG28__DATALO1
:
8394 case CP0_REG28__DATALO2
:
8395 case CP0_REG28__DATALO3
:
8396 gen_helper_mtc0_datalo(cpu_env
, arg
);
8397 register_name
= "DataLo";
8400 goto cp0_unimplemented
;
8403 case CP0_REGISTER_29
:
8405 case CP0_REG29__TAGHI
:
8406 case CP0_REG29__TAGHI1
:
8407 case CP0_REG29__TAGHI2
:
8408 case CP0_REG29__TAGHI3
:
8409 gen_helper_mtc0_taghi(cpu_env
, arg
);
8410 register_name
= "TagHi";
8412 case CP0_REG29__DATAHI
:
8413 case CP0_REG29__DATAHI1
:
8414 case CP0_REG29__DATAHI2
:
8415 case CP0_REG29__DATAHI3
:
8416 gen_helper_mtc0_datahi(cpu_env
, arg
);
8417 register_name
= "DataHi";
8420 register_name
= "invalid sel";
8421 goto cp0_unimplemented
;
8424 case CP0_REGISTER_30
:
8426 case CP0_REG30__ERROREPC
:
8427 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8428 register_name
= "ErrorEPC";
8431 goto cp0_unimplemented
;
8434 case CP0_REGISTER_31
:
8436 case CP0_REG31__DESAVE
:
8438 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8439 register_name
= "DESAVE";
8441 case CP0_REG31__KSCRATCH1
:
8442 case CP0_REG31__KSCRATCH2
:
8443 case CP0_REG31__KSCRATCH3
:
8444 case CP0_REG31__KSCRATCH4
:
8445 case CP0_REG31__KSCRATCH5
:
8446 case CP0_REG31__KSCRATCH6
:
8447 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8448 tcg_gen_st_tl(arg
, cpu_env
,
8449 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8450 register_name
= "KScratch";
8453 goto cp0_unimplemented
;
8457 goto cp0_unimplemented
;
8459 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8461 /* For simplicity assume that all writes can cause interrupts. */
8462 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8464 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8465 * translated code to check for pending interrupts.
8467 gen_save_pc(ctx
->base
.pc_next
+ 4);
8468 ctx
->base
.is_jmp
= DISAS_EXIT
;
8473 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8474 register_name
, reg
, sel
);
8477 #if defined(TARGET_MIPS64)
8478 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8480 const char *register_name
= "invalid";
8483 check_insn(ctx
, ISA_MIPS64
);
8487 case CP0_REGISTER_00
:
8489 case CP0_REG00__INDEX
:
8490 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8491 register_name
= "Index";
8493 case CP0_REG00__MVPCONTROL
:
8494 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8495 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8496 register_name
= "MVPControl";
8498 case CP0_REG00__MVPCONF0
:
8499 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8500 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8501 register_name
= "MVPConf0";
8503 case CP0_REG00__MVPCONF1
:
8504 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8505 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8506 register_name
= "MVPConf1";
8508 case CP0_REG00__VPCONTROL
:
8510 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8511 register_name
= "VPControl";
8514 goto cp0_unimplemented
;
8517 case CP0_REGISTER_01
:
8519 case CP0_REG01__RANDOM
:
8520 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8521 gen_helper_mfc0_random(arg
, cpu_env
);
8522 register_name
= "Random";
8524 case CP0_REG01__VPECONTROL
:
8525 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8526 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8527 register_name
= "VPEControl";
8529 case CP0_REG01__VPECONF0
:
8530 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8531 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8532 register_name
= "VPEConf0";
8534 case CP0_REG01__VPECONF1
:
8535 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8536 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
8537 register_name
= "VPEConf1";
8539 case CP0_REG01__YQMASK
:
8540 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8541 tcg_gen_ld_tl(arg
, cpu_env
,
8542 offsetof(CPUMIPSState
, CP0_YQMask
));
8543 register_name
= "YQMask";
8545 case CP0_REG01__VPESCHEDULE
:
8546 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8547 tcg_gen_ld_tl(arg
, cpu_env
,
8548 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8549 register_name
= "VPESchedule";
8551 case CP0_REG01__VPESCHEFBACK
:
8552 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8553 tcg_gen_ld_tl(arg
, cpu_env
,
8554 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8555 register_name
= "VPEScheFBack";
8557 case CP0_REG01__VPEOPT
:
8558 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8559 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
8560 register_name
= "VPEOpt";
8563 goto cp0_unimplemented
;
8566 case CP0_REGISTER_02
:
8568 case CP0_REG02__ENTRYLO0
:
8569 tcg_gen_ld_tl(arg
, cpu_env
,
8570 offsetof(CPUMIPSState
, CP0_EntryLo0
));
8571 register_name
= "EntryLo0";
8573 case CP0_REG02__TCSTATUS
:
8574 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8575 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
8576 register_name
= "TCStatus";
8578 case CP0_REG02__TCBIND
:
8579 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8580 gen_helper_mfc0_tcbind(arg
, cpu_env
);
8581 register_name
= "TCBind";
8583 case CP0_REG02__TCRESTART
:
8584 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8585 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
8586 register_name
= "TCRestart";
8588 case CP0_REG02__TCHALT
:
8589 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8590 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
8591 register_name
= "TCHalt";
8593 case CP0_REG02__TCCONTEXT
:
8594 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8595 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
8596 register_name
= "TCContext";
8598 case CP0_REG02__TCSCHEDULE
:
8599 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8600 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
8601 register_name
= "TCSchedule";
8603 case CP0_REG02__TCSCHEFBACK
:
8604 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8605 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
8606 register_name
= "TCScheFBack";
8609 goto cp0_unimplemented
;
8612 case CP0_REGISTER_03
:
8614 case CP0_REG03__ENTRYLO1
:
8615 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
8616 register_name
= "EntryLo1";
8618 case CP0_REG03__GLOBALNUM
:
8620 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
8621 register_name
= "GlobalNumber";
8624 goto cp0_unimplemented
;
8627 case CP0_REGISTER_04
:
8629 case CP0_REG04__CONTEXT
:
8630 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
8631 register_name
= "Context";
8633 case CP0_REG04__CONTEXTCONFIG
:
8635 /* gen_helper_dmfc0_contextconfig(arg); */
8636 register_name
= "ContextConfig";
8637 goto cp0_unimplemented
;
8638 case CP0_REG04__USERLOCAL
:
8639 CP0_CHECK(ctx
->ulri
);
8640 tcg_gen_ld_tl(arg
, cpu_env
,
8641 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8642 register_name
= "UserLocal";
8644 case CP0_REG04__MMID
:
8646 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
8647 register_name
= "MMID";
8650 goto cp0_unimplemented
;
8653 case CP0_REGISTER_05
:
8655 case CP0_REG05__PAGEMASK
:
8656 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
8657 register_name
= "PageMask";
8659 case CP0_REG05__PAGEGRAIN
:
8660 check_insn(ctx
, ISA_MIPS32R2
);
8661 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
8662 register_name
= "PageGrain";
8664 case CP0_REG05__SEGCTL0
:
8666 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
8667 register_name
= "SegCtl0";
8669 case CP0_REG05__SEGCTL1
:
8671 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
8672 register_name
= "SegCtl1";
8674 case CP0_REG05__SEGCTL2
:
8676 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
8677 register_name
= "SegCtl2";
8679 case CP0_REG05__PWBASE
:
8681 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8682 register_name
= "PWBase";
8684 case CP0_REG05__PWFIELD
:
8686 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
8687 register_name
= "PWField";
8689 case CP0_REG05__PWSIZE
:
8691 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
8692 register_name
= "PWSize";
8695 goto cp0_unimplemented
;
8698 case CP0_REGISTER_06
:
8700 case CP0_REG06__WIRED
:
8701 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
8702 register_name
= "Wired";
8704 case CP0_REG06__SRSCONF0
:
8705 check_insn(ctx
, ISA_MIPS32R2
);
8706 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
8707 register_name
= "SRSConf0";
8709 case CP0_REG06__SRSCONF1
:
8710 check_insn(ctx
, ISA_MIPS32R2
);
8711 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
8712 register_name
= "SRSConf1";
8714 case CP0_REG06__SRSCONF2
:
8715 check_insn(ctx
, ISA_MIPS32R2
);
8716 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
8717 register_name
= "SRSConf2";
8719 case CP0_REG06__SRSCONF3
:
8720 check_insn(ctx
, ISA_MIPS32R2
);
8721 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
8722 register_name
= "SRSConf3";
8724 case CP0_REG06__SRSCONF4
:
8725 check_insn(ctx
, ISA_MIPS32R2
);
8726 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
8727 register_name
= "SRSConf4";
8729 case CP0_REG06__PWCTL
:
8731 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
8732 register_name
= "PWCtl";
8735 goto cp0_unimplemented
;
8738 case CP0_REGISTER_07
:
8740 case CP0_REG07__HWRENA
:
8741 check_insn(ctx
, ISA_MIPS32R2
);
8742 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
8743 register_name
= "HWREna";
8746 goto cp0_unimplemented
;
8749 case CP0_REGISTER_08
:
8751 case CP0_REG08__BADVADDR
:
8752 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
8753 register_name
= "BadVAddr";
8755 case CP0_REG08__BADINSTR
:
8757 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
8758 register_name
= "BadInstr";
8760 case CP0_REG08__BADINSTRP
:
8762 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
8763 register_name
= "BadInstrP";
8765 case CP0_REG08__BADINSTRX
:
8767 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
8768 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
8769 register_name
= "BadInstrX";
8772 goto cp0_unimplemented
;
8775 case CP0_REGISTER_09
:
8777 case CP0_REG09__COUNT
:
8778 /* Mark as an IO operation because we read the time. */
8779 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8782 gen_helper_mfc0_count(arg
, cpu_env
);
8784 * Break the TB to be able to take timer interrupts immediately
8785 * after reading count. DISAS_STOP isn't sufficient, we need to
8786 * ensure we break completely out of translated code.
8788 gen_save_pc(ctx
->base
.pc_next
+ 4);
8789 ctx
->base
.is_jmp
= DISAS_EXIT
;
8790 register_name
= "Count";
8792 case CP0_REG09__SAARI
:
8793 CP0_CHECK(ctx
->saar
);
8794 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
8795 register_name
= "SAARI";
8797 case CP0_REG09__SAAR
:
8798 CP0_CHECK(ctx
->saar
);
8799 gen_helper_dmfc0_saar(arg
, cpu_env
);
8800 register_name
= "SAAR";
8803 goto cp0_unimplemented
;
8806 case CP0_REGISTER_10
:
8808 case CP0_REG10__ENTRYHI
:
8809 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
8810 register_name
= "EntryHi";
8813 goto cp0_unimplemented
;
8816 case CP0_REGISTER_11
:
8818 case CP0_REG11__COMPARE
:
8819 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
8820 register_name
= "Compare";
8822 /* 6,7 are implementation dependent */
8824 goto cp0_unimplemented
;
8827 case CP0_REGISTER_12
:
8829 case CP0_REG12__STATUS
:
8830 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
8831 register_name
= "Status";
8833 case CP0_REG12__INTCTL
:
8834 check_insn(ctx
, ISA_MIPS32R2
);
8835 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
8836 register_name
= "IntCtl";
8838 case CP0_REG12__SRSCTL
:
8839 check_insn(ctx
, ISA_MIPS32R2
);
8840 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
8841 register_name
= "SRSCtl";
8843 case CP0_REG12__SRSMAP
:
8844 check_insn(ctx
, ISA_MIPS32R2
);
8845 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8846 register_name
= "SRSMap";
8849 goto cp0_unimplemented
;
8852 case CP0_REGISTER_13
:
8854 case CP0_REG13__CAUSE
:
8855 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
8856 register_name
= "Cause";
8859 goto cp0_unimplemented
;
8862 case CP0_REGISTER_14
:
8864 case CP0_REG14__EPC
:
8865 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8866 register_name
= "EPC";
8869 goto cp0_unimplemented
;
8872 case CP0_REGISTER_15
:
8874 case CP0_REG15__PRID
:
8875 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
8876 register_name
= "PRid";
8878 case CP0_REG15__EBASE
:
8879 check_insn(ctx
, ISA_MIPS32R2
);
8880 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
8881 register_name
= "EBase";
8883 case CP0_REG15__CMGCRBASE
:
8884 check_insn(ctx
, ISA_MIPS32R2
);
8885 CP0_CHECK(ctx
->cmgcr
);
8886 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
8887 register_name
= "CMGCRBase";
8890 goto cp0_unimplemented
;
8893 case CP0_REGISTER_16
:
8895 case CP0_REG16__CONFIG
:
8896 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
8897 register_name
= "Config";
8899 case CP0_REG16__CONFIG1
:
8900 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
8901 register_name
= "Config1";
8903 case CP0_REG16__CONFIG2
:
8904 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
8905 register_name
= "Config2";
8907 case CP0_REG16__CONFIG3
:
8908 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
8909 register_name
= "Config3";
8911 case CP0_REG16__CONFIG4
:
8912 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
8913 register_name
= "Config4";
8915 case CP0_REG16__CONFIG5
:
8916 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
8917 register_name
= "Config5";
8919 /* 6,7 are implementation dependent */
8920 case CP0_REG16__CONFIG6
:
8921 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
8922 register_name
= "Config6";
8924 case CP0_REG16__CONFIG7
:
8925 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
8926 register_name
= "Config7";
8929 goto cp0_unimplemented
;
8932 case CP0_REGISTER_17
:
8934 case CP0_REG17__LLADDR
:
8935 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
8936 register_name
= "LLAddr";
8938 case CP0_REG17__MAAR
:
8939 CP0_CHECK(ctx
->mrp
);
8940 gen_helper_dmfc0_maar(arg
, cpu_env
);
8941 register_name
= "MAAR";
8943 case CP0_REG17__MAARI
:
8944 CP0_CHECK(ctx
->mrp
);
8945 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
8946 register_name
= "MAARI";
8949 goto cp0_unimplemented
;
8952 case CP0_REGISTER_18
:
8954 case CP0_REG18__WATCHLO0
:
8955 case CP0_REG18__WATCHLO1
:
8956 case CP0_REG18__WATCHLO2
:
8957 case CP0_REG18__WATCHLO3
:
8958 case CP0_REG18__WATCHLO4
:
8959 case CP0_REG18__WATCHLO5
:
8960 case CP0_REG18__WATCHLO6
:
8961 case CP0_REG18__WATCHLO7
:
8962 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8963 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
8964 register_name
= "WatchLo";
8967 goto cp0_unimplemented
;
8970 case CP0_REGISTER_19
:
8972 case CP0_REG19__WATCHHI0
:
8973 case CP0_REG19__WATCHHI1
:
8974 case CP0_REG19__WATCHHI2
:
8975 case CP0_REG19__WATCHHI3
:
8976 case CP0_REG19__WATCHHI4
:
8977 case CP0_REG19__WATCHHI5
:
8978 case CP0_REG19__WATCHHI6
:
8979 case CP0_REG19__WATCHHI7
:
8980 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8981 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
8982 register_name
= "WatchHi";
8985 goto cp0_unimplemented
;
8988 case CP0_REGISTER_20
:
8990 case CP0_REG20__XCONTEXT
:
8991 check_insn(ctx
, ISA_MIPS3
);
8992 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
8993 register_name
= "XContext";
8996 goto cp0_unimplemented
;
8999 case CP0_REGISTER_21
:
9000 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9001 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
9004 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
9005 register_name
= "Framemask";
9008 goto cp0_unimplemented
;
9011 case CP0_REGISTER_22
:
9012 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9013 register_name
= "'Diagnostic"; /* implementation dependent */
9015 case CP0_REGISTER_23
:
9017 case CP0_REG23__DEBUG
:
9018 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
9019 register_name
= "Debug";
9021 case CP0_REG23__TRACECONTROL
:
9022 /* PDtrace support */
9023 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
9024 register_name
= "TraceControl";
9025 goto cp0_unimplemented
;
9026 case CP0_REG23__TRACECONTROL2
:
9027 /* PDtrace support */
9028 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9029 register_name
= "TraceControl2";
9030 goto cp0_unimplemented
;
9031 case CP0_REG23__USERTRACEDATA1
:
9032 /* PDtrace support */
9033 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9034 register_name
= "UserTraceData1";
9035 goto cp0_unimplemented
;
9036 case CP0_REG23__TRACEIBPC
:
9037 /* PDtrace support */
9038 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9039 register_name
= "TraceIBPC";
9040 goto cp0_unimplemented
;
9041 case CP0_REG23__TRACEDBPC
:
9042 /* PDtrace support */
9043 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9044 register_name
= "TraceDBPC";
9045 goto cp0_unimplemented
;
9047 goto cp0_unimplemented
;
9050 case CP0_REGISTER_24
:
9052 case CP0_REG24__DEPC
:
9054 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9055 register_name
= "DEPC";
9058 goto cp0_unimplemented
;
9061 case CP0_REGISTER_25
:
9063 case CP0_REG25__PERFCTL0
:
9064 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
9065 register_name
= "Performance0";
9067 case CP0_REG25__PERFCNT0
:
9068 /* gen_helper_dmfc0_performance1(arg); */
9069 register_name
= "Performance1";
9070 goto cp0_unimplemented
;
9071 case CP0_REG25__PERFCTL1
:
9072 /* gen_helper_dmfc0_performance2(arg); */
9073 register_name
= "Performance2";
9074 goto cp0_unimplemented
;
9075 case CP0_REG25__PERFCNT1
:
9076 /* gen_helper_dmfc0_performance3(arg); */
9077 register_name
= "Performance3";
9078 goto cp0_unimplemented
;
9079 case CP0_REG25__PERFCTL2
:
9080 /* gen_helper_dmfc0_performance4(arg); */
9081 register_name
= "Performance4";
9082 goto cp0_unimplemented
;
9083 case CP0_REG25__PERFCNT2
:
9084 /* gen_helper_dmfc0_performance5(arg); */
9085 register_name
= "Performance5";
9086 goto cp0_unimplemented
;
9087 case CP0_REG25__PERFCTL3
:
9088 /* gen_helper_dmfc0_performance6(arg); */
9089 register_name
= "Performance6";
9090 goto cp0_unimplemented
;
9091 case CP0_REG25__PERFCNT3
:
9092 /* gen_helper_dmfc0_performance7(arg); */
9093 register_name
= "Performance7";
9094 goto cp0_unimplemented
;
9096 goto cp0_unimplemented
;
9099 case CP0_REGISTER_26
:
9101 case CP0_REG26__ERRCTL
:
9102 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
9103 register_name
= "ErrCtl";
9106 goto cp0_unimplemented
;
9109 case CP0_REGISTER_27
:
9112 case CP0_REG27__CACHERR
:
9113 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9114 register_name
= "CacheErr";
9117 goto cp0_unimplemented
;
9120 case CP0_REGISTER_28
:
9122 case CP0_REG28__TAGLO
:
9123 case CP0_REG28__TAGLO1
:
9124 case CP0_REG28__TAGLO2
:
9125 case CP0_REG28__TAGLO3
:
9126 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
9127 register_name
= "TagLo";
9129 case CP0_REG28__DATALO
:
9130 case CP0_REG28__DATALO1
:
9131 case CP0_REG28__DATALO2
:
9132 case CP0_REG28__DATALO3
:
9133 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
9134 register_name
= "DataLo";
9137 goto cp0_unimplemented
;
9140 case CP0_REGISTER_29
:
9142 case CP0_REG29__TAGHI
:
9143 case CP0_REG29__TAGHI1
:
9144 case CP0_REG29__TAGHI2
:
9145 case CP0_REG29__TAGHI3
:
9146 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
9147 register_name
= "TagHi";
9149 case CP0_REG29__DATAHI
:
9150 case CP0_REG29__DATAHI1
:
9151 case CP0_REG29__DATAHI2
:
9152 case CP0_REG29__DATAHI3
:
9153 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
9154 register_name
= "DataHi";
9157 goto cp0_unimplemented
;
9160 case CP0_REGISTER_30
:
9162 case CP0_REG30__ERROREPC
:
9163 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9164 register_name
= "ErrorEPC";
9167 goto cp0_unimplemented
;
9170 case CP0_REGISTER_31
:
9172 case CP0_REG31__DESAVE
:
9174 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9175 register_name
= "DESAVE";
9177 case CP0_REG31__KSCRATCH1
:
9178 case CP0_REG31__KSCRATCH2
:
9179 case CP0_REG31__KSCRATCH3
:
9180 case CP0_REG31__KSCRATCH4
:
9181 case CP0_REG31__KSCRATCH5
:
9182 case CP0_REG31__KSCRATCH6
:
9183 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9184 tcg_gen_ld_tl(arg
, cpu_env
,
9185 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9186 register_name
= "KScratch";
9189 goto cp0_unimplemented
;
9193 goto cp0_unimplemented
;
9195 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9199 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9200 register_name
, reg
, sel
);
9201 gen_mfc0_unimplemented(ctx
, arg
);
9204 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9206 const char *register_name
= "invalid";
9209 check_insn(ctx
, ISA_MIPS64
);
9212 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9217 case CP0_REGISTER_00
:
9219 case CP0_REG00__INDEX
:
9220 gen_helper_mtc0_index(cpu_env
, arg
);
9221 register_name
= "Index";
9223 case CP0_REG00__MVPCONTROL
:
9224 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9225 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9226 register_name
= "MVPControl";
9228 case CP0_REG00__MVPCONF0
:
9229 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9231 register_name
= "MVPConf0";
9233 case CP0_REG00__MVPCONF1
:
9234 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9236 register_name
= "MVPConf1";
9238 case CP0_REG00__VPCONTROL
:
9241 register_name
= "VPControl";
9244 goto cp0_unimplemented
;
9247 case CP0_REGISTER_01
:
9249 case CP0_REG01__RANDOM
:
9251 register_name
= "Random";
9253 case CP0_REG01__VPECONTROL
:
9254 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9255 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9256 register_name
= "VPEControl";
9258 case CP0_REG01__VPECONF0
:
9259 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9260 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9261 register_name
= "VPEConf0";
9263 case CP0_REG01__VPECONF1
:
9264 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9265 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9266 register_name
= "VPEConf1";
9268 case CP0_REG01__YQMASK
:
9269 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9270 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9271 register_name
= "YQMask";
9273 case CP0_REG01__VPESCHEDULE
:
9274 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9275 tcg_gen_st_tl(arg
, cpu_env
,
9276 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9277 register_name
= "VPESchedule";
9279 case CP0_REG01__VPESCHEFBACK
:
9280 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9281 tcg_gen_st_tl(arg
, cpu_env
,
9282 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9283 register_name
= "VPEScheFBack";
9285 case CP0_REG01__VPEOPT
:
9286 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9287 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9288 register_name
= "VPEOpt";
9291 goto cp0_unimplemented
;
9294 case CP0_REGISTER_02
:
9296 case CP0_REG02__ENTRYLO0
:
9297 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9298 register_name
= "EntryLo0";
9300 case CP0_REG02__TCSTATUS
:
9301 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9302 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9303 register_name
= "TCStatus";
9305 case CP0_REG02__TCBIND
:
9306 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9307 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9308 register_name
= "TCBind";
9310 case CP0_REG02__TCRESTART
:
9311 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9312 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9313 register_name
= "TCRestart";
9315 case CP0_REG02__TCHALT
:
9316 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9317 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9318 register_name
= "TCHalt";
9320 case CP0_REG02__TCCONTEXT
:
9321 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9322 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9323 register_name
= "TCContext";
9325 case CP0_REG02__TCSCHEDULE
:
9326 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9327 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9328 register_name
= "TCSchedule";
9330 case CP0_REG02__TCSCHEFBACK
:
9331 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9332 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9333 register_name
= "TCScheFBack";
9336 goto cp0_unimplemented
;
9339 case CP0_REGISTER_03
:
9341 case CP0_REG03__ENTRYLO1
:
9342 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9343 register_name
= "EntryLo1";
9345 case CP0_REG03__GLOBALNUM
:
9348 register_name
= "GlobalNumber";
9351 goto cp0_unimplemented
;
9354 case CP0_REGISTER_04
:
9356 case CP0_REG04__CONTEXT
:
9357 gen_helper_mtc0_context(cpu_env
, arg
);
9358 register_name
= "Context";
9360 case CP0_REG04__CONTEXTCONFIG
:
9362 /* gen_helper_dmtc0_contextconfig(arg); */
9363 register_name
= "ContextConfig";
9364 goto cp0_unimplemented
;
9365 case CP0_REG04__USERLOCAL
:
9366 CP0_CHECK(ctx
->ulri
);
9367 tcg_gen_st_tl(arg
, cpu_env
,
9368 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9369 register_name
= "UserLocal";
9371 case CP0_REG04__MMID
:
9373 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9374 register_name
= "MMID";
9377 goto cp0_unimplemented
;
9380 case CP0_REGISTER_05
:
9382 case CP0_REG05__PAGEMASK
:
9383 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9384 register_name
= "PageMask";
9386 case CP0_REG05__PAGEGRAIN
:
9387 check_insn(ctx
, ISA_MIPS32R2
);
9388 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9389 register_name
= "PageGrain";
9391 case CP0_REG05__SEGCTL0
:
9393 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9394 register_name
= "SegCtl0";
9396 case CP0_REG05__SEGCTL1
:
9398 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9399 register_name
= "SegCtl1";
9401 case CP0_REG05__SEGCTL2
:
9403 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9404 register_name
= "SegCtl2";
9406 case CP0_REG05__PWBASE
:
9408 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9409 register_name
= "PWBase";
9411 case CP0_REG05__PWFIELD
:
9413 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9414 register_name
= "PWField";
9416 case CP0_REG05__PWSIZE
:
9418 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9419 register_name
= "PWSize";
9422 goto cp0_unimplemented
;
9425 case CP0_REGISTER_06
:
9427 case CP0_REG06__WIRED
:
9428 gen_helper_mtc0_wired(cpu_env
, arg
);
9429 register_name
= "Wired";
9431 case CP0_REG06__SRSCONF0
:
9432 check_insn(ctx
, ISA_MIPS32R2
);
9433 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9434 register_name
= "SRSConf0";
9436 case CP0_REG06__SRSCONF1
:
9437 check_insn(ctx
, ISA_MIPS32R2
);
9438 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9439 register_name
= "SRSConf1";
9441 case CP0_REG06__SRSCONF2
:
9442 check_insn(ctx
, ISA_MIPS32R2
);
9443 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9444 register_name
= "SRSConf2";
9446 case CP0_REG06__SRSCONF3
:
9447 check_insn(ctx
, ISA_MIPS32R2
);
9448 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9449 register_name
= "SRSConf3";
9451 case CP0_REG06__SRSCONF4
:
9452 check_insn(ctx
, ISA_MIPS32R2
);
9453 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9454 register_name
= "SRSConf4";
9456 case CP0_REG06__PWCTL
:
9458 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9459 register_name
= "PWCtl";
9462 goto cp0_unimplemented
;
9465 case CP0_REGISTER_07
:
9467 case CP0_REG07__HWRENA
:
9468 check_insn(ctx
, ISA_MIPS32R2
);
9469 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9470 ctx
->base
.is_jmp
= DISAS_STOP
;
9471 register_name
= "HWREna";
9474 goto cp0_unimplemented
;
9477 case CP0_REGISTER_08
:
9479 case CP0_REG08__BADVADDR
:
9481 register_name
= "BadVAddr";
9483 case CP0_REG08__BADINSTR
:
9485 register_name
= "BadInstr";
9487 case CP0_REG08__BADINSTRP
:
9489 register_name
= "BadInstrP";
9491 case CP0_REG08__BADINSTRX
:
9493 register_name
= "BadInstrX";
9496 goto cp0_unimplemented
;
9499 case CP0_REGISTER_09
:
9501 case CP0_REG09__COUNT
:
9502 gen_helper_mtc0_count(cpu_env
, arg
);
9503 register_name
= "Count";
9505 case CP0_REG09__SAARI
:
9506 CP0_CHECK(ctx
->saar
);
9507 gen_helper_mtc0_saari(cpu_env
, arg
);
9508 register_name
= "SAARI";
9510 case CP0_REG09__SAAR
:
9511 CP0_CHECK(ctx
->saar
);
9512 gen_helper_mtc0_saar(cpu_env
, arg
);
9513 register_name
= "SAAR";
9516 goto cp0_unimplemented
;
9518 /* Stop translation as we may have switched the execution mode */
9519 ctx
->base
.is_jmp
= DISAS_STOP
;
9521 case CP0_REGISTER_10
:
9523 case CP0_REG10__ENTRYHI
:
9524 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9525 register_name
= "EntryHi";
9528 goto cp0_unimplemented
;
9531 case CP0_REGISTER_11
:
9533 case CP0_REG11__COMPARE
:
9534 gen_helper_mtc0_compare(cpu_env
, arg
);
9535 register_name
= "Compare";
9537 /* 6,7 are implementation dependent */
9539 goto cp0_unimplemented
;
9541 /* Stop translation as we may have switched the execution mode */
9542 ctx
->base
.is_jmp
= DISAS_STOP
;
9544 case CP0_REGISTER_12
:
9546 case CP0_REG12__STATUS
:
9547 save_cpu_state(ctx
, 1);
9548 gen_helper_mtc0_status(cpu_env
, arg
);
9549 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9550 gen_save_pc(ctx
->base
.pc_next
+ 4);
9551 ctx
->base
.is_jmp
= DISAS_EXIT
;
9552 register_name
= "Status";
9554 case CP0_REG12__INTCTL
:
9555 check_insn(ctx
, ISA_MIPS32R2
);
9556 gen_helper_mtc0_intctl(cpu_env
, arg
);
9557 /* Stop translation as we may have switched the execution mode */
9558 ctx
->base
.is_jmp
= DISAS_STOP
;
9559 register_name
= "IntCtl";
9561 case CP0_REG12__SRSCTL
:
9562 check_insn(ctx
, ISA_MIPS32R2
);
9563 gen_helper_mtc0_srsctl(cpu_env
, arg
);
9564 /* Stop translation as we may have switched the execution mode */
9565 ctx
->base
.is_jmp
= DISAS_STOP
;
9566 register_name
= "SRSCtl";
9568 case CP0_REG12__SRSMAP
:
9569 check_insn(ctx
, ISA_MIPS32R2
);
9570 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9571 /* Stop translation as we may have switched the execution mode */
9572 ctx
->base
.is_jmp
= DISAS_STOP
;
9573 register_name
= "SRSMap";
9576 goto cp0_unimplemented
;
9579 case CP0_REGISTER_13
:
9581 case CP0_REG13__CAUSE
:
9582 save_cpu_state(ctx
, 1);
9583 gen_helper_mtc0_cause(cpu_env
, arg
);
9585 * Stop translation as we may have triggered an interrupt.
9586 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9587 * translated code to check for pending interrupts.
9589 gen_save_pc(ctx
->base
.pc_next
+ 4);
9590 ctx
->base
.is_jmp
= DISAS_EXIT
;
9591 register_name
= "Cause";
9594 goto cp0_unimplemented
;
9597 case CP0_REGISTER_14
:
9599 case CP0_REG14__EPC
:
9600 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9601 register_name
= "EPC";
9604 goto cp0_unimplemented
;
9607 case CP0_REGISTER_15
:
9609 case CP0_REG15__PRID
:
9611 register_name
= "PRid";
9613 case CP0_REG15__EBASE
:
9614 check_insn(ctx
, ISA_MIPS32R2
);
9615 gen_helper_mtc0_ebase(cpu_env
, arg
);
9616 register_name
= "EBase";
9619 goto cp0_unimplemented
;
9622 case CP0_REGISTER_16
:
9624 case CP0_REG16__CONFIG
:
9625 gen_helper_mtc0_config0(cpu_env
, arg
);
9626 register_name
= "Config";
9627 /* Stop translation as we may have switched the execution mode */
9628 ctx
->base
.is_jmp
= DISAS_STOP
;
9630 case CP0_REG16__CONFIG1
:
9631 /* ignored, read only */
9632 register_name
= "Config1";
9634 case CP0_REG16__CONFIG2
:
9635 gen_helper_mtc0_config2(cpu_env
, arg
);
9636 register_name
= "Config2";
9637 /* Stop translation as we may have switched the execution mode */
9638 ctx
->base
.is_jmp
= DISAS_STOP
;
9640 case CP0_REG16__CONFIG3
:
9641 gen_helper_mtc0_config3(cpu_env
, arg
);
9642 register_name
= "Config3";
9643 /* Stop translation as we may have switched the execution mode */
9644 ctx
->base
.is_jmp
= DISAS_STOP
;
9646 case CP0_REG16__CONFIG4
:
9647 /* currently ignored */
9648 register_name
= "Config4";
9650 case CP0_REG16__CONFIG5
:
9651 gen_helper_mtc0_config5(cpu_env
, arg
);
9652 register_name
= "Config5";
9653 /* Stop translation as we may have switched the execution mode */
9654 ctx
->base
.is_jmp
= DISAS_STOP
;
9656 /* 6,7 are implementation dependent */
9658 register_name
= "Invalid config selector";
9659 goto cp0_unimplemented
;
9662 case CP0_REGISTER_17
:
9664 case CP0_REG17__LLADDR
:
9665 gen_helper_mtc0_lladdr(cpu_env
, arg
);
9666 register_name
= "LLAddr";
9668 case CP0_REG17__MAAR
:
9669 CP0_CHECK(ctx
->mrp
);
9670 gen_helper_mtc0_maar(cpu_env
, arg
);
9671 register_name
= "MAAR";
9673 case CP0_REG17__MAARI
:
9674 CP0_CHECK(ctx
->mrp
);
9675 gen_helper_mtc0_maari(cpu_env
, arg
);
9676 register_name
= "MAARI";
9679 goto cp0_unimplemented
;
9682 case CP0_REGISTER_18
:
9684 case CP0_REG18__WATCHLO0
:
9685 case CP0_REG18__WATCHLO1
:
9686 case CP0_REG18__WATCHLO2
:
9687 case CP0_REG18__WATCHLO3
:
9688 case CP0_REG18__WATCHLO4
:
9689 case CP0_REG18__WATCHLO5
:
9690 case CP0_REG18__WATCHLO6
:
9691 case CP0_REG18__WATCHLO7
:
9692 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9693 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
9694 register_name
= "WatchLo";
9697 goto cp0_unimplemented
;
9700 case CP0_REGISTER_19
:
9702 case CP0_REG19__WATCHHI0
:
9703 case CP0_REG19__WATCHHI1
:
9704 case CP0_REG19__WATCHHI2
:
9705 case CP0_REG19__WATCHHI3
:
9706 case CP0_REG19__WATCHHI4
:
9707 case CP0_REG19__WATCHHI5
:
9708 case CP0_REG19__WATCHHI6
:
9709 case CP0_REG19__WATCHHI7
:
9710 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9711 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
9712 register_name
= "WatchHi";
9715 goto cp0_unimplemented
;
9718 case CP0_REGISTER_20
:
9720 case CP0_REG20__XCONTEXT
:
9721 check_insn(ctx
, ISA_MIPS3
);
9722 gen_helper_mtc0_xcontext(cpu_env
, arg
);
9723 register_name
= "XContext";
9726 goto cp0_unimplemented
;
9729 case CP0_REGISTER_21
:
9730 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9731 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
9734 gen_helper_mtc0_framemask(cpu_env
, arg
);
9735 register_name
= "Framemask";
9738 goto cp0_unimplemented
;
9741 case CP0_REGISTER_22
:
9743 register_name
= "Diagnostic"; /* implementation dependent */
9745 case CP0_REGISTER_23
:
9747 case CP0_REG23__DEBUG
:
9748 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
9749 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9750 gen_save_pc(ctx
->base
.pc_next
+ 4);
9751 ctx
->base
.is_jmp
= DISAS_EXIT
;
9752 register_name
= "Debug";
9754 case CP0_REG23__TRACECONTROL
:
9755 /* PDtrace support */
9756 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
9757 /* Stop translation as we may have switched the execution mode */
9758 ctx
->base
.is_jmp
= DISAS_STOP
;
9759 register_name
= "TraceControl";
9760 goto cp0_unimplemented
;
9761 case CP0_REG23__TRACECONTROL2
:
9762 /* PDtrace support */
9763 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
9764 /* Stop translation as we may have switched the execution mode */
9765 ctx
->base
.is_jmp
= DISAS_STOP
;
9766 register_name
= "TraceControl2";
9767 goto cp0_unimplemented
;
9768 case CP0_REG23__USERTRACEDATA1
:
9769 /* PDtrace support */
9770 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
9771 /* Stop translation as we may have switched the execution mode */
9772 ctx
->base
.is_jmp
= DISAS_STOP
;
9773 register_name
= "UserTraceData1";
9774 goto cp0_unimplemented
;
9775 case CP0_REG23__TRACEIBPC
:
9776 /* PDtrace support */
9777 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
9778 /* Stop translation as we may have switched the execution mode */
9779 ctx
->base
.is_jmp
= DISAS_STOP
;
9780 register_name
= "TraceIBPC";
9781 goto cp0_unimplemented
;
9782 case CP0_REG23__TRACEDBPC
:
9783 /* PDtrace support */
9784 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
9785 /* Stop translation as we may have switched the execution mode */
9786 ctx
->base
.is_jmp
= DISAS_STOP
;
9787 register_name
= "TraceDBPC";
9788 goto cp0_unimplemented
;
9790 goto cp0_unimplemented
;
9793 case CP0_REGISTER_24
:
9795 case CP0_REG24__DEPC
:
9797 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9798 register_name
= "DEPC";
9801 goto cp0_unimplemented
;
9804 case CP0_REGISTER_25
:
9806 case CP0_REG25__PERFCTL0
:
9807 gen_helper_mtc0_performance0(cpu_env
, arg
);
9808 register_name
= "Performance0";
9810 case CP0_REG25__PERFCNT0
:
9811 /* gen_helper_mtc0_performance1(cpu_env, arg); */
9812 register_name
= "Performance1";
9813 goto cp0_unimplemented
;
9814 case CP0_REG25__PERFCTL1
:
9815 /* gen_helper_mtc0_performance2(cpu_env, arg); */
9816 register_name
= "Performance2";
9817 goto cp0_unimplemented
;
9818 case CP0_REG25__PERFCNT1
:
9819 /* gen_helper_mtc0_performance3(cpu_env, arg); */
9820 register_name
= "Performance3";
9821 goto cp0_unimplemented
;
9822 case CP0_REG25__PERFCTL2
:
9823 /* gen_helper_mtc0_performance4(cpu_env, arg); */
9824 register_name
= "Performance4";
9825 goto cp0_unimplemented
;
9826 case CP0_REG25__PERFCNT2
:
9827 /* gen_helper_mtc0_performance5(cpu_env, arg); */
9828 register_name
= "Performance5";
9829 goto cp0_unimplemented
;
9830 case CP0_REG25__PERFCTL3
:
9831 /* gen_helper_mtc0_performance6(cpu_env, arg); */
9832 register_name
= "Performance6";
9833 goto cp0_unimplemented
;
9834 case CP0_REG25__PERFCNT3
:
9835 /* gen_helper_mtc0_performance7(cpu_env, arg); */
9836 register_name
= "Performance7";
9837 goto cp0_unimplemented
;
9839 goto cp0_unimplemented
;
9842 case CP0_REGISTER_26
:
9844 case CP0_REG26__ERRCTL
:
9845 gen_helper_mtc0_errctl(cpu_env
, arg
);
9846 ctx
->base
.is_jmp
= DISAS_STOP
;
9847 register_name
= "ErrCtl";
9850 goto cp0_unimplemented
;
9853 case CP0_REGISTER_27
:
9855 case CP0_REG27__CACHERR
:
9857 register_name
= "CacheErr";
9860 goto cp0_unimplemented
;
9863 case CP0_REGISTER_28
:
9865 case CP0_REG28__TAGLO
:
9866 case CP0_REG28__TAGLO1
:
9867 case CP0_REG28__TAGLO2
:
9868 case CP0_REG28__TAGLO3
:
9869 gen_helper_mtc0_taglo(cpu_env
, arg
);
9870 register_name
= "TagLo";
9872 case CP0_REG28__DATALO
:
9873 case CP0_REG28__DATALO1
:
9874 case CP0_REG28__DATALO2
:
9875 case CP0_REG28__DATALO3
:
9876 gen_helper_mtc0_datalo(cpu_env
, arg
);
9877 register_name
= "DataLo";
9880 goto cp0_unimplemented
;
9883 case CP0_REGISTER_29
:
9885 case CP0_REG29__TAGHI
:
9886 case CP0_REG29__TAGHI1
:
9887 case CP0_REG29__TAGHI2
:
9888 case CP0_REG29__TAGHI3
:
9889 gen_helper_mtc0_taghi(cpu_env
, arg
);
9890 register_name
= "TagHi";
9892 case CP0_REG29__DATAHI
:
9893 case CP0_REG29__DATAHI1
:
9894 case CP0_REG29__DATAHI2
:
9895 case CP0_REG29__DATAHI3
:
9896 gen_helper_mtc0_datahi(cpu_env
, arg
);
9897 register_name
= "DataHi";
9900 register_name
= "invalid sel";
9901 goto cp0_unimplemented
;
9904 case CP0_REGISTER_30
:
9906 case CP0_REG30__ERROREPC
:
9907 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9908 register_name
= "ErrorEPC";
9911 goto cp0_unimplemented
;
9914 case CP0_REGISTER_31
:
9916 case CP0_REG31__DESAVE
:
9918 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9919 register_name
= "DESAVE";
9921 case CP0_REG31__KSCRATCH1
:
9922 case CP0_REG31__KSCRATCH2
:
9923 case CP0_REG31__KSCRATCH3
:
9924 case CP0_REG31__KSCRATCH4
:
9925 case CP0_REG31__KSCRATCH5
:
9926 case CP0_REG31__KSCRATCH6
:
9927 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9928 tcg_gen_st_tl(arg
, cpu_env
,
9929 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9930 register_name
= "KScratch";
9933 goto cp0_unimplemented
;
9937 goto cp0_unimplemented
;
9939 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
9941 /* For simplicity assume that all writes can cause interrupts. */
9942 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9944 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9945 * translated code to check for pending interrupts.
9947 gen_save_pc(ctx
->base
.pc_next
+ 4);
9948 ctx
->base
.is_jmp
= DISAS_EXIT
;
9953 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
9954 register_name
, reg
, sel
);
9956 #endif /* TARGET_MIPS64 */
9958 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
9959 int u
, int sel
, int h
)
9961 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9962 TCGv t0
= tcg_temp_local_new();
9964 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9965 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9966 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9967 tcg_gen_movi_tl(t0
, -1);
9968 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9969 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9970 tcg_gen_movi_tl(t0
, -1);
9971 } else if (u
== 0) {
9976 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
9979 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
9989 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
9992 gen_helper_mftc0_tcbind(t0
, cpu_env
);
9995 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
9998 gen_helper_mftc0_tchalt(t0
, cpu_env
);
10001 gen_helper_mftc0_tccontext(t0
, cpu_env
);
10004 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
10007 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
10010 gen_mfc0(ctx
, t0
, rt
, sel
);
10017 gen_helper_mftc0_entryhi(t0
, cpu_env
);
10020 gen_mfc0(ctx
, t0
, rt
, sel
);
10027 gen_helper_mftc0_status(t0
, cpu_env
);
10030 gen_mfc0(ctx
, t0
, rt
, sel
);
10037 gen_helper_mftc0_cause(t0
, cpu_env
);
10047 gen_helper_mftc0_epc(t0
, cpu_env
);
10057 gen_helper_mftc0_ebase(t0
, cpu_env
);
10074 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
10084 gen_helper_mftc0_debug(t0
, cpu_env
);
10087 gen_mfc0(ctx
, t0
, rt
, sel
);
10092 gen_mfc0(ctx
, t0
, rt
, sel
);
10096 /* GPR registers. */
10098 gen_helper_1e0i(mftgpr
, t0
, rt
);
10100 /* Auxiliary CPU registers */
10104 gen_helper_1e0i(mftlo
, t0
, 0);
10107 gen_helper_1e0i(mfthi
, t0
, 0);
10110 gen_helper_1e0i(mftacx
, t0
, 0);
10113 gen_helper_1e0i(mftlo
, t0
, 1);
10116 gen_helper_1e0i(mfthi
, t0
, 1);
10119 gen_helper_1e0i(mftacx
, t0
, 1);
10122 gen_helper_1e0i(mftlo
, t0
, 2);
10125 gen_helper_1e0i(mfthi
, t0
, 2);
10128 gen_helper_1e0i(mftacx
, t0
, 2);
10131 gen_helper_1e0i(mftlo
, t0
, 3);
10134 gen_helper_1e0i(mfthi
, t0
, 3);
10137 gen_helper_1e0i(mftacx
, t0
, 3);
10140 gen_helper_mftdsp(t0
, cpu_env
);
10146 /* Floating point (COP1). */
10148 /* XXX: For now we support only a single FPU context. */
10150 TCGv_i32 fp0
= tcg_temp_new_i32();
10152 gen_load_fpr32(ctx
, fp0
, rt
);
10153 tcg_gen_ext_i32_tl(t0
, fp0
);
10154 tcg_temp_free_i32(fp0
);
10156 TCGv_i32 fp0
= tcg_temp_new_i32();
10158 gen_load_fpr32h(ctx
, fp0
, rt
);
10159 tcg_gen_ext_i32_tl(t0
, fp0
);
10160 tcg_temp_free_i32(fp0
);
10164 /* XXX: For now we support only a single FPU context. */
10165 gen_helper_1e0i(cfc1
, t0
, rt
);
10167 /* COP2: Not implemented. */
10175 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10176 gen_store_gpr(t0
, rd
);
10182 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10183 generate_exception_end(ctx
, EXCP_RI
);
10186 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10187 int u
, int sel
, int h
)
10189 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10190 TCGv t0
= tcg_temp_local_new();
10192 gen_load_gpr(t0
, rt
);
10193 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10194 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10195 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10198 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10199 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10202 } else if (u
== 0) {
10207 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10210 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10220 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10223 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10226 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10229 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10232 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10235 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10238 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10241 gen_mtc0(ctx
, t0
, rd
, sel
);
10248 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10251 gen_mtc0(ctx
, t0
, rd
, sel
);
10258 gen_helper_mttc0_status(cpu_env
, t0
);
10261 gen_mtc0(ctx
, t0
, rd
, sel
);
10268 gen_helper_mttc0_cause(cpu_env
, t0
);
10278 gen_helper_mttc0_ebase(cpu_env
, t0
);
10288 gen_helper_mttc0_debug(cpu_env
, t0
);
10291 gen_mtc0(ctx
, t0
, rd
, sel
);
10296 gen_mtc0(ctx
, t0
, rd
, sel
);
10300 /* GPR registers. */
10302 gen_helper_0e1i(mttgpr
, t0
, rd
);
10304 /* Auxiliary CPU registers */
10308 gen_helper_0e1i(mttlo
, t0
, 0);
10311 gen_helper_0e1i(mtthi
, t0
, 0);
10314 gen_helper_0e1i(mttacx
, t0
, 0);
10317 gen_helper_0e1i(mttlo
, t0
, 1);
10320 gen_helper_0e1i(mtthi
, t0
, 1);
10323 gen_helper_0e1i(mttacx
, t0
, 1);
10326 gen_helper_0e1i(mttlo
, t0
, 2);
10329 gen_helper_0e1i(mtthi
, t0
, 2);
10332 gen_helper_0e1i(mttacx
, t0
, 2);
10335 gen_helper_0e1i(mttlo
, t0
, 3);
10338 gen_helper_0e1i(mtthi
, t0
, 3);
10341 gen_helper_0e1i(mttacx
, t0
, 3);
10344 gen_helper_mttdsp(cpu_env
, t0
);
10350 /* Floating point (COP1). */
10352 /* XXX: For now we support only a single FPU context. */
10354 TCGv_i32 fp0
= tcg_temp_new_i32();
10356 tcg_gen_trunc_tl_i32(fp0
, t0
);
10357 gen_store_fpr32(ctx
, fp0
, rd
);
10358 tcg_temp_free_i32(fp0
);
10360 TCGv_i32 fp0
= tcg_temp_new_i32();
10362 tcg_gen_trunc_tl_i32(fp0
, t0
);
10363 gen_store_fpr32h(ctx
, fp0
, rd
);
10364 tcg_temp_free_i32(fp0
);
10368 /* XXX: For now we support only a single FPU context. */
10370 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10372 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10373 tcg_temp_free_i32(fs_tmp
);
10375 /* Stop translation as we may have changed hflags */
10376 ctx
->base
.is_jmp
= DISAS_STOP
;
10378 /* COP2: Not implemented. */
10386 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10392 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10393 generate_exception_end(ctx
, EXCP_RI
);
10396 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10399 const char *opn
= "ldst";
10401 check_cp0_enabled(ctx
);
10405 /* Treat as NOP. */
10408 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10413 TCGv t0
= tcg_temp_new();
10415 gen_load_gpr(t0
, rt
);
10416 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10421 #if defined(TARGET_MIPS64)
10423 check_insn(ctx
, ISA_MIPS3
);
10425 /* Treat as NOP. */
10428 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10432 check_insn(ctx
, ISA_MIPS3
);
10434 TCGv t0
= tcg_temp_new();
10436 gen_load_gpr(t0
, rt
);
10437 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10446 /* Treat as NOP. */
10449 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10455 TCGv t0
= tcg_temp_new();
10456 gen_load_gpr(t0
, rt
);
10457 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10463 check_cp0_enabled(ctx
);
10465 /* Treat as NOP. */
10468 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10469 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10473 check_cp0_enabled(ctx
);
10474 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10475 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10480 if (!env
->tlb
->helper_tlbwi
) {
10483 gen_helper_tlbwi(cpu_env
);
10487 if (ctx
->ie
>= 2) {
10488 if (!env
->tlb
->helper_tlbinv
) {
10491 gen_helper_tlbinv(cpu_env
);
10492 } /* treat as nop if TLBINV not supported */
10496 if (ctx
->ie
>= 2) {
10497 if (!env
->tlb
->helper_tlbinvf
) {
10500 gen_helper_tlbinvf(cpu_env
);
10501 } /* treat as nop if TLBINV not supported */
10505 if (!env
->tlb
->helper_tlbwr
) {
10508 gen_helper_tlbwr(cpu_env
);
10512 if (!env
->tlb
->helper_tlbp
) {
10515 gen_helper_tlbp(cpu_env
);
10519 if (!env
->tlb
->helper_tlbr
) {
10522 gen_helper_tlbr(cpu_env
);
10524 case OPC_ERET
: /* OPC_ERETNC */
10525 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10526 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10529 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10530 if (ctx
->opcode
& (1 << bit_shift
)) {
10533 check_insn(ctx
, ISA_MIPS32R5
);
10534 gen_helper_eretnc(cpu_env
);
10538 check_insn(ctx
, ISA_MIPS2
);
10539 gen_helper_eret(cpu_env
);
10541 ctx
->base
.is_jmp
= DISAS_EXIT
;
10546 check_insn(ctx
, ISA_MIPS32
);
10547 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10548 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10551 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10553 generate_exception_end(ctx
, EXCP_RI
);
10555 gen_helper_deret(cpu_env
);
10556 ctx
->base
.is_jmp
= DISAS_EXIT
;
10561 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
10562 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10563 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10566 /* If we get an exception, we want to restart at next instruction */
10567 ctx
->base
.pc_next
+= 4;
10568 save_cpu_state(ctx
, 1);
10569 ctx
->base
.pc_next
-= 4;
10570 gen_helper_wait(cpu_env
);
10571 ctx
->base
.is_jmp
= DISAS_NORETURN
;
10576 generate_exception_end(ctx
, EXCP_RI
);
10579 (void)opn
; /* avoid a compiler warning */
10581 #endif /* !CONFIG_USER_ONLY */
10583 /* CP1 Branches (before delay slot) */
10584 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
10585 int32_t cc
, int32_t offset
)
10587 target_ulong btarget
;
10588 TCGv_i32 t0
= tcg_temp_new_i32();
10590 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10591 generate_exception_end(ctx
, EXCP_RI
);
10596 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
10599 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
10603 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10604 tcg_gen_not_i32(t0
, t0
);
10605 tcg_gen_andi_i32(t0
, t0
, 1);
10606 tcg_gen_extu_i32_tl(bcond
, t0
);
10609 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10610 tcg_gen_not_i32(t0
, t0
);
10611 tcg_gen_andi_i32(t0
, t0
, 1);
10612 tcg_gen_extu_i32_tl(bcond
, t0
);
10615 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10616 tcg_gen_andi_i32(t0
, t0
, 1);
10617 tcg_gen_extu_i32_tl(bcond
, t0
);
10620 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10621 tcg_gen_andi_i32(t0
, t0
, 1);
10622 tcg_gen_extu_i32_tl(bcond
, t0
);
10624 ctx
->hflags
|= MIPS_HFLAG_BL
;
10628 TCGv_i32 t1
= tcg_temp_new_i32();
10629 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10630 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10631 tcg_gen_nand_i32(t0
, t0
, t1
);
10632 tcg_temp_free_i32(t1
);
10633 tcg_gen_andi_i32(t0
, t0
, 1);
10634 tcg_gen_extu_i32_tl(bcond
, t0
);
10639 TCGv_i32 t1
= tcg_temp_new_i32();
10640 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10641 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10642 tcg_gen_or_i32(t0
, t0
, t1
);
10643 tcg_temp_free_i32(t1
);
10644 tcg_gen_andi_i32(t0
, t0
, 1);
10645 tcg_gen_extu_i32_tl(bcond
, t0
);
10650 TCGv_i32 t1
= tcg_temp_new_i32();
10651 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10652 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10653 tcg_gen_and_i32(t0
, t0
, t1
);
10654 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10655 tcg_gen_and_i32(t0
, t0
, t1
);
10656 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10657 tcg_gen_nand_i32(t0
, t0
, t1
);
10658 tcg_temp_free_i32(t1
);
10659 tcg_gen_andi_i32(t0
, t0
, 1);
10660 tcg_gen_extu_i32_tl(bcond
, t0
);
10665 TCGv_i32 t1
= tcg_temp_new_i32();
10666 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10667 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10668 tcg_gen_or_i32(t0
, t0
, t1
);
10669 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10670 tcg_gen_or_i32(t0
, t0
, t1
);
10671 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10672 tcg_gen_or_i32(t0
, t0
, t1
);
10673 tcg_temp_free_i32(t1
);
10674 tcg_gen_andi_i32(t0
, t0
, 1);
10675 tcg_gen_extu_i32_tl(bcond
, t0
);
10678 ctx
->hflags
|= MIPS_HFLAG_BC
;
10681 MIPS_INVAL("cp1 cond branch");
10682 generate_exception_end(ctx
, EXCP_RI
);
10685 ctx
->btarget
= btarget
;
10686 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10688 tcg_temp_free_i32(t0
);
10691 /* R6 CP1 Branches */
10692 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
10693 int32_t ft
, int32_t offset
,
10694 int delayslot_size
)
10696 target_ulong btarget
;
10697 TCGv_i64 t0
= tcg_temp_new_i64();
10699 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10700 #ifdef MIPS_DEBUG_DISAS
10701 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10702 "\n", ctx
->base
.pc_next
);
10704 generate_exception_end(ctx
, EXCP_RI
);
10708 gen_load_fpr64(ctx
, t0
, ft
);
10709 tcg_gen_andi_i64(t0
, t0
, 1);
10711 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
10715 tcg_gen_xori_i64(t0
, t0
, 1);
10716 ctx
->hflags
|= MIPS_HFLAG_BC
;
10719 /* t0 already set */
10720 ctx
->hflags
|= MIPS_HFLAG_BC
;
10723 MIPS_INVAL("cp1 cond branch");
10724 generate_exception_end(ctx
, EXCP_RI
);
10728 tcg_gen_trunc_i64_tl(bcond
, t0
);
10730 ctx
->btarget
= btarget
;
10732 switch (delayslot_size
) {
10734 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
10737 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10742 tcg_temp_free_i64(t0
);
10745 /* Coprocessor 1 (FPU) */
10747 #define FOP(func, fmt) (((fmt) << 21) | (func))
10750 OPC_ADD_S
= FOP(0, FMT_S
),
10751 OPC_SUB_S
= FOP(1, FMT_S
),
10752 OPC_MUL_S
= FOP(2, FMT_S
),
10753 OPC_DIV_S
= FOP(3, FMT_S
),
10754 OPC_SQRT_S
= FOP(4, FMT_S
),
10755 OPC_ABS_S
= FOP(5, FMT_S
),
10756 OPC_MOV_S
= FOP(6, FMT_S
),
10757 OPC_NEG_S
= FOP(7, FMT_S
),
10758 OPC_ROUND_L_S
= FOP(8, FMT_S
),
10759 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
10760 OPC_CEIL_L_S
= FOP(10, FMT_S
),
10761 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
10762 OPC_ROUND_W_S
= FOP(12, FMT_S
),
10763 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
10764 OPC_CEIL_W_S
= FOP(14, FMT_S
),
10765 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
10766 OPC_SEL_S
= FOP(16, FMT_S
),
10767 OPC_MOVCF_S
= FOP(17, FMT_S
),
10768 OPC_MOVZ_S
= FOP(18, FMT_S
),
10769 OPC_MOVN_S
= FOP(19, FMT_S
),
10770 OPC_SELEQZ_S
= FOP(20, FMT_S
),
10771 OPC_RECIP_S
= FOP(21, FMT_S
),
10772 OPC_RSQRT_S
= FOP(22, FMT_S
),
10773 OPC_SELNEZ_S
= FOP(23, FMT_S
),
10774 OPC_MADDF_S
= FOP(24, FMT_S
),
10775 OPC_MSUBF_S
= FOP(25, FMT_S
),
10776 OPC_RINT_S
= FOP(26, FMT_S
),
10777 OPC_CLASS_S
= FOP(27, FMT_S
),
10778 OPC_MIN_S
= FOP(28, FMT_S
),
10779 OPC_RECIP2_S
= FOP(28, FMT_S
),
10780 OPC_MINA_S
= FOP(29, FMT_S
),
10781 OPC_RECIP1_S
= FOP(29, FMT_S
),
10782 OPC_MAX_S
= FOP(30, FMT_S
),
10783 OPC_RSQRT1_S
= FOP(30, FMT_S
),
10784 OPC_MAXA_S
= FOP(31, FMT_S
),
10785 OPC_RSQRT2_S
= FOP(31, FMT_S
),
10786 OPC_CVT_D_S
= FOP(33, FMT_S
),
10787 OPC_CVT_W_S
= FOP(36, FMT_S
),
10788 OPC_CVT_L_S
= FOP(37, FMT_S
),
10789 OPC_CVT_PS_S
= FOP(38, FMT_S
),
10790 OPC_CMP_F_S
= FOP(48, FMT_S
),
10791 OPC_CMP_UN_S
= FOP(49, FMT_S
),
10792 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
10793 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
10794 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
10795 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
10796 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
10797 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
10798 OPC_CMP_SF_S
= FOP(56, FMT_S
),
10799 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
10800 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
10801 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
10802 OPC_CMP_LT_S
= FOP(60, FMT_S
),
10803 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
10804 OPC_CMP_LE_S
= FOP(62, FMT_S
),
10805 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
10807 OPC_ADD_D
= FOP(0, FMT_D
),
10808 OPC_SUB_D
= FOP(1, FMT_D
),
10809 OPC_MUL_D
= FOP(2, FMT_D
),
10810 OPC_DIV_D
= FOP(3, FMT_D
),
10811 OPC_SQRT_D
= FOP(4, FMT_D
),
10812 OPC_ABS_D
= FOP(5, FMT_D
),
10813 OPC_MOV_D
= FOP(6, FMT_D
),
10814 OPC_NEG_D
= FOP(7, FMT_D
),
10815 OPC_ROUND_L_D
= FOP(8, FMT_D
),
10816 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
10817 OPC_CEIL_L_D
= FOP(10, FMT_D
),
10818 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
10819 OPC_ROUND_W_D
= FOP(12, FMT_D
),
10820 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
10821 OPC_CEIL_W_D
= FOP(14, FMT_D
),
10822 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
10823 OPC_SEL_D
= FOP(16, FMT_D
),
10824 OPC_MOVCF_D
= FOP(17, FMT_D
),
10825 OPC_MOVZ_D
= FOP(18, FMT_D
),
10826 OPC_MOVN_D
= FOP(19, FMT_D
),
10827 OPC_SELEQZ_D
= FOP(20, FMT_D
),
10828 OPC_RECIP_D
= FOP(21, FMT_D
),
10829 OPC_RSQRT_D
= FOP(22, FMT_D
),
10830 OPC_SELNEZ_D
= FOP(23, FMT_D
),
10831 OPC_MADDF_D
= FOP(24, FMT_D
),
10832 OPC_MSUBF_D
= FOP(25, FMT_D
),
10833 OPC_RINT_D
= FOP(26, FMT_D
),
10834 OPC_CLASS_D
= FOP(27, FMT_D
),
10835 OPC_MIN_D
= FOP(28, FMT_D
),
10836 OPC_RECIP2_D
= FOP(28, FMT_D
),
10837 OPC_MINA_D
= FOP(29, FMT_D
),
10838 OPC_RECIP1_D
= FOP(29, FMT_D
),
10839 OPC_MAX_D
= FOP(30, FMT_D
),
10840 OPC_RSQRT1_D
= FOP(30, FMT_D
),
10841 OPC_MAXA_D
= FOP(31, FMT_D
),
10842 OPC_RSQRT2_D
= FOP(31, FMT_D
),
10843 OPC_CVT_S_D
= FOP(32, FMT_D
),
10844 OPC_CVT_W_D
= FOP(36, FMT_D
),
10845 OPC_CVT_L_D
= FOP(37, FMT_D
),
10846 OPC_CMP_F_D
= FOP(48, FMT_D
),
10847 OPC_CMP_UN_D
= FOP(49, FMT_D
),
10848 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
10849 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
10850 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
10851 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
10852 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
10853 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
10854 OPC_CMP_SF_D
= FOP(56, FMT_D
),
10855 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
10856 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
10857 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
10858 OPC_CMP_LT_D
= FOP(60, FMT_D
),
10859 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
10860 OPC_CMP_LE_D
= FOP(62, FMT_D
),
10861 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
10863 OPC_CVT_S_W
= FOP(32, FMT_W
),
10864 OPC_CVT_D_W
= FOP(33, FMT_W
),
10865 OPC_CVT_S_L
= FOP(32, FMT_L
),
10866 OPC_CVT_D_L
= FOP(33, FMT_L
),
10867 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
10869 OPC_ADD_PS
= FOP(0, FMT_PS
),
10870 OPC_SUB_PS
= FOP(1, FMT_PS
),
10871 OPC_MUL_PS
= FOP(2, FMT_PS
),
10872 OPC_DIV_PS
= FOP(3, FMT_PS
),
10873 OPC_ABS_PS
= FOP(5, FMT_PS
),
10874 OPC_MOV_PS
= FOP(6, FMT_PS
),
10875 OPC_NEG_PS
= FOP(7, FMT_PS
),
10876 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
10877 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
10878 OPC_MOVN_PS
= FOP(19, FMT_PS
),
10879 OPC_ADDR_PS
= FOP(24, FMT_PS
),
10880 OPC_MULR_PS
= FOP(26, FMT_PS
),
10881 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
10882 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
10883 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
10884 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
10886 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
10887 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
10888 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
10889 OPC_PLL_PS
= FOP(44, FMT_PS
),
10890 OPC_PLU_PS
= FOP(45, FMT_PS
),
10891 OPC_PUL_PS
= FOP(46, FMT_PS
),
10892 OPC_PUU_PS
= FOP(47, FMT_PS
),
10893 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
10894 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
10895 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
10896 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
10897 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
10898 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
10899 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
10900 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
10901 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
10902 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
10903 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
10904 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
10905 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
10906 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
10907 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
10908 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
10912 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
10913 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
10914 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
10915 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
10916 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
10917 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
10918 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
10919 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
10920 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
10921 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
10922 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
10923 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
10924 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
10925 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
10926 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
10927 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
10928 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
10929 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
10930 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
10931 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
10932 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
10933 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
10935 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
10936 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
10937 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
10938 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
10939 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
10940 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
10941 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
10942 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
10943 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
10944 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
10945 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
10946 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
10947 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
10948 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
10949 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
10950 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
10951 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
10952 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
10953 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
10954 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
10955 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
10956 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
10959 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
10961 TCGv t0
= tcg_temp_new();
10966 TCGv_i32 fp0
= tcg_temp_new_i32();
10968 gen_load_fpr32(ctx
, fp0
, fs
);
10969 tcg_gen_ext_i32_tl(t0
, fp0
);
10970 tcg_temp_free_i32(fp0
);
10972 gen_store_gpr(t0
, rt
);
10975 gen_load_gpr(t0
, rt
);
10977 TCGv_i32 fp0
= tcg_temp_new_i32();
10979 tcg_gen_trunc_tl_i32(fp0
, t0
);
10980 gen_store_fpr32(ctx
, fp0
, fs
);
10981 tcg_temp_free_i32(fp0
);
10985 gen_helper_1e0i(cfc1
, t0
, fs
);
10986 gen_store_gpr(t0
, rt
);
10989 gen_load_gpr(t0
, rt
);
10990 save_cpu_state(ctx
, 0);
10992 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
10994 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10995 tcg_temp_free_i32(fs_tmp
);
10997 /* Stop translation as we may have changed hflags */
10998 ctx
->base
.is_jmp
= DISAS_STOP
;
11000 #if defined(TARGET_MIPS64)
11002 gen_load_fpr64(ctx
, t0
, fs
);
11003 gen_store_gpr(t0
, rt
);
11006 gen_load_gpr(t0
, rt
);
11007 gen_store_fpr64(ctx
, t0
, fs
);
11012 TCGv_i32 fp0
= tcg_temp_new_i32();
11014 gen_load_fpr32h(ctx
, fp0
, fs
);
11015 tcg_gen_ext_i32_tl(t0
, fp0
);
11016 tcg_temp_free_i32(fp0
);
11018 gen_store_gpr(t0
, rt
);
11021 gen_load_gpr(t0
, rt
);
11023 TCGv_i32 fp0
= tcg_temp_new_i32();
11025 tcg_gen_trunc_tl_i32(fp0
, t0
);
11026 gen_store_fpr32h(ctx
, fp0
, fs
);
11027 tcg_temp_free_i32(fp0
);
11031 MIPS_INVAL("cp1 move");
11032 generate_exception_end(ctx
, EXCP_RI
);
11040 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
11047 /* Treat as NOP. */
11052 cond
= TCG_COND_EQ
;
11054 cond
= TCG_COND_NE
;
11057 l1
= gen_new_label();
11058 t0
= tcg_temp_new_i32();
11059 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11060 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11061 tcg_temp_free_i32(t0
);
11063 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
11065 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
11070 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11074 TCGv_i32 t0
= tcg_temp_new_i32();
11075 TCGLabel
*l1
= gen_new_label();
11078 cond
= TCG_COND_EQ
;
11080 cond
= TCG_COND_NE
;
11083 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11084 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11085 gen_load_fpr32(ctx
, t0
, fs
);
11086 gen_store_fpr32(ctx
, t0
, fd
);
11088 tcg_temp_free_i32(t0
);
11091 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11095 TCGv_i32 t0
= tcg_temp_new_i32();
11097 TCGLabel
*l1
= gen_new_label();
11100 cond
= TCG_COND_EQ
;
11102 cond
= TCG_COND_NE
;
11105 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11106 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11107 tcg_temp_free_i32(t0
);
11108 fp0
= tcg_temp_new_i64();
11109 gen_load_fpr64(ctx
, fp0
, fs
);
11110 gen_store_fpr64(ctx
, fp0
, fd
);
11111 tcg_temp_free_i64(fp0
);
11115 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
11119 TCGv_i32 t0
= tcg_temp_new_i32();
11120 TCGLabel
*l1
= gen_new_label();
11121 TCGLabel
*l2
= gen_new_label();
11124 cond
= TCG_COND_EQ
;
11126 cond
= TCG_COND_NE
;
11129 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11130 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11131 gen_load_fpr32(ctx
, t0
, fs
);
11132 gen_store_fpr32(ctx
, t0
, fd
);
11135 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
11136 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
11137 gen_load_fpr32h(ctx
, t0
, fs
);
11138 gen_store_fpr32h(ctx
, t0
, fd
);
11139 tcg_temp_free_i32(t0
);
11143 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11146 TCGv_i32 t1
= tcg_const_i32(0);
11147 TCGv_i32 fp0
= tcg_temp_new_i32();
11148 TCGv_i32 fp1
= tcg_temp_new_i32();
11149 TCGv_i32 fp2
= tcg_temp_new_i32();
11150 gen_load_fpr32(ctx
, fp0
, fd
);
11151 gen_load_fpr32(ctx
, fp1
, ft
);
11152 gen_load_fpr32(ctx
, fp2
, fs
);
11156 tcg_gen_andi_i32(fp0
, fp0
, 1);
11157 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11160 tcg_gen_andi_i32(fp1
, fp1
, 1);
11161 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11164 tcg_gen_andi_i32(fp1
, fp1
, 1);
11165 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11168 MIPS_INVAL("gen_sel_s");
11169 generate_exception_end(ctx
, EXCP_RI
);
11173 gen_store_fpr32(ctx
, fp0
, fd
);
11174 tcg_temp_free_i32(fp2
);
11175 tcg_temp_free_i32(fp1
);
11176 tcg_temp_free_i32(fp0
);
11177 tcg_temp_free_i32(t1
);
11180 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11183 TCGv_i64 t1
= tcg_const_i64(0);
11184 TCGv_i64 fp0
= tcg_temp_new_i64();
11185 TCGv_i64 fp1
= tcg_temp_new_i64();
11186 TCGv_i64 fp2
= tcg_temp_new_i64();
11187 gen_load_fpr64(ctx
, fp0
, fd
);
11188 gen_load_fpr64(ctx
, fp1
, ft
);
11189 gen_load_fpr64(ctx
, fp2
, fs
);
11193 tcg_gen_andi_i64(fp0
, fp0
, 1);
11194 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11197 tcg_gen_andi_i64(fp1
, fp1
, 1);
11198 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11201 tcg_gen_andi_i64(fp1
, fp1
, 1);
11202 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11205 MIPS_INVAL("gen_sel_d");
11206 generate_exception_end(ctx
, EXCP_RI
);
11210 gen_store_fpr64(ctx
, fp0
, fd
);
11211 tcg_temp_free_i64(fp2
);
11212 tcg_temp_free_i64(fp1
);
11213 tcg_temp_free_i64(fp0
);
11214 tcg_temp_free_i64(t1
);
11217 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11218 int ft
, int fs
, int fd
, int cc
)
11220 uint32_t func
= ctx
->opcode
& 0x3f;
11224 TCGv_i32 fp0
= tcg_temp_new_i32();
11225 TCGv_i32 fp1
= tcg_temp_new_i32();
11227 gen_load_fpr32(ctx
, fp0
, fs
);
11228 gen_load_fpr32(ctx
, fp1
, ft
);
11229 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11230 tcg_temp_free_i32(fp1
);
11231 gen_store_fpr32(ctx
, fp0
, fd
);
11232 tcg_temp_free_i32(fp0
);
11237 TCGv_i32 fp0
= tcg_temp_new_i32();
11238 TCGv_i32 fp1
= tcg_temp_new_i32();
11240 gen_load_fpr32(ctx
, fp0
, fs
);
11241 gen_load_fpr32(ctx
, fp1
, ft
);
11242 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11243 tcg_temp_free_i32(fp1
);
11244 gen_store_fpr32(ctx
, fp0
, fd
);
11245 tcg_temp_free_i32(fp0
);
11250 TCGv_i32 fp0
= tcg_temp_new_i32();
11251 TCGv_i32 fp1
= tcg_temp_new_i32();
11253 gen_load_fpr32(ctx
, fp0
, fs
);
11254 gen_load_fpr32(ctx
, fp1
, ft
);
11255 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11256 tcg_temp_free_i32(fp1
);
11257 gen_store_fpr32(ctx
, fp0
, fd
);
11258 tcg_temp_free_i32(fp0
);
11263 TCGv_i32 fp0
= tcg_temp_new_i32();
11264 TCGv_i32 fp1
= tcg_temp_new_i32();
11266 gen_load_fpr32(ctx
, fp0
, fs
);
11267 gen_load_fpr32(ctx
, fp1
, ft
);
11268 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11269 tcg_temp_free_i32(fp1
);
11270 gen_store_fpr32(ctx
, fp0
, fd
);
11271 tcg_temp_free_i32(fp0
);
11276 TCGv_i32 fp0
= tcg_temp_new_i32();
11278 gen_load_fpr32(ctx
, fp0
, fs
);
11279 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11280 gen_store_fpr32(ctx
, fp0
, fd
);
11281 tcg_temp_free_i32(fp0
);
11286 TCGv_i32 fp0
= tcg_temp_new_i32();
11288 gen_load_fpr32(ctx
, fp0
, fs
);
11289 if (ctx
->abs2008
) {
11290 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11292 gen_helper_float_abs_s(fp0
, fp0
);
11294 gen_store_fpr32(ctx
, fp0
, fd
);
11295 tcg_temp_free_i32(fp0
);
11300 TCGv_i32 fp0
= tcg_temp_new_i32();
11302 gen_load_fpr32(ctx
, fp0
, fs
);
11303 gen_store_fpr32(ctx
, fp0
, fd
);
11304 tcg_temp_free_i32(fp0
);
11309 TCGv_i32 fp0
= tcg_temp_new_i32();
11311 gen_load_fpr32(ctx
, fp0
, fs
);
11312 if (ctx
->abs2008
) {
11313 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11315 gen_helper_float_chs_s(fp0
, fp0
);
11317 gen_store_fpr32(ctx
, fp0
, fd
);
11318 tcg_temp_free_i32(fp0
);
11321 case OPC_ROUND_L_S
:
11322 check_cp1_64bitmode(ctx
);
11324 TCGv_i32 fp32
= tcg_temp_new_i32();
11325 TCGv_i64 fp64
= tcg_temp_new_i64();
11327 gen_load_fpr32(ctx
, fp32
, fs
);
11328 if (ctx
->nan2008
) {
11329 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11331 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11333 tcg_temp_free_i32(fp32
);
11334 gen_store_fpr64(ctx
, fp64
, fd
);
11335 tcg_temp_free_i64(fp64
);
11338 case OPC_TRUNC_L_S
:
11339 check_cp1_64bitmode(ctx
);
11341 TCGv_i32 fp32
= tcg_temp_new_i32();
11342 TCGv_i64 fp64
= tcg_temp_new_i64();
11344 gen_load_fpr32(ctx
, fp32
, fs
);
11345 if (ctx
->nan2008
) {
11346 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11348 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11350 tcg_temp_free_i32(fp32
);
11351 gen_store_fpr64(ctx
, fp64
, fd
);
11352 tcg_temp_free_i64(fp64
);
11356 check_cp1_64bitmode(ctx
);
11358 TCGv_i32 fp32
= tcg_temp_new_i32();
11359 TCGv_i64 fp64
= tcg_temp_new_i64();
11361 gen_load_fpr32(ctx
, fp32
, fs
);
11362 if (ctx
->nan2008
) {
11363 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11365 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11367 tcg_temp_free_i32(fp32
);
11368 gen_store_fpr64(ctx
, fp64
, fd
);
11369 tcg_temp_free_i64(fp64
);
11372 case OPC_FLOOR_L_S
:
11373 check_cp1_64bitmode(ctx
);
11375 TCGv_i32 fp32
= tcg_temp_new_i32();
11376 TCGv_i64 fp64
= tcg_temp_new_i64();
11378 gen_load_fpr32(ctx
, fp32
, fs
);
11379 if (ctx
->nan2008
) {
11380 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11382 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11384 tcg_temp_free_i32(fp32
);
11385 gen_store_fpr64(ctx
, fp64
, fd
);
11386 tcg_temp_free_i64(fp64
);
11389 case OPC_ROUND_W_S
:
11391 TCGv_i32 fp0
= tcg_temp_new_i32();
11393 gen_load_fpr32(ctx
, fp0
, fs
);
11394 if (ctx
->nan2008
) {
11395 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11397 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11399 gen_store_fpr32(ctx
, fp0
, fd
);
11400 tcg_temp_free_i32(fp0
);
11403 case OPC_TRUNC_W_S
:
11405 TCGv_i32 fp0
= tcg_temp_new_i32();
11407 gen_load_fpr32(ctx
, fp0
, fs
);
11408 if (ctx
->nan2008
) {
11409 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11411 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11413 gen_store_fpr32(ctx
, fp0
, fd
);
11414 tcg_temp_free_i32(fp0
);
11419 TCGv_i32 fp0
= tcg_temp_new_i32();
11421 gen_load_fpr32(ctx
, fp0
, fs
);
11422 if (ctx
->nan2008
) {
11423 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11425 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11427 gen_store_fpr32(ctx
, fp0
, fd
);
11428 tcg_temp_free_i32(fp0
);
11431 case OPC_FLOOR_W_S
:
11433 TCGv_i32 fp0
= tcg_temp_new_i32();
11435 gen_load_fpr32(ctx
, fp0
, fs
);
11436 if (ctx
->nan2008
) {
11437 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11439 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11441 gen_store_fpr32(ctx
, fp0
, fd
);
11442 tcg_temp_free_i32(fp0
);
11446 check_insn(ctx
, ISA_MIPS32R6
);
11447 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11450 check_insn(ctx
, ISA_MIPS32R6
);
11451 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11454 check_insn(ctx
, ISA_MIPS32R6
);
11455 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11458 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11459 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11462 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11464 TCGLabel
*l1
= gen_new_label();
11468 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11470 fp0
= tcg_temp_new_i32();
11471 gen_load_fpr32(ctx
, fp0
, fs
);
11472 gen_store_fpr32(ctx
, fp0
, fd
);
11473 tcg_temp_free_i32(fp0
);
11478 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11480 TCGLabel
*l1
= gen_new_label();
11484 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11485 fp0
= tcg_temp_new_i32();
11486 gen_load_fpr32(ctx
, fp0
, fs
);
11487 gen_store_fpr32(ctx
, fp0
, fd
);
11488 tcg_temp_free_i32(fp0
);
11495 TCGv_i32 fp0
= tcg_temp_new_i32();
11497 gen_load_fpr32(ctx
, fp0
, fs
);
11498 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11499 gen_store_fpr32(ctx
, fp0
, fd
);
11500 tcg_temp_free_i32(fp0
);
11505 TCGv_i32 fp0
= tcg_temp_new_i32();
11507 gen_load_fpr32(ctx
, fp0
, fs
);
11508 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11509 gen_store_fpr32(ctx
, fp0
, fd
);
11510 tcg_temp_free_i32(fp0
);
11514 check_insn(ctx
, ISA_MIPS32R6
);
11516 TCGv_i32 fp0
= tcg_temp_new_i32();
11517 TCGv_i32 fp1
= tcg_temp_new_i32();
11518 TCGv_i32 fp2
= tcg_temp_new_i32();
11519 gen_load_fpr32(ctx
, fp0
, fs
);
11520 gen_load_fpr32(ctx
, fp1
, ft
);
11521 gen_load_fpr32(ctx
, fp2
, fd
);
11522 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11523 gen_store_fpr32(ctx
, fp2
, fd
);
11524 tcg_temp_free_i32(fp2
);
11525 tcg_temp_free_i32(fp1
);
11526 tcg_temp_free_i32(fp0
);
11530 check_insn(ctx
, ISA_MIPS32R6
);
11532 TCGv_i32 fp0
= tcg_temp_new_i32();
11533 TCGv_i32 fp1
= tcg_temp_new_i32();
11534 TCGv_i32 fp2
= tcg_temp_new_i32();
11535 gen_load_fpr32(ctx
, fp0
, fs
);
11536 gen_load_fpr32(ctx
, fp1
, ft
);
11537 gen_load_fpr32(ctx
, fp2
, fd
);
11538 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11539 gen_store_fpr32(ctx
, fp2
, fd
);
11540 tcg_temp_free_i32(fp2
);
11541 tcg_temp_free_i32(fp1
);
11542 tcg_temp_free_i32(fp0
);
11546 check_insn(ctx
, ISA_MIPS32R6
);
11548 TCGv_i32 fp0
= tcg_temp_new_i32();
11549 gen_load_fpr32(ctx
, fp0
, fs
);
11550 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
11551 gen_store_fpr32(ctx
, fp0
, fd
);
11552 tcg_temp_free_i32(fp0
);
11556 check_insn(ctx
, ISA_MIPS32R6
);
11558 TCGv_i32 fp0
= tcg_temp_new_i32();
11559 gen_load_fpr32(ctx
, fp0
, fs
);
11560 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
11561 gen_store_fpr32(ctx
, fp0
, fd
);
11562 tcg_temp_free_i32(fp0
);
11565 case OPC_MIN_S
: /* OPC_RECIP2_S */
11566 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11568 TCGv_i32 fp0
= tcg_temp_new_i32();
11569 TCGv_i32 fp1
= tcg_temp_new_i32();
11570 TCGv_i32 fp2
= tcg_temp_new_i32();
11571 gen_load_fpr32(ctx
, fp0
, fs
);
11572 gen_load_fpr32(ctx
, fp1
, ft
);
11573 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
11574 gen_store_fpr32(ctx
, fp2
, fd
);
11575 tcg_temp_free_i32(fp2
);
11576 tcg_temp_free_i32(fp1
);
11577 tcg_temp_free_i32(fp0
);
11580 check_cp1_64bitmode(ctx
);
11582 TCGv_i32 fp0
= tcg_temp_new_i32();
11583 TCGv_i32 fp1
= tcg_temp_new_i32();
11585 gen_load_fpr32(ctx
, fp0
, fs
);
11586 gen_load_fpr32(ctx
, fp1
, ft
);
11587 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
11588 tcg_temp_free_i32(fp1
);
11589 gen_store_fpr32(ctx
, fp0
, fd
);
11590 tcg_temp_free_i32(fp0
);
11594 case OPC_MINA_S
: /* OPC_RECIP1_S */
11595 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11597 TCGv_i32 fp0
= tcg_temp_new_i32();
11598 TCGv_i32 fp1
= tcg_temp_new_i32();
11599 TCGv_i32 fp2
= tcg_temp_new_i32();
11600 gen_load_fpr32(ctx
, fp0
, fs
);
11601 gen_load_fpr32(ctx
, fp1
, ft
);
11602 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
11603 gen_store_fpr32(ctx
, fp2
, fd
);
11604 tcg_temp_free_i32(fp2
);
11605 tcg_temp_free_i32(fp1
);
11606 tcg_temp_free_i32(fp0
);
11609 check_cp1_64bitmode(ctx
);
11611 TCGv_i32 fp0
= tcg_temp_new_i32();
11613 gen_load_fpr32(ctx
, fp0
, fs
);
11614 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
11615 gen_store_fpr32(ctx
, fp0
, fd
);
11616 tcg_temp_free_i32(fp0
);
11620 case OPC_MAX_S
: /* OPC_RSQRT1_S */
11621 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11623 TCGv_i32 fp0
= tcg_temp_new_i32();
11624 TCGv_i32 fp1
= tcg_temp_new_i32();
11625 gen_load_fpr32(ctx
, fp0
, fs
);
11626 gen_load_fpr32(ctx
, fp1
, ft
);
11627 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
11628 gen_store_fpr32(ctx
, fp1
, fd
);
11629 tcg_temp_free_i32(fp1
);
11630 tcg_temp_free_i32(fp0
);
11633 check_cp1_64bitmode(ctx
);
11635 TCGv_i32 fp0
= tcg_temp_new_i32();
11637 gen_load_fpr32(ctx
, fp0
, fs
);
11638 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
11639 gen_store_fpr32(ctx
, fp0
, fd
);
11640 tcg_temp_free_i32(fp0
);
11644 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
11645 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11647 TCGv_i32 fp0
= tcg_temp_new_i32();
11648 TCGv_i32 fp1
= tcg_temp_new_i32();
11649 gen_load_fpr32(ctx
, fp0
, fs
);
11650 gen_load_fpr32(ctx
, fp1
, ft
);
11651 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
11652 gen_store_fpr32(ctx
, fp1
, fd
);
11653 tcg_temp_free_i32(fp1
);
11654 tcg_temp_free_i32(fp0
);
11657 check_cp1_64bitmode(ctx
);
11659 TCGv_i32 fp0
= tcg_temp_new_i32();
11660 TCGv_i32 fp1
= tcg_temp_new_i32();
11662 gen_load_fpr32(ctx
, fp0
, fs
);
11663 gen_load_fpr32(ctx
, fp1
, ft
);
11664 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
11665 tcg_temp_free_i32(fp1
);
11666 gen_store_fpr32(ctx
, fp0
, fd
);
11667 tcg_temp_free_i32(fp0
);
11672 check_cp1_registers(ctx
, fd
);
11674 TCGv_i32 fp32
= tcg_temp_new_i32();
11675 TCGv_i64 fp64
= tcg_temp_new_i64();
11677 gen_load_fpr32(ctx
, fp32
, fs
);
11678 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
11679 tcg_temp_free_i32(fp32
);
11680 gen_store_fpr64(ctx
, fp64
, fd
);
11681 tcg_temp_free_i64(fp64
);
11686 TCGv_i32 fp0
= tcg_temp_new_i32();
11688 gen_load_fpr32(ctx
, fp0
, fs
);
11689 if (ctx
->nan2008
) {
11690 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
11692 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
11694 gen_store_fpr32(ctx
, fp0
, fd
);
11695 tcg_temp_free_i32(fp0
);
11699 check_cp1_64bitmode(ctx
);
11701 TCGv_i32 fp32
= tcg_temp_new_i32();
11702 TCGv_i64 fp64
= tcg_temp_new_i64();
11704 gen_load_fpr32(ctx
, fp32
, fs
);
11705 if (ctx
->nan2008
) {
11706 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
11708 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
11710 tcg_temp_free_i32(fp32
);
11711 gen_store_fpr64(ctx
, fp64
, fd
);
11712 tcg_temp_free_i64(fp64
);
11718 TCGv_i64 fp64
= tcg_temp_new_i64();
11719 TCGv_i32 fp32_0
= tcg_temp_new_i32();
11720 TCGv_i32 fp32_1
= tcg_temp_new_i32();
11722 gen_load_fpr32(ctx
, fp32_0
, fs
);
11723 gen_load_fpr32(ctx
, fp32_1
, ft
);
11724 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
11725 tcg_temp_free_i32(fp32_1
);
11726 tcg_temp_free_i32(fp32_0
);
11727 gen_store_fpr64(ctx
, fp64
, fd
);
11728 tcg_temp_free_i64(fp64
);
11734 case OPC_CMP_UEQ_S
:
11735 case OPC_CMP_OLT_S
:
11736 case OPC_CMP_ULT_S
:
11737 case OPC_CMP_OLE_S
:
11738 case OPC_CMP_ULE_S
:
11740 case OPC_CMP_NGLE_S
:
11741 case OPC_CMP_SEQ_S
:
11742 case OPC_CMP_NGL_S
:
11744 case OPC_CMP_NGE_S
:
11746 case OPC_CMP_NGT_S
:
11747 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11748 if (ctx
->opcode
& (1 << 6)) {
11749 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
11751 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
11755 check_cp1_registers(ctx
, fs
| ft
| fd
);
11757 TCGv_i64 fp0
= tcg_temp_new_i64();
11758 TCGv_i64 fp1
= tcg_temp_new_i64();
11760 gen_load_fpr64(ctx
, fp0
, fs
);
11761 gen_load_fpr64(ctx
, fp1
, ft
);
11762 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
11763 tcg_temp_free_i64(fp1
);
11764 gen_store_fpr64(ctx
, fp0
, fd
);
11765 tcg_temp_free_i64(fp0
);
11769 check_cp1_registers(ctx
, fs
| ft
| fd
);
11771 TCGv_i64 fp0
= tcg_temp_new_i64();
11772 TCGv_i64 fp1
= tcg_temp_new_i64();
11774 gen_load_fpr64(ctx
, fp0
, fs
);
11775 gen_load_fpr64(ctx
, fp1
, ft
);
11776 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
11777 tcg_temp_free_i64(fp1
);
11778 gen_store_fpr64(ctx
, fp0
, fd
);
11779 tcg_temp_free_i64(fp0
);
11783 check_cp1_registers(ctx
, fs
| ft
| fd
);
11785 TCGv_i64 fp0
= tcg_temp_new_i64();
11786 TCGv_i64 fp1
= tcg_temp_new_i64();
11788 gen_load_fpr64(ctx
, fp0
, fs
);
11789 gen_load_fpr64(ctx
, fp1
, ft
);
11790 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
11791 tcg_temp_free_i64(fp1
);
11792 gen_store_fpr64(ctx
, fp0
, fd
);
11793 tcg_temp_free_i64(fp0
);
11797 check_cp1_registers(ctx
, fs
| ft
| fd
);
11799 TCGv_i64 fp0
= tcg_temp_new_i64();
11800 TCGv_i64 fp1
= tcg_temp_new_i64();
11802 gen_load_fpr64(ctx
, fp0
, fs
);
11803 gen_load_fpr64(ctx
, fp1
, ft
);
11804 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
11805 tcg_temp_free_i64(fp1
);
11806 gen_store_fpr64(ctx
, fp0
, fd
);
11807 tcg_temp_free_i64(fp0
);
11811 check_cp1_registers(ctx
, fs
| fd
);
11813 TCGv_i64 fp0
= tcg_temp_new_i64();
11815 gen_load_fpr64(ctx
, fp0
, fs
);
11816 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
11817 gen_store_fpr64(ctx
, fp0
, fd
);
11818 tcg_temp_free_i64(fp0
);
11822 check_cp1_registers(ctx
, fs
| fd
);
11824 TCGv_i64 fp0
= tcg_temp_new_i64();
11826 gen_load_fpr64(ctx
, fp0
, fs
);
11827 if (ctx
->abs2008
) {
11828 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
11830 gen_helper_float_abs_d(fp0
, fp0
);
11832 gen_store_fpr64(ctx
, fp0
, fd
);
11833 tcg_temp_free_i64(fp0
);
11837 check_cp1_registers(ctx
, fs
| fd
);
11839 TCGv_i64 fp0
= tcg_temp_new_i64();
11841 gen_load_fpr64(ctx
, fp0
, fs
);
11842 gen_store_fpr64(ctx
, fp0
, fd
);
11843 tcg_temp_free_i64(fp0
);
11847 check_cp1_registers(ctx
, fs
| fd
);
11849 TCGv_i64 fp0
= tcg_temp_new_i64();
11851 gen_load_fpr64(ctx
, fp0
, fs
);
11852 if (ctx
->abs2008
) {
11853 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
11855 gen_helper_float_chs_d(fp0
, fp0
);
11857 gen_store_fpr64(ctx
, fp0
, fd
);
11858 tcg_temp_free_i64(fp0
);
11861 case OPC_ROUND_L_D
:
11862 check_cp1_64bitmode(ctx
);
11864 TCGv_i64 fp0
= tcg_temp_new_i64();
11866 gen_load_fpr64(ctx
, fp0
, fs
);
11867 if (ctx
->nan2008
) {
11868 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
11870 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
11872 gen_store_fpr64(ctx
, fp0
, fd
);
11873 tcg_temp_free_i64(fp0
);
11876 case OPC_TRUNC_L_D
:
11877 check_cp1_64bitmode(ctx
);
11879 TCGv_i64 fp0
= tcg_temp_new_i64();
11881 gen_load_fpr64(ctx
, fp0
, fs
);
11882 if (ctx
->nan2008
) {
11883 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
11885 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
11887 gen_store_fpr64(ctx
, fp0
, fd
);
11888 tcg_temp_free_i64(fp0
);
11892 check_cp1_64bitmode(ctx
);
11894 TCGv_i64 fp0
= tcg_temp_new_i64();
11896 gen_load_fpr64(ctx
, fp0
, fs
);
11897 if (ctx
->nan2008
) {
11898 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
11900 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
11902 gen_store_fpr64(ctx
, fp0
, fd
);
11903 tcg_temp_free_i64(fp0
);
11906 case OPC_FLOOR_L_D
:
11907 check_cp1_64bitmode(ctx
);
11909 TCGv_i64 fp0
= tcg_temp_new_i64();
11911 gen_load_fpr64(ctx
, fp0
, fs
);
11912 if (ctx
->nan2008
) {
11913 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
11915 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
11917 gen_store_fpr64(ctx
, fp0
, fd
);
11918 tcg_temp_free_i64(fp0
);
11921 case OPC_ROUND_W_D
:
11922 check_cp1_registers(ctx
, fs
);
11924 TCGv_i32 fp32
= tcg_temp_new_i32();
11925 TCGv_i64 fp64
= tcg_temp_new_i64();
11927 gen_load_fpr64(ctx
, fp64
, fs
);
11928 if (ctx
->nan2008
) {
11929 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
11931 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
11933 tcg_temp_free_i64(fp64
);
11934 gen_store_fpr32(ctx
, fp32
, fd
);
11935 tcg_temp_free_i32(fp32
);
11938 case OPC_TRUNC_W_D
:
11939 check_cp1_registers(ctx
, fs
);
11941 TCGv_i32 fp32
= tcg_temp_new_i32();
11942 TCGv_i64 fp64
= tcg_temp_new_i64();
11944 gen_load_fpr64(ctx
, fp64
, fs
);
11945 if (ctx
->nan2008
) {
11946 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
11948 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
11950 tcg_temp_free_i64(fp64
);
11951 gen_store_fpr32(ctx
, fp32
, fd
);
11952 tcg_temp_free_i32(fp32
);
11956 check_cp1_registers(ctx
, fs
);
11958 TCGv_i32 fp32
= tcg_temp_new_i32();
11959 TCGv_i64 fp64
= tcg_temp_new_i64();
11961 gen_load_fpr64(ctx
, fp64
, fs
);
11962 if (ctx
->nan2008
) {
11963 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
11965 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
11967 tcg_temp_free_i64(fp64
);
11968 gen_store_fpr32(ctx
, fp32
, fd
);
11969 tcg_temp_free_i32(fp32
);
11972 case OPC_FLOOR_W_D
:
11973 check_cp1_registers(ctx
, fs
);
11975 TCGv_i32 fp32
= tcg_temp_new_i32();
11976 TCGv_i64 fp64
= tcg_temp_new_i64();
11978 gen_load_fpr64(ctx
, fp64
, fs
);
11979 if (ctx
->nan2008
) {
11980 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
11982 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
11984 tcg_temp_free_i64(fp64
);
11985 gen_store_fpr32(ctx
, fp32
, fd
);
11986 tcg_temp_free_i32(fp32
);
11990 check_insn(ctx
, ISA_MIPS32R6
);
11991 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11994 check_insn(ctx
, ISA_MIPS32R6
);
11995 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11998 check_insn(ctx
, ISA_MIPS32R6
);
11999 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12002 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12003 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12006 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12008 TCGLabel
*l1
= gen_new_label();
12012 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12014 fp0
= tcg_temp_new_i64();
12015 gen_load_fpr64(ctx
, fp0
, fs
);
12016 gen_store_fpr64(ctx
, fp0
, fd
);
12017 tcg_temp_free_i64(fp0
);
12022 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12024 TCGLabel
*l1
= gen_new_label();
12028 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12029 fp0
= tcg_temp_new_i64();
12030 gen_load_fpr64(ctx
, fp0
, fs
);
12031 gen_store_fpr64(ctx
, fp0
, fd
);
12032 tcg_temp_free_i64(fp0
);
12038 check_cp1_registers(ctx
, fs
| fd
);
12040 TCGv_i64 fp0
= tcg_temp_new_i64();
12042 gen_load_fpr64(ctx
, fp0
, fs
);
12043 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
12044 gen_store_fpr64(ctx
, fp0
, fd
);
12045 tcg_temp_free_i64(fp0
);
12049 check_cp1_registers(ctx
, fs
| fd
);
12051 TCGv_i64 fp0
= tcg_temp_new_i64();
12053 gen_load_fpr64(ctx
, fp0
, fs
);
12054 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
12055 gen_store_fpr64(ctx
, fp0
, fd
);
12056 tcg_temp_free_i64(fp0
);
12060 check_insn(ctx
, ISA_MIPS32R6
);
12062 TCGv_i64 fp0
= tcg_temp_new_i64();
12063 TCGv_i64 fp1
= tcg_temp_new_i64();
12064 TCGv_i64 fp2
= tcg_temp_new_i64();
12065 gen_load_fpr64(ctx
, fp0
, fs
);
12066 gen_load_fpr64(ctx
, fp1
, ft
);
12067 gen_load_fpr64(ctx
, fp2
, fd
);
12068 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12069 gen_store_fpr64(ctx
, fp2
, fd
);
12070 tcg_temp_free_i64(fp2
);
12071 tcg_temp_free_i64(fp1
);
12072 tcg_temp_free_i64(fp0
);
12076 check_insn(ctx
, ISA_MIPS32R6
);
12078 TCGv_i64 fp0
= tcg_temp_new_i64();
12079 TCGv_i64 fp1
= tcg_temp_new_i64();
12080 TCGv_i64 fp2
= tcg_temp_new_i64();
12081 gen_load_fpr64(ctx
, fp0
, fs
);
12082 gen_load_fpr64(ctx
, fp1
, ft
);
12083 gen_load_fpr64(ctx
, fp2
, fd
);
12084 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12085 gen_store_fpr64(ctx
, fp2
, fd
);
12086 tcg_temp_free_i64(fp2
);
12087 tcg_temp_free_i64(fp1
);
12088 tcg_temp_free_i64(fp0
);
12092 check_insn(ctx
, ISA_MIPS32R6
);
12094 TCGv_i64 fp0
= tcg_temp_new_i64();
12095 gen_load_fpr64(ctx
, fp0
, fs
);
12096 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
12097 gen_store_fpr64(ctx
, fp0
, fd
);
12098 tcg_temp_free_i64(fp0
);
12102 check_insn(ctx
, ISA_MIPS32R6
);
12104 TCGv_i64 fp0
= tcg_temp_new_i64();
12105 gen_load_fpr64(ctx
, fp0
, fs
);
12106 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
12107 gen_store_fpr64(ctx
, fp0
, fd
);
12108 tcg_temp_free_i64(fp0
);
12111 case OPC_MIN_D
: /* OPC_RECIP2_D */
12112 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12114 TCGv_i64 fp0
= tcg_temp_new_i64();
12115 TCGv_i64 fp1
= tcg_temp_new_i64();
12116 gen_load_fpr64(ctx
, fp0
, fs
);
12117 gen_load_fpr64(ctx
, fp1
, ft
);
12118 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
12119 gen_store_fpr64(ctx
, fp1
, fd
);
12120 tcg_temp_free_i64(fp1
);
12121 tcg_temp_free_i64(fp0
);
12124 check_cp1_64bitmode(ctx
);
12126 TCGv_i64 fp0
= tcg_temp_new_i64();
12127 TCGv_i64 fp1
= tcg_temp_new_i64();
12129 gen_load_fpr64(ctx
, fp0
, fs
);
12130 gen_load_fpr64(ctx
, fp1
, ft
);
12131 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
12132 tcg_temp_free_i64(fp1
);
12133 gen_store_fpr64(ctx
, fp0
, fd
);
12134 tcg_temp_free_i64(fp0
);
12138 case OPC_MINA_D
: /* OPC_RECIP1_D */
12139 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12141 TCGv_i64 fp0
= tcg_temp_new_i64();
12142 TCGv_i64 fp1
= tcg_temp_new_i64();
12143 gen_load_fpr64(ctx
, fp0
, fs
);
12144 gen_load_fpr64(ctx
, fp1
, ft
);
12145 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
12146 gen_store_fpr64(ctx
, fp1
, fd
);
12147 tcg_temp_free_i64(fp1
);
12148 tcg_temp_free_i64(fp0
);
12151 check_cp1_64bitmode(ctx
);
12153 TCGv_i64 fp0
= tcg_temp_new_i64();
12155 gen_load_fpr64(ctx
, fp0
, fs
);
12156 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12157 gen_store_fpr64(ctx
, fp0
, fd
);
12158 tcg_temp_free_i64(fp0
);
12162 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12163 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12165 TCGv_i64 fp0
= tcg_temp_new_i64();
12166 TCGv_i64 fp1
= tcg_temp_new_i64();
12167 gen_load_fpr64(ctx
, fp0
, fs
);
12168 gen_load_fpr64(ctx
, fp1
, ft
);
12169 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12170 gen_store_fpr64(ctx
, fp1
, fd
);
12171 tcg_temp_free_i64(fp1
);
12172 tcg_temp_free_i64(fp0
);
12175 check_cp1_64bitmode(ctx
);
12177 TCGv_i64 fp0
= tcg_temp_new_i64();
12179 gen_load_fpr64(ctx
, fp0
, fs
);
12180 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12181 gen_store_fpr64(ctx
, fp0
, fd
);
12182 tcg_temp_free_i64(fp0
);
12186 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12187 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12189 TCGv_i64 fp0
= tcg_temp_new_i64();
12190 TCGv_i64 fp1
= tcg_temp_new_i64();
12191 gen_load_fpr64(ctx
, fp0
, fs
);
12192 gen_load_fpr64(ctx
, fp1
, ft
);
12193 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12194 gen_store_fpr64(ctx
, fp1
, fd
);
12195 tcg_temp_free_i64(fp1
);
12196 tcg_temp_free_i64(fp0
);
12199 check_cp1_64bitmode(ctx
);
12201 TCGv_i64 fp0
= tcg_temp_new_i64();
12202 TCGv_i64 fp1
= tcg_temp_new_i64();
12204 gen_load_fpr64(ctx
, fp0
, fs
);
12205 gen_load_fpr64(ctx
, fp1
, ft
);
12206 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12207 tcg_temp_free_i64(fp1
);
12208 gen_store_fpr64(ctx
, fp0
, fd
);
12209 tcg_temp_free_i64(fp0
);
12216 case OPC_CMP_UEQ_D
:
12217 case OPC_CMP_OLT_D
:
12218 case OPC_CMP_ULT_D
:
12219 case OPC_CMP_OLE_D
:
12220 case OPC_CMP_ULE_D
:
12222 case OPC_CMP_NGLE_D
:
12223 case OPC_CMP_SEQ_D
:
12224 case OPC_CMP_NGL_D
:
12226 case OPC_CMP_NGE_D
:
12228 case OPC_CMP_NGT_D
:
12229 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12230 if (ctx
->opcode
& (1 << 6)) {
12231 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12233 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12237 check_cp1_registers(ctx
, fs
);
12239 TCGv_i32 fp32
= tcg_temp_new_i32();
12240 TCGv_i64 fp64
= tcg_temp_new_i64();
12242 gen_load_fpr64(ctx
, fp64
, fs
);
12243 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12244 tcg_temp_free_i64(fp64
);
12245 gen_store_fpr32(ctx
, fp32
, fd
);
12246 tcg_temp_free_i32(fp32
);
12250 check_cp1_registers(ctx
, fs
);
12252 TCGv_i32 fp32
= tcg_temp_new_i32();
12253 TCGv_i64 fp64
= tcg_temp_new_i64();
12255 gen_load_fpr64(ctx
, fp64
, fs
);
12256 if (ctx
->nan2008
) {
12257 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12259 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12261 tcg_temp_free_i64(fp64
);
12262 gen_store_fpr32(ctx
, fp32
, fd
);
12263 tcg_temp_free_i32(fp32
);
12267 check_cp1_64bitmode(ctx
);
12269 TCGv_i64 fp0
= tcg_temp_new_i64();
12271 gen_load_fpr64(ctx
, fp0
, fs
);
12272 if (ctx
->nan2008
) {
12273 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12275 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12277 gen_store_fpr64(ctx
, fp0
, fd
);
12278 tcg_temp_free_i64(fp0
);
12283 TCGv_i32 fp0
= tcg_temp_new_i32();
12285 gen_load_fpr32(ctx
, fp0
, fs
);
12286 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12287 gen_store_fpr32(ctx
, fp0
, fd
);
12288 tcg_temp_free_i32(fp0
);
12292 check_cp1_registers(ctx
, fd
);
12294 TCGv_i32 fp32
= tcg_temp_new_i32();
12295 TCGv_i64 fp64
= tcg_temp_new_i64();
12297 gen_load_fpr32(ctx
, fp32
, fs
);
12298 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12299 tcg_temp_free_i32(fp32
);
12300 gen_store_fpr64(ctx
, fp64
, fd
);
12301 tcg_temp_free_i64(fp64
);
12305 check_cp1_64bitmode(ctx
);
12307 TCGv_i32 fp32
= tcg_temp_new_i32();
12308 TCGv_i64 fp64
= tcg_temp_new_i64();
12310 gen_load_fpr64(ctx
, fp64
, fs
);
12311 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12312 tcg_temp_free_i64(fp64
);
12313 gen_store_fpr32(ctx
, fp32
, fd
);
12314 tcg_temp_free_i32(fp32
);
12318 check_cp1_64bitmode(ctx
);
12320 TCGv_i64 fp0
= tcg_temp_new_i64();
12322 gen_load_fpr64(ctx
, fp0
, fs
);
12323 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12324 gen_store_fpr64(ctx
, fp0
, fd
);
12325 tcg_temp_free_i64(fp0
);
12328 case OPC_CVT_PS_PW
:
12331 TCGv_i64 fp0
= tcg_temp_new_i64();
12333 gen_load_fpr64(ctx
, fp0
, fs
);
12334 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12335 gen_store_fpr64(ctx
, fp0
, fd
);
12336 tcg_temp_free_i64(fp0
);
12342 TCGv_i64 fp0
= tcg_temp_new_i64();
12343 TCGv_i64 fp1
= tcg_temp_new_i64();
12345 gen_load_fpr64(ctx
, fp0
, fs
);
12346 gen_load_fpr64(ctx
, fp1
, ft
);
12347 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12348 tcg_temp_free_i64(fp1
);
12349 gen_store_fpr64(ctx
, fp0
, fd
);
12350 tcg_temp_free_i64(fp0
);
12356 TCGv_i64 fp0
= tcg_temp_new_i64();
12357 TCGv_i64 fp1
= tcg_temp_new_i64();
12359 gen_load_fpr64(ctx
, fp0
, fs
);
12360 gen_load_fpr64(ctx
, fp1
, ft
);
12361 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12362 tcg_temp_free_i64(fp1
);
12363 gen_store_fpr64(ctx
, fp0
, fd
);
12364 tcg_temp_free_i64(fp0
);
12370 TCGv_i64 fp0
= tcg_temp_new_i64();
12371 TCGv_i64 fp1
= tcg_temp_new_i64();
12373 gen_load_fpr64(ctx
, fp0
, fs
);
12374 gen_load_fpr64(ctx
, fp1
, ft
);
12375 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12376 tcg_temp_free_i64(fp1
);
12377 gen_store_fpr64(ctx
, fp0
, fd
);
12378 tcg_temp_free_i64(fp0
);
12384 TCGv_i64 fp0
= tcg_temp_new_i64();
12386 gen_load_fpr64(ctx
, fp0
, fs
);
12387 gen_helper_float_abs_ps(fp0
, fp0
);
12388 gen_store_fpr64(ctx
, fp0
, fd
);
12389 tcg_temp_free_i64(fp0
);
12395 TCGv_i64 fp0
= tcg_temp_new_i64();
12397 gen_load_fpr64(ctx
, fp0
, fs
);
12398 gen_store_fpr64(ctx
, fp0
, fd
);
12399 tcg_temp_free_i64(fp0
);
12405 TCGv_i64 fp0
= tcg_temp_new_i64();
12407 gen_load_fpr64(ctx
, fp0
, fs
);
12408 gen_helper_float_chs_ps(fp0
, fp0
);
12409 gen_store_fpr64(ctx
, fp0
, fd
);
12410 tcg_temp_free_i64(fp0
);
12415 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12420 TCGLabel
*l1
= gen_new_label();
12424 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12426 fp0
= tcg_temp_new_i64();
12427 gen_load_fpr64(ctx
, fp0
, fs
);
12428 gen_store_fpr64(ctx
, fp0
, fd
);
12429 tcg_temp_free_i64(fp0
);
12436 TCGLabel
*l1
= gen_new_label();
12440 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12441 fp0
= tcg_temp_new_i64();
12442 gen_load_fpr64(ctx
, fp0
, fs
);
12443 gen_store_fpr64(ctx
, fp0
, fd
);
12444 tcg_temp_free_i64(fp0
);
12452 TCGv_i64 fp0
= tcg_temp_new_i64();
12453 TCGv_i64 fp1
= tcg_temp_new_i64();
12455 gen_load_fpr64(ctx
, fp0
, ft
);
12456 gen_load_fpr64(ctx
, fp1
, fs
);
12457 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12458 tcg_temp_free_i64(fp1
);
12459 gen_store_fpr64(ctx
, fp0
, fd
);
12460 tcg_temp_free_i64(fp0
);
12466 TCGv_i64 fp0
= tcg_temp_new_i64();
12467 TCGv_i64 fp1
= tcg_temp_new_i64();
12469 gen_load_fpr64(ctx
, fp0
, ft
);
12470 gen_load_fpr64(ctx
, fp1
, fs
);
12471 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12472 tcg_temp_free_i64(fp1
);
12473 gen_store_fpr64(ctx
, fp0
, fd
);
12474 tcg_temp_free_i64(fp0
);
12477 case OPC_RECIP2_PS
:
12480 TCGv_i64 fp0
= tcg_temp_new_i64();
12481 TCGv_i64 fp1
= tcg_temp_new_i64();
12483 gen_load_fpr64(ctx
, fp0
, fs
);
12484 gen_load_fpr64(ctx
, fp1
, ft
);
12485 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12486 tcg_temp_free_i64(fp1
);
12487 gen_store_fpr64(ctx
, fp0
, fd
);
12488 tcg_temp_free_i64(fp0
);
12491 case OPC_RECIP1_PS
:
12494 TCGv_i64 fp0
= tcg_temp_new_i64();
12496 gen_load_fpr64(ctx
, fp0
, fs
);
12497 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12498 gen_store_fpr64(ctx
, fp0
, fd
);
12499 tcg_temp_free_i64(fp0
);
12502 case OPC_RSQRT1_PS
:
12505 TCGv_i64 fp0
= tcg_temp_new_i64();
12507 gen_load_fpr64(ctx
, fp0
, fs
);
12508 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12509 gen_store_fpr64(ctx
, fp0
, fd
);
12510 tcg_temp_free_i64(fp0
);
12513 case OPC_RSQRT2_PS
:
12516 TCGv_i64 fp0
= tcg_temp_new_i64();
12517 TCGv_i64 fp1
= tcg_temp_new_i64();
12519 gen_load_fpr64(ctx
, fp0
, fs
);
12520 gen_load_fpr64(ctx
, fp1
, ft
);
12521 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12522 tcg_temp_free_i64(fp1
);
12523 gen_store_fpr64(ctx
, fp0
, fd
);
12524 tcg_temp_free_i64(fp0
);
12528 check_cp1_64bitmode(ctx
);
12530 TCGv_i32 fp0
= tcg_temp_new_i32();
12532 gen_load_fpr32h(ctx
, fp0
, fs
);
12533 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12534 gen_store_fpr32(ctx
, fp0
, fd
);
12535 tcg_temp_free_i32(fp0
);
12538 case OPC_CVT_PW_PS
:
12541 TCGv_i64 fp0
= tcg_temp_new_i64();
12543 gen_load_fpr64(ctx
, fp0
, fs
);
12544 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
12545 gen_store_fpr64(ctx
, fp0
, fd
);
12546 tcg_temp_free_i64(fp0
);
12550 check_cp1_64bitmode(ctx
);
12552 TCGv_i32 fp0
= tcg_temp_new_i32();
12554 gen_load_fpr32(ctx
, fp0
, fs
);
12555 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
12556 gen_store_fpr32(ctx
, fp0
, fd
);
12557 tcg_temp_free_i32(fp0
);
12563 TCGv_i32 fp0
= tcg_temp_new_i32();
12564 TCGv_i32 fp1
= tcg_temp_new_i32();
12566 gen_load_fpr32(ctx
, fp0
, fs
);
12567 gen_load_fpr32(ctx
, fp1
, ft
);
12568 gen_store_fpr32h(ctx
, fp0
, fd
);
12569 gen_store_fpr32(ctx
, fp1
, fd
);
12570 tcg_temp_free_i32(fp0
);
12571 tcg_temp_free_i32(fp1
);
12577 TCGv_i32 fp0
= tcg_temp_new_i32();
12578 TCGv_i32 fp1
= tcg_temp_new_i32();
12580 gen_load_fpr32(ctx
, fp0
, fs
);
12581 gen_load_fpr32h(ctx
, fp1
, ft
);
12582 gen_store_fpr32(ctx
, fp1
, fd
);
12583 gen_store_fpr32h(ctx
, fp0
, fd
);
12584 tcg_temp_free_i32(fp0
);
12585 tcg_temp_free_i32(fp1
);
12591 TCGv_i32 fp0
= tcg_temp_new_i32();
12592 TCGv_i32 fp1
= tcg_temp_new_i32();
12594 gen_load_fpr32h(ctx
, fp0
, fs
);
12595 gen_load_fpr32(ctx
, fp1
, ft
);
12596 gen_store_fpr32(ctx
, fp1
, fd
);
12597 gen_store_fpr32h(ctx
, fp0
, fd
);
12598 tcg_temp_free_i32(fp0
);
12599 tcg_temp_free_i32(fp1
);
12605 TCGv_i32 fp0
= tcg_temp_new_i32();
12606 TCGv_i32 fp1
= tcg_temp_new_i32();
12608 gen_load_fpr32h(ctx
, fp0
, fs
);
12609 gen_load_fpr32h(ctx
, fp1
, ft
);
12610 gen_store_fpr32(ctx
, fp1
, fd
);
12611 gen_store_fpr32h(ctx
, fp0
, fd
);
12612 tcg_temp_free_i32(fp0
);
12613 tcg_temp_free_i32(fp1
);
12617 case OPC_CMP_UN_PS
:
12618 case OPC_CMP_EQ_PS
:
12619 case OPC_CMP_UEQ_PS
:
12620 case OPC_CMP_OLT_PS
:
12621 case OPC_CMP_ULT_PS
:
12622 case OPC_CMP_OLE_PS
:
12623 case OPC_CMP_ULE_PS
:
12624 case OPC_CMP_SF_PS
:
12625 case OPC_CMP_NGLE_PS
:
12626 case OPC_CMP_SEQ_PS
:
12627 case OPC_CMP_NGL_PS
:
12628 case OPC_CMP_LT_PS
:
12629 case OPC_CMP_NGE_PS
:
12630 case OPC_CMP_LE_PS
:
12631 case OPC_CMP_NGT_PS
:
12632 if (ctx
->opcode
& (1 << 6)) {
12633 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
12635 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
12639 MIPS_INVAL("farith");
12640 generate_exception_end(ctx
, EXCP_RI
);
12645 /* Coprocessor 3 (FPU) */
12646 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
12647 int fd
, int fs
, int base
, int index
)
12649 TCGv t0
= tcg_temp_new();
12652 gen_load_gpr(t0
, index
);
12653 } else if (index
== 0) {
12654 gen_load_gpr(t0
, base
);
12656 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
12659 * Don't do NOP if destination is zero: we must perform the actual
12666 TCGv_i32 fp0
= tcg_temp_new_i32();
12668 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12669 tcg_gen_trunc_tl_i32(fp0
, t0
);
12670 gen_store_fpr32(ctx
, fp0
, fd
);
12671 tcg_temp_free_i32(fp0
);
12676 check_cp1_registers(ctx
, fd
);
12678 TCGv_i64 fp0
= tcg_temp_new_i64();
12679 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12680 gen_store_fpr64(ctx
, fp0
, fd
);
12681 tcg_temp_free_i64(fp0
);
12685 check_cp1_64bitmode(ctx
);
12686 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12688 TCGv_i64 fp0
= tcg_temp_new_i64();
12690 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12691 gen_store_fpr64(ctx
, fp0
, fd
);
12692 tcg_temp_free_i64(fp0
);
12698 TCGv_i32 fp0
= tcg_temp_new_i32();
12699 gen_load_fpr32(ctx
, fp0
, fs
);
12700 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
12701 tcg_temp_free_i32(fp0
);
12706 check_cp1_registers(ctx
, fs
);
12708 TCGv_i64 fp0
= tcg_temp_new_i64();
12709 gen_load_fpr64(ctx
, fp0
, fs
);
12710 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12711 tcg_temp_free_i64(fp0
);
12715 check_cp1_64bitmode(ctx
);
12716 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12718 TCGv_i64 fp0
= tcg_temp_new_i64();
12719 gen_load_fpr64(ctx
, fp0
, fs
);
12720 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12721 tcg_temp_free_i64(fp0
);
12728 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
12729 int fd
, int fr
, int fs
, int ft
)
12735 TCGv t0
= tcg_temp_local_new();
12736 TCGv_i32 fp
= tcg_temp_new_i32();
12737 TCGv_i32 fph
= tcg_temp_new_i32();
12738 TCGLabel
*l1
= gen_new_label();
12739 TCGLabel
*l2
= gen_new_label();
12741 gen_load_gpr(t0
, fr
);
12742 tcg_gen_andi_tl(t0
, t0
, 0x7);
12744 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
12745 gen_load_fpr32(ctx
, fp
, fs
);
12746 gen_load_fpr32h(ctx
, fph
, fs
);
12747 gen_store_fpr32(ctx
, fp
, fd
);
12748 gen_store_fpr32h(ctx
, fph
, fd
);
12751 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
12753 #ifdef TARGET_WORDS_BIGENDIAN
12754 gen_load_fpr32(ctx
, fp
, fs
);
12755 gen_load_fpr32h(ctx
, fph
, ft
);
12756 gen_store_fpr32h(ctx
, fp
, fd
);
12757 gen_store_fpr32(ctx
, fph
, fd
);
12759 gen_load_fpr32h(ctx
, fph
, fs
);
12760 gen_load_fpr32(ctx
, fp
, ft
);
12761 gen_store_fpr32(ctx
, fph
, fd
);
12762 gen_store_fpr32h(ctx
, fp
, fd
);
12765 tcg_temp_free_i32(fp
);
12766 tcg_temp_free_i32(fph
);
12772 TCGv_i32 fp0
= tcg_temp_new_i32();
12773 TCGv_i32 fp1
= tcg_temp_new_i32();
12774 TCGv_i32 fp2
= tcg_temp_new_i32();
12776 gen_load_fpr32(ctx
, fp0
, fs
);
12777 gen_load_fpr32(ctx
, fp1
, ft
);
12778 gen_load_fpr32(ctx
, fp2
, fr
);
12779 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12780 tcg_temp_free_i32(fp0
);
12781 tcg_temp_free_i32(fp1
);
12782 gen_store_fpr32(ctx
, fp2
, fd
);
12783 tcg_temp_free_i32(fp2
);
12788 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12790 TCGv_i64 fp0
= tcg_temp_new_i64();
12791 TCGv_i64 fp1
= tcg_temp_new_i64();
12792 TCGv_i64 fp2
= tcg_temp_new_i64();
12794 gen_load_fpr64(ctx
, fp0
, fs
);
12795 gen_load_fpr64(ctx
, fp1
, ft
);
12796 gen_load_fpr64(ctx
, fp2
, fr
);
12797 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12798 tcg_temp_free_i64(fp0
);
12799 tcg_temp_free_i64(fp1
);
12800 gen_store_fpr64(ctx
, fp2
, fd
);
12801 tcg_temp_free_i64(fp2
);
12807 TCGv_i64 fp0
= tcg_temp_new_i64();
12808 TCGv_i64 fp1
= tcg_temp_new_i64();
12809 TCGv_i64 fp2
= tcg_temp_new_i64();
12811 gen_load_fpr64(ctx
, fp0
, fs
);
12812 gen_load_fpr64(ctx
, fp1
, ft
);
12813 gen_load_fpr64(ctx
, fp2
, fr
);
12814 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12815 tcg_temp_free_i64(fp0
);
12816 tcg_temp_free_i64(fp1
);
12817 gen_store_fpr64(ctx
, fp2
, fd
);
12818 tcg_temp_free_i64(fp2
);
12824 TCGv_i32 fp0
= tcg_temp_new_i32();
12825 TCGv_i32 fp1
= tcg_temp_new_i32();
12826 TCGv_i32 fp2
= tcg_temp_new_i32();
12828 gen_load_fpr32(ctx
, fp0
, fs
);
12829 gen_load_fpr32(ctx
, fp1
, ft
);
12830 gen_load_fpr32(ctx
, fp2
, fr
);
12831 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12832 tcg_temp_free_i32(fp0
);
12833 tcg_temp_free_i32(fp1
);
12834 gen_store_fpr32(ctx
, fp2
, fd
);
12835 tcg_temp_free_i32(fp2
);
12840 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12842 TCGv_i64 fp0
= tcg_temp_new_i64();
12843 TCGv_i64 fp1
= tcg_temp_new_i64();
12844 TCGv_i64 fp2
= tcg_temp_new_i64();
12846 gen_load_fpr64(ctx
, fp0
, fs
);
12847 gen_load_fpr64(ctx
, fp1
, ft
);
12848 gen_load_fpr64(ctx
, fp2
, fr
);
12849 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12850 tcg_temp_free_i64(fp0
);
12851 tcg_temp_free_i64(fp1
);
12852 gen_store_fpr64(ctx
, fp2
, fd
);
12853 tcg_temp_free_i64(fp2
);
12859 TCGv_i64 fp0
= tcg_temp_new_i64();
12860 TCGv_i64 fp1
= tcg_temp_new_i64();
12861 TCGv_i64 fp2
= tcg_temp_new_i64();
12863 gen_load_fpr64(ctx
, fp0
, fs
);
12864 gen_load_fpr64(ctx
, fp1
, ft
);
12865 gen_load_fpr64(ctx
, fp2
, fr
);
12866 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12867 tcg_temp_free_i64(fp0
);
12868 tcg_temp_free_i64(fp1
);
12869 gen_store_fpr64(ctx
, fp2
, fd
);
12870 tcg_temp_free_i64(fp2
);
12876 TCGv_i32 fp0
= tcg_temp_new_i32();
12877 TCGv_i32 fp1
= tcg_temp_new_i32();
12878 TCGv_i32 fp2
= tcg_temp_new_i32();
12880 gen_load_fpr32(ctx
, fp0
, fs
);
12881 gen_load_fpr32(ctx
, fp1
, ft
);
12882 gen_load_fpr32(ctx
, fp2
, fr
);
12883 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12884 tcg_temp_free_i32(fp0
);
12885 tcg_temp_free_i32(fp1
);
12886 gen_store_fpr32(ctx
, fp2
, fd
);
12887 tcg_temp_free_i32(fp2
);
12892 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12894 TCGv_i64 fp0
= tcg_temp_new_i64();
12895 TCGv_i64 fp1
= tcg_temp_new_i64();
12896 TCGv_i64 fp2
= tcg_temp_new_i64();
12898 gen_load_fpr64(ctx
, fp0
, fs
);
12899 gen_load_fpr64(ctx
, fp1
, ft
);
12900 gen_load_fpr64(ctx
, fp2
, fr
);
12901 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12902 tcg_temp_free_i64(fp0
);
12903 tcg_temp_free_i64(fp1
);
12904 gen_store_fpr64(ctx
, fp2
, fd
);
12905 tcg_temp_free_i64(fp2
);
12911 TCGv_i64 fp0
= tcg_temp_new_i64();
12912 TCGv_i64 fp1
= tcg_temp_new_i64();
12913 TCGv_i64 fp2
= tcg_temp_new_i64();
12915 gen_load_fpr64(ctx
, fp0
, fs
);
12916 gen_load_fpr64(ctx
, fp1
, ft
);
12917 gen_load_fpr64(ctx
, fp2
, fr
);
12918 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12919 tcg_temp_free_i64(fp0
);
12920 tcg_temp_free_i64(fp1
);
12921 gen_store_fpr64(ctx
, fp2
, fd
);
12922 tcg_temp_free_i64(fp2
);
12928 TCGv_i32 fp0
= tcg_temp_new_i32();
12929 TCGv_i32 fp1
= tcg_temp_new_i32();
12930 TCGv_i32 fp2
= tcg_temp_new_i32();
12932 gen_load_fpr32(ctx
, fp0
, fs
);
12933 gen_load_fpr32(ctx
, fp1
, ft
);
12934 gen_load_fpr32(ctx
, fp2
, fr
);
12935 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12936 tcg_temp_free_i32(fp0
);
12937 tcg_temp_free_i32(fp1
);
12938 gen_store_fpr32(ctx
, fp2
, fd
);
12939 tcg_temp_free_i32(fp2
);
12944 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12946 TCGv_i64 fp0
= tcg_temp_new_i64();
12947 TCGv_i64 fp1
= tcg_temp_new_i64();
12948 TCGv_i64 fp2
= tcg_temp_new_i64();
12950 gen_load_fpr64(ctx
, fp0
, fs
);
12951 gen_load_fpr64(ctx
, fp1
, ft
);
12952 gen_load_fpr64(ctx
, fp2
, fr
);
12953 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12954 tcg_temp_free_i64(fp0
);
12955 tcg_temp_free_i64(fp1
);
12956 gen_store_fpr64(ctx
, fp2
, fd
);
12957 tcg_temp_free_i64(fp2
);
12963 TCGv_i64 fp0
= tcg_temp_new_i64();
12964 TCGv_i64 fp1
= tcg_temp_new_i64();
12965 TCGv_i64 fp2
= tcg_temp_new_i64();
12967 gen_load_fpr64(ctx
, fp0
, fs
);
12968 gen_load_fpr64(ctx
, fp1
, ft
);
12969 gen_load_fpr64(ctx
, fp2
, fr
);
12970 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12971 tcg_temp_free_i64(fp0
);
12972 tcg_temp_free_i64(fp1
);
12973 gen_store_fpr64(ctx
, fp2
, fd
);
12974 tcg_temp_free_i64(fp2
);
12978 MIPS_INVAL("flt3_arith");
12979 generate_exception_end(ctx
, EXCP_RI
);
12984 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
12988 #if !defined(CONFIG_USER_ONLY)
12990 * The Linux kernel will emulate rdhwr if it's not supported natively.
12991 * Therefore only check the ISA in system mode.
12993 check_insn(ctx
, ISA_MIPS32R2
);
12995 t0
= tcg_temp_new();
12999 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
13000 gen_store_gpr(t0
, rt
);
13003 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
13004 gen_store_gpr(t0
, rt
);
13007 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
13010 gen_helper_rdhwr_cc(t0
, cpu_env
);
13011 gen_store_gpr(t0
, rt
);
13013 * Break the TB to be able to take timer interrupts immediately
13014 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13015 * we break completely out of translated code.
13017 gen_save_pc(ctx
->base
.pc_next
+ 4);
13018 ctx
->base
.is_jmp
= DISAS_EXIT
;
13021 gen_helper_rdhwr_ccres(t0
, cpu_env
);
13022 gen_store_gpr(t0
, rt
);
13025 check_insn(ctx
, ISA_MIPS32R6
);
13028 * Performance counter registers are not implemented other than
13029 * control register 0.
13031 generate_exception(ctx
, EXCP_RI
);
13033 gen_helper_rdhwr_performance(t0
, cpu_env
);
13034 gen_store_gpr(t0
, rt
);
13037 check_insn(ctx
, ISA_MIPS32R6
);
13038 gen_helper_rdhwr_xnp(t0
, cpu_env
);
13039 gen_store_gpr(t0
, rt
);
13042 #if defined(CONFIG_USER_ONLY)
13043 tcg_gen_ld_tl(t0
, cpu_env
,
13044 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13045 gen_store_gpr(t0
, rt
);
13048 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
13049 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
13050 tcg_gen_ld_tl(t0
, cpu_env
,
13051 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13052 gen_store_gpr(t0
, rt
);
13054 generate_exception_end(ctx
, EXCP_RI
);
13058 default: /* Invalid */
13059 MIPS_INVAL("rdhwr");
13060 generate_exception_end(ctx
, EXCP_RI
);
13066 static inline void clear_branch_hflags(DisasContext
*ctx
)
13068 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
13069 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
13070 save_cpu_state(ctx
, 0);
13073 * It is not safe to save ctx->hflags as hflags may be changed
13074 * in execution time by the instruction in delay / forbidden slot.
13076 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
13080 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
13082 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13083 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
13084 /* Branches completion */
13085 clear_branch_hflags(ctx
);
13086 ctx
->base
.is_jmp
= DISAS_NORETURN
;
13087 /* FIXME: Need to clear can_do_io. */
13088 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
13089 case MIPS_HFLAG_FBNSLOT
:
13090 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
13093 /* unconditional branch */
13094 if (proc_hflags
& MIPS_HFLAG_BX
) {
13095 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
13097 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13099 case MIPS_HFLAG_BL
:
13100 /* blikely taken case */
13101 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13103 case MIPS_HFLAG_BC
:
13104 /* Conditional branch */
13106 TCGLabel
*l1
= gen_new_label();
13108 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
13109 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
13111 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13114 case MIPS_HFLAG_BR
:
13115 /* unconditional branch to register */
13116 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
13117 TCGv t0
= tcg_temp_new();
13118 TCGv_i32 t1
= tcg_temp_new_i32();
13120 tcg_gen_andi_tl(t0
, btarget
, 0x1);
13121 tcg_gen_trunc_tl_i32(t1
, t0
);
13123 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
13124 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
13125 tcg_gen_or_i32(hflags
, hflags
, t1
);
13126 tcg_temp_free_i32(t1
);
13128 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
13130 tcg_gen_mov_tl(cpu_PC
, btarget
);
13132 if (ctx
->base
.singlestep_enabled
) {
13133 save_cpu_state(ctx
, 0);
13134 gen_helper_raise_exception_debug(cpu_env
);
13136 tcg_gen_lookup_and_goto_ptr();
13139 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
13145 /* Compact Branches */
13146 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
13147 int rs
, int rt
, int32_t offset
)
13149 int bcond_compute
= 0;
13150 TCGv t0
= tcg_temp_new();
13151 TCGv t1
= tcg_temp_new();
13152 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
13154 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13155 #ifdef MIPS_DEBUG_DISAS
13156 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13157 "\n", ctx
->base
.pc_next
);
13159 generate_exception_end(ctx
, EXCP_RI
);
13163 /* Load needed operands and calculate btarget */
13165 /* compact branch */
13166 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13167 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13168 gen_load_gpr(t0
, rs
);
13169 gen_load_gpr(t1
, rt
);
13171 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13172 if (rs
<= rt
&& rs
== 0) {
13173 /* OPC_BEQZALC, OPC_BNEZALC */
13174 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13177 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13178 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13179 gen_load_gpr(t0
, rs
);
13180 gen_load_gpr(t1
, rt
);
13182 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13184 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13185 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13186 if (rs
== 0 || rs
== rt
) {
13187 /* OPC_BLEZALC, OPC_BGEZALC */
13188 /* OPC_BGTZALC, OPC_BLTZALC */
13189 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13191 gen_load_gpr(t0
, rs
);
13192 gen_load_gpr(t1
, rt
);
13194 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13198 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13203 /* OPC_BEQZC, OPC_BNEZC */
13204 gen_load_gpr(t0
, rs
);
13206 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13208 /* OPC_JIC, OPC_JIALC */
13209 TCGv tbase
= tcg_temp_new();
13210 TCGv toffset
= tcg_temp_new();
13212 gen_load_gpr(tbase
, rt
);
13213 tcg_gen_movi_tl(toffset
, offset
);
13214 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13215 tcg_temp_free(tbase
);
13216 tcg_temp_free(toffset
);
13220 MIPS_INVAL("Compact branch/jump");
13221 generate_exception_end(ctx
, EXCP_RI
);
13225 if (bcond_compute
== 0) {
13226 /* Uncoditional compact branch */
13229 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13232 ctx
->hflags
|= MIPS_HFLAG_BR
;
13235 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13238 ctx
->hflags
|= MIPS_HFLAG_B
;
13241 MIPS_INVAL("Compact branch/jump");
13242 generate_exception_end(ctx
, EXCP_RI
);
13246 /* Generating branch here as compact branches don't have delay slot */
13247 gen_branch(ctx
, 4);
13249 /* Conditional compact branch */
13250 TCGLabel
*fs
= gen_new_label();
13251 save_cpu_state(ctx
, 0);
13254 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13255 if (rs
== 0 && rt
!= 0) {
13257 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13258 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13260 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13263 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13266 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13267 if (rs
== 0 && rt
!= 0) {
13269 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13270 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13272 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13275 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13278 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13279 if (rs
== 0 && rt
!= 0) {
13281 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13282 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13284 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13287 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13290 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13291 if (rs
== 0 && rt
!= 0) {
13293 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13294 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13296 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13299 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13302 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13303 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13305 /* OPC_BOVC, OPC_BNVC */
13306 TCGv t2
= tcg_temp_new();
13307 TCGv t3
= tcg_temp_new();
13308 TCGv t4
= tcg_temp_new();
13309 TCGv input_overflow
= tcg_temp_new();
13311 gen_load_gpr(t0
, rs
);
13312 gen_load_gpr(t1
, rt
);
13313 tcg_gen_ext32s_tl(t2
, t0
);
13314 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13315 tcg_gen_ext32s_tl(t3
, t1
);
13316 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13317 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13319 tcg_gen_add_tl(t4
, t2
, t3
);
13320 tcg_gen_ext32s_tl(t4
, t4
);
13321 tcg_gen_xor_tl(t2
, t2
, t3
);
13322 tcg_gen_xor_tl(t3
, t4
, t3
);
13323 tcg_gen_andc_tl(t2
, t3
, t2
);
13324 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13325 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13326 if (opc
== OPC_BOVC
) {
13328 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13331 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13333 tcg_temp_free(input_overflow
);
13337 } else if (rs
< rt
&& rs
== 0) {
13338 /* OPC_BEQZALC, OPC_BNEZALC */
13339 if (opc
== OPC_BEQZALC
) {
13341 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13344 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13347 /* OPC_BEQC, OPC_BNEC */
13348 if (opc
== OPC_BEQC
) {
13350 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13353 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13358 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13361 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13364 MIPS_INVAL("Compact conditional branch/jump");
13365 generate_exception_end(ctx
, EXCP_RI
);
13369 /* Generating branch here as compact branches don't have delay slot */
13370 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13373 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13381 /* ISA extensions (ASEs) */
13382 /* MIPS16 extension to MIPS32 */
13384 /* MIPS16 major opcodes */
13386 M16_OPC_ADDIUSP
= 0x00,
13387 M16_OPC_ADDIUPC
= 0x01,
13389 M16_OPC_JAL
= 0x03,
13390 M16_OPC_BEQZ
= 0x04,
13391 M16_OPC_BNEQZ
= 0x05,
13392 M16_OPC_SHIFT
= 0x06,
13394 M16_OPC_RRIA
= 0x08,
13395 M16_OPC_ADDIU8
= 0x09,
13396 M16_OPC_SLTI
= 0x0a,
13397 M16_OPC_SLTIU
= 0x0b,
13400 M16_OPC_CMPI
= 0x0e,
13404 M16_OPC_LWSP
= 0x12,
13406 M16_OPC_LBU
= 0x14,
13407 M16_OPC_LHU
= 0x15,
13408 M16_OPC_LWPC
= 0x16,
13409 M16_OPC_LWU
= 0x17,
13412 M16_OPC_SWSP
= 0x1a,
13414 M16_OPC_RRR
= 0x1c,
13416 M16_OPC_EXTEND
= 0x1e,
13420 /* I8 funct field */
13439 /* RR funct field */
13473 /* I64 funct field */
13481 I64_DADDIUPC
= 0x6,
13485 /* RR ry field for CNVT */
13487 RR_RY_CNVT_ZEB
= 0x0,
13488 RR_RY_CNVT_ZEH
= 0x1,
13489 RR_RY_CNVT_ZEW
= 0x2,
13490 RR_RY_CNVT_SEB
= 0x4,
13491 RR_RY_CNVT_SEH
= 0x5,
13492 RR_RY_CNVT_SEW
= 0x6,
13495 static int xlat(int r
)
13497 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13502 static void gen_mips16_save(DisasContext
*ctx
,
13503 int xsregs
, int aregs
,
13504 int do_ra
, int do_s0
, int do_s1
,
13507 TCGv t0
= tcg_temp_new();
13508 TCGv t1
= tcg_temp_new();
13509 TCGv t2
= tcg_temp_new();
13539 generate_exception_end(ctx
, EXCP_RI
);
13545 gen_base_offset_addr(ctx
, t0
, 29, 12);
13546 gen_load_gpr(t1
, 7);
13547 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13550 gen_base_offset_addr(ctx
, t0
, 29, 8);
13551 gen_load_gpr(t1
, 6);
13552 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13555 gen_base_offset_addr(ctx
, t0
, 29, 4);
13556 gen_load_gpr(t1
, 5);
13557 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13560 gen_base_offset_addr(ctx
, t0
, 29, 0);
13561 gen_load_gpr(t1
, 4);
13562 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13565 gen_load_gpr(t0
, 29);
13567 #define DECR_AND_STORE(reg) do { \
13568 tcg_gen_movi_tl(t2, -4); \
13569 gen_op_addr_add(ctx, t0, t0, t2); \
13570 gen_load_gpr(t1, reg); \
13571 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13575 DECR_AND_STORE(31);
13580 DECR_AND_STORE(30);
13583 DECR_AND_STORE(23);
13586 DECR_AND_STORE(22);
13589 DECR_AND_STORE(21);
13592 DECR_AND_STORE(20);
13595 DECR_AND_STORE(19);
13598 DECR_AND_STORE(18);
13602 DECR_AND_STORE(17);
13605 DECR_AND_STORE(16);
13635 generate_exception_end(ctx
, EXCP_RI
);
13651 #undef DECR_AND_STORE
13653 tcg_gen_movi_tl(t2
, -framesize
);
13654 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13660 static void gen_mips16_restore(DisasContext
*ctx
,
13661 int xsregs
, int aregs
,
13662 int do_ra
, int do_s0
, int do_s1
,
13666 TCGv t0
= tcg_temp_new();
13667 TCGv t1
= tcg_temp_new();
13668 TCGv t2
= tcg_temp_new();
13670 tcg_gen_movi_tl(t2
, framesize
);
13671 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
13673 #define DECR_AND_LOAD(reg) do { \
13674 tcg_gen_movi_tl(t2, -4); \
13675 gen_op_addr_add(ctx, t0, t0, t2); \
13676 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13677 gen_store_gpr(t1, reg); \
13741 generate_exception_end(ctx
, EXCP_RI
);
13757 #undef DECR_AND_LOAD
13759 tcg_gen_movi_tl(t2
, framesize
);
13760 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13766 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
13767 int is_64_bit
, int extended
)
13771 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13772 generate_exception_end(ctx
, EXCP_RI
);
13776 t0
= tcg_temp_new();
13778 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
13779 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
13781 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13787 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
13790 TCGv_i32 t0
= tcg_const_i32(op
);
13791 TCGv t1
= tcg_temp_new();
13792 gen_base_offset_addr(ctx
, t1
, base
, offset
);
13793 gen_helper_cache(cpu_env
, t1
, t0
);
13796 #if defined(TARGET_MIPS64)
13797 static void decode_i64_mips16(DisasContext
*ctx
,
13798 int ry
, int funct
, int16_t offset
,
13803 check_insn(ctx
, ISA_MIPS3
);
13804 check_mips_64(ctx
);
13805 offset
= extended
? offset
: offset
<< 3;
13806 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
13809 check_insn(ctx
, ISA_MIPS3
);
13810 check_mips_64(ctx
);
13811 offset
= extended
? offset
: offset
<< 3;
13812 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
13815 check_insn(ctx
, ISA_MIPS3
);
13816 check_mips_64(ctx
);
13817 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
13818 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
13821 check_insn(ctx
, ISA_MIPS3
);
13822 check_mips_64(ctx
);
13823 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
13824 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
13827 check_insn(ctx
, ISA_MIPS3
);
13828 check_mips_64(ctx
);
13829 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13830 generate_exception_end(ctx
, EXCP_RI
);
13832 offset
= extended
? offset
: offset
<< 3;
13833 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
13837 check_insn(ctx
, ISA_MIPS3
);
13838 check_mips_64(ctx
);
13839 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
13840 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
13843 check_insn(ctx
, ISA_MIPS3
);
13844 check_mips_64(ctx
);
13845 offset
= extended
? offset
: offset
<< 2;
13846 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
13849 check_insn(ctx
, ISA_MIPS3
);
13850 check_mips_64(ctx
);
13851 offset
= extended
? offset
: offset
<< 2;
13852 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
13858 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13860 int extend
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
13861 int op
, rx
, ry
, funct
, sa
;
13862 int16_t imm
, offset
;
13864 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
13865 op
= (ctx
->opcode
>> 11) & 0x1f;
13866 sa
= (ctx
->opcode
>> 22) & 0x1f;
13867 funct
= (ctx
->opcode
>> 8) & 0x7;
13868 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13869 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13870 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
13871 | ((ctx
->opcode
>> 21) & 0x3f) << 5
13872 | (ctx
->opcode
& 0x1f));
13875 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13879 case M16_OPC_ADDIUSP
:
13880 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13882 case M16_OPC_ADDIUPC
:
13883 gen_addiupc(ctx
, rx
, imm
, 0, 1);
13886 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
13887 /* No delay slot, so just process as a normal instruction */
13890 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
13891 /* No delay slot, so just process as a normal instruction */
13893 case M16_OPC_BNEQZ
:
13894 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
13895 /* No delay slot, so just process as a normal instruction */
13897 case M16_OPC_SHIFT
:
13898 switch (ctx
->opcode
& 0x3) {
13900 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13903 #if defined(TARGET_MIPS64)
13904 check_mips_64(ctx
);
13905 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13907 generate_exception_end(ctx
, EXCP_RI
);
13911 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13914 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13918 #if defined(TARGET_MIPS64)
13920 check_insn(ctx
, ISA_MIPS3
);
13921 check_mips_64(ctx
);
13922 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
13926 imm
= ctx
->opcode
& 0xf;
13927 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
13928 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
13929 imm
= (int16_t) (imm
<< 1) >> 1;
13930 if ((ctx
->opcode
>> 4) & 0x1) {
13931 #if defined(TARGET_MIPS64)
13932 check_mips_64(ctx
);
13933 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13935 generate_exception_end(ctx
, EXCP_RI
);
13938 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13941 case M16_OPC_ADDIU8
:
13942 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13945 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13947 case M16_OPC_SLTIU
:
13948 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13953 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
13956 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
13959 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
13962 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
13965 check_insn(ctx
, ISA_MIPS32
);
13967 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
13968 int aregs
= (ctx
->opcode
>> 16) & 0xf;
13969 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
13970 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
13971 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
13972 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
13973 | (ctx
->opcode
& 0xf)) << 3;
13975 if (ctx
->opcode
& (1 << 7)) {
13976 gen_mips16_save(ctx
, xsregs
, aregs
,
13977 do_ra
, do_s0
, do_s1
,
13980 gen_mips16_restore(ctx
, xsregs
, aregs
,
13981 do_ra
, do_s0
, do_s1
,
13987 generate_exception_end(ctx
, EXCP_RI
);
13992 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
13995 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
13997 #if defined(TARGET_MIPS64)
13999 check_insn(ctx
, ISA_MIPS3
);
14000 check_mips_64(ctx
);
14001 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
14005 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14008 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
14011 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
14014 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
14017 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14020 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
14023 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
14025 #if defined(TARGET_MIPS64)
14027 check_insn(ctx
, ISA_MIPS3
);
14028 check_mips_64(ctx
);
14029 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
14033 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14036 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
14039 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
14042 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
14044 #if defined(TARGET_MIPS64)
14046 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
14050 generate_exception_end(ctx
, EXCP_RI
);
14057 static inline bool is_uhi(int sdbbp_code
)
14059 #ifdef CONFIG_USER_ONLY
14062 return semihosting_enabled() && sdbbp_code
== 1;
14066 #ifdef CONFIG_USER_ONLY
14067 /* The above should dead-code away any calls to this..*/
14068 static inline void gen_helper_do_semihosting(void *env
)
14070 g_assert_not_reached();
14074 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14078 int op
, cnvt_op
, op1
, offset
;
14082 op
= (ctx
->opcode
>> 11) & 0x1f;
14083 sa
= (ctx
->opcode
>> 2) & 0x7;
14084 sa
= sa
== 0 ? 8 : sa
;
14085 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14086 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
14087 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14088 op1
= offset
= ctx
->opcode
& 0x1f;
14093 case M16_OPC_ADDIUSP
:
14095 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
14097 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14100 case M16_OPC_ADDIUPC
:
14101 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
14104 offset
= (ctx
->opcode
& 0x7ff) << 1;
14105 offset
= (int16_t)(offset
<< 4) >> 4;
14106 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
14107 /* No delay slot, so just process as a normal instruction */
14110 offset
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14111 offset
= (((ctx
->opcode
& 0x1f) << 21)
14112 | ((ctx
->opcode
>> 5) & 0x1f) << 16
14114 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
14115 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
14119 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
14120 ((int8_t)ctx
->opcode
) << 1, 0);
14121 /* No delay slot, so just process as a normal instruction */
14123 case M16_OPC_BNEQZ
:
14124 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
14125 ((int8_t)ctx
->opcode
) << 1, 0);
14126 /* No delay slot, so just process as a normal instruction */
14128 case M16_OPC_SHIFT
:
14129 switch (ctx
->opcode
& 0x3) {
14131 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14134 #if defined(TARGET_MIPS64)
14135 check_insn(ctx
, ISA_MIPS3
);
14136 check_mips_64(ctx
);
14137 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14139 generate_exception_end(ctx
, EXCP_RI
);
14143 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14146 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14150 #if defined(TARGET_MIPS64)
14152 check_insn(ctx
, ISA_MIPS3
);
14153 check_mips_64(ctx
);
14154 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14159 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14161 if ((ctx
->opcode
>> 4) & 1) {
14162 #if defined(TARGET_MIPS64)
14163 check_insn(ctx
, ISA_MIPS3
);
14164 check_mips_64(ctx
);
14165 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14167 generate_exception_end(ctx
, EXCP_RI
);
14170 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14174 case M16_OPC_ADDIU8
:
14176 int16_t imm
= (int8_t) ctx
->opcode
;
14178 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14183 int16_t imm
= (uint8_t) ctx
->opcode
;
14184 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14187 case M16_OPC_SLTIU
:
14189 int16_t imm
= (uint8_t) ctx
->opcode
;
14190 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14197 funct
= (ctx
->opcode
>> 8) & 0x7;
14200 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14201 ((int8_t)ctx
->opcode
) << 1, 0);
14204 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14205 ((int8_t)ctx
->opcode
) << 1, 0);
14208 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14211 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14212 ((int8_t)ctx
->opcode
) << 3);
14215 check_insn(ctx
, ISA_MIPS32
);
14217 int do_ra
= ctx
->opcode
& (1 << 6);
14218 int do_s0
= ctx
->opcode
& (1 << 5);
14219 int do_s1
= ctx
->opcode
& (1 << 4);
14220 int framesize
= ctx
->opcode
& 0xf;
14222 if (framesize
== 0) {
14225 framesize
= framesize
<< 3;
14228 if (ctx
->opcode
& (1 << 7)) {
14229 gen_mips16_save(ctx
, 0, 0,
14230 do_ra
, do_s0
, do_s1
, framesize
);
14232 gen_mips16_restore(ctx
, 0, 0,
14233 do_ra
, do_s0
, do_s1
, framesize
);
14239 int rz
= xlat(ctx
->opcode
& 0x7);
14241 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14242 ((ctx
->opcode
>> 5) & 0x7);
14243 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14247 reg32
= ctx
->opcode
& 0x1f;
14248 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14251 generate_exception_end(ctx
, EXCP_RI
);
14258 int16_t imm
= (uint8_t) ctx
->opcode
;
14260 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14265 int16_t imm
= (uint8_t) ctx
->opcode
;
14266 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14269 #if defined(TARGET_MIPS64)
14271 check_insn(ctx
, ISA_MIPS3
);
14272 check_mips_64(ctx
);
14273 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14277 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14280 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14283 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14286 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14289 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14292 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14295 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14297 #if defined(TARGET_MIPS64)
14299 check_insn(ctx
, ISA_MIPS3
);
14300 check_mips_64(ctx
);
14301 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14305 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14308 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14311 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14314 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14318 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14321 switch (ctx
->opcode
& 0x3) {
14323 mips32_op
= OPC_ADDU
;
14326 mips32_op
= OPC_SUBU
;
14328 #if defined(TARGET_MIPS64)
14330 mips32_op
= OPC_DADDU
;
14331 check_insn(ctx
, ISA_MIPS3
);
14332 check_mips_64(ctx
);
14335 mips32_op
= OPC_DSUBU
;
14336 check_insn(ctx
, ISA_MIPS3
);
14337 check_mips_64(ctx
);
14341 generate_exception_end(ctx
, EXCP_RI
);
14345 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14354 int nd
= (ctx
->opcode
>> 7) & 0x1;
14355 int link
= (ctx
->opcode
>> 6) & 0x1;
14356 int ra
= (ctx
->opcode
>> 5) & 0x1;
14359 check_insn(ctx
, ISA_MIPS32
);
14368 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14373 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14374 gen_helper_do_semihosting(cpu_env
);
14377 * XXX: not clear which exception should be raised
14378 * when in debug mode...
14380 check_insn(ctx
, ISA_MIPS32
);
14381 generate_exception_end(ctx
, EXCP_DBp
);
14385 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14388 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14391 generate_exception_end(ctx
, EXCP_BREAK
);
14394 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14397 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14400 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14402 #if defined(TARGET_MIPS64)
14404 check_insn(ctx
, ISA_MIPS3
);
14405 check_mips_64(ctx
);
14406 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14410 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14413 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14416 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14419 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14422 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14425 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14428 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14431 check_insn(ctx
, ISA_MIPS32
);
14433 case RR_RY_CNVT_ZEB
:
14434 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14436 case RR_RY_CNVT_ZEH
:
14437 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14439 case RR_RY_CNVT_SEB
:
14440 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14442 case RR_RY_CNVT_SEH
:
14443 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14445 #if defined(TARGET_MIPS64)
14446 case RR_RY_CNVT_ZEW
:
14447 check_insn(ctx
, ISA_MIPS64
);
14448 check_mips_64(ctx
);
14449 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14451 case RR_RY_CNVT_SEW
:
14452 check_insn(ctx
, ISA_MIPS64
);
14453 check_mips_64(ctx
);
14454 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14458 generate_exception_end(ctx
, EXCP_RI
);
14463 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14465 #if defined(TARGET_MIPS64)
14467 check_insn(ctx
, ISA_MIPS3
);
14468 check_mips_64(ctx
);
14469 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14472 check_insn(ctx
, ISA_MIPS3
);
14473 check_mips_64(ctx
);
14474 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14477 check_insn(ctx
, ISA_MIPS3
);
14478 check_mips_64(ctx
);
14479 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14482 check_insn(ctx
, ISA_MIPS3
);
14483 check_mips_64(ctx
);
14484 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14488 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14491 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14494 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14497 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14499 #if defined(TARGET_MIPS64)
14501 check_insn(ctx
, ISA_MIPS3
);
14502 check_mips_64(ctx
);
14503 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14506 check_insn(ctx
, ISA_MIPS3
);
14507 check_mips_64(ctx
);
14508 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14511 check_insn(ctx
, ISA_MIPS3
);
14512 check_mips_64(ctx
);
14513 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14516 check_insn(ctx
, ISA_MIPS3
);
14517 check_mips_64(ctx
);
14518 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14522 generate_exception_end(ctx
, EXCP_RI
);
14526 case M16_OPC_EXTEND
:
14527 decode_extended_mips16_opc(env
, ctx
);
14530 #if defined(TARGET_MIPS64)
14532 funct
= (ctx
->opcode
>> 8) & 0x7;
14533 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
14537 generate_exception_end(ctx
, EXCP_RI
);
14544 /* microMIPS extension to MIPS32/MIPS64 */
14547 * microMIPS32/microMIPS64 major opcodes
14549 * 1. MIPS Architecture for Programmers Volume II-B:
14550 * The microMIPS32 Instruction Set (Revision 3.05)
14552 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14554 * 2. MIPS Architecture For Programmers Volume II-A:
14555 * The MIPS64 Instruction Set (Revision 3.51)
14585 POOL32S
= 0x16, /* MIPS64 */
14586 DADDIU32
= 0x17, /* MIPS64 */
14615 /* 0x29 is reserved */
14628 /* 0x31 is reserved */
14641 SD32
= 0x36, /* MIPS64 */
14642 LD32
= 0x37, /* MIPS64 */
14644 /* 0x39 is reserved */
14660 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14682 /* POOL32A encoding of minor opcode field */
14686 * These opcodes are distinguished only by bits 9..6; those bits are
14687 * what are recorded below.
14725 /* The following can be distinguished by their lower 6 bits. */
14735 /* POOL32AXF encoding of minor opcode field extension */
14738 * 1. MIPS Architecture for Programmers Volume II-B:
14739 * The microMIPS32 Instruction Set (Revision 3.05)
14741 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14743 * 2. MIPS Architecture for Programmers VolumeIV-e:
14744 * The MIPS DSP Application-Specific Extension
14745 * to the microMIPS32 Architecture (Revision 2.34)
14747 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14762 /* begin of microMIPS32 DSP */
14764 /* bits 13..12 for 0x01 */
14770 /* bits 13..12 for 0x2a */
14776 /* bits 13..12 for 0x32 */
14780 /* end of microMIPS32 DSP */
14782 /* bits 15..12 for 0x2c */
14799 /* bits 15..12 for 0x34 */
14807 /* bits 15..12 for 0x3c */
14809 JR
= 0x0, /* alias */
14817 /* bits 15..12 for 0x05 */
14821 /* bits 15..12 for 0x0d */
14833 /* bits 15..12 for 0x15 */
14839 /* bits 15..12 for 0x1d */
14843 /* bits 15..12 for 0x2d */
14848 /* bits 15..12 for 0x35 */
14855 /* POOL32B encoding of minor opcode field (bits 15..12) */
14871 /* POOL32C encoding of minor opcode field (bits 15..12) */
14892 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14905 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14918 /* POOL32F encoding of minor opcode field (bits 5..0) */
14921 /* These are the bit 7..6 values */
14930 /* These are the bit 8..6 values */
14955 MOVZ_FMT_05
= 0x05,
14989 CABS_COND_FMT
= 0x1c, /* MIPS3D */
14996 /* POOL32Fxf encoding of minor opcode extension field */
15034 /* POOL32I encoding of minor opcode field (bits 25..21) */
15064 /* These overlap and are distinguished by bit16 of the instruction */
15073 /* POOL16A encoding of minor opcode field */
15080 /* POOL16B encoding of minor opcode field */
15087 /* POOL16C encoding of minor opcode field */
15107 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15131 /* POOL16D encoding of minor opcode field */
15138 /* POOL16E encoding of minor opcode field */
15145 static int mmreg(int r
)
15147 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15152 /* Used for 16-bit store instructions. */
15153 static int mmreg2(int r
)
15155 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15160 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15161 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15162 #define uMIPS_RS2(op) uMIPS_RS(op)
15163 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15164 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15165 #define uMIPS_RS5(op) (op & 0x1f)
15167 /* Signed immediate */
15168 #define SIMM(op, start, width) \
15169 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15172 /* Zero-extended immediate */
15173 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15175 static void gen_addiur1sp(DisasContext
*ctx
)
15177 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15179 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15182 static void gen_addiur2(DisasContext
*ctx
)
15184 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15185 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15186 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15188 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15191 static void gen_addiusp(DisasContext
*ctx
)
15193 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15196 if (encoded
<= 1) {
15197 decoded
= 256 + encoded
;
15198 } else if (encoded
<= 255) {
15200 } else if (encoded
<= 509) {
15201 decoded
= encoded
- 512;
15203 decoded
= encoded
- 768;
15206 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15209 static void gen_addius5(DisasContext
*ctx
)
15211 int imm
= SIMM(ctx
->opcode
, 1, 4);
15212 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15214 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15217 static void gen_andi16(DisasContext
*ctx
)
15219 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15220 31, 32, 63, 64, 255, 32768, 65535 };
15221 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15222 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15223 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15225 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15228 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15229 int base
, int16_t offset
)
15234 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15235 generate_exception_end(ctx
, EXCP_RI
);
15239 t0
= tcg_temp_new();
15241 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15243 t1
= tcg_const_tl(reglist
);
15244 t2
= tcg_const_i32(ctx
->mem_idx
);
15246 save_cpu_state(ctx
, 1);
15249 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15252 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15254 #ifdef TARGET_MIPS64
15256 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15259 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15265 tcg_temp_free_i32(t2
);
15269 static void gen_pool16c_insn(DisasContext
*ctx
)
15271 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15272 int rs
= mmreg(ctx
->opcode
& 0x7);
15274 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15279 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15285 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15291 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15297 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15304 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15305 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15307 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15316 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15317 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15319 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15326 int reg
= ctx
->opcode
& 0x1f;
15328 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15334 int reg
= ctx
->opcode
& 0x1f;
15335 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15337 * Let normal delay slot handling in our caller take us
15338 * to the branch target.
15344 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15345 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15349 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15350 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15354 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15358 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15361 generate_exception_end(ctx
, EXCP_BREAK
);
15364 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15365 gen_helper_do_semihosting(cpu_env
);
15368 * XXX: not clear which exception should be raised
15369 * when in debug mode...
15371 check_insn(ctx
, ISA_MIPS32
);
15372 generate_exception_end(ctx
, EXCP_DBp
);
15375 case JRADDIUSP
+ 0:
15376 case JRADDIUSP
+ 1:
15378 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15379 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15380 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15382 * Let normal delay slot handling in our caller take us
15383 * to the branch target.
15388 generate_exception_end(ctx
, EXCP_RI
);
15393 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15396 int rd
, rs
, re
, rt
;
15397 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15398 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15399 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15400 rd
= rd_enc
[enc_dest
];
15401 re
= re_enc
[enc_dest
];
15402 rs
= rs_rt_enc
[enc_rs
];
15403 rt
= rs_rt_enc
[enc_rt
];
15405 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15407 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15410 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15412 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15416 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15418 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15419 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15421 switch (ctx
->opcode
& 0xf) {
15423 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15426 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15430 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15431 int offset
= extract32(ctx
->opcode
, 4, 4);
15432 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15435 case R6_JRC16
: /* JRCADDIUSP */
15436 if ((ctx
->opcode
>> 4) & 1) {
15438 int imm
= extract32(ctx
->opcode
, 5, 5);
15439 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15440 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15443 rs
= extract32(ctx
->opcode
, 5, 5);
15444 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15456 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15457 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15458 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15459 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15463 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15466 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15470 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15471 int offset
= extract32(ctx
->opcode
, 4, 4);
15472 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15475 case JALRC16
: /* BREAK16, SDBBP16 */
15476 switch (ctx
->opcode
& 0x3f) {
15478 case JALRC16
+ 0x20:
15480 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15485 generate_exception(ctx
, EXCP_BREAK
);
15489 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15490 gen_helper_do_semihosting(cpu_env
);
15492 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15493 generate_exception(ctx
, EXCP_RI
);
15495 generate_exception(ctx
, EXCP_DBp
);
15502 generate_exception(ctx
, EXCP_RI
);
15507 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15509 TCGv t0
= tcg_temp_new();
15510 TCGv t1
= tcg_temp_new();
15512 gen_load_gpr(t0
, base
);
15515 gen_load_gpr(t1
, index
);
15516 tcg_gen_shli_tl(t1
, t1
, 2);
15517 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15520 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15521 gen_store_gpr(t1
, rd
);
15527 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15528 int base
, int16_t offset
)
15532 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15533 generate_exception_end(ctx
, EXCP_RI
);
15537 t0
= tcg_temp_new();
15538 t1
= tcg_temp_new();
15540 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15545 generate_exception_end(ctx
, EXCP_RI
);
15548 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15549 gen_store_gpr(t1
, rd
);
15550 tcg_gen_movi_tl(t1
, 4);
15551 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15552 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15553 gen_store_gpr(t1
, rd
+ 1);
15556 gen_load_gpr(t1
, rd
);
15557 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15558 tcg_gen_movi_tl(t1
, 4);
15559 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15560 gen_load_gpr(t1
, rd
+ 1);
15561 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15563 #ifdef TARGET_MIPS64
15566 generate_exception_end(ctx
, EXCP_RI
);
15569 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15570 gen_store_gpr(t1
, rd
);
15571 tcg_gen_movi_tl(t1
, 8);
15572 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15573 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15574 gen_store_gpr(t1
, rd
+ 1);
15577 gen_load_gpr(t1
, rd
);
15578 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15579 tcg_gen_movi_tl(t1
, 8);
15580 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15581 gen_load_gpr(t1
, rd
+ 1);
15582 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15590 static void gen_sync(int stype
)
15592 TCGBar tcg_mo
= TCG_BAR_SC
;
15595 case 0x4: /* SYNC_WMB */
15596 tcg_mo
|= TCG_MO_ST_ST
;
15598 case 0x10: /* SYNC_MB */
15599 tcg_mo
|= TCG_MO_ALL
;
15601 case 0x11: /* SYNC_ACQUIRE */
15602 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
15604 case 0x12: /* SYNC_RELEASE */
15605 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
15607 case 0x13: /* SYNC_RMB */
15608 tcg_mo
|= TCG_MO_LD_LD
;
15611 tcg_mo
|= TCG_MO_ALL
;
15615 tcg_gen_mb(tcg_mo
);
15618 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
15620 int extension
= (ctx
->opcode
>> 6) & 0x3f;
15621 int minor
= (ctx
->opcode
>> 12) & 0xf;
15622 uint32_t mips32_op
;
15624 switch (extension
) {
15626 mips32_op
= OPC_TEQ
;
15629 mips32_op
= OPC_TGE
;
15632 mips32_op
= OPC_TGEU
;
15635 mips32_op
= OPC_TLT
;
15638 mips32_op
= OPC_TLTU
;
15641 mips32_op
= OPC_TNE
;
15643 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
15645 #ifndef CONFIG_USER_ONLY
15648 check_cp0_enabled(ctx
);
15650 /* Treat as NOP. */
15653 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
15657 check_cp0_enabled(ctx
);
15659 TCGv t0
= tcg_temp_new();
15661 gen_load_gpr(t0
, rt
);
15662 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
15668 switch (minor
& 3) {
15670 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15673 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15676 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15679 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15682 goto pool32axf_invalid
;
15686 switch (minor
& 3) {
15688 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15691 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15694 goto pool32axf_invalid
;
15700 check_insn(ctx
, ISA_MIPS32R6
);
15701 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
15704 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
15707 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
15710 mips32_op
= OPC_CLO
;
15713 mips32_op
= OPC_CLZ
;
15715 check_insn(ctx
, ISA_MIPS32
);
15716 gen_cl(ctx
, mips32_op
, rt
, rs
);
15719 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15720 gen_rdhwr(ctx
, rt
, rs
, 0);
15723 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
15726 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15727 mips32_op
= OPC_MULT
;
15730 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15731 mips32_op
= OPC_MULTU
;
15734 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15735 mips32_op
= OPC_DIV
;
15738 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15739 mips32_op
= OPC_DIVU
;
15742 check_insn(ctx
, ISA_MIPS32
);
15743 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15746 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15747 mips32_op
= OPC_MADD
;
15750 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15751 mips32_op
= OPC_MADDU
;
15754 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15755 mips32_op
= OPC_MSUB
;
15758 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15759 mips32_op
= OPC_MSUBU
;
15761 check_insn(ctx
, ISA_MIPS32
);
15762 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15765 goto pool32axf_invalid
;
15776 generate_exception_err(ctx
, EXCP_CpU
, 2);
15779 goto pool32axf_invalid
;
15784 case JALR
: /* JALRC */
15785 case JALR_HB
: /* JALRC_HB */
15786 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15787 /* JALRC, JALRC_HB */
15788 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
15790 /* JALR, JALR_HB */
15791 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
15792 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15797 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15798 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
15799 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15802 goto pool32axf_invalid
;
15808 check_cp0_enabled(ctx
);
15809 check_insn(ctx
, ISA_MIPS32R2
);
15810 gen_load_srsgpr(rs
, rt
);
15813 check_cp0_enabled(ctx
);
15814 check_insn(ctx
, ISA_MIPS32R2
);
15815 gen_store_srsgpr(rs
, rt
);
15818 goto pool32axf_invalid
;
15821 #ifndef CONFIG_USER_ONLY
15825 mips32_op
= OPC_TLBP
;
15828 mips32_op
= OPC_TLBR
;
15831 mips32_op
= OPC_TLBWI
;
15834 mips32_op
= OPC_TLBWR
;
15837 mips32_op
= OPC_TLBINV
;
15840 mips32_op
= OPC_TLBINVF
;
15843 mips32_op
= OPC_WAIT
;
15846 mips32_op
= OPC_DERET
;
15849 mips32_op
= OPC_ERET
;
15851 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
15854 goto pool32axf_invalid
;
15860 check_cp0_enabled(ctx
);
15862 TCGv t0
= tcg_temp_new();
15864 save_cpu_state(ctx
, 1);
15865 gen_helper_di(t0
, cpu_env
);
15866 gen_store_gpr(t0
, rs
);
15868 * Stop translation as we may have switched the execution
15871 ctx
->base
.is_jmp
= DISAS_STOP
;
15876 check_cp0_enabled(ctx
);
15878 TCGv t0
= tcg_temp_new();
15880 save_cpu_state(ctx
, 1);
15881 gen_helper_ei(t0
, cpu_env
);
15882 gen_store_gpr(t0
, rs
);
15884 * DISAS_STOP isn't sufficient, we need to ensure we break out
15885 * of translated code to check for pending interrupts.
15887 gen_save_pc(ctx
->base
.pc_next
+ 4);
15888 ctx
->base
.is_jmp
= DISAS_EXIT
;
15893 goto pool32axf_invalid
;
15900 gen_sync(extract32(ctx
->opcode
, 16, 5));
15903 generate_exception_end(ctx
, EXCP_SYSCALL
);
15906 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
15907 gen_helper_do_semihosting(cpu_env
);
15909 check_insn(ctx
, ISA_MIPS32
);
15910 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15911 generate_exception_end(ctx
, EXCP_RI
);
15913 generate_exception_end(ctx
, EXCP_DBp
);
15918 goto pool32axf_invalid
;
15922 switch (minor
& 3) {
15924 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
15927 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
15930 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
15933 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
15936 goto pool32axf_invalid
;
15940 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15943 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
15946 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
15949 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
15952 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
15955 goto pool32axf_invalid
;
15960 MIPS_INVAL("pool32axf");
15961 generate_exception_end(ctx
, EXCP_RI
);
15967 * Values for microMIPS fmt field. Variable-width, depending on which
15968 * formats the instruction supports.
15987 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
15989 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
15990 uint32_t mips32_op
;
15992 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
15993 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
15994 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
15996 switch (extension
) {
15997 case FLOAT_1BIT_FMT(CFC1
, 0):
15998 mips32_op
= OPC_CFC1
;
16000 case FLOAT_1BIT_FMT(CTC1
, 0):
16001 mips32_op
= OPC_CTC1
;
16003 case FLOAT_1BIT_FMT(MFC1
, 0):
16004 mips32_op
= OPC_MFC1
;
16006 case FLOAT_1BIT_FMT(MTC1
, 0):
16007 mips32_op
= OPC_MTC1
;
16009 case FLOAT_1BIT_FMT(MFHC1
, 0):
16010 mips32_op
= OPC_MFHC1
;
16012 case FLOAT_1BIT_FMT(MTHC1
, 0):
16013 mips32_op
= OPC_MTHC1
;
16015 gen_cp1(ctx
, mips32_op
, rt
, rs
);
16018 /* Reciprocal square root */
16019 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
16020 mips32_op
= OPC_RSQRT_S
;
16022 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
16023 mips32_op
= OPC_RSQRT_D
;
16027 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
16028 mips32_op
= OPC_SQRT_S
;
16030 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
16031 mips32_op
= OPC_SQRT_D
;
16035 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
16036 mips32_op
= OPC_RECIP_S
;
16038 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
16039 mips32_op
= OPC_RECIP_D
;
16043 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
16044 mips32_op
= OPC_FLOOR_L_S
;
16046 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
16047 mips32_op
= OPC_FLOOR_L_D
;
16049 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
16050 mips32_op
= OPC_FLOOR_W_S
;
16052 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
16053 mips32_op
= OPC_FLOOR_W_D
;
16057 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
16058 mips32_op
= OPC_CEIL_L_S
;
16060 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
16061 mips32_op
= OPC_CEIL_L_D
;
16063 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
16064 mips32_op
= OPC_CEIL_W_S
;
16066 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
16067 mips32_op
= OPC_CEIL_W_D
;
16071 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
16072 mips32_op
= OPC_TRUNC_L_S
;
16074 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
16075 mips32_op
= OPC_TRUNC_L_D
;
16077 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
16078 mips32_op
= OPC_TRUNC_W_S
;
16080 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
16081 mips32_op
= OPC_TRUNC_W_D
;
16085 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
16086 mips32_op
= OPC_ROUND_L_S
;
16088 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
16089 mips32_op
= OPC_ROUND_L_D
;
16091 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
16092 mips32_op
= OPC_ROUND_W_S
;
16094 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
16095 mips32_op
= OPC_ROUND_W_D
;
16098 /* Integer to floating-point conversion */
16099 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
16100 mips32_op
= OPC_CVT_L_S
;
16102 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
16103 mips32_op
= OPC_CVT_L_D
;
16105 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
16106 mips32_op
= OPC_CVT_W_S
;
16108 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
16109 mips32_op
= OPC_CVT_W_D
;
16112 /* Paired-foo conversions */
16113 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
16114 mips32_op
= OPC_CVT_S_PL
;
16116 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
16117 mips32_op
= OPC_CVT_S_PU
;
16119 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
16120 mips32_op
= OPC_CVT_PW_PS
;
16122 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
16123 mips32_op
= OPC_CVT_PS_PW
;
16126 /* Floating-point moves */
16127 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
16128 mips32_op
= OPC_MOV_S
;
16130 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
16131 mips32_op
= OPC_MOV_D
;
16133 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
16134 mips32_op
= OPC_MOV_PS
;
16137 /* Absolute value */
16138 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
16139 mips32_op
= OPC_ABS_S
;
16141 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
16142 mips32_op
= OPC_ABS_D
;
16144 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
16145 mips32_op
= OPC_ABS_PS
;
16149 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
16150 mips32_op
= OPC_NEG_S
;
16152 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
16153 mips32_op
= OPC_NEG_D
;
16155 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16156 mips32_op
= OPC_NEG_PS
;
16159 /* Reciprocal square root step */
16160 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16161 mips32_op
= OPC_RSQRT1_S
;
16163 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16164 mips32_op
= OPC_RSQRT1_D
;
16166 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16167 mips32_op
= OPC_RSQRT1_PS
;
16170 /* Reciprocal step */
16171 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16172 mips32_op
= OPC_RECIP1_S
;
16174 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16175 mips32_op
= OPC_RECIP1_S
;
16177 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16178 mips32_op
= OPC_RECIP1_PS
;
16181 /* Conversions from double */
16182 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16183 mips32_op
= OPC_CVT_D_S
;
16185 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16186 mips32_op
= OPC_CVT_D_W
;
16188 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16189 mips32_op
= OPC_CVT_D_L
;
16192 /* Conversions from single */
16193 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16194 mips32_op
= OPC_CVT_S_D
;
16196 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16197 mips32_op
= OPC_CVT_S_W
;
16199 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16200 mips32_op
= OPC_CVT_S_L
;
16202 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16205 /* Conditional moves on floating-point codes */
16206 case COND_FLOAT_MOV(MOVT
, 0):
16207 case COND_FLOAT_MOV(MOVT
, 1):
16208 case COND_FLOAT_MOV(MOVT
, 2):
16209 case COND_FLOAT_MOV(MOVT
, 3):
16210 case COND_FLOAT_MOV(MOVT
, 4):
16211 case COND_FLOAT_MOV(MOVT
, 5):
16212 case COND_FLOAT_MOV(MOVT
, 6):
16213 case COND_FLOAT_MOV(MOVT
, 7):
16214 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16215 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16217 case COND_FLOAT_MOV(MOVF
, 0):
16218 case COND_FLOAT_MOV(MOVF
, 1):
16219 case COND_FLOAT_MOV(MOVF
, 2):
16220 case COND_FLOAT_MOV(MOVF
, 3):
16221 case COND_FLOAT_MOV(MOVF
, 4):
16222 case COND_FLOAT_MOV(MOVF
, 5):
16223 case COND_FLOAT_MOV(MOVF
, 6):
16224 case COND_FLOAT_MOV(MOVF
, 7):
16225 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16226 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16229 MIPS_INVAL("pool32fxf");
16230 generate_exception_end(ctx
, EXCP_RI
);
16235 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16239 int rt
, rs
, rd
, rr
;
16241 uint32_t op
, minor
, minor2
, mips32_op
;
16242 uint32_t cond
, fmt
, cc
;
16244 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
16245 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16247 rt
= (ctx
->opcode
>> 21) & 0x1f;
16248 rs
= (ctx
->opcode
>> 16) & 0x1f;
16249 rd
= (ctx
->opcode
>> 11) & 0x1f;
16250 rr
= (ctx
->opcode
>> 6) & 0x1f;
16251 imm
= (int16_t) ctx
->opcode
;
16253 op
= (ctx
->opcode
>> 26) & 0x3f;
16256 minor
= ctx
->opcode
& 0x3f;
16259 minor
= (ctx
->opcode
>> 6) & 0xf;
16262 mips32_op
= OPC_SLL
;
16265 mips32_op
= OPC_SRA
;
16268 mips32_op
= OPC_SRL
;
16271 mips32_op
= OPC_ROTR
;
16273 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16276 check_insn(ctx
, ISA_MIPS32R6
);
16277 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16280 check_insn(ctx
, ISA_MIPS32R6
);
16281 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16284 check_insn(ctx
, ISA_MIPS32R6
);
16285 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16288 goto pool32a_invalid
;
16292 minor
= (ctx
->opcode
>> 6) & 0xf;
16296 mips32_op
= OPC_ADD
;
16299 mips32_op
= OPC_ADDU
;
16302 mips32_op
= OPC_SUB
;
16305 mips32_op
= OPC_SUBU
;
16308 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16309 mips32_op
= OPC_MUL
;
16311 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16315 mips32_op
= OPC_SLLV
;
16318 mips32_op
= OPC_SRLV
;
16321 mips32_op
= OPC_SRAV
;
16324 mips32_op
= OPC_ROTRV
;
16326 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16328 /* Logical operations */
16330 mips32_op
= OPC_AND
;
16333 mips32_op
= OPC_OR
;
16336 mips32_op
= OPC_NOR
;
16339 mips32_op
= OPC_XOR
;
16341 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16343 /* Set less than */
16345 mips32_op
= OPC_SLT
;
16348 mips32_op
= OPC_SLTU
;
16350 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16353 goto pool32a_invalid
;
16357 minor
= (ctx
->opcode
>> 6) & 0xf;
16359 /* Conditional moves */
16360 case MOVN
: /* MUL */
16361 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16363 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16366 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16369 case MOVZ
: /* MUH */
16370 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16372 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16375 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16379 check_insn(ctx
, ISA_MIPS32R6
);
16380 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16383 check_insn(ctx
, ISA_MIPS32R6
);
16384 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16386 case LWXS
: /* DIV */
16387 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16389 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16392 gen_ldxs(ctx
, rs
, rt
, rd
);
16396 check_insn(ctx
, ISA_MIPS32R6
);
16397 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16400 check_insn(ctx
, ISA_MIPS32R6
);
16401 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16404 check_insn(ctx
, ISA_MIPS32R6
);
16405 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16408 goto pool32a_invalid
;
16412 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16415 check_insn(ctx
, ISA_MIPS32R6
);
16416 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
16417 extract32(ctx
->opcode
, 9, 2));
16420 check_insn(ctx
, ISA_MIPS32R6
);
16421 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16424 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16427 gen_pool32axf(env
, ctx
, rt
, rs
);
16430 generate_exception_end(ctx
, EXCP_BREAK
);
16433 check_insn(ctx
, ISA_MIPS32R6
);
16434 generate_exception_end(ctx
, EXCP_RI
);
16438 MIPS_INVAL("pool32a");
16439 generate_exception_end(ctx
, EXCP_RI
);
16444 minor
= (ctx
->opcode
>> 12) & 0xf;
16447 check_cp0_enabled(ctx
);
16448 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16449 gen_cache_operation(ctx
, rt
, rs
, imm
);
16454 /* COP2: Not implemented. */
16455 generate_exception_err(ctx
, EXCP_CpU
, 2);
16457 #ifdef TARGET_MIPS64
16460 check_insn(ctx
, ISA_MIPS3
);
16461 check_mips_64(ctx
);
16466 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16468 #ifdef TARGET_MIPS64
16471 check_insn(ctx
, ISA_MIPS3
);
16472 check_mips_64(ctx
);
16477 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16480 MIPS_INVAL("pool32b");
16481 generate_exception_end(ctx
, EXCP_RI
);
16486 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16487 minor
= ctx
->opcode
& 0x3f;
16488 check_cp1_enabled(ctx
);
16491 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16492 mips32_op
= OPC_ALNV_PS
;
16495 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16496 mips32_op
= OPC_MADD_S
;
16499 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16500 mips32_op
= OPC_MADD_D
;
16503 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16504 mips32_op
= OPC_MADD_PS
;
16507 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16508 mips32_op
= OPC_MSUB_S
;
16511 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16512 mips32_op
= OPC_MSUB_D
;
16515 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16516 mips32_op
= OPC_MSUB_PS
;
16519 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16520 mips32_op
= OPC_NMADD_S
;
16523 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16524 mips32_op
= OPC_NMADD_D
;
16527 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16528 mips32_op
= OPC_NMADD_PS
;
16531 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16532 mips32_op
= OPC_NMSUB_S
;
16535 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16536 mips32_op
= OPC_NMSUB_D
;
16539 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16540 mips32_op
= OPC_NMSUB_PS
;
16542 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
16544 case CABS_COND_FMT
:
16545 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16546 cond
= (ctx
->opcode
>> 6) & 0xf;
16547 cc
= (ctx
->opcode
>> 13) & 0x7;
16548 fmt
= (ctx
->opcode
>> 10) & 0x3;
16551 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
16554 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
16557 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
16560 goto pool32f_invalid
;
16564 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16565 cond
= (ctx
->opcode
>> 6) & 0xf;
16566 cc
= (ctx
->opcode
>> 13) & 0x7;
16567 fmt
= (ctx
->opcode
>> 10) & 0x3;
16570 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
16573 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
16576 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
16579 goto pool32f_invalid
;
16583 check_insn(ctx
, ISA_MIPS32R6
);
16584 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16587 check_insn(ctx
, ISA_MIPS32R6
);
16588 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16591 gen_pool32fxf(ctx
, rt
, rs
);
16595 switch ((ctx
->opcode
>> 6) & 0x7) {
16597 mips32_op
= OPC_PLL_PS
;
16600 mips32_op
= OPC_PLU_PS
;
16603 mips32_op
= OPC_PUL_PS
;
16606 mips32_op
= OPC_PUU_PS
;
16609 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16610 mips32_op
= OPC_CVT_PS_S
;
16612 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16615 goto pool32f_invalid
;
16619 check_insn(ctx
, ISA_MIPS32R6
);
16620 switch ((ctx
->opcode
>> 9) & 0x3) {
16622 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
16625 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
16628 goto pool32f_invalid
;
16633 switch ((ctx
->opcode
>> 6) & 0x7) {
16635 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16636 mips32_op
= OPC_LWXC1
;
16639 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16640 mips32_op
= OPC_SWXC1
;
16643 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16644 mips32_op
= OPC_LDXC1
;
16647 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16648 mips32_op
= OPC_SDXC1
;
16651 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16652 mips32_op
= OPC_LUXC1
;
16655 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16656 mips32_op
= OPC_SUXC1
;
16658 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
16661 goto pool32f_invalid
;
16665 check_insn(ctx
, ISA_MIPS32R6
);
16666 switch ((ctx
->opcode
>> 9) & 0x3) {
16668 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
16671 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
16674 goto pool32f_invalid
;
16679 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16680 fmt
= (ctx
->opcode
>> 9) & 0x3;
16681 switch ((ctx
->opcode
>> 6) & 0x7) {
16685 mips32_op
= OPC_RSQRT2_S
;
16688 mips32_op
= OPC_RSQRT2_D
;
16691 mips32_op
= OPC_RSQRT2_PS
;
16694 goto pool32f_invalid
;
16700 mips32_op
= OPC_RECIP2_S
;
16703 mips32_op
= OPC_RECIP2_D
;
16706 mips32_op
= OPC_RECIP2_PS
;
16709 goto pool32f_invalid
;
16713 mips32_op
= OPC_ADDR_PS
;
16716 mips32_op
= OPC_MULR_PS
;
16718 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16721 goto pool32f_invalid
;
16725 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16726 cc
= (ctx
->opcode
>> 13) & 0x7;
16727 fmt
= (ctx
->opcode
>> 9) & 0x3;
16728 switch ((ctx
->opcode
>> 6) & 0x7) {
16729 case MOVF_FMT
: /* RINT_FMT */
16730 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16734 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
16737 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
16740 goto pool32f_invalid
;
16746 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
16749 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
16753 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
16756 goto pool32f_invalid
;
16760 case MOVT_FMT
: /* CLASS_FMT */
16761 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16765 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
16768 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
16771 goto pool32f_invalid
;
16777 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
16780 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
16784 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
16787 goto pool32f_invalid
;
16792 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16795 goto pool32f_invalid
;
16798 #define FINSN_3ARG_SDPS(prfx) \
16799 switch ((ctx->opcode >> 8) & 0x3) { \
16801 mips32_op = OPC_##prfx##_S; \
16804 mips32_op = OPC_##prfx##_D; \
16806 case FMT_SDPS_PS: \
16808 mips32_op = OPC_##prfx##_PS; \
16811 goto pool32f_invalid; \
16814 check_insn(ctx
, ISA_MIPS32R6
);
16815 switch ((ctx
->opcode
>> 9) & 0x3) {
16817 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
16820 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
16823 goto pool32f_invalid
;
16827 check_insn(ctx
, ISA_MIPS32R6
);
16828 switch ((ctx
->opcode
>> 9) & 0x3) {
16830 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
16833 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
16836 goto pool32f_invalid
;
16840 /* regular FP ops */
16841 switch ((ctx
->opcode
>> 6) & 0x3) {
16843 FINSN_3ARG_SDPS(ADD
);
16846 FINSN_3ARG_SDPS(SUB
);
16849 FINSN_3ARG_SDPS(MUL
);
16852 fmt
= (ctx
->opcode
>> 8) & 0x3;
16854 mips32_op
= OPC_DIV_D
;
16855 } else if (fmt
== 0) {
16856 mips32_op
= OPC_DIV_S
;
16858 goto pool32f_invalid
;
16862 goto pool32f_invalid
;
16867 switch ((ctx
->opcode
>> 6) & 0x7) {
16868 case MOVN_FMT
: /* SELEQZ_FMT */
16869 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16871 switch ((ctx
->opcode
>> 9) & 0x3) {
16873 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
16876 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
16879 goto pool32f_invalid
;
16883 FINSN_3ARG_SDPS(MOVN
);
16887 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16888 FINSN_3ARG_SDPS(MOVN
);
16890 case MOVZ_FMT
: /* SELNEZ_FMT */
16891 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16893 switch ((ctx
->opcode
>> 9) & 0x3) {
16895 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
16898 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
16901 goto pool32f_invalid
;
16905 FINSN_3ARG_SDPS(MOVZ
);
16909 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16910 FINSN_3ARG_SDPS(MOVZ
);
16913 check_insn(ctx
, ISA_MIPS32R6
);
16914 switch ((ctx
->opcode
>> 9) & 0x3) {
16916 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
16919 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
16922 goto pool32f_invalid
;
16926 check_insn(ctx
, ISA_MIPS32R6
);
16927 switch ((ctx
->opcode
>> 9) & 0x3) {
16929 mips32_op
= OPC_MADDF_S
;
16932 mips32_op
= OPC_MADDF_D
;
16935 goto pool32f_invalid
;
16939 check_insn(ctx
, ISA_MIPS32R6
);
16940 switch ((ctx
->opcode
>> 9) & 0x3) {
16942 mips32_op
= OPC_MSUBF_S
;
16945 mips32_op
= OPC_MSUBF_D
;
16948 goto pool32f_invalid
;
16952 goto pool32f_invalid
;
16956 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16960 MIPS_INVAL("pool32f");
16961 generate_exception_end(ctx
, EXCP_RI
);
16965 generate_exception_err(ctx
, EXCP_CpU
, 1);
16969 minor
= (ctx
->opcode
>> 21) & 0x1f;
16972 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16973 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
16976 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16977 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
16978 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16981 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16982 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
16983 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16986 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16987 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
16990 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16991 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
16992 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16995 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16996 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
16997 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17000 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17001 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
17004 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17005 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
17009 case TLTI
: /* BC1EQZC */
17010 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17012 check_cp1_enabled(ctx
);
17013 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
17016 mips32_op
= OPC_TLTI
;
17020 case TGEI
: /* BC1NEZC */
17021 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17023 check_cp1_enabled(ctx
);
17024 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
17027 mips32_op
= OPC_TGEI
;
17032 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17033 mips32_op
= OPC_TLTIU
;
17036 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17037 mips32_op
= OPC_TGEIU
;
17039 case TNEI
: /* SYNCI */
17040 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17043 * Break the TB to be able to sync copied instructions
17046 ctx
->base
.is_jmp
= DISAS_STOP
;
17049 mips32_op
= OPC_TNEI
;
17054 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17055 mips32_op
= OPC_TEQI
;
17057 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
17062 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17063 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
17064 4, rs
, 0, imm
<< 1, 0);
17066 * Compact branches don't have a delay slot, so just let
17067 * the normal delay slot handling take us to the branch
17072 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17073 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
17076 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17078 * Break the TB to be able to sync copied instructions
17081 ctx
->base
.is_jmp
= DISAS_STOP
;
17085 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17086 /* COP2: Not implemented. */
17087 generate_exception_err(ctx
, EXCP_CpU
, 2);
17090 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17091 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
17094 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17095 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
17098 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17099 mips32_op
= OPC_BC1FANY4
;
17102 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17103 mips32_op
= OPC_BC1TANY4
;
17106 check_insn(ctx
, ASE_MIPS3D
);
17109 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17110 check_cp1_enabled(ctx
);
17111 gen_compute_branch1(ctx
, mips32_op
,
17112 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
17114 generate_exception_err(ctx
, EXCP_CpU
, 1);
17119 /* MIPS DSP: not implemented */
17122 MIPS_INVAL("pool32i");
17123 generate_exception_end(ctx
, EXCP_RI
);
17128 minor
= (ctx
->opcode
>> 12) & 0xf;
17129 offset
= sextract32(ctx
->opcode
, 0,
17130 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
17133 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17134 mips32_op
= OPC_LWL
;
17137 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17138 mips32_op
= OPC_SWL
;
17141 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17142 mips32_op
= OPC_LWR
;
17145 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17146 mips32_op
= OPC_SWR
;
17148 #if defined(TARGET_MIPS64)
17150 check_insn(ctx
, ISA_MIPS3
);
17151 check_mips_64(ctx
);
17152 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17153 mips32_op
= OPC_LDL
;
17156 check_insn(ctx
, ISA_MIPS3
);
17157 check_mips_64(ctx
);
17158 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17159 mips32_op
= OPC_SDL
;
17162 check_insn(ctx
, ISA_MIPS3
);
17163 check_mips_64(ctx
);
17164 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17165 mips32_op
= OPC_LDR
;
17168 check_insn(ctx
, ISA_MIPS3
);
17169 check_mips_64(ctx
);
17170 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17171 mips32_op
= OPC_SDR
;
17174 check_insn(ctx
, ISA_MIPS3
);
17175 check_mips_64(ctx
);
17176 mips32_op
= OPC_LWU
;
17179 check_insn(ctx
, ISA_MIPS3
);
17180 check_mips_64(ctx
);
17181 mips32_op
= OPC_LLD
;
17185 mips32_op
= OPC_LL
;
17188 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17191 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17194 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17196 #if defined(TARGET_MIPS64)
17198 check_insn(ctx
, ISA_MIPS3
);
17199 check_mips_64(ctx
);
17200 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17205 MIPS_INVAL("pool32c ld-eva");
17206 generate_exception_end(ctx
, EXCP_RI
);
17209 check_cp0_enabled(ctx
);
17211 minor2
= (ctx
->opcode
>> 9) & 0x7;
17212 offset
= sextract32(ctx
->opcode
, 0, 9);
17215 mips32_op
= OPC_LBUE
;
17218 mips32_op
= OPC_LHUE
;
17221 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17222 mips32_op
= OPC_LWLE
;
17225 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17226 mips32_op
= OPC_LWRE
;
17229 mips32_op
= OPC_LBE
;
17232 mips32_op
= OPC_LHE
;
17235 mips32_op
= OPC_LLE
;
17238 mips32_op
= OPC_LWE
;
17244 MIPS_INVAL("pool32c st-eva");
17245 generate_exception_end(ctx
, EXCP_RI
);
17248 check_cp0_enabled(ctx
);
17250 minor2
= (ctx
->opcode
>> 9) & 0x7;
17251 offset
= sextract32(ctx
->opcode
, 0, 9);
17254 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17255 mips32_op
= OPC_SWLE
;
17258 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17259 mips32_op
= OPC_SWRE
;
17262 /* Treat as no-op */
17263 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17264 /* hint codes 24-31 are reserved and signal RI */
17265 generate_exception(ctx
, EXCP_RI
);
17269 /* Treat as no-op */
17270 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17271 gen_cache_operation(ctx
, rt
, rs
, offset
);
17275 mips32_op
= OPC_SBE
;
17278 mips32_op
= OPC_SHE
;
17281 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17284 mips32_op
= OPC_SWE
;
17289 /* Treat as no-op */
17290 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17291 /* hint codes 24-31 are reserved and signal RI */
17292 generate_exception(ctx
, EXCP_RI
);
17296 MIPS_INVAL("pool32c");
17297 generate_exception_end(ctx
, EXCP_RI
);
17301 case ADDI32
: /* AUI, LUI */
17302 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17304 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17307 mips32_op
= OPC_ADDI
;
17312 mips32_op
= OPC_ADDIU
;
17314 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17317 /* Logical operations */
17319 mips32_op
= OPC_ORI
;
17322 mips32_op
= OPC_XORI
;
17325 mips32_op
= OPC_ANDI
;
17327 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17330 /* Set less than immediate */
17332 mips32_op
= OPC_SLTI
;
17335 mips32_op
= OPC_SLTIU
;
17337 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17340 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17341 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17342 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17343 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17345 case JALS32
: /* BOVC, BEQC, BEQZALC */
17346 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17349 mips32_op
= OPC_BOVC
;
17350 } else if (rs
< rt
&& rs
== 0) {
17352 mips32_op
= OPC_BEQZALC
;
17355 mips32_op
= OPC_BEQC
;
17357 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17360 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17361 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17362 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17365 case BEQ32
: /* BC */
17366 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17368 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17369 sextract32(ctx
->opcode
<< 1, 0, 27));
17372 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17375 case BNE32
: /* BALC */
17376 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17378 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17379 sextract32(ctx
->opcode
<< 1, 0, 27));
17382 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17385 case J32
: /* BGTZC, BLTZC, BLTC */
17386 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17387 if (rs
== 0 && rt
!= 0) {
17389 mips32_op
= OPC_BGTZC
;
17390 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17392 mips32_op
= OPC_BLTZC
;
17395 mips32_op
= OPC_BLTC
;
17397 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17400 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17401 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17404 case JAL32
: /* BLEZC, BGEZC, BGEC */
17405 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17406 if (rs
== 0 && rt
!= 0) {
17408 mips32_op
= OPC_BLEZC
;
17409 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17411 mips32_op
= OPC_BGEZC
;
17414 mips32_op
= OPC_BGEC
;
17416 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17419 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17420 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17421 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17424 /* Floating point (COP1) */
17426 mips32_op
= OPC_LWC1
;
17429 mips32_op
= OPC_LDC1
;
17432 mips32_op
= OPC_SWC1
;
17435 mips32_op
= OPC_SDC1
;
17437 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17439 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17440 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17441 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17442 switch ((ctx
->opcode
>> 16) & 0x1f) {
17451 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17454 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17457 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17467 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17470 generate_exception(ctx
, EXCP_RI
);
17475 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17476 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17478 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17481 case BNVC
: /* BNEC, BNEZALC */
17482 check_insn(ctx
, ISA_MIPS32R6
);
17485 mips32_op
= OPC_BNVC
;
17486 } else if (rs
< rt
&& rs
== 0) {
17488 mips32_op
= OPC_BNEZALC
;
17491 mips32_op
= OPC_BNEC
;
17493 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17495 case R6_BNEZC
: /* JIALC */
17496 check_insn(ctx
, ISA_MIPS32R6
);
17499 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17500 sextract32(ctx
->opcode
<< 1, 0, 22));
17503 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17506 case R6_BEQZC
: /* JIC */
17507 check_insn(ctx
, ISA_MIPS32R6
);
17510 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17511 sextract32(ctx
->opcode
<< 1, 0, 22));
17514 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17517 case BLEZALC
: /* BGEZALC, BGEUC */
17518 check_insn(ctx
, ISA_MIPS32R6
);
17519 if (rs
== 0 && rt
!= 0) {
17521 mips32_op
= OPC_BLEZALC
;
17522 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17524 mips32_op
= OPC_BGEZALC
;
17527 mips32_op
= OPC_BGEUC
;
17529 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17531 case BGTZALC
: /* BLTZALC, BLTUC */
17532 check_insn(ctx
, ISA_MIPS32R6
);
17533 if (rs
== 0 && rt
!= 0) {
17535 mips32_op
= OPC_BGTZALC
;
17536 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17538 mips32_op
= OPC_BLTZALC
;
17541 mips32_op
= OPC_BLTUC
;
17543 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17545 /* Loads and stores */
17547 mips32_op
= OPC_LB
;
17550 mips32_op
= OPC_LBU
;
17553 mips32_op
= OPC_LH
;
17556 mips32_op
= OPC_LHU
;
17559 mips32_op
= OPC_LW
;
17561 #ifdef TARGET_MIPS64
17563 check_insn(ctx
, ISA_MIPS3
);
17564 check_mips_64(ctx
);
17565 mips32_op
= OPC_LD
;
17568 check_insn(ctx
, ISA_MIPS3
);
17569 check_mips_64(ctx
);
17570 mips32_op
= OPC_SD
;
17574 mips32_op
= OPC_SB
;
17577 mips32_op
= OPC_SH
;
17580 mips32_op
= OPC_SW
;
17583 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
17586 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
17589 generate_exception_end(ctx
, EXCP_RI
);
17594 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
17598 /* make sure instructions are on a halfword boundary */
17599 if (ctx
->base
.pc_next
& 0x1) {
17600 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
17601 generate_exception_end(ctx
, EXCP_AdEL
);
17605 op
= (ctx
->opcode
>> 10) & 0x3f;
17606 /* Enforce properly-sized instructions in a delay slot */
17607 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
17608 switch (op
& 0x7) { /* MSB-3..MSB-5 */
17610 /* POOL32A, POOL32B, POOL32I, POOL32C */
17612 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17614 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17616 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17618 /* LB32, LH32, LWC132, LDC132, LW32 */
17619 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
17620 generate_exception_end(ctx
, EXCP_RI
);
17625 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17627 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17629 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17630 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
17631 generate_exception_end(ctx
, EXCP_RI
);
17641 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17642 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
17643 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
17646 switch (ctx
->opcode
& 0x1) {
17654 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17656 * In the Release 6, the register number location in
17657 * the instruction encoding has changed.
17659 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
17661 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
17667 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17668 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
17669 int amount
= (ctx
->opcode
>> 1) & 0x7;
17671 amount
= amount
== 0 ? 8 : amount
;
17673 switch (ctx
->opcode
& 0x1) {
17682 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
17686 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17687 gen_pool16c_r6_insn(ctx
);
17689 gen_pool16c_insn(ctx
);
17694 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17695 int rb
= 28; /* GP */
17696 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
17698 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17702 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17703 if (ctx
->opcode
& 1) {
17704 generate_exception_end(ctx
, EXCP_RI
);
17707 int enc_dest
= uMIPS_RD(ctx
->opcode
);
17708 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
17709 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
17710 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
17715 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17716 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17717 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17718 offset
= (offset
== 0xf ? -1 : offset
);
17720 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
17725 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17726 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17727 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17729 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
17734 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17735 int rb
= 29; /* SP */
17736 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17738 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17743 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17744 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17745 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17747 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17752 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17753 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17754 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17756 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
17761 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17762 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17763 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17765 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
17770 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17771 int rb
= 29; /* SP */
17772 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17774 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17779 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17780 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17781 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17783 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17788 int rd
= uMIPS_RD5(ctx
->opcode
);
17789 int rs
= uMIPS_RS5(ctx
->opcode
);
17791 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
17798 switch (ctx
->opcode
& 0x1) {
17808 switch (ctx
->opcode
& 0x1) {
17813 gen_addiur1sp(ctx
);
17817 case B16
: /* BC16 */
17818 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
17819 sextract32(ctx
->opcode
, 0, 10) << 1,
17820 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
17822 case BNEZ16
: /* BNEZC16 */
17823 case BEQZ16
: /* BEQZC16 */
17824 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
17825 mmreg(uMIPS_RD(ctx
->opcode
)),
17826 0, sextract32(ctx
->opcode
, 0, 7) << 1,
17827 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
17832 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
17833 int imm
= ZIMM(ctx
->opcode
, 0, 7);
17835 imm
= (imm
== 0x7f ? -1 : imm
);
17836 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
17842 generate_exception_end(ctx
, EXCP_RI
);
17845 decode_micromips32_opc(env
, ctx
);
17858 /* MAJOR, P16, and P32 pools opcodes */
17862 NM_MOVE_BALC
= 0x02,
17870 NM_P16_SHIFT
= 0x0c,
17888 NM_P_LS_U12
= 0x21,
17898 NM_P16_ADDU
= 0x2c,
17912 NM_MOVEPREV
= 0x3f,
17915 /* POOL32A instruction pool */
17917 NM_POOL32A0
= 0x00,
17918 NM_SPECIAL2
= 0x01,
17921 NM_POOL32A5
= 0x05,
17922 NM_POOL32A7
= 0x07,
17925 /* P.GP.W instruction pool */
17927 NM_ADDIUGP_W
= 0x00,
17932 /* P48I instruction pool */
17936 NM_ADDIUGP48
= 0x02,
17937 NM_ADDIUPC48
= 0x03,
17942 /* P.U12 instruction pool */
17951 NM_ADDIUNEG
= 0x08,
17958 /* POOL32F instruction pool */
17960 NM_POOL32F_0
= 0x00,
17961 NM_POOL32F_3
= 0x03,
17962 NM_POOL32F_5
= 0x05,
17965 /* POOL32S instruction pool */
17967 NM_POOL32S_0
= 0x00,
17968 NM_POOL32S_4
= 0x04,
17971 /* P.LUI instruction pool */
17977 /* P.GP.BH instruction pool */
17982 NM_ADDIUGP_B
= 0x03,
17985 NM_P_GP_CP1
= 0x06,
17988 /* P.LS.U12 instruction pool */
17993 NM_P_PREFU12
= 0x03,
18006 /* P.LS.S9 instruction pool */
18012 NM_P_LS_UAWM
= 0x05,
18015 /* P.BAL instruction pool */
18021 /* P.J instruction pool */
18024 NM_JALRC_HB
= 0x01,
18025 NM_P_BALRSC
= 0x08,
18028 /* P.BR1 instruction pool */
18036 /* P.BR2 instruction pool */
18043 /* P.BRI instruction pool */
18055 /* P16.SHIFT instruction pool */
18061 /* POOL16C instruction pool */
18063 NM_POOL16C_0
= 0x00,
18067 /* P16.A1 instruction pool */
18069 NM_ADDIUR1SP
= 0x01,
18072 /* P16.A2 instruction pool */
18075 NM_P_ADDIURS5
= 0x01,
18078 /* P16.ADDU instruction pool */
18084 /* P16.SR instruction pool */
18087 NM_RESTORE_JRC16
= 0x01,
18090 /* P16.4X4 instruction pool */
18096 /* P16.LB instruction pool */
18103 /* P16.LH instruction pool */
18110 /* P.RI instruction pool */
18113 NM_P_SYSCALL
= 0x01,
18118 /* POOL32A0 instruction pool */
18153 NM_D_E_MT_VPE
= 0x56,
18161 /* CRC32 instruction pool */
18171 /* POOL32A5 instruction pool */
18173 NM_CMP_EQ_PH
= 0x00,
18174 NM_CMP_LT_PH
= 0x08,
18175 NM_CMP_LE_PH
= 0x10,
18176 NM_CMPGU_EQ_QB
= 0x18,
18177 NM_CMPGU_LT_QB
= 0x20,
18178 NM_CMPGU_LE_QB
= 0x28,
18179 NM_CMPGDU_EQ_QB
= 0x30,
18180 NM_CMPGDU_LT_QB
= 0x38,
18181 NM_CMPGDU_LE_QB
= 0x40,
18182 NM_CMPU_EQ_QB
= 0x48,
18183 NM_CMPU_LT_QB
= 0x50,
18184 NM_CMPU_LE_QB
= 0x58,
18185 NM_ADDQ_S_W
= 0x60,
18186 NM_SUBQ_S_W
= 0x68,
18190 NM_ADDQ_S_PH
= 0x01,
18191 NM_ADDQH_R_PH
= 0x09,
18192 NM_ADDQH_R_W
= 0x11,
18193 NM_ADDU_S_QB
= 0x19,
18194 NM_ADDU_S_PH
= 0x21,
18195 NM_ADDUH_R_QB
= 0x29,
18196 NM_SHRAV_R_PH
= 0x31,
18197 NM_SHRAV_R_QB
= 0x39,
18198 NM_SUBQ_S_PH
= 0x41,
18199 NM_SUBQH_R_PH
= 0x49,
18200 NM_SUBQH_R_W
= 0x51,
18201 NM_SUBU_S_QB
= 0x59,
18202 NM_SUBU_S_PH
= 0x61,
18203 NM_SUBUH_R_QB
= 0x69,
18204 NM_SHLLV_S_PH
= 0x71,
18205 NM_PRECR_SRA_R_PH_W
= 0x79,
18207 NM_MULEU_S_PH_QBL
= 0x12,
18208 NM_MULEU_S_PH_QBR
= 0x1a,
18209 NM_MULQ_RS_PH
= 0x22,
18210 NM_MULQ_S_PH
= 0x2a,
18211 NM_MULQ_RS_W
= 0x32,
18212 NM_MULQ_S_W
= 0x3a,
18215 NM_SHRAV_R_W
= 0x5a,
18216 NM_SHRLV_PH
= 0x62,
18217 NM_SHRLV_QB
= 0x6a,
18218 NM_SHLLV_QB
= 0x72,
18219 NM_SHLLV_S_W
= 0x7a,
18223 NM_MULEQ_S_W_PHL
= 0x04,
18224 NM_MULEQ_S_W_PHR
= 0x0c,
18226 NM_MUL_S_PH
= 0x05,
18227 NM_PRECR_QB_PH
= 0x0d,
18228 NM_PRECRQ_QB_PH
= 0x15,
18229 NM_PRECRQ_PH_W
= 0x1d,
18230 NM_PRECRQ_RS_PH_W
= 0x25,
18231 NM_PRECRQU_S_QB_PH
= 0x2d,
18232 NM_PACKRL_PH
= 0x35,
18236 NM_SHRA_R_W
= 0x5e,
18237 NM_SHRA_R_PH
= 0x66,
18238 NM_SHLL_S_PH
= 0x76,
18239 NM_SHLL_S_W
= 0x7e,
18244 /* POOL32A7 instruction pool */
18249 NM_POOL32AXF
= 0x07,
18252 /* P.SR instruction pool */
18258 /* P.SHIFT instruction pool */
18266 /* P.ROTX instruction pool */
18271 /* P.INS instruction pool */
18276 /* P.EXT instruction pool */
18281 /* POOL32F_0 (fmt) instruction pool */
18286 NM_SELEQZ_S
= 0x07,
18287 NM_SELEQZ_D
= 0x47,
18291 NM_SELNEZ_S
= 0x0f,
18292 NM_SELNEZ_D
= 0x4f,
18307 /* POOL32F_3 instruction pool */
18311 NM_MINA_FMT
= 0x04,
18312 NM_MAXA_FMT
= 0x05,
18313 NM_POOL32FXF
= 0x07,
18316 /* POOL32F_5 instruction pool */
18318 NM_CMP_CONDN_S
= 0x00,
18319 NM_CMP_CONDN_D
= 0x02,
18322 /* P.GP.LH instruction pool */
18328 /* P.GP.SH instruction pool */
18333 /* P.GP.CP1 instruction pool */
18341 /* P.LS.S0 instruction pool */
18358 NM_P_PREFS9
= 0x03,
18364 /* P.LS.S1 instruction pool */
18366 NM_ASET_ACLR
= 0x02,
18374 /* P.LS.E0 instruction pool */
18390 /* P.PREFE instruction pool */
18396 /* P.LLE instruction pool */
18402 /* P.SCE instruction pool */
18408 /* P.LS.WM instruction pool */
18414 /* P.LS.UAWM instruction pool */
18420 /* P.BR3A instruction pool */
18426 NM_BPOSGE32C
= 0x04,
18429 /* P16.RI instruction pool */
18431 NM_P16_SYSCALL
= 0x01,
18436 /* POOL16C_0 instruction pool */
18438 NM_POOL16C_00
= 0x00,
18441 /* P16.JRC instruction pool */
18447 /* P.SYSCALL instruction pool */
18453 /* P.TRAP instruction pool */
18459 /* P.CMOVE instruction pool */
18465 /* POOL32Axf instruction pool */
18467 NM_POOL32AXF_1
= 0x01,
18468 NM_POOL32AXF_2
= 0x02,
18469 NM_POOL32AXF_4
= 0x04,
18470 NM_POOL32AXF_5
= 0x05,
18471 NM_POOL32AXF_7
= 0x07,
18474 /* POOL32Axf_1 instruction pool */
18476 NM_POOL32AXF_1_0
= 0x00,
18477 NM_POOL32AXF_1_1
= 0x01,
18478 NM_POOL32AXF_1_3
= 0x03,
18479 NM_POOL32AXF_1_4
= 0x04,
18480 NM_POOL32AXF_1_5
= 0x05,
18481 NM_POOL32AXF_1_7
= 0x07,
18484 /* POOL32Axf_2 instruction pool */
18486 NM_POOL32AXF_2_0_7
= 0x00,
18487 NM_POOL32AXF_2_8_15
= 0x01,
18488 NM_POOL32AXF_2_16_23
= 0x02,
18489 NM_POOL32AXF_2_24_31
= 0x03,
18492 /* POOL32Axf_7 instruction pool */
18494 NM_SHRA_R_QB
= 0x0,
18499 /* POOL32Axf_1_0 instruction pool */
18507 /* POOL32Axf_1_1 instruction pool */
18513 /* POOL32Axf_1_3 instruction pool */
18521 /* POOL32Axf_1_4 instruction pool */
18527 /* POOL32Axf_1_5 instruction pool */
18529 NM_MAQ_S_W_PHR
= 0x0,
18530 NM_MAQ_S_W_PHL
= 0x1,
18531 NM_MAQ_SA_W_PHR
= 0x2,
18532 NM_MAQ_SA_W_PHL
= 0x3,
18535 /* POOL32Axf_1_7 instruction pool */
18539 NM_EXTR_RS_W
= 0x2,
18543 /* POOL32Axf_2_0_7 instruction pool */
18546 NM_DPAQ_S_W_PH
= 0x1,
18548 NM_DPSQ_S_W_PH
= 0x3,
18555 /* POOL32Axf_2_8_15 instruction pool */
18557 NM_DPAX_W_PH
= 0x0,
18558 NM_DPAQ_SA_L_W
= 0x1,
18559 NM_DPSX_W_PH
= 0x2,
18560 NM_DPSQ_SA_L_W
= 0x3,
18563 NM_EXTRV_R_W
= 0x7,
18566 /* POOL32Axf_2_16_23 instruction pool */
18568 NM_DPAU_H_QBL
= 0x0,
18569 NM_DPAQX_S_W_PH
= 0x1,
18570 NM_DPSU_H_QBL
= 0x2,
18571 NM_DPSQX_S_W_PH
= 0x3,
18574 NM_MULSA_W_PH
= 0x6,
18575 NM_EXTRV_RS_W
= 0x7,
18578 /* POOL32Axf_2_24_31 instruction pool */
18580 NM_DPAU_H_QBR
= 0x0,
18581 NM_DPAQX_SA_W_PH
= 0x1,
18582 NM_DPSU_H_QBR
= 0x2,
18583 NM_DPSQX_SA_W_PH
= 0x3,
18586 NM_MULSAQ_S_W_PH
= 0x6,
18587 NM_EXTRV_S_H
= 0x7,
18590 /* POOL32Axf_{4, 5} instruction pool */
18609 /* nanoMIPS DSP instructions */
18610 NM_ABSQ_S_QB
= 0x00,
18611 NM_ABSQ_S_PH
= 0x08,
18612 NM_ABSQ_S_W
= 0x10,
18613 NM_PRECEQ_W_PHL
= 0x28,
18614 NM_PRECEQ_W_PHR
= 0x30,
18615 NM_PRECEQU_PH_QBL
= 0x38,
18616 NM_PRECEQU_PH_QBR
= 0x48,
18617 NM_PRECEU_PH_QBL
= 0x58,
18618 NM_PRECEU_PH_QBR
= 0x68,
18619 NM_PRECEQU_PH_QBLA
= 0x39,
18620 NM_PRECEQU_PH_QBRA
= 0x49,
18621 NM_PRECEU_PH_QBLA
= 0x59,
18622 NM_PRECEU_PH_QBRA
= 0x69,
18623 NM_REPLV_PH
= 0x01,
18624 NM_REPLV_QB
= 0x09,
18627 NM_RADDU_W_QB
= 0x78,
18633 /* PP.SR instruction pool */
18637 NM_RESTORE_JRC
= 0x03,
18640 /* P.SR.F instruction pool */
18643 NM_RESTOREF
= 0x01,
18646 /* P16.SYSCALL instruction pool */
18648 NM_SYSCALL16
= 0x00,
18649 NM_HYPCALL16
= 0x01,
18652 /* POOL16C_00 instruction pool */
18660 /* PP.LSX and PP.LSXS instruction pool */
18698 /* ERETx instruction pool */
18704 /* POOL32FxF_{0, 1} insturction pool */
18713 NM_CVT_S_PL
= 0x84,
18714 NM_CVT_S_PU
= 0xa4,
18716 NM_CVT_L_S
= 0x004,
18717 NM_CVT_L_D
= 0x104,
18718 NM_CVT_W_S
= 0x024,
18719 NM_CVT_W_D
= 0x124,
18721 NM_RSQRT_S
= 0x008,
18722 NM_RSQRT_D
= 0x108,
18727 NM_RECIP_S
= 0x048,
18728 NM_RECIP_D
= 0x148,
18730 NM_FLOOR_L_S
= 0x00c,
18731 NM_FLOOR_L_D
= 0x10c,
18733 NM_FLOOR_W_S
= 0x02c,
18734 NM_FLOOR_W_D
= 0x12c,
18736 NM_CEIL_L_S
= 0x04c,
18737 NM_CEIL_L_D
= 0x14c,
18738 NM_CEIL_W_S
= 0x06c,
18739 NM_CEIL_W_D
= 0x16c,
18740 NM_TRUNC_L_S
= 0x08c,
18741 NM_TRUNC_L_D
= 0x18c,
18742 NM_TRUNC_W_S
= 0x0ac,
18743 NM_TRUNC_W_D
= 0x1ac,
18744 NM_ROUND_L_S
= 0x0cc,
18745 NM_ROUND_L_D
= 0x1cc,
18746 NM_ROUND_W_S
= 0x0ec,
18747 NM_ROUND_W_D
= 0x1ec,
18755 NM_CVT_D_S
= 0x04d,
18756 NM_CVT_D_W
= 0x0cd,
18757 NM_CVT_D_L
= 0x14d,
18758 NM_CVT_S_D
= 0x06d,
18759 NM_CVT_S_W
= 0x0ed,
18760 NM_CVT_S_L
= 0x16d,
18763 /* P.LL instruction pool */
18769 /* P.SC instruction pool */
18775 /* P.DVP instruction pool */
18784 * nanoMIPS decoding engine
18789 /* extraction utilities */
18791 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18792 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18793 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18794 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18795 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18797 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18798 static inline int decode_gpr_gpr3(int r
)
18800 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18802 return map
[r
& 0x7];
18805 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18806 static inline int decode_gpr_gpr3_src_store(int r
)
18808 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18810 return map
[r
& 0x7];
18813 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18814 static inline int decode_gpr_gpr4(int r
)
18816 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18817 16, 17, 18, 19, 20, 21, 22, 23 };
18819 return map
[r
& 0xf];
18822 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18823 static inline int decode_gpr_gpr4_zero(int r
)
18825 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18826 16, 17, 18, 19, 20, 21, 22, 23 };
18828 return map
[r
& 0xf];
18832 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
18834 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
18837 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18838 uint8_t gp
, uint16_t u
)
18841 TCGv va
= tcg_temp_new();
18842 TCGv t0
= tcg_temp_new();
18844 while (counter
!= count
) {
18845 bool use_gp
= gp
&& (counter
== count
- 1);
18846 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18847 int this_offset
= -((counter
+ 1) << 2);
18848 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18849 gen_load_gpr(t0
, this_rt
);
18850 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
18851 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
18855 /* adjust stack pointer */
18856 gen_adjust_sp(ctx
, -u
);
18862 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18863 uint8_t gp
, uint16_t u
)
18866 TCGv va
= tcg_temp_new();
18867 TCGv t0
= tcg_temp_new();
18869 while (counter
!= count
) {
18870 bool use_gp
= gp
&& (counter
== count
- 1);
18871 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18872 int this_offset
= u
- ((counter
+ 1) << 2);
18873 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18874 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
18875 ctx
->default_tcg_memop_mask
);
18876 tcg_gen_ext32s_tl(t0
, t0
);
18877 gen_store_gpr(t0
, this_rt
);
18881 /* adjust stack pointer */
18882 gen_adjust_sp(ctx
, u
);
18888 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
18890 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
18891 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
18893 switch (extract32(ctx
->opcode
, 2, 2)) {
18895 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
18898 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
18901 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
18904 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
18909 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18911 int rt
= extract32(ctx
->opcode
, 21, 5);
18912 int rs
= extract32(ctx
->opcode
, 16, 5);
18913 int rd
= extract32(ctx
->opcode
, 11, 5);
18915 switch (extract32(ctx
->opcode
, 3, 7)) {
18917 switch (extract32(ctx
->opcode
, 10, 1)) {
18920 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
18924 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
18930 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
18934 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
18937 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
18940 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
18943 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
18946 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
18949 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
18952 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
18955 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
18959 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
18962 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
18965 switch (extract32(ctx
->opcode
, 10, 1)) {
18967 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
18970 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
18975 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
18978 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
18981 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
18984 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
18987 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
18992 #ifndef CONFIG_USER_ONLY
18993 TCGv t0
= tcg_temp_new();
18994 switch (extract32(ctx
->opcode
, 10, 1)) {
18997 check_cp0_enabled(ctx
);
18998 gen_helper_dvp(t0
, cpu_env
);
18999 gen_store_gpr(t0
, rt
);
19004 check_cp0_enabled(ctx
);
19005 gen_helper_evp(t0
, cpu_env
);
19006 gen_store_gpr(t0
, rt
);
19013 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
19018 TCGv t0
= tcg_temp_new();
19019 TCGv t1
= tcg_temp_new();
19020 TCGv t2
= tcg_temp_new();
19022 gen_load_gpr(t1
, rs
);
19023 gen_load_gpr(t2
, rt
);
19024 tcg_gen_add_tl(t0
, t1
, t2
);
19025 tcg_gen_ext32s_tl(t0
, t0
);
19026 tcg_gen_xor_tl(t1
, t1
, t2
);
19027 tcg_gen_xor_tl(t2
, t0
, t2
);
19028 tcg_gen_andc_tl(t1
, t2
, t1
);
19030 /* operands of same sign, result different sign */
19031 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
19032 gen_store_gpr(t0
, rd
);
19040 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
19043 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
19046 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
19049 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
19052 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
19055 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
19058 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
19061 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
19063 #ifndef CONFIG_USER_ONLY
19065 check_cp0_enabled(ctx
);
19067 /* Treat as NOP. */
19070 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
19073 check_cp0_enabled(ctx
);
19075 TCGv t0
= tcg_temp_new();
19077 gen_load_gpr(t0
, rt
);
19078 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
19082 case NM_D_E_MT_VPE
:
19084 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
19085 TCGv t0
= tcg_temp_new();
19092 gen_helper_dmt(t0
);
19093 gen_store_gpr(t0
, rt
);
19094 } else if (rs
== 0) {
19097 gen_helper_dvpe(t0
, cpu_env
);
19098 gen_store_gpr(t0
, rt
);
19100 generate_exception_end(ctx
, EXCP_RI
);
19107 gen_helper_emt(t0
);
19108 gen_store_gpr(t0
, rt
);
19109 } else if (rs
== 0) {
19112 gen_helper_evpe(t0
, cpu_env
);
19113 gen_store_gpr(t0
, rt
);
19115 generate_exception_end(ctx
, EXCP_RI
);
19126 TCGv t0
= tcg_temp_new();
19127 TCGv t1
= tcg_temp_new();
19129 gen_load_gpr(t0
, rt
);
19130 gen_load_gpr(t1
, rs
);
19131 gen_helper_fork(t0
, t1
);
19138 check_cp0_enabled(ctx
);
19140 /* Treat as NOP. */
19143 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19144 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19148 check_cp0_enabled(ctx
);
19149 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19150 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19155 TCGv t0
= tcg_temp_new();
19157 gen_load_gpr(t0
, rs
);
19158 gen_helper_yield(t0
, cpu_env
, t0
);
19159 gen_store_gpr(t0
, rt
);
19165 generate_exception_end(ctx
, EXCP_RI
);
19171 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19172 int ret
, int v1
, int v2
)
19178 t0
= tcg_temp_new_i32();
19180 v0_t
= tcg_temp_new();
19181 v1_t
= tcg_temp_new();
19183 tcg_gen_movi_i32(t0
, v2
>> 3);
19185 gen_load_gpr(v0_t
, ret
);
19186 gen_load_gpr(v1_t
, v1
);
19189 case NM_MAQ_S_W_PHR
:
19191 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19193 case NM_MAQ_S_W_PHL
:
19195 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19197 case NM_MAQ_SA_W_PHR
:
19199 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19201 case NM_MAQ_SA_W_PHL
:
19203 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19206 generate_exception_end(ctx
, EXCP_RI
);
19210 tcg_temp_free_i32(t0
);
19212 tcg_temp_free(v0_t
);
19213 tcg_temp_free(v1_t
);
19217 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19218 int ret
, int v1
, int v2
)
19221 TCGv t0
= tcg_temp_new();
19222 TCGv t1
= tcg_temp_new();
19223 TCGv v0_t
= tcg_temp_new();
19225 gen_load_gpr(v0_t
, v1
);
19228 case NM_POOL32AXF_1_0
:
19230 switch (extract32(ctx
->opcode
, 12, 2)) {
19232 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19235 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19238 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19241 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19245 case NM_POOL32AXF_1_1
:
19247 switch (extract32(ctx
->opcode
, 12, 2)) {
19249 tcg_gen_movi_tl(t0
, v2
);
19250 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19253 tcg_gen_movi_tl(t0
, v2
>> 3);
19254 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19257 generate_exception_end(ctx
, EXCP_RI
);
19261 case NM_POOL32AXF_1_3
:
19263 imm
= extract32(ctx
->opcode
, 14, 7);
19264 switch (extract32(ctx
->opcode
, 12, 2)) {
19266 tcg_gen_movi_tl(t0
, imm
);
19267 gen_helper_rddsp(t0
, t0
, cpu_env
);
19268 gen_store_gpr(t0
, ret
);
19271 gen_load_gpr(t0
, ret
);
19272 tcg_gen_movi_tl(t1
, imm
);
19273 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19276 tcg_gen_movi_tl(t0
, v2
>> 3);
19277 tcg_gen_movi_tl(t1
, v1
);
19278 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19279 gen_store_gpr(t0
, ret
);
19282 tcg_gen_movi_tl(t0
, v2
>> 3);
19283 tcg_gen_movi_tl(t1
, v1
);
19284 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19285 gen_store_gpr(t0
, ret
);
19289 case NM_POOL32AXF_1_4
:
19291 tcg_gen_movi_tl(t0
, v2
>> 2);
19292 switch (extract32(ctx
->opcode
, 12, 1)) {
19294 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19295 gen_store_gpr(t0
, ret
);
19298 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19299 gen_store_gpr(t0
, ret
);
19303 case NM_POOL32AXF_1_5
:
19304 opc
= extract32(ctx
->opcode
, 12, 2);
19305 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19307 case NM_POOL32AXF_1_7
:
19309 tcg_gen_movi_tl(t0
, v2
>> 3);
19310 tcg_gen_movi_tl(t1
, v1
);
19311 switch (extract32(ctx
->opcode
, 12, 2)) {
19313 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19314 gen_store_gpr(t0
, ret
);
19317 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19318 gen_store_gpr(t0
, ret
);
19321 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19322 gen_store_gpr(t0
, ret
);
19325 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19326 gen_store_gpr(t0
, ret
);
19331 generate_exception_end(ctx
, EXCP_RI
);
19337 tcg_temp_free(v0_t
);
19340 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19341 TCGv v0
, TCGv v1
, int rd
)
19345 t0
= tcg_temp_new_i32();
19347 tcg_gen_movi_i32(t0
, rd
>> 3);
19350 case NM_POOL32AXF_2_0_7
:
19351 switch (extract32(ctx
->opcode
, 9, 3)) {
19354 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19356 case NM_DPAQ_S_W_PH
:
19358 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19362 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19364 case NM_DPSQ_S_W_PH
:
19366 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19369 generate_exception_end(ctx
, EXCP_RI
);
19373 case NM_POOL32AXF_2_8_15
:
19374 switch (extract32(ctx
->opcode
, 9, 3)) {
19377 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19379 case NM_DPAQ_SA_L_W
:
19381 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19385 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19387 case NM_DPSQ_SA_L_W
:
19389 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19392 generate_exception_end(ctx
, EXCP_RI
);
19396 case NM_POOL32AXF_2_16_23
:
19397 switch (extract32(ctx
->opcode
, 9, 3)) {
19398 case NM_DPAU_H_QBL
:
19400 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19402 case NM_DPAQX_S_W_PH
:
19404 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19406 case NM_DPSU_H_QBL
:
19408 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19410 case NM_DPSQX_S_W_PH
:
19412 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19414 case NM_MULSA_W_PH
:
19416 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19419 generate_exception_end(ctx
, EXCP_RI
);
19423 case NM_POOL32AXF_2_24_31
:
19424 switch (extract32(ctx
->opcode
, 9, 3)) {
19425 case NM_DPAU_H_QBR
:
19427 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19429 case NM_DPAQX_SA_W_PH
:
19431 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19433 case NM_DPSU_H_QBR
:
19435 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19437 case NM_DPSQX_SA_W_PH
:
19439 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19441 case NM_MULSAQ_S_W_PH
:
19443 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19446 generate_exception_end(ctx
, EXCP_RI
);
19451 generate_exception_end(ctx
, EXCP_RI
);
19455 tcg_temp_free_i32(t0
);
19458 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19459 int rt
, int rs
, int rd
)
19462 TCGv t0
= tcg_temp_new();
19463 TCGv t1
= tcg_temp_new();
19464 TCGv v0_t
= tcg_temp_new();
19465 TCGv v1_t
= tcg_temp_new();
19467 gen_load_gpr(v0_t
, rt
);
19468 gen_load_gpr(v1_t
, rs
);
19471 case NM_POOL32AXF_2_0_7
:
19472 switch (extract32(ctx
->opcode
, 9, 3)) {
19474 case NM_DPAQ_S_W_PH
:
19476 case NM_DPSQ_S_W_PH
:
19477 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19482 gen_load_gpr(t0
, rs
);
19484 if (rd
!= 0 && rd
!= 2) {
19485 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19486 tcg_gen_ext32u_tl(t0
, t0
);
19487 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19488 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19490 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19496 int acc
= extract32(ctx
->opcode
, 14, 2);
19497 TCGv_i64 t2
= tcg_temp_new_i64();
19498 TCGv_i64 t3
= tcg_temp_new_i64();
19500 gen_load_gpr(t0
, rt
);
19501 gen_load_gpr(t1
, rs
);
19502 tcg_gen_ext_tl_i64(t2
, t0
);
19503 tcg_gen_ext_tl_i64(t3
, t1
);
19504 tcg_gen_mul_i64(t2
, t2
, t3
);
19505 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19506 tcg_gen_add_i64(t2
, t2
, t3
);
19507 tcg_temp_free_i64(t3
);
19508 gen_move_low32(cpu_LO
[acc
], t2
);
19509 gen_move_high32(cpu_HI
[acc
], t2
);
19510 tcg_temp_free_i64(t2
);
19516 int acc
= extract32(ctx
->opcode
, 14, 2);
19517 TCGv_i32 t2
= tcg_temp_new_i32();
19518 TCGv_i32 t3
= tcg_temp_new_i32();
19520 gen_load_gpr(t0
, rs
);
19521 gen_load_gpr(t1
, rt
);
19522 tcg_gen_trunc_tl_i32(t2
, t0
);
19523 tcg_gen_trunc_tl_i32(t3
, t1
);
19524 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19525 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19526 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19527 tcg_temp_free_i32(t2
);
19528 tcg_temp_free_i32(t3
);
19533 gen_load_gpr(v1_t
, rs
);
19534 tcg_gen_movi_tl(t0
, rd
>> 3);
19535 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19536 gen_store_gpr(t0
, ret
);
19540 case NM_POOL32AXF_2_8_15
:
19541 switch (extract32(ctx
->opcode
, 9, 3)) {
19543 case NM_DPAQ_SA_L_W
:
19545 case NM_DPSQ_SA_L_W
:
19546 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19551 int acc
= extract32(ctx
->opcode
, 14, 2);
19552 TCGv_i64 t2
= tcg_temp_new_i64();
19553 TCGv_i64 t3
= tcg_temp_new_i64();
19555 gen_load_gpr(t0
, rs
);
19556 gen_load_gpr(t1
, rt
);
19557 tcg_gen_ext32u_tl(t0
, t0
);
19558 tcg_gen_ext32u_tl(t1
, t1
);
19559 tcg_gen_extu_tl_i64(t2
, t0
);
19560 tcg_gen_extu_tl_i64(t3
, t1
);
19561 tcg_gen_mul_i64(t2
, t2
, t3
);
19562 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19563 tcg_gen_add_i64(t2
, t2
, t3
);
19564 tcg_temp_free_i64(t3
);
19565 gen_move_low32(cpu_LO
[acc
], t2
);
19566 gen_move_high32(cpu_HI
[acc
], t2
);
19567 tcg_temp_free_i64(t2
);
19573 int acc
= extract32(ctx
->opcode
, 14, 2);
19574 TCGv_i32 t2
= tcg_temp_new_i32();
19575 TCGv_i32 t3
= tcg_temp_new_i32();
19577 gen_load_gpr(t0
, rs
);
19578 gen_load_gpr(t1
, rt
);
19579 tcg_gen_trunc_tl_i32(t2
, t0
);
19580 tcg_gen_trunc_tl_i32(t3
, t1
);
19581 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
19582 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19583 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19584 tcg_temp_free_i32(t2
);
19585 tcg_temp_free_i32(t3
);
19590 tcg_gen_movi_tl(t0
, rd
>> 3);
19591 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
19592 gen_store_gpr(t0
, ret
);
19595 generate_exception_end(ctx
, EXCP_RI
);
19599 case NM_POOL32AXF_2_16_23
:
19600 switch (extract32(ctx
->opcode
, 9, 3)) {
19601 case NM_DPAU_H_QBL
:
19602 case NM_DPAQX_S_W_PH
:
19603 case NM_DPSU_H_QBL
:
19604 case NM_DPSQX_S_W_PH
:
19605 case NM_MULSA_W_PH
:
19606 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19610 tcg_gen_movi_tl(t0
, rd
>> 3);
19611 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
19612 gen_store_gpr(t0
, ret
);
19617 int acc
= extract32(ctx
->opcode
, 14, 2);
19618 TCGv_i64 t2
= tcg_temp_new_i64();
19619 TCGv_i64 t3
= tcg_temp_new_i64();
19621 gen_load_gpr(t0
, rs
);
19622 gen_load_gpr(t1
, rt
);
19623 tcg_gen_ext_tl_i64(t2
, t0
);
19624 tcg_gen_ext_tl_i64(t3
, t1
);
19625 tcg_gen_mul_i64(t2
, t2
, t3
);
19626 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19627 tcg_gen_sub_i64(t2
, t3
, t2
);
19628 tcg_temp_free_i64(t3
);
19629 gen_move_low32(cpu_LO
[acc
], t2
);
19630 gen_move_high32(cpu_HI
[acc
], t2
);
19631 tcg_temp_free_i64(t2
);
19634 case NM_EXTRV_RS_W
:
19636 tcg_gen_movi_tl(t0
, rd
>> 3);
19637 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
19638 gen_store_gpr(t0
, ret
);
19642 case NM_POOL32AXF_2_24_31
:
19643 switch (extract32(ctx
->opcode
, 9, 3)) {
19644 case NM_DPAU_H_QBR
:
19645 case NM_DPAQX_SA_W_PH
:
19646 case NM_DPSU_H_QBR
:
19647 case NM_DPSQX_SA_W_PH
:
19648 case NM_MULSAQ_S_W_PH
:
19649 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19653 tcg_gen_movi_tl(t0
, rd
>> 3);
19654 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
19655 gen_store_gpr(t0
, ret
);
19660 int acc
= extract32(ctx
->opcode
, 14, 2);
19661 TCGv_i64 t2
= tcg_temp_new_i64();
19662 TCGv_i64 t3
= tcg_temp_new_i64();
19664 gen_load_gpr(t0
, rs
);
19665 gen_load_gpr(t1
, rt
);
19666 tcg_gen_ext32u_tl(t0
, t0
);
19667 tcg_gen_ext32u_tl(t1
, t1
);
19668 tcg_gen_extu_tl_i64(t2
, t0
);
19669 tcg_gen_extu_tl_i64(t3
, t1
);
19670 tcg_gen_mul_i64(t2
, t2
, t3
);
19671 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19672 tcg_gen_sub_i64(t2
, t3
, t2
);
19673 tcg_temp_free_i64(t3
);
19674 gen_move_low32(cpu_LO
[acc
], t2
);
19675 gen_move_high32(cpu_HI
[acc
], t2
);
19676 tcg_temp_free_i64(t2
);
19681 tcg_gen_movi_tl(t0
, rd
>> 3);
19682 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
19683 gen_store_gpr(t0
, ret
);
19688 generate_exception_end(ctx
, EXCP_RI
);
19695 tcg_temp_free(v0_t
);
19696 tcg_temp_free(v1_t
);
19699 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19703 TCGv t0
= tcg_temp_new();
19704 TCGv v0_t
= tcg_temp_new();
19706 gen_load_gpr(v0_t
, rs
);
19711 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
19712 gen_store_gpr(v0_t
, ret
);
19716 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
19717 gen_store_gpr(v0_t
, ret
);
19721 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
19722 gen_store_gpr(v0_t
, ret
);
19724 case NM_PRECEQ_W_PHL
:
19726 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
19727 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19728 gen_store_gpr(v0_t
, ret
);
19730 case NM_PRECEQ_W_PHR
:
19732 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
19733 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
19734 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19735 gen_store_gpr(v0_t
, ret
);
19737 case NM_PRECEQU_PH_QBL
:
19739 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
19740 gen_store_gpr(v0_t
, ret
);
19742 case NM_PRECEQU_PH_QBR
:
19744 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
19745 gen_store_gpr(v0_t
, ret
);
19747 case NM_PRECEQU_PH_QBLA
:
19749 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
19750 gen_store_gpr(v0_t
, ret
);
19752 case NM_PRECEQU_PH_QBRA
:
19754 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
19755 gen_store_gpr(v0_t
, ret
);
19757 case NM_PRECEU_PH_QBL
:
19759 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
19760 gen_store_gpr(v0_t
, ret
);
19762 case NM_PRECEU_PH_QBR
:
19764 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
19765 gen_store_gpr(v0_t
, ret
);
19767 case NM_PRECEU_PH_QBLA
:
19769 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
19770 gen_store_gpr(v0_t
, ret
);
19772 case NM_PRECEU_PH_QBRA
:
19774 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
19775 gen_store_gpr(v0_t
, ret
);
19779 tcg_gen_ext16u_tl(v0_t
, v0_t
);
19780 tcg_gen_shli_tl(t0
, v0_t
, 16);
19781 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19782 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19783 gen_store_gpr(v0_t
, ret
);
19787 tcg_gen_ext8u_tl(v0_t
, v0_t
);
19788 tcg_gen_shli_tl(t0
, v0_t
, 8);
19789 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19790 tcg_gen_shli_tl(t0
, v0_t
, 16);
19791 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19792 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19793 gen_store_gpr(v0_t
, ret
);
19797 gen_helper_bitrev(v0_t
, v0_t
);
19798 gen_store_gpr(v0_t
, ret
);
19803 TCGv tv0
= tcg_temp_new();
19805 gen_load_gpr(tv0
, rt
);
19806 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
19807 gen_store_gpr(v0_t
, ret
);
19808 tcg_temp_free(tv0
);
19811 case NM_RADDU_W_QB
:
19813 gen_helper_raddu_w_qb(v0_t
, v0_t
);
19814 gen_store_gpr(v0_t
, ret
);
19817 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
19821 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
19825 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
19828 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
19831 generate_exception_end(ctx
, EXCP_RI
);
19835 tcg_temp_free(v0_t
);
19839 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19840 int rt
, int rs
, int rd
)
19842 TCGv t0
= tcg_temp_new();
19843 TCGv rs_t
= tcg_temp_new();
19845 gen_load_gpr(rs_t
, rs
);
19850 tcg_gen_movi_tl(t0
, rd
>> 2);
19851 switch (extract32(ctx
->opcode
, 12, 1)) {
19854 gen_helper_shra_qb(t0
, t0
, rs_t
);
19855 gen_store_gpr(t0
, rt
);
19859 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
19860 gen_store_gpr(t0
, rt
);
19866 tcg_gen_movi_tl(t0
, rd
>> 1);
19867 gen_helper_shrl_ph(t0
, t0
, rs_t
);
19868 gen_store_gpr(t0
, rt
);
19874 target_long result
;
19875 imm
= extract32(ctx
->opcode
, 13, 8);
19876 result
= (uint32_t)imm
<< 24 |
19877 (uint32_t)imm
<< 16 |
19878 (uint32_t)imm
<< 8 |
19880 result
= (int32_t)result
;
19881 tcg_gen_movi_tl(t0
, result
);
19882 gen_store_gpr(t0
, rt
);
19886 generate_exception_end(ctx
, EXCP_RI
);
19890 tcg_temp_free(rs_t
);
19894 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19896 int rt
= extract32(ctx
->opcode
, 21, 5);
19897 int rs
= extract32(ctx
->opcode
, 16, 5);
19898 int rd
= extract32(ctx
->opcode
, 11, 5);
19900 switch (extract32(ctx
->opcode
, 6, 3)) {
19901 case NM_POOL32AXF_1
:
19903 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19904 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19907 case NM_POOL32AXF_2
:
19909 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
19910 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19913 case NM_POOL32AXF_4
:
19915 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
19916 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
19919 case NM_POOL32AXF_5
:
19920 switch (extract32(ctx
->opcode
, 9, 7)) {
19921 #ifndef CONFIG_USER_ONLY
19923 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
19926 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
19929 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
19932 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
19935 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
19938 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
19941 check_cp0_enabled(ctx
);
19943 TCGv t0
= tcg_temp_new();
19945 save_cpu_state(ctx
, 1);
19946 gen_helper_di(t0
, cpu_env
);
19947 gen_store_gpr(t0
, rt
);
19948 /* Stop translation as we may have switched the execution mode */
19949 ctx
->base
.is_jmp
= DISAS_STOP
;
19954 check_cp0_enabled(ctx
);
19956 TCGv t0
= tcg_temp_new();
19958 save_cpu_state(ctx
, 1);
19959 gen_helper_ei(t0
, cpu_env
);
19960 gen_store_gpr(t0
, rt
);
19961 /* Stop translation as we may have switched the execution mode */
19962 ctx
->base
.is_jmp
= DISAS_STOP
;
19967 gen_load_srsgpr(rs
, rt
);
19970 gen_store_srsgpr(rs
, rt
);
19973 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
19976 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
19979 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
19983 generate_exception_end(ctx
, EXCP_RI
);
19987 case NM_POOL32AXF_7
:
19989 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19990 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19994 generate_exception_end(ctx
, EXCP_RI
);
19999 /* Immediate Value Compact Branches */
20000 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
20001 int rt
, int32_t imm
, int32_t offset
)
20004 int bcond_compute
= 0;
20005 TCGv t0
= tcg_temp_new();
20006 TCGv t1
= tcg_temp_new();
20008 gen_load_gpr(t0
, rt
);
20009 tcg_gen_movi_tl(t1
, imm
);
20010 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20012 /* Load needed operands and calculate btarget */
20015 if (rt
== 0 && imm
== 0) {
20016 /* Unconditional branch */
20017 } else if (rt
== 0 && imm
!= 0) {
20022 cond
= TCG_COND_EQ
;
20028 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
20029 generate_exception_end(ctx
, EXCP_RI
);
20031 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
20032 /* Unconditional branch */
20033 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
20037 tcg_gen_shri_tl(t0
, t0
, imm
);
20038 tcg_gen_andi_tl(t0
, t0
, 1);
20039 tcg_gen_movi_tl(t1
, 0);
20041 if (opc
== NM_BBEQZC
) {
20042 cond
= TCG_COND_EQ
;
20044 cond
= TCG_COND_NE
;
20049 if (rt
== 0 && imm
== 0) {
20052 } else if (rt
== 0 && imm
!= 0) {
20053 /* Unconditional branch */
20056 cond
= TCG_COND_NE
;
20060 if (rt
== 0 && imm
== 0) {
20061 /* Unconditional branch */
20064 cond
= TCG_COND_GE
;
20069 cond
= TCG_COND_LT
;
20072 if (rt
== 0 && imm
== 0) {
20073 /* Unconditional branch */
20076 cond
= TCG_COND_GEU
;
20081 cond
= TCG_COND_LTU
;
20084 MIPS_INVAL("Immediate Value Compact branch");
20085 generate_exception_end(ctx
, EXCP_RI
);
20089 /* branch completion */
20090 clear_branch_hflags(ctx
);
20091 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20093 if (bcond_compute
== 0) {
20094 /* Uncoditional compact branch */
20095 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20097 /* Conditional compact branch */
20098 TCGLabel
*fs
= gen_new_label();
20100 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
20102 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20105 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20113 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20114 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
20117 TCGv t0
= tcg_temp_new();
20118 TCGv t1
= tcg_temp_new();
20121 gen_load_gpr(t0
, rs
);
20125 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
20128 /* calculate btarget */
20129 tcg_gen_shli_tl(t0
, t0
, 1);
20130 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
20131 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
20133 /* branch completion */
20134 clear_branch_hflags(ctx
);
20135 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20137 /* unconditional branch to register */
20138 tcg_gen_mov_tl(cpu_PC
, btarget
);
20139 tcg_gen_lookup_and_goto_ptr();
20145 /* nanoMIPS Branches */
20146 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
20147 int rs
, int rt
, int32_t offset
)
20149 int bcond_compute
= 0;
20150 TCGv t0
= tcg_temp_new();
20151 TCGv t1
= tcg_temp_new();
20153 /* Load needed operands and calculate btarget */
20155 /* compact branch */
20158 gen_load_gpr(t0
, rs
);
20159 gen_load_gpr(t1
, rt
);
20161 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20165 if (rs
== 0 || rs
== rt
) {
20166 /* OPC_BLEZALC, OPC_BGEZALC */
20167 /* OPC_BGTZALC, OPC_BLTZALC */
20168 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20170 gen_load_gpr(t0
, rs
);
20171 gen_load_gpr(t1
, rt
);
20173 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20176 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20180 /* OPC_BEQZC, OPC_BNEZC */
20181 gen_load_gpr(t0
, rs
);
20183 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20185 /* OPC_JIC, OPC_JIALC */
20186 TCGv tbase
= tcg_temp_new();
20187 TCGv toffset
= tcg_temp_new();
20189 gen_load_gpr(tbase
, rt
);
20190 tcg_gen_movi_tl(toffset
, offset
);
20191 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20192 tcg_temp_free(tbase
);
20193 tcg_temp_free(toffset
);
20197 MIPS_INVAL("Compact branch/jump");
20198 generate_exception_end(ctx
, EXCP_RI
);
20202 if (bcond_compute
== 0) {
20203 /* Uncoditional compact branch */
20206 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20209 MIPS_INVAL("Compact branch/jump");
20210 generate_exception_end(ctx
, EXCP_RI
);
20214 /* Conditional compact branch */
20215 TCGLabel
*fs
= gen_new_label();
20219 if (rs
== 0 && rt
!= 0) {
20221 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20222 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20224 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20227 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20231 if (rs
== 0 && rt
!= 0) {
20233 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20234 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20236 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20239 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20243 if (rs
== 0 && rt
!= 0) {
20245 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20246 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20248 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20251 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20255 if (rs
== 0 && rt
!= 0) {
20257 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20258 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20260 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20263 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20267 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20270 MIPS_INVAL("Compact conditional branch/jump");
20271 generate_exception_end(ctx
, EXCP_RI
);
20275 /* branch completion */
20276 clear_branch_hflags(ctx
);
20277 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20279 /* Generating branch here as compact branches don't have delay slot */
20280 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20283 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20292 /* nanoMIPS CP1 Branches */
20293 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20294 int32_t ft
, int32_t offset
)
20296 target_ulong btarget
;
20297 TCGv_i64 t0
= tcg_temp_new_i64();
20299 gen_load_fpr64(ctx
, t0
, ft
);
20300 tcg_gen_andi_i64(t0
, t0
, 1);
20302 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20306 tcg_gen_xori_i64(t0
, t0
, 1);
20307 ctx
->hflags
|= MIPS_HFLAG_BC
;
20310 /* t0 already set */
20311 ctx
->hflags
|= MIPS_HFLAG_BC
;
20314 MIPS_INVAL("cp1 cond branch");
20315 generate_exception_end(ctx
, EXCP_RI
);
20319 tcg_gen_trunc_i64_tl(bcond
, t0
);
20321 ctx
->btarget
= btarget
;
20324 tcg_temp_free_i64(t0
);
20328 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20331 t0
= tcg_temp_new();
20332 t1
= tcg_temp_new();
20334 gen_load_gpr(t0
, rs
);
20335 gen_load_gpr(t1
, rt
);
20337 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20338 /* PP.LSXS instructions require shifting */
20339 switch (extract32(ctx
->opcode
, 7, 4)) {
20345 tcg_gen_shli_tl(t0
, t0
, 1);
20353 tcg_gen_shli_tl(t0
, t0
, 2);
20357 tcg_gen_shli_tl(t0
, t0
, 3);
20361 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20363 switch (extract32(ctx
->opcode
, 7, 4)) {
20365 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20367 gen_store_gpr(t0
, rd
);
20371 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20373 gen_store_gpr(t0
, rd
);
20377 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20379 gen_store_gpr(t0
, rd
);
20382 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20384 gen_store_gpr(t0
, rd
);
20388 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20390 gen_store_gpr(t0
, rd
);
20394 gen_load_gpr(t1
, rd
);
20395 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20401 gen_load_gpr(t1
, rd
);
20402 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20408 gen_load_gpr(t1
, rd
);
20409 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20413 /*case NM_LWC1XS:*/
20415 /*case NM_LDC1XS:*/
20417 /*case NM_SWC1XS:*/
20419 /*case NM_SDC1XS:*/
20420 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20421 check_cp1_enabled(ctx
);
20422 switch (extract32(ctx
->opcode
, 7, 4)) {
20424 /*case NM_LWC1XS:*/
20425 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20428 /*case NM_LDC1XS:*/
20429 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20432 /*case NM_SWC1XS:*/
20433 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20436 /*case NM_SDC1XS:*/
20437 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20441 generate_exception_err(ctx
, EXCP_CpU
, 1);
20445 generate_exception_end(ctx
, EXCP_RI
);
20453 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20457 rt
= extract32(ctx
->opcode
, 21, 5);
20458 rs
= extract32(ctx
->opcode
, 16, 5);
20459 rd
= extract32(ctx
->opcode
, 11, 5);
20461 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20462 generate_exception_end(ctx
, EXCP_RI
);
20465 check_cp1_enabled(ctx
);
20466 switch (extract32(ctx
->opcode
, 0, 3)) {
20468 switch (extract32(ctx
->opcode
, 3, 7)) {
20470 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20473 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20476 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20479 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20482 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20485 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20488 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20491 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20494 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20497 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20500 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20503 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20506 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20509 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20512 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20515 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20518 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20521 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20524 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20527 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20530 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20533 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20536 generate_exception_end(ctx
, EXCP_RI
);
20541 switch (extract32(ctx
->opcode
, 3, 3)) {
20543 switch (extract32(ctx
->opcode
, 9, 1)) {
20545 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
20548 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
20553 switch (extract32(ctx
->opcode
, 9, 1)) {
20555 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
20558 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
20563 switch (extract32(ctx
->opcode
, 9, 1)) {
20565 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
20568 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
20573 switch (extract32(ctx
->opcode
, 9, 1)) {
20575 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
20578 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
20583 switch (extract32(ctx
->opcode
, 6, 8)) {
20585 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
20588 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
20591 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
20594 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
20597 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
20600 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
20603 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
20606 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
20609 switch (extract32(ctx
->opcode
, 6, 9)) {
20611 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
20614 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
20617 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
20620 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
20623 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
20626 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
20629 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
20632 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
20635 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
20638 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
20641 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
20644 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
20647 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
20650 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
20653 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
20656 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
20659 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
20662 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
20665 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
20668 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
20671 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
20674 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
20677 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
20680 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
20683 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
20686 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
20689 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
20692 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
20695 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
20698 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
20701 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
20704 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
20707 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
20710 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
20713 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
20716 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
20719 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
20722 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
20725 generate_exception_end(ctx
, EXCP_RI
);
20734 switch (extract32(ctx
->opcode
, 3, 3)) {
20735 case NM_CMP_CONDN_S
:
20736 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20738 case NM_CMP_CONDN_D
:
20739 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20742 generate_exception_end(ctx
, EXCP_RI
);
20747 generate_exception_end(ctx
, EXCP_RI
);
20752 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
20753 int rd
, int rs
, int rt
)
20756 TCGv t0
= tcg_temp_new();
20757 TCGv v1_t
= tcg_temp_new();
20758 TCGv v2_t
= tcg_temp_new();
20760 gen_load_gpr(v1_t
, rs
);
20761 gen_load_gpr(v2_t
, rt
);
20766 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
20770 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
20774 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
20776 case NM_CMPU_EQ_QB
:
20778 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
20780 case NM_CMPU_LT_QB
:
20782 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
20784 case NM_CMPU_LE_QB
:
20786 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
20788 case NM_CMPGU_EQ_QB
:
20790 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20791 gen_store_gpr(v1_t
, ret
);
20793 case NM_CMPGU_LT_QB
:
20795 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20796 gen_store_gpr(v1_t
, ret
);
20798 case NM_CMPGU_LE_QB
:
20800 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20801 gen_store_gpr(v1_t
, ret
);
20803 case NM_CMPGDU_EQ_QB
:
20805 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20806 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20807 gen_store_gpr(v1_t
, ret
);
20809 case NM_CMPGDU_LT_QB
:
20811 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20812 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20813 gen_store_gpr(v1_t
, ret
);
20815 case NM_CMPGDU_LE_QB
:
20817 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20818 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20819 gen_store_gpr(v1_t
, ret
);
20823 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
20824 gen_store_gpr(v1_t
, ret
);
20828 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20829 gen_store_gpr(v1_t
, ret
);
20833 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20834 gen_store_gpr(v1_t
, ret
);
20838 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20839 gen_store_gpr(v1_t
, ret
);
20843 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20844 gen_store_gpr(v1_t
, ret
);
20848 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
20849 gen_store_gpr(v1_t
, ret
);
20853 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
20854 gen_store_gpr(v1_t
, ret
);
20858 switch (extract32(ctx
->opcode
, 10, 1)) {
20861 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20862 gen_store_gpr(v1_t
, ret
);
20866 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20867 gen_store_gpr(v1_t
, ret
);
20871 case NM_ADDQH_R_PH
:
20873 switch (extract32(ctx
->opcode
, 10, 1)) {
20876 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
20877 gen_store_gpr(v1_t
, ret
);
20881 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
20882 gen_store_gpr(v1_t
, ret
);
20888 switch (extract32(ctx
->opcode
, 10, 1)) {
20891 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
20892 gen_store_gpr(v1_t
, ret
);
20896 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
20897 gen_store_gpr(v1_t
, ret
);
20903 switch (extract32(ctx
->opcode
, 10, 1)) {
20906 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20907 gen_store_gpr(v1_t
, ret
);
20911 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20912 gen_store_gpr(v1_t
, ret
);
20918 switch (extract32(ctx
->opcode
, 10, 1)) {
20921 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20922 gen_store_gpr(v1_t
, ret
);
20926 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20927 gen_store_gpr(v1_t
, ret
);
20931 case NM_ADDUH_R_QB
:
20933 switch (extract32(ctx
->opcode
, 10, 1)) {
20936 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
20937 gen_store_gpr(v1_t
, ret
);
20941 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
20942 gen_store_gpr(v1_t
, ret
);
20946 case NM_SHRAV_R_PH
:
20948 switch (extract32(ctx
->opcode
, 10, 1)) {
20951 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
20952 gen_store_gpr(v1_t
, ret
);
20956 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
20957 gen_store_gpr(v1_t
, ret
);
20961 case NM_SHRAV_R_QB
:
20963 switch (extract32(ctx
->opcode
, 10, 1)) {
20966 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
20967 gen_store_gpr(v1_t
, ret
);
20971 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
20972 gen_store_gpr(v1_t
, ret
);
20978 switch (extract32(ctx
->opcode
, 10, 1)) {
20981 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20982 gen_store_gpr(v1_t
, ret
);
20986 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20987 gen_store_gpr(v1_t
, ret
);
20991 case NM_SUBQH_R_PH
:
20993 switch (extract32(ctx
->opcode
, 10, 1)) {
20996 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
20997 gen_store_gpr(v1_t
, ret
);
21001 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
21002 gen_store_gpr(v1_t
, ret
);
21008 switch (extract32(ctx
->opcode
, 10, 1)) {
21011 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
21012 gen_store_gpr(v1_t
, ret
);
21016 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
21017 gen_store_gpr(v1_t
, ret
);
21023 switch (extract32(ctx
->opcode
, 10, 1)) {
21026 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21027 gen_store_gpr(v1_t
, ret
);
21031 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21032 gen_store_gpr(v1_t
, ret
);
21038 switch (extract32(ctx
->opcode
, 10, 1)) {
21041 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21042 gen_store_gpr(v1_t
, ret
);
21046 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21047 gen_store_gpr(v1_t
, ret
);
21051 case NM_SUBUH_R_QB
:
21053 switch (extract32(ctx
->opcode
, 10, 1)) {
21056 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
21057 gen_store_gpr(v1_t
, ret
);
21061 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
21062 gen_store_gpr(v1_t
, ret
);
21066 case NM_SHLLV_S_PH
:
21068 switch (extract32(ctx
->opcode
, 10, 1)) {
21071 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21072 gen_store_gpr(v1_t
, ret
);
21076 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21077 gen_store_gpr(v1_t
, ret
);
21081 case NM_PRECR_SRA_R_PH_W
:
21083 switch (extract32(ctx
->opcode
, 10, 1)) {
21085 /* PRECR_SRA_PH_W */
21087 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21088 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
21090 gen_store_gpr(v1_t
, rt
);
21091 tcg_temp_free_i32(sa_t
);
21095 /* PRECR_SRA_R_PH_W */
21097 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21098 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
21100 gen_store_gpr(v1_t
, rt
);
21101 tcg_temp_free_i32(sa_t
);
21106 case NM_MULEU_S_PH_QBL
:
21108 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
21109 gen_store_gpr(v1_t
, ret
);
21111 case NM_MULEU_S_PH_QBR
:
21113 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
21114 gen_store_gpr(v1_t
, ret
);
21116 case NM_MULQ_RS_PH
:
21118 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21119 gen_store_gpr(v1_t
, ret
);
21123 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21124 gen_store_gpr(v1_t
, ret
);
21128 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21129 gen_store_gpr(v1_t
, ret
);
21133 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21134 gen_store_gpr(v1_t
, ret
);
21138 gen_load_gpr(t0
, rs
);
21140 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
21142 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21146 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
21147 gen_store_gpr(v1_t
, ret
);
21151 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
21152 gen_store_gpr(v1_t
, ret
);
21156 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
21157 gen_store_gpr(v1_t
, ret
);
21161 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21162 gen_store_gpr(v1_t
, ret
);
21166 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21167 gen_store_gpr(v1_t
, ret
);
21171 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21172 gen_store_gpr(v1_t
, ret
);
21177 TCGv tv0
= tcg_temp_new();
21178 TCGv tv1
= tcg_temp_new();
21179 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21181 tcg_gen_movi_tl(tv0
, rd
>> 3);
21182 tcg_gen_movi_tl(tv1
, imm
);
21183 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21186 case NM_MULEQ_S_W_PHL
:
21188 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21189 gen_store_gpr(v1_t
, ret
);
21191 case NM_MULEQ_S_W_PHR
:
21193 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21194 gen_store_gpr(v1_t
, ret
);
21198 switch (extract32(ctx
->opcode
, 10, 1)) {
21201 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21202 gen_store_gpr(v1_t
, ret
);
21206 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21207 gen_store_gpr(v1_t
, ret
);
21211 case NM_PRECR_QB_PH
:
21213 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21214 gen_store_gpr(v1_t
, ret
);
21216 case NM_PRECRQ_QB_PH
:
21218 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21219 gen_store_gpr(v1_t
, ret
);
21221 case NM_PRECRQ_PH_W
:
21223 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21224 gen_store_gpr(v1_t
, ret
);
21226 case NM_PRECRQ_RS_PH_W
:
21228 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21229 gen_store_gpr(v1_t
, ret
);
21231 case NM_PRECRQU_S_QB_PH
:
21233 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21234 gen_store_gpr(v1_t
, ret
);
21238 tcg_gen_movi_tl(t0
, rd
);
21239 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21240 gen_store_gpr(v1_t
, rt
);
21244 tcg_gen_movi_tl(t0
, rd
>> 1);
21245 switch (extract32(ctx
->opcode
, 10, 1)) {
21248 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21249 gen_store_gpr(v1_t
, rt
);
21253 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21254 gen_store_gpr(v1_t
, rt
);
21260 tcg_gen_movi_tl(t0
, rd
>> 1);
21261 switch (extract32(ctx
->opcode
, 10, 2)) {
21264 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21265 gen_store_gpr(v1_t
, rt
);
21269 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21270 gen_store_gpr(v1_t
, rt
);
21273 generate_exception_end(ctx
, EXCP_RI
);
21279 tcg_gen_movi_tl(t0
, rd
);
21280 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21281 gen_store_gpr(v1_t
, rt
);
21287 imm
= sextract32(ctx
->opcode
, 11, 11);
21288 imm
= (int16_t)(imm
<< 6) >> 6;
21290 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21295 generate_exception_end(ctx
, EXCP_RI
);
21300 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21308 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
21309 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21311 rt
= extract32(ctx
->opcode
, 21, 5);
21312 rs
= extract32(ctx
->opcode
, 16, 5);
21313 rd
= extract32(ctx
->opcode
, 11, 5);
21315 op
= extract32(ctx
->opcode
, 26, 6);
21320 switch (extract32(ctx
->opcode
, 19, 2)) {
21323 generate_exception_end(ctx
, EXCP_RI
);
21326 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21327 generate_exception_end(ctx
, EXCP_SYSCALL
);
21329 generate_exception_end(ctx
, EXCP_RI
);
21333 generate_exception_end(ctx
, EXCP_BREAK
);
21336 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21337 gen_helper_do_semihosting(cpu_env
);
21339 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21340 generate_exception_end(ctx
, EXCP_RI
);
21342 generate_exception_end(ctx
, EXCP_DBp
);
21349 imm
= extract32(ctx
->opcode
, 0, 16);
21351 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21353 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21355 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21360 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21361 extract32(ctx
->opcode
, 1, 20) << 1;
21362 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21363 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21367 switch (ctx
->opcode
& 0x07) {
21369 gen_pool32a0_nanomips_insn(env
, ctx
);
21373 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21374 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21378 switch (extract32(ctx
->opcode
, 3, 3)) {
21380 gen_p_lsx(ctx
, rd
, rs
, rt
);
21384 * In nanoMIPS, the shift field directly encodes the shift
21385 * amount, meaning that the supported shift values are in
21386 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21388 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
21389 extract32(ctx
->opcode
, 9, 2) - 1);
21392 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21395 gen_pool32axf_nanomips_insn(env
, ctx
);
21398 generate_exception_end(ctx
, EXCP_RI
);
21403 generate_exception_end(ctx
, EXCP_RI
);
21408 switch (ctx
->opcode
& 0x03) {
21411 offset
= extract32(ctx
->opcode
, 0, 21);
21412 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21416 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21419 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21422 generate_exception_end(ctx
, EXCP_RI
);
21428 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 4);
21429 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21430 switch (extract32(ctx
->opcode
, 16, 5)) {
21434 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21440 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21441 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21447 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21453 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21456 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21463 t0
= tcg_temp_new();
21465 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21468 tcg_gen_movi_tl(t0
, addr
);
21469 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21477 t0
= tcg_temp_new();
21478 t1
= tcg_temp_new();
21480 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21483 tcg_gen_movi_tl(t0
, addr
);
21484 gen_load_gpr(t1
, rt
);
21486 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21493 generate_exception_end(ctx
, EXCP_RI
);
21499 switch (extract32(ctx
->opcode
, 12, 4)) {
21501 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21504 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21507 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21510 switch (extract32(ctx
->opcode
, 20, 1)) {
21512 switch (ctx
->opcode
& 3) {
21514 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21515 extract32(ctx
->opcode
, 2, 1),
21516 extract32(ctx
->opcode
, 3, 9) << 3);
21519 case NM_RESTORE_JRC
:
21520 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21521 extract32(ctx
->opcode
, 2, 1),
21522 extract32(ctx
->opcode
, 3, 9) << 3);
21523 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21524 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21528 generate_exception_end(ctx
, EXCP_RI
);
21533 generate_exception_end(ctx
, EXCP_RI
);
21538 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21541 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21545 TCGv t0
= tcg_temp_new();
21547 imm
= extract32(ctx
->opcode
, 0, 12);
21548 gen_load_gpr(t0
, rs
);
21549 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
21550 gen_store_gpr(t0
, rt
);
21556 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
21557 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
21561 int shift
= extract32(ctx
->opcode
, 0, 5);
21562 switch (extract32(ctx
->opcode
, 5, 4)) {
21564 if (rt
== 0 && shift
== 0) {
21566 } else if (rt
== 0 && shift
== 3) {
21567 /* EHB - treat as NOP */
21568 } else if (rt
== 0 && shift
== 5) {
21569 /* PAUSE - treat as NOP */
21570 } else if (rt
== 0 && shift
== 6) {
21572 gen_sync(extract32(ctx
->opcode
, 16, 5));
21575 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
21576 extract32(ctx
->opcode
, 0, 5));
21580 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
21581 extract32(ctx
->opcode
, 0, 5));
21584 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
21585 extract32(ctx
->opcode
, 0, 5));
21588 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
21589 extract32(ctx
->opcode
, 0, 5));
21597 TCGv t0
= tcg_temp_new();
21598 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
21599 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
21601 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
21603 gen_load_gpr(t0
, rs
);
21604 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
21607 tcg_temp_free_i32(shift
);
21608 tcg_temp_free_i32(shiftx
);
21609 tcg_temp_free_i32(stripe
);
21613 switch (((ctx
->opcode
>> 10) & 2) |
21614 (extract32(ctx
->opcode
, 5, 1))) {
21617 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21618 extract32(ctx
->opcode
, 6, 5));
21621 generate_exception_end(ctx
, EXCP_RI
);
21626 switch (((ctx
->opcode
>> 10) & 2) |
21627 (extract32(ctx
->opcode
, 5, 1))) {
21630 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21631 extract32(ctx
->opcode
, 6, 5));
21634 generate_exception_end(ctx
, EXCP_RI
);
21639 generate_exception_end(ctx
, EXCP_RI
);
21644 gen_pool32f_nanomips_insn(ctx
);
21649 switch (extract32(ctx
->opcode
, 1, 1)) {
21652 tcg_gen_movi_tl(cpu_gpr
[rt
],
21653 sextract32(ctx
->opcode
, 0, 1) << 31 |
21654 extract32(ctx
->opcode
, 2, 10) << 21 |
21655 extract32(ctx
->opcode
, 12, 9) << 12);
21660 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
21661 extract32(ctx
->opcode
, 2, 10) << 21 |
21662 extract32(ctx
->opcode
, 12, 9) << 12;
21664 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21665 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21672 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
21674 switch (extract32(ctx
->opcode
, 18, 3)) {
21676 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
21679 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
21682 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
21686 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
21691 switch (ctx
->opcode
& 1) {
21693 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
21696 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
21702 switch (ctx
->opcode
& 1) {
21704 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
21707 generate_exception_end(ctx
, EXCP_RI
);
21713 switch (ctx
->opcode
& 0x3) {
21715 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
21718 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
21721 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
21724 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
21729 generate_exception_end(ctx
, EXCP_RI
);
21736 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
21738 switch (extract32(ctx
->opcode
, 12, 4)) {
21743 * Break the TB to be able to sync copied instructions
21746 ctx
->base
.is_jmp
= DISAS_STOP
;
21749 /* Treat as NOP. */
21753 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
21756 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
21759 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
21762 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
21765 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
21768 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
21771 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
21774 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
21777 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
21780 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
21783 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
21786 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
21789 generate_exception_end(ctx
, EXCP_RI
);
21796 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
21797 extract32(ctx
->opcode
, 0, 8);
21799 switch (extract32(ctx
->opcode
, 8, 3)) {
21801 switch (extract32(ctx
->opcode
, 11, 4)) {
21803 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
21806 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
21809 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
21812 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
21815 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
21818 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
21821 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
21824 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
21827 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
21830 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
21833 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
21836 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
21842 * Break the TB to be able to sync copied instructions
21845 ctx
->base
.is_jmp
= DISAS_STOP
;
21848 /* Treat as NOP. */
21852 generate_exception_end(ctx
, EXCP_RI
);
21857 switch (extract32(ctx
->opcode
, 11, 4)) {
21862 TCGv t0
= tcg_temp_new();
21863 TCGv t1
= tcg_temp_new();
21865 gen_base_offset_addr(ctx
, t0
, rs
, s
);
21867 switch (extract32(ctx
->opcode
, 11, 4)) {
21869 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
21871 gen_store_gpr(t0
, rt
);
21874 gen_load_gpr(t1
, rt
);
21875 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
21884 switch (ctx
->opcode
& 0x03) {
21886 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
21890 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21895 switch (ctx
->opcode
& 0x03) {
21897 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
21901 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21907 check_cp0_enabled(ctx
);
21908 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
21909 gen_cache_operation(ctx
, rt
, rs
, s
);
21915 switch (extract32(ctx
->opcode
, 11, 4)) {
21918 check_cp0_enabled(ctx
);
21919 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
21923 check_cp0_enabled(ctx
);
21924 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
21928 check_cp0_enabled(ctx
);
21929 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
21933 /* case NM_SYNCIE */
21935 check_cp0_enabled(ctx
);
21937 * Break the TB to be able to sync copied instructions
21940 ctx
->base
.is_jmp
= DISAS_STOP
;
21942 /* case NM_PREFE */
21944 check_cp0_enabled(ctx
);
21945 /* Treat as NOP. */
21950 check_cp0_enabled(ctx
);
21951 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
21955 check_cp0_enabled(ctx
);
21956 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
21960 check_cp0_enabled(ctx
);
21961 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
21964 check_nms_dl_il_sl_tl_l2c(ctx
);
21965 gen_cache_operation(ctx
, rt
, rs
, s
);
21969 check_cp0_enabled(ctx
);
21970 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
21974 check_cp0_enabled(ctx
);
21975 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
21978 switch (extract32(ctx
->opcode
, 2, 2)) {
21982 check_cp0_enabled(ctx
);
21983 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
21988 check_cp0_enabled(ctx
);
21989 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21992 generate_exception_end(ctx
, EXCP_RI
);
21997 switch (extract32(ctx
->opcode
, 2, 2)) {
22001 check_cp0_enabled(ctx
);
22002 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
22007 check_cp0_enabled(ctx
);
22008 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22012 generate_exception_end(ctx
, EXCP_RI
);
22022 int count
= extract32(ctx
->opcode
, 12, 3);
22025 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
22026 extract32(ctx
->opcode
, 0, 8);
22027 TCGv va
= tcg_temp_new();
22028 TCGv t1
= tcg_temp_new();
22029 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
22030 NM_P_LS_UAWM
? MO_UNALN
: 0;
22032 count
= (count
== 0) ? 8 : count
;
22033 while (counter
!= count
) {
22034 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
22035 int this_offset
= offset
+ (counter
<< 2);
22037 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
22039 switch (extract32(ctx
->opcode
, 11, 1)) {
22041 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
22043 gen_store_gpr(t1
, this_rt
);
22044 if ((this_rt
== rs
) &&
22045 (counter
!= (count
- 1))) {
22046 /* UNPREDICTABLE */
22050 this_rt
= (rt
== 0) ? 0 : this_rt
;
22051 gen_load_gpr(t1
, this_rt
);
22052 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
22063 generate_exception_end(ctx
, EXCP_RI
);
22071 TCGv t0
= tcg_temp_new();
22072 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
22073 extract32(ctx
->opcode
, 1, 20) << 1;
22074 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
22075 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
22076 extract32(ctx
->opcode
, 21, 3));
22077 gen_load_gpr(t0
, rt
);
22078 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22079 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22085 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
22086 extract32(ctx
->opcode
, 1, 24) << 1;
22088 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
22090 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
22093 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22098 switch (extract32(ctx
->opcode
, 12, 4)) {
22101 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
22104 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
22107 generate_exception_end(ctx
, EXCP_RI
);
22113 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22114 extract32(ctx
->opcode
, 1, 13) << 1;
22115 switch (extract32(ctx
->opcode
, 14, 2)) {
22118 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
22121 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22122 extract32(ctx
->opcode
, 1, 13) << 1;
22123 check_cp1_enabled(ctx
);
22124 switch (extract32(ctx
->opcode
, 16, 5)) {
22126 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
22129 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
22134 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
22135 extract32(ctx
->opcode
, 0, 1) << 13;
22137 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
22142 generate_exception_end(ctx
, EXCP_RI
);
22148 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
22150 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
22154 if (rs
== rt
|| rt
== 0) {
22155 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
22156 } else if (rs
== 0) {
22157 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
22159 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22167 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22168 extract32(ctx
->opcode
, 1, 13) << 1;
22169 switch (extract32(ctx
->opcode
, 14, 2)) {
22172 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22175 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22177 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22179 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22183 if (rs
== 0 || rs
== rt
) {
22185 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22187 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22191 generate_exception_end(ctx
, EXCP_RI
);
22198 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22199 extract32(ctx
->opcode
, 1, 10) << 1;
22200 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22202 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22207 generate_exception_end(ctx
, EXCP_RI
);
22213 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22216 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22217 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22218 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22222 /* make sure instructions are on a halfword boundary */
22223 if (ctx
->base
.pc_next
& 0x1) {
22224 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22225 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22226 tcg_temp_free(tmp
);
22227 generate_exception_end(ctx
, EXCP_AdEL
);
22231 op
= extract32(ctx
->opcode
, 10, 6);
22234 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22237 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22238 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22241 switch (extract32(ctx
->opcode
, 3, 2)) {
22242 case NM_P16_SYSCALL
:
22243 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22244 generate_exception_end(ctx
, EXCP_SYSCALL
);
22246 generate_exception_end(ctx
, EXCP_RI
);
22250 generate_exception_end(ctx
, EXCP_BREAK
);
22253 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22254 gen_helper_do_semihosting(cpu_env
);
22256 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22257 generate_exception_end(ctx
, EXCP_RI
);
22259 generate_exception_end(ctx
, EXCP_DBp
);
22264 generate_exception_end(ctx
, EXCP_RI
);
22271 int shift
= extract32(ctx
->opcode
, 0, 3);
22273 shift
= (shift
== 0) ? 8 : shift
;
22275 switch (extract32(ctx
->opcode
, 3, 1)) {
22283 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22287 switch (ctx
->opcode
& 1) {
22289 gen_pool16c_nanomips_insn(ctx
);
22292 gen_ldxs(ctx
, rt
, rs
, rd
);
22297 switch (extract32(ctx
->opcode
, 6, 1)) {
22299 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22300 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22303 generate_exception_end(ctx
, EXCP_RI
);
22308 switch (extract32(ctx
->opcode
, 3, 1)) {
22310 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22311 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22313 case NM_P_ADDIURS5
:
22314 rt
= extract32(ctx
->opcode
, 5, 5);
22316 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22317 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22318 (extract32(ctx
->opcode
, 0, 3));
22319 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22325 switch (ctx
->opcode
& 0x1) {
22327 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22330 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22335 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22336 extract32(ctx
->opcode
, 5, 3);
22337 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22338 extract32(ctx
->opcode
, 0, 3);
22339 rt
= decode_gpr_gpr4(rt
);
22340 rs
= decode_gpr_gpr4(rs
);
22341 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22342 (extract32(ctx
->opcode
, 3, 1))) {
22345 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22349 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22352 generate_exception_end(ctx
, EXCP_RI
);
22358 int imm
= extract32(ctx
->opcode
, 0, 7);
22359 imm
= (imm
== 0x7f ? -1 : imm
);
22361 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22367 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22368 u
= (u
== 12) ? 0xff :
22369 (u
== 13) ? 0xffff : u
;
22370 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22374 offset
= extract32(ctx
->opcode
, 0, 2);
22375 switch (extract32(ctx
->opcode
, 2, 2)) {
22377 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22380 rt
= decode_gpr_gpr3_src_store(
22381 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22382 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22385 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22388 generate_exception_end(ctx
, EXCP_RI
);
22393 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22394 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22396 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22399 rt
= decode_gpr_gpr3_src_store(
22400 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22401 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22404 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22407 generate_exception_end(ctx
, EXCP_RI
);
22412 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22413 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22416 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22417 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22418 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22422 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22423 extract32(ctx
->opcode
, 5, 3);
22424 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22425 extract32(ctx
->opcode
, 0, 3);
22426 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22427 (extract32(ctx
->opcode
, 8, 1) << 2);
22428 rt
= decode_gpr_gpr4(rt
);
22429 rs
= decode_gpr_gpr4(rs
);
22430 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22434 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22435 extract32(ctx
->opcode
, 5, 3);
22436 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22437 extract32(ctx
->opcode
, 0, 3);
22438 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22439 (extract32(ctx
->opcode
, 8, 1) << 2);
22440 rt
= decode_gpr_gpr4_zero(rt
);
22441 rs
= decode_gpr_gpr4(rs
);
22442 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22445 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22446 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22449 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22450 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22451 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22454 rt
= decode_gpr_gpr3_src_store(
22455 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22456 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22457 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22458 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22461 rt
= decode_gpr_gpr3_src_store(
22462 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22463 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22464 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22467 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22468 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22469 (extract32(ctx
->opcode
, 1, 9) << 1));
22472 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22473 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22474 (extract32(ctx
->opcode
, 1, 9) << 1));
22477 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22478 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22479 (extract32(ctx
->opcode
, 1, 6) << 1));
22482 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22483 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22484 (extract32(ctx
->opcode
, 1, 6) << 1));
22487 switch (ctx
->opcode
& 0xf) {
22490 switch (extract32(ctx
->opcode
, 4, 1)) {
22492 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22493 extract32(ctx
->opcode
, 5, 5), 0, 0);
22496 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22497 extract32(ctx
->opcode
, 5, 5), 31, 0);
22504 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22505 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22506 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22507 extract32(ctx
->opcode
, 0, 4) << 1);
22514 int count
= extract32(ctx
->opcode
, 0, 4);
22515 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22517 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22518 switch (extract32(ctx
->opcode
, 8, 1)) {
22520 gen_save(ctx
, rt
, count
, 0, u
);
22522 case NM_RESTORE_JRC16
:
22523 gen_restore(ctx
, rt
, count
, 0, u
);
22524 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22533 static const int gpr2reg1
[] = {4, 5, 6, 7};
22534 static const int gpr2reg2
[] = {5, 6, 7, 8};
22536 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22537 extract32(ctx
->opcode
, 8, 1);
22538 int r1
= gpr2reg1
[rd2
];
22539 int r2
= gpr2reg2
[rd2
];
22540 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22541 extract32(ctx
->opcode
, 0, 3);
22542 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22543 extract32(ctx
->opcode
, 5, 3);
22544 TCGv t0
= tcg_temp_new();
22545 TCGv t1
= tcg_temp_new();
22546 if (op
== NM_MOVEP
) {
22549 rs
= decode_gpr_gpr4_zero(r3
);
22550 rt
= decode_gpr_gpr4_zero(r4
);
22552 rd
= decode_gpr_gpr4(r3
);
22553 re
= decode_gpr_gpr4(r4
);
22557 gen_load_gpr(t0
, rs
);
22558 gen_load_gpr(t1
, rt
);
22559 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22560 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
22566 return decode_nanomips_32_48_opc(env
, ctx
);
22573 /* SmartMIPS extension to MIPS32 */
22575 #if defined(TARGET_MIPS64)
22577 /* MDMX extension to MIPS64 */
22581 /* MIPSDSP functions. */
22582 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
22583 int rd
, int base
, int offset
)
22588 t0
= tcg_temp_new();
22591 gen_load_gpr(t0
, offset
);
22592 } else if (offset
== 0) {
22593 gen_load_gpr(t0
, base
);
22595 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
22600 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
22601 gen_store_gpr(t0
, rd
);
22604 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
22605 gen_store_gpr(t0
, rd
);
22608 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
22609 gen_store_gpr(t0
, rd
);
22611 #if defined(TARGET_MIPS64)
22613 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
22614 gen_store_gpr(t0
, rd
);
22621 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22622 int ret
, int v1
, int v2
)
22628 /* Treat as NOP. */
22632 v1_t
= tcg_temp_new();
22633 v2_t
= tcg_temp_new();
22635 gen_load_gpr(v1_t
, v1
);
22636 gen_load_gpr(v2_t
, v2
);
22639 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22640 case OPC_MULT_G_2E
:
22644 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22646 case OPC_ADDUH_R_QB
:
22647 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22650 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22652 case OPC_ADDQH_R_PH
:
22653 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22656 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22658 case OPC_ADDQH_R_W
:
22659 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22662 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22664 case OPC_SUBUH_R_QB
:
22665 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22668 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22670 case OPC_SUBQH_R_PH
:
22671 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22674 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22676 case OPC_SUBQH_R_W
:
22677 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22681 case OPC_ABSQ_S_PH_DSP
:
22683 case OPC_ABSQ_S_QB
:
22685 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
22687 case OPC_ABSQ_S_PH
:
22689 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
22693 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
22695 case OPC_PRECEQ_W_PHL
:
22697 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
22698 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22700 case OPC_PRECEQ_W_PHR
:
22702 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
22703 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
22704 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22706 case OPC_PRECEQU_PH_QBL
:
22708 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
22710 case OPC_PRECEQU_PH_QBR
:
22712 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
22714 case OPC_PRECEQU_PH_QBLA
:
22716 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
22718 case OPC_PRECEQU_PH_QBRA
:
22720 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
22722 case OPC_PRECEU_PH_QBL
:
22724 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
22726 case OPC_PRECEU_PH_QBR
:
22728 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
22730 case OPC_PRECEU_PH_QBLA
:
22732 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
22734 case OPC_PRECEU_PH_QBRA
:
22736 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
22740 case OPC_ADDU_QB_DSP
:
22744 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22746 case OPC_ADDQ_S_PH
:
22748 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22752 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22756 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22758 case OPC_ADDU_S_QB
:
22760 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22764 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22766 case OPC_ADDU_S_PH
:
22768 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22772 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22774 case OPC_SUBQ_S_PH
:
22776 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22780 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22784 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22786 case OPC_SUBU_S_QB
:
22788 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22792 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22794 case OPC_SUBU_S_PH
:
22796 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22800 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22804 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22808 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
22810 case OPC_RADDU_W_QB
:
22812 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
22816 case OPC_CMPU_EQ_QB_DSP
:
22818 case OPC_PRECR_QB_PH
:
22820 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22822 case OPC_PRECRQ_QB_PH
:
22824 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22826 case OPC_PRECR_SRA_PH_W
:
22829 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22830 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22832 tcg_temp_free_i32(sa_t
);
22835 case OPC_PRECR_SRA_R_PH_W
:
22838 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22839 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22841 tcg_temp_free_i32(sa_t
);
22844 case OPC_PRECRQ_PH_W
:
22846 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22848 case OPC_PRECRQ_RS_PH_W
:
22850 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22852 case OPC_PRECRQU_S_QB_PH
:
22854 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22858 #ifdef TARGET_MIPS64
22859 case OPC_ABSQ_S_QH_DSP
:
22861 case OPC_PRECEQ_L_PWL
:
22863 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
22865 case OPC_PRECEQ_L_PWR
:
22867 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
22869 case OPC_PRECEQ_PW_QHL
:
22871 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
22873 case OPC_PRECEQ_PW_QHR
:
22875 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
22877 case OPC_PRECEQ_PW_QHLA
:
22879 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
22881 case OPC_PRECEQ_PW_QHRA
:
22883 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
22885 case OPC_PRECEQU_QH_OBL
:
22887 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
22889 case OPC_PRECEQU_QH_OBR
:
22891 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
22893 case OPC_PRECEQU_QH_OBLA
:
22895 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
22897 case OPC_PRECEQU_QH_OBRA
:
22899 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
22901 case OPC_PRECEU_QH_OBL
:
22903 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
22905 case OPC_PRECEU_QH_OBR
:
22907 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
22909 case OPC_PRECEU_QH_OBLA
:
22911 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
22913 case OPC_PRECEU_QH_OBRA
:
22915 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
22917 case OPC_ABSQ_S_OB
:
22919 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
22921 case OPC_ABSQ_S_PW
:
22923 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
22925 case OPC_ABSQ_S_QH
:
22927 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
22931 case OPC_ADDU_OB_DSP
:
22933 case OPC_RADDU_L_OB
:
22935 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
22939 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22941 case OPC_SUBQ_S_PW
:
22943 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22947 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22949 case OPC_SUBQ_S_QH
:
22951 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22955 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22957 case OPC_SUBU_S_OB
:
22959 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22963 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22965 case OPC_SUBU_S_QH
:
22967 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22971 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22973 case OPC_SUBUH_R_OB
:
22975 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22979 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22981 case OPC_ADDQ_S_PW
:
22983 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22987 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22989 case OPC_ADDQ_S_QH
:
22991 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22995 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22997 case OPC_ADDU_S_OB
:
22999 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23003 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23005 case OPC_ADDU_S_QH
:
23007 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23011 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23013 case OPC_ADDUH_R_OB
:
23015 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23019 case OPC_CMPU_EQ_OB_DSP
:
23021 case OPC_PRECR_OB_QH
:
23023 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23025 case OPC_PRECR_SRA_QH_PW
:
23028 TCGv_i32 ret_t
= tcg_const_i32(ret
);
23029 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
23030 tcg_temp_free_i32(ret_t
);
23033 case OPC_PRECR_SRA_R_QH_PW
:
23036 TCGv_i32 sa_v
= tcg_const_i32(ret
);
23037 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
23038 tcg_temp_free_i32(sa_v
);
23041 case OPC_PRECRQ_OB_QH
:
23043 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23045 case OPC_PRECRQ_PW_L
:
23047 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
23049 case OPC_PRECRQ_QH_PW
:
23051 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23053 case OPC_PRECRQ_RS_QH_PW
:
23055 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23057 case OPC_PRECRQU_S_OB_QH
:
23059 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23066 tcg_temp_free(v1_t
);
23067 tcg_temp_free(v2_t
);
23070 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
23071 int ret
, int v1
, int v2
)
23079 /* Treat as NOP. */
23083 t0
= tcg_temp_new();
23084 v1_t
= tcg_temp_new();
23085 v2_t
= tcg_temp_new();
23087 tcg_gen_movi_tl(t0
, v1
);
23088 gen_load_gpr(v1_t
, v1
);
23089 gen_load_gpr(v2_t
, v2
);
23092 case OPC_SHLL_QB_DSP
:
23094 op2
= MASK_SHLL_QB(ctx
->opcode
);
23098 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23102 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23106 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23110 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23112 case OPC_SHLL_S_PH
:
23114 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23116 case OPC_SHLLV_S_PH
:
23118 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23122 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23124 case OPC_SHLLV_S_W
:
23126 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23130 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
23134 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23138 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
23142 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23146 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
23148 case OPC_SHRA_R_QB
:
23150 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
23154 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23156 case OPC_SHRAV_R_QB
:
23158 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23162 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23164 case OPC_SHRA_R_PH
:
23166 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23170 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23172 case OPC_SHRAV_R_PH
:
23174 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23178 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23180 case OPC_SHRAV_R_W
:
23182 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23184 default: /* Invalid */
23185 MIPS_INVAL("MASK SHLL.QB");
23186 generate_exception_end(ctx
, EXCP_RI
);
23191 #ifdef TARGET_MIPS64
23192 case OPC_SHLL_OB_DSP
:
23193 op2
= MASK_SHLL_OB(ctx
->opcode
);
23197 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23201 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23203 case OPC_SHLL_S_PW
:
23205 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23207 case OPC_SHLLV_S_PW
:
23209 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23213 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23217 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23221 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23225 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23227 case OPC_SHLL_S_QH
:
23229 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23231 case OPC_SHLLV_S_QH
:
23233 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23237 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23241 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23243 case OPC_SHRA_R_OB
:
23245 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23247 case OPC_SHRAV_R_OB
:
23249 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23253 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23257 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23259 case OPC_SHRA_R_PW
:
23261 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23263 case OPC_SHRAV_R_PW
:
23265 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23269 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23273 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23275 case OPC_SHRA_R_QH
:
23277 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23279 case OPC_SHRAV_R_QH
:
23281 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23285 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23289 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23293 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23297 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23299 default: /* Invalid */
23300 MIPS_INVAL("MASK SHLL.OB");
23301 generate_exception_end(ctx
, EXCP_RI
);
23309 tcg_temp_free(v1_t
);
23310 tcg_temp_free(v2_t
);
23313 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23314 int ret
, int v1
, int v2
, int check_ret
)
23320 if ((ret
== 0) && (check_ret
== 1)) {
23321 /* Treat as NOP. */
23325 t0
= tcg_temp_new_i32();
23326 v1_t
= tcg_temp_new();
23327 v2_t
= tcg_temp_new();
23329 tcg_gen_movi_i32(t0
, ret
);
23330 gen_load_gpr(v1_t
, v1
);
23331 gen_load_gpr(v2_t
, v2
);
23335 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23336 * the same mask and op1.
23338 case OPC_MULT_G_2E
:
23342 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23345 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23348 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23350 case OPC_MULQ_RS_W
:
23351 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23355 case OPC_DPA_W_PH_DSP
:
23357 case OPC_DPAU_H_QBL
:
23359 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23361 case OPC_DPAU_H_QBR
:
23363 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23365 case OPC_DPSU_H_QBL
:
23367 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23369 case OPC_DPSU_H_QBR
:
23371 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23375 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23377 case OPC_DPAX_W_PH
:
23379 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23381 case OPC_DPAQ_S_W_PH
:
23383 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23385 case OPC_DPAQX_S_W_PH
:
23387 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23389 case OPC_DPAQX_SA_W_PH
:
23391 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23395 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23397 case OPC_DPSX_W_PH
:
23399 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23401 case OPC_DPSQ_S_W_PH
:
23403 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23405 case OPC_DPSQX_S_W_PH
:
23407 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23409 case OPC_DPSQX_SA_W_PH
:
23411 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23413 case OPC_MULSAQ_S_W_PH
:
23415 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23417 case OPC_DPAQ_SA_L_W
:
23419 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23421 case OPC_DPSQ_SA_L_W
:
23423 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23425 case OPC_MAQ_S_W_PHL
:
23427 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23429 case OPC_MAQ_S_W_PHR
:
23431 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23433 case OPC_MAQ_SA_W_PHL
:
23435 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23437 case OPC_MAQ_SA_W_PHR
:
23439 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23441 case OPC_MULSA_W_PH
:
23443 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23447 #ifdef TARGET_MIPS64
23448 case OPC_DPAQ_W_QH_DSP
:
23450 int ac
= ret
& 0x03;
23451 tcg_gen_movi_i32(t0
, ac
);
23456 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23460 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23464 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23468 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23472 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23474 case OPC_DPAQ_S_W_QH
:
23476 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23478 case OPC_DPAQ_SA_L_PW
:
23480 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23482 case OPC_DPAU_H_OBL
:
23484 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23486 case OPC_DPAU_H_OBR
:
23488 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23492 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23494 case OPC_DPSQ_S_W_QH
:
23496 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23498 case OPC_DPSQ_SA_L_PW
:
23500 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23502 case OPC_DPSU_H_OBL
:
23504 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23506 case OPC_DPSU_H_OBR
:
23508 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23510 case OPC_MAQ_S_L_PWL
:
23512 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23514 case OPC_MAQ_S_L_PWR
:
23516 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23518 case OPC_MAQ_S_W_QHLL
:
23520 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23522 case OPC_MAQ_SA_W_QHLL
:
23524 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23526 case OPC_MAQ_S_W_QHLR
:
23528 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23530 case OPC_MAQ_SA_W_QHLR
:
23532 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23534 case OPC_MAQ_S_W_QHRL
:
23536 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23538 case OPC_MAQ_SA_W_QHRL
:
23540 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23542 case OPC_MAQ_S_W_QHRR
:
23544 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23546 case OPC_MAQ_SA_W_QHRR
:
23548 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23550 case OPC_MULSAQ_S_L_PW
:
23552 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23554 case OPC_MULSAQ_S_W_QH
:
23556 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23562 case OPC_ADDU_QB_DSP
:
23564 case OPC_MULEU_S_PH_QBL
:
23566 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23568 case OPC_MULEU_S_PH_QBR
:
23570 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23572 case OPC_MULQ_RS_PH
:
23574 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23576 case OPC_MULEQ_S_W_PHL
:
23578 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23580 case OPC_MULEQ_S_W_PHR
:
23582 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23584 case OPC_MULQ_S_PH
:
23586 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23590 #ifdef TARGET_MIPS64
23591 case OPC_ADDU_OB_DSP
:
23593 case OPC_MULEQ_S_PW_QHL
:
23595 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23597 case OPC_MULEQ_S_PW_QHR
:
23599 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23601 case OPC_MULEU_S_QH_OBL
:
23603 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23605 case OPC_MULEU_S_QH_OBR
:
23607 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23609 case OPC_MULQ_RS_QH
:
23611 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23618 tcg_temp_free_i32(t0
);
23619 tcg_temp_free(v1_t
);
23620 tcg_temp_free(v2_t
);
23623 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23631 /* Treat as NOP. */
23635 t0
= tcg_temp_new();
23636 val_t
= tcg_temp_new();
23637 gen_load_gpr(val_t
, val
);
23640 case OPC_ABSQ_S_PH_DSP
:
23644 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
23649 target_long result
;
23650 imm
= (ctx
->opcode
>> 16) & 0xFF;
23651 result
= (uint32_t)imm
<< 24 |
23652 (uint32_t)imm
<< 16 |
23653 (uint32_t)imm
<< 8 |
23655 result
= (int32_t)result
;
23656 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
23661 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23662 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23663 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23664 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23665 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23666 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23671 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23672 imm
= (int16_t)(imm
<< 6) >> 6;
23673 tcg_gen_movi_tl(cpu_gpr
[ret
], \
23674 (target_long
)((int32_t)imm
<< 16 | \
23680 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23681 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23682 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23683 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23687 #ifdef TARGET_MIPS64
23688 case OPC_ABSQ_S_QH_DSP
:
23695 imm
= (ctx
->opcode
>> 16) & 0xFF;
23696 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
23697 temp
= (temp
<< 16) | temp
;
23698 temp
= (temp
<< 32) | temp
;
23699 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23707 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23708 imm
= (int16_t)(imm
<< 6) >> 6;
23709 temp
= ((target_long
)imm
<< 32) \
23710 | ((target_long
)imm
& 0xFFFFFFFF);
23711 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23719 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23720 imm
= (int16_t)(imm
<< 6) >> 6;
23722 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
23723 ((uint64_t)(uint16_t)imm
<< 32) |
23724 ((uint64_t)(uint16_t)imm
<< 16) |
23725 (uint64_t)(uint16_t)imm
;
23726 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23731 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23732 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23733 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23734 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23735 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23736 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23737 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23741 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
23742 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23743 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23747 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23748 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23749 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23750 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23751 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23758 tcg_temp_free(val_t
);
23761 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
23762 uint32_t op1
, uint32_t op2
,
23763 int ret
, int v1
, int v2
, int check_ret
)
23769 if ((ret
== 0) && (check_ret
== 1)) {
23770 /* Treat as NOP. */
23774 t1
= tcg_temp_new();
23775 v1_t
= tcg_temp_new();
23776 v2_t
= tcg_temp_new();
23778 gen_load_gpr(v1_t
, v1
);
23779 gen_load_gpr(v2_t
, v2
);
23782 case OPC_CMPU_EQ_QB_DSP
:
23784 case OPC_CMPU_EQ_QB
:
23786 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
23788 case OPC_CMPU_LT_QB
:
23790 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
23792 case OPC_CMPU_LE_QB
:
23794 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
23796 case OPC_CMPGU_EQ_QB
:
23798 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23800 case OPC_CMPGU_LT_QB
:
23802 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23804 case OPC_CMPGU_LE_QB
:
23806 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23808 case OPC_CMPGDU_EQ_QB
:
23810 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
23811 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23812 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23813 tcg_gen_shli_tl(t1
, t1
, 24);
23814 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23816 case OPC_CMPGDU_LT_QB
:
23818 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
23819 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23820 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23821 tcg_gen_shli_tl(t1
, t1
, 24);
23822 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23824 case OPC_CMPGDU_LE_QB
:
23826 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
23827 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23828 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23829 tcg_gen_shli_tl(t1
, t1
, 24);
23830 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23832 case OPC_CMP_EQ_PH
:
23834 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
23836 case OPC_CMP_LT_PH
:
23838 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
23840 case OPC_CMP_LE_PH
:
23842 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
23846 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23850 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23852 case OPC_PACKRL_PH
:
23854 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23858 #ifdef TARGET_MIPS64
23859 case OPC_CMPU_EQ_OB_DSP
:
23861 case OPC_CMP_EQ_PW
:
23863 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
23865 case OPC_CMP_LT_PW
:
23867 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
23869 case OPC_CMP_LE_PW
:
23871 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
23873 case OPC_CMP_EQ_QH
:
23875 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
23877 case OPC_CMP_LT_QH
:
23879 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
23881 case OPC_CMP_LE_QH
:
23883 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
23885 case OPC_CMPGDU_EQ_OB
:
23887 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23889 case OPC_CMPGDU_LT_OB
:
23891 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23893 case OPC_CMPGDU_LE_OB
:
23895 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23897 case OPC_CMPGU_EQ_OB
:
23899 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23901 case OPC_CMPGU_LT_OB
:
23903 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23905 case OPC_CMPGU_LE_OB
:
23907 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23909 case OPC_CMPU_EQ_OB
:
23911 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
23913 case OPC_CMPU_LT_OB
:
23915 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
23917 case OPC_CMPU_LE_OB
:
23919 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
23921 case OPC_PACKRL_PW
:
23923 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23927 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23931 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23935 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23943 tcg_temp_free(v1_t
);
23944 tcg_temp_free(v2_t
);
23947 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
23948 uint32_t op1
, int rt
, int rs
, int sa
)
23955 /* Treat as NOP. */
23959 t0
= tcg_temp_new();
23960 gen_load_gpr(t0
, rs
);
23963 case OPC_APPEND_DSP
:
23964 switch (MASK_APPEND(ctx
->opcode
)) {
23967 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
23969 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23973 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23974 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23975 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
23976 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23978 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23982 if (sa
!= 0 && sa
!= 2) {
23983 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23984 tcg_gen_ext32u_tl(t0
, t0
);
23985 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
23986 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23988 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23990 default: /* Invalid */
23991 MIPS_INVAL("MASK APPEND");
23992 generate_exception_end(ctx
, EXCP_RI
);
23996 #ifdef TARGET_MIPS64
23997 case OPC_DAPPEND_DSP
:
23998 switch (MASK_DAPPEND(ctx
->opcode
)) {
24001 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
24005 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
24006 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
24007 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
24011 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24012 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
24013 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24018 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
24019 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24020 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
24021 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24024 default: /* Invalid */
24025 MIPS_INVAL("MASK DAPPEND");
24026 generate_exception_end(ctx
, EXCP_RI
);
24035 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24036 int ret
, int v1
, int v2
, int check_ret
)
24045 if ((ret
== 0) && (check_ret
== 1)) {
24046 /* Treat as NOP. */
24050 t0
= tcg_temp_new();
24051 t1
= tcg_temp_new();
24052 v1_t
= tcg_temp_new();
24053 v2_t
= tcg_temp_new();
24055 gen_load_gpr(v1_t
, v1
);
24056 gen_load_gpr(v2_t
, v2
);
24059 case OPC_EXTR_W_DSP
:
24063 tcg_gen_movi_tl(t0
, v2
);
24064 tcg_gen_movi_tl(t1
, v1
);
24065 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24068 tcg_gen_movi_tl(t0
, v2
);
24069 tcg_gen_movi_tl(t1
, v1
);
24070 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24072 case OPC_EXTR_RS_W
:
24073 tcg_gen_movi_tl(t0
, v2
);
24074 tcg_gen_movi_tl(t1
, v1
);
24075 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24078 tcg_gen_movi_tl(t0
, v2
);
24079 tcg_gen_movi_tl(t1
, v1
);
24080 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24082 case OPC_EXTRV_S_H
:
24083 tcg_gen_movi_tl(t0
, v2
);
24084 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24087 tcg_gen_movi_tl(t0
, v2
);
24088 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24090 case OPC_EXTRV_R_W
:
24091 tcg_gen_movi_tl(t0
, v2
);
24092 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24094 case OPC_EXTRV_RS_W
:
24095 tcg_gen_movi_tl(t0
, v2
);
24096 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24099 tcg_gen_movi_tl(t0
, v2
);
24100 tcg_gen_movi_tl(t1
, v1
);
24101 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24104 tcg_gen_movi_tl(t0
, v2
);
24105 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24108 tcg_gen_movi_tl(t0
, v2
);
24109 tcg_gen_movi_tl(t1
, v1
);
24110 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24113 tcg_gen_movi_tl(t0
, v2
);
24114 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24117 imm
= (ctx
->opcode
>> 20) & 0x3F;
24118 tcg_gen_movi_tl(t0
, ret
);
24119 tcg_gen_movi_tl(t1
, imm
);
24120 gen_helper_shilo(t0
, t1
, cpu_env
);
24123 tcg_gen_movi_tl(t0
, ret
);
24124 gen_helper_shilo(t0
, v1_t
, cpu_env
);
24127 tcg_gen_movi_tl(t0
, ret
);
24128 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
24131 imm
= (ctx
->opcode
>> 11) & 0x3FF;
24132 tcg_gen_movi_tl(t0
, imm
);
24133 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
24136 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24137 tcg_gen_movi_tl(t0
, imm
);
24138 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
24142 #ifdef TARGET_MIPS64
24143 case OPC_DEXTR_W_DSP
:
24147 tcg_gen_movi_tl(t0
, ret
);
24148 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
24152 int shift
= (ctx
->opcode
>> 19) & 0x7F;
24153 int ac
= (ctx
->opcode
>> 11) & 0x03;
24154 tcg_gen_movi_tl(t0
, shift
);
24155 tcg_gen_movi_tl(t1
, ac
);
24156 gen_helper_dshilo(t0
, t1
, cpu_env
);
24161 int ac
= (ctx
->opcode
>> 11) & 0x03;
24162 tcg_gen_movi_tl(t0
, ac
);
24163 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24167 tcg_gen_movi_tl(t0
, v2
);
24168 tcg_gen_movi_tl(t1
, v1
);
24170 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24173 tcg_gen_movi_tl(t0
, v2
);
24174 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24177 tcg_gen_movi_tl(t0
, v2
);
24178 tcg_gen_movi_tl(t1
, v1
);
24179 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24182 tcg_gen_movi_tl(t0
, v2
);
24183 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24186 tcg_gen_movi_tl(t0
, v2
);
24187 tcg_gen_movi_tl(t1
, v1
);
24188 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24190 case OPC_DEXTR_R_L
:
24191 tcg_gen_movi_tl(t0
, v2
);
24192 tcg_gen_movi_tl(t1
, v1
);
24193 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24195 case OPC_DEXTR_RS_L
:
24196 tcg_gen_movi_tl(t0
, v2
);
24197 tcg_gen_movi_tl(t1
, v1
);
24198 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24201 tcg_gen_movi_tl(t0
, v2
);
24202 tcg_gen_movi_tl(t1
, v1
);
24203 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24205 case OPC_DEXTR_R_W
:
24206 tcg_gen_movi_tl(t0
, v2
);
24207 tcg_gen_movi_tl(t1
, v1
);
24208 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24210 case OPC_DEXTR_RS_W
:
24211 tcg_gen_movi_tl(t0
, v2
);
24212 tcg_gen_movi_tl(t1
, v1
);
24213 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24215 case OPC_DEXTR_S_H
:
24216 tcg_gen_movi_tl(t0
, v2
);
24217 tcg_gen_movi_tl(t1
, v1
);
24218 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24220 case OPC_DEXTRV_S_H
:
24221 tcg_gen_movi_tl(t0
, v2
);
24222 tcg_gen_movi_tl(t1
, v1
);
24223 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24226 tcg_gen_movi_tl(t0
, v2
);
24227 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24229 case OPC_DEXTRV_R_L
:
24230 tcg_gen_movi_tl(t0
, v2
);
24231 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24233 case OPC_DEXTRV_RS_L
:
24234 tcg_gen_movi_tl(t0
, v2
);
24235 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24238 tcg_gen_movi_tl(t0
, v2
);
24239 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24241 case OPC_DEXTRV_R_W
:
24242 tcg_gen_movi_tl(t0
, v2
);
24243 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24245 case OPC_DEXTRV_RS_W
:
24246 tcg_gen_movi_tl(t0
, v2
);
24247 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24256 tcg_temp_free(v1_t
);
24257 tcg_temp_free(v2_t
);
24260 /* End MIPSDSP functions. */
24262 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24264 int rs
, rt
, rd
, sa
;
24267 rs
= (ctx
->opcode
>> 21) & 0x1f;
24268 rt
= (ctx
->opcode
>> 16) & 0x1f;
24269 rd
= (ctx
->opcode
>> 11) & 0x1f;
24270 sa
= (ctx
->opcode
>> 6) & 0x1f;
24272 op1
= MASK_SPECIAL(ctx
->opcode
);
24275 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24281 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24291 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24294 MIPS_INVAL("special_r6 muldiv");
24295 generate_exception_end(ctx
, EXCP_RI
);
24301 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24305 if (rt
== 0 && sa
== 1) {
24307 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24308 * We need additionally to check other fields.
24310 gen_cl(ctx
, op1
, rd
, rs
);
24312 generate_exception_end(ctx
, EXCP_RI
);
24316 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24317 gen_helper_do_semihosting(cpu_env
);
24319 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24320 generate_exception_end(ctx
, EXCP_RI
);
24322 generate_exception_end(ctx
, EXCP_DBp
);
24326 #if defined(TARGET_MIPS64)
24328 check_mips_64(ctx
);
24329 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24333 if (rt
== 0 && sa
== 1) {
24335 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24336 * We need additionally to check other fields.
24338 check_mips_64(ctx
);
24339 gen_cl(ctx
, op1
, rd
, rs
);
24341 generate_exception_end(ctx
, EXCP_RI
);
24349 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24359 check_mips_64(ctx
);
24360 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24363 MIPS_INVAL("special_r6 muldiv");
24364 generate_exception_end(ctx
, EXCP_RI
);
24369 default: /* Invalid */
24370 MIPS_INVAL("special_r6");
24371 generate_exception_end(ctx
, EXCP_RI
);
24376 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24378 int rs
= extract32(ctx
->opcode
, 21, 5);
24379 int rt
= extract32(ctx
->opcode
, 16, 5);
24380 int rd
= extract32(ctx
->opcode
, 11, 5);
24381 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24384 case OPC_MOVN
: /* Conditional move */
24386 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24388 case OPC_MFHI
: /* Move from HI/LO */
24390 gen_HILO(ctx
, op1
, 0, rd
);
24393 case OPC_MTLO
: /* Move to HI/LO */
24394 gen_HILO(ctx
, op1
, 0, rs
);
24398 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24402 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24404 #if defined(TARGET_MIPS64)
24409 check_insn_opc_user_only(ctx
, INSN_R5900
);
24410 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24414 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24416 default: /* Invalid */
24417 MIPS_INVAL("special_tx79");
24418 generate_exception_end(ctx
, EXCP_RI
);
24423 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24425 int rs
, rt
, rd
, sa
;
24428 rs
= (ctx
->opcode
>> 21) & 0x1f;
24429 rt
= (ctx
->opcode
>> 16) & 0x1f;
24430 rd
= (ctx
->opcode
>> 11) & 0x1f;
24431 sa
= (ctx
->opcode
>> 6) & 0x1f;
24433 op1
= MASK_SPECIAL(ctx
->opcode
);
24435 case OPC_MOVN
: /* Conditional move */
24437 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
24438 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24439 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24441 case OPC_MFHI
: /* Move from HI/LO */
24443 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24446 case OPC_MTLO
: /* Move to HI/LO */
24447 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24450 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
24451 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24452 check_cp1_enabled(ctx
);
24453 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24454 (ctx
->opcode
>> 16) & 1);
24456 generate_exception_err(ctx
, EXCP_CpU
, 1);
24462 check_insn(ctx
, INSN_VR54XX
);
24463 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24464 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24466 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24471 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24473 #if defined(TARGET_MIPS64)
24478 check_insn(ctx
, ISA_MIPS3
);
24479 check_mips_64(ctx
);
24480 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24484 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24487 #ifdef MIPS_STRICT_STANDARD
24488 MIPS_INVAL("SPIM");
24489 generate_exception_end(ctx
, EXCP_RI
);
24491 /* Implemented as RI exception for now. */
24492 MIPS_INVAL("spim (unofficial)");
24493 generate_exception_end(ctx
, EXCP_RI
);
24496 default: /* Invalid */
24497 MIPS_INVAL("special_legacy");
24498 generate_exception_end(ctx
, EXCP_RI
);
24503 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24505 int rs
, rt
, rd
, sa
;
24508 rs
= (ctx
->opcode
>> 21) & 0x1f;
24509 rt
= (ctx
->opcode
>> 16) & 0x1f;
24510 rd
= (ctx
->opcode
>> 11) & 0x1f;
24511 sa
= (ctx
->opcode
>> 6) & 0x1f;
24513 op1
= MASK_SPECIAL(ctx
->opcode
);
24515 case OPC_SLL
: /* Shift with immediate */
24516 if (sa
== 5 && rd
== 0 &&
24517 rs
== 0 && rt
== 0) { /* PAUSE */
24518 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
24519 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24520 generate_exception_end(ctx
, EXCP_RI
);
24526 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24529 switch ((ctx
->opcode
>> 21) & 0x1f) {
24531 /* rotr is decoded as srl on non-R2 CPUs */
24532 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24537 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24540 generate_exception_end(ctx
, EXCP_RI
);
24548 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24550 case OPC_SLLV
: /* Shifts */
24552 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24555 switch ((ctx
->opcode
>> 6) & 0x1f) {
24557 /* rotrv is decoded as srlv on non-R2 CPUs */
24558 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24563 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24566 generate_exception_end(ctx
, EXCP_RI
);
24570 case OPC_SLT
: /* Set on less than */
24572 gen_slt(ctx
, op1
, rd
, rs
, rt
);
24574 case OPC_AND
: /* Logic*/
24578 gen_logic(ctx
, op1
, rd
, rs
, rt
);
24581 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24583 case OPC_TGE
: /* Traps */
24589 check_insn(ctx
, ISA_MIPS2
);
24590 gen_trap(ctx
, op1
, rs
, rt
, -1);
24592 case OPC_LSA
: /* OPC_PMON */
24593 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
24594 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
24595 decode_opc_special_r6(env
, ctx
);
24597 /* Pmon entry point, also R4010 selsl */
24598 #ifdef MIPS_STRICT_STANDARD
24599 MIPS_INVAL("PMON / selsl");
24600 generate_exception_end(ctx
, EXCP_RI
);
24602 gen_helper_0e0i(pmon
, sa
);
24607 generate_exception_end(ctx
, EXCP_SYSCALL
);
24610 generate_exception_end(ctx
, EXCP_BREAK
);
24613 check_insn(ctx
, ISA_MIPS2
);
24614 gen_sync(extract32(ctx
->opcode
, 6, 5));
24617 #if defined(TARGET_MIPS64)
24618 /* MIPS64 specific opcodes */
24623 check_insn(ctx
, ISA_MIPS3
);
24624 check_mips_64(ctx
);
24625 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24628 switch ((ctx
->opcode
>> 21) & 0x1f) {
24630 /* drotr is decoded as dsrl on non-R2 CPUs */
24631 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24636 check_insn(ctx
, ISA_MIPS3
);
24637 check_mips_64(ctx
);
24638 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24641 generate_exception_end(ctx
, EXCP_RI
);
24646 switch ((ctx
->opcode
>> 21) & 0x1f) {
24648 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24649 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24654 check_insn(ctx
, ISA_MIPS3
);
24655 check_mips_64(ctx
);
24656 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24659 generate_exception_end(ctx
, EXCP_RI
);
24667 check_insn(ctx
, ISA_MIPS3
);
24668 check_mips_64(ctx
);
24669 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24673 check_insn(ctx
, ISA_MIPS3
);
24674 check_mips_64(ctx
);
24675 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24678 switch ((ctx
->opcode
>> 6) & 0x1f) {
24680 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24681 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24686 check_insn(ctx
, ISA_MIPS3
);
24687 check_mips_64(ctx
);
24688 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24691 generate_exception_end(ctx
, EXCP_RI
);
24696 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
24697 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
24698 decode_opc_special_r6(env
, ctx
);
24703 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
24704 decode_opc_special_r6(env
, ctx
);
24705 } else if (ctx
->insn_flags
& INSN_R5900
) {
24706 decode_opc_special_tx79(env
, ctx
);
24708 decode_opc_special_legacy(env
, ctx
);
24714 #if defined(TARGET_MIPS64)
24718 * MMI (MultiMedia Interface) ASE instructions
24719 * ===========================================
24723 * MMI instructions category: data communication
24724 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24726 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24727 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24728 * PCPYUD PEXEH PEXTLW PPACW
24737 * Parallel Copy Halfword
24739 * 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
24740 * +-----------+---------+---------+---------+---------+-----------+
24741 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
24742 * +-----------+---------+---------+---------+---------+-----------+
24744 static void gen_mmi_pcpyh(DisasContext
*ctx
)
24746 uint32_t pd
, rt
, rd
;
24749 opcode
= ctx
->opcode
;
24751 pd
= extract32(opcode
, 21, 5);
24752 rt
= extract32(opcode
, 16, 5);
24753 rd
= extract32(opcode
, 11, 5);
24755 if (unlikely(pd
!= 0)) {
24756 generate_exception_end(ctx
, EXCP_RI
);
24757 } else if (rd
== 0) {
24759 } else if (rt
== 0) {
24760 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24761 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24763 TCGv_i64 t0
= tcg_temp_new();
24764 TCGv_i64 t1
= tcg_temp_new();
24765 uint64_t mask
= (1ULL << 16) - 1;
24767 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
24768 tcg_gen_movi_i64(t1
, 0);
24769 tcg_gen_or_i64(t1
, t0
, t1
);
24770 tcg_gen_shli_i64(t0
, t0
, 16);
24771 tcg_gen_or_i64(t1
, t0
, t1
);
24772 tcg_gen_shli_i64(t0
, t0
, 16);
24773 tcg_gen_or_i64(t1
, t0
, t1
);
24774 tcg_gen_shli_i64(t0
, t0
, 16);
24775 tcg_gen_or_i64(t1
, t0
, t1
);
24777 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
24779 tcg_gen_andi_i64(t0
, cpu_mmr
[rt
], mask
);
24780 tcg_gen_movi_i64(t1
, 0);
24781 tcg_gen_or_i64(t1
, t0
, t1
);
24782 tcg_gen_shli_i64(t0
, t0
, 16);
24783 tcg_gen_or_i64(t1
, t0
, t1
);
24784 tcg_gen_shli_i64(t0
, t0
, 16);
24785 tcg_gen_or_i64(t1
, t0
, t1
);
24786 tcg_gen_shli_i64(t0
, t0
, 16);
24787 tcg_gen_or_i64(t1
, t0
, t1
);
24789 tcg_gen_mov_i64(cpu_mmr
[rd
], t1
);
24797 * PCPYLD rd, rs, rt
24799 * Parallel Copy Lower Doubleword
24801 * 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
24802 * +-----------+---------+---------+---------+---------+-----------+
24803 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
24804 * +-----------+---------+---------+---------+---------+-----------+
24806 static void gen_mmi_pcpyld(DisasContext
*ctx
)
24808 uint32_t rs
, rt
, rd
;
24811 opcode
= ctx
->opcode
;
24813 rs
= extract32(opcode
, 21, 5);
24814 rt
= extract32(opcode
, 16, 5);
24815 rd
= extract32(opcode
, 11, 5);
24821 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24823 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_gpr
[rs
]);
24826 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24829 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
24836 * PCPYUD rd, rs, rt
24838 * Parallel Copy Upper Doubleword
24840 * 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
24841 * +-----------+---------+---------+---------+---------+-----------+
24842 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
24843 * +-----------+---------+---------+---------+---------+-----------+
24845 static void gen_mmi_pcpyud(DisasContext
*ctx
)
24847 uint32_t rs
, rt
, rd
;
24850 opcode
= ctx
->opcode
;
24852 rs
= extract32(opcode
, 21, 5);
24853 rt
= extract32(opcode
, 16, 5);
24854 rd
= extract32(opcode
, 11, 5);
24860 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24862 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_mmr
[rs
]);
24865 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24868 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_mmr
[rt
]);
24877 #if !defined(TARGET_MIPS64)
24879 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24880 #define MXU_APTN1_A 0
24881 #define MXU_APTN1_S 1
24883 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24884 #define MXU_APTN2_AA 0
24885 #define MXU_APTN2_AS 1
24886 #define MXU_APTN2_SA 2
24887 #define MXU_APTN2_SS 3
24889 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24890 #define MXU_EPTN2_AA 0
24891 #define MXU_EPTN2_AS 1
24892 #define MXU_EPTN2_SA 2
24893 #define MXU_EPTN2_SS 3
24895 /* MXU operand getting pattern 'optn2' */
24896 #define MXU_OPTN2_PTN0 0
24897 #define MXU_OPTN2_PTN1 1
24898 #define MXU_OPTN2_PTN2 2
24899 #define MXU_OPTN2_PTN3 3
24900 /* alternative naming scheme for 'optn2' */
24901 #define MXU_OPTN2_WW 0
24902 #define MXU_OPTN2_LW 1
24903 #define MXU_OPTN2_HW 2
24904 #define MXU_OPTN2_XW 3
24906 /* MXU operand getting pattern 'optn3' */
24907 #define MXU_OPTN3_PTN0 0
24908 #define MXU_OPTN3_PTN1 1
24909 #define MXU_OPTN3_PTN2 2
24910 #define MXU_OPTN3_PTN3 3
24911 #define MXU_OPTN3_PTN4 4
24912 #define MXU_OPTN3_PTN5 5
24913 #define MXU_OPTN3_PTN6 6
24914 #define MXU_OPTN3_PTN7 7
24918 * S32I2M XRa, rb - Register move from GRF to XRF
24920 static void gen_mxu_s32i2m(DisasContext
*ctx
)
24925 t0
= tcg_temp_new();
24927 XRa
= extract32(ctx
->opcode
, 6, 5);
24928 Rb
= extract32(ctx
->opcode
, 16, 5);
24930 gen_load_gpr(t0
, Rb
);
24932 gen_store_mxu_gpr(t0
, XRa
);
24933 } else if (XRa
== 16) {
24934 gen_store_mxu_cr(t0
);
24941 * S32M2I XRa, rb - Register move from XRF to GRF
24943 static void gen_mxu_s32m2i(DisasContext
*ctx
)
24948 t0
= tcg_temp_new();
24950 XRa
= extract32(ctx
->opcode
, 6, 5);
24951 Rb
= extract32(ctx
->opcode
, 16, 5);
24954 gen_load_mxu_gpr(t0
, XRa
);
24955 } else if (XRa
== 16) {
24956 gen_load_mxu_cr(t0
);
24959 gen_store_gpr(t0
, Rb
);
24965 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24967 static void gen_mxu_s8ldd(DisasContext
*ctx
)
24970 uint32_t XRa
, Rb
, s8
, optn3
;
24972 t0
= tcg_temp_new();
24973 t1
= tcg_temp_new();
24975 XRa
= extract32(ctx
->opcode
, 6, 4);
24976 s8
= extract32(ctx
->opcode
, 10, 8);
24977 optn3
= extract32(ctx
->opcode
, 18, 3);
24978 Rb
= extract32(ctx
->opcode
, 21, 5);
24980 gen_load_gpr(t0
, Rb
);
24981 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
24984 /* XRa[7:0] = tmp8 */
24985 case MXU_OPTN3_PTN0
:
24986 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24987 gen_load_mxu_gpr(t0
, XRa
);
24988 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
24990 /* XRa[15:8] = tmp8 */
24991 case MXU_OPTN3_PTN1
:
24992 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24993 gen_load_mxu_gpr(t0
, XRa
);
24994 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
24996 /* XRa[23:16] = tmp8 */
24997 case MXU_OPTN3_PTN2
:
24998 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24999 gen_load_mxu_gpr(t0
, XRa
);
25000 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
25002 /* XRa[31:24] = tmp8 */
25003 case MXU_OPTN3_PTN3
:
25004 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25005 gen_load_mxu_gpr(t0
, XRa
);
25006 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
25008 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25009 case MXU_OPTN3_PTN4
:
25010 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25011 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25013 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25014 case MXU_OPTN3_PTN5
:
25015 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25016 tcg_gen_shli_tl(t1
, t1
, 8);
25017 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25019 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25020 case MXU_OPTN3_PTN6
:
25021 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
25022 tcg_gen_mov_tl(t0
, t1
);
25023 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
25024 tcg_gen_shli_tl(t1
, t1
, 16);
25025 tcg_gen_or_tl(t0
, t0
, t1
);
25027 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25028 case MXU_OPTN3_PTN7
:
25029 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25030 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
25031 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25035 gen_store_mxu_gpr(t0
, XRa
);
25042 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25044 static void gen_mxu_d16mul(DisasContext
*ctx
)
25046 TCGv t0
, t1
, t2
, t3
;
25047 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
25049 t0
= tcg_temp_new();
25050 t1
= tcg_temp_new();
25051 t2
= tcg_temp_new();
25052 t3
= tcg_temp_new();
25054 XRa
= extract32(ctx
->opcode
, 6, 4);
25055 XRb
= extract32(ctx
->opcode
, 10, 4);
25056 XRc
= extract32(ctx
->opcode
, 14, 4);
25057 XRd
= extract32(ctx
->opcode
, 18, 4);
25058 optn2
= extract32(ctx
->opcode
, 22, 2);
25060 gen_load_mxu_gpr(t1
, XRb
);
25061 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25062 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25063 gen_load_mxu_gpr(t3
, XRc
);
25064 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25065 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25068 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25069 tcg_gen_mul_tl(t3
, t1
, t3
);
25070 tcg_gen_mul_tl(t2
, t0
, t2
);
25072 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25073 tcg_gen_mul_tl(t3
, t0
, t3
);
25074 tcg_gen_mul_tl(t2
, t0
, t2
);
25076 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25077 tcg_gen_mul_tl(t3
, t1
, t3
);
25078 tcg_gen_mul_tl(t2
, t1
, t2
);
25080 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25081 tcg_gen_mul_tl(t3
, t0
, t3
);
25082 tcg_gen_mul_tl(t2
, t1
, t2
);
25085 gen_store_mxu_gpr(t3
, XRa
);
25086 gen_store_mxu_gpr(t2
, XRd
);
25095 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25098 static void gen_mxu_d16mac(DisasContext
*ctx
)
25100 TCGv t0
, t1
, t2
, t3
;
25101 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
25103 t0
= tcg_temp_new();
25104 t1
= tcg_temp_new();
25105 t2
= tcg_temp_new();
25106 t3
= tcg_temp_new();
25108 XRa
= extract32(ctx
->opcode
, 6, 4);
25109 XRb
= extract32(ctx
->opcode
, 10, 4);
25110 XRc
= extract32(ctx
->opcode
, 14, 4);
25111 XRd
= extract32(ctx
->opcode
, 18, 4);
25112 optn2
= extract32(ctx
->opcode
, 22, 2);
25113 aptn2
= extract32(ctx
->opcode
, 24, 2);
25115 gen_load_mxu_gpr(t1
, XRb
);
25116 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25117 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25119 gen_load_mxu_gpr(t3
, XRc
);
25120 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25121 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25124 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25125 tcg_gen_mul_tl(t3
, t1
, t3
);
25126 tcg_gen_mul_tl(t2
, t0
, t2
);
25128 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25129 tcg_gen_mul_tl(t3
, t0
, t3
);
25130 tcg_gen_mul_tl(t2
, t0
, t2
);
25132 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25133 tcg_gen_mul_tl(t3
, t1
, t3
);
25134 tcg_gen_mul_tl(t2
, t1
, t2
);
25136 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25137 tcg_gen_mul_tl(t3
, t0
, t3
);
25138 tcg_gen_mul_tl(t2
, t1
, t2
);
25141 gen_load_mxu_gpr(t0
, XRa
);
25142 gen_load_mxu_gpr(t1
, XRd
);
25146 tcg_gen_add_tl(t3
, t0
, t3
);
25147 tcg_gen_add_tl(t2
, t1
, t2
);
25150 tcg_gen_add_tl(t3
, t0
, t3
);
25151 tcg_gen_sub_tl(t2
, t1
, t2
);
25154 tcg_gen_sub_tl(t3
, t0
, t3
);
25155 tcg_gen_add_tl(t2
, t1
, t2
);
25158 tcg_gen_sub_tl(t3
, t0
, t3
);
25159 tcg_gen_sub_tl(t2
, t1
, t2
);
25162 gen_store_mxu_gpr(t3
, XRa
);
25163 gen_store_mxu_gpr(t2
, XRd
);
25172 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25173 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25175 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25177 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25178 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25180 t0
= tcg_temp_new();
25181 t1
= tcg_temp_new();
25182 t2
= tcg_temp_new();
25183 t3
= tcg_temp_new();
25184 t4
= tcg_temp_new();
25185 t5
= tcg_temp_new();
25186 t6
= tcg_temp_new();
25187 t7
= tcg_temp_new();
25189 XRa
= extract32(ctx
->opcode
, 6, 4);
25190 XRb
= extract32(ctx
->opcode
, 10, 4);
25191 XRc
= extract32(ctx
->opcode
, 14, 4);
25192 XRd
= extract32(ctx
->opcode
, 18, 4);
25193 sel
= extract32(ctx
->opcode
, 22, 2);
25195 gen_load_mxu_gpr(t3
, XRb
);
25196 gen_load_mxu_gpr(t7
, XRc
);
25200 tcg_gen_ext8s_tl(t0
, t3
);
25201 tcg_gen_shri_tl(t3
, t3
, 8);
25202 tcg_gen_ext8s_tl(t1
, t3
);
25203 tcg_gen_shri_tl(t3
, t3
, 8);
25204 tcg_gen_ext8s_tl(t2
, t3
);
25205 tcg_gen_shri_tl(t3
, t3
, 8);
25206 tcg_gen_ext8s_tl(t3
, t3
);
25209 tcg_gen_ext8u_tl(t0
, t3
);
25210 tcg_gen_shri_tl(t3
, t3
, 8);
25211 tcg_gen_ext8u_tl(t1
, t3
);
25212 tcg_gen_shri_tl(t3
, t3
, 8);
25213 tcg_gen_ext8u_tl(t2
, t3
);
25214 tcg_gen_shri_tl(t3
, t3
, 8);
25215 tcg_gen_ext8u_tl(t3
, t3
);
25218 tcg_gen_ext8u_tl(t4
, t7
);
25219 tcg_gen_shri_tl(t7
, t7
, 8);
25220 tcg_gen_ext8u_tl(t5
, t7
);
25221 tcg_gen_shri_tl(t7
, t7
, 8);
25222 tcg_gen_ext8u_tl(t6
, t7
);
25223 tcg_gen_shri_tl(t7
, t7
, 8);
25224 tcg_gen_ext8u_tl(t7
, t7
);
25226 tcg_gen_mul_tl(t0
, t0
, t4
);
25227 tcg_gen_mul_tl(t1
, t1
, t5
);
25228 tcg_gen_mul_tl(t2
, t2
, t6
);
25229 tcg_gen_mul_tl(t3
, t3
, t7
);
25231 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25232 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25233 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25234 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25236 tcg_gen_shli_tl(t1
, t1
, 16);
25237 tcg_gen_shli_tl(t3
, t3
, 16);
25239 tcg_gen_or_tl(t0
, t0
, t1
);
25240 tcg_gen_or_tl(t1
, t2
, t3
);
25242 gen_store_mxu_gpr(t0
, XRd
);
25243 gen_store_mxu_gpr(t1
, XRa
);
25256 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25257 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25259 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25262 uint32_t XRa
, Rb
, s12
, sel
;
25264 t0
= tcg_temp_new();
25265 t1
= tcg_temp_new();
25267 XRa
= extract32(ctx
->opcode
, 6, 4);
25268 s12
= extract32(ctx
->opcode
, 10, 10);
25269 sel
= extract32(ctx
->opcode
, 20, 1);
25270 Rb
= extract32(ctx
->opcode
, 21, 5);
25272 gen_load_gpr(t0
, Rb
);
25274 tcg_gen_movi_tl(t1
, s12
);
25275 tcg_gen_shli_tl(t1
, t1
, 2);
25277 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25279 tcg_gen_add_tl(t1
, t0
, t1
);
25280 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25284 tcg_gen_bswap32_tl(t1
, t1
);
25286 gen_store_mxu_gpr(t1
, XRa
);
25294 * MXU instruction category: logic
25295 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25297 * S32NOR S32AND S32OR S32XOR
25301 * S32NOR XRa, XRb, XRc
25302 * Update XRa with the result of logical bitwise 'nor' operation
25303 * applied to the content of XRb and XRc.
25305 * 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
25306 * +-----------+---------+-----+-------+-------+-------+-----------+
25307 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25308 * +-----------+---------+-----+-------+-------+-------+-----------+
25310 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25312 uint32_t pad
, XRc
, XRb
, XRa
;
25314 pad
= extract32(ctx
->opcode
, 21, 5);
25315 XRc
= extract32(ctx
->opcode
, 14, 4);
25316 XRb
= extract32(ctx
->opcode
, 10, 4);
25317 XRa
= extract32(ctx
->opcode
, 6, 4);
25319 if (unlikely(pad
!= 0)) {
25320 /* opcode padding incorrect -> do nothing */
25321 } else if (unlikely(XRa
== 0)) {
25322 /* destination is zero register -> do nothing */
25323 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25324 /* both operands zero registers -> just set destination to all 1s */
25325 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25326 } else if (unlikely(XRb
== 0)) {
25327 /* XRb zero register -> just set destination to the negation of XRc */
25328 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25329 } else if (unlikely(XRc
== 0)) {
25330 /* XRa zero register -> just set destination to the negation of XRb */
25331 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25332 } else if (unlikely(XRb
== XRc
)) {
25333 /* both operands same -> just set destination to the negation of XRb */
25334 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25336 /* the most general case */
25337 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25342 * S32AND XRa, XRb, XRc
25343 * Update XRa with the result of logical bitwise 'and' operation
25344 * applied to the content of XRb and XRc.
25346 * 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
25347 * +-----------+---------+-----+-------+-------+-------+-----------+
25348 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25349 * +-----------+---------+-----+-------+-------+-------+-----------+
25351 static void gen_mxu_S32AND(DisasContext
*ctx
)
25353 uint32_t pad
, XRc
, XRb
, XRa
;
25355 pad
= extract32(ctx
->opcode
, 21, 5);
25356 XRc
= extract32(ctx
->opcode
, 14, 4);
25357 XRb
= extract32(ctx
->opcode
, 10, 4);
25358 XRa
= extract32(ctx
->opcode
, 6, 4);
25360 if (unlikely(pad
!= 0)) {
25361 /* opcode padding incorrect -> do nothing */
25362 } else if (unlikely(XRa
== 0)) {
25363 /* destination is zero register -> do nothing */
25364 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25365 /* one of operands zero register -> just set destination to all 0s */
25366 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25367 } else if (unlikely(XRb
== XRc
)) {
25368 /* both operands same -> just set destination to one of them */
25369 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25371 /* the most general case */
25372 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25377 * S32OR XRa, XRb, XRc
25378 * Update XRa with the result of logical bitwise 'or' operation
25379 * applied to the content of XRb and XRc.
25381 * 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
25382 * +-----------+---------+-----+-------+-------+-------+-----------+
25383 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25384 * +-----------+---------+-----+-------+-------+-------+-----------+
25386 static void gen_mxu_S32OR(DisasContext
*ctx
)
25388 uint32_t pad
, XRc
, XRb
, XRa
;
25390 pad
= extract32(ctx
->opcode
, 21, 5);
25391 XRc
= extract32(ctx
->opcode
, 14, 4);
25392 XRb
= extract32(ctx
->opcode
, 10, 4);
25393 XRa
= extract32(ctx
->opcode
, 6, 4);
25395 if (unlikely(pad
!= 0)) {
25396 /* opcode padding incorrect -> do nothing */
25397 } else if (unlikely(XRa
== 0)) {
25398 /* destination is zero register -> do nothing */
25399 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25400 /* both operands zero registers -> just set destination to all 0s */
25401 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25402 } else if (unlikely(XRb
== 0)) {
25403 /* XRb zero register -> just set destination to the content of XRc */
25404 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25405 } else if (unlikely(XRc
== 0)) {
25406 /* XRc zero register -> just set destination to the content of XRb */
25407 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25408 } else if (unlikely(XRb
== XRc
)) {
25409 /* both operands same -> just set destination to one of them */
25410 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25412 /* the most general case */
25413 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25418 * S32XOR XRa, XRb, XRc
25419 * Update XRa with the result of logical bitwise 'xor' operation
25420 * applied to the content of XRb and XRc.
25422 * 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
25423 * +-----------+---------+-----+-------+-------+-------+-----------+
25424 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25425 * +-----------+---------+-----+-------+-------+-------+-----------+
25427 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25429 uint32_t pad
, XRc
, XRb
, XRa
;
25431 pad
= extract32(ctx
->opcode
, 21, 5);
25432 XRc
= extract32(ctx
->opcode
, 14, 4);
25433 XRb
= extract32(ctx
->opcode
, 10, 4);
25434 XRa
= extract32(ctx
->opcode
, 6, 4);
25436 if (unlikely(pad
!= 0)) {
25437 /* opcode padding incorrect -> do nothing */
25438 } else if (unlikely(XRa
== 0)) {
25439 /* destination is zero register -> do nothing */
25440 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25441 /* both operands zero registers -> just set destination to all 0s */
25442 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25443 } else if (unlikely(XRb
== 0)) {
25444 /* XRb zero register -> just set destination to the content of XRc */
25445 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25446 } else if (unlikely(XRc
== 0)) {
25447 /* XRc zero register -> just set destination to the content of XRb */
25448 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25449 } else if (unlikely(XRb
== XRc
)) {
25450 /* both operands same -> just set destination to all 0s */
25451 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25453 /* the most general case */
25454 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25460 * MXU instruction category max/min
25461 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25463 * S32MAX D16MAX Q8MAX
25464 * S32MIN D16MIN Q8MIN
25468 * S32MAX XRa, XRb, XRc
25469 * Update XRa with the maximum of signed 32-bit integers contained
25472 * S32MIN XRa, XRb, XRc
25473 * Update XRa with the minimum of signed 32-bit integers contained
25476 * 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
25477 * +-----------+---------+-----+-------+-------+-------+-----------+
25478 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25479 * +-----------+---------+-----+-------+-------+-------+-----------+
25481 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25483 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25485 pad
= extract32(ctx
->opcode
, 21, 5);
25486 opc
= extract32(ctx
->opcode
, 18, 3);
25487 XRc
= extract32(ctx
->opcode
, 14, 4);
25488 XRb
= extract32(ctx
->opcode
, 10, 4);
25489 XRa
= extract32(ctx
->opcode
, 6, 4);
25491 if (unlikely(pad
!= 0)) {
25492 /* opcode padding incorrect -> do nothing */
25493 } else if (unlikely(XRa
== 0)) {
25494 /* destination is zero register -> do nothing */
25495 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25496 /* both operands zero registers -> just set destination to zero */
25497 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25498 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25499 /* exactly one operand is zero register - find which one is not...*/
25500 uint32_t XRx
= XRb
? XRb
: XRc
;
25501 /* ...and do max/min operation with one operand 0 */
25502 if (opc
== OPC_MXU_S32MAX
) {
25503 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25505 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25507 } else if (unlikely(XRb
== XRc
)) {
25508 /* both operands same -> just set destination to one of them */
25509 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25511 /* the most general case */
25512 if (opc
== OPC_MXU_S32MAX
) {
25513 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25516 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25524 * Update XRa with the 16-bit-wise maximums of signed integers
25525 * contained in XRb and XRc.
25528 * Update XRa with the 16-bit-wise minimums of signed integers
25529 * contained in XRb and XRc.
25531 * 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
25532 * +-----------+---------+-----+-------+-------+-------+-----------+
25533 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25534 * +-----------+---------+-----+-------+-------+-------+-----------+
25536 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25538 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25540 pad
= extract32(ctx
->opcode
, 21, 5);
25541 opc
= extract32(ctx
->opcode
, 18, 3);
25542 XRc
= extract32(ctx
->opcode
, 14, 4);
25543 XRb
= extract32(ctx
->opcode
, 10, 4);
25544 XRa
= extract32(ctx
->opcode
, 6, 4);
25546 if (unlikely(pad
!= 0)) {
25547 /* opcode padding incorrect -> do nothing */
25548 } else if (unlikely(XRc
== 0)) {
25549 /* destination is zero register -> do nothing */
25550 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
25551 /* both operands zero registers -> just set destination to zero */
25552 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
25553 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
25554 /* exactly one operand is zero register - find which one is not...*/
25555 uint32_t XRx
= XRb
? XRb
: XRc
;
25556 /* ...and do half-word-wise max/min with one operand 0 */
25557 TCGv_i32 t0
= tcg_temp_new();
25558 TCGv_i32 t1
= tcg_const_i32(0);
25560 /* the left half-word first */
25561 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
25562 if (opc
== OPC_MXU_D16MAX
) {
25563 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25565 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25568 /* the right half-word */
25569 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
25570 /* move half-words to the leftmost position */
25571 tcg_gen_shli_i32(t0
, t0
, 16);
25572 /* t0 will be max/min of t0 and t1 */
25573 if (opc
== OPC_MXU_D16MAX
) {
25574 tcg_gen_smax_i32(t0
, t0
, t1
);
25576 tcg_gen_smin_i32(t0
, t0
, t1
);
25578 /* return resulting half-words to its original position */
25579 tcg_gen_shri_i32(t0
, t0
, 16);
25580 /* finaly update the destination */
25581 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25585 } else if (unlikely(XRb
== XRc
)) {
25586 /* both operands same -> just set destination to one of them */
25587 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25589 /* the most general case */
25590 TCGv_i32 t0
= tcg_temp_new();
25591 TCGv_i32 t1
= tcg_temp_new();
25593 /* the left half-word first */
25594 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
25595 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25596 if (opc
== OPC_MXU_D16MAX
) {
25597 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25599 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25602 /* the right half-word */
25603 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25604 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
25605 /* move half-words to the leftmost position */
25606 tcg_gen_shli_i32(t0
, t0
, 16);
25607 tcg_gen_shli_i32(t1
, t1
, 16);
25608 /* t0 will be max/min of t0 and t1 */
25609 if (opc
== OPC_MXU_D16MAX
) {
25610 tcg_gen_smax_i32(t0
, t0
, t1
);
25612 tcg_gen_smin_i32(t0
, t0
, t1
);
25614 /* return resulting half-words to its original position */
25615 tcg_gen_shri_i32(t0
, t0
, 16);
25616 /* finaly update the destination */
25617 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25626 * Update XRa with the 8-bit-wise maximums of signed integers
25627 * contained in XRb and XRc.
25630 * Update XRa with the 8-bit-wise minimums of signed integers
25631 * contained in XRb and XRc.
25633 * 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
25634 * +-----------+---------+-----+-------+-------+-------+-----------+
25635 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25636 * +-----------+---------+-----+-------+-------+-------+-----------+
25638 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
25640 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25642 pad
= extract32(ctx
->opcode
, 21, 5);
25643 opc
= extract32(ctx
->opcode
, 18, 3);
25644 XRc
= extract32(ctx
->opcode
, 14, 4);
25645 XRb
= extract32(ctx
->opcode
, 10, 4);
25646 XRa
= extract32(ctx
->opcode
, 6, 4);
25648 if (unlikely(pad
!= 0)) {
25649 /* opcode padding incorrect -> do nothing */
25650 } else if (unlikely(XRa
== 0)) {
25651 /* destination is zero register -> do nothing */
25652 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25653 /* both operands zero registers -> just set destination to zero */
25654 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25655 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25656 /* exactly one operand is zero register - make it be the first...*/
25657 uint32_t XRx
= XRb
? XRb
: XRc
;
25658 /* ...and do byte-wise max/min with one operand 0 */
25659 TCGv_i32 t0
= tcg_temp_new();
25660 TCGv_i32 t1
= tcg_const_i32(0);
25663 /* the leftmost byte (byte 3) first */
25664 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
25665 if (opc
== OPC_MXU_Q8MAX
) {
25666 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25668 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25671 /* bytes 2, 1, 0 */
25672 for (i
= 2; i
>= 0; i
--) {
25673 /* extract the byte */
25674 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
25675 /* move the byte to the leftmost position */
25676 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25677 /* t0 will be max/min of t0 and t1 */
25678 if (opc
== OPC_MXU_Q8MAX
) {
25679 tcg_gen_smax_i32(t0
, t0
, t1
);
25681 tcg_gen_smin_i32(t0
, t0
, t1
);
25683 /* return resulting byte to its original position */
25684 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25685 /* finaly update the destination */
25686 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25691 } else if (unlikely(XRb
== XRc
)) {
25692 /* both operands same -> just set destination to one of them */
25693 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25695 /* the most general case */
25696 TCGv_i32 t0
= tcg_temp_new();
25697 TCGv_i32 t1
= tcg_temp_new();
25700 /* the leftmost bytes (bytes 3) first */
25701 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
25702 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25703 if (opc
== OPC_MXU_Q8MAX
) {
25704 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25706 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25709 /* bytes 2, 1, 0 */
25710 for (i
= 2; i
>= 0; i
--) {
25711 /* extract corresponding bytes */
25712 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
25713 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
25714 /* move the bytes to the leftmost position */
25715 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25716 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
25717 /* t0 will be max/min of t0 and t1 */
25718 if (opc
== OPC_MXU_Q8MAX
) {
25719 tcg_gen_smax_i32(t0
, t0
, t1
);
25721 tcg_gen_smin_i32(t0
, t0
, t1
);
25723 /* return resulting byte to its original position */
25724 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25725 /* finaly update the destination */
25726 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25736 * MXU instruction category: align
25737 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25743 * S32ALNI XRc, XRb, XRa, optn3
25744 * Arrange bytes from XRb and XRc according to one of five sets of
25745 * rules determined by optn3, and place the result in XRa.
25747 * 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
25748 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25749 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25750 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25753 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
25755 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
25757 optn3
= extract32(ctx
->opcode
, 23, 3);
25758 pad
= extract32(ctx
->opcode
, 21, 2);
25759 XRc
= extract32(ctx
->opcode
, 14, 4);
25760 XRb
= extract32(ctx
->opcode
, 10, 4);
25761 XRa
= extract32(ctx
->opcode
, 6, 4);
25763 if (unlikely(pad
!= 0)) {
25764 /* opcode padding incorrect -> do nothing */
25765 } else if (unlikely(XRa
== 0)) {
25766 /* destination is zero register -> do nothing */
25767 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25768 /* both operands zero registers -> just set destination to all 0s */
25769 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25770 } else if (unlikely(XRb
== 0)) {
25771 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25773 case MXU_OPTN3_PTN0
:
25774 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25776 case MXU_OPTN3_PTN1
:
25777 case MXU_OPTN3_PTN2
:
25778 case MXU_OPTN3_PTN3
:
25779 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
25782 case MXU_OPTN3_PTN4
:
25783 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25786 } else if (unlikely(XRc
== 0)) {
25787 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25789 case MXU_OPTN3_PTN0
:
25790 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25792 case MXU_OPTN3_PTN1
:
25793 case MXU_OPTN3_PTN2
:
25794 case MXU_OPTN3_PTN3
:
25795 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25797 case MXU_OPTN3_PTN4
:
25798 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25801 } else if (unlikely(XRb
== XRc
)) {
25802 /* both operands same -> just rotation or moving from any of them */
25804 case MXU_OPTN3_PTN0
:
25805 case MXU_OPTN3_PTN4
:
25806 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25808 case MXU_OPTN3_PTN1
:
25809 case MXU_OPTN3_PTN2
:
25810 case MXU_OPTN3_PTN3
:
25811 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25815 /* the most general case */
25817 case MXU_OPTN3_PTN0
:
25821 /* +---------------+ */
25822 /* | A B C D | E F G H */
25823 /* +-------+-------+ */
25828 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25831 case MXU_OPTN3_PTN1
:
25835 /* +-------------------+ */
25836 /* A | B C D E | F G H */
25837 /* +---------+---------+ */
25842 TCGv_i32 t0
= tcg_temp_new();
25843 TCGv_i32 t1
= tcg_temp_new();
25845 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
25846 tcg_gen_shli_i32(t0
, t0
, 8);
25848 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25849 tcg_gen_shri_i32(t1
, t1
, 24);
25851 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25857 case MXU_OPTN3_PTN2
:
25861 /* +-------------------+ */
25862 /* A B | C D E F | G H */
25863 /* +---------+---------+ */
25868 TCGv_i32 t0
= tcg_temp_new();
25869 TCGv_i32 t1
= tcg_temp_new();
25871 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25872 tcg_gen_shli_i32(t0
, t0
, 16);
25874 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25875 tcg_gen_shri_i32(t1
, t1
, 16);
25877 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25883 case MXU_OPTN3_PTN3
:
25887 /* +-------------------+ */
25888 /* A B C | D E F G | H */
25889 /* +---------+---------+ */
25894 TCGv_i32 t0
= tcg_temp_new();
25895 TCGv_i32 t1
= tcg_temp_new();
25897 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
25898 tcg_gen_shli_i32(t0
, t0
, 24);
25900 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
25901 tcg_gen_shri_i32(t1
, t1
, 8);
25903 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25909 case MXU_OPTN3_PTN4
:
25913 /* +---------------+ */
25914 /* A B C D | E F G H | */
25915 /* +-------+-------+ */
25920 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25929 * Decoding engine for MXU
25930 * =======================
25935 * Decode MXU pool00
25937 * 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
25938 * +-----------+---------+-----+-------+-------+-------+-----------+
25939 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25940 * +-----------+---------+-----+-------+-------+-------+-----------+
25943 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
25945 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25948 case OPC_MXU_S32MAX
:
25949 case OPC_MXU_S32MIN
:
25950 gen_mxu_S32MAX_S32MIN(ctx
);
25952 case OPC_MXU_D16MAX
:
25953 case OPC_MXU_D16MIN
:
25954 gen_mxu_D16MAX_D16MIN(ctx
);
25956 case OPC_MXU_Q8MAX
:
25957 case OPC_MXU_Q8MIN
:
25958 gen_mxu_Q8MAX_Q8MIN(ctx
);
25960 case OPC_MXU_Q8SLT
:
25961 /* TODO: Implement emulation of Q8SLT instruction. */
25962 MIPS_INVAL("OPC_MXU_Q8SLT");
25963 generate_exception_end(ctx
, EXCP_RI
);
25965 case OPC_MXU_Q8SLTU
:
25966 /* TODO: Implement emulation of Q8SLTU instruction. */
25967 MIPS_INVAL("OPC_MXU_Q8SLTU");
25968 generate_exception_end(ctx
, EXCP_RI
);
25971 MIPS_INVAL("decode_opc_mxu");
25972 generate_exception_end(ctx
, EXCP_RI
);
25979 * Decode MXU pool01
25981 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25982 * 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
25983 * +-----------+---------+-----+-------+-------+-------+-----------+
25984 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25985 * +-----------+---------+-----+-------+-------+-------+-----------+
25988 * 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
25989 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25990 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25991 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25994 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
25996 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25999 case OPC_MXU_S32SLT
:
26000 /* TODO: Implement emulation of S32SLT instruction. */
26001 MIPS_INVAL("OPC_MXU_S32SLT");
26002 generate_exception_end(ctx
, EXCP_RI
);
26004 case OPC_MXU_D16SLT
:
26005 /* TODO: Implement emulation of D16SLT instruction. */
26006 MIPS_INVAL("OPC_MXU_D16SLT");
26007 generate_exception_end(ctx
, EXCP_RI
);
26009 case OPC_MXU_D16AVG
:
26010 /* TODO: Implement emulation of D16AVG instruction. */
26011 MIPS_INVAL("OPC_MXU_D16AVG");
26012 generate_exception_end(ctx
, EXCP_RI
);
26014 case OPC_MXU_D16AVGR
:
26015 /* TODO: Implement emulation of D16AVGR instruction. */
26016 MIPS_INVAL("OPC_MXU_D16AVGR");
26017 generate_exception_end(ctx
, EXCP_RI
);
26019 case OPC_MXU_Q8AVG
:
26020 /* TODO: Implement emulation of Q8AVG instruction. */
26021 MIPS_INVAL("OPC_MXU_Q8AVG");
26022 generate_exception_end(ctx
, EXCP_RI
);
26024 case OPC_MXU_Q8AVGR
:
26025 /* TODO: Implement emulation of Q8AVGR instruction. */
26026 MIPS_INVAL("OPC_MXU_Q8AVGR");
26027 generate_exception_end(ctx
, EXCP_RI
);
26029 case OPC_MXU_Q8ADD
:
26030 /* TODO: Implement emulation of Q8ADD instruction. */
26031 MIPS_INVAL("OPC_MXU_Q8ADD");
26032 generate_exception_end(ctx
, EXCP_RI
);
26035 MIPS_INVAL("decode_opc_mxu");
26036 generate_exception_end(ctx
, EXCP_RI
);
26043 * Decode MXU pool02
26045 * 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
26046 * +-----------+---------+-----+-------+-------+-------+-----------+
26047 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26048 * +-----------+---------+-----+-------+-------+-------+-----------+
26051 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
26053 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26056 case OPC_MXU_S32CPS
:
26057 /* TODO: Implement emulation of S32CPS instruction. */
26058 MIPS_INVAL("OPC_MXU_S32CPS");
26059 generate_exception_end(ctx
, EXCP_RI
);
26061 case OPC_MXU_D16CPS
:
26062 /* TODO: Implement emulation of D16CPS instruction. */
26063 MIPS_INVAL("OPC_MXU_D16CPS");
26064 generate_exception_end(ctx
, EXCP_RI
);
26066 case OPC_MXU_Q8ABD
:
26067 /* TODO: Implement emulation of Q8ABD instruction. */
26068 MIPS_INVAL("OPC_MXU_Q8ABD");
26069 generate_exception_end(ctx
, EXCP_RI
);
26071 case OPC_MXU_Q16SAT
:
26072 /* TODO: Implement emulation of Q16SAT instruction. */
26073 MIPS_INVAL("OPC_MXU_Q16SAT");
26074 generate_exception_end(ctx
, EXCP_RI
);
26077 MIPS_INVAL("decode_opc_mxu");
26078 generate_exception_end(ctx
, EXCP_RI
);
26085 * Decode MXU pool03
26088 * 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
26089 * +-----------+---+---+-------+-------+-------+-------+-----------+
26090 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26091 * +-----------+---+---+-------+-------+-------+-------+-----------+
26094 * 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
26095 * +-----------+---+---+-------+-------+-------+-------+-----------+
26096 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26097 * +-----------+---+---+-------+-------+-------+-------+-----------+
26100 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
26102 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
26105 case OPC_MXU_D16MULF
:
26106 /* TODO: Implement emulation of D16MULF instruction. */
26107 MIPS_INVAL("OPC_MXU_D16MULF");
26108 generate_exception_end(ctx
, EXCP_RI
);
26110 case OPC_MXU_D16MULE
:
26111 /* TODO: Implement emulation of D16MULE instruction. */
26112 MIPS_INVAL("OPC_MXU_D16MULE");
26113 generate_exception_end(ctx
, EXCP_RI
);
26116 MIPS_INVAL("decode_opc_mxu");
26117 generate_exception_end(ctx
, EXCP_RI
);
26124 * Decode MXU pool04
26126 * 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
26127 * +-----------+---------+-+-------------------+-------+-----------+
26128 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26129 * +-----------+---------+-+-------------------+-------+-----------+
26132 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
26134 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26137 case OPC_MXU_S32LDD
:
26138 case OPC_MXU_S32LDDR
:
26139 gen_mxu_s32ldd_s32lddr(ctx
);
26142 MIPS_INVAL("decode_opc_mxu");
26143 generate_exception_end(ctx
, EXCP_RI
);
26150 * Decode MXU pool05
26152 * 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
26153 * +-----------+---------+-+-------------------+-------+-----------+
26154 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26155 * +-----------+---------+-+-------------------+-------+-----------+
26158 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
26160 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26163 case OPC_MXU_S32STD
:
26164 /* TODO: Implement emulation of S32STD instruction. */
26165 MIPS_INVAL("OPC_MXU_S32STD");
26166 generate_exception_end(ctx
, EXCP_RI
);
26168 case OPC_MXU_S32STDR
:
26169 /* TODO: Implement emulation of S32STDR instruction. */
26170 MIPS_INVAL("OPC_MXU_S32STDR");
26171 generate_exception_end(ctx
, EXCP_RI
);
26174 MIPS_INVAL("decode_opc_mxu");
26175 generate_exception_end(ctx
, EXCP_RI
);
26182 * Decode MXU pool06
26184 * 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
26185 * +-----------+---------+---------+---+-------+-------+-----------+
26186 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26187 * +-----------+---------+---------+---+-------+-------+-----------+
26190 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26192 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26195 case OPC_MXU_S32LDDV
:
26196 /* TODO: Implement emulation of S32LDDV instruction. */
26197 MIPS_INVAL("OPC_MXU_S32LDDV");
26198 generate_exception_end(ctx
, EXCP_RI
);
26200 case OPC_MXU_S32LDDVR
:
26201 /* TODO: Implement emulation of S32LDDVR instruction. */
26202 MIPS_INVAL("OPC_MXU_S32LDDVR");
26203 generate_exception_end(ctx
, EXCP_RI
);
26206 MIPS_INVAL("decode_opc_mxu");
26207 generate_exception_end(ctx
, EXCP_RI
);
26214 * Decode MXU pool07
26216 * 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
26217 * +-----------+---------+---------+---+-------+-------+-----------+
26218 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26219 * +-----------+---------+---------+---+-------+-------+-----------+
26222 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26224 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26227 case OPC_MXU_S32STDV
:
26228 /* TODO: Implement emulation of S32TDV instruction. */
26229 MIPS_INVAL("OPC_MXU_S32TDV");
26230 generate_exception_end(ctx
, EXCP_RI
);
26232 case OPC_MXU_S32STDVR
:
26233 /* TODO: Implement emulation of S32TDVR instruction. */
26234 MIPS_INVAL("OPC_MXU_S32TDVR");
26235 generate_exception_end(ctx
, EXCP_RI
);
26238 MIPS_INVAL("decode_opc_mxu");
26239 generate_exception_end(ctx
, EXCP_RI
);
26246 * Decode MXU pool08
26248 * 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
26249 * +-----------+---------+-+-------------------+-------+-----------+
26250 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26251 * +-----------+---------+-+-------------------+-------+-----------+
26254 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26256 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26259 case OPC_MXU_S32LDI
:
26260 /* TODO: Implement emulation of S32LDI instruction. */
26261 MIPS_INVAL("OPC_MXU_S32LDI");
26262 generate_exception_end(ctx
, EXCP_RI
);
26264 case OPC_MXU_S32LDIR
:
26265 /* TODO: Implement emulation of S32LDIR instruction. */
26266 MIPS_INVAL("OPC_MXU_S32LDIR");
26267 generate_exception_end(ctx
, EXCP_RI
);
26270 MIPS_INVAL("decode_opc_mxu");
26271 generate_exception_end(ctx
, EXCP_RI
);
26278 * Decode MXU pool09
26280 * 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
26281 * +-----------+---------+-+-------------------+-------+-----------+
26282 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26283 * +-----------+---------+-+-------------------+-------+-----------+
26286 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26288 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26291 case OPC_MXU_S32SDI
:
26292 /* TODO: Implement emulation of S32SDI instruction. */
26293 MIPS_INVAL("OPC_MXU_S32SDI");
26294 generate_exception_end(ctx
, EXCP_RI
);
26296 case OPC_MXU_S32SDIR
:
26297 /* TODO: Implement emulation of S32SDIR instruction. */
26298 MIPS_INVAL("OPC_MXU_S32SDIR");
26299 generate_exception_end(ctx
, EXCP_RI
);
26302 MIPS_INVAL("decode_opc_mxu");
26303 generate_exception_end(ctx
, EXCP_RI
);
26310 * Decode MXU pool10
26312 * 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
26313 * +-----------+---------+---------+---+-------+-------+-----------+
26314 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26315 * +-----------+---------+---------+---+-------+-------+-----------+
26318 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26320 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26323 case OPC_MXU_S32LDIV
:
26324 /* TODO: Implement emulation of S32LDIV instruction. */
26325 MIPS_INVAL("OPC_MXU_S32LDIV");
26326 generate_exception_end(ctx
, EXCP_RI
);
26328 case OPC_MXU_S32LDIVR
:
26329 /* TODO: Implement emulation of S32LDIVR instruction. */
26330 MIPS_INVAL("OPC_MXU_S32LDIVR");
26331 generate_exception_end(ctx
, EXCP_RI
);
26334 MIPS_INVAL("decode_opc_mxu");
26335 generate_exception_end(ctx
, EXCP_RI
);
26342 * Decode MXU pool11
26344 * 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
26345 * +-----------+---------+---------+---+-------+-------+-----------+
26346 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26347 * +-----------+---------+---------+---+-------+-------+-----------+
26350 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26352 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26355 case OPC_MXU_S32SDIV
:
26356 /* TODO: Implement emulation of S32SDIV instruction. */
26357 MIPS_INVAL("OPC_MXU_S32SDIV");
26358 generate_exception_end(ctx
, EXCP_RI
);
26360 case OPC_MXU_S32SDIVR
:
26361 /* TODO: Implement emulation of S32SDIVR instruction. */
26362 MIPS_INVAL("OPC_MXU_S32SDIVR");
26363 generate_exception_end(ctx
, EXCP_RI
);
26366 MIPS_INVAL("decode_opc_mxu");
26367 generate_exception_end(ctx
, EXCP_RI
);
26374 * Decode MXU pool12
26376 * 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
26377 * +-----------+---+---+-------+-------+-------+-------+-----------+
26378 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26379 * +-----------+---+---+-------+-------+-------+-------+-----------+
26382 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26384 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26387 case OPC_MXU_D32ACC
:
26388 /* TODO: Implement emulation of D32ACC instruction. */
26389 MIPS_INVAL("OPC_MXU_D32ACC");
26390 generate_exception_end(ctx
, EXCP_RI
);
26392 case OPC_MXU_D32ACCM
:
26393 /* TODO: Implement emulation of D32ACCM instruction. */
26394 MIPS_INVAL("OPC_MXU_D32ACCM");
26395 generate_exception_end(ctx
, EXCP_RI
);
26397 case OPC_MXU_D32ASUM
:
26398 /* TODO: Implement emulation of D32ASUM instruction. */
26399 MIPS_INVAL("OPC_MXU_D32ASUM");
26400 generate_exception_end(ctx
, EXCP_RI
);
26403 MIPS_INVAL("decode_opc_mxu");
26404 generate_exception_end(ctx
, EXCP_RI
);
26411 * Decode MXU pool13
26413 * 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
26414 * +-----------+---+---+-------+-------+-------+-------+-----------+
26415 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26416 * +-----------+---+---+-------+-------+-------+-------+-----------+
26419 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26421 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26424 case OPC_MXU_Q16ACC
:
26425 /* TODO: Implement emulation of Q16ACC instruction. */
26426 MIPS_INVAL("OPC_MXU_Q16ACC");
26427 generate_exception_end(ctx
, EXCP_RI
);
26429 case OPC_MXU_Q16ACCM
:
26430 /* TODO: Implement emulation of Q16ACCM instruction. */
26431 MIPS_INVAL("OPC_MXU_Q16ACCM");
26432 generate_exception_end(ctx
, EXCP_RI
);
26434 case OPC_MXU_Q16ASUM
:
26435 /* TODO: Implement emulation of Q16ASUM instruction. */
26436 MIPS_INVAL("OPC_MXU_Q16ASUM");
26437 generate_exception_end(ctx
, EXCP_RI
);
26440 MIPS_INVAL("decode_opc_mxu");
26441 generate_exception_end(ctx
, EXCP_RI
);
26448 * Decode MXU pool14
26451 * 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
26452 * +-----------+---+---+-------+-------+-------+-------+-----------+
26453 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26454 * +-----------+---+---+-------+-------+-------+-------+-----------+
26457 * 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
26458 * +-----------+---+---+-------+-------+-------+-------+-----------+
26459 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26460 * +-----------+---+---+-------+-------+-------+-------+-----------+
26463 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26465 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26468 case OPC_MXU_Q8ADDE
:
26469 /* TODO: Implement emulation of Q8ADDE instruction. */
26470 MIPS_INVAL("OPC_MXU_Q8ADDE");
26471 generate_exception_end(ctx
, EXCP_RI
);
26473 case OPC_MXU_D8SUM
:
26474 /* TODO: Implement emulation of D8SUM instruction. */
26475 MIPS_INVAL("OPC_MXU_D8SUM");
26476 generate_exception_end(ctx
, EXCP_RI
);
26478 case OPC_MXU_D8SUMC
:
26479 /* TODO: Implement emulation of D8SUMC instruction. */
26480 MIPS_INVAL("OPC_MXU_D8SUMC");
26481 generate_exception_end(ctx
, EXCP_RI
);
26484 MIPS_INVAL("decode_opc_mxu");
26485 generate_exception_end(ctx
, EXCP_RI
);
26492 * Decode MXU pool15
26494 * S32MUL, S32MULU, S32EXTRV:
26495 * 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
26496 * +-----------+---------+---------+---+-------+-------+-----------+
26497 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26498 * +-----------+---------+---------+---+-------+-------+-----------+
26501 * 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
26502 * +-----------+---------+---------+---+-------+-------+-----------+
26503 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26504 * +-----------+---------+---------+---+-------+-------+-----------+
26507 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26509 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26512 case OPC_MXU_S32MUL
:
26513 /* TODO: Implement emulation of S32MUL instruction. */
26514 MIPS_INVAL("OPC_MXU_S32MUL");
26515 generate_exception_end(ctx
, EXCP_RI
);
26517 case OPC_MXU_S32MULU
:
26518 /* TODO: Implement emulation of S32MULU instruction. */
26519 MIPS_INVAL("OPC_MXU_S32MULU");
26520 generate_exception_end(ctx
, EXCP_RI
);
26522 case OPC_MXU_S32EXTR
:
26523 /* TODO: Implement emulation of S32EXTR instruction. */
26524 MIPS_INVAL("OPC_MXU_S32EXTR");
26525 generate_exception_end(ctx
, EXCP_RI
);
26527 case OPC_MXU_S32EXTRV
:
26528 /* TODO: Implement emulation of S32EXTRV instruction. */
26529 MIPS_INVAL("OPC_MXU_S32EXTRV");
26530 generate_exception_end(ctx
, EXCP_RI
);
26533 MIPS_INVAL("decode_opc_mxu");
26534 generate_exception_end(ctx
, EXCP_RI
);
26541 * Decode MXU pool16
26544 * 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
26545 * +-----------+---------+-----+-------+-------+-------+-----------+
26546 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26547 * +-----------+---------+-----+-------+-------+-------+-----------+
26550 * 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
26551 * +-----------+---------+-----+-------+-------+-------+-----------+
26552 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26553 * +-----------+---------+-----+-------+-------+-------+-----------+
26556 * 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
26557 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26558 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26559 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26562 * 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
26563 * +-----------+-----+---+-----+-------+---------------+-----------+
26564 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26565 * +-----------+-----+---+-----+-------+---------------+-----------+
26567 * S32NOR, S32AND, S32OR, S32XOR:
26568 * 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
26569 * +-----------+---------+-----+-------+-------+-------+-----------+
26570 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26571 * +-----------+---------+-----+-------+-------+-------+-----------+
26574 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
26576 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26579 case OPC_MXU_D32SARW
:
26580 /* TODO: Implement emulation of D32SARW instruction. */
26581 MIPS_INVAL("OPC_MXU_D32SARW");
26582 generate_exception_end(ctx
, EXCP_RI
);
26584 case OPC_MXU_S32ALN
:
26585 /* TODO: Implement emulation of S32ALN instruction. */
26586 MIPS_INVAL("OPC_MXU_S32ALN");
26587 generate_exception_end(ctx
, EXCP_RI
);
26589 case OPC_MXU_S32ALNI
:
26590 gen_mxu_S32ALNI(ctx
);
26592 case OPC_MXU_S32LUI
:
26593 /* TODO: Implement emulation of S32LUI instruction. */
26594 MIPS_INVAL("OPC_MXU_S32LUI");
26595 generate_exception_end(ctx
, EXCP_RI
);
26597 case OPC_MXU_S32NOR
:
26598 gen_mxu_S32NOR(ctx
);
26600 case OPC_MXU_S32AND
:
26601 gen_mxu_S32AND(ctx
);
26603 case OPC_MXU_S32OR
:
26604 gen_mxu_S32OR(ctx
);
26606 case OPC_MXU_S32XOR
:
26607 gen_mxu_S32XOR(ctx
);
26610 MIPS_INVAL("decode_opc_mxu");
26611 generate_exception_end(ctx
, EXCP_RI
);
26618 * Decode MXU pool17
26620 * 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
26621 * +-----------+---------+---------+---+---------+-----+-----------+
26622 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26623 * +-----------+---------+---------+---+---------+-----+-----------+
26626 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
26628 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
26632 /* TODO: Implement emulation of LXW instruction. */
26633 MIPS_INVAL("OPC_MXU_LXW");
26634 generate_exception_end(ctx
, EXCP_RI
);
26637 /* TODO: Implement emulation of LXH instruction. */
26638 MIPS_INVAL("OPC_MXU_LXH");
26639 generate_exception_end(ctx
, EXCP_RI
);
26642 /* TODO: Implement emulation of LXHU instruction. */
26643 MIPS_INVAL("OPC_MXU_LXHU");
26644 generate_exception_end(ctx
, EXCP_RI
);
26647 /* TODO: Implement emulation of LXB instruction. */
26648 MIPS_INVAL("OPC_MXU_LXB");
26649 generate_exception_end(ctx
, EXCP_RI
);
26652 /* TODO: Implement emulation of LXBU instruction. */
26653 MIPS_INVAL("OPC_MXU_LXBU");
26654 generate_exception_end(ctx
, EXCP_RI
);
26657 MIPS_INVAL("decode_opc_mxu");
26658 generate_exception_end(ctx
, EXCP_RI
);
26664 * Decode MXU pool18
26666 * 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
26667 * +-----------+---------+-----+-------+-------+-------+-----------+
26668 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26669 * +-----------+---------+-----+-------+-------+-------+-----------+
26672 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
26674 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26677 case OPC_MXU_D32SLLV
:
26678 /* TODO: Implement emulation of D32SLLV instruction. */
26679 MIPS_INVAL("OPC_MXU_D32SLLV");
26680 generate_exception_end(ctx
, EXCP_RI
);
26682 case OPC_MXU_D32SLRV
:
26683 /* TODO: Implement emulation of D32SLRV instruction. */
26684 MIPS_INVAL("OPC_MXU_D32SLRV");
26685 generate_exception_end(ctx
, EXCP_RI
);
26687 case OPC_MXU_D32SARV
:
26688 /* TODO: Implement emulation of D32SARV instruction. */
26689 MIPS_INVAL("OPC_MXU_D32SARV");
26690 generate_exception_end(ctx
, EXCP_RI
);
26692 case OPC_MXU_Q16SLLV
:
26693 /* TODO: Implement emulation of Q16SLLV instruction. */
26694 MIPS_INVAL("OPC_MXU_Q16SLLV");
26695 generate_exception_end(ctx
, EXCP_RI
);
26697 case OPC_MXU_Q16SLRV
:
26698 /* TODO: Implement emulation of Q16SLRV instruction. */
26699 MIPS_INVAL("OPC_MXU_Q16SLRV");
26700 generate_exception_end(ctx
, EXCP_RI
);
26702 case OPC_MXU_Q16SARV
:
26703 /* TODO: Implement emulation of Q16SARV instruction. */
26704 MIPS_INVAL("OPC_MXU_Q16SARV");
26705 generate_exception_end(ctx
, EXCP_RI
);
26708 MIPS_INVAL("decode_opc_mxu");
26709 generate_exception_end(ctx
, EXCP_RI
);
26716 * Decode MXU pool19
26718 * 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
26719 * +-----------+---+---+-------+-------+-------+-------+-----------+
26720 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
26721 * +-----------+---+---+-------+-------+-------+-------+-----------+
26724 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
26726 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26729 case OPC_MXU_Q8MUL
:
26730 case OPC_MXU_Q8MULSU
:
26731 gen_mxu_q8mul_q8mulsu(ctx
);
26734 MIPS_INVAL("decode_opc_mxu");
26735 generate_exception_end(ctx
, EXCP_RI
);
26742 * Decode MXU pool20
26744 * 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
26745 * +-----------+---------+-----+-------+-------+-------+-----------+
26746 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
26747 * +-----------+---------+-----+-------+-------+-------+-----------+
26750 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
26752 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26755 case OPC_MXU_Q8MOVZ
:
26756 /* TODO: Implement emulation of Q8MOVZ instruction. */
26757 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26758 generate_exception_end(ctx
, EXCP_RI
);
26760 case OPC_MXU_Q8MOVN
:
26761 /* TODO: Implement emulation of Q8MOVN instruction. */
26762 MIPS_INVAL("OPC_MXU_Q8MOVN");
26763 generate_exception_end(ctx
, EXCP_RI
);
26765 case OPC_MXU_D16MOVZ
:
26766 /* TODO: Implement emulation of D16MOVZ instruction. */
26767 MIPS_INVAL("OPC_MXU_D16MOVZ");
26768 generate_exception_end(ctx
, EXCP_RI
);
26770 case OPC_MXU_D16MOVN
:
26771 /* TODO: Implement emulation of D16MOVN instruction. */
26772 MIPS_INVAL("OPC_MXU_D16MOVN");
26773 generate_exception_end(ctx
, EXCP_RI
);
26775 case OPC_MXU_S32MOVZ
:
26776 /* TODO: Implement emulation of S32MOVZ instruction. */
26777 MIPS_INVAL("OPC_MXU_S32MOVZ");
26778 generate_exception_end(ctx
, EXCP_RI
);
26780 case OPC_MXU_S32MOVN
:
26781 /* TODO: Implement emulation of S32MOVN instruction. */
26782 MIPS_INVAL("OPC_MXU_S32MOVN");
26783 generate_exception_end(ctx
, EXCP_RI
);
26786 MIPS_INVAL("decode_opc_mxu");
26787 generate_exception_end(ctx
, EXCP_RI
);
26794 * Decode MXU pool21
26796 * 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
26797 * +-----------+---+---+-------+-------+-------+-------+-----------+
26798 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
26799 * +-----------+---+---+-------+-------+-------+-------+-----------+
26802 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
26804 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26807 case OPC_MXU_Q8MAC
:
26808 /* TODO: Implement emulation of Q8MAC instruction. */
26809 MIPS_INVAL("OPC_MXU_Q8MAC");
26810 generate_exception_end(ctx
, EXCP_RI
);
26812 case OPC_MXU_Q8MACSU
:
26813 /* TODO: Implement emulation of Q8MACSU instruction. */
26814 MIPS_INVAL("OPC_MXU_Q8MACSU");
26815 generate_exception_end(ctx
, EXCP_RI
);
26818 MIPS_INVAL("decode_opc_mxu");
26819 generate_exception_end(ctx
, EXCP_RI
);
26826 * Main MXU decoding function
26828 * 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
26829 * +-----------+---------------------------------------+-----------+
26830 * | SPECIAL2 | |x x x x x x|
26831 * +-----------+---------------------------------------+-----------+
26834 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
26837 * TODO: Investigate necessity of including handling of
26838 * CLZ, CLO, SDBB in this function, as they belong to
26839 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26841 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
26843 if (opcode
== OPC__MXU_MUL
) {
26844 uint32_t rs
, rt
, rd
, op1
;
26846 rs
= extract32(ctx
->opcode
, 21, 5);
26847 rt
= extract32(ctx
->opcode
, 16, 5);
26848 rd
= extract32(ctx
->opcode
, 11, 5);
26849 op1
= MASK_SPECIAL2(ctx
->opcode
);
26851 gen_arith(ctx
, op1
, rd
, rs
, rt
);
26856 if (opcode
== OPC_MXU_S32M2I
) {
26857 gen_mxu_s32m2i(ctx
);
26861 if (opcode
== OPC_MXU_S32I2M
) {
26862 gen_mxu_s32i2m(ctx
);
26867 TCGv t_mxu_cr
= tcg_temp_new();
26868 TCGLabel
*l_exit
= gen_new_label();
26870 gen_load_mxu_cr(t_mxu_cr
);
26871 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
26872 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
26875 case OPC_MXU_S32MADD
:
26876 /* TODO: Implement emulation of S32MADD instruction. */
26877 MIPS_INVAL("OPC_MXU_S32MADD");
26878 generate_exception_end(ctx
, EXCP_RI
);
26880 case OPC_MXU_S32MADDU
:
26881 /* TODO: Implement emulation of S32MADDU instruction. */
26882 MIPS_INVAL("OPC_MXU_S32MADDU");
26883 generate_exception_end(ctx
, EXCP_RI
);
26885 case OPC_MXU__POOL00
:
26886 decode_opc_mxu__pool00(env
, ctx
);
26888 case OPC_MXU_S32MSUB
:
26889 /* TODO: Implement emulation of S32MSUB instruction. */
26890 MIPS_INVAL("OPC_MXU_S32MSUB");
26891 generate_exception_end(ctx
, EXCP_RI
);
26893 case OPC_MXU_S32MSUBU
:
26894 /* TODO: Implement emulation of S32MSUBU instruction. */
26895 MIPS_INVAL("OPC_MXU_S32MSUBU");
26896 generate_exception_end(ctx
, EXCP_RI
);
26898 case OPC_MXU__POOL01
:
26899 decode_opc_mxu__pool01(env
, ctx
);
26901 case OPC_MXU__POOL02
:
26902 decode_opc_mxu__pool02(env
, ctx
);
26904 case OPC_MXU_D16MUL
:
26905 gen_mxu_d16mul(ctx
);
26907 case OPC_MXU__POOL03
:
26908 decode_opc_mxu__pool03(env
, ctx
);
26910 case OPC_MXU_D16MAC
:
26911 gen_mxu_d16mac(ctx
);
26913 case OPC_MXU_D16MACF
:
26914 /* TODO: Implement emulation of D16MACF instruction. */
26915 MIPS_INVAL("OPC_MXU_D16MACF");
26916 generate_exception_end(ctx
, EXCP_RI
);
26918 case OPC_MXU_D16MADL
:
26919 /* TODO: Implement emulation of D16MADL instruction. */
26920 MIPS_INVAL("OPC_MXU_D16MADL");
26921 generate_exception_end(ctx
, EXCP_RI
);
26923 case OPC_MXU_S16MAD
:
26924 /* TODO: Implement emulation of S16MAD instruction. */
26925 MIPS_INVAL("OPC_MXU_S16MAD");
26926 generate_exception_end(ctx
, EXCP_RI
);
26928 case OPC_MXU_Q16ADD
:
26929 /* TODO: Implement emulation of Q16ADD instruction. */
26930 MIPS_INVAL("OPC_MXU_Q16ADD");
26931 generate_exception_end(ctx
, EXCP_RI
);
26933 case OPC_MXU_D16MACE
:
26934 /* TODO: Implement emulation of D16MACE instruction. */
26935 MIPS_INVAL("OPC_MXU_D16MACE");
26936 generate_exception_end(ctx
, EXCP_RI
);
26938 case OPC_MXU__POOL04
:
26939 decode_opc_mxu__pool04(env
, ctx
);
26941 case OPC_MXU__POOL05
:
26942 decode_opc_mxu__pool05(env
, ctx
);
26944 case OPC_MXU__POOL06
:
26945 decode_opc_mxu__pool06(env
, ctx
);
26947 case OPC_MXU__POOL07
:
26948 decode_opc_mxu__pool07(env
, ctx
);
26950 case OPC_MXU__POOL08
:
26951 decode_opc_mxu__pool08(env
, ctx
);
26953 case OPC_MXU__POOL09
:
26954 decode_opc_mxu__pool09(env
, ctx
);
26956 case OPC_MXU__POOL10
:
26957 decode_opc_mxu__pool10(env
, ctx
);
26959 case OPC_MXU__POOL11
:
26960 decode_opc_mxu__pool11(env
, ctx
);
26962 case OPC_MXU_D32ADD
:
26963 /* TODO: Implement emulation of D32ADD instruction. */
26964 MIPS_INVAL("OPC_MXU_D32ADD");
26965 generate_exception_end(ctx
, EXCP_RI
);
26967 case OPC_MXU__POOL12
:
26968 decode_opc_mxu__pool12(env
, ctx
);
26970 case OPC_MXU__POOL13
:
26971 decode_opc_mxu__pool13(env
, ctx
);
26973 case OPC_MXU__POOL14
:
26974 decode_opc_mxu__pool14(env
, ctx
);
26976 case OPC_MXU_Q8ACCE
:
26977 /* TODO: Implement emulation of Q8ACCE instruction. */
26978 MIPS_INVAL("OPC_MXU_Q8ACCE");
26979 generate_exception_end(ctx
, EXCP_RI
);
26981 case OPC_MXU_S8LDD
:
26982 gen_mxu_s8ldd(ctx
);
26984 case OPC_MXU_S8STD
:
26985 /* TODO: Implement emulation of S8STD instruction. */
26986 MIPS_INVAL("OPC_MXU_S8STD");
26987 generate_exception_end(ctx
, EXCP_RI
);
26989 case OPC_MXU_S8LDI
:
26990 /* TODO: Implement emulation of S8LDI instruction. */
26991 MIPS_INVAL("OPC_MXU_S8LDI");
26992 generate_exception_end(ctx
, EXCP_RI
);
26994 case OPC_MXU_S8SDI
:
26995 /* TODO: Implement emulation of S8SDI instruction. */
26996 MIPS_INVAL("OPC_MXU_S8SDI");
26997 generate_exception_end(ctx
, EXCP_RI
);
26999 case OPC_MXU__POOL15
:
27000 decode_opc_mxu__pool15(env
, ctx
);
27002 case OPC_MXU__POOL16
:
27003 decode_opc_mxu__pool16(env
, ctx
);
27005 case OPC_MXU__POOL17
:
27006 decode_opc_mxu__pool17(env
, ctx
);
27008 case OPC_MXU_S16LDD
:
27009 /* TODO: Implement emulation of S16LDD instruction. */
27010 MIPS_INVAL("OPC_MXU_S16LDD");
27011 generate_exception_end(ctx
, EXCP_RI
);
27013 case OPC_MXU_S16STD
:
27014 /* TODO: Implement emulation of S16STD instruction. */
27015 MIPS_INVAL("OPC_MXU_S16STD");
27016 generate_exception_end(ctx
, EXCP_RI
);
27018 case OPC_MXU_S16LDI
:
27019 /* TODO: Implement emulation of S16LDI instruction. */
27020 MIPS_INVAL("OPC_MXU_S16LDI");
27021 generate_exception_end(ctx
, EXCP_RI
);
27023 case OPC_MXU_S16SDI
:
27024 /* TODO: Implement emulation of S16SDI instruction. */
27025 MIPS_INVAL("OPC_MXU_S16SDI");
27026 generate_exception_end(ctx
, EXCP_RI
);
27028 case OPC_MXU_D32SLL
:
27029 /* TODO: Implement emulation of D32SLL instruction. */
27030 MIPS_INVAL("OPC_MXU_D32SLL");
27031 generate_exception_end(ctx
, EXCP_RI
);
27033 case OPC_MXU_D32SLR
:
27034 /* TODO: Implement emulation of D32SLR instruction. */
27035 MIPS_INVAL("OPC_MXU_D32SLR");
27036 generate_exception_end(ctx
, EXCP_RI
);
27038 case OPC_MXU_D32SARL
:
27039 /* TODO: Implement emulation of D32SARL instruction. */
27040 MIPS_INVAL("OPC_MXU_D32SARL");
27041 generate_exception_end(ctx
, EXCP_RI
);
27043 case OPC_MXU_D32SAR
:
27044 /* TODO: Implement emulation of D32SAR instruction. */
27045 MIPS_INVAL("OPC_MXU_D32SAR");
27046 generate_exception_end(ctx
, EXCP_RI
);
27048 case OPC_MXU_Q16SLL
:
27049 /* TODO: Implement emulation of Q16SLL instruction. */
27050 MIPS_INVAL("OPC_MXU_Q16SLL");
27051 generate_exception_end(ctx
, EXCP_RI
);
27053 case OPC_MXU_Q16SLR
:
27054 /* TODO: Implement emulation of Q16SLR instruction. */
27055 MIPS_INVAL("OPC_MXU_Q16SLR");
27056 generate_exception_end(ctx
, EXCP_RI
);
27058 case OPC_MXU__POOL18
:
27059 decode_opc_mxu__pool18(env
, ctx
);
27061 case OPC_MXU_Q16SAR
:
27062 /* TODO: Implement emulation of Q16SAR instruction. */
27063 MIPS_INVAL("OPC_MXU_Q16SAR");
27064 generate_exception_end(ctx
, EXCP_RI
);
27066 case OPC_MXU__POOL19
:
27067 decode_opc_mxu__pool19(env
, ctx
);
27069 case OPC_MXU__POOL20
:
27070 decode_opc_mxu__pool20(env
, ctx
);
27072 case OPC_MXU__POOL21
:
27073 decode_opc_mxu__pool21(env
, ctx
);
27075 case OPC_MXU_Q16SCOP
:
27076 /* TODO: Implement emulation of Q16SCOP instruction. */
27077 MIPS_INVAL("OPC_MXU_Q16SCOP");
27078 generate_exception_end(ctx
, EXCP_RI
);
27080 case OPC_MXU_Q8MADL
:
27081 /* TODO: Implement emulation of Q8MADL instruction. */
27082 MIPS_INVAL("OPC_MXU_Q8MADL");
27083 generate_exception_end(ctx
, EXCP_RI
);
27085 case OPC_MXU_S32SFL
:
27086 /* TODO: Implement emulation of S32SFL instruction. */
27087 MIPS_INVAL("OPC_MXU_S32SFL");
27088 generate_exception_end(ctx
, EXCP_RI
);
27090 case OPC_MXU_Q8SAD
:
27091 /* TODO: Implement emulation of Q8SAD instruction. */
27092 MIPS_INVAL("OPC_MXU_Q8SAD");
27093 generate_exception_end(ctx
, EXCP_RI
);
27096 MIPS_INVAL("decode_opc_mxu");
27097 generate_exception_end(ctx
, EXCP_RI
);
27100 gen_set_label(l_exit
);
27101 tcg_temp_free(t_mxu_cr
);
27105 #endif /* !defined(TARGET_MIPS64) */
27108 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27113 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
27115 rs
= (ctx
->opcode
>> 21) & 0x1f;
27116 rt
= (ctx
->opcode
>> 16) & 0x1f;
27117 rd
= (ctx
->opcode
>> 11) & 0x1f;
27119 op1
= MASK_SPECIAL2(ctx
->opcode
);
27121 case OPC_MADD
: /* Multiply and add/sub */
27125 check_insn(ctx
, ISA_MIPS32
);
27126 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
27129 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27132 case OPC_DIVU_G_2F
:
27133 case OPC_MULT_G_2F
:
27134 case OPC_MULTU_G_2F
:
27136 case OPC_MODU_G_2F
:
27137 check_insn(ctx
, INSN_LOONGSON2F
);
27138 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27142 check_insn(ctx
, ISA_MIPS32
);
27143 gen_cl(ctx
, op1
, rd
, rs
);
27146 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
27147 gen_helper_do_semihosting(cpu_env
);
27150 * XXX: not clear which exception should be raised
27151 * when in debug mode...
27153 check_insn(ctx
, ISA_MIPS32
);
27154 generate_exception_end(ctx
, EXCP_DBp
);
27157 #if defined(TARGET_MIPS64)
27160 check_insn(ctx
, ISA_MIPS64
);
27161 check_mips_64(ctx
);
27162 gen_cl(ctx
, op1
, rd
, rs
);
27164 case OPC_DMULT_G_2F
:
27165 case OPC_DMULTU_G_2F
:
27166 case OPC_DDIV_G_2F
:
27167 case OPC_DDIVU_G_2F
:
27168 case OPC_DMOD_G_2F
:
27169 case OPC_DMODU_G_2F
:
27170 check_insn(ctx
, INSN_LOONGSON2F
);
27171 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27174 default: /* Invalid */
27175 MIPS_INVAL("special2_legacy");
27176 generate_exception_end(ctx
, EXCP_RI
);
27181 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27183 int rs
, rt
, rd
, sa
;
27187 rs
= (ctx
->opcode
>> 21) & 0x1f;
27188 rt
= (ctx
->opcode
>> 16) & 0x1f;
27189 rd
= (ctx
->opcode
>> 11) & 0x1f;
27190 sa
= (ctx
->opcode
>> 6) & 0x1f;
27191 imm
= (int16_t)ctx
->opcode
>> 7;
27193 op1
= MASK_SPECIAL3(ctx
->opcode
);
27197 /* hint codes 24-31 are reserved and signal RI */
27198 generate_exception_end(ctx
, EXCP_RI
);
27200 /* Treat as NOP. */
27203 check_cp0_enabled(ctx
);
27204 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27205 gen_cache_operation(ctx
, rt
, rs
, imm
);
27209 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27212 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27217 /* Treat as NOP. */
27220 op2
= MASK_BSHFL(ctx
->opcode
);
27226 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27229 gen_bitswap(ctx
, op2
, rd
, rt
);
27234 #ifndef CONFIG_USER_ONLY
27236 if (unlikely(ctx
->gi
<= 1)) {
27237 generate_exception_end(ctx
, EXCP_RI
);
27239 check_cp0_enabled(ctx
);
27240 switch ((ctx
->opcode
>> 6) & 3) {
27241 case 0: /* GINVI */
27242 /* Treat as NOP. */
27244 case 2: /* GINVT */
27245 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
27248 generate_exception_end(ctx
, EXCP_RI
);
27253 #if defined(TARGET_MIPS64)
27255 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27258 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27261 check_mips_64(ctx
);
27264 /* Treat as NOP. */
27267 op2
= MASK_DBSHFL(ctx
->opcode
);
27277 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27280 gen_bitswap(ctx
, op2
, rd
, rt
);
27287 default: /* Invalid */
27288 MIPS_INVAL("special3_r6");
27289 generate_exception_end(ctx
, EXCP_RI
);
27294 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27299 rs
= (ctx
->opcode
>> 21) & 0x1f;
27300 rt
= (ctx
->opcode
>> 16) & 0x1f;
27301 rd
= (ctx
->opcode
>> 11) & 0x1f;
27303 op1
= MASK_SPECIAL3(ctx
->opcode
);
27306 case OPC_DIVU_G_2E
:
27308 case OPC_MODU_G_2E
:
27309 case OPC_MULT_G_2E
:
27310 case OPC_MULTU_G_2E
:
27312 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27313 * the same mask and op1.
27315 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27316 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27319 case OPC_ADDUH_R_QB
:
27321 case OPC_ADDQH_R_PH
:
27323 case OPC_ADDQH_R_W
:
27325 case OPC_SUBUH_R_QB
:
27327 case OPC_SUBQH_R_PH
:
27329 case OPC_SUBQH_R_W
:
27330 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27335 case OPC_MULQ_RS_W
:
27336 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27339 MIPS_INVAL("MASK ADDUH.QB");
27340 generate_exception_end(ctx
, EXCP_RI
);
27343 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27344 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27346 generate_exception_end(ctx
, EXCP_RI
);
27350 op2
= MASK_LX(ctx
->opcode
);
27352 #if defined(TARGET_MIPS64)
27358 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27360 default: /* Invalid */
27361 MIPS_INVAL("MASK LX");
27362 generate_exception_end(ctx
, EXCP_RI
);
27366 case OPC_ABSQ_S_PH_DSP
:
27367 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27369 case OPC_ABSQ_S_QB
:
27370 case OPC_ABSQ_S_PH
:
27372 case OPC_PRECEQ_W_PHL
:
27373 case OPC_PRECEQ_W_PHR
:
27374 case OPC_PRECEQU_PH_QBL
:
27375 case OPC_PRECEQU_PH_QBR
:
27376 case OPC_PRECEQU_PH_QBLA
:
27377 case OPC_PRECEQU_PH_QBRA
:
27378 case OPC_PRECEU_PH_QBL
:
27379 case OPC_PRECEU_PH_QBR
:
27380 case OPC_PRECEU_PH_QBLA
:
27381 case OPC_PRECEU_PH_QBRA
:
27382 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27389 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27392 MIPS_INVAL("MASK ABSQ_S.PH");
27393 generate_exception_end(ctx
, EXCP_RI
);
27397 case OPC_ADDU_QB_DSP
:
27398 op2
= MASK_ADDU_QB(ctx
->opcode
);
27401 case OPC_ADDQ_S_PH
:
27404 case OPC_ADDU_S_QB
:
27406 case OPC_ADDU_S_PH
:
27408 case OPC_SUBQ_S_PH
:
27411 case OPC_SUBU_S_QB
:
27413 case OPC_SUBU_S_PH
:
27417 case OPC_RADDU_W_QB
:
27418 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27420 case OPC_MULEU_S_PH_QBL
:
27421 case OPC_MULEU_S_PH_QBR
:
27422 case OPC_MULQ_RS_PH
:
27423 case OPC_MULEQ_S_W_PHL
:
27424 case OPC_MULEQ_S_W_PHR
:
27425 case OPC_MULQ_S_PH
:
27426 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27428 default: /* Invalid */
27429 MIPS_INVAL("MASK ADDU.QB");
27430 generate_exception_end(ctx
, EXCP_RI
);
27435 case OPC_CMPU_EQ_QB_DSP
:
27436 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27438 case OPC_PRECR_SRA_PH_W
:
27439 case OPC_PRECR_SRA_R_PH_W
:
27440 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27442 case OPC_PRECR_QB_PH
:
27443 case OPC_PRECRQ_QB_PH
:
27444 case OPC_PRECRQ_PH_W
:
27445 case OPC_PRECRQ_RS_PH_W
:
27446 case OPC_PRECRQU_S_QB_PH
:
27447 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27449 case OPC_CMPU_EQ_QB
:
27450 case OPC_CMPU_LT_QB
:
27451 case OPC_CMPU_LE_QB
:
27452 case OPC_CMP_EQ_PH
:
27453 case OPC_CMP_LT_PH
:
27454 case OPC_CMP_LE_PH
:
27455 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27457 case OPC_CMPGU_EQ_QB
:
27458 case OPC_CMPGU_LT_QB
:
27459 case OPC_CMPGU_LE_QB
:
27460 case OPC_CMPGDU_EQ_QB
:
27461 case OPC_CMPGDU_LT_QB
:
27462 case OPC_CMPGDU_LE_QB
:
27465 case OPC_PACKRL_PH
:
27466 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27468 default: /* Invalid */
27469 MIPS_INVAL("MASK CMPU.EQ.QB");
27470 generate_exception_end(ctx
, EXCP_RI
);
27474 case OPC_SHLL_QB_DSP
:
27475 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27477 case OPC_DPA_W_PH_DSP
:
27478 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27480 case OPC_DPAU_H_QBL
:
27481 case OPC_DPAU_H_QBR
:
27482 case OPC_DPSU_H_QBL
:
27483 case OPC_DPSU_H_QBR
:
27485 case OPC_DPAX_W_PH
:
27486 case OPC_DPAQ_S_W_PH
:
27487 case OPC_DPAQX_S_W_PH
:
27488 case OPC_DPAQX_SA_W_PH
:
27490 case OPC_DPSX_W_PH
:
27491 case OPC_DPSQ_S_W_PH
:
27492 case OPC_DPSQX_S_W_PH
:
27493 case OPC_DPSQX_SA_W_PH
:
27494 case OPC_MULSAQ_S_W_PH
:
27495 case OPC_DPAQ_SA_L_W
:
27496 case OPC_DPSQ_SA_L_W
:
27497 case OPC_MAQ_S_W_PHL
:
27498 case OPC_MAQ_S_W_PHR
:
27499 case OPC_MAQ_SA_W_PHL
:
27500 case OPC_MAQ_SA_W_PHR
:
27501 case OPC_MULSA_W_PH
:
27502 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27504 default: /* Invalid */
27505 MIPS_INVAL("MASK DPAW.PH");
27506 generate_exception_end(ctx
, EXCP_RI
);
27511 op2
= MASK_INSV(ctx
->opcode
);
27522 t0
= tcg_temp_new();
27523 t1
= tcg_temp_new();
27525 gen_load_gpr(t0
, rt
);
27526 gen_load_gpr(t1
, rs
);
27528 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27534 default: /* Invalid */
27535 MIPS_INVAL("MASK INSV");
27536 generate_exception_end(ctx
, EXCP_RI
);
27540 case OPC_APPEND_DSP
:
27541 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27543 case OPC_EXTR_W_DSP
:
27544 op2
= MASK_EXTR_W(ctx
->opcode
);
27548 case OPC_EXTR_RS_W
:
27550 case OPC_EXTRV_S_H
:
27552 case OPC_EXTRV_R_W
:
27553 case OPC_EXTRV_RS_W
:
27558 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27561 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27567 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27569 default: /* Invalid */
27570 MIPS_INVAL("MASK EXTR.W");
27571 generate_exception_end(ctx
, EXCP_RI
);
27575 #if defined(TARGET_MIPS64)
27576 case OPC_DDIV_G_2E
:
27577 case OPC_DDIVU_G_2E
:
27578 case OPC_DMULT_G_2E
:
27579 case OPC_DMULTU_G_2E
:
27580 case OPC_DMOD_G_2E
:
27581 case OPC_DMODU_G_2E
:
27582 check_insn(ctx
, INSN_LOONGSON2E
);
27583 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27585 case OPC_ABSQ_S_QH_DSP
:
27586 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
27588 case OPC_PRECEQ_L_PWL
:
27589 case OPC_PRECEQ_L_PWR
:
27590 case OPC_PRECEQ_PW_QHL
:
27591 case OPC_PRECEQ_PW_QHR
:
27592 case OPC_PRECEQ_PW_QHLA
:
27593 case OPC_PRECEQ_PW_QHRA
:
27594 case OPC_PRECEQU_QH_OBL
:
27595 case OPC_PRECEQU_QH_OBR
:
27596 case OPC_PRECEQU_QH_OBLA
:
27597 case OPC_PRECEQU_QH_OBRA
:
27598 case OPC_PRECEU_QH_OBL
:
27599 case OPC_PRECEU_QH_OBR
:
27600 case OPC_PRECEU_QH_OBLA
:
27601 case OPC_PRECEU_QH_OBRA
:
27602 case OPC_ABSQ_S_OB
:
27603 case OPC_ABSQ_S_PW
:
27604 case OPC_ABSQ_S_QH
:
27605 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27613 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27615 default: /* Invalid */
27616 MIPS_INVAL("MASK ABSQ_S.QH");
27617 generate_exception_end(ctx
, EXCP_RI
);
27621 case OPC_ADDU_OB_DSP
:
27622 op2
= MASK_ADDU_OB(ctx
->opcode
);
27624 case OPC_RADDU_L_OB
:
27626 case OPC_SUBQ_S_PW
:
27628 case OPC_SUBQ_S_QH
:
27630 case OPC_SUBU_S_OB
:
27632 case OPC_SUBU_S_QH
:
27634 case OPC_SUBUH_R_OB
:
27636 case OPC_ADDQ_S_PW
:
27638 case OPC_ADDQ_S_QH
:
27640 case OPC_ADDU_S_OB
:
27642 case OPC_ADDU_S_QH
:
27644 case OPC_ADDUH_R_OB
:
27645 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27647 case OPC_MULEQ_S_PW_QHL
:
27648 case OPC_MULEQ_S_PW_QHR
:
27649 case OPC_MULEU_S_QH_OBL
:
27650 case OPC_MULEU_S_QH_OBR
:
27651 case OPC_MULQ_RS_QH
:
27652 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27654 default: /* Invalid */
27655 MIPS_INVAL("MASK ADDU.OB");
27656 generate_exception_end(ctx
, EXCP_RI
);
27660 case OPC_CMPU_EQ_OB_DSP
:
27661 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
27663 case OPC_PRECR_SRA_QH_PW
:
27664 case OPC_PRECR_SRA_R_QH_PW
:
27665 /* Return value is rt. */
27666 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27668 case OPC_PRECR_OB_QH
:
27669 case OPC_PRECRQ_OB_QH
:
27670 case OPC_PRECRQ_PW_L
:
27671 case OPC_PRECRQ_QH_PW
:
27672 case OPC_PRECRQ_RS_QH_PW
:
27673 case OPC_PRECRQU_S_OB_QH
:
27674 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27676 case OPC_CMPU_EQ_OB
:
27677 case OPC_CMPU_LT_OB
:
27678 case OPC_CMPU_LE_OB
:
27679 case OPC_CMP_EQ_QH
:
27680 case OPC_CMP_LT_QH
:
27681 case OPC_CMP_LE_QH
:
27682 case OPC_CMP_EQ_PW
:
27683 case OPC_CMP_LT_PW
:
27684 case OPC_CMP_LE_PW
:
27685 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27687 case OPC_CMPGDU_EQ_OB
:
27688 case OPC_CMPGDU_LT_OB
:
27689 case OPC_CMPGDU_LE_OB
:
27690 case OPC_CMPGU_EQ_OB
:
27691 case OPC_CMPGU_LT_OB
:
27692 case OPC_CMPGU_LE_OB
:
27693 case OPC_PACKRL_PW
:
27697 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27699 default: /* Invalid */
27700 MIPS_INVAL("MASK CMPU_EQ.OB");
27701 generate_exception_end(ctx
, EXCP_RI
);
27705 case OPC_DAPPEND_DSP
:
27706 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27708 case OPC_DEXTR_W_DSP
:
27709 op2
= MASK_DEXTR_W(ctx
->opcode
);
27716 case OPC_DEXTR_R_L
:
27717 case OPC_DEXTR_RS_L
:
27719 case OPC_DEXTR_R_W
:
27720 case OPC_DEXTR_RS_W
:
27721 case OPC_DEXTR_S_H
:
27723 case OPC_DEXTRV_R_L
:
27724 case OPC_DEXTRV_RS_L
:
27725 case OPC_DEXTRV_S_H
:
27727 case OPC_DEXTRV_R_W
:
27728 case OPC_DEXTRV_RS_W
:
27729 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27734 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27736 default: /* Invalid */
27737 MIPS_INVAL("MASK EXTR.W");
27738 generate_exception_end(ctx
, EXCP_RI
);
27742 case OPC_DPAQ_W_QH_DSP
:
27743 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
27745 case OPC_DPAU_H_OBL
:
27746 case OPC_DPAU_H_OBR
:
27747 case OPC_DPSU_H_OBL
:
27748 case OPC_DPSU_H_OBR
:
27750 case OPC_DPAQ_S_W_QH
:
27752 case OPC_DPSQ_S_W_QH
:
27753 case OPC_MULSAQ_S_W_QH
:
27754 case OPC_DPAQ_SA_L_PW
:
27755 case OPC_DPSQ_SA_L_PW
:
27756 case OPC_MULSAQ_S_L_PW
:
27757 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27759 case OPC_MAQ_S_W_QHLL
:
27760 case OPC_MAQ_S_W_QHLR
:
27761 case OPC_MAQ_S_W_QHRL
:
27762 case OPC_MAQ_S_W_QHRR
:
27763 case OPC_MAQ_SA_W_QHLL
:
27764 case OPC_MAQ_SA_W_QHLR
:
27765 case OPC_MAQ_SA_W_QHRL
:
27766 case OPC_MAQ_SA_W_QHRR
:
27767 case OPC_MAQ_S_L_PWL
:
27768 case OPC_MAQ_S_L_PWR
:
27773 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27775 default: /* Invalid */
27776 MIPS_INVAL("MASK DPAQ.W.QH");
27777 generate_exception_end(ctx
, EXCP_RI
);
27781 case OPC_DINSV_DSP
:
27782 op2
= MASK_INSV(ctx
->opcode
);
27793 t0
= tcg_temp_new();
27794 t1
= tcg_temp_new();
27796 gen_load_gpr(t0
, rt
);
27797 gen_load_gpr(t1
, rs
);
27799 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27805 default: /* Invalid */
27806 MIPS_INVAL("MASK DINSV");
27807 generate_exception_end(ctx
, EXCP_RI
);
27811 case OPC_SHLL_OB_DSP
:
27812 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27815 default: /* Invalid */
27816 MIPS_INVAL("special3_legacy");
27817 generate_exception_end(ctx
, EXCP_RI
);
27823 #if defined(TARGET_MIPS64)
27825 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
27827 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
27830 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
27831 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
27832 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
27833 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
27834 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
27835 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
27836 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
27837 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
27838 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
27839 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
27840 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
27841 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
27842 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
27843 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
27844 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
27845 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
27846 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
27847 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
27848 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
27849 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
27850 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
27851 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
27852 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
27853 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
27854 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
27855 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI0 */
27858 MIPS_INVAL("TX79 MMI class MMI0");
27859 generate_exception_end(ctx
, EXCP_RI
);
27864 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
27866 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
27869 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
27870 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
27871 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
27872 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
27873 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
27874 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
27875 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
27876 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
27877 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
27878 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
27879 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
27880 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
27881 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
27882 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
27883 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
27884 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
27885 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
27886 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
27887 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI1 */
27890 MIPS_INVAL("TX79 MMI class MMI1");
27891 generate_exception_end(ctx
, EXCP_RI
);
27896 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
27898 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
27901 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
27902 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
27903 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
27904 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
27905 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
27906 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
27907 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
27908 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
27909 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
27910 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
27911 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
27912 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
27913 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
27914 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
27915 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
27916 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
27917 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
27918 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
27919 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
27920 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
27921 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
27922 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI2 */
27924 case MMI_OPC_2_PCPYLD
:
27925 gen_mmi_pcpyld(ctx
);
27928 MIPS_INVAL("TX79 MMI class MMI2");
27929 generate_exception_end(ctx
, EXCP_RI
);
27934 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
27936 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
27939 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
27940 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
27941 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
27942 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
27943 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
27944 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
27945 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
27946 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
27947 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
27948 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
27949 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
27950 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI3 */
27952 case MMI_OPC_3_PCPYH
:
27953 gen_mmi_pcpyh(ctx
);
27955 case MMI_OPC_3_PCPYUD
:
27956 gen_mmi_pcpyud(ctx
);
27959 MIPS_INVAL("TX79 MMI class MMI3");
27960 generate_exception_end(ctx
, EXCP_RI
);
27965 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
27967 uint32_t opc
= MASK_MMI(ctx
->opcode
);
27968 int rs
= extract32(ctx
->opcode
, 21, 5);
27969 int rt
= extract32(ctx
->opcode
, 16, 5);
27970 int rd
= extract32(ctx
->opcode
, 11, 5);
27973 case MMI_OPC_CLASS_MMI0
:
27974 decode_mmi0(env
, ctx
);
27976 case MMI_OPC_CLASS_MMI1
:
27977 decode_mmi1(env
, ctx
);
27979 case MMI_OPC_CLASS_MMI2
:
27980 decode_mmi2(env
, ctx
);
27982 case MMI_OPC_CLASS_MMI3
:
27983 decode_mmi3(env
, ctx
);
27985 case MMI_OPC_MULT1
:
27986 case MMI_OPC_MULTU1
:
27988 case MMI_OPC_MADDU
:
27989 case MMI_OPC_MADD1
:
27990 case MMI_OPC_MADDU1
:
27991 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
27994 case MMI_OPC_DIVU1
:
27995 gen_div1_tx79(ctx
, opc
, rs
, rt
);
27997 case MMI_OPC_MTLO1
:
27998 case MMI_OPC_MTHI1
:
27999 gen_HILO1_tx79(ctx
, opc
, rs
);
28001 case MMI_OPC_MFLO1
:
28002 case MMI_OPC_MFHI1
:
28003 gen_HILO1_tx79(ctx
, opc
, rd
);
28005 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
28006 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
28007 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
28008 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
28009 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
28010 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
28011 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
28012 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
28013 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
28014 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI */
28017 MIPS_INVAL("TX79 MMI class");
28018 generate_exception_end(ctx
, EXCP_RI
);
28023 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
28025 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_LQ */
28028 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
28030 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_SQ */
28034 * The TX79-specific instruction Store Quadword
28036 * +--------+-------+-------+------------------------+
28037 * | 011111 | base | rt | offset | SQ
28038 * +--------+-------+-------+------------------------+
28041 * has the same opcode as the Read Hardware Register instruction
28043 * +--------+-------+-------+-------+-------+--------+
28044 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28045 * +--------+-------+-------+-------+-------+--------+
28048 * that is required, trapped and emulated by the Linux kernel. However, all
28049 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28050 * offset is odd. Therefore all valid SQ instructions can execute normally.
28051 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28052 * between SQ and RDHWR, as the Linux kernel does.
28054 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
28056 int base
= extract32(ctx
->opcode
, 21, 5);
28057 int rt
= extract32(ctx
->opcode
, 16, 5);
28058 int offset
= extract32(ctx
->opcode
, 0, 16);
28060 #ifdef CONFIG_USER_ONLY
28061 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
28062 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
28064 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
28065 int rd
= extract32(ctx
->opcode
, 11, 5);
28067 gen_rdhwr(ctx
, rt
, rd
, 0);
28072 gen_mmi_sq(ctx
, base
, rt
, offset
);
28077 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
28079 int rs
, rt
, rd
, sa
;
28083 rs
= (ctx
->opcode
>> 21) & 0x1f;
28084 rt
= (ctx
->opcode
>> 16) & 0x1f;
28085 rd
= (ctx
->opcode
>> 11) & 0x1f;
28086 sa
= (ctx
->opcode
>> 6) & 0x1f;
28087 imm
= sextract32(ctx
->opcode
, 7, 9);
28089 op1
= MASK_SPECIAL3(ctx
->opcode
);
28092 * EVA loads and stores overlap Loongson 2E instructions decoded by
28093 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28100 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
28108 check_cp0_enabled(ctx
);
28109 gen_ld(ctx
, op1
, rt
, rs
, imm
);
28113 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
28118 check_cp0_enabled(ctx
);
28119 gen_st(ctx
, op1
, rt
, rs
, imm
);
28122 check_cp0_enabled(ctx
);
28123 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
28126 check_cp0_enabled(ctx
);
28127 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28128 gen_cache_operation(ctx
, rt
, rs
, imm
);
28130 /* Treat as NOP. */
28133 check_cp0_enabled(ctx
);
28134 /* Treat as NOP. */
28142 check_insn(ctx
, ISA_MIPS32R2
);
28143 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28146 op2
= MASK_BSHFL(ctx
->opcode
);
28153 check_insn(ctx
, ISA_MIPS32R6
);
28154 decode_opc_special3_r6(env
, ctx
);
28157 check_insn(ctx
, ISA_MIPS32R2
);
28158 gen_bshfl(ctx
, op2
, rt
, rd
);
28162 #if defined(TARGET_MIPS64)
28169 check_insn(ctx
, ISA_MIPS64R2
);
28170 check_mips_64(ctx
);
28171 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28174 op2
= MASK_DBSHFL(ctx
->opcode
);
28185 check_insn(ctx
, ISA_MIPS32R6
);
28186 decode_opc_special3_r6(env
, ctx
);
28189 check_insn(ctx
, ISA_MIPS64R2
);
28190 check_mips_64(ctx
);
28191 op2
= MASK_DBSHFL(ctx
->opcode
);
28192 gen_bshfl(ctx
, op2
, rt
, rd
);
28198 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28203 TCGv t0
= tcg_temp_new();
28204 TCGv t1
= tcg_temp_new();
28206 gen_load_gpr(t0
, rt
);
28207 gen_load_gpr(t1
, rs
);
28208 gen_helper_fork(t0
, t1
);
28216 TCGv t0
= tcg_temp_new();
28218 gen_load_gpr(t0
, rs
);
28219 gen_helper_yield(t0
, cpu_env
, t0
);
28220 gen_store_gpr(t0
, rd
);
28225 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
28226 decode_opc_special3_r6(env
, ctx
);
28228 decode_opc_special3_legacy(env
, ctx
);
28233 /* MIPS SIMD Architecture (MSA) */
28234 static inline int check_msa_access(DisasContext
*ctx
)
28236 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
28237 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
28238 generate_exception_end(ctx
, EXCP_RI
);
28242 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
28243 if (ctx
->insn_flags
& ASE_MSA
) {
28244 generate_exception_end(ctx
, EXCP_MSADIS
);
28247 generate_exception_end(ctx
, EXCP_RI
);
28254 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
28256 /* generates tcg ops to check if any element is 0 */
28257 /* Note this function only works with MSA_WRLEN = 128 */
28258 uint64_t eval_zero_or_big
= 0;
28259 uint64_t eval_big
= 0;
28260 TCGv_i64 t0
= tcg_temp_new_i64();
28261 TCGv_i64 t1
= tcg_temp_new_i64();
28264 eval_zero_or_big
= 0x0101010101010101ULL
;
28265 eval_big
= 0x8080808080808080ULL
;
28268 eval_zero_or_big
= 0x0001000100010001ULL
;
28269 eval_big
= 0x8000800080008000ULL
;
28272 eval_zero_or_big
= 0x0000000100000001ULL
;
28273 eval_big
= 0x8000000080000000ULL
;
28276 eval_zero_or_big
= 0x0000000000000001ULL
;
28277 eval_big
= 0x8000000000000000ULL
;
28280 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<< 1], eval_zero_or_big
);
28281 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<< 1]);
28282 tcg_gen_andi_i64(t0
, t0
, eval_big
);
28283 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<< 1) + 1], eval_zero_or_big
);
28284 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<< 1) + 1]);
28285 tcg_gen_andi_i64(t1
, t1
, eval_big
);
28286 tcg_gen_or_i64(t0
, t0
, t1
);
28287 /* if all bits are zero then all elements are not zero */
28288 /* if some bit is non-zero then some element is zero */
28289 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
28290 tcg_gen_trunc_i64_tl(tresult
, t0
);
28291 tcg_temp_free_i64(t0
);
28292 tcg_temp_free_i64(t1
);
28295 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
28297 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28298 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28299 int64_t s16
= (int16_t)ctx
->opcode
;
28301 check_msa_access(ctx
);
28303 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
28304 generate_exception_end(ctx
, EXCP_RI
);
28311 TCGv_i64 t0
= tcg_temp_new_i64();
28312 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<< 1], msa_wr_d
[(wt
<< 1) + 1]);
28313 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
28314 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
28315 tcg_gen_trunc_i64_tl(bcond
, t0
);
28316 tcg_temp_free_i64(t0
);
28323 gen_check_zero_element(bcond
, df
, wt
);
28329 gen_check_zero_element(bcond
, df
, wt
);
28330 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
28334 ctx
->btarget
= ctx
->base
.pc_next
+ (s16
<< 2) + 4;
28336 ctx
->hflags
|= MIPS_HFLAG_BC
;
28337 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
28340 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
28342 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28343 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
28344 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28345 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28347 TCGv_i32 twd
= tcg_const_i32(wd
);
28348 TCGv_i32 tws
= tcg_const_i32(ws
);
28349 TCGv_i32 ti8
= tcg_const_i32(i8
);
28351 switch (MASK_MSA_I8(ctx
->opcode
)) {
28353 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
28356 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
28359 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
28362 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
28365 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
28368 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
28371 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
28377 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
28378 if (df
== DF_DOUBLE
) {
28379 generate_exception_end(ctx
, EXCP_RI
);
28381 TCGv_i32 tdf
= tcg_const_i32(df
);
28382 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
28383 tcg_temp_free_i32(tdf
);
28388 MIPS_INVAL("MSA instruction");
28389 generate_exception_end(ctx
, EXCP_RI
);
28393 tcg_temp_free_i32(twd
);
28394 tcg_temp_free_i32(tws
);
28395 tcg_temp_free_i32(ti8
);
28398 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
28400 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28401 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28402 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
28403 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
28404 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28405 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28407 TCGv_i32 tdf
= tcg_const_i32(df
);
28408 TCGv_i32 twd
= tcg_const_i32(wd
);
28409 TCGv_i32 tws
= tcg_const_i32(ws
);
28410 TCGv_i32 timm
= tcg_temp_new_i32();
28411 tcg_gen_movi_i32(timm
, u5
);
28413 switch (MASK_MSA_I5(ctx
->opcode
)) {
28415 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28418 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28420 case OPC_MAXI_S_df
:
28421 tcg_gen_movi_i32(timm
, s5
);
28422 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28424 case OPC_MAXI_U_df
:
28425 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28427 case OPC_MINI_S_df
:
28428 tcg_gen_movi_i32(timm
, s5
);
28429 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28431 case OPC_MINI_U_df
:
28432 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28435 tcg_gen_movi_i32(timm
, s5
);
28436 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28438 case OPC_CLTI_S_df
:
28439 tcg_gen_movi_i32(timm
, s5
);
28440 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28442 case OPC_CLTI_U_df
:
28443 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28445 case OPC_CLEI_S_df
:
28446 tcg_gen_movi_i32(timm
, s5
);
28447 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28449 case OPC_CLEI_U_df
:
28450 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28454 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
28455 tcg_gen_movi_i32(timm
, s10
);
28456 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
28460 MIPS_INVAL("MSA instruction");
28461 generate_exception_end(ctx
, EXCP_RI
);
28465 tcg_temp_free_i32(tdf
);
28466 tcg_temp_free_i32(twd
);
28467 tcg_temp_free_i32(tws
);
28468 tcg_temp_free_i32(timm
);
28471 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
28473 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28474 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
28475 uint32_t df
= 0, m
= 0;
28476 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28477 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28484 if ((dfm
& 0x40) == 0x00) {
28487 } else if ((dfm
& 0x60) == 0x40) {
28490 } else if ((dfm
& 0x70) == 0x60) {
28493 } else if ((dfm
& 0x78) == 0x70) {
28497 generate_exception_end(ctx
, EXCP_RI
);
28501 tdf
= tcg_const_i32(df
);
28502 tm
= tcg_const_i32(m
);
28503 twd
= tcg_const_i32(wd
);
28504 tws
= tcg_const_i32(ws
);
28506 switch (MASK_MSA_BIT(ctx
->opcode
)) {
28508 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28511 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
28514 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28517 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28520 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
28523 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
28525 case OPC_BINSLI_df
:
28526 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28528 case OPC_BINSRI_df
:
28529 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28532 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
28535 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
28538 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
28541 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28544 MIPS_INVAL("MSA instruction");
28545 generate_exception_end(ctx
, EXCP_RI
);
28549 tcg_temp_free_i32(tdf
);
28550 tcg_temp_free_i32(tm
);
28551 tcg_temp_free_i32(twd
);
28552 tcg_temp_free_i32(tws
);
28555 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
28557 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28558 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28559 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28560 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28561 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28563 TCGv_i32 tdf
= tcg_const_i32(df
);
28564 TCGv_i32 twd
= tcg_const_i32(wd
);
28565 TCGv_i32 tws
= tcg_const_i32(ws
);
28566 TCGv_i32 twt
= tcg_const_i32(wt
);
28568 switch (MASK_MSA_3R(ctx
->opcode
)) {
28572 gen_helper_msa_binsl_b(cpu_env
, twd
, tws
, twt
);
28575 gen_helper_msa_binsl_h(cpu_env
, twd
, tws
, twt
);
28578 gen_helper_msa_binsl_w(cpu_env
, twd
, tws
, twt
);
28581 gen_helper_msa_binsl_d(cpu_env
, twd
, tws
, twt
);
28588 gen_helper_msa_binsr_b(cpu_env
, twd
, tws
, twt
);
28591 gen_helper_msa_binsr_h(cpu_env
, twd
, tws
, twt
);
28594 gen_helper_msa_binsr_w(cpu_env
, twd
, tws
, twt
);
28597 gen_helper_msa_binsr_d(cpu_env
, twd
, tws
, twt
);
28604 gen_helper_msa_bclr_b(cpu_env
, twd
, tws
, twt
);
28607 gen_helper_msa_bclr_h(cpu_env
, twd
, tws
, twt
);
28610 gen_helper_msa_bclr_w(cpu_env
, twd
, tws
, twt
);
28613 gen_helper_msa_bclr_d(cpu_env
, twd
, tws
, twt
);
28620 gen_helper_msa_bneg_b(cpu_env
, twd
, tws
, twt
);
28623 gen_helper_msa_bneg_h(cpu_env
, twd
, tws
, twt
);
28626 gen_helper_msa_bneg_w(cpu_env
, twd
, tws
, twt
);
28629 gen_helper_msa_bneg_d(cpu_env
, twd
, tws
, twt
);
28636 gen_helper_msa_bset_b(cpu_env
, twd
, tws
, twt
);
28639 gen_helper_msa_bset_h(cpu_env
, twd
, tws
, twt
);
28642 gen_helper_msa_bset_w(cpu_env
, twd
, tws
, twt
);
28645 gen_helper_msa_bset_d(cpu_env
, twd
, tws
, twt
);
28652 gen_helper_msa_add_a_b(cpu_env
, twd
, tws
, twt
);
28655 gen_helper_msa_add_a_h(cpu_env
, twd
, tws
, twt
);
28658 gen_helper_msa_add_a_w(cpu_env
, twd
, tws
, twt
);
28661 gen_helper_msa_add_a_d(cpu_env
, twd
, tws
, twt
);
28665 case OPC_ADDS_A_df
:
28668 gen_helper_msa_adds_a_b(cpu_env
, twd
, tws
, twt
);
28671 gen_helper_msa_adds_a_h(cpu_env
, twd
, tws
, twt
);
28674 gen_helper_msa_adds_a_w(cpu_env
, twd
, tws
, twt
);
28677 gen_helper_msa_adds_a_d(cpu_env
, twd
, tws
, twt
);
28681 case OPC_ADDS_S_df
:
28684 gen_helper_msa_adds_s_b(cpu_env
, twd
, tws
, twt
);
28687 gen_helper_msa_adds_s_h(cpu_env
, twd
, tws
, twt
);
28690 gen_helper_msa_adds_s_w(cpu_env
, twd
, tws
, twt
);
28693 gen_helper_msa_adds_s_d(cpu_env
, twd
, tws
, twt
);
28697 case OPC_ADDS_U_df
:
28700 gen_helper_msa_adds_u_b(cpu_env
, twd
, tws
, twt
);
28703 gen_helper_msa_adds_u_h(cpu_env
, twd
, tws
, twt
);
28706 gen_helper_msa_adds_u_w(cpu_env
, twd
, tws
, twt
);
28709 gen_helper_msa_adds_u_d(cpu_env
, twd
, tws
, twt
);
28716 gen_helper_msa_addv_b(cpu_env
, twd
, tws
, twt
);
28719 gen_helper_msa_addv_h(cpu_env
, twd
, tws
, twt
);
28722 gen_helper_msa_addv_w(cpu_env
, twd
, tws
, twt
);
28725 gen_helper_msa_addv_d(cpu_env
, twd
, tws
, twt
);
28732 gen_helper_msa_ave_s_b(cpu_env
, twd
, tws
, twt
);
28735 gen_helper_msa_ave_s_h(cpu_env
, twd
, tws
, twt
);
28738 gen_helper_msa_ave_s_w(cpu_env
, twd
, tws
, twt
);
28741 gen_helper_msa_ave_s_d(cpu_env
, twd
, tws
, twt
);
28748 gen_helper_msa_ave_u_b(cpu_env
, twd
, tws
, twt
);
28751 gen_helper_msa_ave_u_h(cpu_env
, twd
, tws
, twt
);
28754 gen_helper_msa_ave_u_w(cpu_env
, twd
, tws
, twt
);
28757 gen_helper_msa_ave_u_d(cpu_env
, twd
, tws
, twt
);
28761 case OPC_AVER_S_df
:
28764 gen_helper_msa_aver_s_b(cpu_env
, twd
, tws
, twt
);
28767 gen_helper_msa_aver_s_h(cpu_env
, twd
, tws
, twt
);
28770 gen_helper_msa_aver_s_w(cpu_env
, twd
, tws
, twt
);
28773 gen_helper_msa_aver_s_d(cpu_env
, twd
, tws
, twt
);
28777 case OPC_AVER_U_df
:
28780 gen_helper_msa_aver_u_b(cpu_env
, twd
, tws
, twt
);
28783 gen_helper_msa_aver_u_h(cpu_env
, twd
, tws
, twt
);
28786 gen_helper_msa_aver_u_w(cpu_env
, twd
, tws
, twt
);
28789 gen_helper_msa_aver_u_d(cpu_env
, twd
, tws
, twt
);
28796 gen_helper_msa_ceq_b(cpu_env
, twd
, tws
, twt
);
28799 gen_helper_msa_ceq_h(cpu_env
, twd
, tws
, twt
);
28802 gen_helper_msa_ceq_w(cpu_env
, twd
, tws
, twt
);
28805 gen_helper_msa_ceq_d(cpu_env
, twd
, tws
, twt
);
28812 gen_helper_msa_cle_s_b(cpu_env
, twd
, tws
, twt
);
28815 gen_helper_msa_cle_s_h(cpu_env
, twd
, tws
, twt
);
28818 gen_helper_msa_cle_s_w(cpu_env
, twd
, tws
, twt
);
28821 gen_helper_msa_cle_s_d(cpu_env
, twd
, tws
, twt
);
28828 gen_helper_msa_cle_u_b(cpu_env
, twd
, tws
, twt
);
28831 gen_helper_msa_cle_u_h(cpu_env
, twd
, tws
, twt
);
28834 gen_helper_msa_cle_u_w(cpu_env
, twd
, tws
, twt
);
28837 gen_helper_msa_cle_u_d(cpu_env
, twd
, tws
, twt
);
28844 gen_helper_msa_clt_s_b(cpu_env
, twd
, tws
, twt
);
28847 gen_helper_msa_clt_s_h(cpu_env
, twd
, tws
, twt
);
28850 gen_helper_msa_clt_s_w(cpu_env
, twd
, tws
, twt
);
28853 gen_helper_msa_clt_s_d(cpu_env
, twd
, tws
, twt
);
28860 gen_helper_msa_clt_u_b(cpu_env
, twd
, tws
, twt
);
28863 gen_helper_msa_clt_u_h(cpu_env
, twd
, tws
, twt
);
28866 gen_helper_msa_clt_u_w(cpu_env
, twd
, tws
, twt
);
28869 gen_helper_msa_clt_u_d(cpu_env
, twd
, tws
, twt
);
28876 gen_helper_msa_div_s_b(cpu_env
, twd
, tws
, twt
);
28879 gen_helper_msa_div_s_h(cpu_env
, twd
, tws
, twt
);
28882 gen_helper_msa_div_s_w(cpu_env
, twd
, tws
, twt
);
28885 gen_helper_msa_div_s_d(cpu_env
, twd
, tws
, twt
);
28892 gen_helper_msa_div_u_b(cpu_env
, twd
, tws
, twt
);
28895 gen_helper_msa_div_u_h(cpu_env
, twd
, tws
, twt
);
28898 gen_helper_msa_div_u_w(cpu_env
, twd
, tws
, twt
);
28901 gen_helper_msa_div_u_d(cpu_env
, twd
, tws
, twt
);
28908 gen_helper_msa_max_a_b(cpu_env
, twd
, tws
, twt
);
28911 gen_helper_msa_max_a_h(cpu_env
, twd
, tws
, twt
);
28914 gen_helper_msa_max_a_w(cpu_env
, twd
, tws
, twt
);
28917 gen_helper_msa_max_a_d(cpu_env
, twd
, tws
, twt
);
28924 gen_helper_msa_max_s_b(cpu_env
, twd
, tws
, twt
);
28927 gen_helper_msa_max_s_h(cpu_env
, twd
, tws
, twt
);
28930 gen_helper_msa_max_s_w(cpu_env
, twd
, tws
, twt
);
28933 gen_helper_msa_max_s_d(cpu_env
, twd
, tws
, twt
);
28940 gen_helper_msa_max_u_b(cpu_env
, twd
, tws
, twt
);
28943 gen_helper_msa_max_u_h(cpu_env
, twd
, tws
, twt
);
28946 gen_helper_msa_max_u_w(cpu_env
, twd
, tws
, twt
);
28949 gen_helper_msa_max_u_d(cpu_env
, twd
, tws
, twt
);
28956 gen_helper_msa_min_a_b(cpu_env
, twd
, tws
, twt
);
28959 gen_helper_msa_min_a_h(cpu_env
, twd
, tws
, twt
);
28962 gen_helper_msa_min_a_w(cpu_env
, twd
, tws
, twt
);
28965 gen_helper_msa_min_a_d(cpu_env
, twd
, tws
, twt
);
28972 gen_helper_msa_min_s_b(cpu_env
, twd
, tws
, twt
);
28975 gen_helper_msa_min_s_h(cpu_env
, twd
, tws
, twt
);
28978 gen_helper_msa_min_s_w(cpu_env
, twd
, tws
, twt
);
28981 gen_helper_msa_min_s_d(cpu_env
, twd
, tws
, twt
);
28988 gen_helper_msa_min_u_b(cpu_env
, twd
, tws
, twt
);
28991 gen_helper_msa_min_u_h(cpu_env
, twd
, tws
, twt
);
28994 gen_helper_msa_min_u_w(cpu_env
, twd
, tws
, twt
);
28997 gen_helper_msa_min_u_d(cpu_env
, twd
, tws
, twt
);
29004 gen_helper_msa_mod_s_b(cpu_env
, twd
, tws
, twt
);
29007 gen_helper_msa_mod_s_h(cpu_env
, twd
, tws
, twt
);
29010 gen_helper_msa_mod_s_w(cpu_env
, twd
, tws
, twt
);
29013 gen_helper_msa_mod_s_d(cpu_env
, twd
, tws
, twt
);
29020 gen_helper_msa_mod_u_b(cpu_env
, twd
, tws
, twt
);
29023 gen_helper_msa_mod_u_h(cpu_env
, twd
, tws
, twt
);
29026 gen_helper_msa_mod_u_w(cpu_env
, twd
, tws
, twt
);
29029 gen_helper_msa_mod_u_d(cpu_env
, twd
, tws
, twt
);
29033 case OPC_ASUB_S_df
:
29036 gen_helper_msa_asub_s_b(cpu_env
, twd
, tws
, twt
);
29039 gen_helper_msa_asub_s_h(cpu_env
, twd
, tws
, twt
);
29042 gen_helper_msa_asub_s_w(cpu_env
, twd
, tws
, twt
);
29045 gen_helper_msa_asub_s_d(cpu_env
, twd
, tws
, twt
);
29049 case OPC_ASUB_U_df
:
29052 gen_helper_msa_asub_u_b(cpu_env
, twd
, tws
, twt
);
29055 gen_helper_msa_asub_u_h(cpu_env
, twd
, tws
, twt
);
29058 gen_helper_msa_asub_u_w(cpu_env
, twd
, tws
, twt
);
29061 gen_helper_msa_asub_u_d(cpu_env
, twd
, tws
, twt
);
29068 gen_helper_msa_ilvev_b(cpu_env
, twd
, tws
, twt
);
29071 gen_helper_msa_ilvev_h(cpu_env
, twd
, tws
, twt
);
29074 gen_helper_msa_ilvev_w(cpu_env
, twd
, tws
, twt
);
29077 gen_helper_msa_ilvev_d(cpu_env
, twd
, tws
, twt
);
29084 gen_helper_msa_ilvod_b(cpu_env
, twd
, tws
, twt
);
29087 gen_helper_msa_ilvod_h(cpu_env
, twd
, tws
, twt
);
29090 gen_helper_msa_ilvod_w(cpu_env
, twd
, tws
, twt
);
29093 gen_helper_msa_ilvod_d(cpu_env
, twd
, tws
, twt
);
29100 gen_helper_msa_ilvl_b(cpu_env
, twd
, tws
, twt
);
29103 gen_helper_msa_ilvl_h(cpu_env
, twd
, tws
, twt
);
29106 gen_helper_msa_ilvl_w(cpu_env
, twd
, tws
, twt
);
29109 gen_helper_msa_ilvl_d(cpu_env
, twd
, tws
, twt
);
29116 gen_helper_msa_ilvr_b(cpu_env
, twd
, tws
, twt
);
29119 gen_helper_msa_ilvr_h(cpu_env
, twd
, tws
, twt
);
29122 gen_helper_msa_ilvr_w(cpu_env
, twd
, tws
, twt
);
29125 gen_helper_msa_ilvr_d(cpu_env
, twd
, tws
, twt
);
29132 gen_helper_msa_pckev_b(cpu_env
, twd
, tws
, twt
);
29135 gen_helper_msa_pckev_h(cpu_env
, twd
, tws
, twt
);
29138 gen_helper_msa_pckev_w(cpu_env
, twd
, tws
, twt
);
29141 gen_helper_msa_pckev_d(cpu_env
, twd
, tws
, twt
);
29148 gen_helper_msa_pckod_b(cpu_env
, twd
, tws
, twt
);
29151 gen_helper_msa_pckod_h(cpu_env
, twd
, tws
, twt
);
29154 gen_helper_msa_pckod_w(cpu_env
, twd
, tws
, twt
);
29157 gen_helper_msa_pckod_d(cpu_env
, twd
, tws
, twt
);
29164 gen_helper_msa_sll_b(cpu_env
, twd
, tws
, twt
);
29167 gen_helper_msa_sll_h(cpu_env
, twd
, tws
, twt
);
29170 gen_helper_msa_sll_w(cpu_env
, twd
, tws
, twt
);
29173 gen_helper_msa_sll_d(cpu_env
, twd
, tws
, twt
);
29180 gen_helper_msa_sra_b(cpu_env
, twd
, tws
, twt
);
29183 gen_helper_msa_sra_h(cpu_env
, twd
, tws
, twt
);
29186 gen_helper_msa_sra_w(cpu_env
, twd
, tws
, twt
);
29189 gen_helper_msa_sra_d(cpu_env
, twd
, tws
, twt
);
29196 gen_helper_msa_srar_b(cpu_env
, twd
, tws
, twt
);
29199 gen_helper_msa_srar_h(cpu_env
, twd
, tws
, twt
);
29202 gen_helper_msa_srar_w(cpu_env
, twd
, tws
, twt
);
29205 gen_helper_msa_srar_d(cpu_env
, twd
, tws
, twt
);
29212 gen_helper_msa_srl_b(cpu_env
, twd
, tws
, twt
);
29215 gen_helper_msa_srl_h(cpu_env
, twd
, tws
, twt
);
29218 gen_helper_msa_srl_w(cpu_env
, twd
, tws
, twt
);
29221 gen_helper_msa_srl_d(cpu_env
, twd
, tws
, twt
);
29228 gen_helper_msa_srlr_b(cpu_env
, twd
, tws
, twt
);
29231 gen_helper_msa_srlr_h(cpu_env
, twd
, tws
, twt
);
29234 gen_helper_msa_srlr_w(cpu_env
, twd
, tws
, twt
);
29237 gen_helper_msa_srlr_d(cpu_env
, twd
, tws
, twt
);
29241 case OPC_SUBS_S_df
:
29242 gen_helper_msa_subs_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29245 gen_helper_msa_mulv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29248 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
29251 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29254 gen_helper_msa_subv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29256 case OPC_SUBS_U_df
:
29257 gen_helper_msa_subs_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29260 gen_helper_msa_maddv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29263 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
29265 case OPC_SUBSUS_U_df
:
29266 gen_helper_msa_subsus_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29269 gen_helper_msa_msubv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29271 case OPC_SUBSUU_S_df
:
29272 gen_helper_msa_subsuu_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29275 case OPC_DOTP_S_df
:
29276 case OPC_DOTP_U_df
:
29277 case OPC_DPADD_S_df
:
29278 case OPC_DPADD_U_df
:
29279 case OPC_DPSUB_S_df
:
29280 case OPC_HADD_S_df
:
29281 case OPC_DPSUB_U_df
:
29282 case OPC_HADD_U_df
:
29283 case OPC_HSUB_S_df
:
29284 case OPC_HSUB_U_df
:
29285 if (df
== DF_BYTE
) {
29286 generate_exception_end(ctx
, EXCP_RI
);
29289 switch (MASK_MSA_3R(ctx
->opcode
)) {
29290 case OPC_HADD_S_df
:
29293 gen_helper_msa_hadd_s_h(cpu_env
, twd
, tws
, twt
);
29296 gen_helper_msa_hadd_s_w(cpu_env
, twd
, tws
, twt
);
29299 gen_helper_msa_hadd_s_d(cpu_env
, twd
, tws
, twt
);
29303 case OPC_HADD_U_df
:
29306 gen_helper_msa_hadd_u_h(cpu_env
, twd
, tws
, twt
);
29309 gen_helper_msa_hadd_u_w(cpu_env
, twd
, tws
, twt
);
29312 gen_helper_msa_hadd_u_d(cpu_env
, twd
, tws
, twt
);
29316 case OPC_HSUB_S_df
:
29319 gen_helper_msa_hsub_s_h(cpu_env
, twd
, tws
, twt
);
29322 gen_helper_msa_hsub_s_w(cpu_env
, twd
, tws
, twt
);
29325 gen_helper_msa_hsub_s_d(cpu_env
, twd
, tws
, twt
);
29329 case OPC_HSUB_U_df
:
29332 gen_helper_msa_hsub_u_h(cpu_env
, twd
, tws
, twt
);
29335 gen_helper_msa_hsub_u_w(cpu_env
, twd
, tws
, twt
);
29338 gen_helper_msa_hsub_u_d(cpu_env
, twd
, tws
, twt
);
29342 case OPC_DOTP_S_df
:
29343 gen_helper_msa_dotp_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29345 case OPC_DOTP_U_df
:
29346 gen_helper_msa_dotp_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29348 case OPC_DPADD_S_df
:
29349 gen_helper_msa_dpadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29351 case OPC_DPADD_U_df
:
29352 gen_helper_msa_dpadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29354 case OPC_DPSUB_S_df
:
29355 gen_helper_msa_dpsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29357 case OPC_DPSUB_U_df
:
29358 gen_helper_msa_dpsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29363 MIPS_INVAL("MSA instruction");
29364 generate_exception_end(ctx
, EXCP_RI
);
29367 tcg_temp_free_i32(twd
);
29368 tcg_temp_free_i32(tws
);
29369 tcg_temp_free_i32(twt
);
29370 tcg_temp_free_i32(tdf
);
29373 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
29375 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29376 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
29377 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
29378 TCGv telm
= tcg_temp_new();
29379 TCGv_i32 tsr
= tcg_const_i32(source
);
29380 TCGv_i32 tdt
= tcg_const_i32(dest
);
29382 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
29384 gen_load_gpr(telm
, source
);
29385 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
29388 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
29389 gen_store_gpr(telm
, dest
);
29392 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
29395 MIPS_INVAL("MSA instruction");
29396 generate_exception_end(ctx
, EXCP_RI
);
29400 tcg_temp_free(telm
);
29401 tcg_temp_free_i32(tdt
);
29402 tcg_temp_free_i32(tsr
);
29405 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
29408 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29409 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29410 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29412 TCGv_i32 tws
= tcg_const_i32(ws
);
29413 TCGv_i32 twd
= tcg_const_i32(wd
);
29414 TCGv_i32 tn
= tcg_const_i32(n
);
29415 TCGv_i32 tdf
= tcg_const_i32(df
);
29417 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29419 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
29421 case OPC_SPLATI_df
:
29422 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
29425 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
29427 case OPC_COPY_S_df
:
29428 case OPC_COPY_U_df
:
29429 case OPC_INSERT_df
:
29430 #if !defined(TARGET_MIPS64)
29431 /* Double format valid only for MIPS64 */
29432 if (df
== DF_DOUBLE
) {
29433 generate_exception_end(ctx
, EXCP_RI
);
29436 if ((MASK_MSA_ELM(ctx
->opcode
) == OPC_COPY_U_df
) &&
29438 generate_exception_end(ctx
, EXCP_RI
);
29442 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29443 case OPC_COPY_S_df
:
29444 if (likely(wd
!= 0)) {
29447 gen_helper_msa_copy_s_b(cpu_env
, twd
, tws
, tn
);
29450 gen_helper_msa_copy_s_h(cpu_env
, twd
, tws
, tn
);
29453 gen_helper_msa_copy_s_w(cpu_env
, twd
, tws
, tn
);
29455 #if defined(TARGET_MIPS64)
29457 gen_helper_msa_copy_s_d(cpu_env
, twd
, tws
, tn
);
29465 case OPC_COPY_U_df
:
29466 if (likely(wd
!= 0)) {
29469 gen_helper_msa_copy_u_b(cpu_env
, twd
, tws
, tn
);
29472 gen_helper_msa_copy_u_h(cpu_env
, twd
, tws
, tn
);
29474 #if defined(TARGET_MIPS64)
29476 gen_helper_msa_copy_u_w(cpu_env
, twd
, tws
, tn
);
29484 case OPC_INSERT_df
:
29487 gen_helper_msa_insert_b(cpu_env
, twd
, tws
, tn
);
29490 gen_helper_msa_insert_h(cpu_env
, twd
, tws
, tn
);
29493 gen_helper_msa_insert_w(cpu_env
, twd
, tws
, tn
);
29495 #if defined(TARGET_MIPS64)
29497 gen_helper_msa_insert_d(cpu_env
, twd
, tws
, tn
);
29507 MIPS_INVAL("MSA instruction");
29508 generate_exception_end(ctx
, EXCP_RI
);
29510 tcg_temp_free_i32(twd
);
29511 tcg_temp_free_i32(tws
);
29512 tcg_temp_free_i32(tn
);
29513 tcg_temp_free_i32(tdf
);
29516 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
29518 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
29519 uint32_t df
= 0, n
= 0;
29521 if ((dfn
& 0x30) == 0x00) {
29524 } else if ((dfn
& 0x38) == 0x20) {
29527 } else if ((dfn
& 0x3c) == 0x30) {
29530 } else if ((dfn
& 0x3e) == 0x38) {
29533 } else if (dfn
== 0x3E) {
29534 /* CTCMSA, CFCMSA, MOVE.V */
29535 gen_msa_elm_3e(env
, ctx
);
29538 generate_exception_end(ctx
, EXCP_RI
);
29542 gen_msa_elm_df(env
, ctx
, df
, n
);
29545 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
29547 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29548 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
29549 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29550 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29551 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29553 TCGv_i32 twd
= tcg_const_i32(wd
);
29554 TCGv_i32 tws
= tcg_const_i32(ws
);
29555 TCGv_i32 twt
= tcg_const_i32(wt
);
29556 TCGv_i32 tdf
= tcg_temp_new_i32();
29558 /* adjust df value for floating-point instruction */
29559 tcg_gen_movi_i32(tdf
, df
+ 2);
29561 switch (MASK_MSA_3RF(ctx
->opcode
)) {
29563 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29566 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
29569 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
29572 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
29575 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
29578 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29581 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
29584 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
29587 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29590 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29593 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
29596 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
29599 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
29602 tcg_gen_movi_i32(tdf
, df
+ 1);
29603 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29606 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
29609 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
29611 case OPC_MADD_Q_df
:
29612 tcg_gen_movi_i32(tdf
, df
+ 1);
29613 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29616 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
29618 case OPC_MSUB_Q_df
:
29619 tcg_gen_movi_i32(tdf
, df
+ 1);
29620 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29623 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
29626 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
29629 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29632 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
29635 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
29638 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
29641 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29644 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29647 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
29650 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29653 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
29656 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
29659 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
29661 case OPC_MULR_Q_df
:
29662 tcg_gen_movi_i32(tdf
, df
+ 1);
29663 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29666 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
29668 case OPC_FMIN_A_df
:
29669 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
29671 case OPC_MADDR_Q_df
:
29672 tcg_gen_movi_i32(tdf
, df
+ 1);
29673 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29676 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
29679 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
29681 case OPC_MSUBR_Q_df
:
29682 tcg_gen_movi_i32(tdf
, df
+ 1);
29683 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29686 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
29688 case OPC_FMAX_A_df
:
29689 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
29692 MIPS_INVAL("MSA instruction");
29693 generate_exception_end(ctx
, EXCP_RI
);
29697 tcg_temp_free_i32(twd
);
29698 tcg_temp_free_i32(tws
);
29699 tcg_temp_free_i32(twt
);
29700 tcg_temp_free_i32(tdf
);
29703 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
29705 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29706 (op & (0x7 << 18)))
29707 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29708 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29709 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29710 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
29711 TCGv_i32 twd
= tcg_const_i32(wd
);
29712 TCGv_i32 tws
= tcg_const_i32(ws
);
29713 TCGv_i32 twt
= tcg_const_i32(wt
);
29714 TCGv_i32 tdf
= tcg_const_i32(df
);
29716 switch (MASK_MSA_2R(ctx
->opcode
)) {
29718 #if !defined(TARGET_MIPS64)
29719 /* Double format valid only for MIPS64 */
29720 if (df
== DF_DOUBLE
) {
29721 generate_exception_end(ctx
, EXCP_RI
);
29725 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
29730 gen_helper_msa_nloc_b(cpu_env
, twd
, tws
);
29733 gen_helper_msa_nloc_h(cpu_env
, twd
, tws
);
29736 gen_helper_msa_nloc_w(cpu_env
, twd
, tws
);
29739 gen_helper_msa_nloc_d(cpu_env
, twd
, tws
);
29746 gen_helper_msa_nlzc_b(cpu_env
, twd
, tws
);
29749 gen_helper_msa_nlzc_h(cpu_env
, twd
, tws
);
29752 gen_helper_msa_nlzc_w(cpu_env
, twd
, tws
);
29755 gen_helper_msa_nlzc_d(cpu_env
, twd
, tws
);
29762 gen_helper_msa_pcnt_b(cpu_env
, twd
, tws
);
29765 gen_helper_msa_pcnt_h(cpu_env
, twd
, tws
);
29768 gen_helper_msa_pcnt_w(cpu_env
, twd
, tws
);
29771 gen_helper_msa_pcnt_d(cpu_env
, twd
, tws
);
29776 MIPS_INVAL("MSA instruction");
29777 generate_exception_end(ctx
, EXCP_RI
);
29781 tcg_temp_free_i32(twd
);
29782 tcg_temp_free_i32(tws
);
29783 tcg_temp_free_i32(twt
);
29784 tcg_temp_free_i32(tdf
);
29787 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
29789 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29790 (op & (0xf << 17)))
29791 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29792 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29793 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29794 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
29795 TCGv_i32 twd
= tcg_const_i32(wd
);
29796 TCGv_i32 tws
= tcg_const_i32(ws
);
29797 TCGv_i32 twt
= tcg_const_i32(wt
);
29798 /* adjust df value for floating-point instruction */
29799 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
29801 switch (MASK_MSA_2RF(ctx
->opcode
)) {
29802 case OPC_FCLASS_df
:
29803 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
29805 case OPC_FTRUNC_S_df
:
29806 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
29808 case OPC_FTRUNC_U_df
:
29809 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
29812 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
29814 case OPC_FRSQRT_df
:
29815 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
29818 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
29821 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
29824 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
29826 case OPC_FEXUPL_df
:
29827 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
29829 case OPC_FEXUPR_df
:
29830 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
29833 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
29836 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
29838 case OPC_FTINT_S_df
:
29839 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
29841 case OPC_FTINT_U_df
:
29842 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
29844 case OPC_FFINT_S_df
:
29845 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
29847 case OPC_FFINT_U_df
:
29848 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
29852 tcg_temp_free_i32(twd
);
29853 tcg_temp_free_i32(tws
);
29854 tcg_temp_free_i32(twt
);
29855 tcg_temp_free_i32(tdf
);
29858 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
29860 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
29861 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29862 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29863 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29864 TCGv_i32 twd
= tcg_const_i32(wd
);
29865 TCGv_i32 tws
= tcg_const_i32(ws
);
29866 TCGv_i32 twt
= tcg_const_i32(wt
);
29868 switch (MASK_MSA_VEC(ctx
->opcode
)) {
29870 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
29873 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
29876 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
29879 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
29882 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
29885 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
29888 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
29891 MIPS_INVAL("MSA instruction");
29892 generate_exception_end(ctx
, EXCP_RI
);
29896 tcg_temp_free_i32(twd
);
29897 tcg_temp_free_i32(tws
);
29898 tcg_temp_free_i32(twt
);
29901 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
29903 switch (MASK_MSA_VEC(ctx
->opcode
)) {
29911 gen_msa_vec_v(env
, ctx
);
29914 gen_msa_2r(env
, ctx
);
29917 gen_msa_2rf(env
, ctx
);
29920 MIPS_INVAL("MSA instruction");
29921 generate_exception_end(ctx
, EXCP_RI
);
29926 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
29928 uint32_t opcode
= ctx
->opcode
;
29929 check_insn(ctx
, ASE_MSA
);
29930 check_msa_access(ctx
);
29932 switch (MASK_MSA_MINOR(opcode
)) {
29933 case OPC_MSA_I8_00
:
29934 case OPC_MSA_I8_01
:
29935 case OPC_MSA_I8_02
:
29936 gen_msa_i8(env
, ctx
);
29938 case OPC_MSA_I5_06
:
29939 case OPC_MSA_I5_07
:
29940 gen_msa_i5(env
, ctx
);
29942 case OPC_MSA_BIT_09
:
29943 case OPC_MSA_BIT_0A
:
29944 gen_msa_bit(env
, ctx
);
29946 case OPC_MSA_3R_0D
:
29947 case OPC_MSA_3R_0E
:
29948 case OPC_MSA_3R_0F
:
29949 case OPC_MSA_3R_10
:
29950 case OPC_MSA_3R_11
:
29951 case OPC_MSA_3R_12
:
29952 case OPC_MSA_3R_13
:
29953 case OPC_MSA_3R_14
:
29954 case OPC_MSA_3R_15
:
29955 gen_msa_3r(env
, ctx
);
29958 gen_msa_elm(env
, ctx
);
29960 case OPC_MSA_3RF_1A
:
29961 case OPC_MSA_3RF_1B
:
29962 case OPC_MSA_3RF_1C
:
29963 gen_msa_3rf(env
, ctx
);
29966 gen_msa_vec(env
, ctx
);
29977 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
29978 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
29979 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29980 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
29982 TCGv_i32 twd
= tcg_const_i32(wd
);
29983 TCGv taddr
= tcg_temp_new();
29984 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
29986 switch (MASK_MSA_MINOR(opcode
)) {
29988 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
29991 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
29994 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
29997 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
30000 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
30003 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
30006 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
30009 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
30013 tcg_temp_free_i32(twd
);
30014 tcg_temp_free(taddr
);
30018 MIPS_INVAL("MSA instruction");
30019 generate_exception_end(ctx
, EXCP_RI
);
30025 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
30028 int rs
, rt
, rd
, sa
;
30032 /* make sure instructions are on a word boundary */
30033 if (ctx
->base
.pc_next
& 0x3) {
30034 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
30035 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
30039 /* Handle blikely not taken case */
30040 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
30041 TCGLabel
*l1
= gen_new_label();
30043 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
30044 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
30045 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
30049 op
= MASK_OP_MAJOR(ctx
->opcode
);
30050 rs
= (ctx
->opcode
>> 21) & 0x1f;
30051 rt
= (ctx
->opcode
>> 16) & 0x1f;
30052 rd
= (ctx
->opcode
>> 11) & 0x1f;
30053 sa
= (ctx
->opcode
>> 6) & 0x1f;
30054 imm
= (int16_t)ctx
->opcode
;
30057 decode_opc_special(env
, ctx
);
30060 #if defined(TARGET_MIPS64)
30061 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
30062 decode_mmi(env
, ctx
);
30064 if (ctx
->insn_flags
& ASE_MXU
) {
30065 decode_opc_mxu(env
, ctx
);
30068 decode_opc_special2_legacy(env
, ctx
);
30072 #if defined(TARGET_MIPS64)
30073 if (ctx
->insn_flags
& INSN_R5900
) {
30074 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
30076 decode_opc_special3(env
, ctx
);
30079 decode_opc_special3(env
, ctx
);
30083 op1
= MASK_REGIMM(ctx
->opcode
);
30085 case OPC_BLTZL
: /* REGIMM branches */
30089 check_insn(ctx
, ISA_MIPS2
);
30090 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30094 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30098 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30100 /* OPC_NAL, OPC_BAL */
30101 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
30103 generate_exception_end(ctx
, EXCP_RI
);
30106 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30109 case OPC_TGEI
: /* REGIMM traps */
30116 check_insn(ctx
, ISA_MIPS2
);
30117 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30118 gen_trap(ctx
, op1
, rs
, -1, imm
);
30121 check_insn(ctx
, ISA_MIPS32R6
);
30122 generate_exception_end(ctx
, EXCP_RI
);
30125 check_insn(ctx
, ISA_MIPS32R2
);
30127 * Break the TB to be able to sync copied instructions
30130 ctx
->base
.is_jmp
= DISAS_STOP
;
30132 case OPC_BPOSGE32
: /* MIPS DSP branch */
30133 #if defined(TARGET_MIPS64)
30137 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
30139 #if defined(TARGET_MIPS64)
30141 check_insn(ctx
, ISA_MIPS32R6
);
30142 check_mips_64(ctx
);
30144 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
30148 check_insn(ctx
, ISA_MIPS32R6
);
30149 check_mips_64(ctx
);
30151 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
30155 default: /* Invalid */
30156 MIPS_INVAL("regimm");
30157 generate_exception_end(ctx
, EXCP_RI
);
30162 check_cp0_enabled(ctx
);
30163 op1
= MASK_CP0(ctx
->opcode
);
30171 #if defined(TARGET_MIPS64)
30175 #ifndef CONFIG_USER_ONLY
30176 gen_cp0(env
, ctx
, op1
, rt
, rd
);
30177 #endif /* !CONFIG_USER_ONLY */
30195 #ifndef CONFIG_USER_ONLY
30196 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
30197 #endif /* !CONFIG_USER_ONLY */
30200 #ifndef CONFIG_USER_ONLY
30203 TCGv t0
= tcg_temp_new();
30205 op2
= MASK_MFMC0(ctx
->opcode
);
30209 gen_helper_dmt(t0
);
30210 gen_store_gpr(t0
, rt
);
30214 gen_helper_emt(t0
);
30215 gen_store_gpr(t0
, rt
);
30219 gen_helper_dvpe(t0
, cpu_env
);
30220 gen_store_gpr(t0
, rt
);
30224 gen_helper_evpe(t0
, cpu_env
);
30225 gen_store_gpr(t0
, rt
);
30228 check_insn(ctx
, ISA_MIPS32R6
);
30230 gen_helper_dvp(t0
, cpu_env
);
30231 gen_store_gpr(t0
, rt
);
30235 check_insn(ctx
, ISA_MIPS32R6
);
30237 gen_helper_evp(t0
, cpu_env
);
30238 gen_store_gpr(t0
, rt
);
30242 check_insn(ctx
, ISA_MIPS32R2
);
30243 save_cpu_state(ctx
, 1);
30244 gen_helper_di(t0
, cpu_env
);
30245 gen_store_gpr(t0
, rt
);
30247 * Stop translation as we may have switched
30248 * the execution mode.
30250 ctx
->base
.is_jmp
= DISAS_STOP
;
30253 check_insn(ctx
, ISA_MIPS32R2
);
30254 save_cpu_state(ctx
, 1);
30255 gen_helper_ei(t0
, cpu_env
);
30256 gen_store_gpr(t0
, rt
);
30258 * DISAS_STOP isn't sufficient, we need to ensure we break
30259 * out of translated code to check for pending interrupts.
30261 gen_save_pc(ctx
->base
.pc_next
+ 4);
30262 ctx
->base
.is_jmp
= DISAS_EXIT
;
30264 default: /* Invalid */
30265 MIPS_INVAL("mfmc0");
30266 generate_exception_end(ctx
, EXCP_RI
);
30271 #endif /* !CONFIG_USER_ONLY */
30274 check_insn(ctx
, ISA_MIPS32R2
);
30275 gen_load_srsgpr(rt
, rd
);
30278 check_insn(ctx
, ISA_MIPS32R2
);
30279 gen_store_srsgpr(rt
, rd
);
30283 generate_exception_end(ctx
, EXCP_RI
);
30287 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30288 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30289 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30290 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30293 /* Arithmetic with immediate opcode */
30294 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30298 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30300 case OPC_SLTI
: /* Set on less than with immediate opcode */
30302 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
30304 case OPC_ANDI
: /* Arithmetic with immediate opcode */
30305 case OPC_LUI
: /* OPC_AUI */
30308 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
30310 case OPC_J
: /* Jump */
30312 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30313 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30316 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30317 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30319 generate_exception_end(ctx
, EXCP_RI
);
30322 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30323 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30326 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30329 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30330 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30332 generate_exception_end(ctx
, EXCP_RI
);
30335 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30336 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30339 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30342 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30345 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30347 check_insn(ctx
, ISA_MIPS32R6
);
30348 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30349 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30352 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30355 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30357 check_insn(ctx
, ISA_MIPS32R6
);
30358 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30359 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30364 check_insn(ctx
, ISA_MIPS2
);
30365 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30369 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30371 case OPC_LL
: /* Load and stores */
30372 check_insn(ctx
, ISA_MIPS2
);
30373 if (ctx
->insn_flags
& INSN_R5900
) {
30374 check_insn_opc_user_only(ctx
, INSN_R5900
);
30379 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30387 gen_ld(ctx
, op
, rt
, rs
, imm
);
30391 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30396 gen_st(ctx
, op
, rt
, rs
, imm
);
30399 check_insn(ctx
, ISA_MIPS2
);
30400 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30401 if (ctx
->insn_flags
& INSN_R5900
) {
30402 check_insn_opc_user_only(ctx
, INSN_R5900
);
30404 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
30407 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30408 check_cp0_enabled(ctx
);
30409 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
30410 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
30411 gen_cache_operation(ctx
, rt
, rs
, imm
);
30413 /* Treat as NOP. */
30416 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30417 if (ctx
->insn_flags
& INSN_R5900
) {
30418 /* Treat as NOP. */
30420 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
30421 /* Treat as NOP. */
30425 /* Floating point (COP1). */
30430 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
30434 op1
= MASK_CP1(ctx
->opcode
);
30439 check_cp1_enabled(ctx
);
30440 check_insn(ctx
, ISA_MIPS32R2
);
30446 check_cp1_enabled(ctx
);
30447 gen_cp1(ctx
, op1
, rt
, rd
);
30449 #if defined(TARGET_MIPS64)
30452 check_cp1_enabled(ctx
);
30453 check_insn(ctx
, ISA_MIPS3
);
30454 check_mips_64(ctx
);
30455 gen_cp1(ctx
, op1
, rt
, rd
);
30458 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
30459 check_cp1_enabled(ctx
);
30460 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30462 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
30467 check_insn(ctx
, ASE_MIPS3D
);
30468 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
30469 (rt
>> 2) & 0x7, imm
<< 2);
30473 check_cp1_enabled(ctx
);
30474 check_insn(ctx
, ISA_MIPS32R6
);
30475 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
30479 check_cp1_enabled(ctx
);
30480 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30482 check_insn(ctx
, ASE_MIPS3D
);
30485 check_cp1_enabled(ctx
);
30486 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30487 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
30488 (rt
>> 2) & 0x7, imm
<< 2);
30495 check_cp1_enabled(ctx
);
30496 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
30502 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
30503 check_cp1_enabled(ctx
);
30504 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30506 case R6_OPC_CMP_AF_S
:
30507 case R6_OPC_CMP_UN_S
:
30508 case R6_OPC_CMP_EQ_S
:
30509 case R6_OPC_CMP_UEQ_S
:
30510 case R6_OPC_CMP_LT_S
:
30511 case R6_OPC_CMP_ULT_S
:
30512 case R6_OPC_CMP_LE_S
:
30513 case R6_OPC_CMP_ULE_S
:
30514 case R6_OPC_CMP_SAF_S
:
30515 case R6_OPC_CMP_SUN_S
:
30516 case R6_OPC_CMP_SEQ_S
:
30517 case R6_OPC_CMP_SEUQ_S
:
30518 case R6_OPC_CMP_SLT_S
:
30519 case R6_OPC_CMP_SULT_S
:
30520 case R6_OPC_CMP_SLE_S
:
30521 case R6_OPC_CMP_SULE_S
:
30522 case R6_OPC_CMP_OR_S
:
30523 case R6_OPC_CMP_UNE_S
:
30524 case R6_OPC_CMP_NE_S
:
30525 case R6_OPC_CMP_SOR_S
:
30526 case R6_OPC_CMP_SUNE_S
:
30527 case R6_OPC_CMP_SNE_S
:
30528 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
30530 case R6_OPC_CMP_AF_D
:
30531 case R6_OPC_CMP_UN_D
:
30532 case R6_OPC_CMP_EQ_D
:
30533 case R6_OPC_CMP_UEQ_D
:
30534 case R6_OPC_CMP_LT_D
:
30535 case R6_OPC_CMP_ULT_D
:
30536 case R6_OPC_CMP_LE_D
:
30537 case R6_OPC_CMP_ULE_D
:
30538 case R6_OPC_CMP_SAF_D
:
30539 case R6_OPC_CMP_SUN_D
:
30540 case R6_OPC_CMP_SEQ_D
:
30541 case R6_OPC_CMP_SEUQ_D
:
30542 case R6_OPC_CMP_SLT_D
:
30543 case R6_OPC_CMP_SULT_D
:
30544 case R6_OPC_CMP_SLE_D
:
30545 case R6_OPC_CMP_SULE_D
:
30546 case R6_OPC_CMP_OR_D
:
30547 case R6_OPC_CMP_UNE_D
:
30548 case R6_OPC_CMP_NE_D
:
30549 case R6_OPC_CMP_SOR_D
:
30550 case R6_OPC_CMP_SUNE_D
:
30551 case R6_OPC_CMP_SNE_D
:
30552 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
30555 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
30556 rt
, rd
, sa
, (imm
>> 8) & 0x7);
30561 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
30576 check_insn(ctx
, ASE_MSA
);
30577 gen_msa_branch(env
, ctx
, op1
);
30581 generate_exception_end(ctx
, EXCP_RI
);
30586 /* Compact branches [R6] and COP2 [non-R6] */
30587 case OPC_BC
: /* OPC_LWC2 */
30588 case OPC_BALC
: /* OPC_SWC2 */
30589 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30590 /* OPC_BC, OPC_BALC */
30591 gen_compute_compact_branch(ctx
, op
, 0, 0,
30592 sextract32(ctx
->opcode
<< 2, 0, 28));
30594 /* OPC_LWC2, OPC_SWC2 */
30595 /* COP2: Not implemented. */
30596 generate_exception_err(ctx
, EXCP_CpU
, 2);
30599 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
30600 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
30601 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30603 /* OPC_BEQZC, OPC_BNEZC */
30604 gen_compute_compact_branch(ctx
, op
, rs
, 0,
30605 sextract32(ctx
->opcode
<< 2, 0, 23));
30607 /* OPC_JIC, OPC_JIALC */
30608 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
30611 /* OPC_LWC2, OPC_SWC2 */
30612 /* COP2: Not implemented. */
30613 generate_exception_err(ctx
, EXCP_CpU
, 2);
30617 check_insn(ctx
, INSN_LOONGSON2F
);
30618 /* Note that these instructions use different fields. */
30619 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
30623 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30624 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
30625 check_cp1_enabled(ctx
);
30626 op1
= MASK_CP3(ctx
->opcode
);
30630 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
30636 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30637 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
30640 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30641 /* Treat as NOP. */
30644 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
30658 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30659 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
30663 generate_exception_end(ctx
, EXCP_RI
);
30667 generate_exception_err(ctx
, EXCP_CpU
, 1);
30671 #if defined(TARGET_MIPS64)
30672 /* MIPS64 opcodes */
30674 if (ctx
->insn_flags
& INSN_R5900
) {
30675 check_insn_opc_user_only(ctx
, INSN_R5900
);
30680 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30684 check_insn(ctx
, ISA_MIPS3
);
30685 check_mips_64(ctx
);
30686 gen_ld(ctx
, op
, rt
, rs
, imm
);
30690 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30693 check_insn(ctx
, ISA_MIPS3
);
30694 check_mips_64(ctx
);
30695 gen_st(ctx
, op
, rt
, rs
, imm
);
30698 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30699 check_insn(ctx
, ISA_MIPS3
);
30700 if (ctx
->insn_flags
& INSN_R5900
) {
30701 check_insn_opc_user_only(ctx
, INSN_R5900
);
30703 check_mips_64(ctx
);
30704 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
30706 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
30707 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30708 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
30709 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30712 check_insn(ctx
, ISA_MIPS3
);
30713 check_mips_64(ctx
);
30714 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30718 check_insn(ctx
, ISA_MIPS3
);
30719 check_mips_64(ctx
);
30720 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30723 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
30724 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30725 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30727 MIPS_INVAL("major opcode");
30728 generate_exception_end(ctx
, EXCP_RI
);
30732 case OPC_DAUI
: /* OPC_JALX */
30733 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30734 #if defined(TARGET_MIPS64)
30736 check_mips_64(ctx
);
30738 generate_exception(ctx
, EXCP_RI
);
30739 } else if (rt
!= 0) {
30740 TCGv t0
= tcg_temp_new();
30741 gen_load_gpr(t0
, rs
);
30742 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
30746 generate_exception_end(ctx
, EXCP_RI
);
30747 MIPS_INVAL("major opcode");
30751 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
30752 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30753 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30756 case OPC_MSA
: /* OPC_MDMX */
30757 if (ctx
->insn_flags
& INSN_R5900
) {
30758 #if defined(TARGET_MIPS64)
30759 gen_mmi_lq(env
, ctx
); /* MMI_OPC_LQ */
30762 /* MDMX: Not implemented. */
30767 check_insn(ctx
, ISA_MIPS32R6
);
30768 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
30770 default: /* Invalid */
30771 MIPS_INVAL("major opcode");
30772 generate_exception_end(ctx
, EXCP_RI
);
30777 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
30779 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30780 CPUMIPSState
*env
= cs
->env_ptr
;
30782 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
30783 ctx
->saved_pc
= -1;
30784 ctx
->insn_flags
= env
->insn_flags
;
30785 ctx
->CP0_Config1
= env
->CP0_Config1
;
30786 ctx
->CP0_Config2
= env
->CP0_Config2
;
30787 ctx
->CP0_Config3
= env
->CP0_Config3
;
30788 ctx
->CP0_Config5
= env
->CP0_Config5
;
30790 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
30791 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
30792 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
30793 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
30794 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
30795 ctx
->PAMask
= env
->PAMask
;
30796 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
30797 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
30798 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
30799 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
30800 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
30801 /* Restore delay slot state from the tb context. */
30802 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
30803 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
30804 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
30805 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
30806 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
30807 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
30808 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
30809 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
30810 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
30811 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
30812 restore_cpu_state(env
, ctx
);
30813 #ifdef CONFIG_USER_ONLY
30814 ctx
->mem_idx
= MIPS_HFLAG_UM
;
30816 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
30818 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& ISA_MIPS32R6
) ?
30819 MO_UNALN
: MO_ALIGN
;
30821 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
30825 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
30829 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
30831 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30833 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
30837 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
30838 const CPUBreakpoint
*bp
)
30840 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30842 save_cpu_state(ctx
, 1);
30843 ctx
->base
.is_jmp
= DISAS_NORETURN
;
30844 gen_helper_raise_exception_debug(cpu_env
);
30846 * The address covered by the breakpoint must be included in
30847 * [tb->pc, tb->pc + tb->size) in order to for it to be
30848 * properly cleared -- thus we increment the PC here so that
30849 * the logic setting tb->size below does the right thing.
30851 ctx
->base
.pc_next
+= 4;
30855 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
30857 CPUMIPSState
*env
= cs
->env_ptr
;
30858 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30862 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
30863 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
30864 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30865 insn_bytes
= decode_nanomips_opc(env
, ctx
);
30866 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
30867 ctx
->opcode
= cpu_ldl_code(env
, ctx
->base
.pc_next
);
30869 decode_opc(env
, ctx
);
30870 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
30871 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30872 insn_bytes
= decode_micromips_opc(env
, ctx
);
30873 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
30874 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30875 insn_bytes
= decode_mips16_opc(env
, ctx
);
30877 generate_exception_end(ctx
, EXCP_RI
);
30878 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
30882 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
30883 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
30884 MIPS_HFLAG_FBNSLOT
))) {
30886 * Force to generate branch as there is neither delay nor
30891 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
30892 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
30894 * Force to generate branch as microMIPS R6 doesn't restrict
30895 * branches in the forbidden slot.
30901 gen_branch(ctx
, insn_bytes
);
30903 ctx
->base
.pc_next
+= insn_bytes
;
30905 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
30909 * Execute a branch and its delay slot as a single instruction.
30910 * This is what GDB expects and is consistent with what the
30911 * hardware does (e.g. if a delay slot instruction faults, the
30912 * reported PC is the PC of the branch).
30914 if (ctx
->base
.singlestep_enabled
&&
30915 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
30916 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
30918 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
30919 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
30923 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
30925 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30927 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
30928 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
30929 gen_helper_raise_exception_debug(cpu_env
);
30931 switch (ctx
->base
.is_jmp
) {
30933 gen_save_pc(ctx
->base
.pc_next
);
30934 tcg_gen_lookup_and_goto_ptr();
30937 case DISAS_TOO_MANY
:
30938 save_cpu_state(ctx
, 0);
30939 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
30942 tcg_gen_exit_tb(NULL
, 0);
30944 case DISAS_NORETURN
:
30947 g_assert_not_reached();
30952 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
30954 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
30955 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
30958 static const TranslatorOps mips_tr_ops
= {
30959 .init_disas_context
= mips_tr_init_disas_context
,
30960 .tb_start
= mips_tr_tb_start
,
30961 .insn_start
= mips_tr_insn_start
,
30962 .breakpoint_check
= mips_tr_breakpoint_check
,
30963 .translate_insn
= mips_tr_translate_insn
,
30964 .tb_stop
= mips_tr_tb_stop
,
30965 .disas_log
= mips_tr_disas_log
,
30968 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
30972 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
30975 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
30978 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
30980 #define printfpr(fp) \
30983 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
30984 " fd:%13g fs:%13g psu: %13g\n", \
30985 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
30986 (double)(fp)->fd, \
30987 (double)(fp)->fs[FP_ENDIAN_IDX], \
30988 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
30991 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
30992 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
30993 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
30994 " fd:%13g fs:%13g psu:%13g\n", \
30995 tmp.w[FP_ENDIAN_IDX], tmp.d, \
30997 (double)tmp.fs[FP_ENDIAN_IDX], \
30998 (double)tmp.fs[!FP_ENDIAN_IDX]); \
31004 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
31005 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
31006 get_float_exception_flags(&env
->active_fpu
.fp_status
));
31007 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
31008 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
31009 printfpr(&env
->active_fpu
.fpr
[i
]);
31015 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
31017 MIPSCPU
*cpu
= MIPS_CPU(cs
);
31018 CPUMIPSState
*env
= &cpu
->env
;
31021 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
31022 " LO=0x" TARGET_FMT_lx
" ds %04x "
31023 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
31024 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
31025 env
->hflags
, env
->btarget
, env
->bcond
);
31026 for (i
= 0; i
< 32; i
++) {
31027 if ((i
& 3) == 0) {
31028 qemu_fprintf(f
, "GPR%02d:", i
);
31030 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
31031 regnames
[i
], env
->active_tc
.gpr
[i
]);
31032 if ((i
& 3) == 3) {
31033 qemu_fprintf(f
, "\n");
31037 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
31038 TARGET_FMT_lx
"\n",
31039 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
31040 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
31042 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
31043 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
31044 env
->CP0_Config2
, env
->CP0_Config3
);
31045 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
31046 env
->CP0_Config4
, env
->CP0_Config5
);
31047 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
31048 fpu_dump_state(env
, f
, flags
);
31052 void mips_tcg_init(void)
31057 for (i
= 1; i
< 32; i
++)
31058 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31059 offsetof(CPUMIPSState
,
31063 for (i
= 0; i
< 32; i
++) {
31064 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
31066 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
31068 * The scalar floating-point unit (FPU) registers are mapped on
31069 * the MSA vector registers.
31071 fpu_f64
[i
] = msa_wr_d
[i
* 2];
31072 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
31073 msa_wr_d
[i
* 2 + 1] =
31074 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
31077 cpu_PC
= tcg_global_mem_new(cpu_env
,
31078 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
31079 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
31080 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
31081 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
31083 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
31084 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
31087 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
31088 offsetof(CPUMIPSState
,
31089 active_tc
.DSPControl
),
31091 bcond
= tcg_global_mem_new(cpu_env
,
31092 offsetof(CPUMIPSState
, bcond
), "bcond");
31093 btarget
= tcg_global_mem_new(cpu_env
,
31094 offsetof(CPUMIPSState
, btarget
), "btarget");
31095 hflags
= tcg_global_mem_new_i32(cpu_env
,
31096 offsetof(CPUMIPSState
, hflags
), "hflags");
31098 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
31099 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
31101 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
31102 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
31104 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
31106 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
31109 #if defined(TARGET_MIPS64)
31111 for (i
= 1; i
< 32; i
++) {
31112 cpu_mmr
[i
] = tcg_global_mem_new_i64(cpu_env
,
31113 offsetof(CPUMIPSState
,
31119 #if !defined(TARGET_MIPS64)
31120 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
31121 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31122 offsetof(CPUMIPSState
,
31123 active_tc
.mxu_gpr
[i
]),
31127 mxu_CR
= tcg_global_mem_new(cpu_env
,
31128 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
31129 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
31133 #include "translate_init.inc.c"
31135 void cpu_mips_realize_env(CPUMIPSState
*env
)
31137 env
->exception_base
= (int32_t)0xBFC00000;
31139 #ifndef CONFIG_USER_ONLY
31140 mmu_init(env
, env
->cpu_model
);
31142 fpu_init(env
, env
->cpu_model
);
31143 mvp_init(env
, env
->cpu_model
);
31146 bool cpu_supports_cps_smp(const char *cpu_type
)
31148 const MIPSCPUClass
*mcc
= MIPS_CPU_CLASS(object_class_by_name(cpu_type
));
31149 return (mcc
->cpu_def
->CP0_Config3
& (1 << CP0C3_CMGCR
)) != 0;
31152 bool cpu_supports_isa(const char *cpu_type
, uint64_t isa
)
31154 const MIPSCPUClass
*mcc
= MIPS_CPU_CLASS(object_class_by_name(cpu_type
));
31155 return (mcc
->cpu_def
->insn_flags
& isa
) != 0;
31158 void cpu_set_exception_base(int vp_index
, target_ulong address
)
31160 MIPSCPU
*vp
= MIPS_CPU(qemu_get_cpu(vp_index
));
31161 vp
->env
.exception_base
= address
;
31164 void cpu_state_reset(CPUMIPSState
*env
)
31166 CPUState
*cs
= env_cpu(env
);
31168 /* Reset registers to their default values */
31169 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
31170 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
31171 #ifdef TARGET_WORDS_BIGENDIAN
31172 env
->CP0_Config0
|= (1 << CP0C0_BE
);
31174 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
31175 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
31176 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
31177 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
31178 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
31179 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
31180 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
31181 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
31182 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
31183 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
31184 << env
->cpu_model
->CP0_LLAddr_shift
;
31185 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
31186 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
31187 env
->CCRes
= env
->cpu_model
->CCRes
;
31188 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
31189 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
31190 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
31191 env
->current_tc
= 0;
31192 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
31193 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
31194 #if defined(TARGET_MIPS64)
31195 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
31196 env
->SEGMask
|= 3ULL << 62;
31199 env
->PABITS
= env
->cpu_model
->PABITS
;
31200 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
31201 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
31202 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
31203 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
31204 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
31205 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
31206 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
31207 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
31208 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
31209 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
31210 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
31211 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
31212 env
->CP0_EBaseWG_rw_bitmask
= env
->cpu_model
->CP0_EBaseWG_rw_bitmask
;
31213 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
31214 env
->active_fpu
.fcr31_rw_bitmask
= env
->cpu_model
->CP1_fcr31_rw_bitmask
;
31215 env
->active_fpu
.fcr31
= env
->cpu_model
->CP1_fcr31
;
31216 env
->msair
= env
->cpu_model
->MSAIR
;
31217 env
->insn_flags
= env
->cpu_model
->insn_flags
;
31219 #if defined(CONFIG_USER_ONLY)
31220 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
31221 # ifdef TARGET_MIPS64
31222 /* Enable 64-bit register mode. */
31223 env
->CP0_Status
|= (1 << CP0St_PX
);
31225 # ifdef TARGET_ABI_MIPSN64
31226 /* Enable 64-bit address mode. */
31227 env
->CP0_Status
|= (1 << CP0St_UX
);
31230 * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
31231 * hardware registers.
31233 env
->CP0_HWREna
|= 0x0000000F;
31234 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
31235 env
->CP0_Status
|= (1 << CP0St_CU1
);
31237 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
31238 env
->CP0_Status
|= (1 << CP0St_MX
);
31240 # if defined(TARGET_MIPS64)
31241 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
31242 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
31243 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
31244 env
->CP0_Status
|= (1 << CP0St_FR
);
31248 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
31250 * If the exception was raised from a delay slot,
31251 * come back to the jump.
31253 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
31254 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
31256 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
31258 env
->active_tc
.PC
= env
->exception_base
;
31259 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
31260 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
31261 env
->CP0_Wired
= 0;
31262 env
->CP0_GlobalNumber
= (cs
->cpu_index
& 0xFF) << CP0GN_VPId
;
31263 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
31264 if (mips_um_ksegs_enabled()) {
31265 env
->CP0_EBase
|= 0x40000000;
31267 env
->CP0_EBase
|= (int32_t)0x80000000;
31269 if (env
->CP0_Config3
& (1 << CP0C3_CMGCR
)) {
31270 env
->CP0_CMGCRBase
= 0x1fbf8000 >> 4;
31272 env
->CP0_EntryHi_ASID_mask
= (env
->CP0_Config5
& (1 << CP0C5_MI
)) ?
31273 0x0 : (env
->CP0_Config4
& (1 << CP0C4_AE
)) ? 0x3ff : 0xff;
31274 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
31276 * Vectored interrupts not implemented, timer on int 7,
31277 * no performance counters.
31279 env
->CP0_IntCtl
= 0xe0000000;
31283 for (i
= 0; i
< 7; i
++) {
31284 env
->CP0_WatchLo
[i
] = 0;
31285 env
->CP0_WatchHi
[i
] = 0x80000000;
31287 env
->CP0_WatchLo
[7] = 0;
31288 env
->CP0_WatchHi
[7] = 0;
31290 /* Count register increments in debug mode, EJTAG version 1 */
31291 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
31293 cpu_mips_store_count(env
, 1);
31295 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
31298 /* Only TC0 on VPE 0 starts as active. */
31299 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
31300 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
31301 env
->tcs
[i
].CP0_TCHalt
= 1;
31303 env
->active_tc
.CP0_TCHalt
= 1;
31306 if (cs
->cpu_index
== 0) {
31307 /* VPE0 starts up enabled. */
31308 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
31309 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
31311 /* TC0 starts up unhalted. */
31313 env
->active_tc
.CP0_TCHalt
= 0;
31314 env
->tcs
[0].CP0_TCHalt
= 0;
31315 /* With thread 0 active. */
31316 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
31317 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
31322 * Configure default legacy segmentation control. We use this regardless of
31323 * whether segmentation control is presented to the guest.
31325 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
31326 env
->CP0_SegCtl0
= (CP0SC_AM_MK
<< CP0SC_AM
);
31327 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
31328 env
->CP0_SegCtl0
|= ((CP0SC_AM_MSK
<< CP0SC_AM
)) << 16;
31329 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
31330 env
->CP0_SegCtl1
= (0 << CP0SC_PA
) | (CP0SC_AM_UK
<< CP0SC_AM
) |
31332 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
31333 env
->CP0_SegCtl1
|= ((0 << CP0SC_PA
) | (CP0SC_AM_UK
<< CP0SC_AM
) |
31334 (3 << CP0SC_C
)) << 16;
31335 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
31336 env
->CP0_SegCtl2
= (2 << CP0SC_PA
) | (CP0SC_AM_MUSK
<< CP0SC_AM
) |
31337 (1 << CP0SC_EU
) | (2 << CP0SC_C
);
31338 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
31339 env
->CP0_SegCtl2
|= ((0 << CP0SC_PA
) | (CP0SC_AM_MUSK
<< CP0SC_AM
) |
31340 (1 << CP0SC_EU
) | (2 << CP0SC_C
)) << 16;
31341 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
31342 env
->CP0_SegCtl1
|= (CP0SC_AM_UK
<< CP0SC1_XAM
);
31344 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
31345 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
31346 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
31347 env
->CP0_Status
|= (1 << CP0St_FR
);
31350 if (env
->insn_flags
& ISA_MIPS32R6
) {
31352 env
->CP0_PWSize
= 0x40;
31358 env
->CP0_PWField
= 0x0C30C302;
31365 env
->CP0_PWField
= 0x02;
31368 if (env
->CP0_Config3
& (1 << CP0C3_ISA
) & (1 << (CP0C3_ISA
+ 1))) {
31369 /* microMIPS on reset when Config3.ISA is 3 */
31370 env
->hflags
|= MIPS_HFLAG_M16
;
31374 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
31378 compute_hflags(env
);
31379 restore_fp_status(env
);
31380 restore_pamask(env
);
31381 cs
->exception_index
= EXCP_NONE
;
31383 if (semihosting_get_argc()) {
31384 /* UHI interface can be used to obtain argc and argv */
31385 env
->active_tc
.gpr
[4] = -1;
31389 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
31390 target_ulong
*data
)
31392 env
->active_tc
.PC
= data
[0];
31393 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
31394 env
->hflags
|= data
[1];
31395 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
31396 case MIPS_HFLAG_BR
:
31398 case MIPS_HFLAG_BC
:
31399 case MIPS_HFLAG_BL
:
31401 env
->btarget
= data
[2];