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
;
5534 opc
= MASK_LMI(ctx
->opcode
);
5540 t0
= tcg_temp_local_new_i64();
5541 t1
= tcg_temp_local_new_i64();
5544 t0
= tcg_temp_new_i64();
5545 t1
= tcg_temp_new_i64();
5549 check_cp1_enabled(ctx
);
5550 gen_load_fpr64(ctx
, t0
, rs
);
5551 gen_load_fpr64(ctx
, t1
, rt
);
5555 gen_helper_paddsh(t0
, t0
, t1
);
5558 gen_helper_paddush(t0
, t0
, t1
);
5561 gen_helper_paddh(t0
, t0
, t1
);
5564 gen_helper_paddw(t0
, t0
, t1
);
5567 gen_helper_paddsb(t0
, t0
, t1
);
5570 gen_helper_paddusb(t0
, t0
, t1
);
5573 gen_helper_paddb(t0
, t0
, t1
);
5577 gen_helper_psubsh(t0
, t0
, t1
);
5580 gen_helper_psubush(t0
, t0
, t1
);
5583 gen_helper_psubh(t0
, t0
, t1
);
5586 gen_helper_psubw(t0
, t0
, t1
);
5589 gen_helper_psubsb(t0
, t0
, t1
);
5592 gen_helper_psubusb(t0
, t0
, t1
);
5595 gen_helper_psubb(t0
, t0
, t1
);
5599 gen_helper_pshufh(t0
, t0
, t1
);
5602 gen_helper_packsswh(t0
, t0
, t1
);
5605 gen_helper_packsshb(t0
, t0
, t1
);
5608 gen_helper_packushb(t0
, t0
, t1
);
5612 gen_helper_punpcklhw(t0
, t0
, t1
);
5615 gen_helper_punpckhhw(t0
, t0
, t1
);
5618 gen_helper_punpcklbh(t0
, t0
, t1
);
5621 gen_helper_punpckhbh(t0
, t0
, t1
);
5624 gen_helper_punpcklwd(t0
, t0
, t1
);
5627 gen_helper_punpckhwd(t0
, t0
, t1
);
5631 gen_helper_pavgh(t0
, t0
, t1
);
5634 gen_helper_pavgb(t0
, t0
, t1
);
5637 gen_helper_pmaxsh(t0
, t0
, t1
);
5640 gen_helper_pminsh(t0
, t0
, t1
);
5643 gen_helper_pmaxub(t0
, t0
, t1
);
5646 gen_helper_pminub(t0
, t0
, t1
);
5650 gen_helper_pcmpeqw(t0
, t0
, t1
);
5653 gen_helper_pcmpgtw(t0
, t0
, t1
);
5656 gen_helper_pcmpeqh(t0
, t0
, t1
);
5659 gen_helper_pcmpgth(t0
, t0
, t1
);
5662 gen_helper_pcmpeqb(t0
, t0
, t1
);
5665 gen_helper_pcmpgtb(t0
, t0
, t1
);
5669 gen_helper_psllw(t0
, t0
, t1
);
5672 gen_helper_psllh(t0
, t0
, t1
);
5675 gen_helper_psrlw(t0
, t0
, t1
);
5678 gen_helper_psrlh(t0
, t0
, t1
);
5681 gen_helper_psraw(t0
, t0
, t1
);
5684 gen_helper_psrah(t0
, t0
, t1
);
5688 gen_helper_pmullh(t0
, t0
, t1
);
5691 gen_helper_pmulhh(t0
, t0
, t1
);
5694 gen_helper_pmulhuh(t0
, t0
, t1
);
5697 gen_helper_pmaddhw(t0
, t0
, t1
);
5701 gen_helper_pasubub(t0
, t0
, t1
);
5704 gen_helper_biadd(t0
, t0
);
5707 gen_helper_pmovmskb(t0
, t0
);
5711 tcg_gen_add_i64(t0
, t0
, t1
);
5714 tcg_gen_sub_i64(t0
, t0
, t1
);
5717 tcg_gen_xor_i64(t0
, t0
, t1
);
5720 tcg_gen_nor_i64(t0
, t0
, t1
);
5723 tcg_gen_and_i64(t0
, t0
, t1
);
5726 tcg_gen_or_i64(t0
, t0
, t1
);
5730 tcg_gen_andc_i64(t0
, t1
, t0
);
5734 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5737 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5740 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5743 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5747 tcg_gen_andi_i64(t1
, t1
, 3);
5748 tcg_gen_shli_i64(t1
, t1
, 4);
5749 tcg_gen_shr_i64(t0
, t0
, t1
);
5750 tcg_gen_ext16u_i64(t0
, t0
);
5754 tcg_gen_add_i64(t0
, t0
, t1
);
5755 tcg_gen_ext32s_i64(t0
, t0
);
5758 tcg_gen_sub_i64(t0
, t0
, t1
);
5759 tcg_gen_ext32s_i64(t0
, t0
);
5781 /* Make sure shift count isn't TCG undefined behaviour. */
5782 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5787 tcg_gen_shl_i64(t0
, t0
, t1
);
5792 * Since SRA is UndefinedResult without sign-extended inputs,
5793 * we can treat SRA and DSRA the same.
5795 tcg_gen_sar_i64(t0
, t0
, t1
);
5798 /* We want to shift in zeros for SRL; zero-extend first. */
5799 tcg_gen_ext32u_i64(t0
, t0
);
5802 tcg_gen_shr_i64(t0
, t0
, t1
);
5806 if (shift_max
== 32) {
5807 tcg_gen_ext32s_i64(t0
, t0
);
5810 /* Shifts larger than MAX produce zero. */
5811 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5812 tcg_gen_neg_i64(t1
, t1
);
5813 tcg_gen_and_i64(t0
, t0
, t1
);
5819 TCGv_i64 t2
= tcg_temp_new_i64();
5820 TCGLabel
*lab
= gen_new_label();
5822 tcg_gen_mov_i64(t2
, t0
);
5823 tcg_gen_add_i64(t0
, t1
, t2
);
5824 if (opc
== OPC_ADD_CP2
) {
5825 tcg_gen_ext32s_i64(t0
, t0
);
5827 tcg_gen_xor_i64(t1
, t1
, t2
);
5828 tcg_gen_xor_i64(t2
, t2
, t0
);
5829 tcg_gen_andc_i64(t1
, t2
, t1
);
5830 tcg_temp_free_i64(t2
);
5831 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5832 generate_exception(ctx
, EXCP_OVERFLOW
);
5840 TCGv_i64 t2
= tcg_temp_new_i64();
5841 TCGLabel
*lab
= gen_new_label();
5843 tcg_gen_mov_i64(t2
, t0
);
5844 tcg_gen_sub_i64(t0
, t1
, t2
);
5845 if (opc
== OPC_SUB_CP2
) {
5846 tcg_gen_ext32s_i64(t0
, t0
);
5848 tcg_gen_xor_i64(t1
, t1
, t2
);
5849 tcg_gen_xor_i64(t2
, t2
, t0
);
5850 tcg_gen_and_i64(t1
, t1
, t2
);
5851 tcg_temp_free_i64(t2
);
5852 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5853 generate_exception(ctx
, EXCP_OVERFLOW
);
5859 tcg_gen_ext32u_i64(t0
, t0
);
5860 tcg_gen_ext32u_i64(t1
, t1
);
5861 tcg_gen_mul_i64(t0
, t0
, t1
);
5870 cond
= TCG_COND_LTU
;
5878 cond
= TCG_COND_LEU
;
5885 int cc
= (ctx
->opcode
>> 8) & 0x7;
5886 TCGv_i64 t64
= tcg_temp_new_i64();
5887 TCGv_i32 t32
= tcg_temp_new_i32();
5889 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
5890 tcg_gen_extrl_i64_i32(t32
, t64
);
5891 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
5894 tcg_temp_free_i32(t32
);
5895 tcg_temp_free_i64(t64
);
5900 MIPS_INVAL("loongson_cp2");
5901 generate_exception_end(ctx
, EXCP_RI
);
5905 gen_store_fpr64(ctx
, t0
, rd
);
5908 tcg_temp_free_i64(t0
);
5909 tcg_temp_free_i64(t1
);
5913 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
5914 int rs
, int rt
, int16_t imm
)
5917 TCGv t0
= tcg_temp_new();
5918 TCGv t1
= tcg_temp_new();
5921 /* Load needed operands */
5929 /* Compare two registers */
5931 gen_load_gpr(t0
, rs
);
5932 gen_load_gpr(t1
, rt
);
5942 /* Compare register to immediate */
5943 if (rs
!= 0 || imm
!= 0) {
5944 gen_load_gpr(t0
, rs
);
5945 tcg_gen_movi_tl(t1
, (int32_t)imm
);
5952 case OPC_TEQ
: /* rs == rs */
5953 case OPC_TEQI
: /* r0 == 0 */
5954 case OPC_TGE
: /* rs >= rs */
5955 case OPC_TGEI
: /* r0 >= 0 */
5956 case OPC_TGEU
: /* rs >= rs unsigned */
5957 case OPC_TGEIU
: /* r0 >= 0 unsigned */
5959 generate_exception_end(ctx
, EXCP_TRAP
);
5961 case OPC_TLT
: /* rs < rs */
5962 case OPC_TLTI
: /* r0 < 0 */
5963 case OPC_TLTU
: /* rs < rs unsigned */
5964 case OPC_TLTIU
: /* r0 < 0 unsigned */
5965 case OPC_TNE
: /* rs != rs */
5966 case OPC_TNEI
: /* r0 != 0 */
5967 /* Never trap: treat as NOP. */
5971 TCGLabel
*l1
= gen_new_label();
5976 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
5980 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
5984 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
5988 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
5992 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
5996 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
5999 generate_exception(ctx
, EXCP_TRAP
);
6006 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
6008 if (unlikely(ctx
->base
.singlestep_enabled
)) {
6012 #ifndef CONFIG_USER_ONLY
6013 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
6019 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
6021 if (use_goto_tb(ctx
, dest
)) {
6024 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
6027 if (ctx
->base
.singlestep_enabled
) {
6028 save_cpu_state(ctx
, 0);
6029 gen_helper_raise_exception_debug(cpu_env
);
6031 tcg_gen_lookup_and_goto_ptr();
6035 /* Branches (before delay slot) */
6036 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
6038 int rs
, int rt
, int32_t offset
,
6041 target_ulong btgt
= -1;
6043 int bcond_compute
= 0;
6044 TCGv t0
= tcg_temp_new();
6045 TCGv t1
= tcg_temp_new();
6047 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
6048 #ifdef MIPS_DEBUG_DISAS
6049 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6050 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
6052 generate_exception_end(ctx
, EXCP_RI
);
6056 /* Load needed operands */
6062 /* Compare two registers */
6064 gen_load_gpr(t0
, rs
);
6065 gen_load_gpr(t1
, rt
);
6068 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6082 /* Compare to zero */
6084 gen_load_gpr(t0
, rs
);
6087 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6090 #if defined(TARGET_MIPS64)
6092 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
6094 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6097 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6102 /* Jump to immediate */
6103 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
6108 /* Jump to register */
6109 if (offset
!= 0 && offset
!= 16) {
6111 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6112 * others are reserved.
6114 MIPS_INVAL("jump hint");
6115 generate_exception_end(ctx
, EXCP_RI
);
6118 gen_load_gpr(btarget
, rs
);
6121 MIPS_INVAL("branch/jump");
6122 generate_exception_end(ctx
, EXCP_RI
);
6125 if (bcond_compute
== 0) {
6126 /* No condition to be computed */
6128 case OPC_BEQ
: /* rx == rx */
6129 case OPC_BEQL
: /* rx == rx likely */
6130 case OPC_BGEZ
: /* 0 >= 0 */
6131 case OPC_BGEZL
: /* 0 >= 0 likely */
6132 case OPC_BLEZ
: /* 0 <= 0 */
6133 case OPC_BLEZL
: /* 0 <= 0 likely */
6135 ctx
->hflags
|= MIPS_HFLAG_B
;
6137 case OPC_BGEZAL
: /* 0 >= 0 */
6138 case OPC_BGEZALL
: /* 0 >= 0 likely */
6139 /* Always take and link */
6141 ctx
->hflags
|= MIPS_HFLAG_B
;
6143 case OPC_BNE
: /* rx != rx */
6144 case OPC_BGTZ
: /* 0 > 0 */
6145 case OPC_BLTZ
: /* 0 < 0 */
6148 case OPC_BLTZAL
: /* 0 < 0 */
6150 * Handle as an unconditional branch to get correct delay
6154 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6155 ctx
->hflags
|= MIPS_HFLAG_B
;
6157 case OPC_BLTZALL
: /* 0 < 0 likely */
6158 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6159 /* Skip the instruction in the delay slot */
6160 ctx
->base
.pc_next
+= 4;
6162 case OPC_BNEL
: /* rx != rx likely */
6163 case OPC_BGTZL
: /* 0 > 0 likely */
6164 case OPC_BLTZL
: /* 0 < 0 likely */
6165 /* Skip the instruction in the delay slot */
6166 ctx
->base
.pc_next
+= 4;
6169 ctx
->hflags
|= MIPS_HFLAG_B
;
6172 ctx
->hflags
|= MIPS_HFLAG_BX
;
6176 ctx
->hflags
|= MIPS_HFLAG_B
;
6179 ctx
->hflags
|= MIPS_HFLAG_BR
;
6183 ctx
->hflags
|= MIPS_HFLAG_BR
;
6186 MIPS_INVAL("branch/jump");
6187 generate_exception_end(ctx
, EXCP_RI
);
6193 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6196 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6199 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6202 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6205 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6208 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6211 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6215 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6219 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6222 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6225 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6228 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6231 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6234 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6237 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6239 #if defined(TARGET_MIPS64)
6241 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6245 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6248 ctx
->hflags
|= MIPS_HFLAG_BC
;
6251 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6254 ctx
->hflags
|= MIPS_HFLAG_BL
;
6257 MIPS_INVAL("conditional branch/jump");
6258 generate_exception_end(ctx
, EXCP_RI
);
6263 ctx
->btarget
= btgt
;
6265 switch (delayslot_size
) {
6267 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6270 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6275 int post_delay
= insn_bytes
+ delayslot_size
;
6276 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6278 tcg_gen_movi_tl(cpu_gpr
[blink
],
6279 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6283 if (insn_bytes
== 2) {
6284 ctx
->hflags
|= MIPS_HFLAG_B16
;
6291 /* nanoMIPS Branches */
6292 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6294 int rs
, int rt
, int32_t offset
)
6296 target_ulong btgt
= -1;
6297 int bcond_compute
= 0;
6298 TCGv t0
= tcg_temp_new();
6299 TCGv t1
= tcg_temp_new();
6301 /* Load needed operands */
6305 /* Compare two registers */
6307 gen_load_gpr(t0
, rs
);
6308 gen_load_gpr(t1
, rt
);
6311 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6314 /* Compare to zero */
6316 gen_load_gpr(t0
, rs
);
6319 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6322 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6324 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6328 /* Jump to register */
6329 if (offset
!= 0 && offset
!= 16) {
6331 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6332 * others are reserved.
6334 MIPS_INVAL("jump hint");
6335 generate_exception_end(ctx
, EXCP_RI
);
6338 gen_load_gpr(btarget
, rs
);
6341 MIPS_INVAL("branch/jump");
6342 generate_exception_end(ctx
, EXCP_RI
);
6345 if (bcond_compute
== 0) {
6346 /* No condition to be computed */
6348 case OPC_BEQ
: /* rx == rx */
6350 ctx
->hflags
|= MIPS_HFLAG_B
;
6352 case OPC_BGEZAL
: /* 0 >= 0 */
6353 /* Always take and link */
6354 tcg_gen_movi_tl(cpu_gpr
[31],
6355 ctx
->base
.pc_next
+ insn_bytes
);
6356 ctx
->hflags
|= MIPS_HFLAG_B
;
6358 case OPC_BNE
: /* rx != rx */
6359 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6360 /* Skip the instruction in the delay slot */
6361 ctx
->base
.pc_next
+= 4;
6364 ctx
->hflags
|= MIPS_HFLAG_BR
;
6368 tcg_gen_movi_tl(cpu_gpr
[rt
],
6369 ctx
->base
.pc_next
+ insn_bytes
);
6371 ctx
->hflags
|= MIPS_HFLAG_BR
;
6374 MIPS_INVAL("branch/jump");
6375 generate_exception_end(ctx
, EXCP_RI
);
6381 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6384 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6387 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6388 tcg_gen_movi_tl(cpu_gpr
[31],
6389 ctx
->base
.pc_next
+ insn_bytes
);
6392 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6394 ctx
->hflags
|= MIPS_HFLAG_BC
;
6397 MIPS_INVAL("conditional branch/jump");
6398 generate_exception_end(ctx
, EXCP_RI
);
6403 ctx
->btarget
= btgt
;
6406 if (insn_bytes
== 2) {
6407 ctx
->hflags
|= MIPS_HFLAG_B16
;
6414 /* special3 bitfield operations */
6415 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6416 int rs
, int lsb
, int msb
)
6418 TCGv t0
= tcg_temp_new();
6419 TCGv t1
= tcg_temp_new();
6421 gen_load_gpr(t1
, rs
);
6424 if (lsb
+ msb
> 31) {
6428 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6431 * The two checks together imply that lsb == 0,
6432 * so this is a simple sign-extension.
6434 tcg_gen_ext32s_tl(t0
, t1
);
6437 #if defined(TARGET_MIPS64)
6446 if (lsb
+ msb
> 63) {
6449 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6456 gen_load_gpr(t0
, rt
);
6457 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6458 tcg_gen_ext32s_tl(t0
, t0
);
6460 #if defined(TARGET_MIPS64)
6471 gen_load_gpr(t0
, rt
);
6472 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6477 MIPS_INVAL("bitops");
6478 generate_exception_end(ctx
, EXCP_RI
);
6483 gen_store_gpr(t0
, rt
);
6488 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6493 /* If no destination, treat it as a NOP. */
6497 t0
= tcg_temp_new();
6498 gen_load_gpr(t0
, rt
);
6502 TCGv t1
= tcg_temp_new();
6503 TCGv t2
= tcg_const_tl(0x00FF00FF);
6505 tcg_gen_shri_tl(t1
, t0
, 8);
6506 tcg_gen_and_tl(t1
, t1
, t2
);
6507 tcg_gen_and_tl(t0
, t0
, t2
);
6508 tcg_gen_shli_tl(t0
, t0
, 8);
6509 tcg_gen_or_tl(t0
, t0
, t1
);
6512 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6516 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6519 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6521 #if defined(TARGET_MIPS64)
6524 TCGv t1
= tcg_temp_new();
6525 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6527 tcg_gen_shri_tl(t1
, t0
, 8);
6528 tcg_gen_and_tl(t1
, t1
, t2
);
6529 tcg_gen_and_tl(t0
, t0
, t2
);
6530 tcg_gen_shli_tl(t0
, t0
, 8);
6531 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6538 TCGv t1
= tcg_temp_new();
6539 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6541 tcg_gen_shri_tl(t1
, t0
, 16);
6542 tcg_gen_and_tl(t1
, t1
, t2
);
6543 tcg_gen_and_tl(t0
, t0
, t2
);
6544 tcg_gen_shli_tl(t0
, t0
, 16);
6545 tcg_gen_or_tl(t0
, t0
, t1
);
6546 tcg_gen_shri_tl(t1
, t0
, 32);
6547 tcg_gen_shli_tl(t0
, t0
, 32);
6548 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6555 MIPS_INVAL("bsfhl");
6556 generate_exception_end(ctx
, EXCP_RI
);
6563 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
6572 t0
= tcg_temp_new();
6573 t1
= tcg_temp_new();
6574 gen_load_gpr(t0
, rs
);
6575 gen_load_gpr(t1
, rt
);
6576 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
6577 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
6578 if (opc
== OPC_LSA
) {
6579 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
6588 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
6596 t0
= tcg_temp_new();
6597 if (bits
== 0 || bits
== wordsz
) {
6599 gen_load_gpr(t0
, rt
);
6601 gen_load_gpr(t0
, rs
);
6605 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6607 #if defined(TARGET_MIPS64)
6609 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
6614 TCGv t1
= tcg_temp_new();
6615 gen_load_gpr(t0
, rt
);
6616 gen_load_gpr(t1
, rs
);
6620 TCGv_i64 t2
= tcg_temp_new_i64();
6621 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
6622 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
6623 gen_move_low32(cpu_gpr
[rd
], t2
);
6624 tcg_temp_free_i64(t2
);
6627 #if defined(TARGET_MIPS64)
6629 tcg_gen_shli_tl(t0
, t0
, bits
);
6630 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
6631 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
6641 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6644 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
6647 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6650 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
6653 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
6660 t0
= tcg_temp_new();
6661 gen_load_gpr(t0
, rt
);
6664 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
6666 #if defined(TARGET_MIPS64)
6668 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
6675 #ifndef CONFIG_USER_ONLY
6676 /* CP0 (MMU and control) */
6677 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
6679 TCGv_i64 t0
= tcg_temp_new_i64();
6680 TCGv_i64 t1
= tcg_temp_new_i64();
6682 tcg_gen_ext_tl_i64(t0
, arg
);
6683 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6684 #if defined(TARGET_MIPS64)
6685 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
6687 tcg_gen_concat32_i64(t1
, t1
, t0
);
6689 tcg_gen_st_i64(t1
, cpu_env
, off
);
6690 tcg_temp_free_i64(t1
);
6691 tcg_temp_free_i64(t0
);
6694 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
6696 TCGv_i64 t0
= tcg_temp_new_i64();
6697 TCGv_i64 t1
= tcg_temp_new_i64();
6699 tcg_gen_ext_tl_i64(t0
, arg
);
6700 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6701 tcg_gen_concat32_i64(t1
, t1
, t0
);
6702 tcg_gen_st_i64(t1
, cpu_env
, off
);
6703 tcg_temp_free_i64(t1
);
6704 tcg_temp_free_i64(t0
);
6707 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
6709 TCGv_i64 t0
= tcg_temp_new_i64();
6711 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6712 #if defined(TARGET_MIPS64)
6713 tcg_gen_shri_i64(t0
, t0
, 30);
6715 tcg_gen_shri_i64(t0
, t0
, 32);
6717 gen_move_low32(arg
, t0
);
6718 tcg_temp_free_i64(t0
);
6721 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
6723 TCGv_i64 t0
= tcg_temp_new_i64();
6725 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6726 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
6727 gen_move_low32(arg
, t0
);
6728 tcg_temp_free_i64(t0
);
6731 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
6733 TCGv_i32 t0
= tcg_temp_new_i32();
6735 tcg_gen_ld_i32(t0
, cpu_env
, off
);
6736 tcg_gen_ext_i32_tl(arg
, t0
);
6737 tcg_temp_free_i32(t0
);
6740 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
6742 tcg_gen_ld_tl(arg
, cpu_env
, off
);
6743 tcg_gen_ext32s_tl(arg
, arg
);
6746 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
6748 TCGv_i32 t0
= tcg_temp_new_i32();
6750 tcg_gen_trunc_tl_i32(t0
, arg
);
6751 tcg_gen_st_i32(t0
, cpu_env
, off
);
6752 tcg_temp_free_i32(t0
);
6755 #define CP0_CHECK(c) \
6758 goto cp0_unimplemented; \
6762 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6764 const char *register_name
= "invalid";
6767 case CP0_REGISTER_02
:
6770 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6771 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6772 register_name
= "EntryLo0";
6775 goto cp0_unimplemented
;
6778 case CP0_REGISTER_03
:
6780 case CP0_REG03__ENTRYLO1
:
6781 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6782 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6783 register_name
= "EntryLo1";
6786 goto cp0_unimplemented
;
6789 case CP0_REGISTER_09
:
6791 case CP0_REG09__SAAR
:
6792 CP0_CHECK(ctx
->saar
);
6793 gen_helper_mfhc0_saar(arg
, cpu_env
);
6794 register_name
= "SAAR";
6797 goto cp0_unimplemented
;
6800 case CP0_REGISTER_17
:
6802 case CP0_REG17__LLADDR
:
6803 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
6804 ctx
->CP0_LLAddr_shift
);
6805 register_name
= "LLAddr";
6807 case CP0_REG17__MAAR
:
6808 CP0_CHECK(ctx
->mrp
);
6809 gen_helper_mfhc0_maar(arg
, cpu_env
);
6810 register_name
= "MAAR";
6813 goto cp0_unimplemented
;
6816 case CP0_REGISTER_19
:
6818 case CP0_REG19__WATCHHI0
:
6819 case CP0_REG19__WATCHHI1
:
6820 case CP0_REG19__WATCHHI2
:
6821 case CP0_REG19__WATCHHI3
:
6822 case CP0_REG19__WATCHHI4
:
6823 case CP0_REG19__WATCHHI5
:
6824 case CP0_REG19__WATCHHI6
:
6825 case CP0_REG19__WATCHHI7
:
6826 /* upper 32 bits are only available when Config5MI != 0 */
6828 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
6829 register_name
= "WatchHi";
6832 goto cp0_unimplemented
;
6835 case CP0_REGISTER_28
:
6841 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
6842 register_name
= "TagLo";
6845 goto cp0_unimplemented
;
6849 goto cp0_unimplemented
;
6851 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
6855 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
6856 register_name
, reg
, sel
);
6857 tcg_gen_movi_tl(arg
, 0);
6860 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6862 const char *register_name
= "invalid";
6863 uint64_t mask
= ctx
->PAMask
>> 36;
6866 case CP0_REGISTER_02
:
6869 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6870 tcg_gen_andi_tl(arg
, arg
, mask
);
6871 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6872 register_name
= "EntryLo0";
6875 goto cp0_unimplemented
;
6878 case CP0_REGISTER_03
:
6880 case CP0_REG03__ENTRYLO1
:
6881 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6882 tcg_gen_andi_tl(arg
, arg
, mask
);
6883 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6884 register_name
= "EntryLo1";
6887 goto cp0_unimplemented
;
6890 case CP0_REGISTER_09
:
6892 case CP0_REG09__SAAR
:
6893 CP0_CHECK(ctx
->saar
);
6894 gen_helper_mthc0_saar(cpu_env
, arg
);
6895 register_name
= "SAAR";
6898 goto cp0_unimplemented
;
6901 case CP0_REGISTER_17
:
6903 case CP0_REG17__LLADDR
:
6905 * LLAddr is read-only (the only exception is bit 0 if LLB is
6906 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6907 * relevant for modern MIPS cores supporting MTHC0, therefore
6908 * treating MTHC0 to LLAddr as NOP.
6910 register_name
= "LLAddr";
6912 case CP0_REG17__MAAR
:
6913 CP0_CHECK(ctx
->mrp
);
6914 gen_helper_mthc0_maar(cpu_env
, arg
);
6915 register_name
= "MAAR";
6918 goto cp0_unimplemented
;
6921 case CP0_REGISTER_19
:
6923 case CP0_REG19__WATCHHI0
:
6924 case CP0_REG19__WATCHHI1
:
6925 case CP0_REG19__WATCHHI2
:
6926 case CP0_REG19__WATCHHI3
:
6927 case CP0_REG19__WATCHHI4
:
6928 case CP0_REG19__WATCHHI5
:
6929 case CP0_REG19__WATCHHI6
:
6930 case CP0_REG19__WATCHHI7
:
6931 /* upper 32 bits are only available when Config5MI != 0 */
6933 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
6934 register_name
= "WatchHi";
6937 goto cp0_unimplemented
;
6940 case CP0_REGISTER_28
:
6946 tcg_gen_andi_tl(arg
, arg
, mask
);
6947 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6948 register_name
= "TagLo";
6951 goto cp0_unimplemented
;
6955 goto cp0_unimplemented
;
6957 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
6960 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
6961 register_name
, reg
, sel
);
6964 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
6966 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
6967 tcg_gen_movi_tl(arg
, 0);
6969 tcg_gen_movi_tl(arg
, ~0);
6973 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6975 const char *register_name
= "invalid";
6978 check_insn(ctx
, ISA_MIPS32
);
6982 case CP0_REGISTER_00
:
6984 case CP0_REG00__INDEX
:
6985 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6986 register_name
= "Index";
6988 case CP0_REG00__MVPCONTROL
:
6989 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6990 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6991 register_name
= "MVPControl";
6993 case CP0_REG00__MVPCONF0
:
6994 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6995 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6996 register_name
= "MVPConf0";
6998 case CP0_REG00__MVPCONF1
:
6999 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7000 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7001 register_name
= "MVPConf1";
7003 case CP0_REG00__VPCONTROL
:
7005 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7006 register_name
= "VPControl";
7009 goto cp0_unimplemented
;
7012 case CP0_REGISTER_01
:
7014 case CP0_REG01__RANDOM
:
7015 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7016 gen_helper_mfc0_random(arg
, cpu_env
);
7017 register_name
= "Random";
7019 case CP0_REG01__VPECONTROL
:
7020 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7021 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7022 register_name
= "VPEControl";
7024 case CP0_REG01__VPECONF0
:
7025 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7026 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7027 register_name
= "VPEConf0";
7029 case CP0_REG01__VPECONF1
:
7030 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7031 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7032 register_name
= "VPEConf1";
7034 case CP0_REG01__YQMASK
:
7035 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7036 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
7037 register_name
= "YQMask";
7039 case CP0_REG01__VPESCHEDULE
:
7040 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7041 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7042 register_name
= "VPESchedule";
7044 case CP0_REG01__VPESCHEFBACK
:
7045 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7046 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7047 register_name
= "VPEScheFBack";
7049 case CP0_REG01__VPEOPT
:
7050 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7051 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7052 register_name
= "VPEOpt";
7055 goto cp0_unimplemented
;
7058 case CP0_REGISTER_02
:
7060 case CP0_REG02__ENTRYLO0
:
7062 TCGv_i64 tmp
= tcg_temp_new_i64();
7063 tcg_gen_ld_i64(tmp
, cpu_env
,
7064 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7065 #if defined(TARGET_MIPS64)
7067 /* Move RI/XI fields to bits 31:30 */
7068 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7069 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7072 gen_move_low32(arg
, tmp
);
7073 tcg_temp_free_i64(tmp
);
7075 register_name
= "EntryLo0";
7077 case CP0_REG02__TCSTATUS
:
7078 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7079 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7080 register_name
= "TCStatus";
7082 case CP0_REG02__TCBIND
:
7083 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7084 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7085 register_name
= "TCBind";
7087 case CP0_REG02__TCRESTART
:
7088 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7089 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
7090 register_name
= "TCRestart";
7092 case CP0_REG02__TCHALT
:
7093 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7094 gen_helper_mfc0_tchalt(arg
, cpu_env
);
7095 register_name
= "TCHalt";
7097 case CP0_REG02__TCCONTEXT
:
7098 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7099 gen_helper_mfc0_tccontext(arg
, cpu_env
);
7100 register_name
= "TCContext";
7102 case CP0_REG02__TCSCHEDULE
:
7103 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7104 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
7105 register_name
= "TCSchedule";
7107 case CP0_REG02__TCSCHEFBACK
:
7108 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7109 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
7110 register_name
= "TCScheFBack";
7113 goto cp0_unimplemented
;
7116 case CP0_REGISTER_03
:
7118 case CP0_REG03__ENTRYLO1
:
7120 TCGv_i64 tmp
= tcg_temp_new_i64();
7121 tcg_gen_ld_i64(tmp
, cpu_env
,
7122 offsetof(CPUMIPSState
, CP0_EntryLo1
));
7123 #if defined(TARGET_MIPS64)
7125 /* Move RI/XI fields to bits 31:30 */
7126 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7127 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7130 gen_move_low32(arg
, tmp
);
7131 tcg_temp_free_i64(tmp
);
7133 register_name
= "EntryLo1";
7135 case CP0_REG03__GLOBALNUM
:
7137 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7138 register_name
= "GlobalNumber";
7141 goto cp0_unimplemented
;
7144 case CP0_REGISTER_04
:
7146 case CP0_REG04__CONTEXT
:
7147 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7148 tcg_gen_ext32s_tl(arg
, arg
);
7149 register_name
= "Context";
7151 case CP0_REG04__CONTEXTCONFIG
:
7153 /* gen_helper_mfc0_contextconfig(arg); */
7154 register_name
= "ContextConfig";
7155 goto cp0_unimplemented
;
7156 case CP0_REG04__USERLOCAL
:
7157 CP0_CHECK(ctx
->ulri
);
7158 tcg_gen_ld_tl(arg
, cpu_env
,
7159 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7160 tcg_gen_ext32s_tl(arg
, arg
);
7161 register_name
= "UserLocal";
7163 case CP0_REG04__MMID
:
7165 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7166 register_name
= "MMID";
7169 goto cp0_unimplemented
;
7172 case CP0_REGISTER_05
:
7174 case CP0_REG05__PAGEMASK
:
7175 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7176 register_name
= "PageMask";
7178 case CP0_REG05__PAGEGRAIN
:
7179 check_insn(ctx
, ISA_MIPS32R2
);
7180 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7181 register_name
= "PageGrain";
7183 case CP0_REG05__SEGCTL0
:
7185 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7186 tcg_gen_ext32s_tl(arg
, arg
);
7187 register_name
= "SegCtl0";
7189 case CP0_REG05__SEGCTL1
:
7191 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7192 tcg_gen_ext32s_tl(arg
, arg
);
7193 register_name
= "SegCtl1";
7195 case CP0_REG05__SEGCTL2
:
7197 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7198 tcg_gen_ext32s_tl(arg
, arg
);
7199 register_name
= "SegCtl2";
7201 case CP0_REG05__PWBASE
:
7203 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7204 register_name
= "PWBase";
7206 case CP0_REG05__PWFIELD
:
7208 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7209 register_name
= "PWField";
7211 case CP0_REG05__PWSIZE
:
7213 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7214 register_name
= "PWSize";
7217 goto cp0_unimplemented
;
7220 case CP0_REGISTER_06
:
7222 case CP0_REG06__WIRED
:
7223 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7224 register_name
= "Wired";
7226 case CP0_REG06__SRSCONF0
:
7227 check_insn(ctx
, ISA_MIPS32R2
);
7228 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7229 register_name
= "SRSConf0";
7231 case CP0_REG06__SRSCONF1
:
7232 check_insn(ctx
, ISA_MIPS32R2
);
7233 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7234 register_name
= "SRSConf1";
7236 case CP0_REG06__SRSCONF2
:
7237 check_insn(ctx
, ISA_MIPS32R2
);
7238 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7239 register_name
= "SRSConf2";
7241 case CP0_REG06__SRSCONF3
:
7242 check_insn(ctx
, ISA_MIPS32R2
);
7243 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7244 register_name
= "SRSConf3";
7246 case CP0_REG06__SRSCONF4
:
7247 check_insn(ctx
, ISA_MIPS32R2
);
7248 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7249 register_name
= "SRSConf4";
7251 case CP0_REG06__PWCTL
:
7253 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7254 register_name
= "PWCtl";
7257 goto cp0_unimplemented
;
7260 case CP0_REGISTER_07
:
7262 case CP0_REG07__HWRENA
:
7263 check_insn(ctx
, ISA_MIPS32R2
);
7264 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7265 register_name
= "HWREna";
7268 goto cp0_unimplemented
;
7271 case CP0_REGISTER_08
:
7273 case CP0_REG08__BADVADDR
:
7274 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7275 tcg_gen_ext32s_tl(arg
, arg
);
7276 register_name
= "BadVAddr";
7278 case CP0_REG08__BADINSTR
:
7280 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7281 register_name
= "BadInstr";
7283 case CP0_REG08__BADINSTRP
:
7285 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7286 register_name
= "BadInstrP";
7288 case CP0_REG08__BADINSTRX
:
7290 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7291 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7292 register_name
= "BadInstrX";
7295 goto cp0_unimplemented
;
7298 case CP0_REGISTER_09
:
7300 case CP0_REG09__COUNT
:
7301 /* Mark as an IO operation because we read the time. */
7302 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7305 gen_helper_mfc0_count(arg
, cpu_env
);
7307 * Break the TB to be able to take timer interrupts immediately
7308 * after reading count. DISAS_STOP isn't sufficient, we need to
7309 * ensure we break completely out of translated code.
7311 gen_save_pc(ctx
->base
.pc_next
+ 4);
7312 ctx
->base
.is_jmp
= DISAS_EXIT
;
7313 register_name
= "Count";
7315 case CP0_REG09__SAARI
:
7316 CP0_CHECK(ctx
->saar
);
7317 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7318 register_name
= "SAARI";
7320 case CP0_REG09__SAAR
:
7321 CP0_CHECK(ctx
->saar
);
7322 gen_helper_mfc0_saar(arg
, cpu_env
);
7323 register_name
= "SAAR";
7326 goto cp0_unimplemented
;
7329 case CP0_REGISTER_10
:
7331 case CP0_REG10__ENTRYHI
:
7332 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7333 tcg_gen_ext32s_tl(arg
, arg
);
7334 register_name
= "EntryHi";
7337 goto cp0_unimplemented
;
7340 case CP0_REGISTER_11
:
7342 case CP0_REG11__COMPARE
:
7343 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7344 register_name
= "Compare";
7346 /* 6,7 are implementation dependent */
7348 goto cp0_unimplemented
;
7351 case CP0_REGISTER_12
:
7353 case CP0_REG12__STATUS
:
7354 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7355 register_name
= "Status";
7357 case CP0_REG12__INTCTL
:
7358 check_insn(ctx
, ISA_MIPS32R2
);
7359 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7360 register_name
= "IntCtl";
7362 case CP0_REG12__SRSCTL
:
7363 check_insn(ctx
, ISA_MIPS32R2
);
7364 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7365 register_name
= "SRSCtl";
7367 case CP0_REG12__SRSMAP
:
7368 check_insn(ctx
, ISA_MIPS32R2
);
7369 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7370 register_name
= "SRSMap";
7373 goto cp0_unimplemented
;
7376 case CP0_REGISTER_13
:
7378 case CP0_REG13__CAUSE
:
7379 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7380 register_name
= "Cause";
7383 goto cp0_unimplemented
;
7386 case CP0_REGISTER_14
:
7388 case CP0_REG14__EPC
:
7389 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7390 tcg_gen_ext32s_tl(arg
, arg
);
7391 register_name
= "EPC";
7394 goto cp0_unimplemented
;
7397 case CP0_REGISTER_15
:
7399 case CP0_REG15__PRID
:
7400 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7401 register_name
= "PRid";
7403 case CP0_REG15__EBASE
:
7404 check_insn(ctx
, ISA_MIPS32R2
);
7405 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7406 tcg_gen_ext32s_tl(arg
, arg
);
7407 register_name
= "EBase";
7409 case CP0_REG15__CMGCRBASE
:
7410 check_insn(ctx
, ISA_MIPS32R2
);
7411 CP0_CHECK(ctx
->cmgcr
);
7412 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7413 tcg_gen_ext32s_tl(arg
, arg
);
7414 register_name
= "CMGCRBase";
7417 goto cp0_unimplemented
;
7420 case CP0_REGISTER_16
:
7422 case CP0_REG16__CONFIG
:
7423 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7424 register_name
= "Config";
7426 case CP0_REG16__CONFIG1
:
7427 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7428 register_name
= "Config1";
7430 case CP0_REG16__CONFIG2
:
7431 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7432 register_name
= "Config2";
7434 case CP0_REG16__CONFIG3
:
7435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7436 register_name
= "Config3";
7438 case CP0_REG16__CONFIG4
:
7439 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7440 register_name
= "Config4";
7442 case CP0_REG16__CONFIG5
:
7443 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7444 register_name
= "Config5";
7446 /* 6,7 are implementation dependent */
7447 case CP0_REG16__CONFIG6
:
7448 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7449 register_name
= "Config6";
7451 case CP0_REG16__CONFIG7
:
7452 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7453 register_name
= "Config7";
7456 goto cp0_unimplemented
;
7459 case CP0_REGISTER_17
:
7461 case CP0_REG17__LLADDR
:
7462 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7463 register_name
= "LLAddr";
7465 case CP0_REG17__MAAR
:
7466 CP0_CHECK(ctx
->mrp
);
7467 gen_helper_mfc0_maar(arg
, cpu_env
);
7468 register_name
= "MAAR";
7470 case CP0_REG17__MAARI
:
7471 CP0_CHECK(ctx
->mrp
);
7472 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7473 register_name
= "MAARI";
7476 goto cp0_unimplemented
;
7479 case CP0_REGISTER_18
:
7481 case CP0_REG18__WATCHLO0
:
7482 case CP0_REG18__WATCHLO1
:
7483 case CP0_REG18__WATCHLO2
:
7484 case CP0_REG18__WATCHLO3
:
7485 case CP0_REG18__WATCHLO4
:
7486 case CP0_REG18__WATCHLO5
:
7487 case CP0_REG18__WATCHLO6
:
7488 case CP0_REG18__WATCHLO7
:
7489 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7490 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7491 register_name
= "WatchLo";
7494 goto cp0_unimplemented
;
7497 case CP0_REGISTER_19
:
7499 case CP0_REG19__WATCHHI0
:
7500 case CP0_REG19__WATCHHI1
:
7501 case CP0_REG19__WATCHHI2
:
7502 case CP0_REG19__WATCHHI3
:
7503 case CP0_REG19__WATCHHI4
:
7504 case CP0_REG19__WATCHHI5
:
7505 case CP0_REG19__WATCHHI6
:
7506 case CP0_REG19__WATCHHI7
:
7507 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7508 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7509 register_name
= "WatchHi";
7512 goto cp0_unimplemented
;
7515 case CP0_REGISTER_20
:
7517 case CP0_REG20__XCONTEXT
:
7518 #if defined(TARGET_MIPS64)
7519 check_insn(ctx
, ISA_MIPS3
);
7520 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7521 tcg_gen_ext32s_tl(arg
, arg
);
7522 register_name
= "XContext";
7526 goto cp0_unimplemented
;
7529 case CP0_REGISTER_21
:
7530 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7531 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7534 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7535 register_name
= "Framemask";
7538 goto cp0_unimplemented
;
7541 case CP0_REGISTER_22
:
7542 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7543 register_name
= "'Diagnostic"; /* implementation dependent */
7545 case CP0_REGISTER_23
:
7547 case CP0_REG23__DEBUG
:
7548 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7549 register_name
= "Debug";
7551 case CP0_REG23__TRACECONTROL
:
7552 /* PDtrace support */
7553 /* gen_helper_mfc0_tracecontrol(arg); */
7554 register_name
= "TraceControl";
7555 goto cp0_unimplemented
;
7556 case CP0_REG23__TRACECONTROL2
:
7557 /* PDtrace support */
7558 /* gen_helper_mfc0_tracecontrol2(arg); */
7559 register_name
= "TraceControl2";
7560 goto cp0_unimplemented
;
7561 case CP0_REG23__USERTRACEDATA1
:
7562 /* PDtrace support */
7563 /* gen_helper_mfc0_usertracedata1(arg);*/
7564 register_name
= "UserTraceData1";
7565 goto cp0_unimplemented
;
7566 case CP0_REG23__TRACEIBPC
:
7567 /* PDtrace support */
7568 /* gen_helper_mfc0_traceibpc(arg); */
7569 register_name
= "TraceIBPC";
7570 goto cp0_unimplemented
;
7571 case CP0_REG23__TRACEDBPC
:
7572 /* PDtrace support */
7573 /* gen_helper_mfc0_tracedbpc(arg); */
7574 register_name
= "TraceDBPC";
7575 goto cp0_unimplemented
;
7577 goto cp0_unimplemented
;
7580 case CP0_REGISTER_24
:
7582 case CP0_REG24__DEPC
:
7584 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7585 tcg_gen_ext32s_tl(arg
, arg
);
7586 register_name
= "DEPC";
7589 goto cp0_unimplemented
;
7592 case CP0_REGISTER_25
:
7594 case CP0_REG25__PERFCTL0
:
7595 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
7596 register_name
= "Performance0";
7598 case CP0_REG25__PERFCNT0
:
7599 /* gen_helper_mfc0_performance1(arg); */
7600 register_name
= "Performance1";
7601 goto cp0_unimplemented
;
7602 case CP0_REG25__PERFCTL1
:
7603 /* gen_helper_mfc0_performance2(arg); */
7604 register_name
= "Performance2";
7605 goto cp0_unimplemented
;
7606 case CP0_REG25__PERFCNT1
:
7607 /* gen_helper_mfc0_performance3(arg); */
7608 register_name
= "Performance3";
7609 goto cp0_unimplemented
;
7610 case CP0_REG25__PERFCTL2
:
7611 /* gen_helper_mfc0_performance4(arg); */
7612 register_name
= "Performance4";
7613 goto cp0_unimplemented
;
7614 case CP0_REG25__PERFCNT2
:
7615 /* gen_helper_mfc0_performance5(arg); */
7616 register_name
= "Performance5";
7617 goto cp0_unimplemented
;
7618 case CP0_REG25__PERFCTL3
:
7619 /* gen_helper_mfc0_performance6(arg); */
7620 register_name
= "Performance6";
7621 goto cp0_unimplemented
;
7622 case CP0_REG25__PERFCNT3
:
7623 /* gen_helper_mfc0_performance7(arg); */
7624 register_name
= "Performance7";
7625 goto cp0_unimplemented
;
7627 goto cp0_unimplemented
;
7630 case CP0_REGISTER_26
:
7632 case CP0_REG26__ERRCTL
:
7633 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
7634 register_name
= "ErrCtl";
7637 goto cp0_unimplemented
;
7640 case CP0_REGISTER_27
:
7642 case CP0_REG27__CACHERR
:
7643 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7644 register_name
= "CacheErr";
7647 goto cp0_unimplemented
;
7650 case CP0_REGISTER_28
:
7652 case CP0_REG28__TAGLO
:
7653 case CP0_REG28__TAGLO1
:
7654 case CP0_REG28__TAGLO2
:
7655 case CP0_REG28__TAGLO3
:
7657 TCGv_i64 tmp
= tcg_temp_new_i64();
7658 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
7659 gen_move_low32(arg
, tmp
);
7660 tcg_temp_free_i64(tmp
);
7662 register_name
= "TagLo";
7664 case CP0_REG28__DATALO
:
7665 case CP0_REG28__DATALO1
:
7666 case CP0_REG28__DATALO2
:
7667 case CP0_REG28__DATALO3
:
7668 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7669 register_name
= "DataLo";
7672 goto cp0_unimplemented
;
7675 case CP0_REGISTER_29
:
7677 case CP0_REG29__TAGHI
:
7678 case CP0_REG29__TAGHI1
:
7679 case CP0_REG29__TAGHI2
:
7680 case CP0_REG29__TAGHI3
:
7681 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7682 register_name
= "TagHi";
7684 case CP0_REG29__DATAHI
:
7685 case CP0_REG29__DATAHI1
:
7686 case CP0_REG29__DATAHI2
:
7687 case CP0_REG29__DATAHI3
:
7688 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7689 register_name
= "DataHi";
7692 goto cp0_unimplemented
;
7695 case CP0_REGISTER_30
:
7697 case CP0_REG30__ERROREPC
:
7698 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7699 tcg_gen_ext32s_tl(arg
, arg
);
7700 register_name
= "ErrorEPC";
7703 goto cp0_unimplemented
;
7706 case CP0_REGISTER_31
:
7708 case CP0_REG31__DESAVE
:
7710 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7711 register_name
= "DESAVE";
7713 case CP0_REG31__KSCRATCH1
:
7714 case CP0_REG31__KSCRATCH2
:
7715 case CP0_REG31__KSCRATCH3
:
7716 case CP0_REG31__KSCRATCH4
:
7717 case CP0_REG31__KSCRATCH5
:
7718 case CP0_REG31__KSCRATCH6
:
7719 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7720 tcg_gen_ld_tl(arg
, cpu_env
,
7721 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7722 tcg_gen_ext32s_tl(arg
, arg
);
7723 register_name
= "KScratch";
7726 goto cp0_unimplemented
;
7730 goto cp0_unimplemented
;
7732 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
7736 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
7737 register_name
, reg
, sel
);
7738 gen_mfc0_unimplemented(ctx
, arg
);
7741 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7743 const char *register_name
= "invalid";
7746 check_insn(ctx
, ISA_MIPS32
);
7749 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7754 case CP0_REGISTER_00
:
7756 case CP0_REG00__INDEX
:
7757 gen_helper_mtc0_index(cpu_env
, arg
);
7758 register_name
= "Index";
7760 case CP0_REG00__MVPCONTROL
:
7761 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7762 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7763 register_name
= "MVPControl";
7765 case CP0_REG00__MVPCONF0
:
7766 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7768 register_name
= "MVPConf0";
7770 case CP0_REG00__MVPCONF1
:
7771 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7773 register_name
= "MVPConf1";
7775 case CP0_REG00__VPCONTROL
:
7778 register_name
= "VPControl";
7781 goto cp0_unimplemented
;
7784 case CP0_REGISTER_01
:
7786 case CP0_REG01__RANDOM
:
7788 register_name
= "Random";
7790 case CP0_REG01__VPECONTROL
:
7791 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7792 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7793 register_name
= "VPEControl";
7795 case CP0_REG01__VPECONF0
:
7796 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7797 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7798 register_name
= "VPEConf0";
7800 case CP0_REG01__VPECONF1
:
7801 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7802 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7803 register_name
= "VPEConf1";
7805 case CP0_REG01__YQMASK
:
7806 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7807 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7808 register_name
= "YQMask";
7810 case CP0_REG01__VPESCHEDULE
:
7811 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7812 tcg_gen_st_tl(arg
, cpu_env
,
7813 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7814 register_name
= "VPESchedule";
7816 case CP0_REG01__VPESCHEFBACK
:
7817 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7818 tcg_gen_st_tl(arg
, cpu_env
,
7819 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7820 register_name
= "VPEScheFBack";
7822 case CP0_REG01__VPEOPT
:
7823 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7824 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7825 register_name
= "VPEOpt";
7828 goto cp0_unimplemented
;
7831 case CP0_REGISTER_02
:
7833 case CP0_REG02__ENTRYLO0
:
7834 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
7835 register_name
= "EntryLo0";
7837 case CP0_REG02__TCSTATUS
:
7838 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7839 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7840 register_name
= "TCStatus";
7842 case CP0_REG02__TCBIND
:
7843 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7844 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7845 register_name
= "TCBind";
7847 case CP0_REG02__TCRESTART
:
7848 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7849 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7850 register_name
= "TCRestart";
7852 case CP0_REG02__TCHALT
:
7853 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7854 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7855 register_name
= "TCHalt";
7857 case CP0_REG02__TCCONTEXT
:
7858 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7859 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7860 register_name
= "TCContext";
7862 case CP0_REG02__TCSCHEDULE
:
7863 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7864 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7865 register_name
= "TCSchedule";
7867 case CP0_REG02__TCSCHEFBACK
:
7868 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7869 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7870 register_name
= "TCScheFBack";
7873 goto cp0_unimplemented
;
7876 case CP0_REGISTER_03
:
7878 case CP0_REG03__ENTRYLO1
:
7879 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
7880 register_name
= "EntryLo1";
7882 case CP0_REG03__GLOBALNUM
:
7885 register_name
= "GlobalNumber";
7888 goto cp0_unimplemented
;
7891 case CP0_REGISTER_04
:
7893 case CP0_REG04__CONTEXT
:
7894 gen_helper_mtc0_context(cpu_env
, arg
);
7895 register_name
= "Context";
7897 case CP0_REG04__CONTEXTCONFIG
:
7899 /* gen_helper_mtc0_contextconfig(arg); */
7900 register_name
= "ContextConfig";
7901 goto cp0_unimplemented
;
7902 case CP0_REG04__USERLOCAL
:
7903 CP0_CHECK(ctx
->ulri
);
7904 tcg_gen_st_tl(arg
, cpu_env
,
7905 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7906 register_name
= "UserLocal";
7908 case CP0_REG04__MMID
:
7910 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
7911 register_name
= "MMID";
7914 goto cp0_unimplemented
;
7917 case CP0_REGISTER_05
:
7919 case CP0_REG05__PAGEMASK
:
7920 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7921 register_name
= "PageMask";
7923 case CP0_REG05__PAGEGRAIN
:
7924 check_insn(ctx
, ISA_MIPS32R2
);
7925 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7926 register_name
= "PageGrain";
7927 ctx
->base
.is_jmp
= DISAS_STOP
;
7929 case CP0_REG05__SEGCTL0
:
7931 gen_helper_mtc0_segctl0(cpu_env
, arg
);
7932 register_name
= "SegCtl0";
7934 case CP0_REG05__SEGCTL1
:
7936 gen_helper_mtc0_segctl1(cpu_env
, arg
);
7937 register_name
= "SegCtl1";
7939 case CP0_REG05__SEGCTL2
:
7941 gen_helper_mtc0_segctl2(cpu_env
, arg
);
7942 register_name
= "SegCtl2";
7944 case CP0_REG05__PWBASE
:
7946 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7947 register_name
= "PWBase";
7949 case CP0_REG05__PWFIELD
:
7951 gen_helper_mtc0_pwfield(cpu_env
, arg
);
7952 register_name
= "PWField";
7954 case CP0_REG05__PWSIZE
:
7956 gen_helper_mtc0_pwsize(cpu_env
, arg
);
7957 register_name
= "PWSize";
7960 goto cp0_unimplemented
;
7963 case CP0_REGISTER_06
:
7965 case CP0_REG06__WIRED
:
7966 gen_helper_mtc0_wired(cpu_env
, arg
);
7967 register_name
= "Wired";
7969 case CP0_REG06__SRSCONF0
:
7970 check_insn(ctx
, ISA_MIPS32R2
);
7971 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7972 register_name
= "SRSConf0";
7974 case CP0_REG06__SRSCONF1
:
7975 check_insn(ctx
, ISA_MIPS32R2
);
7976 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7977 register_name
= "SRSConf1";
7979 case CP0_REG06__SRSCONF2
:
7980 check_insn(ctx
, ISA_MIPS32R2
);
7981 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7982 register_name
= "SRSConf2";
7984 case CP0_REG06__SRSCONF3
:
7985 check_insn(ctx
, ISA_MIPS32R2
);
7986 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7987 register_name
= "SRSConf3";
7989 case CP0_REG06__SRSCONF4
:
7990 check_insn(ctx
, ISA_MIPS32R2
);
7991 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7992 register_name
= "SRSConf4";
7994 case CP0_REG06__PWCTL
:
7996 gen_helper_mtc0_pwctl(cpu_env
, arg
);
7997 register_name
= "PWCtl";
8000 goto cp0_unimplemented
;
8003 case CP0_REGISTER_07
:
8005 case CP0_REG07__HWRENA
:
8006 check_insn(ctx
, ISA_MIPS32R2
);
8007 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8008 ctx
->base
.is_jmp
= DISAS_STOP
;
8009 register_name
= "HWREna";
8012 goto cp0_unimplemented
;
8015 case CP0_REGISTER_08
:
8017 case CP0_REG08__BADVADDR
:
8019 register_name
= "BadVAddr";
8021 case CP0_REG08__BADINSTR
:
8023 register_name
= "BadInstr";
8025 case CP0_REG08__BADINSTRP
:
8027 register_name
= "BadInstrP";
8029 case CP0_REG08__BADINSTRX
:
8031 register_name
= "BadInstrX";
8034 goto cp0_unimplemented
;
8037 case CP0_REGISTER_09
:
8039 case CP0_REG09__COUNT
:
8040 gen_helper_mtc0_count(cpu_env
, arg
);
8041 register_name
= "Count";
8043 case CP0_REG09__SAARI
:
8044 CP0_CHECK(ctx
->saar
);
8045 gen_helper_mtc0_saari(cpu_env
, arg
);
8046 register_name
= "SAARI";
8048 case CP0_REG09__SAAR
:
8049 CP0_CHECK(ctx
->saar
);
8050 gen_helper_mtc0_saar(cpu_env
, arg
);
8051 register_name
= "SAAR";
8054 goto cp0_unimplemented
;
8057 case CP0_REGISTER_10
:
8059 case CP0_REG10__ENTRYHI
:
8060 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8061 register_name
= "EntryHi";
8064 goto cp0_unimplemented
;
8067 case CP0_REGISTER_11
:
8069 case CP0_REG11__COMPARE
:
8070 gen_helper_mtc0_compare(cpu_env
, arg
);
8071 register_name
= "Compare";
8073 /* 6,7 are implementation dependent */
8075 goto cp0_unimplemented
;
8078 case CP0_REGISTER_12
:
8080 case CP0_REG12__STATUS
:
8081 save_cpu_state(ctx
, 1);
8082 gen_helper_mtc0_status(cpu_env
, arg
);
8083 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8084 gen_save_pc(ctx
->base
.pc_next
+ 4);
8085 ctx
->base
.is_jmp
= DISAS_EXIT
;
8086 register_name
= "Status";
8088 case CP0_REG12__INTCTL
:
8089 check_insn(ctx
, ISA_MIPS32R2
);
8090 gen_helper_mtc0_intctl(cpu_env
, arg
);
8091 /* Stop translation as we may have switched the execution mode */
8092 ctx
->base
.is_jmp
= DISAS_STOP
;
8093 register_name
= "IntCtl";
8095 case CP0_REG12__SRSCTL
:
8096 check_insn(ctx
, ISA_MIPS32R2
);
8097 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8098 /* Stop translation as we may have switched the execution mode */
8099 ctx
->base
.is_jmp
= DISAS_STOP
;
8100 register_name
= "SRSCtl";
8102 case CP0_REG12__SRSMAP
:
8103 check_insn(ctx
, ISA_MIPS32R2
);
8104 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8105 /* Stop translation as we may have switched the execution mode */
8106 ctx
->base
.is_jmp
= DISAS_STOP
;
8107 register_name
= "SRSMap";
8110 goto cp0_unimplemented
;
8113 case CP0_REGISTER_13
:
8115 case CP0_REG13__CAUSE
:
8116 save_cpu_state(ctx
, 1);
8117 gen_helper_mtc0_cause(cpu_env
, arg
);
8119 * Stop translation as we may have triggered an interrupt.
8120 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8121 * translated code to check for pending interrupts.
8123 gen_save_pc(ctx
->base
.pc_next
+ 4);
8124 ctx
->base
.is_jmp
= DISAS_EXIT
;
8125 register_name
= "Cause";
8128 goto cp0_unimplemented
;
8131 case CP0_REGISTER_14
:
8133 case CP0_REG14__EPC
:
8134 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8135 register_name
= "EPC";
8138 goto cp0_unimplemented
;
8141 case CP0_REGISTER_15
:
8143 case CP0_REG15__PRID
:
8145 register_name
= "PRid";
8147 case CP0_REG15__EBASE
:
8148 check_insn(ctx
, ISA_MIPS32R2
);
8149 gen_helper_mtc0_ebase(cpu_env
, arg
);
8150 register_name
= "EBase";
8153 goto cp0_unimplemented
;
8156 case CP0_REGISTER_16
:
8158 case CP0_REG16__CONFIG
:
8159 gen_helper_mtc0_config0(cpu_env
, arg
);
8160 register_name
= "Config";
8161 /* Stop translation as we may have switched the execution mode */
8162 ctx
->base
.is_jmp
= DISAS_STOP
;
8164 case CP0_REG16__CONFIG1
:
8165 /* ignored, read only */
8166 register_name
= "Config1";
8168 case CP0_REG16__CONFIG2
:
8169 gen_helper_mtc0_config2(cpu_env
, arg
);
8170 register_name
= "Config2";
8171 /* Stop translation as we may have switched the execution mode */
8172 ctx
->base
.is_jmp
= DISAS_STOP
;
8174 case CP0_REG16__CONFIG3
:
8175 gen_helper_mtc0_config3(cpu_env
, arg
);
8176 register_name
= "Config3";
8177 /* Stop translation as we may have switched the execution mode */
8178 ctx
->base
.is_jmp
= DISAS_STOP
;
8180 case CP0_REG16__CONFIG4
:
8181 gen_helper_mtc0_config4(cpu_env
, arg
);
8182 register_name
= "Config4";
8183 ctx
->base
.is_jmp
= DISAS_STOP
;
8185 case CP0_REG16__CONFIG5
:
8186 gen_helper_mtc0_config5(cpu_env
, arg
);
8187 register_name
= "Config5";
8188 /* Stop translation as we may have switched the execution mode */
8189 ctx
->base
.is_jmp
= DISAS_STOP
;
8191 /* 6,7 are implementation dependent */
8192 case CP0_REG16__CONFIG6
:
8194 register_name
= "Config6";
8196 case CP0_REG16__CONFIG7
:
8198 register_name
= "Config7";
8201 register_name
= "Invalid config selector";
8202 goto cp0_unimplemented
;
8205 case CP0_REGISTER_17
:
8207 case CP0_REG17__LLADDR
:
8208 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8209 register_name
= "LLAddr";
8211 case CP0_REG17__MAAR
:
8212 CP0_CHECK(ctx
->mrp
);
8213 gen_helper_mtc0_maar(cpu_env
, arg
);
8214 register_name
= "MAAR";
8216 case CP0_REG17__MAARI
:
8217 CP0_CHECK(ctx
->mrp
);
8218 gen_helper_mtc0_maari(cpu_env
, arg
);
8219 register_name
= "MAARI";
8222 goto cp0_unimplemented
;
8225 case CP0_REGISTER_18
:
8227 case CP0_REG18__WATCHLO0
:
8228 case CP0_REG18__WATCHLO1
:
8229 case CP0_REG18__WATCHLO2
:
8230 case CP0_REG18__WATCHLO3
:
8231 case CP0_REG18__WATCHLO4
:
8232 case CP0_REG18__WATCHLO5
:
8233 case CP0_REG18__WATCHLO6
:
8234 case CP0_REG18__WATCHLO7
:
8235 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8236 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8237 register_name
= "WatchLo";
8240 goto cp0_unimplemented
;
8243 case CP0_REGISTER_19
:
8245 case CP0_REG19__WATCHHI0
:
8246 case CP0_REG19__WATCHHI1
:
8247 case CP0_REG19__WATCHHI2
:
8248 case CP0_REG19__WATCHHI3
:
8249 case CP0_REG19__WATCHHI4
:
8250 case CP0_REG19__WATCHHI5
:
8251 case CP0_REG19__WATCHHI6
:
8252 case CP0_REG19__WATCHHI7
:
8253 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8254 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8255 register_name
= "WatchHi";
8258 goto cp0_unimplemented
;
8261 case CP0_REGISTER_20
:
8263 case CP0_REG20__XCONTEXT
:
8264 #if defined(TARGET_MIPS64)
8265 check_insn(ctx
, ISA_MIPS3
);
8266 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8267 register_name
= "XContext";
8271 goto cp0_unimplemented
;
8274 case CP0_REGISTER_21
:
8275 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8276 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8279 gen_helper_mtc0_framemask(cpu_env
, arg
);
8280 register_name
= "Framemask";
8283 goto cp0_unimplemented
;
8286 case CP0_REGISTER_22
:
8288 register_name
= "Diagnostic"; /* implementation dependent */
8290 case CP0_REGISTER_23
:
8292 case CP0_REG23__DEBUG
:
8293 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8294 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8295 gen_save_pc(ctx
->base
.pc_next
+ 4);
8296 ctx
->base
.is_jmp
= DISAS_EXIT
;
8297 register_name
= "Debug";
8299 case CP0_REG23__TRACECONTROL
:
8300 /* PDtrace support */
8301 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8302 register_name
= "TraceControl";
8303 /* Stop translation as we may have switched the execution mode */
8304 ctx
->base
.is_jmp
= DISAS_STOP
;
8305 goto cp0_unimplemented
;
8306 case CP0_REG23__TRACECONTROL2
:
8307 /* PDtrace support */
8308 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8309 register_name
= "TraceControl2";
8310 /* Stop translation as we may have switched the execution mode */
8311 ctx
->base
.is_jmp
= DISAS_STOP
;
8312 goto cp0_unimplemented
;
8313 case CP0_REG23__USERTRACEDATA1
:
8314 /* Stop translation as we may have switched the execution mode */
8315 ctx
->base
.is_jmp
= DISAS_STOP
;
8316 /* PDtrace support */
8317 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8318 register_name
= "UserTraceData";
8319 /* Stop translation as we may have switched the execution mode */
8320 ctx
->base
.is_jmp
= DISAS_STOP
;
8321 goto cp0_unimplemented
;
8322 case CP0_REG23__TRACEIBPC
:
8323 /* PDtrace support */
8324 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8325 /* Stop translation as we may have switched the execution mode */
8326 ctx
->base
.is_jmp
= DISAS_STOP
;
8327 register_name
= "TraceIBPC";
8328 goto cp0_unimplemented
;
8329 case CP0_REG23__TRACEDBPC
:
8330 /* PDtrace support */
8331 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8332 /* Stop translation as we may have switched the execution mode */
8333 ctx
->base
.is_jmp
= DISAS_STOP
;
8334 register_name
= "TraceDBPC";
8335 goto cp0_unimplemented
;
8337 goto cp0_unimplemented
;
8340 case CP0_REGISTER_24
:
8342 case CP0_REG24__DEPC
:
8344 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8345 register_name
= "DEPC";
8348 goto cp0_unimplemented
;
8351 case CP0_REGISTER_25
:
8353 case CP0_REG25__PERFCTL0
:
8354 gen_helper_mtc0_performance0(cpu_env
, arg
);
8355 register_name
= "Performance0";
8357 case CP0_REG25__PERFCNT0
:
8358 /* gen_helper_mtc0_performance1(arg); */
8359 register_name
= "Performance1";
8360 goto cp0_unimplemented
;
8361 case CP0_REG25__PERFCTL1
:
8362 /* gen_helper_mtc0_performance2(arg); */
8363 register_name
= "Performance2";
8364 goto cp0_unimplemented
;
8365 case CP0_REG25__PERFCNT1
:
8366 /* gen_helper_mtc0_performance3(arg); */
8367 register_name
= "Performance3";
8368 goto cp0_unimplemented
;
8369 case CP0_REG25__PERFCTL2
:
8370 /* gen_helper_mtc0_performance4(arg); */
8371 register_name
= "Performance4";
8372 goto cp0_unimplemented
;
8373 case CP0_REG25__PERFCNT2
:
8374 /* gen_helper_mtc0_performance5(arg); */
8375 register_name
= "Performance5";
8376 goto cp0_unimplemented
;
8377 case CP0_REG25__PERFCTL3
:
8378 /* gen_helper_mtc0_performance6(arg); */
8379 register_name
= "Performance6";
8380 goto cp0_unimplemented
;
8381 case CP0_REG25__PERFCNT3
:
8382 /* gen_helper_mtc0_performance7(arg); */
8383 register_name
= "Performance7";
8384 goto cp0_unimplemented
;
8386 goto cp0_unimplemented
;
8389 case CP0_REGISTER_26
:
8391 case CP0_REG26__ERRCTL
:
8392 gen_helper_mtc0_errctl(cpu_env
, arg
);
8393 ctx
->base
.is_jmp
= DISAS_STOP
;
8394 register_name
= "ErrCtl";
8397 goto cp0_unimplemented
;
8400 case CP0_REGISTER_27
:
8402 case CP0_REG27__CACHERR
:
8404 register_name
= "CacheErr";
8407 goto cp0_unimplemented
;
8410 case CP0_REGISTER_28
:
8412 case CP0_REG28__TAGLO
:
8413 case CP0_REG28__TAGLO1
:
8414 case CP0_REG28__TAGLO2
:
8415 case CP0_REG28__TAGLO3
:
8416 gen_helper_mtc0_taglo(cpu_env
, arg
);
8417 register_name
= "TagLo";
8419 case CP0_REG28__DATALO
:
8420 case CP0_REG28__DATALO1
:
8421 case CP0_REG28__DATALO2
:
8422 case CP0_REG28__DATALO3
:
8423 gen_helper_mtc0_datalo(cpu_env
, arg
);
8424 register_name
= "DataLo";
8427 goto cp0_unimplemented
;
8430 case CP0_REGISTER_29
:
8432 case CP0_REG29__TAGHI
:
8433 case CP0_REG29__TAGHI1
:
8434 case CP0_REG29__TAGHI2
:
8435 case CP0_REG29__TAGHI3
:
8436 gen_helper_mtc0_taghi(cpu_env
, arg
);
8437 register_name
= "TagHi";
8439 case CP0_REG29__DATAHI
:
8440 case CP0_REG29__DATAHI1
:
8441 case CP0_REG29__DATAHI2
:
8442 case CP0_REG29__DATAHI3
:
8443 gen_helper_mtc0_datahi(cpu_env
, arg
);
8444 register_name
= "DataHi";
8447 register_name
= "invalid sel";
8448 goto cp0_unimplemented
;
8451 case CP0_REGISTER_30
:
8453 case CP0_REG30__ERROREPC
:
8454 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8455 register_name
= "ErrorEPC";
8458 goto cp0_unimplemented
;
8461 case CP0_REGISTER_31
:
8463 case CP0_REG31__DESAVE
:
8465 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8466 register_name
= "DESAVE";
8468 case CP0_REG31__KSCRATCH1
:
8469 case CP0_REG31__KSCRATCH2
:
8470 case CP0_REG31__KSCRATCH3
:
8471 case CP0_REG31__KSCRATCH4
:
8472 case CP0_REG31__KSCRATCH5
:
8473 case CP0_REG31__KSCRATCH6
:
8474 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8475 tcg_gen_st_tl(arg
, cpu_env
,
8476 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8477 register_name
= "KScratch";
8480 goto cp0_unimplemented
;
8484 goto cp0_unimplemented
;
8486 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8488 /* For simplicity assume that all writes can cause interrupts. */
8489 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8491 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8492 * translated code to check for pending interrupts.
8494 gen_save_pc(ctx
->base
.pc_next
+ 4);
8495 ctx
->base
.is_jmp
= DISAS_EXIT
;
8500 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8501 register_name
, reg
, sel
);
8504 #if defined(TARGET_MIPS64)
8505 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8507 const char *register_name
= "invalid";
8510 check_insn(ctx
, ISA_MIPS64
);
8514 case CP0_REGISTER_00
:
8516 case CP0_REG00__INDEX
:
8517 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8518 register_name
= "Index";
8520 case CP0_REG00__MVPCONTROL
:
8521 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8522 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8523 register_name
= "MVPControl";
8525 case CP0_REG00__MVPCONF0
:
8526 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8527 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8528 register_name
= "MVPConf0";
8530 case CP0_REG00__MVPCONF1
:
8531 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8532 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8533 register_name
= "MVPConf1";
8535 case CP0_REG00__VPCONTROL
:
8537 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8538 register_name
= "VPControl";
8541 goto cp0_unimplemented
;
8544 case CP0_REGISTER_01
:
8546 case CP0_REG01__RANDOM
:
8547 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8548 gen_helper_mfc0_random(arg
, cpu_env
);
8549 register_name
= "Random";
8551 case CP0_REG01__VPECONTROL
:
8552 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8553 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8554 register_name
= "VPEControl";
8556 case CP0_REG01__VPECONF0
:
8557 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8558 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8559 register_name
= "VPEConf0";
8561 case CP0_REG01__VPECONF1
:
8562 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8563 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
8564 register_name
= "VPEConf1";
8566 case CP0_REG01__YQMASK
:
8567 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8568 tcg_gen_ld_tl(arg
, cpu_env
,
8569 offsetof(CPUMIPSState
, CP0_YQMask
));
8570 register_name
= "YQMask";
8572 case CP0_REG01__VPESCHEDULE
:
8573 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8574 tcg_gen_ld_tl(arg
, cpu_env
,
8575 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8576 register_name
= "VPESchedule";
8578 case CP0_REG01__VPESCHEFBACK
:
8579 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8580 tcg_gen_ld_tl(arg
, cpu_env
,
8581 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8582 register_name
= "VPEScheFBack";
8584 case CP0_REG01__VPEOPT
:
8585 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8586 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
8587 register_name
= "VPEOpt";
8590 goto cp0_unimplemented
;
8593 case CP0_REGISTER_02
:
8595 case CP0_REG02__ENTRYLO0
:
8596 tcg_gen_ld_tl(arg
, cpu_env
,
8597 offsetof(CPUMIPSState
, CP0_EntryLo0
));
8598 register_name
= "EntryLo0";
8600 case CP0_REG02__TCSTATUS
:
8601 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8602 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
8603 register_name
= "TCStatus";
8605 case CP0_REG02__TCBIND
:
8606 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8607 gen_helper_mfc0_tcbind(arg
, cpu_env
);
8608 register_name
= "TCBind";
8610 case CP0_REG02__TCRESTART
:
8611 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8612 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
8613 register_name
= "TCRestart";
8615 case CP0_REG02__TCHALT
:
8616 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8617 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
8618 register_name
= "TCHalt";
8620 case CP0_REG02__TCCONTEXT
:
8621 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8622 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
8623 register_name
= "TCContext";
8625 case CP0_REG02__TCSCHEDULE
:
8626 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8627 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
8628 register_name
= "TCSchedule";
8630 case CP0_REG02__TCSCHEFBACK
:
8631 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8632 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
8633 register_name
= "TCScheFBack";
8636 goto cp0_unimplemented
;
8639 case CP0_REGISTER_03
:
8641 case CP0_REG03__ENTRYLO1
:
8642 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
8643 register_name
= "EntryLo1";
8645 case CP0_REG03__GLOBALNUM
:
8647 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
8648 register_name
= "GlobalNumber";
8651 goto cp0_unimplemented
;
8654 case CP0_REGISTER_04
:
8656 case CP0_REG04__CONTEXT
:
8657 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
8658 register_name
= "Context";
8660 case CP0_REG04__CONTEXTCONFIG
:
8662 /* gen_helper_dmfc0_contextconfig(arg); */
8663 register_name
= "ContextConfig";
8664 goto cp0_unimplemented
;
8665 case CP0_REG04__USERLOCAL
:
8666 CP0_CHECK(ctx
->ulri
);
8667 tcg_gen_ld_tl(arg
, cpu_env
,
8668 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8669 register_name
= "UserLocal";
8671 case CP0_REG04__MMID
:
8673 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
8674 register_name
= "MMID";
8677 goto cp0_unimplemented
;
8680 case CP0_REGISTER_05
:
8682 case CP0_REG05__PAGEMASK
:
8683 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
8684 register_name
= "PageMask";
8686 case CP0_REG05__PAGEGRAIN
:
8687 check_insn(ctx
, ISA_MIPS32R2
);
8688 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
8689 register_name
= "PageGrain";
8691 case CP0_REG05__SEGCTL0
:
8693 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
8694 register_name
= "SegCtl0";
8696 case CP0_REG05__SEGCTL1
:
8698 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
8699 register_name
= "SegCtl1";
8701 case CP0_REG05__SEGCTL2
:
8703 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
8704 register_name
= "SegCtl2";
8706 case CP0_REG05__PWBASE
:
8708 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8709 register_name
= "PWBase";
8711 case CP0_REG05__PWFIELD
:
8713 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
8714 register_name
= "PWField";
8716 case CP0_REG05__PWSIZE
:
8718 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
8719 register_name
= "PWSize";
8722 goto cp0_unimplemented
;
8725 case CP0_REGISTER_06
:
8727 case CP0_REG06__WIRED
:
8728 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
8729 register_name
= "Wired";
8731 case CP0_REG06__SRSCONF0
:
8732 check_insn(ctx
, ISA_MIPS32R2
);
8733 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
8734 register_name
= "SRSConf0";
8736 case CP0_REG06__SRSCONF1
:
8737 check_insn(ctx
, ISA_MIPS32R2
);
8738 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
8739 register_name
= "SRSConf1";
8741 case CP0_REG06__SRSCONF2
:
8742 check_insn(ctx
, ISA_MIPS32R2
);
8743 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
8744 register_name
= "SRSConf2";
8746 case CP0_REG06__SRSCONF3
:
8747 check_insn(ctx
, ISA_MIPS32R2
);
8748 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
8749 register_name
= "SRSConf3";
8751 case CP0_REG06__SRSCONF4
:
8752 check_insn(ctx
, ISA_MIPS32R2
);
8753 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
8754 register_name
= "SRSConf4";
8756 case CP0_REG06__PWCTL
:
8758 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
8759 register_name
= "PWCtl";
8762 goto cp0_unimplemented
;
8765 case CP0_REGISTER_07
:
8767 case CP0_REG07__HWRENA
:
8768 check_insn(ctx
, ISA_MIPS32R2
);
8769 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
8770 register_name
= "HWREna";
8773 goto cp0_unimplemented
;
8776 case CP0_REGISTER_08
:
8778 case CP0_REG08__BADVADDR
:
8779 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
8780 register_name
= "BadVAddr";
8782 case CP0_REG08__BADINSTR
:
8784 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
8785 register_name
= "BadInstr";
8787 case CP0_REG08__BADINSTRP
:
8789 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
8790 register_name
= "BadInstrP";
8792 case CP0_REG08__BADINSTRX
:
8794 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
8795 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
8796 register_name
= "BadInstrX";
8799 goto cp0_unimplemented
;
8802 case CP0_REGISTER_09
:
8804 case CP0_REG09__COUNT
:
8805 /* Mark as an IO operation because we read the time. */
8806 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8809 gen_helper_mfc0_count(arg
, cpu_env
);
8811 * Break the TB to be able to take timer interrupts immediately
8812 * after reading count. DISAS_STOP isn't sufficient, we need to
8813 * ensure we break completely out of translated code.
8815 gen_save_pc(ctx
->base
.pc_next
+ 4);
8816 ctx
->base
.is_jmp
= DISAS_EXIT
;
8817 register_name
= "Count";
8819 case CP0_REG09__SAARI
:
8820 CP0_CHECK(ctx
->saar
);
8821 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
8822 register_name
= "SAARI";
8824 case CP0_REG09__SAAR
:
8825 CP0_CHECK(ctx
->saar
);
8826 gen_helper_dmfc0_saar(arg
, cpu_env
);
8827 register_name
= "SAAR";
8830 goto cp0_unimplemented
;
8833 case CP0_REGISTER_10
:
8835 case CP0_REG10__ENTRYHI
:
8836 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
8837 register_name
= "EntryHi";
8840 goto cp0_unimplemented
;
8843 case CP0_REGISTER_11
:
8845 case CP0_REG11__COMPARE
:
8846 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
8847 register_name
= "Compare";
8849 /* 6,7 are implementation dependent */
8851 goto cp0_unimplemented
;
8854 case CP0_REGISTER_12
:
8856 case CP0_REG12__STATUS
:
8857 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
8858 register_name
= "Status";
8860 case CP0_REG12__INTCTL
:
8861 check_insn(ctx
, ISA_MIPS32R2
);
8862 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
8863 register_name
= "IntCtl";
8865 case CP0_REG12__SRSCTL
:
8866 check_insn(ctx
, ISA_MIPS32R2
);
8867 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
8868 register_name
= "SRSCtl";
8870 case CP0_REG12__SRSMAP
:
8871 check_insn(ctx
, ISA_MIPS32R2
);
8872 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8873 register_name
= "SRSMap";
8876 goto cp0_unimplemented
;
8879 case CP0_REGISTER_13
:
8881 case CP0_REG13__CAUSE
:
8882 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
8883 register_name
= "Cause";
8886 goto cp0_unimplemented
;
8889 case CP0_REGISTER_14
:
8891 case CP0_REG14__EPC
:
8892 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8893 register_name
= "EPC";
8896 goto cp0_unimplemented
;
8899 case CP0_REGISTER_15
:
8901 case CP0_REG15__PRID
:
8902 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
8903 register_name
= "PRid";
8905 case CP0_REG15__EBASE
:
8906 check_insn(ctx
, ISA_MIPS32R2
);
8907 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
8908 register_name
= "EBase";
8910 case CP0_REG15__CMGCRBASE
:
8911 check_insn(ctx
, ISA_MIPS32R2
);
8912 CP0_CHECK(ctx
->cmgcr
);
8913 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
8914 register_name
= "CMGCRBase";
8917 goto cp0_unimplemented
;
8920 case CP0_REGISTER_16
:
8922 case CP0_REG16__CONFIG
:
8923 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
8924 register_name
= "Config";
8926 case CP0_REG16__CONFIG1
:
8927 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
8928 register_name
= "Config1";
8930 case CP0_REG16__CONFIG2
:
8931 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
8932 register_name
= "Config2";
8934 case CP0_REG16__CONFIG3
:
8935 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
8936 register_name
= "Config3";
8938 case CP0_REG16__CONFIG4
:
8939 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
8940 register_name
= "Config4";
8942 case CP0_REG16__CONFIG5
:
8943 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
8944 register_name
= "Config5";
8946 /* 6,7 are implementation dependent */
8947 case CP0_REG16__CONFIG6
:
8948 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
8949 register_name
= "Config6";
8951 case CP0_REG16__CONFIG7
:
8952 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
8953 register_name
= "Config7";
8956 goto cp0_unimplemented
;
8959 case CP0_REGISTER_17
:
8961 case CP0_REG17__LLADDR
:
8962 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
8963 register_name
= "LLAddr";
8965 case CP0_REG17__MAAR
:
8966 CP0_CHECK(ctx
->mrp
);
8967 gen_helper_dmfc0_maar(arg
, cpu_env
);
8968 register_name
= "MAAR";
8970 case CP0_REG17__MAARI
:
8971 CP0_CHECK(ctx
->mrp
);
8972 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
8973 register_name
= "MAARI";
8976 goto cp0_unimplemented
;
8979 case CP0_REGISTER_18
:
8981 case CP0_REG18__WATCHLO0
:
8982 case CP0_REG18__WATCHLO1
:
8983 case CP0_REG18__WATCHLO2
:
8984 case CP0_REG18__WATCHLO3
:
8985 case CP0_REG18__WATCHLO4
:
8986 case CP0_REG18__WATCHLO5
:
8987 case CP0_REG18__WATCHLO6
:
8988 case CP0_REG18__WATCHLO7
:
8989 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8990 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
8991 register_name
= "WatchLo";
8994 goto cp0_unimplemented
;
8997 case CP0_REGISTER_19
:
8999 case CP0_REG19__WATCHHI0
:
9000 case CP0_REG19__WATCHHI1
:
9001 case CP0_REG19__WATCHHI2
:
9002 case CP0_REG19__WATCHHI3
:
9003 case CP0_REG19__WATCHHI4
:
9004 case CP0_REG19__WATCHHI5
:
9005 case CP0_REG19__WATCHHI6
:
9006 case CP0_REG19__WATCHHI7
:
9007 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9008 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
9009 register_name
= "WatchHi";
9012 goto cp0_unimplemented
;
9015 case CP0_REGISTER_20
:
9017 case CP0_REG20__XCONTEXT
:
9018 check_insn(ctx
, ISA_MIPS3
);
9019 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
9020 register_name
= "XContext";
9023 goto cp0_unimplemented
;
9026 case CP0_REGISTER_21
:
9027 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9028 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
9031 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
9032 register_name
= "Framemask";
9035 goto cp0_unimplemented
;
9038 case CP0_REGISTER_22
:
9039 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9040 register_name
= "'Diagnostic"; /* implementation dependent */
9042 case CP0_REGISTER_23
:
9044 case CP0_REG23__DEBUG
:
9045 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
9046 register_name
= "Debug";
9048 case CP0_REG23__TRACECONTROL
:
9049 /* PDtrace support */
9050 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
9051 register_name
= "TraceControl";
9052 goto cp0_unimplemented
;
9053 case CP0_REG23__TRACECONTROL2
:
9054 /* PDtrace support */
9055 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9056 register_name
= "TraceControl2";
9057 goto cp0_unimplemented
;
9058 case CP0_REG23__USERTRACEDATA1
:
9059 /* PDtrace support */
9060 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9061 register_name
= "UserTraceData1";
9062 goto cp0_unimplemented
;
9063 case CP0_REG23__TRACEIBPC
:
9064 /* PDtrace support */
9065 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9066 register_name
= "TraceIBPC";
9067 goto cp0_unimplemented
;
9068 case CP0_REG23__TRACEDBPC
:
9069 /* PDtrace support */
9070 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9071 register_name
= "TraceDBPC";
9072 goto cp0_unimplemented
;
9074 goto cp0_unimplemented
;
9077 case CP0_REGISTER_24
:
9079 case CP0_REG24__DEPC
:
9081 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9082 register_name
= "DEPC";
9085 goto cp0_unimplemented
;
9088 case CP0_REGISTER_25
:
9090 case CP0_REG25__PERFCTL0
:
9091 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
9092 register_name
= "Performance0";
9094 case CP0_REG25__PERFCNT0
:
9095 /* gen_helper_dmfc0_performance1(arg); */
9096 register_name
= "Performance1";
9097 goto cp0_unimplemented
;
9098 case CP0_REG25__PERFCTL1
:
9099 /* gen_helper_dmfc0_performance2(arg); */
9100 register_name
= "Performance2";
9101 goto cp0_unimplemented
;
9102 case CP0_REG25__PERFCNT1
:
9103 /* gen_helper_dmfc0_performance3(arg); */
9104 register_name
= "Performance3";
9105 goto cp0_unimplemented
;
9106 case CP0_REG25__PERFCTL2
:
9107 /* gen_helper_dmfc0_performance4(arg); */
9108 register_name
= "Performance4";
9109 goto cp0_unimplemented
;
9110 case CP0_REG25__PERFCNT2
:
9111 /* gen_helper_dmfc0_performance5(arg); */
9112 register_name
= "Performance5";
9113 goto cp0_unimplemented
;
9114 case CP0_REG25__PERFCTL3
:
9115 /* gen_helper_dmfc0_performance6(arg); */
9116 register_name
= "Performance6";
9117 goto cp0_unimplemented
;
9118 case CP0_REG25__PERFCNT3
:
9119 /* gen_helper_dmfc0_performance7(arg); */
9120 register_name
= "Performance7";
9121 goto cp0_unimplemented
;
9123 goto cp0_unimplemented
;
9126 case CP0_REGISTER_26
:
9128 case CP0_REG26__ERRCTL
:
9129 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
9130 register_name
= "ErrCtl";
9133 goto cp0_unimplemented
;
9136 case CP0_REGISTER_27
:
9139 case CP0_REG27__CACHERR
:
9140 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9141 register_name
= "CacheErr";
9144 goto cp0_unimplemented
;
9147 case CP0_REGISTER_28
:
9149 case CP0_REG28__TAGLO
:
9150 case CP0_REG28__TAGLO1
:
9151 case CP0_REG28__TAGLO2
:
9152 case CP0_REG28__TAGLO3
:
9153 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
9154 register_name
= "TagLo";
9156 case CP0_REG28__DATALO
:
9157 case CP0_REG28__DATALO1
:
9158 case CP0_REG28__DATALO2
:
9159 case CP0_REG28__DATALO3
:
9160 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
9161 register_name
= "DataLo";
9164 goto cp0_unimplemented
;
9167 case CP0_REGISTER_29
:
9169 case CP0_REG29__TAGHI
:
9170 case CP0_REG29__TAGHI1
:
9171 case CP0_REG29__TAGHI2
:
9172 case CP0_REG29__TAGHI3
:
9173 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
9174 register_name
= "TagHi";
9176 case CP0_REG29__DATAHI
:
9177 case CP0_REG29__DATAHI1
:
9178 case CP0_REG29__DATAHI2
:
9179 case CP0_REG29__DATAHI3
:
9180 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
9181 register_name
= "DataHi";
9184 goto cp0_unimplemented
;
9187 case CP0_REGISTER_30
:
9189 case CP0_REG30__ERROREPC
:
9190 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9191 register_name
= "ErrorEPC";
9194 goto cp0_unimplemented
;
9197 case CP0_REGISTER_31
:
9199 case CP0_REG31__DESAVE
:
9201 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9202 register_name
= "DESAVE";
9204 case CP0_REG31__KSCRATCH1
:
9205 case CP0_REG31__KSCRATCH2
:
9206 case CP0_REG31__KSCRATCH3
:
9207 case CP0_REG31__KSCRATCH4
:
9208 case CP0_REG31__KSCRATCH5
:
9209 case CP0_REG31__KSCRATCH6
:
9210 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9211 tcg_gen_ld_tl(arg
, cpu_env
,
9212 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9213 register_name
= "KScratch";
9216 goto cp0_unimplemented
;
9220 goto cp0_unimplemented
;
9222 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9226 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9227 register_name
, reg
, sel
);
9228 gen_mfc0_unimplemented(ctx
, arg
);
9231 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9233 const char *register_name
= "invalid";
9236 check_insn(ctx
, ISA_MIPS64
);
9239 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9244 case CP0_REGISTER_00
:
9246 case CP0_REG00__INDEX
:
9247 gen_helper_mtc0_index(cpu_env
, arg
);
9248 register_name
= "Index";
9250 case CP0_REG00__MVPCONTROL
:
9251 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9252 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9253 register_name
= "MVPControl";
9255 case CP0_REG00__MVPCONF0
:
9256 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9258 register_name
= "MVPConf0";
9260 case CP0_REG00__MVPCONF1
:
9261 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9263 register_name
= "MVPConf1";
9265 case CP0_REG00__VPCONTROL
:
9268 register_name
= "VPControl";
9271 goto cp0_unimplemented
;
9274 case CP0_REGISTER_01
:
9276 case CP0_REG01__RANDOM
:
9278 register_name
= "Random";
9280 case CP0_REG01__VPECONTROL
:
9281 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9282 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9283 register_name
= "VPEControl";
9285 case CP0_REG01__VPECONF0
:
9286 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9287 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9288 register_name
= "VPEConf0";
9290 case CP0_REG01__VPECONF1
:
9291 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9292 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9293 register_name
= "VPEConf1";
9295 case CP0_REG01__YQMASK
:
9296 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9297 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9298 register_name
= "YQMask";
9300 case CP0_REG01__VPESCHEDULE
:
9301 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9302 tcg_gen_st_tl(arg
, cpu_env
,
9303 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9304 register_name
= "VPESchedule";
9306 case CP0_REG01__VPESCHEFBACK
:
9307 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9308 tcg_gen_st_tl(arg
, cpu_env
,
9309 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9310 register_name
= "VPEScheFBack";
9312 case CP0_REG01__VPEOPT
:
9313 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9314 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9315 register_name
= "VPEOpt";
9318 goto cp0_unimplemented
;
9321 case CP0_REGISTER_02
:
9323 case CP0_REG02__ENTRYLO0
:
9324 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9325 register_name
= "EntryLo0";
9327 case CP0_REG02__TCSTATUS
:
9328 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9329 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9330 register_name
= "TCStatus";
9332 case CP0_REG02__TCBIND
:
9333 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9334 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9335 register_name
= "TCBind";
9337 case CP0_REG02__TCRESTART
:
9338 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9339 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9340 register_name
= "TCRestart";
9342 case CP0_REG02__TCHALT
:
9343 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9344 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9345 register_name
= "TCHalt";
9347 case CP0_REG02__TCCONTEXT
:
9348 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9349 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9350 register_name
= "TCContext";
9352 case CP0_REG02__TCSCHEDULE
:
9353 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9354 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9355 register_name
= "TCSchedule";
9357 case CP0_REG02__TCSCHEFBACK
:
9358 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9359 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9360 register_name
= "TCScheFBack";
9363 goto cp0_unimplemented
;
9366 case CP0_REGISTER_03
:
9368 case CP0_REG03__ENTRYLO1
:
9369 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9370 register_name
= "EntryLo1";
9372 case CP0_REG03__GLOBALNUM
:
9375 register_name
= "GlobalNumber";
9378 goto cp0_unimplemented
;
9381 case CP0_REGISTER_04
:
9383 case CP0_REG04__CONTEXT
:
9384 gen_helper_mtc0_context(cpu_env
, arg
);
9385 register_name
= "Context";
9387 case CP0_REG04__CONTEXTCONFIG
:
9389 /* gen_helper_dmtc0_contextconfig(arg); */
9390 register_name
= "ContextConfig";
9391 goto cp0_unimplemented
;
9392 case CP0_REG04__USERLOCAL
:
9393 CP0_CHECK(ctx
->ulri
);
9394 tcg_gen_st_tl(arg
, cpu_env
,
9395 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9396 register_name
= "UserLocal";
9398 case CP0_REG04__MMID
:
9400 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9401 register_name
= "MMID";
9404 goto cp0_unimplemented
;
9407 case CP0_REGISTER_05
:
9409 case CP0_REG05__PAGEMASK
:
9410 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9411 register_name
= "PageMask";
9413 case CP0_REG05__PAGEGRAIN
:
9414 check_insn(ctx
, ISA_MIPS32R2
);
9415 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9416 register_name
= "PageGrain";
9418 case CP0_REG05__SEGCTL0
:
9420 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9421 register_name
= "SegCtl0";
9423 case CP0_REG05__SEGCTL1
:
9425 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9426 register_name
= "SegCtl1";
9428 case CP0_REG05__SEGCTL2
:
9430 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9431 register_name
= "SegCtl2";
9433 case CP0_REG05__PWBASE
:
9435 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9436 register_name
= "PWBase";
9438 case CP0_REG05__PWFIELD
:
9440 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9441 register_name
= "PWField";
9443 case CP0_REG05__PWSIZE
:
9445 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9446 register_name
= "PWSize";
9449 goto cp0_unimplemented
;
9452 case CP0_REGISTER_06
:
9454 case CP0_REG06__WIRED
:
9455 gen_helper_mtc0_wired(cpu_env
, arg
);
9456 register_name
= "Wired";
9458 case CP0_REG06__SRSCONF0
:
9459 check_insn(ctx
, ISA_MIPS32R2
);
9460 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9461 register_name
= "SRSConf0";
9463 case CP0_REG06__SRSCONF1
:
9464 check_insn(ctx
, ISA_MIPS32R2
);
9465 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9466 register_name
= "SRSConf1";
9468 case CP0_REG06__SRSCONF2
:
9469 check_insn(ctx
, ISA_MIPS32R2
);
9470 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9471 register_name
= "SRSConf2";
9473 case CP0_REG06__SRSCONF3
:
9474 check_insn(ctx
, ISA_MIPS32R2
);
9475 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9476 register_name
= "SRSConf3";
9478 case CP0_REG06__SRSCONF4
:
9479 check_insn(ctx
, ISA_MIPS32R2
);
9480 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9481 register_name
= "SRSConf4";
9483 case CP0_REG06__PWCTL
:
9485 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9486 register_name
= "PWCtl";
9489 goto cp0_unimplemented
;
9492 case CP0_REGISTER_07
:
9494 case CP0_REG07__HWRENA
:
9495 check_insn(ctx
, ISA_MIPS32R2
);
9496 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9497 ctx
->base
.is_jmp
= DISAS_STOP
;
9498 register_name
= "HWREna";
9501 goto cp0_unimplemented
;
9504 case CP0_REGISTER_08
:
9506 case CP0_REG08__BADVADDR
:
9508 register_name
= "BadVAddr";
9510 case CP0_REG08__BADINSTR
:
9512 register_name
= "BadInstr";
9514 case CP0_REG08__BADINSTRP
:
9516 register_name
= "BadInstrP";
9518 case CP0_REG08__BADINSTRX
:
9520 register_name
= "BadInstrX";
9523 goto cp0_unimplemented
;
9526 case CP0_REGISTER_09
:
9528 case CP0_REG09__COUNT
:
9529 gen_helper_mtc0_count(cpu_env
, arg
);
9530 register_name
= "Count";
9532 case CP0_REG09__SAARI
:
9533 CP0_CHECK(ctx
->saar
);
9534 gen_helper_mtc0_saari(cpu_env
, arg
);
9535 register_name
= "SAARI";
9537 case CP0_REG09__SAAR
:
9538 CP0_CHECK(ctx
->saar
);
9539 gen_helper_mtc0_saar(cpu_env
, arg
);
9540 register_name
= "SAAR";
9543 goto cp0_unimplemented
;
9545 /* Stop translation as we may have switched the execution mode */
9546 ctx
->base
.is_jmp
= DISAS_STOP
;
9548 case CP0_REGISTER_10
:
9550 case CP0_REG10__ENTRYHI
:
9551 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9552 register_name
= "EntryHi";
9555 goto cp0_unimplemented
;
9558 case CP0_REGISTER_11
:
9560 case CP0_REG11__COMPARE
:
9561 gen_helper_mtc0_compare(cpu_env
, arg
);
9562 register_name
= "Compare";
9564 /* 6,7 are implementation dependent */
9566 goto cp0_unimplemented
;
9568 /* Stop translation as we may have switched the execution mode */
9569 ctx
->base
.is_jmp
= DISAS_STOP
;
9571 case CP0_REGISTER_12
:
9573 case CP0_REG12__STATUS
:
9574 save_cpu_state(ctx
, 1);
9575 gen_helper_mtc0_status(cpu_env
, arg
);
9576 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9577 gen_save_pc(ctx
->base
.pc_next
+ 4);
9578 ctx
->base
.is_jmp
= DISAS_EXIT
;
9579 register_name
= "Status";
9581 case CP0_REG12__INTCTL
:
9582 check_insn(ctx
, ISA_MIPS32R2
);
9583 gen_helper_mtc0_intctl(cpu_env
, arg
);
9584 /* Stop translation as we may have switched the execution mode */
9585 ctx
->base
.is_jmp
= DISAS_STOP
;
9586 register_name
= "IntCtl";
9588 case CP0_REG12__SRSCTL
:
9589 check_insn(ctx
, ISA_MIPS32R2
);
9590 gen_helper_mtc0_srsctl(cpu_env
, arg
);
9591 /* Stop translation as we may have switched the execution mode */
9592 ctx
->base
.is_jmp
= DISAS_STOP
;
9593 register_name
= "SRSCtl";
9595 case CP0_REG12__SRSMAP
:
9596 check_insn(ctx
, ISA_MIPS32R2
);
9597 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9598 /* Stop translation as we may have switched the execution mode */
9599 ctx
->base
.is_jmp
= DISAS_STOP
;
9600 register_name
= "SRSMap";
9603 goto cp0_unimplemented
;
9606 case CP0_REGISTER_13
:
9608 case CP0_REG13__CAUSE
:
9609 save_cpu_state(ctx
, 1);
9610 gen_helper_mtc0_cause(cpu_env
, arg
);
9612 * Stop translation as we may have triggered an interrupt.
9613 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9614 * translated code to check for pending interrupts.
9616 gen_save_pc(ctx
->base
.pc_next
+ 4);
9617 ctx
->base
.is_jmp
= DISAS_EXIT
;
9618 register_name
= "Cause";
9621 goto cp0_unimplemented
;
9624 case CP0_REGISTER_14
:
9626 case CP0_REG14__EPC
:
9627 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9628 register_name
= "EPC";
9631 goto cp0_unimplemented
;
9634 case CP0_REGISTER_15
:
9636 case CP0_REG15__PRID
:
9638 register_name
= "PRid";
9640 case CP0_REG15__EBASE
:
9641 check_insn(ctx
, ISA_MIPS32R2
);
9642 gen_helper_mtc0_ebase(cpu_env
, arg
);
9643 register_name
= "EBase";
9646 goto cp0_unimplemented
;
9649 case CP0_REGISTER_16
:
9651 case CP0_REG16__CONFIG
:
9652 gen_helper_mtc0_config0(cpu_env
, arg
);
9653 register_name
= "Config";
9654 /* Stop translation as we may have switched the execution mode */
9655 ctx
->base
.is_jmp
= DISAS_STOP
;
9657 case CP0_REG16__CONFIG1
:
9658 /* ignored, read only */
9659 register_name
= "Config1";
9661 case CP0_REG16__CONFIG2
:
9662 gen_helper_mtc0_config2(cpu_env
, arg
);
9663 register_name
= "Config2";
9664 /* Stop translation as we may have switched the execution mode */
9665 ctx
->base
.is_jmp
= DISAS_STOP
;
9667 case CP0_REG16__CONFIG3
:
9668 gen_helper_mtc0_config3(cpu_env
, arg
);
9669 register_name
= "Config3";
9670 /* Stop translation as we may have switched the execution mode */
9671 ctx
->base
.is_jmp
= DISAS_STOP
;
9673 case CP0_REG16__CONFIG4
:
9674 /* currently ignored */
9675 register_name
= "Config4";
9677 case CP0_REG16__CONFIG5
:
9678 gen_helper_mtc0_config5(cpu_env
, arg
);
9679 register_name
= "Config5";
9680 /* Stop translation as we may have switched the execution mode */
9681 ctx
->base
.is_jmp
= DISAS_STOP
;
9683 /* 6,7 are implementation dependent */
9685 register_name
= "Invalid config selector";
9686 goto cp0_unimplemented
;
9689 case CP0_REGISTER_17
:
9691 case CP0_REG17__LLADDR
:
9692 gen_helper_mtc0_lladdr(cpu_env
, arg
);
9693 register_name
= "LLAddr";
9695 case CP0_REG17__MAAR
:
9696 CP0_CHECK(ctx
->mrp
);
9697 gen_helper_mtc0_maar(cpu_env
, arg
);
9698 register_name
= "MAAR";
9700 case CP0_REG17__MAARI
:
9701 CP0_CHECK(ctx
->mrp
);
9702 gen_helper_mtc0_maari(cpu_env
, arg
);
9703 register_name
= "MAARI";
9706 goto cp0_unimplemented
;
9709 case CP0_REGISTER_18
:
9711 case CP0_REG18__WATCHLO0
:
9712 case CP0_REG18__WATCHLO1
:
9713 case CP0_REG18__WATCHLO2
:
9714 case CP0_REG18__WATCHLO3
:
9715 case CP0_REG18__WATCHLO4
:
9716 case CP0_REG18__WATCHLO5
:
9717 case CP0_REG18__WATCHLO6
:
9718 case CP0_REG18__WATCHLO7
:
9719 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9720 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
9721 register_name
= "WatchLo";
9724 goto cp0_unimplemented
;
9727 case CP0_REGISTER_19
:
9729 case CP0_REG19__WATCHHI0
:
9730 case CP0_REG19__WATCHHI1
:
9731 case CP0_REG19__WATCHHI2
:
9732 case CP0_REG19__WATCHHI3
:
9733 case CP0_REG19__WATCHHI4
:
9734 case CP0_REG19__WATCHHI5
:
9735 case CP0_REG19__WATCHHI6
:
9736 case CP0_REG19__WATCHHI7
:
9737 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9738 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
9739 register_name
= "WatchHi";
9742 goto cp0_unimplemented
;
9745 case CP0_REGISTER_20
:
9747 case CP0_REG20__XCONTEXT
:
9748 check_insn(ctx
, ISA_MIPS3
);
9749 gen_helper_mtc0_xcontext(cpu_env
, arg
);
9750 register_name
= "XContext";
9753 goto cp0_unimplemented
;
9756 case CP0_REGISTER_21
:
9757 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9758 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
9761 gen_helper_mtc0_framemask(cpu_env
, arg
);
9762 register_name
= "Framemask";
9765 goto cp0_unimplemented
;
9768 case CP0_REGISTER_22
:
9770 register_name
= "Diagnostic"; /* implementation dependent */
9772 case CP0_REGISTER_23
:
9774 case CP0_REG23__DEBUG
:
9775 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
9776 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9777 gen_save_pc(ctx
->base
.pc_next
+ 4);
9778 ctx
->base
.is_jmp
= DISAS_EXIT
;
9779 register_name
= "Debug";
9781 case CP0_REG23__TRACECONTROL
:
9782 /* PDtrace support */
9783 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
9784 /* Stop translation as we may have switched the execution mode */
9785 ctx
->base
.is_jmp
= DISAS_STOP
;
9786 register_name
= "TraceControl";
9787 goto cp0_unimplemented
;
9788 case CP0_REG23__TRACECONTROL2
:
9789 /* PDtrace support */
9790 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
9791 /* Stop translation as we may have switched the execution mode */
9792 ctx
->base
.is_jmp
= DISAS_STOP
;
9793 register_name
= "TraceControl2";
9794 goto cp0_unimplemented
;
9795 case CP0_REG23__USERTRACEDATA1
:
9796 /* PDtrace support */
9797 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
9798 /* Stop translation as we may have switched the execution mode */
9799 ctx
->base
.is_jmp
= DISAS_STOP
;
9800 register_name
= "UserTraceData1";
9801 goto cp0_unimplemented
;
9802 case CP0_REG23__TRACEIBPC
:
9803 /* PDtrace support */
9804 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
9805 /* Stop translation as we may have switched the execution mode */
9806 ctx
->base
.is_jmp
= DISAS_STOP
;
9807 register_name
= "TraceIBPC";
9808 goto cp0_unimplemented
;
9809 case CP0_REG23__TRACEDBPC
:
9810 /* PDtrace support */
9811 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
9812 /* Stop translation as we may have switched the execution mode */
9813 ctx
->base
.is_jmp
= DISAS_STOP
;
9814 register_name
= "TraceDBPC";
9815 goto cp0_unimplemented
;
9817 goto cp0_unimplemented
;
9820 case CP0_REGISTER_24
:
9822 case CP0_REG24__DEPC
:
9824 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9825 register_name
= "DEPC";
9828 goto cp0_unimplemented
;
9831 case CP0_REGISTER_25
:
9833 case CP0_REG25__PERFCTL0
:
9834 gen_helper_mtc0_performance0(cpu_env
, arg
);
9835 register_name
= "Performance0";
9837 case CP0_REG25__PERFCNT0
:
9838 /* gen_helper_mtc0_performance1(cpu_env, arg); */
9839 register_name
= "Performance1";
9840 goto cp0_unimplemented
;
9841 case CP0_REG25__PERFCTL1
:
9842 /* gen_helper_mtc0_performance2(cpu_env, arg); */
9843 register_name
= "Performance2";
9844 goto cp0_unimplemented
;
9845 case CP0_REG25__PERFCNT1
:
9846 /* gen_helper_mtc0_performance3(cpu_env, arg); */
9847 register_name
= "Performance3";
9848 goto cp0_unimplemented
;
9849 case CP0_REG25__PERFCTL2
:
9850 /* gen_helper_mtc0_performance4(cpu_env, arg); */
9851 register_name
= "Performance4";
9852 goto cp0_unimplemented
;
9853 case CP0_REG25__PERFCNT2
:
9854 /* gen_helper_mtc0_performance5(cpu_env, arg); */
9855 register_name
= "Performance5";
9856 goto cp0_unimplemented
;
9857 case CP0_REG25__PERFCTL3
:
9858 /* gen_helper_mtc0_performance6(cpu_env, arg); */
9859 register_name
= "Performance6";
9860 goto cp0_unimplemented
;
9861 case CP0_REG25__PERFCNT3
:
9862 /* gen_helper_mtc0_performance7(cpu_env, arg); */
9863 register_name
= "Performance7";
9864 goto cp0_unimplemented
;
9866 goto cp0_unimplemented
;
9869 case CP0_REGISTER_26
:
9871 case CP0_REG26__ERRCTL
:
9872 gen_helper_mtc0_errctl(cpu_env
, arg
);
9873 ctx
->base
.is_jmp
= DISAS_STOP
;
9874 register_name
= "ErrCtl";
9877 goto cp0_unimplemented
;
9880 case CP0_REGISTER_27
:
9882 case CP0_REG27__CACHERR
:
9884 register_name
= "CacheErr";
9887 goto cp0_unimplemented
;
9890 case CP0_REGISTER_28
:
9892 case CP0_REG28__TAGLO
:
9893 case CP0_REG28__TAGLO1
:
9894 case CP0_REG28__TAGLO2
:
9895 case CP0_REG28__TAGLO3
:
9896 gen_helper_mtc0_taglo(cpu_env
, arg
);
9897 register_name
= "TagLo";
9899 case CP0_REG28__DATALO
:
9900 case CP0_REG28__DATALO1
:
9901 case CP0_REG28__DATALO2
:
9902 case CP0_REG28__DATALO3
:
9903 gen_helper_mtc0_datalo(cpu_env
, arg
);
9904 register_name
= "DataLo";
9907 goto cp0_unimplemented
;
9910 case CP0_REGISTER_29
:
9912 case CP0_REG29__TAGHI
:
9913 case CP0_REG29__TAGHI1
:
9914 case CP0_REG29__TAGHI2
:
9915 case CP0_REG29__TAGHI3
:
9916 gen_helper_mtc0_taghi(cpu_env
, arg
);
9917 register_name
= "TagHi";
9919 case CP0_REG29__DATAHI
:
9920 case CP0_REG29__DATAHI1
:
9921 case CP0_REG29__DATAHI2
:
9922 case CP0_REG29__DATAHI3
:
9923 gen_helper_mtc0_datahi(cpu_env
, arg
);
9924 register_name
= "DataHi";
9927 register_name
= "invalid sel";
9928 goto cp0_unimplemented
;
9931 case CP0_REGISTER_30
:
9933 case CP0_REG30__ERROREPC
:
9934 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9935 register_name
= "ErrorEPC";
9938 goto cp0_unimplemented
;
9941 case CP0_REGISTER_31
:
9943 case CP0_REG31__DESAVE
:
9945 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9946 register_name
= "DESAVE";
9948 case CP0_REG31__KSCRATCH1
:
9949 case CP0_REG31__KSCRATCH2
:
9950 case CP0_REG31__KSCRATCH3
:
9951 case CP0_REG31__KSCRATCH4
:
9952 case CP0_REG31__KSCRATCH5
:
9953 case CP0_REG31__KSCRATCH6
:
9954 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9955 tcg_gen_st_tl(arg
, cpu_env
,
9956 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9957 register_name
= "KScratch";
9960 goto cp0_unimplemented
;
9964 goto cp0_unimplemented
;
9966 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
9968 /* For simplicity assume that all writes can cause interrupts. */
9969 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9971 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9972 * translated code to check for pending interrupts.
9974 gen_save_pc(ctx
->base
.pc_next
+ 4);
9975 ctx
->base
.is_jmp
= DISAS_EXIT
;
9980 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
9981 register_name
, reg
, sel
);
9983 #endif /* TARGET_MIPS64 */
9985 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
9986 int u
, int sel
, int h
)
9988 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9989 TCGv t0
= tcg_temp_local_new();
9991 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9992 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9993 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9994 tcg_gen_movi_tl(t0
, -1);
9995 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9996 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9997 tcg_gen_movi_tl(t0
, -1);
9998 } else if (u
== 0) {
10003 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
10006 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
10016 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
10019 gen_helper_mftc0_tcbind(t0
, cpu_env
);
10022 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
10025 gen_helper_mftc0_tchalt(t0
, cpu_env
);
10028 gen_helper_mftc0_tccontext(t0
, cpu_env
);
10031 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
10034 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
10037 gen_mfc0(ctx
, t0
, rt
, sel
);
10044 gen_helper_mftc0_entryhi(t0
, cpu_env
);
10047 gen_mfc0(ctx
, t0
, rt
, sel
);
10054 gen_helper_mftc0_status(t0
, cpu_env
);
10057 gen_mfc0(ctx
, t0
, rt
, sel
);
10064 gen_helper_mftc0_cause(t0
, cpu_env
);
10074 gen_helper_mftc0_epc(t0
, cpu_env
);
10084 gen_helper_mftc0_ebase(t0
, cpu_env
);
10101 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
10111 gen_helper_mftc0_debug(t0
, cpu_env
);
10114 gen_mfc0(ctx
, t0
, rt
, sel
);
10119 gen_mfc0(ctx
, t0
, rt
, sel
);
10123 /* GPR registers. */
10125 gen_helper_1e0i(mftgpr
, t0
, rt
);
10127 /* Auxiliary CPU registers */
10131 gen_helper_1e0i(mftlo
, t0
, 0);
10134 gen_helper_1e0i(mfthi
, t0
, 0);
10137 gen_helper_1e0i(mftacx
, t0
, 0);
10140 gen_helper_1e0i(mftlo
, t0
, 1);
10143 gen_helper_1e0i(mfthi
, t0
, 1);
10146 gen_helper_1e0i(mftacx
, t0
, 1);
10149 gen_helper_1e0i(mftlo
, t0
, 2);
10152 gen_helper_1e0i(mfthi
, t0
, 2);
10155 gen_helper_1e0i(mftacx
, t0
, 2);
10158 gen_helper_1e0i(mftlo
, t0
, 3);
10161 gen_helper_1e0i(mfthi
, t0
, 3);
10164 gen_helper_1e0i(mftacx
, t0
, 3);
10167 gen_helper_mftdsp(t0
, cpu_env
);
10173 /* Floating point (COP1). */
10175 /* XXX: For now we support only a single FPU context. */
10177 TCGv_i32 fp0
= tcg_temp_new_i32();
10179 gen_load_fpr32(ctx
, fp0
, rt
);
10180 tcg_gen_ext_i32_tl(t0
, fp0
);
10181 tcg_temp_free_i32(fp0
);
10183 TCGv_i32 fp0
= tcg_temp_new_i32();
10185 gen_load_fpr32h(ctx
, fp0
, rt
);
10186 tcg_gen_ext_i32_tl(t0
, fp0
);
10187 tcg_temp_free_i32(fp0
);
10191 /* XXX: For now we support only a single FPU context. */
10192 gen_helper_1e0i(cfc1
, t0
, rt
);
10194 /* COP2: Not implemented. */
10202 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10203 gen_store_gpr(t0
, rd
);
10209 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10210 generate_exception_end(ctx
, EXCP_RI
);
10213 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10214 int u
, int sel
, int h
)
10216 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10217 TCGv t0
= tcg_temp_local_new();
10219 gen_load_gpr(t0
, rt
);
10220 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10221 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10222 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10225 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10226 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10229 } else if (u
== 0) {
10234 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10237 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10247 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10250 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10253 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10256 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10259 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10262 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10265 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10268 gen_mtc0(ctx
, t0
, rd
, sel
);
10275 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10278 gen_mtc0(ctx
, t0
, rd
, sel
);
10285 gen_helper_mttc0_status(cpu_env
, t0
);
10288 gen_mtc0(ctx
, t0
, rd
, sel
);
10295 gen_helper_mttc0_cause(cpu_env
, t0
);
10305 gen_helper_mttc0_ebase(cpu_env
, t0
);
10315 gen_helper_mttc0_debug(cpu_env
, t0
);
10318 gen_mtc0(ctx
, t0
, rd
, sel
);
10323 gen_mtc0(ctx
, t0
, rd
, sel
);
10327 /* GPR registers. */
10329 gen_helper_0e1i(mttgpr
, t0
, rd
);
10331 /* Auxiliary CPU registers */
10335 gen_helper_0e1i(mttlo
, t0
, 0);
10338 gen_helper_0e1i(mtthi
, t0
, 0);
10341 gen_helper_0e1i(mttacx
, t0
, 0);
10344 gen_helper_0e1i(mttlo
, t0
, 1);
10347 gen_helper_0e1i(mtthi
, t0
, 1);
10350 gen_helper_0e1i(mttacx
, t0
, 1);
10353 gen_helper_0e1i(mttlo
, t0
, 2);
10356 gen_helper_0e1i(mtthi
, t0
, 2);
10359 gen_helper_0e1i(mttacx
, t0
, 2);
10362 gen_helper_0e1i(mttlo
, t0
, 3);
10365 gen_helper_0e1i(mtthi
, t0
, 3);
10368 gen_helper_0e1i(mttacx
, t0
, 3);
10371 gen_helper_mttdsp(cpu_env
, t0
);
10377 /* Floating point (COP1). */
10379 /* XXX: For now we support only a single FPU context. */
10381 TCGv_i32 fp0
= tcg_temp_new_i32();
10383 tcg_gen_trunc_tl_i32(fp0
, t0
);
10384 gen_store_fpr32(ctx
, fp0
, rd
);
10385 tcg_temp_free_i32(fp0
);
10387 TCGv_i32 fp0
= tcg_temp_new_i32();
10389 tcg_gen_trunc_tl_i32(fp0
, t0
);
10390 gen_store_fpr32h(ctx
, fp0
, rd
);
10391 tcg_temp_free_i32(fp0
);
10395 /* XXX: For now we support only a single FPU context. */
10397 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10399 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10400 tcg_temp_free_i32(fs_tmp
);
10402 /* Stop translation as we may have changed hflags */
10403 ctx
->base
.is_jmp
= DISAS_STOP
;
10405 /* COP2: Not implemented. */
10413 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10419 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10420 generate_exception_end(ctx
, EXCP_RI
);
10423 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10426 const char *opn
= "ldst";
10428 check_cp0_enabled(ctx
);
10432 /* Treat as NOP. */
10435 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10440 TCGv t0
= tcg_temp_new();
10442 gen_load_gpr(t0
, rt
);
10443 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10448 #if defined(TARGET_MIPS64)
10450 check_insn(ctx
, ISA_MIPS3
);
10452 /* Treat as NOP. */
10455 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10459 check_insn(ctx
, ISA_MIPS3
);
10461 TCGv t0
= tcg_temp_new();
10463 gen_load_gpr(t0
, rt
);
10464 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10473 /* Treat as NOP. */
10476 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10482 TCGv t0
= tcg_temp_new();
10483 gen_load_gpr(t0
, rt
);
10484 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10490 check_cp0_enabled(ctx
);
10492 /* Treat as NOP. */
10495 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10496 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10500 check_cp0_enabled(ctx
);
10501 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10502 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10507 if (!env
->tlb
->helper_tlbwi
) {
10510 gen_helper_tlbwi(cpu_env
);
10514 if (ctx
->ie
>= 2) {
10515 if (!env
->tlb
->helper_tlbinv
) {
10518 gen_helper_tlbinv(cpu_env
);
10519 } /* treat as nop if TLBINV not supported */
10523 if (ctx
->ie
>= 2) {
10524 if (!env
->tlb
->helper_tlbinvf
) {
10527 gen_helper_tlbinvf(cpu_env
);
10528 } /* treat as nop if TLBINV not supported */
10532 if (!env
->tlb
->helper_tlbwr
) {
10535 gen_helper_tlbwr(cpu_env
);
10539 if (!env
->tlb
->helper_tlbp
) {
10542 gen_helper_tlbp(cpu_env
);
10546 if (!env
->tlb
->helper_tlbr
) {
10549 gen_helper_tlbr(cpu_env
);
10551 case OPC_ERET
: /* OPC_ERETNC */
10552 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10553 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10556 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10557 if (ctx
->opcode
& (1 << bit_shift
)) {
10560 check_insn(ctx
, ISA_MIPS32R5
);
10561 gen_helper_eretnc(cpu_env
);
10565 check_insn(ctx
, ISA_MIPS2
);
10566 gen_helper_eret(cpu_env
);
10568 ctx
->base
.is_jmp
= DISAS_EXIT
;
10573 check_insn(ctx
, ISA_MIPS32
);
10574 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10575 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10578 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10580 generate_exception_end(ctx
, EXCP_RI
);
10582 gen_helper_deret(cpu_env
);
10583 ctx
->base
.is_jmp
= DISAS_EXIT
;
10588 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
10589 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10590 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10593 /* If we get an exception, we want to restart at next instruction */
10594 ctx
->base
.pc_next
+= 4;
10595 save_cpu_state(ctx
, 1);
10596 ctx
->base
.pc_next
-= 4;
10597 gen_helper_wait(cpu_env
);
10598 ctx
->base
.is_jmp
= DISAS_NORETURN
;
10603 generate_exception_end(ctx
, EXCP_RI
);
10606 (void)opn
; /* avoid a compiler warning */
10608 #endif /* !CONFIG_USER_ONLY */
10610 /* CP1 Branches (before delay slot) */
10611 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
10612 int32_t cc
, int32_t offset
)
10614 target_ulong btarget
;
10615 TCGv_i32 t0
= tcg_temp_new_i32();
10617 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10618 generate_exception_end(ctx
, EXCP_RI
);
10623 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
10626 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
10630 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10631 tcg_gen_not_i32(t0
, t0
);
10632 tcg_gen_andi_i32(t0
, t0
, 1);
10633 tcg_gen_extu_i32_tl(bcond
, t0
);
10636 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10637 tcg_gen_not_i32(t0
, t0
);
10638 tcg_gen_andi_i32(t0
, t0
, 1);
10639 tcg_gen_extu_i32_tl(bcond
, t0
);
10642 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10643 tcg_gen_andi_i32(t0
, t0
, 1);
10644 tcg_gen_extu_i32_tl(bcond
, t0
);
10647 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10648 tcg_gen_andi_i32(t0
, t0
, 1);
10649 tcg_gen_extu_i32_tl(bcond
, t0
);
10651 ctx
->hflags
|= MIPS_HFLAG_BL
;
10655 TCGv_i32 t1
= tcg_temp_new_i32();
10656 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10657 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10658 tcg_gen_nand_i32(t0
, t0
, t1
);
10659 tcg_temp_free_i32(t1
);
10660 tcg_gen_andi_i32(t0
, t0
, 1);
10661 tcg_gen_extu_i32_tl(bcond
, t0
);
10666 TCGv_i32 t1
= tcg_temp_new_i32();
10667 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10668 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10669 tcg_gen_or_i32(t0
, t0
, t1
);
10670 tcg_temp_free_i32(t1
);
10671 tcg_gen_andi_i32(t0
, t0
, 1);
10672 tcg_gen_extu_i32_tl(bcond
, t0
);
10677 TCGv_i32 t1
= tcg_temp_new_i32();
10678 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10679 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10680 tcg_gen_and_i32(t0
, t0
, t1
);
10681 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10682 tcg_gen_and_i32(t0
, t0
, t1
);
10683 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10684 tcg_gen_nand_i32(t0
, t0
, t1
);
10685 tcg_temp_free_i32(t1
);
10686 tcg_gen_andi_i32(t0
, t0
, 1);
10687 tcg_gen_extu_i32_tl(bcond
, t0
);
10692 TCGv_i32 t1
= tcg_temp_new_i32();
10693 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10694 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10695 tcg_gen_or_i32(t0
, t0
, t1
);
10696 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10697 tcg_gen_or_i32(t0
, t0
, t1
);
10698 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10699 tcg_gen_or_i32(t0
, t0
, t1
);
10700 tcg_temp_free_i32(t1
);
10701 tcg_gen_andi_i32(t0
, t0
, 1);
10702 tcg_gen_extu_i32_tl(bcond
, t0
);
10705 ctx
->hflags
|= MIPS_HFLAG_BC
;
10708 MIPS_INVAL("cp1 cond branch");
10709 generate_exception_end(ctx
, EXCP_RI
);
10712 ctx
->btarget
= btarget
;
10713 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10715 tcg_temp_free_i32(t0
);
10718 /* R6 CP1 Branches */
10719 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
10720 int32_t ft
, int32_t offset
,
10721 int delayslot_size
)
10723 target_ulong btarget
;
10724 TCGv_i64 t0
= tcg_temp_new_i64();
10726 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10727 #ifdef MIPS_DEBUG_DISAS
10728 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10729 "\n", ctx
->base
.pc_next
);
10731 generate_exception_end(ctx
, EXCP_RI
);
10735 gen_load_fpr64(ctx
, t0
, ft
);
10736 tcg_gen_andi_i64(t0
, t0
, 1);
10738 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
10742 tcg_gen_xori_i64(t0
, t0
, 1);
10743 ctx
->hflags
|= MIPS_HFLAG_BC
;
10746 /* t0 already set */
10747 ctx
->hflags
|= MIPS_HFLAG_BC
;
10750 MIPS_INVAL("cp1 cond branch");
10751 generate_exception_end(ctx
, EXCP_RI
);
10755 tcg_gen_trunc_i64_tl(bcond
, t0
);
10757 ctx
->btarget
= btarget
;
10759 switch (delayslot_size
) {
10761 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
10764 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10769 tcg_temp_free_i64(t0
);
10772 /* Coprocessor 1 (FPU) */
10774 #define FOP(func, fmt) (((fmt) << 21) | (func))
10777 OPC_ADD_S
= FOP(0, FMT_S
),
10778 OPC_SUB_S
= FOP(1, FMT_S
),
10779 OPC_MUL_S
= FOP(2, FMT_S
),
10780 OPC_DIV_S
= FOP(3, FMT_S
),
10781 OPC_SQRT_S
= FOP(4, FMT_S
),
10782 OPC_ABS_S
= FOP(5, FMT_S
),
10783 OPC_MOV_S
= FOP(6, FMT_S
),
10784 OPC_NEG_S
= FOP(7, FMT_S
),
10785 OPC_ROUND_L_S
= FOP(8, FMT_S
),
10786 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
10787 OPC_CEIL_L_S
= FOP(10, FMT_S
),
10788 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
10789 OPC_ROUND_W_S
= FOP(12, FMT_S
),
10790 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
10791 OPC_CEIL_W_S
= FOP(14, FMT_S
),
10792 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
10793 OPC_SEL_S
= FOP(16, FMT_S
),
10794 OPC_MOVCF_S
= FOP(17, FMT_S
),
10795 OPC_MOVZ_S
= FOP(18, FMT_S
),
10796 OPC_MOVN_S
= FOP(19, FMT_S
),
10797 OPC_SELEQZ_S
= FOP(20, FMT_S
),
10798 OPC_RECIP_S
= FOP(21, FMT_S
),
10799 OPC_RSQRT_S
= FOP(22, FMT_S
),
10800 OPC_SELNEZ_S
= FOP(23, FMT_S
),
10801 OPC_MADDF_S
= FOP(24, FMT_S
),
10802 OPC_MSUBF_S
= FOP(25, FMT_S
),
10803 OPC_RINT_S
= FOP(26, FMT_S
),
10804 OPC_CLASS_S
= FOP(27, FMT_S
),
10805 OPC_MIN_S
= FOP(28, FMT_S
),
10806 OPC_RECIP2_S
= FOP(28, FMT_S
),
10807 OPC_MINA_S
= FOP(29, FMT_S
),
10808 OPC_RECIP1_S
= FOP(29, FMT_S
),
10809 OPC_MAX_S
= FOP(30, FMT_S
),
10810 OPC_RSQRT1_S
= FOP(30, FMT_S
),
10811 OPC_MAXA_S
= FOP(31, FMT_S
),
10812 OPC_RSQRT2_S
= FOP(31, FMT_S
),
10813 OPC_CVT_D_S
= FOP(33, FMT_S
),
10814 OPC_CVT_W_S
= FOP(36, FMT_S
),
10815 OPC_CVT_L_S
= FOP(37, FMT_S
),
10816 OPC_CVT_PS_S
= FOP(38, FMT_S
),
10817 OPC_CMP_F_S
= FOP(48, FMT_S
),
10818 OPC_CMP_UN_S
= FOP(49, FMT_S
),
10819 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
10820 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
10821 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
10822 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
10823 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
10824 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
10825 OPC_CMP_SF_S
= FOP(56, FMT_S
),
10826 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
10827 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
10828 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
10829 OPC_CMP_LT_S
= FOP(60, FMT_S
),
10830 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
10831 OPC_CMP_LE_S
= FOP(62, FMT_S
),
10832 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
10834 OPC_ADD_D
= FOP(0, FMT_D
),
10835 OPC_SUB_D
= FOP(1, FMT_D
),
10836 OPC_MUL_D
= FOP(2, FMT_D
),
10837 OPC_DIV_D
= FOP(3, FMT_D
),
10838 OPC_SQRT_D
= FOP(4, FMT_D
),
10839 OPC_ABS_D
= FOP(5, FMT_D
),
10840 OPC_MOV_D
= FOP(6, FMT_D
),
10841 OPC_NEG_D
= FOP(7, FMT_D
),
10842 OPC_ROUND_L_D
= FOP(8, FMT_D
),
10843 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
10844 OPC_CEIL_L_D
= FOP(10, FMT_D
),
10845 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
10846 OPC_ROUND_W_D
= FOP(12, FMT_D
),
10847 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
10848 OPC_CEIL_W_D
= FOP(14, FMT_D
),
10849 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
10850 OPC_SEL_D
= FOP(16, FMT_D
),
10851 OPC_MOVCF_D
= FOP(17, FMT_D
),
10852 OPC_MOVZ_D
= FOP(18, FMT_D
),
10853 OPC_MOVN_D
= FOP(19, FMT_D
),
10854 OPC_SELEQZ_D
= FOP(20, FMT_D
),
10855 OPC_RECIP_D
= FOP(21, FMT_D
),
10856 OPC_RSQRT_D
= FOP(22, FMT_D
),
10857 OPC_SELNEZ_D
= FOP(23, FMT_D
),
10858 OPC_MADDF_D
= FOP(24, FMT_D
),
10859 OPC_MSUBF_D
= FOP(25, FMT_D
),
10860 OPC_RINT_D
= FOP(26, FMT_D
),
10861 OPC_CLASS_D
= FOP(27, FMT_D
),
10862 OPC_MIN_D
= FOP(28, FMT_D
),
10863 OPC_RECIP2_D
= FOP(28, FMT_D
),
10864 OPC_MINA_D
= FOP(29, FMT_D
),
10865 OPC_RECIP1_D
= FOP(29, FMT_D
),
10866 OPC_MAX_D
= FOP(30, FMT_D
),
10867 OPC_RSQRT1_D
= FOP(30, FMT_D
),
10868 OPC_MAXA_D
= FOP(31, FMT_D
),
10869 OPC_RSQRT2_D
= FOP(31, FMT_D
),
10870 OPC_CVT_S_D
= FOP(32, FMT_D
),
10871 OPC_CVT_W_D
= FOP(36, FMT_D
),
10872 OPC_CVT_L_D
= FOP(37, FMT_D
),
10873 OPC_CMP_F_D
= FOP(48, FMT_D
),
10874 OPC_CMP_UN_D
= FOP(49, FMT_D
),
10875 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
10876 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
10877 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
10878 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
10879 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
10880 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
10881 OPC_CMP_SF_D
= FOP(56, FMT_D
),
10882 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
10883 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
10884 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
10885 OPC_CMP_LT_D
= FOP(60, FMT_D
),
10886 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
10887 OPC_CMP_LE_D
= FOP(62, FMT_D
),
10888 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
10890 OPC_CVT_S_W
= FOP(32, FMT_W
),
10891 OPC_CVT_D_W
= FOP(33, FMT_W
),
10892 OPC_CVT_S_L
= FOP(32, FMT_L
),
10893 OPC_CVT_D_L
= FOP(33, FMT_L
),
10894 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
10896 OPC_ADD_PS
= FOP(0, FMT_PS
),
10897 OPC_SUB_PS
= FOP(1, FMT_PS
),
10898 OPC_MUL_PS
= FOP(2, FMT_PS
),
10899 OPC_DIV_PS
= FOP(3, FMT_PS
),
10900 OPC_ABS_PS
= FOP(5, FMT_PS
),
10901 OPC_MOV_PS
= FOP(6, FMT_PS
),
10902 OPC_NEG_PS
= FOP(7, FMT_PS
),
10903 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
10904 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
10905 OPC_MOVN_PS
= FOP(19, FMT_PS
),
10906 OPC_ADDR_PS
= FOP(24, FMT_PS
),
10907 OPC_MULR_PS
= FOP(26, FMT_PS
),
10908 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
10909 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
10910 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
10911 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
10913 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
10914 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
10915 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
10916 OPC_PLL_PS
= FOP(44, FMT_PS
),
10917 OPC_PLU_PS
= FOP(45, FMT_PS
),
10918 OPC_PUL_PS
= FOP(46, FMT_PS
),
10919 OPC_PUU_PS
= FOP(47, FMT_PS
),
10920 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
10921 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
10922 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
10923 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
10924 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
10925 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
10926 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
10927 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
10928 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
10929 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
10930 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
10931 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
10932 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
10933 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
10934 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
10935 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
10939 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
10940 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
10941 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
10942 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
10943 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
10944 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
10945 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
10946 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
10947 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
10948 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
10949 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
10950 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
10951 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
10952 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
10953 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
10954 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
10955 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
10956 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
10957 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
10958 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
10959 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
10960 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
10962 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
10963 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
10964 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
10965 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
10966 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
10967 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
10968 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
10969 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
10970 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
10971 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
10972 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
10973 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
10974 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
10975 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
10976 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
10977 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
10978 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
10979 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
10980 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
10981 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
10982 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
10983 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
10986 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
10988 TCGv t0
= tcg_temp_new();
10993 TCGv_i32 fp0
= tcg_temp_new_i32();
10995 gen_load_fpr32(ctx
, fp0
, fs
);
10996 tcg_gen_ext_i32_tl(t0
, fp0
);
10997 tcg_temp_free_i32(fp0
);
10999 gen_store_gpr(t0
, rt
);
11002 gen_load_gpr(t0
, rt
);
11004 TCGv_i32 fp0
= tcg_temp_new_i32();
11006 tcg_gen_trunc_tl_i32(fp0
, t0
);
11007 gen_store_fpr32(ctx
, fp0
, fs
);
11008 tcg_temp_free_i32(fp0
);
11012 gen_helper_1e0i(cfc1
, t0
, fs
);
11013 gen_store_gpr(t0
, rt
);
11016 gen_load_gpr(t0
, rt
);
11017 save_cpu_state(ctx
, 0);
11019 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
11021 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
11022 tcg_temp_free_i32(fs_tmp
);
11024 /* Stop translation as we may have changed hflags */
11025 ctx
->base
.is_jmp
= DISAS_STOP
;
11027 #if defined(TARGET_MIPS64)
11029 gen_load_fpr64(ctx
, t0
, fs
);
11030 gen_store_gpr(t0
, rt
);
11033 gen_load_gpr(t0
, rt
);
11034 gen_store_fpr64(ctx
, t0
, fs
);
11039 TCGv_i32 fp0
= tcg_temp_new_i32();
11041 gen_load_fpr32h(ctx
, fp0
, fs
);
11042 tcg_gen_ext_i32_tl(t0
, fp0
);
11043 tcg_temp_free_i32(fp0
);
11045 gen_store_gpr(t0
, rt
);
11048 gen_load_gpr(t0
, rt
);
11050 TCGv_i32 fp0
= tcg_temp_new_i32();
11052 tcg_gen_trunc_tl_i32(fp0
, t0
);
11053 gen_store_fpr32h(ctx
, fp0
, fs
);
11054 tcg_temp_free_i32(fp0
);
11058 MIPS_INVAL("cp1 move");
11059 generate_exception_end(ctx
, EXCP_RI
);
11067 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
11074 /* Treat as NOP. */
11079 cond
= TCG_COND_EQ
;
11081 cond
= TCG_COND_NE
;
11084 l1
= gen_new_label();
11085 t0
= tcg_temp_new_i32();
11086 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11087 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11088 tcg_temp_free_i32(t0
);
11090 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
11092 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
11097 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11101 TCGv_i32 t0
= tcg_temp_new_i32();
11102 TCGLabel
*l1
= gen_new_label();
11105 cond
= TCG_COND_EQ
;
11107 cond
= TCG_COND_NE
;
11110 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11111 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11112 gen_load_fpr32(ctx
, t0
, fs
);
11113 gen_store_fpr32(ctx
, t0
, fd
);
11115 tcg_temp_free_i32(t0
);
11118 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11122 TCGv_i32 t0
= tcg_temp_new_i32();
11124 TCGLabel
*l1
= gen_new_label();
11127 cond
= TCG_COND_EQ
;
11129 cond
= TCG_COND_NE
;
11132 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11133 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11134 tcg_temp_free_i32(t0
);
11135 fp0
= tcg_temp_new_i64();
11136 gen_load_fpr64(ctx
, fp0
, fs
);
11137 gen_store_fpr64(ctx
, fp0
, fd
);
11138 tcg_temp_free_i64(fp0
);
11142 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
11146 TCGv_i32 t0
= tcg_temp_new_i32();
11147 TCGLabel
*l1
= gen_new_label();
11148 TCGLabel
*l2
= gen_new_label();
11151 cond
= TCG_COND_EQ
;
11153 cond
= TCG_COND_NE
;
11156 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11157 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11158 gen_load_fpr32(ctx
, t0
, fs
);
11159 gen_store_fpr32(ctx
, t0
, fd
);
11162 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
11163 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
11164 gen_load_fpr32h(ctx
, t0
, fs
);
11165 gen_store_fpr32h(ctx
, t0
, fd
);
11166 tcg_temp_free_i32(t0
);
11170 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11173 TCGv_i32 t1
= tcg_const_i32(0);
11174 TCGv_i32 fp0
= tcg_temp_new_i32();
11175 TCGv_i32 fp1
= tcg_temp_new_i32();
11176 TCGv_i32 fp2
= tcg_temp_new_i32();
11177 gen_load_fpr32(ctx
, fp0
, fd
);
11178 gen_load_fpr32(ctx
, fp1
, ft
);
11179 gen_load_fpr32(ctx
, fp2
, fs
);
11183 tcg_gen_andi_i32(fp0
, fp0
, 1);
11184 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11187 tcg_gen_andi_i32(fp1
, fp1
, 1);
11188 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11191 tcg_gen_andi_i32(fp1
, fp1
, 1);
11192 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11195 MIPS_INVAL("gen_sel_s");
11196 generate_exception_end(ctx
, EXCP_RI
);
11200 gen_store_fpr32(ctx
, fp0
, fd
);
11201 tcg_temp_free_i32(fp2
);
11202 tcg_temp_free_i32(fp1
);
11203 tcg_temp_free_i32(fp0
);
11204 tcg_temp_free_i32(t1
);
11207 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11210 TCGv_i64 t1
= tcg_const_i64(0);
11211 TCGv_i64 fp0
= tcg_temp_new_i64();
11212 TCGv_i64 fp1
= tcg_temp_new_i64();
11213 TCGv_i64 fp2
= tcg_temp_new_i64();
11214 gen_load_fpr64(ctx
, fp0
, fd
);
11215 gen_load_fpr64(ctx
, fp1
, ft
);
11216 gen_load_fpr64(ctx
, fp2
, fs
);
11220 tcg_gen_andi_i64(fp0
, fp0
, 1);
11221 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11224 tcg_gen_andi_i64(fp1
, fp1
, 1);
11225 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11228 tcg_gen_andi_i64(fp1
, fp1
, 1);
11229 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11232 MIPS_INVAL("gen_sel_d");
11233 generate_exception_end(ctx
, EXCP_RI
);
11237 gen_store_fpr64(ctx
, fp0
, fd
);
11238 tcg_temp_free_i64(fp2
);
11239 tcg_temp_free_i64(fp1
);
11240 tcg_temp_free_i64(fp0
);
11241 tcg_temp_free_i64(t1
);
11244 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11245 int ft
, int fs
, int fd
, int cc
)
11247 uint32_t func
= ctx
->opcode
& 0x3f;
11251 TCGv_i32 fp0
= tcg_temp_new_i32();
11252 TCGv_i32 fp1
= tcg_temp_new_i32();
11254 gen_load_fpr32(ctx
, fp0
, fs
);
11255 gen_load_fpr32(ctx
, fp1
, ft
);
11256 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11257 tcg_temp_free_i32(fp1
);
11258 gen_store_fpr32(ctx
, fp0
, fd
);
11259 tcg_temp_free_i32(fp0
);
11264 TCGv_i32 fp0
= tcg_temp_new_i32();
11265 TCGv_i32 fp1
= tcg_temp_new_i32();
11267 gen_load_fpr32(ctx
, fp0
, fs
);
11268 gen_load_fpr32(ctx
, fp1
, ft
);
11269 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11270 tcg_temp_free_i32(fp1
);
11271 gen_store_fpr32(ctx
, fp0
, fd
);
11272 tcg_temp_free_i32(fp0
);
11277 TCGv_i32 fp0
= tcg_temp_new_i32();
11278 TCGv_i32 fp1
= tcg_temp_new_i32();
11280 gen_load_fpr32(ctx
, fp0
, fs
);
11281 gen_load_fpr32(ctx
, fp1
, ft
);
11282 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11283 tcg_temp_free_i32(fp1
);
11284 gen_store_fpr32(ctx
, fp0
, fd
);
11285 tcg_temp_free_i32(fp0
);
11290 TCGv_i32 fp0
= tcg_temp_new_i32();
11291 TCGv_i32 fp1
= tcg_temp_new_i32();
11293 gen_load_fpr32(ctx
, fp0
, fs
);
11294 gen_load_fpr32(ctx
, fp1
, ft
);
11295 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11296 tcg_temp_free_i32(fp1
);
11297 gen_store_fpr32(ctx
, fp0
, fd
);
11298 tcg_temp_free_i32(fp0
);
11303 TCGv_i32 fp0
= tcg_temp_new_i32();
11305 gen_load_fpr32(ctx
, fp0
, fs
);
11306 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11307 gen_store_fpr32(ctx
, fp0
, fd
);
11308 tcg_temp_free_i32(fp0
);
11313 TCGv_i32 fp0
= tcg_temp_new_i32();
11315 gen_load_fpr32(ctx
, fp0
, fs
);
11316 if (ctx
->abs2008
) {
11317 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11319 gen_helper_float_abs_s(fp0
, fp0
);
11321 gen_store_fpr32(ctx
, fp0
, fd
);
11322 tcg_temp_free_i32(fp0
);
11327 TCGv_i32 fp0
= tcg_temp_new_i32();
11329 gen_load_fpr32(ctx
, fp0
, fs
);
11330 gen_store_fpr32(ctx
, fp0
, fd
);
11331 tcg_temp_free_i32(fp0
);
11336 TCGv_i32 fp0
= tcg_temp_new_i32();
11338 gen_load_fpr32(ctx
, fp0
, fs
);
11339 if (ctx
->abs2008
) {
11340 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11342 gen_helper_float_chs_s(fp0
, fp0
);
11344 gen_store_fpr32(ctx
, fp0
, fd
);
11345 tcg_temp_free_i32(fp0
);
11348 case OPC_ROUND_L_S
:
11349 check_cp1_64bitmode(ctx
);
11351 TCGv_i32 fp32
= tcg_temp_new_i32();
11352 TCGv_i64 fp64
= tcg_temp_new_i64();
11354 gen_load_fpr32(ctx
, fp32
, fs
);
11355 if (ctx
->nan2008
) {
11356 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11358 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11360 tcg_temp_free_i32(fp32
);
11361 gen_store_fpr64(ctx
, fp64
, fd
);
11362 tcg_temp_free_i64(fp64
);
11365 case OPC_TRUNC_L_S
:
11366 check_cp1_64bitmode(ctx
);
11368 TCGv_i32 fp32
= tcg_temp_new_i32();
11369 TCGv_i64 fp64
= tcg_temp_new_i64();
11371 gen_load_fpr32(ctx
, fp32
, fs
);
11372 if (ctx
->nan2008
) {
11373 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11375 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11377 tcg_temp_free_i32(fp32
);
11378 gen_store_fpr64(ctx
, fp64
, fd
);
11379 tcg_temp_free_i64(fp64
);
11383 check_cp1_64bitmode(ctx
);
11385 TCGv_i32 fp32
= tcg_temp_new_i32();
11386 TCGv_i64 fp64
= tcg_temp_new_i64();
11388 gen_load_fpr32(ctx
, fp32
, fs
);
11389 if (ctx
->nan2008
) {
11390 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11392 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11394 tcg_temp_free_i32(fp32
);
11395 gen_store_fpr64(ctx
, fp64
, fd
);
11396 tcg_temp_free_i64(fp64
);
11399 case OPC_FLOOR_L_S
:
11400 check_cp1_64bitmode(ctx
);
11402 TCGv_i32 fp32
= tcg_temp_new_i32();
11403 TCGv_i64 fp64
= tcg_temp_new_i64();
11405 gen_load_fpr32(ctx
, fp32
, fs
);
11406 if (ctx
->nan2008
) {
11407 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11409 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11411 tcg_temp_free_i32(fp32
);
11412 gen_store_fpr64(ctx
, fp64
, fd
);
11413 tcg_temp_free_i64(fp64
);
11416 case OPC_ROUND_W_S
:
11418 TCGv_i32 fp0
= tcg_temp_new_i32();
11420 gen_load_fpr32(ctx
, fp0
, fs
);
11421 if (ctx
->nan2008
) {
11422 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11424 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11426 gen_store_fpr32(ctx
, fp0
, fd
);
11427 tcg_temp_free_i32(fp0
);
11430 case OPC_TRUNC_W_S
:
11432 TCGv_i32 fp0
= tcg_temp_new_i32();
11434 gen_load_fpr32(ctx
, fp0
, fs
);
11435 if (ctx
->nan2008
) {
11436 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11438 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11440 gen_store_fpr32(ctx
, fp0
, fd
);
11441 tcg_temp_free_i32(fp0
);
11446 TCGv_i32 fp0
= tcg_temp_new_i32();
11448 gen_load_fpr32(ctx
, fp0
, fs
);
11449 if (ctx
->nan2008
) {
11450 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11452 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11454 gen_store_fpr32(ctx
, fp0
, fd
);
11455 tcg_temp_free_i32(fp0
);
11458 case OPC_FLOOR_W_S
:
11460 TCGv_i32 fp0
= tcg_temp_new_i32();
11462 gen_load_fpr32(ctx
, fp0
, fs
);
11463 if (ctx
->nan2008
) {
11464 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11466 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11468 gen_store_fpr32(ctx
, fp0
, fd
);
11469 tcg_temp_free_i32(fp0
);
11473 check_insn(ctx
, ISA_MIPS32R6
);
11474 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11477 check_insn(ctx
, ISA_MIPS32R6
);
11478 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11481 check_insn(ctx
, ISA_MIPS32R6
);
11482 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11485 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11486 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11489 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11491 TCGLabel
*l1
= gen_new_label();
11495 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11497 fp0
= tcg_temp_new_i32();
11498 gen_load_fpr32(ctx
, fp0
, fs
);
11499 gen_store_fpr32(ctx
, fp0
, fd
);
11500 tcg_temp_free_i32(fp0
);
11505 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11507 TCGLabel
*l1
= gen_new_label();
11511 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11512 fp0
= tcg_temp_new_i32();
11513 gen_load_fpr32(ctx
, fp0
, fs
);
11514 gen_store_fpr32(ctx
, fp0
, fd
);
11515 tcg_temp_free_i32(fp0
);
11522 TCGv_i32 fp0
= tcg_temp_new_i32();
11524 gen_load_fpr32(ctx
, fp0
, fs
);
11525 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11526 gen_store_fpr32(ctx
, fp0
, fd
);
11527 tcg_temp_free_i32(fp0
);
11532 TCGv_i32 fp0
= tcg_temp_new_i32();
11534 gen_load_fpr32(ctx
, fp0
, fs
);
11535 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11536 gen_store_fpr32(ctx
, fp0
, fd
);
11537 tcg_temp_free_i32(fp0
);
11541 check_insn(ctx
, ISA_MIPS32R6
);
11543 TCGv_i32 fp0
= tcg_temp_new_i32();
11544 TCGv_i32 fp1
= tcg_temp_new_i32();
11545 TCGv_i32 fp2
= tcg_temp_new_i32();
11546 gen_load_fpr32(ctx
, fp0
, fs
);
11547 gen_load_fpr32(ctx
, fp1
, ft
);
11548 gen_load_fpr32(ctx
, fp2
, fd
);
11549 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11550 gen_store_fpr32(ctx
, fp2
, fd
);
11551 tcg_temp_free_i32(fp2
);
11552 tcg_temp_free_i32(fp1
);
11553 tcg_temp_free_i32(fp0
);
11557 check_insn(ctx
, ISA_MIPS32R6
);
11559 TCGv_i32 fp0
= tcg_temp_new_i32();
11560 TCGv_i32 fp1
= tcg_temp_new_i32();
11561 TCGv_i32 fp2
= tcg_temp_new_i32();
11562 gen_load_fpr32(ctx
, fp0
, fs
);
11563 gen_load_fpr32(ctx
, fp1
, ft
);
11564 gen_load_fpr32(ctx
, fp2
, fd
);
11565 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11566 gen_store_fpr32(ctx
, fp2
, fd
);
11567 tcg_temp_free_i32(fp2
);
11568 tcg_temp_free_i32(fp1
);
11569 tcg_temp_free_i32(fp0
);
11573 check_insn(ctx
, ISA_MIPS32R6
);
11575 TCGv_i32 fp0
= tcg_temp_new_i32();
11576 gen_load_fpr32(ctx
, fp0
, fs
);
11577 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
11578 gen_store_fpr32(ctx
, fp0
, fd
);
11579 tcg_temp_free_i32(fp0
);
11583 check_insn(ctx
, ISA_MIPS32R6
);
11585 TCGv_i32 fp0
= tcg_temp_new_i32();
11586 gen_load_fpr32(ctx
, fp0
, fs
);
11587 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
11588 gen_store_fpr32(ctx
, fp0
, fd
);
11589 tcg_temp_free_i32(fp0
);
11592 case OPC_MIN_S
: /* OPC_RECIP2_S */
11593 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11595 TCGv_i32 fp0
= tcg_temp_new_i32();
11596 TCGv_i32 fp1
= tcg_temp_new_i32();
11597 TCGv_i32 fp2
= tcg_temp_new_i32();
11598 gen_load_fpr32(ctx
, fp0
, fs
);
11599 gen_load_fpr32(ctx
, fp1
, ft
);
11600 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
11601 gen_store_fpr32(ctx
, fp2
, fd
);
11602 tcg_temp_free_i32(fp2
);
11603 tcg_temp_free_i32(fp1
);
11604 tcg_temp_free_i32(fp0
);
11607 check_cp1_64bitmode(ctx
);
11609 TCGv_i32 fp0
= tcg_temp_new_i32();
11610 TCGv_i32 fp1
= tcg_temp_new_i32();
11612 gen_load_fpr32(ctx
, fp0
, fs
);
11613 gen_load_fpr32(ctx
, fp1
, ft
);
11614 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
11615 tcg_temp_free_i32(fp1
);
11616 gen_store_fpr32(ctx
, fp0
, fd
);
11617 tcg_temp_free_i32(fp0
);
11621 case OPC_MINA_S
: /* OPC_RECIP1_S */
11622 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11624 TCGv_i32 fp0
= tcg_temp_new_i32();
11625 TCGv_i32 fp1
= tcg_temp_new_i32();
11626 TCGv_i32 fp2
= tcg_temp_new_i32();
11627 gen_load_fpr32(ctx
, fp0
, fs
);
11628 gen_load_fpr32(ctx
, fp1
, ft
);
11629 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
11630 gen_store_fpr32(ctx
, fp2
, fd
);
11631 tcg_temp_free_i32(fp2
);
11632 tcg_temp_free_i32(fp1
);
11633 tcg_temp_free_i32(fp0
);
11636 check_cp1_64bitmode(ctx
);
11638 TCGv_i32 fp0
= tcg_temp_new_i32();
11640 gen_load_fpr32(ctx
, fp0
, fs
);
11641 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
11642 gen_store_fpr32(ctx
, fp0
, fd
);
11643 tcg_temp_free_i32(fp0
);
11647 case OPC_MAX_S
: /* OPC_RSQRT1_S */
11648 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11650 TCGv_i32 fp0
= tcg_temp_new_i32();
11651 TCGv_i32 fp1
= tcg_temp_new_i32();
11652 gen_load_fpr32(ctx
, fp0
, fs
);
11653 gen_load_fpr32(ctx
, fp1
, ft
);
11654 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
11655 gen_store_fpr32(ctx
, fp1
, fd
);
11656 tcg_temp_free_i32(fp1
);
11657 tcg_temp_free_i32(fp0
);
11660 check_cp1_64bitmode(ctx
);
11662 TCGv_i32 fp0
= tcg_temp_new_i32();
11664 gen_load_fpr32(ctx
, fp0
, fs
);
11665 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
11666 gen_store_fpr32(ctx
, fp0
, fd
);
11667 tcg_temp_free_i32(fp0
);
11671 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
11672 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11674 TCGv_i32 fp0
= tcg_temp_new_i32();
11675 TCGv_i32 fp1
= tcg_temp_new_i32();
11676 gen_load_fpr32(ctx
, fp0
, fs
);
11677 gen_load_fpr32(ctx
, fp1
, ft
);
11678 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
11679 gen_store_fpr32(ctx
, fp1
, fd
);
11680 tcg_temp_free_i32(fp1
);
11681 tcg_temp_free_i32(fp0
);
11684 check_cp1_64bitmode(ctx
);
11686 TCGv_i32 fp0
= tcg_temp_new_i32();
11687 TCGv_i32 fp1
= tcg_temp_new_i32();
11689 gen_load_fpr32(ctx
, fp0
, fs
);
11690 gen_load_fpr32(ctx
, fp1
, ft
);
11691 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
11692 tcg_temp_free_i32(fp1
);
11693 gen_store_fpr32(ctx
, fp0
, fd
);
11694 tcg_temp_free_i32(fp0
);
11699 check_cp1_registers(ctx
, fd
);
11701 TCGv_i32 fp32
= tcg_temp_new_i32();
11702 TCGv_i64 fp64
= tcg_temp_new_i64();
11704 gen_load_fpr32(ctx
, fp32
, fs
);
11705 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
11706 tcg_temp_free_i32(fp32
);
11707 gen_store_fpr64(ctx
, fp64
, fd
);
11708 tcg_temp_free_i64(fp64
);
11713 TCGv_i32 fp0
= tcg_temp_new_i32();
11715 gen_load_fpr32(ctx
, fp0
, fs
);
11716 if (ctx
->nan2008
) {
11717 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
11719 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
11721 gen_store_fpr32(ctx
, fp0
, fd
);
11722 tcg_temp_free_i32(fp0
);
11726 check_cp1_64bitmode(ctx
);
11728 TCGv_i32 fp32
= tcg_temp_new_i32();
11729 TCGv_i64 fp64
= tcg_temp_new_i64();
11731 gen_load_fpr32(ctx
, fp32
, fs
);
11732 if (ctx
->nan2008
) {
11733 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
11735 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
11737 tcg_temp_free_i32(fp32
);
11738 gen_store_fpr64(ctx
, fp64
, fd
);
11739 tcg_temp_free_i64(fp64
);
11745 TCGv_i64 fp64
= tcg_temp_new_i64();
11746 TCGv_i32 fp32_0
= tcg_temp_new_i32();
11747 TCGv_i32 fp32_1
= tcg_temp_new_i32();
11749 gen_load_fpr32(ctx
, fp32_0
, fs
);
11750 gen_load_fpr32(ctx
, fp32_1
, ft
);
11751 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
11752 tcg_temp_free_i32(fp32_1
);
11753 tcg_temp_free_i32(fp32_0
);
11754 gen_store_fpr64(ctx
, fp64
, fd
);
11755 tcg_temp_free_i64(fp64
);
11761 case OPC_CMP_UEQ_S
:
11762 case OPC_CMP_OLT_S
:
11763 case OPC_CMP_ULT_S
:
11764 case OPC_CMP_OLE_S
:
11765 case OPC_CMP_ULE_S
:
11767 case OPC_CMP_NGLE_S
:
11768 case OPC_CMP_SEQ_S
:
11769 case OPC_CMP_NGL_S
:
11771 case OPC_CMP_NGE_S
:
11773 case OPC_CMP_NGT_S
:
11774 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11775 if (ctx
->opcode
& (1 << 6)) {
11776 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
11778 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
11782 check_cp1_registers(ctx
, fs
| ft
| fd
);
11784 TCGv_i64 fp0
= tcg_temp_new_i64();
11785 TCGv_i64 fp1
= tcg_temp_new_i64();
11787 gen_load_fpr64(ctx
, fp0
, fs
);
11788 gen_load_fpr64(ctx
, fp1
, ft
);
11789 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
11790 tcg_temp_free_i64(fp1
);
11791 gen_store_fpr64(ctx
, fp0
, fd
);
11792 tcg_temp_free_i64(fp0
);
11796 check_cp1_registers(ctx
, fs
| ft
| fd
);
11798 TCGv_i64 fp0
= tcg_temp_new_i64();
11799 TCGv_i64 fp1
= tcg_temp_new_i64();
11801 gen_load_fpr64(ctx
, fp0
, fs
);
11802 gen_load_fpr64(ctx
, fp1
, ft
);
11803 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
11804 tcg_temp_free_i64(fp1
);
11805 gen_store_fpr64(ctx
, fp0
, fd
);
11806 tcg_temp_free_i64(fp0
);
11810 check_cp1_registers(ctx
, fs
| ft
| fd
);
11812 TCGv_i64 fp0
= tcg_temp_new_i64();
11813 TCGv_i64 fp1
= tcg_temp_new_i64();
11815 gen_load_fpr64(ctx
, fp0
, fs
);
11816 gen_load_fpr64(ctx
, fp1
, ft
);
11817 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
11818 tcg_temp_free_i64(fp1
);
11819 gen_store_fpr64(ctx
, fp0
, fd
);
11820 tcg_temp_free_i64(fp0
);
11824 check_cp1_registers(ctx
, fs
| ft
| fd
);
11826 TCGv_i64 fp0
= tcg_temp_new_i64();
11827 TCGv_i64 fp1
= tcg_temp_new_i64();
11829 gen_load_fpr64(ctx
, fp0
, fs
);
11830 gen_load_fpr64(ctx
, fp1
, ft
);
11831 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
11832 tcg_temp_free_i64(fp1
);
11833 gen_store_fpr64(ctx
, fp0
, fd
);
11834 tcg_temp_free_i64(fp0
);
11838 check_cp1_registers(ctx
, fs
| fd
);
11840 TCGv_i64 fp0
= tcg_temp_new_i64();
11842 gen_load_fpr64(ctx
, fp0
, fs
);
11843 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
11844 gen_store_fpr64(ctx
, fp0
, fd
);
11845 tcg_temp_free_i64(fp0
);
11849 check_cp1_registers(ctx
, fs
| fd
);
11851 TCGv_i64 fp0
= tcg_temp_new_i64();
11853 gen_load_fpr64(ctx
, fp0
, fs
);
11854 if (ctx
->abs2008
) {
11855 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
11857 gen_helper_float_abs_d(fp0
, fp0
);
11859 gen_store_fpr64(ctx
, fp0
, fd
);
11860 tcg_temp_free_i64(fp0
);
11864 check_cp1_registers(ctx
, fs
| fd
);
11866 TCGv_i64 fp0
= tcg_temp_new_i64();
11868 gen_load_fpr64(ctx
, fp0
, fs
);
11869 gen_store_fpr64(ctx
, fp0
, fd
);
11870 tcg_temp_free_i64(fp0
);
11874 check_cp1_registers(ctx
, fs
| fd
);
11876 TCGv_i64 fp0
= tcg_temp_new_i64();
11878 gen_load_fpr64(ctx
, fp0
, fs
);
11879 if (ctx
->abs2008
) {
11880 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
11882 gen_helper_float_chs_d(fp0
, fp0
);
11884 gen_store_fpr64(ctx
, fp0
, fd
);
11885 tcg_temp_free_i64(fp0
);
11888 case OPC_ROUND_L_D
:
11889 check_cp1_64bitmode(ctx
);
11891 TCGv_i64 fp0
= tcg_temp_new_i64();
11893 gen_load_fpr64(ctx
, fp0
, fs
);
11894 if (ctx
->nan2008
) {
11895 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
11897 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
11899 gen_store_fpr64(ctx
, fp0
, fd
);
11900 tcg_temp_free_i64(fp0
);
11903 case OPC_TRUNC_L_D
:
11904 check_cp1_64bitmode(ctx
);
11906 TCGv_i64 fp0
= tcg_temp_new_i64();
11908 gen_load_fpr64(ctx
, fp0
, fs
);
11909 if (ctx
->nan2008
) {
11910 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
11912 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
11914 gen_store_fpr64(ctx
, fp0
, fd
);
11915 tcg_temp_free_i64(fp0
);
11919 check_cp1_64bitmode(ctx
);
11921 TCGv_i64 fp0
= tcg_temp_new_i64();
11923 gen_load_fpr64(ctx
, fp0
, fs
);
11924 if (ctx
->nan2008
) {
11925 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
11927 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
11929 gen_store_fpr64(ctx
, fp0
, fd
);
11930 tcg_temp_free_i64(fp0
);
11933 case OPC_FLOOR_L_D
:
11934 check_cp1_64bitmode(ctx
);
11936 TCGv_i64 fp0
= tcg_temp_new_i64();
11938 gen_load_fpr64(ctx
, fp0
, fs
);
11939 if (ctx
->nan2008
) {
11940 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
11942 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
11944 gen_store_fpr64(ctx
, fp0
, fd
);
11945 tcg_temp_free_i64(fp0
);
11948 case OPC_ROUND_W_D
:
11949 check_cp1_registers(ctx
, fs
);
11951 TCGv_i32 fp32
= tcg_temp_new_i32();
11952 TCGv_i64 fp64
= tcg_temp_new_i64();
11954 gen_load_fpr64(ctx
, fp64
, fs
);
11955 if (ctx
->nan2008
) {
11956 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
11958 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
11960 tcg_temp_free_i64(fp64
);
11961 gen_store_fpr32(ctx
, fp32
, fd
);
11962 tcg_temp_free_i32(fp32
);
11965 case OPC_TRUNC_W_D
:
11966 check_cp1_registers(ctx
, fs
);
11968 TCGv_i32 fp32
= tcg_temp_new_i32();
11969 TCGv_i64 fp64
= tcg_temp_new_i64();
11971 gen_load_fpr64(ctx
, fp64
, fs
);
11972 if (ctx
->nan2008
) {
11973 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
11975 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
11977 tcg_temp_free_i64(fp64
);
11978 gen_store_fpr32(ctx
, fp32
, fd
);
11979 tcg_temp_free_i32(fp32
);
11983 check_cp1_registers(ctx
, fs
);
11985 TCGv_i32 fp32
= tcg_temp_new_i32();
11986 TCGv_i64 fp64
= tcg_temp_new_i64();
11988 gen_load_fpr64(ctx
, fp64
, fs
);
11989 if (ctx
->nan2008
) {
11990 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
11992 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
11994 tcg_temp_free_i64(fp64
);
11995 gen_store_fpr32(ctx
, fp32
, fd
);
11996 tcg_temp_free_i32(fp32
);
11999 case OPC_FLOOR_W_D
:
12000 check_cp1_registers(ctx
, fs
);
12002 TCGv_i32 fp32
= tcg_temp_new_i32();
12003 TCGv_i64 fp64
= tcg_temp_new_i64();
12005 gen_load_fpr64(ctx
, fp64
, fs
);
12006 if (ctx
->nan2008
) {
12007 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
12009 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
12011 tcg_temp_free_i64(fp64
);
12012 gen_store_fpr32(ctx
, fp32
, fd
);
12013 tcg_temp_free_i32(fp32
);
12017 check_insn(ctx
, ISA_MIPS32R6
);
12018 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12021 check_insn(ctx
, ISA_MIPS32R6
);
12022 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12025 check_insn(ctx
, ISA_MIPS32R6
);
12026 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12029 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12030 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12033 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12035 TCGLabel
*l1
= gen_new_label();
12039 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12041 fp0
= tcg_temp_new_i64();
12042 gen_load_fpr64(ctx
, fp0
, fs
);
12043 gen_store_fpr64(ctx
, fp0
, fd
);
12044 tcg_temp_free_i64(fp0
);
12049 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12051 TCGLabel
*l1
= gen_new_label();
12055 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12056 fp0
= tcg_temp_new_i64();
12057 gen_load_fpr64(ctx
, fp0
, fs
);
12058 gen_store_fpr64(ctx
, fp0
, fd
);
12059 tcg_temp_free_i64(fp0
);
12065 check_cp1_registers(ctx
, fs
| fd
);
12067 TCGv_i64 fp0
= tcg_temp_new_i64();
12069 gen_load_fpr64(ctx
, fp0
, fs
);
12070 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
12071 gen_store_fpr64(ctx
, fp0
, fd
);
12072 tcg_temp_free_i64(fp0
);
12076 check_cp1_registers(ctx
, fs
| fd
);
12078 TCGv_i64 fp0
= tcg_temp_new_i64();
12080 gen_load_fpr64(ctx
, fp0
, fs
);
12081 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
12082 gen_store_fpr64(ctx
, fp0
, fd
);
12083 tcg_temp_free_i64(fp0
);
12087 check_insn(ctx
, ISA_MIPS32R6
);
12089 TCGv_i64 fp0
= tcg_temp_new_i64();
12090 TCGv_i64 fp1
= tcg_temp_new_i64();
12091 TCGv_i64 fp2
= tcg_temp_new_i64();
12092 gen_load_fpr64(ctx
, fp0
, fs
);
12093 gen_load_fpr64(ctx
, fp1
, ft
);
12094 gen_load_fpr64(ctx
, fp2
, fd
);
12095 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12096 gen_store_fpr64(ctx
, fp2
, fd
);
12097 tcg_temp_free_i64(fp2
);
12098 tcg_temp_free_i64(fp1
);
12099 tcg_temp_free_i64(fp0
);
12103 check_insn(ctx
, ISA_MIPS32R6
);
12105 TCGv_i64 fp0
= tcg_temp_new_i64();
12106 TCGv_i64 fp1
= tcg_temp_new_i64();
12107 TCGv_i64 fp2
= tcg_temp_new_i64();
12108 gen_load_fpr64(ctx
, fp0
, fs
);
12109 gen_load_fpr64(ctx
, fp1
, ft
);
12110 gen_load_fpr64(ctx
, fp2
, fd
);
12111 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12112 gen_store_fpr64(ctx
, fp2
, fd
);
12113 tcg_temp_free_i64(fp2
);
12114 tcg_temp_free_i64(fp1
);
12115 tcg_temp_free_i64(fp0
);
12119 check_insn(ctx
, ISA_MIPS32R6
);
12121 TCGv_i64 fp0
= tcg_temp_new_i64();
12122 gen_load_fpr64(ctx
, fp0
, fs
);
12123 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
12124 gen_store_fpr64(ctx
, fp0
, fd
);
12125 tcg_temp_free_i64(fp0
);
12129 check_insn(ctx
, ISA_MIPS32R6
);
12131 TCGv_i64 fp0
= tcg_temp_new_i64();
12132 gen_load_fpr64(ctx
, fp0
, fs
);
12133 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
12134 gen_store_fpr64(ctx
, fp0
, fd
);
12135 tcg_temp_free_i64(fp0
);
12138 case OPC_MIN_D
: /* OPC_RECIP2_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_min_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();
12154 TCGv_i64 fp1
= tcg_temp_new_i64();
12156 gen_load_fpr64(ctx
, fp0
, fs
);
12157 gen_load_fpr64(ctx
, fp1
, ft
);
12158 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
12159 tcg_temp_free_i64(fp1
);
12160 gen_store_fpr64(ctx
, fp0
, fd
);
12161 tcg_temp_free_i64(fp0
);
12165 case OPC_MINA_D
: /* OPC_RECIP1_D */
12166 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12168 TCGv_i64 fp0
= tcg_temp_new_i64();
12169 TCGv_i64 fp1
= tcg_temp_new_i64();
12170 gen_load_fpr64(ctx
, fp0
, fs
);
12171 gen_load_fpr64(ctx
, fp1
, ft
);
12172 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
12173 gen_store_fpr64(ctx
, fp1
, fd
);
12174 tcg_temp_free_i64(fp1
);
12175 tcg_temp_free_i64(fp0
);
12178 check_cp1_64bitmode(ctx
);
12180 TCGv_i64 fp0
= tcg_temp_new_i64();
12182 gen_load_fpr64(ctx
, fp0
, fs
);
12183 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12184 gen_store_fpr64(ctx
, fp0
, fd
);
12185 tcg_temp_free_i64(fp0
);
12189 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12190 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12192 TCGv_i64 fp0
= tcg_temp_new_i64();
12193 TCGv_i64 fp1
= tcg_temp_new_i64();
12194 gen_load_fpr64(ctx
, fp0
, fs
);
12195 gen_load_fpr64(ctx
, fp1
, ft
);
12196 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12197 gen_store_fpr64(ctx
, fp1
, fd
);
12198 tcg_temp_free_i64(fp1
);
12199 tcg_temp_free_i64(fp0
);
12202 check_cp1_64bitmode(ctx
);
12204 TCGv_i64 fp0
= tcg_temp_new_i64();
12206 gen_load_fpr64(ctx
, fp0
, fs
);
12207 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12208 gen_store_fpr64(ctx
, fp0
, fd
);
12209 tcg_temp_free_i64(fp0
);
12213 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12214 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12216 TCGv_i64 fp0
= tcg_temp_new_i64();
12217 TCGv_i64 fp1
= tcg_temp_new_i64();
12218 gen_load_fpr64(ctx
, fp0
, fs
);
12219 gen_load_fpr64(ctx
, fp1
, ft
);
12220 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12221 gen_store_fpr64(ctx
, fp1
, fd
);
12222 tcg_temp_free_i64(fp1
);
12223 tcg_temp_free_i64(fp0
);
12226 check_cp1_64bitmode(ctx
);
12228 TCGv_i64 fp0
= tcg_temp_new_i64();
12229 TCGv_i64 fp1
= tcg_temp_new_i64();
12231 gen_load_fpr64(ctx
, fp0
, fs
);
12232 gen_load_fpr64(ctx
, fp1
, ft
);
12233 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12234 tcg_temp_free_i64(fp1
);
12235 gen_store_fpr64(ctx
, fp0
, fd
);
12236 tcg_temp_free_i64(fp0
);
12243 case OPC_CMP_UEQ_D
:
12244 case OPC_CMP_OLT_D
:
12245 case OPC_CMP_ULT_D
:
12246 case OPC_CMP_OLE_D
:
12247 case OPC_CMP_ULE_D
:
12249 case OPC_CMP_NGLE_D
:
12250 case OPC_CMP_SEQ_D
:
12251 case OPC_CMP_NGL_D
:
12253 case OPC_CMP_NGE_D
:
12255 case OPC_CMP_NGT_D
:
12256 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12257 if (ctx
->opcode
& (1 << 6)) {
12258 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12260 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12264 check_cp1_registers(ctx
, fs
);
12266 TCGv_i32 fp32
= tcg_temp_new_i32();
12267 TCGv_i64 fp64
= tcg_temp_new_i64();
12269 gen_load_fpr64(ctx
, fp64
, fs
);
12270 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12271 tcg_temp_free_i64(fp64
);
12272 gen_store_fpr32(ctx
, fp32
, fd
);
12273 tcg_temp_free_i32(fp32
);
12277 check_cp1_registers(ctx
, fs
);
12279 TCGv_i32 fp32
= tcg_temp_new_i32();
12280 TCGv_i64 fp64
= tcg_temp_new_i64();
12282 gen_load_fpr64(ctx
, fp64
, fs
);
12283 if (ctx
->nan2008
) {
12284 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12286 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12288 tcg_temp_free_i64(fp64
);
12289 gen_store_fpr32(ctx
, fp32
, fd
);
12290 tcg_temp_free_i32(fp32
);
12294 check_cp1_64bitmode(ctx
);
12296 TCGv_i64 fp0
= tcg_temp_new_i64();
12298 gen_load_fpr64(ctx
, fp0
, fs
);
12299 if (ctx
->nan2008
) {
12300 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12302 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12304 gen_store_fpr64(ctx
, fp0
, fd
);
12305 tcg_temp_free_i64(fp0
);
12310 TCGv_i32 fp0
= tcg_temp_new_i32();
12312 gen_load_fpr32(ctx
, fp0
, fs
);
12313 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12314 gen_store_fpr32(ctx
, fp0
, fd
);
12315 tcg_temp_free_i32(fp0
);
12319 check_cp1_registers(ctx
, fd
);
12321 TCGv_i32 fp32
= tcg_temp_new_i32();
12322 TCGv_i64 fp64
= tcg_temp_new_i64();
12324 gen_load_fpr32(ctx
, fp32
, fs
);
12325 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12326 tcg_temp_free_i32(fp32
);
12327 gen_store_fpr64(ctx
, fp64
, fd
);
12328 tcg_temp_free_i64(fp64
);
12332 check_cp1_64bitmode(ctx
);
12334 TCGv_i32 fp32
= tcg_temp_new_i32();
12335 TCGv_i64 fp64
= tcg_temp_new_i64();
12337 gen_load_fpr64(ctx
, fp64
, fs
);
12338 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12339 tcg_temp_free_i64(fp64
);
12340 gen_store_fpr32(ctx
, fp32
, fd
);
12341 tcg_temp_free_i32(fp32
);
12345 check_cp1_64bitmode(ctx
);
12347 TCGv_i64 fp0
= tcg_temp_new_i64();
12349 gen_load_fpr64(ctx
, fp0
, fs
);
12350 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12351 gen_store_fpr64(ctx
, fp0
, fd
);
12352 tcg_temp_free_i64(fp0
);
12355 case OPC_CVT_PS_PW
:
12358 TCGv_i64 fp0
= tcg_temp_new_i64();
12360 gen_load_fpr64(ctx
, fp0
, fs
);
12361 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12362 gen_store_fpr64(ctx
, fp0
, fd
);
12363 tcg_temp_free_i64(fp0
);
12369 TCGv_i64 fp0
= tcg_temp_new_i64();
12370 TCGv_i64 fp1
= tcg_temp_new_i64();
12372 gen_load_fpr64(ctx
, fp0
, fs
);
12373 gen_load_fpr64(ctx
, fp1
, ft
);
12374 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12375 tcg_temp_free_i64(fp1
);
12376 gen_store_fpr64(ctx
, fp0
, fd
);
12377 tcg_temp_free_i64(fp0
);
12383 TCGv_i64 fp0
= tcg_temp_new_i64();
12384 TCGv_i64 fp1
= tcg_temp_new_i64();
12386 gen_load_fpr64(ctx
, fp0
, fs
);
12387 gen_load_fpr64(ctx
, fp1
, ft
);
12388 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12389 tcg_temp_free_i64(fp1
);
12390 gen_store_fpr64(ctx
, fp0
, fd
);
12391 tcg_temp_free_i64(fp0
);
12397 TCGv_i64 fp0
= tcg_temp_new_i64();
12398 TCGv_i64 fp1
= tcg_temp_new_i64();
12400 gen_load_fpr64(ctx
, fp0
, fs
);
12401 gen_load_fpr64(ctx
, fp1
, ft
);
12402 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12403 tcg_temp_free_i64(fp1
);
12404 gen_store_fpr64(ctx
, fp0
, fd
);
12405 tcg_temp_free_i64(fp0
);
12411 TCGv_i64 fp0
= tcg_temp_new_i64();
12413 gen_load_fpr64(ctx
, fp0
, fs
);
12414 gen_helper_float_abs_ps(fp0
, fp0
);
12415 gen_store_fpr64(ctx
, fp0
, fd
);
12416 tcg_temp_free_i64(fp0
);
12422 TCGv_i64 fp0
= tcg_temp_new_i64();
12424 gen_load_fpr64(ctx
, fp0
, fs
);
12425 gen_store_fpr64(ctx
, fp0
, fd
);
12426 tcg_temp_free_i64(fp0
);
12432 TCGv_i64 fp0
= tcg_temp_new_i64();
12434 gen_load_fpr64(ctx
, fp0
, fs
);
12435 gen_helper_float_chs_ps(fp0
, fp0
);
12436 gen_store_fpr64(ctx
, fp0
, fd
);
12437 tcg_temp_free_i64(fp0
);
12442 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12447 TCGLabel
*l1
= gen_new_label();
12451 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12453 fp0
= tcg_temp_new_i64();
12454 gen_load_fpr64(ctx
, fp0
, fs
);
12455 gen_store_fpr64(ctx
, fp0
, fd
);
12456 tcg_temp_free_i64(fp0
);
12463 TCGLabel
*l1
= gen_new_label();
12467 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12468 fp0
= tcg_temp_new_i64();
12469 gen_load_fpr64(ctx
, fp0
, fs
);
12470 gen_store_fpr64(ctx
, fp0
, fd
);
12471 tcg_temp_free_i64(fp0
);
12479 TCGv_i64 fp0
= tcg_temp_new_i64();
12480 TCGv_i64 fp1
= tcg_temp_new_i64();
12482 gen_load_fpr64(ctx
, fp0
, ft
);
12483 gen_load_fpr64(ctx
, fp1
, fs
);
12484 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12485 tcg_temp_free_i64(fp1
);
12486 gen_store_fpr64(ctx
, fp0
, fd
);
12487 tcg_temp_free_i64(fp0
);
12493 TCGv_i64 fp0
= tcg_temp_new_i64();
12494 TCGv_i64 fp1
= tcg_temp_new_i64();
12496 gen_load_fpr64(ctx
, fp0
, ft
);
12497 gen_load_fpr64(ctx
, fp1
, fs
);
12498 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12499 tcg_temp_free_i64(fp1
);
12500 gen_store_fpr64(ctx
, fp0
, fd
);
12501 tcg_temp_free_i64(fp0
);
12504 case OPC_RECIP2_PS
:
12507 TCGv_i64 fp0
= tcg_temp_new_i64();
12508 TCGv_i64 fp1
= tcg_temp_new_i64();
12510 gen_load_fpr64(ctx
, fp0
, fs
);
12511 gen_load_fpr64(ctx
, fp1
, ft
);
12512 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12513 tcg_temp_free_i64(fp1
);
12514 gen_store_fpr64(ctx
, fp0
, fd
);
12515 tcg_temp_free_i64(fp0
);
12518 case OPC_RECIP1_PS
:
12521 TCGv_i64 fp0
= tcg_temp_new_i64();
12523 gen_load_fpr64(ctx
, fp0
, fs
);
12524 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12525 gen_store_fpr64(ctx
, fp0
, fd
);
12526 tcg_temp_free_i64(fp0
);
12529 case OPC_RSQRT1_PS
:
12532 TCGv_i64 fp0
= tcg_temp_new_i64();
12534 gen_load_fpr64(ctx
, fp0
, fs
);
12535 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12536 gen_store_fpr64(ctx
, fp0
, fd
);
12537 tcg_temp_free_i64(fp0
);
12540 case OPC_RSQRT2_PS
:
12543 TCGv_i64 fp0
= tcg_temp_new_i64();
12544 TCGv_i64 fp1
= tcg_temp_new_i64();
12546 gen_load_fpr64(ctx
, fp0
, fs
);
12547 gen_load_fpr64(ctx
, fp1
, ft
);
12548 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12549 tcg_temp_free_i64(fp1
);
12550 gen_store_fpr64(ctx
, fp0
, fd
);
12551 tcg_temp_free_i64(fp0
);
12555 check_cp1_64bitmode(ctx
);
12557 TCGv_i32 fp0
= tcg_temp_new_i32();
12559 gen_load_fpr32h(ctx
, fp0
, fs
);
12560 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12561 gen_store_fpr32(ctx
, fp0
, fd
);
12562 tcg_temp_free_i32(fp0
);
12565 case OPC_CVT_PW_PS
:
12568 TCGv_i64 fp0
= tcg_temp_new_i64();
12570 gen_load_fpr64(ctx
, fp0
, fs
);
12571 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
12572 gen_store_fpr64(ctx
, fp0
, fd
);
12573 tcg_temp_free_i64(fp0
);
12577 check_cp1_64bitmode(ctx
);
12579 TCGv_i32 fp0
= tcg_temp_new_i32();
12581 gen_load_fpr32(ctx
, fp0
, fs
);
12582 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
12583 gen_store_fpr32(ctx
, fp0
, fd
);
12584 tcg_temp_free_i32(fp0
);
12590 TCGv_i32 fp0
= tcg_temp_new_i32();
12591 TCGv_i32 fp1
= tcg_temp_new_i32();
12593 gen_load_fpr32(ctx
, fp0
, fs
);
12594 gen_load_fpr32(ctx
, fp1
, ft
);
12595 gen_store_fpr32h(ctx
, fp0
, fd
);
12596 gen_store_fpr32(ctx
, fp1
, fd
);
12597 tcg_temp_free_i32(fp0
);
12598 tcg_temp_free_i32(fp1
);
12604 TCGv_i32 fp0
= tcg_temp_new_i32();
12605 TCGv_i32 fp1
= tcg_temp_new_i32();
12607 gen_load_fpr32(ctx
, fp0
, fs
);
12608 gen_load_fpr32h(ctx
, fp1
, ft
);
12609 gen_store_fpr32(ctx
, fp1
, fd
);
12610 gen_store_fpr32h(ctx
, fp0
, fd
);
12611 tcg_temp_free_i32(fp0
);
12612 tcg_temp_free_i32(fp1
);
12618 TCGv_i32 fp0
= tcg_temp_new_i32();
12619 TCGv_i32 fp1
= tcg_temp_new_i32();
12621 gen_load_fpr32h(ctx
, fp0
, fs
);
12622 gen_load_fpr32(ctx
, fp1
, ft
);
12623 gen_store_fpr32(ctx
, fp1
, fd
);
12624 gen_store_fpr32h(ctx
, fp0
, fd
);
12625 tcg_temp_free_i32(fp0
);
12626 tcg_temp_free_i32(fp1
);
12632 TCGv_i32 fp0
= tcg_temp_new_i32();
12633 TCGv_i32 fp1
= tcg_temp_new_i32();
12635 gen_load_fpr32h(ctx
, fp0
, fs
);
12636 gen_load_fpr32h(ctx
, fp1
, ft
);
12637 gen_store_fpr32(ctx
, fp1
, fd
);
12638 gen_store_fpr32h(ctx
, fp0
, fd
);
12639 tcg_temp_free_i32(fp0
);
12640 tcg_temp_free_i32(fp1
);
12644 case OPC_CMP_UN_PS
:
12645 case OPC_CMP_EQ_PS
:
12646 case OPC_CMP_UEQ_PS
:
12647 case OPC_CMP_OLT_PS
:
12648 case OPC_CMP_ULT_PS
:
12649 case OPC_CMP_OLE_PS
:
12650 case OPC_CMP_ULE_PS
:
12651 case OPC_CMP_SF_PS
:
12652 case OPC_CMP_NGLE_PS
:
12653 case OPC_CMP_SEQ_PS
:
12654 case OPC_CMP_NGL_PS
:
12655 case OPC_CMP_LT_PS
:
12656 case OPC_CMP_NGE_PS
:
12657 case OPC_CMP_LE_PS
:
12658 case OPC_CMP_NGT_PS
:
12659 if (ctx
->opcode
& (1 << 6)) {
12660 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
12662 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
12666 MIPS_INVAL("farith");
12667 generate_exception_end(ctx
, EXCP_RI
);
12672 /* Coprocessor 3 (FPU) */
12673 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
12674 int fd
, int fs
, int base
, int index
)
12676 TCGv t0
= tcg_temp_new();
12679 gen_load_gpr(t0
, index
);
12680 } else if (index
== 0) {
12681 gen_load_gpr(t0
, base
);
12683 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
12686 * Don't do NOP if destination is zero: we must perform the actual
12693 TCGv_i32 fp0
= tcg_temp_new_i32();
12695 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12696 tcg_gen_trunc_tl_i32(fp0
, t0
);
12697 gen_store_fpr32(ctx
, fp0
, fd
);
12698 tcg_temp_free_i32(fp0
);
12703 check_cp1_registers(ctx
, fd
);
12705 TCGv_i64 fp0
= tcg_temp_new_i64();
12706 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12707 gen_store_fpr64(ctx
, fp0
, fd
);
12708 tcg_temp_free_i64(fp0
);
12712 check_cp1_64bitmode(ctx
);
12713 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12715 TCGv_i64 fp0
= tcg_temp_new_i64();
12717 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12718 gen_store_fpr64(ctx
, fp0
, fd
);
12719 tcg_temp_free_i64(fp0
);
12725 TCGv_i32 fp0
= tcg_temp_new_i32();
12726 gen_load_fpr32(ctx
, fp0
, fs
);
12727 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
12728 tcg_temp_free_i32(fp0
);
12733 check_cp1_registers(ctx
, fs
);
12735 TCGv_i64 fp0
= tcg_temp_new_i64();
12736 gen_load_fpr64(ctx
, fp0
, fs
);
12737 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12738 tcg_temp_free_i64(fp0
);
12742 check_cp1_64bitmode(ctx
);
12743 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12745 TCGv_i64 fp0
= tcg_temp_new_i64();
12746 gen_load_fpr64(ctx
, fp0
, fs
);
12747 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12748 tcg_temp_free_i64(fp0
);
12755 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
12756 int fd
, int fr
, int fs
, int ft
)
12762 TCGv t0
= tcg_temp_local_new();
12763 TCGv_i32 fp
= tcg_temp_new_i32();
12764 TCGv_i32 fph
= tcg_temp_new_i32();
12765 TCGLabel
*l1
= gen_new_label();
12766 TCGLabel
*l2
= gen_new_label();
12768 gen_load_gpr(t0
, fr
);
12769 tcg_gen_andi_tl(t0
, t0
, 0x7);
12771 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
12772 gen_load_fpr32(ctx
, fp
, fs
);
12773 gen_load_fpr32h(ctx
, fph
, fs
);
12774 gen_store_fpr32(ctx
, fp
, fd
);
12775 gen_store_fpr32h(ctx
, fph
, fd
);
12778 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
12780 #ifdef TARGET_WORDS_BIGENDIAN
12781 gen_load_fpr32(ctx
, fp
, fs
);
12782 gen_load_fpr32h(ctx
, fph
, ft
);
12783 gen_store_fpr32h(ctx
, fp
, fd
);
12784 gen_store_fpr32(ctx
, fph
, fd
);
12786 gen_load_fpr32h(ctx
, fph
, fs
);
12787 gen_load_fpr32(ctx
, fp
, ft
);
12788 gen_store_fpr32(ctx
, fph
, fd
);
12789 gen_store_fpr32h(ctx
, fp
, fd
);
12792 tcg_temp_free_i32(fp
);
12793 tcg_temp_free_i32(fph
);
12799 TCGv_i32 fp0
= tcg_temp_new_i32();
12800 TCGv_i32 fp1
= tcg_temp_new_i32();
12801 TCGv_i32 fp2
= tcg_temp_new_i32();
12803 gen_load_fpr32(ctx
, fp0
, fs
);
12804 gen_load_fpr32(ctx
, fp1
, ft
);
12805 gen_load_fpr32(ctx
, fp2
, fr
);
12806 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12807 tcg_temp_free_i32(fp0
);
12808 tcg_temp_free_i32(fp1
);
12809 gen_store_fpr32(ctx
, fp2
, fd
);
12810 tcg_temp_free_i32(fp2
);
12815 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12817 TCGv_i64 fp0
= tcg_temp_new_i64();
12818 TCGv_i64 fp1
= tcg_temp_new_i64();
12819 TCGv_i64 fp2
= tcg_temp_new_i64();
12821 gen_load_fpr64(ctx
, fp0
, fs
);
12822 gen_load_fpr64(ctx
, fp1
, ft
);
12823 gen_load_fpr64(ctx
, fp2
, fr
);
12824 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12825 tcg_temp_free_i64(fp0
);
12826 tcg_temp_free_i64(fp1
);
12827 gen_store_fpr64(ctx
, fp2
, fd
);
12828 tcg_temp_free_i64(fp2
);
12834 TCGv_i64 fp0
= tcg_temp_new_i64();
12835 TCGv_i64 fp1
= tcg_temp_new_i64();
12836 TCGv_i64 fp2
= tcg_temp_new_i64();
12838 gen_load_fpr64(ctx
, fp0
, fs
);
12839 gen_load_fpr64(ctx
, fp1
, ft
);
12840 gen_load_fpr64(ctx
, fp2
, fr
);
12841 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12842 tcg_temp_free_i64(fp0
);
12843 tcg_temp_free_i64(fp1
);
12844 gen_store_fpr64(ctx
, fp2
, fd
);
12845 tcg_temp_free_i64(fp2
);
12851 TCGv_i32 fp0
= tcg_temp_new_i32();
12852 TCGv_i32 fp1
= tcg_temp_new_i32();
12853 TCGv_i32 fp2
= tcg_temp_new_i32();
12855 gen_load_fpr32(ctx
, fp0
, fs
);
12856 gen_load_fpr32(ctx
, fp1
, ft
);
12857 gen_load_fpr32(ctx
, fp2
, fr
);
12858 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12859 tcg_temp_free_i32(fp0
);
12860 tcg_temp_free_i32(fp1
);
12861 gen_store_fpr32(ctx
, fp2
, fd
);
12862 tcg_temp_free_i32(fp2
);
12867 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12869 TCGv_i64 fp0
= tcg_temp_new_i64();
12870 TCGv_i64 fp1
= tcg_temp_new_i64();
12871 TCGv_i64 fp2
= tcg_temp_new_i64();
12873 gen_load_fpr64(ctx
, fp0
, fs
);
12874 gen_load_fpr64(ctx
, fp1
, ft
);
12875 gen_load_fpr64(ctx
, fp2
, fr
);
12876 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12877 tcg_temp_free_i64(fp0
);
12878 tcg_temp_free_i64(fp1
);
12879 gen_store_fpr64(ctx
, fp2
, fd
);
12880 tcg_temp_free_i64(fp2
);
12886 TCGv_i64 fp0
= tcg_temp_new_i64();
12887 TCGv_i64 fp1
= tcg_temp_new_i64();
12888 TCGv_i64 fp2
= tcg_temp_new_i64();
12890 gen_load_fpr64(ctx
, fp0
, fs
);
12891 gen_load_fpr64(ctx
, fp1
, ft
);
12892 gen_load_fpr64(ctx
, fp2
, fr
);
12893 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12894 tcg_temp_free_i64(fp0
);
12895 tcg_temp_free_i64(fp1
);
12896 gen_store_fpr64(ctx
, fp2
, fd
);
12897 tcg_temp_free_i64(fp2
);
12903 TCGv_i32 fp0
= tcg_temp_new_i32();
12904 TCGv_i32 fp1
= tcg_temp_new_i32();
12905 TCGv_i32 fp2
= tcg_temp_new_i32();
12907 gen_load_fpr32(ctx
, fp0
, fs
);
12908 gen_load_fpr32(ctx
, fp1
, ft
);
12909 gen_load_fpr32(ctx
, fp2
, fr
);
12910 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12911 tcg_temp_free_i32(fp0
);
12912 tcg_temp_free_i32(fp1
);
12913 gen_store_fpr32(ctx
, fp2
, fd
);
12914 tcg_temp_free_i32(fp2
);
12919 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12921 TCGv_i64 fp0
= tcg_temp_new_i64();
12922 TCGv_i64 fp1
= tcg_temp_new_i64();
12923 TCGv_i64 fp2
= tcg_temp_new_i64();
12925 gen_load_fpr64(ctx
, fp0
, fs
);
12926 gen_load_fpr64(ctx
, fp1
, ft
);
12927 gen_load_fpr64(ctx
, fp2
, fr
);
12928 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12929 tcg_temp_free_i64(fp0
);
12930 tcg_temp_free_i64(fp1
);
12931 gen_store_fpr64(ctx
, fp2
, fd
);
12932 tcg_temp_free_i64(fp2
);
12938 TCGv_i64 fp0
= tcg_temp_new_i64();
12939 TCGv_i64 fp1
= tcg_temp_new_i64();
12940 TCGv_i64 fp2
= tcg_temp_new_i64();
12942 gen_load_fpr64(ctx
, fp0
, fs
);
12943 gen_load_fpr64(ctx
, fp1
, ft
);
12944 gen_load_fpr64(ctx
, fp2
, fr
);
12945 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12946 tcg_temp_free_i64(fp0
);
12947 tcg_temp_free_i64(fp1
);
12948 gen_store_fpr64(ctx
, fp2
, fd
);
12949 tcg_temp_free_i64(fp2
);
12955 TCGv_i32 fp0
= tcg_temp_new_i32();
12956 TCGv_i32 fp1
= tcg_temp_new_i32();
12957 TCGv_i32 fp2
= tcg_temp_new_i32();
12959 gen_load_fpr32(ctx
, fp0
, fs
);
12960 gen_load_fpr32(ctx
, fp1
, ft
);
12961 gen_load_fpr32(ctx
, fp2
, fr
);
12962 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12963 tcg_temp_free_i32(fp0
);
12964 tcg_temp_free_i32(fp1
);
12965 gen_store_fpr32(ctx
, fp2
, fd
);
12966 tcg_temp_free_i32(fp2
);
12971 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12973 TCGv_i64 fp0
= tcg_temp_new_i64();
12974 TCGv_i64 fp1
= tcg_temp_new_i64();
12975 TCGv_i64 fp2
= tcg_temp_new_i64();
12977 gen_load_fpr64(ctx
, fp0
, fs
);
12978 gen_load_fpr64(ctx
, fp1
, ft
);
12979 gen_load_fpr64(ctx
, fp2
, fr
);
12980 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12981 tcg_temp_free_i64(fp0
);
12982 tcg_temp_free_i64(fp1
);
12983 gen_store_fpr64(ctx
, fp2
, fd
);
12984 tcg_temp_free_i64(fp2
);
12990 TCGv_i64 fp0
= tcg_temp_new_i64();
12991 TCGv_i64 fp1
= tcg_temp_new_i64();
12992 TCGv_i64 fp2
= tcg_temp_new_i64();
12994 gen_load_fpr64(ctx
, fp0
, fs
);
12995 gen_load_fpr64(ctx
, fp1
, ft
);
12996 gen_load_fpr64(ctx
, fp2
, fr
);
12997 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12998 tcg_temp_free_i64(fp0
);
12999 tcg_temp_free_i64(fp1
);
13000 gen_store_fpr64(ctx
, fp2
, fd
);
13001 tcg_temp_free_i64(fp2
);
13005 MIPS_INVAL("flt3_arith");
13006 generate_exception_end(ctx
, EXCP_RI
);
13011 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
13015 #if !defined(CONFIG_USER_ONLY)
13017 * The Linux kernel will emulate rdhwr if it's not supported natively.
13018 * Therefore only check the ISA in system mode.
13020 check_insn(ctx
, ISA_MIPS32R2
);
13022 t0
= tcg_temp_new();
13026 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
13027 gen_store_gpr(t0
, rt
);
13030 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
13031 gen_store_gpr(t0
, rt
);
13034 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
13037 gen_helper_rdhwr_cc(t0
, cpu_env
);
13038 gen_store_gpr(t0
, rt
);
13040 * Break the TB to be able to take timer interrupts immediately
13041 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13042 * we break completely out of translated code.
13044 gen_save_pc(ctx
->base
.pc_next
+ 4);
13045 ctx
->base
.is_jmp
= DISAS_EXIT
;
13048 gen_helper_rdhwr_ccres(t0
, cpu_env
);
13049 gen_store_gpr(t0
, rt
);
13052 check_insn(ctx
, ISA_MIPS32R6
);
13055 * Performance counter registers are not implemented other than
13056 * control register 0.
13058 generate_exception(ctx
, EXCP_RI
);
13060 gen_helper_rdhwr_performance(t0
, cpu_env
);
13061 gen_store_gpr(t0
, rt
);
13064 check_insn(ctx
, ISA_MIPS32R6
);
13065 gen_helper_rdhwr_xnp(t0
, cpu_env
);
13066 gen_store_gpr(t0
, rt
);
13069 #if defined(CONFIG_USER_ONLY)
13070 tcg_gen_ld_tl(t0
, cpu_env
,
13071 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13072 gen_store_gpr(t0
, rt
);
13075 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
13076 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
13077 tcg_gen_ld_tl(t0
, cpu_env
,
13078 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13079 gen_store_gpr(t0
, rt
);
13081 generate_exception_end(ctx
, EXCP_RI
);
13085 default: /* Invalid */
13086 MIPS_INVAL("rdhwr");
13087 generate_exception_end(ctx
, EXCP_RI
);
13093 static inline void clear_branch_hflags(DisasContext
*ctx
)
13095 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
13096 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
13097 save_cpu_state(ctx
, 0);
13100 * It is not safe to save ctx->hflags as hflags may be changed
13101 * in execution time by the instruction in delay / forbidden slot.
13103 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
13107 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
13109 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13110 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
13111 /* Branches completion */
13112 clear_branch_hflags(ctx
);
13113 ctx
->base
.is_jmp
= DISAS_NORETURN
;
13114 /* FIXME: Need to clear can_do_io. */
13115 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
13116 case MIPS_HFLAG_FBNSLOT
:
13117 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
13120 /* unconditional branch */
13121 if (proc_hflags
& MIPS_HFLAG_BX
) {
13122 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
13124 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13126 case MIPS_HFLAG_BL
:
13127 /* blikely taken case */
13128 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13130 case MIPS_HFLAG_BC
:
13131 /* Conditional branch */
13133 TCGLabel
*l1
= gen_new_label();
13135 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
13136 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
13138 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13141 case MIPS_HFLAG_BR
:
13142 /* unconditional branch to register */
13143 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
13144 TCGv t0
= tcg_temp_new();
13145 TCGv_i32 t1
= tcg_temp_new_i32();
13147 tcg_gen_andi_tl(t0
, btarget
, 0x1);
13148 tcg_gen_trunc_tl_i32(t1
, t0
);
13150 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
13151 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
13152 tcg_gen_or_i32(hflags
, hflags
, t1
);
13153 tcg_temp_free_i32(t1
);
13155 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
13157 tcg_gen_mov_tl(cpu_PC
, btarget
);
13159 if (ctx
->base
.singlestep_enabled
) {
13160 save_cpu_state(ctx
, 0);
13161 gen_helper_raise_exception_debug(cpu_env
);
13163 tcg_gen_lookup_and_goto_ptr();
13166 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
13172 /* Compact Branches */
13173 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
13174 int rs
, int rt
, int32_t offset
)
13176 int bcond_compute
= 0;
13177 TCGv t0
= tcg_temp_new();
13178 TCGv t1
= tcg_temp_new();
13179 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
13181 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13182 #ifdef MIPS_DEBUG_DISAS
13183 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13184 "\n", ctx
->base
.pc_next
);
13186 generate_exception_end(ctx
, EXCP_RI
);
13190 /* Load needed operands and calculate btarget */
13192 /* compact branch */
13193 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13194 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13195 gen_load_gpr(t0
, rs
);
13196 gen_load_gpr(t1
, rt
);
13198 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13199 if (rs
<= rt
&& rs
== 0) {
13200 /* OPC_BEQZALC, OPC_BNEZALC */
13201 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13204 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13205 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13206 gen_load_gpr(t0
, rs
);
13207 gen_load_gpr(t1
, rt
);
13209 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13211 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13212 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13213 if (rs
== 0 || rs
== rt
) {
13214 /* OPC_BLEZALC, OPC_BGEZALC */
13215 /* OPC_BGTZALC, OPC_BLTZALC */
13216 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13218 gen_load_gpr(t0
, rs
);
13219 gen_load_gpr(t1
, rt
);
13221 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13225 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13230 /* OPC_BEQZC, OPC_BNEZC */
13231 gen_load_gpr(t0
, rs
);
13233 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13235 /* OPC_JIC, OPC_JIALC */
13236 TCGv tbase
= tcg_temp_new();
13237 TCGv toffset
= tcg_temp_new();
13239 gen_load_gpr(tbase
, rt
);
13240 tcg_gen_movi_tl(toffset
, offset
);
13241 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13242 tcg_temp_free(tbase
);
13243 tcg_temp_free(toffset
);
13247 MIPS_INVAL("Compact branch/jump");
13248 generate_exception_end(ctx
, EXCP_RI
);
13252 if (bcond_compute
== 0) {
13253 /* Uncoditional compact branch */
13256 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13259 ctx
->hflags
|= MIPS_HFLAG_BR
;
13262 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13265 ctx
->hflags
|= MIPS_HFLAG_B
;
13268 MIPS_INVAL("Compact branch/jump");
13269 generate_exception_end(ctx
, EXCP_RI
);
13273 /* Generating branch here as compact branches don't have delay slot */
13274 gen_branch(ctx
, 4);
13276 /* Conditional compact branch */
13277 TCGLabel
*fs
= gen_new_label();
13278 save_cpu_state(ctx
, 0);
13281 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13282 if (rs
== 0 && rt
!= 0) {
13284 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13285 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13287 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13290 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13293 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13294 if (rs
== 0 && rt
!= 0) {
13296 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13297 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13299 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13302 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13305 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13306 if (rs
== 0 && rt
!= 0) {
13308 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13309 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13311 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13314 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13317 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13318 if (rs
== 0 && rt
!= 0) {
13320 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13321 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13323 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13326 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13329 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13330 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13332 /* OPC_BOVC, OPC_BNVC */
13333 TCGv t2
= tcg_temp_new();
13334 TCGv t3
= tcg_temp_new();
13335 TCGv t4
= tcg_temp_new();
13336 TCGv input_overflow
= tcg_temp_new();
13338 gen_load_gpr(t0
, rs
);
13339 gen_load_gpr(t1
, rt
);
13340 tcg_gen_ext32s_tl(t2
, t0
);
13341 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13342 tcg_gen_ext32s_tl(t3
, t1
);
13343 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13344 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13346 tcg_gen_add_tl(t4
, t2
, t3
);
13347 tcg_gen_ext32s_tl(t4
, t4
);
13348 tcg_gen_xor_tl(t2
, t2
, t3
);
13349 tcg_gen_xor_tl(t3
, t4
, t3
);
13350 tcg_gen_andc_tl(t2
, t3
, t2
);
13351 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13352 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13353 if (opc
== OPC_BOVC
) {
13355 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13358 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13360 tcg_temp_free(input_overflow
);
13364 } else if (rs
< rt
&& rs
== 0) {
13365 /* OPC_BEQZALC, OPC_BNEZALC */
13366 if (opc
== OPC_BEQZALC
) {
13368 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13371 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13374 /* OPC_BEQC, OPC_BNEC */
13375 if (opc
== OPC_BEQC
) {
13377 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13380 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13385 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13388 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13391 MIPS_INVAL("Compact conditional branch/jump");
13392 generate_exception_end(ctx
, EXCP_RI
);
13396 /* Generating branch here as compact branches don't have delay slot */
13397 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13400 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13408 /* ISA extensions (ASEs) */
13409 /* MIPS16 extension to MIPS32 */
13411 /* MIPS16 major opcodes */
13413 M16_OPC_ADDIUSP
= 0x00,
13414 M16_OPC_ADDIUPC
= 0x01,
13416 M16_OPC_JAL
= 0x03,
13417 M16_OPC_BEQZ
= 0x04,
13418 M16_OPC_BNEQZ
= 0x05,
13419 M16_OPC_SHIFT
= 0x06,
13421 M16_OPC_RRIA
= 0x08,
13422 M16_OPC_ADDIU8
= 0x09,
13423 M16_OPC_SLTI
= 0x0a,
13424 M16_OPC_SLTIU
= 0x0b,
13427 M16_OPC_CMPI
= 0x0e,
13431 M16_OPC_LWSP
= 0x12,
13433 M16_OPC_LBU
= 0x14,
13434 M16_OPC_LHU
= 0x15,
13435 M16_OPC_LWPC
= 0x16,
13436 M16_OPC_LWU
= 0x17,
13439 M16_OPC_SWSP
= 0x1a,
13441 M16_OPC_RRR
= 0x1c,
13443 M16_OPC_EXTEND
= 0x1e,
13447 /* I8 funct field */
13466 /* RR funct field */
13500 /* I64 funct field */
13508 I64_DADDIUPC
= 0x6,
13512 /* RR ry field for CNVT */
13514 RR_RY_CNVT_ZEB
= 0x0,
13515 RR_RY_CNVT_ZEH
= 0x1,
13516 RR_RY_CNVT_ZEW
= 0x2,
13517 RR_RY_CNVT_SEB
= 0x4,
13518 RR_RY_CNVT_SEH
= 0x5,
13519 RR_RY_CNVT_SEW
= 0x6,
13522 static int xlat(int r
)
13524 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13529 static void gen_mips16_save(DisasContext
*ctx
,
13530 int xsregs
, int aregs
,
13531 int do_ra
, int do_s0
, int do_s1
,
13534 TCGv t0
= tcg_temp_new();
13535 TCGv t1
= tcg_temp_new();
13536 TCGv t2
= tcg_temp_new();
13566 generate_exception_end(ctx
, EXCP_RI
);
13572 gen_base_offset_addr(ctx
, t0
, 29, 12);
13573 gen_load_gpr(t1
, 7);
13574 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13577 gen_base_offset_addr(ctx
, t0
, 29, 8);
13578 gen_load_gpr(t1
, 6);
13579 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13582 gen_base_offset_addr(ctx
, t0
, 29, 4);
13583 gen_load_gpr(t1
, 5);
13584 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13587 gen_base_offset_addr(ctx
, t0
, 29, 0);
13588 gen_load_gpr(t1
, 4);
13589 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13592 gen_load_gpr(t0
, 29);
13594 #define DECR_AND_STORE(reg) do { \
13595 tcg_gen_movi_tl(t2, -4); \
13596 gen_op_addr_add(ctx, t0, t0, t2); \
13597 gen_load_gpr(t1, reg); \
13598 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13602 DECR_AND_STORE(31);
13607 DECR_AND_STORE(30);
13610 DECR_AND_STORE(23);
13613 DECR_AND_STORE(22);
13616 DECR_AND_STORE(21);
13619 DECR_AND_STORE(20);
13622 DECR_AND_STORE(19);
13625 DECR_AND_STORE(18);
13629 DECR_AND_STORE(17);
13632 DECR_AND_STORE(16);
13662 generate_exception_end(ctx
, EXCP_RI
);
13678 #undef DECR_AND_STORE
13680 tcg_gen_movi_tl(t2
, -framesize
);
13681 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13687 static void gen_mips16_restore(DisasContext
*ctx
,
13688 int xsregs
, int aregs
,
13689 int do_ra
, int do_s0
, int do_s1
,
13693 TCGv t0
= tcg_temp_new();
13694 TCGv t1
= tcg_temp_new();
13695 TCGv t2
= tcg_temp_new();
13697 tcg_gen_movi_tl(t2
, framesize
);
13698 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
13700 #define DECR_AND_LOAD(reg) do { \
13701 tcg_gen_movi_tl(t2, -4); \
13702 gen_op_addr_add(ctx, t0, t0, t2); \
13703 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13704 gen_store_gpr(t1, reg); \
13768 generate_exception_end(ctx
, EXCP_RI
);
13784 #undef DECR_AND_LOAD
13786 tcg_gen_movi_tl(t2
, framesize
);
13787 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13793 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
13794 int is_64_bit
, int extended
)
13798 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13799 generate_exception_end(ctx
, EXCP_RI
);
13803 t0
= tcg_temp_new();
13805 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
13806 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
13808 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13814 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
13817 TCGv_i32 t0
= tcg_const_i32(op
);
13818 TCGv t1
= tcg_temp_new();
13819 gen_base_offset_addr(ctx
, t1
, base
, offset
);
13820 gen_helper_cache(cpu_env
, t1
, t0
);
13823 #if defined(TARGET_MIPS64)
13824 static void decode_i64_mips16(DisasContext
*ctx
,
13825 int ry
, int funct
, int16_t offset
,
13830 check_insn(ctx
, ISA_MIPS3
);
13831 check_mips_64(ctx
);
13832 offset
= extended
? offset
: offset
<< 3;
13833 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
13836 check_insn(ctx
, ISA_MIPS3
);
13837 check_mips_64(ctx
);
13838 offset
= extended
? offset
: offset
<< 3;
13839 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
13842 check_insn(ctx
, ISA_MIPS3
);
13843 check_mips_64(ctx
);
13844 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
13845 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
13848 check_insn(ctx
, ISA_MIPS3
);
13849 check_mips_64(ctx
);
13850 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
13851 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
13854 check_insn(ctx
, ISA_MIPS3
);
13855 check_mips_64(ctx
);
13856 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13857 generate_exception_end(ctx
, EXCP_RI
);
13859 offset
= extended
? offset
: offset
<< 3;
13860 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
13864 check_insn(ctx
, ISA_MIPS3
);
13865 check_mips_64(ctx
);
13866 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
13867 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
13870 check_insn(ctx
, ISA_MIPS3
);
13871 check_mips_64(ctx
);
13872 offset
= extended
? offset
: offset
<< 2;
13873 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
13876 check_insn(ctx
, ISA_MIPS3
);
13877 check_mips_64(ctx
);
13878 offset
= extended
? offset
: offset
<< 2;
13879 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
13885 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13887 int extend
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
13888 int op
, rx
, ry
, funct
, sa
;
13889 int16_t imm
, offset
;
13891 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
13892 op
= (ctx
->opcode
>> 11) & 0x1f;
13893 sa
= (ctx
->opcode
>> 22) & 0x1f;
13894 funct
= (ctx
->opcode
>> 8) & 0x7;
13895 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13896 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13897 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
13898 | ((ctx
->opcode
>> 21) & 0x3f) << 5
13899 | (ctx
->opcode
& 0x1f));
13902 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13906 case M16_OPC_ADDIUSP
:
13907 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13909 case M16_OPC_ADDIUPC
:
13910 gen_addiupc(ctx
, rx
, imm
, 0, 1);
13913 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
13914 /* No delay slot, so just process as a normal instruction */
13917 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
13918 /* No delay slot, so just process as a normal instruction */
13920 case M16_OPC_BNEQZ
:
13921 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
13922 /* No delay slot, so just process as a normal instruction */
13924 case M16_OPC_SHIFT
:
13925 switch (ctx
->opcode
& 0x3) {
13927 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13930 #if defined(TARGET_MIPS64)
13931 check_mips_64(ctx
);
13932 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13934 generate_exception_end(ctx
, EXCP_RI
);
13938 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13941 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13945 #if defined(TARGET_MIPS64)
13947 check_insn(ctx
, ISA_MIPS3
);
13948 check_mips_64(ctx
);
13949 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
13953 imm
= ctx
->opcode
& 0xf;
13954 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
13955 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
13956 imm
= (int16_t) (imm
<< 1) >> 1;
13957 if ((ctx
->opcode
>> 4) & 0x1) {
13958 #if defined(TARGET_MIPS64)
13959 check_mips_64(ctx
);
13960 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13962 generate_exception_end(ctx
, EXCP_RI
);
13965 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13968 case M16_OPC_ADDIU8
:
13969 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13972 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13974 case M16_OPC_SLTIU
:
13975 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13980 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
13983 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
13986 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
13989 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
13992 check_insn(ctx
, ISA_MIPS32
);
13994 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
13995 int aregs
= (ctx
->opcode
>> 16) & 0xf;
13996 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
13997 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
13998 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
13999 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
14000 | (ctx
->opcode
& 0xf)) << 3;
14002 if (ctx
->opcode
& (1 << 7)) {
14003 gen_mips16_save(ctx
, xsregs
, aregs
,
14004 do_ra
, do_s0
, do_s1
,
14007 gen_mips16_restore(ctx
, xsregs
, aregs
,
14008 do_ra
, do_s0
, do_s1
,
14014 generate_exception_end(ctx
, EXCP_RI
);
14019 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
14022 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
14024 #if defined(TARGET_MIPS64)
14026 check_insn(ctx
, ISA_MIPS3
);
14027 check_mips_64(ctx
);
14028 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
14032 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14035 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
14038 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
14041 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
14044 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14047 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
14050 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
14052 #if defined(TARGET_MIPS64)
14054 check_insn(ctx
, ISA_MIPS3
);
14055 check_mips_64(ctx
);
14056 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
14060 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14063 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
14066 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
14069 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
14071 #if defined(TARGET_MIPS64)
14073 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
14077 generate_exception_end(ctx
, EXCP_RI
);
14084 static inline bool is_uhi(int sdbbp_code
)
14086 #ifdef CONFIG_USER_ONLY
14089 return semihosting_enabled() && sdbbp_code
== 1;
14093 #ifdef CONFIG_USER_ONLY
14094 /* The above should dead-code away any calls to this..*/
14095 static inline void gen_helper_do_semihosting(void *env
)
14097 g_assert_not_reached();
14101 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14105 int op
, cnvt_op
, op1
, offset
;
14109 op
= (ctx
->opcode
>> 11) & 0x1f;
14110 sa
= (ctx
->opcode
>> 2) & 0x7;
14111 sa
= sa
== 0 ? 8 : sa
;
14112 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14113 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
14114 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14115 op1
= offset
= ctx
->opcode
& 0x1f;
14120 case M16_OPC_ADDIUSP
:
14122 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
14124 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14127 case M16_OPC_ADDIUPC
:
14128 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
14131 offset
= (ctx
->opcode
& 0x7ff) << 1;
14132 offset
= (int16_t)(offset
<< 4) >> 4;
14133 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
14134 /* No delay slot, so just process as a normal instruction */
14137 offset
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14138 offset
= (((ctx
->opcode
& 0x1f) << 21)
14139 | ((ctx
->opcode
>> 5) & 0x1f) << 16
14141 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
14142 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
14146 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
14147 ((int8_t)ctx
->opcode
) << 1, 0);
14148 /* No delay slot, so just process as a normal instruction */
14150 case M16_OPC_BNEQZ
:
14151 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
14152 ((int8_t)ctx
->opcode
) << 1, 0);
14153 /* No delay slot, so just process as a normal instruction */
14155 case M16_OPC_SHIFT
:
14156 switch (ctx
->opcode
& 0x3) {
14158 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14161 #if defined(TARGET_MIPS64)
14162 check_insn(ctx
, ISA_MIPS3
);
14163 check_mips_64(ctx
);
14164 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14166 generate_exception_end(ctx
, EXCP_RI
);
14170 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14173 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14177 #if defined(TARGET_MIPS64)
14179 check_insn(ctx
, ISA_MIPS3
);
14180 check_mips_64(ctx
);
14181 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14186 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14188 if ((ctx
->opcode
>> 4) & 1) {
14189 #if defined(TARGET_MIPS64)
14190 check_insn(ctx
, ISA_MIPS3
);
14191 check_mips_64(ctx
);
14192 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14194 generate_exception_end(ctx
, EXCP_RI
);
14197 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14201 case M16_OPC_ADDIU8
:
14203 int16_t imm
= (int8_t) ctx
->opcode
;
14205 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14210 int16_t imm
= (uint8_t) ctx
->opcode
;
14211 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14214 case M16_OPC_SLTIU
:
14216 int16_t imm
= (uint8_t) ctx
->opcode
;
14217 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14224 funct
= (ctx
->opcode
>> 8) & 0x7;
14227 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14228 ((int8_t)ctx
->opcode
) << 1, 0);
14231 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14232 ((int8_t)ctx
->opcode
) << 1, 0);
14235 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14238 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14239 ((int8_t)ctx
->opcode
) << 3);
14242 check_insn(ctx
, ISA_MIPS32
);
14244 int do_ra
= ctx
->opcode
& (1 << 6);
14245 int do_s0
= ctx
->opcode
& (1 << 5);
14246 int do_s1
= ctx
->opcode
& (1 << 4);
14247 int framesize
= ctx
->opcode
& 0xf;
14249 if (framesize
== 0) {
14252 framesize
= framesize
<< 3;
14255 if (ctx
->opcode
& (1 << 7)) {
14256 gen_mips16_save(ctx
, 0, 0,
14257 do_ra
, do_s0
, do_s1
, framesize
);
14259 gen_mips16_restore(ctx
, 0, 0,
14260 do_ra
, do_s0
, do_s1
, framesize
);
14266 int rz
= xlat(ctx
->opcode
& 0x7);
14268 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14269 ((ctx
->opcode
>> 5) & 0x7);
14270 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14274 reg32
= ctx
->opcode
& 0x1f;
14275 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14278 generate_exception_end(ctx
, EXCP_RI
);
14285 int16_t imm
= (uint8_t) ctx
->opcode
;
14287 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14292 int16_t imm
= (uint8_t) ctx
->opcode
;
14293 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14296 #if defined(TARGET_MIPS64)
14298 check_insn(ctx
, ISA_MIPS3
);
14299 check_mips_64(ctx
);
14300 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14304 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14307 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14310 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14313 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14316 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14319 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14322 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14324 #if defined(TARGET_MIPS64)
14326 check_insn(ctx
, ISA_MIPS3
);
14327 check_mips_64(ctx
);
14328 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14332 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14335 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14338 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14341 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14345 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14348 switch (ctx
->opcode
& 0x3) {
14350 mips32_op
= OPC_ADDU
;
14353 mips32_op
= OPC_SUBU
;
14355 #if defined(TARGET_MIPS64)
14357 mips32_op
= OPC_DADDU
;
14358 check_insn(ctx
, ISA_MIPS3
);
14359 check_mips_64(ctx
);
14362 mips32_op
= OPC_DSUBU
;
14363 check_insn(ctx
, ISA_MIPS3
);
14364 check_mips_64(ctx
);
14368 generate_exception_end(ctx
, EXCP_RI
);
14372 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14381 int nd
= (ctx
->opcode
>> 7) & 0x1;
14382 int link
= (ctx
->opcode
>> 6) & 0x1;
14383 int ra
= (ctx
->opcode
>> 5) & 0x1;
14386 check_insn(ctx
, ISA_MIPS32
);
14395 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14400 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14401 gen_helper_do_semihosting(cpu_env
);
14404 * XXX: not clear which exception should be raised
14405 * when in debug mode...
14407 check_insn(ctx
, ISA_MIPS32
);
14408 generate_exception_end(ctx
, EXCP_DBp
);
14412 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14415 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14418 generate_exception_end(ctx
, EXCP_BREAK
);
14421 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14424 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14427 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14429 #if defined(TARGET_MIPS64)
14431 check_insn(ctx
, ISA_MIPS3
);
14432 check_mips_64(ctx
);
14433 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14437 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14440 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14443 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14446 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14449 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14452 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14455 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14458 check_insn(ctx
, ISA_MIPS32
);
14460 case RR_RY_CNVT_ZEB
:
14461 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14463 case RR_RY_CNVT_ZEH
:
14464 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14466 case RR_RY_CNVT_SEB
:
14467 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14469 case RR_RY_CNVT_SEH
:
14470 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14472 #if defined(TARGET_MIPS64)
14473 case RR_RY_CNVT_ZEW
:
14474 check_insn(ctx
, ISA_MIPS64
);
14475 check_mips_64(ctx
);
14476 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14478 case RR_RY_CNVT_SEW
:
14479 check_insn(ctx
, ISA_MIPS64
);
14480 check_mips_64(ctx
);
14481 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14485 generate_exception_end(ctx
, EXCP_RI
);
14490 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14492 #if defined(TARGET_MIPS64)
14494 check_insn(ctx
, ISA_MIPS3
);
14495 check_mips_64(ctx
);
14496 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14499 check_insn(ctx
, ISA_MIPS3
);
14500 check_mips_64(ctx
);
14501 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14504 check_insn(ctx
, ISA_MIPS3
);
14505 check_mips_64(ctx
);
14506 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14509 check_insn(ctx
, ISA_MIPS3
);
14510 check_mips_64(ctx
);
14511 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14515 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14518 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14521 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14524 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14526 #if defined(TARGET_MIPS64)
14528 check_insn(ctx
, ISA_MIPS3
);
14529 check_mips_64(ctx
);
14530 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14533 check_insn(ctx
, ISA_MIPS3
);
14534 check_mips_64(ctx
);
14535 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14538 check_insn(ctx
, ISA_MIPS3
);
14539 check_mips_64(ctx
);
14540 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14543 check_insn(ctx
, ISA_MIPS3
);
14544 check_mips_64(ctx
);
14545 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14549 generate_exception_end(ctx
, EXCP_RI
);
14553 case M16_OPC_EXTEND
:
14554 decode_extended_mips16_opc(env
, ctx
);
14557 #if defined(TARGET_MIPS64)
14559 funct
= (ctx
->opcode
>> 8) & 0x7;
14560 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
14564 generate_exception_end(ctx
, EXCP_RI
);
14571 /* microMIPS extension to MIPS32/MIPS64 */
14574 * microMIPS32/microMIPS64 major opcodes
14576 * 1. MIPS Architecture for Programmers Volume II-B:
14577 * The microMIPS32 Instruction Set (Revision 3.05)
14579 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14581 * 2. MIPS Architecture For Programmers Volume II-A:
14582 * The MIPS64 Instruction Set (Revision 3.51)
14612 POOL32S
= 0x16, /* MIPS64 */
14613 DADDIU32
= 0x17, /* MIPS64 */
14642 /* 0x29 is reserved */
14655 /* 0x31 is reserved */
14668 SD32
= 0x36, /* MIPS64 */
14669 LD32
= 0x37, /* MIPS64 */
14671 /* 0x39 is reserved */
14687 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14709 /* POOL32A encoding of minor opcode field */
14713 * These opcodes are distinguished only by bits 9..6; those bits are
14714 * what are recorded below.
14752 /* The following can be distinguished by their lower 6 bits. */
14762 /* POOL32AXF encoding of minor opcode field extension */
14765 * 1. MIPS Architecture for Programmers Volume II-B:
14766 * The microMIPS32 Instruction Set (Revision 3.05)
14768 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14770 * 2. MIPS Architecture for Programmers VolumeIV-e:
14771 * The MIPS DSP Application-Specific Extension
14772 * to the microMIPS32 Architecture (Revision 2.34)
14774 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14789 /* begin of microMIPS32 DSP */
14791 /* bits 13..12 for 0x01 */
14797 /* bits 13..12 for 0x2a */
14803 /* bits 13..12 for 0x32 */
14807 /* end of microMIPS32 DSP */
14809 /* bits 15..12 for 0x2c */
14826 /* bits 15..12 for 0x34 */
14834 /* bits 15..12 for 0x3c */
14836 JR
= 0x0, /* alias */
14844 /* bits 15..12 for 0x05 */
14848 /* bits 15..12 for 0x0d */
14860 /* bits 15..12 for 0x15 */
14866 /* bits 15..12 for 0x1d */
14870 /* bits 15..12 for 0x2d */
14875 /* bits 15..12 for 0x35 */
14882 /* POOL32B encoding of minor opcode field (bits 15..12) */
14898 /* POOL32C encoding of minor opcode field (bits 15..12) */
14919 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14932 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14945 /* POOL32F encoding of minor opcode field (bits 5..0) */
14948 /* These are the bit 7..6 values */
14957 /* These are the bit 8..6 values */
14982 MOVZ_FMT_05
= 0x05,
15016 CABS_COND_FMT
= 0x1c, /* MIPS3D */
15023 /* POOL32Fxf encoding of minor opcode extension field */
15061 /* POOL32I encoding of minor opcode field (bits 25..21) */
15091 /* These overlap and are distinguished by bit16 of the instruction */
15100 /* POOL16A encoding of minor opcode field */
15107 /* POOL16B encoding of minor opcode field */
15114 /* POOL16C encoding of minor opcode field */
15134 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15158 /* POOL16D encoding of minor opcode field */
15165 /* POOL16E encoding of minor opcode field */
15172 static int mmreg(int r
)
15174 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15179 /* Used for 16-bit store instructions. */
15180 static int mmreg2(int r
)
15182 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15187 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15188 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15189 #define uMIPS_RS2(op) uMIPS_RS(op)
15190 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15191 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15192 #define uMIPS_RS5(op) (op & 0x1f)
15194 /* Signed immediate */
15195 #define SIMM(op, start, width) \
15196 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15199 /* Zero-extended immediate */
15200 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15202 static void gen_addiur1sp(DisasContext
*ctx
)
15204 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15206 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15209 static void gen_addiur2(DisasContext
*ctx
)
15211 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15212 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15213 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15215 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15218 static void gen_addiusp(DisasContext
*ctx
)
15220 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15223 if (encoded
<= 1) {
15224 decoded
= 256 + encoded
;
15225 } else if (encoded
<= 255) {
15227 } else if (encoded
<= 509) {
15228 decoded
= encoded
- 512;
15230 decoded
= encoded
- 768;
15233 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15236 static void gen_addius5(DisasContext
*ctx
)
15238 int imm
= SIMM(ctx
->opcode
, 1, 4);
15239 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15241 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15244 static void gen_andi16(DisasContext
*ctx
)
15246 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15247 31, 32, 63, 64, 255, 32768, 65535 };
15248 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15249 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15250 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15252 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15255 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15256 int base
, int16_t offset
)
15261 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15262 generate_exception_end(ctx
, EXCP_RI
);
15266 t0
= tcg_temp_new();
15268 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15270 t1
= tcg_const_tl(reglist
);
15271 t2
= tcg_const_i32(ctx
->mem_idx
);
15273 save_cpu_state(ctx
, 1);
15276 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15279 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15281 #ifdef TARGET_MIPS64
15283 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15286 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15292 tcg_temp_free_i32(t2
);
15296 static void gen_pool16c_insn(DisasContext
*ctx
)
15298 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15299 int rs
= mmreg(ctx
->opcode
& 0x7);
15301 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15306 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15312 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15318 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15324 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15331 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15332 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15334 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15343 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15344 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15346 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15353 int reg
= ctx
->opcode
& 0x1f;
15355 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15361 int reg
= ctx
->opcode
& 0x1f;
15362 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15364 * Let normal delay slot handling in our caller take us
15365 * to the branch target.
15371 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15372 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15376 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15377 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15381 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15385 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15388 generate_exception_end(ctx
, EXCP_BREAK
);
15391 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15392 gen_helper_do_semihosting(cpu_env
);
15395 * XXX: not clear which exception should be raised
15396 * when in debug mode...
15398 check_insn(ctx
, ISA_MIPS32
);
15399 generate_exception_end(ctx
, EXCP_DBp
);
15402 case JRADDIUSP
+ 0:
15403 case JRADDIUSP
+ 1:
15405 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15406 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15407 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15409 * Let normal delay slot handling in our caller take us
15410 * to the branch target.
15415 generate_exception_end(ctx
, EXCP_RI
);
15420 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15423 int rd
, rs
, re
, rt
;
15424 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15425 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15426 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15427 rd
= rd_enc
[enc_dest
];
15428 re
= re_enc
[enc_dest
];
15429 rs
= rs_rt_enc
[enc_rs
];
15430 rt
= rs_rt_enc
[enc_rt
];
15432 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15434 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15437 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15439 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15443 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15445 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15446 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15448 switch (ctx
->opcode
& 0xf) {
15450 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15453 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15457 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15458 int offset
= extract32(ctx
->opcode
, 4, 4);
15459 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15462 case R6_JRC16
: /* JRCADDIUSP */
15463 if ((ctx
->opcode
>> 4) & 1) {
15465 int imm
= extract32(ctx
->opcode
, 5, 5);
15466 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15467 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15470 rs
= extract32(ctx
->opcode
, 5, 5);
15471 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15483 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15484 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15485 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15486 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15490 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15493 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15497 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15498 int offset
= extract32(ctx
->opcode
, 4, 4);
15499 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15502 case JALRC16
: /* BREAK16, SDBBP16 */
15503 switch (ctx
->opcode
& 0x3f) {
15505 case JALRC16
+ 0x20:
15507 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15512 generate_exception(ctx
, EXCP_BREAK
);
15516 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15517 gen_helper_do_semihosting(cpu_env
);
15519 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15520 generate_exception(ctx
, EXCP_RI
);
15522 generate_exception(ctx
, EXCP_DBp
);
15529 generate_exception(ctx
, EXCP_RI
);
15534 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15536 TCGv t0
= tcg_temp_new();
15537 TCGv t1
= tcg_temp_new();
15539 gen_load_gpr(t0
, base
);
15542 gen_load_gpr(t1
, index
);
15543 tcg_gen_shli_tl(t1
, t1
, 2);
15544 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15547 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15548 gen_store_gpr(t1
, rd
);
15554 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15555 int base
, int16_t offset
)
15559 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15560 generate_exception_end(ctx
, EXCP_RI
);
15564 t0
= tcg_temp_new();
15565 t1
= tcg_temp_new();
15567 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15572 generate_exception_end(ctx
, EXCP_RI
);
15575 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15576 gen_store_gpr(t1
, rd
);
15577 tcg_gen_movi_tl(t1
, 4);
15578 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15579 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15580 gen_store_gpr(t1
, rd
+ 1);
15583 gen_load_gpr(t1
, rd
);
15584 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15585 tcg_gen_movi_tl(t1
, 4);
15586 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15587 gen_load_gpr(t1
, rd
+ 1);
15588 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15590 #ifdef TARGET_MIPS64
15593 generate_exception_end(ctx
, EXCP_RI
);
15596 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15597 gen_store_gpr(t1
, rd
);
15598 tcg_gen_movi_tl(t1
, 8);
15599 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15600 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15601 gen_store_gpr(t1
, rd
+ 1);
15604 gen_load_gpr(t1
, rd
);
15605 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15606 tcg_gen_movi_tl(t1
, 8);
15607 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15608 gen_load_gpr(t1
, rd
+ 1);
15609 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15617 static void gen_sync(int stype
)
15619 TCGBar tcg_mo
= TCG_BAR_SC
;
15622 case 0x4: /* SYNC_WMB */
15623 tcg_mo
|= TCG_MO_ST_ST
;
15625 case 0x10: /* SYNC_MB */
15626 tcg_mo
|= TCG_MO_ALL
;
15628 case 0x11: /* SYNC_ACQUIRE */
15629 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
15631 case 0x12: /* SYNC_RELEASE */
15632 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
15634 case 0x13: /* SYNC_RMB */
15635 tcg_mo
|= TCG_MO_LD_LD
;
15638 tcg_mo
|= TCG_MO_ALL
;
15642 tcg_gen_mb(tcg_mo
);
15645 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
15647 int extension
= (ctx
->opcode
>> 6) & 0x3f;
15648 int minor
= (ctx
->opcode
>> 12) & 0xf;
15649 uint32_t mips32_op
;
15651 switch (extension
) {
15653 mips32_op
= OPC_TEQ
;
15656 mips32_op
= OPC_TGE
;
15659 mips32_op
= OPC_TGEU
;
15662 mips32_op
= OPC_TLT
;
15665 mips32_op
= OPC_TLTU
;
15668 mips32_op
= OPC_TNE
;
15670 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
15672 #ifndef CONFIG_USER_ONLY
15675 check_cp0_enabled(ctx
);
15677 /* Treat as NOP. */
15680 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
15684 check_cp0_enabled(ctx
);
15686 TCGv t0
= tcg_temp_new();
15688 gen_load_gpr(t0
, rt
);
15689 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
15695 switch (minor
& 3) {
15697 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15700 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15703 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15706 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15709 goto pool32axf_invalid
;
15713 switch (minor
& 3) {
15715 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15718 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15721 goto pool32axf_invalid
;
15727 check_insn(ctx
, ISA_MIPS32R6
);
15728 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
15731 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
15734 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
15737 mips32_op
= OPC_CLO
;
15740 mips32_op
= OPC_CLZ
;
15742 check_insn(ctx
, ISA_MIPS32
);
15743 gen_cl(ctx
, mips32_op
, rt
, rs
);
15746 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15747 gen_rdhwr(ctx
, rt
, rs
, 0);
15750 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
15753 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15754 mips32_op
= OPC_MULT
;
15757 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15758 mips32_op
= OPC_MULTU
;
15761 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15762 mips32_op
= OPC_DIV
;
15765 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15766 mips32_op
= OPC_DIVU
;
15769 check_insn(ctx
, ISA_MIPS32
);
15770 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15773 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15774 mips32_op
= OPC_MADD
;
15777 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15778 mips32_op
= OPC_MADDU
;
15781 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15782 mips32_op
= OPC_MSUB
;
15785 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15786 mips32_op
= OPC_MSUBU
;
15788 check_insn(ctx
, ISA_MIPS32
);
15789 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15792 goto pool32axf_invalid
;
15803 generate_exception_err(ctx
, EXCP_CpU
, 2);
15806 goto pool32axf_invalid
;
15811 case JALR
: /* JALRC */
15812 case JALR_HB
: /* JALRC_HB */
15813 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15814 /* JALRC, JALRC_HB */
15815 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
15817 /* JALR, JALR_HB */
15818 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
15819 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15824 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15825 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
15826 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15829 goto pool32axf_invalid
;
15835 check_cp0_enabled(ctx
);
15836 check_insn(ctx
, ISA_MIPS32R2
);
15837 gen_load_srsgpr(rs
, rt
);
15840 check_cp0_enabled(ctx
);
15841 check_insn(ctx
, ISA_MIPS32R2
);
15842 gen_store_srsgpr(rs
, rt
);
15845 goto pool32axf_invalid
;
15848 #ifndef CONFIG_USER_ONLY
15852 mips32_op
= OPC_TLBP
;
15855 mips32_op
= OPC_TLBR
;
15858 mips32_op
= OPC_TLBWI
;
15861 mips32_op
= OPC_TLBWR
;
15864 mips32_op
= OPC_TLBINV
;
15867 mips32_op
= OPC_TLBINVF
;
15870 mips32_op
= OPC_WAIT
;
15873 mips32_op
= OPC_DERET
;
15876 mips32_op
= OPC_ERET
;
15878 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
15881 goto pool32axf_invalid
;
15887 check_cp0_enabled(ctx
);
15889 TCGv t0
= tcg_temp_new();
15891 save_cpu_state(ctx
, 1);
15892 gen_helper_di(t0
, cpu_env
);
15893 gen_store_gpr(t0
, rs
);
15895 * Stop translation as we may have switched the execution
15898 ctx
->base
.is_jmp
= DISAS_STOP
;
15903 check_cp0_enabled(ctx
);
15905 TCGv t0
= tcg_temp_new();
15907 save_cpu_state(ctx
, 1);
15908 gen_helper_ei(t0
, cpu_env
);
15909 gen_store_gpr(t0
, rs
);
15911 * DISAS_STOP isn't sufficient, we need to ensure we break out
15912 * of translated code to check for pending interrupts.
15914 gen_save_pc(ctx
->base
.pc_next
+ 4);
15915 ctx
->base
.is_jmp
= DISAS_EXIT
;
15920 goto pool32axf_invalid
;
15927 gen_sync(extract32(ctx
->opcode
, 16, 5));
15930 generate_exception_end(ctx
, EXCP_SYSCALL
);
15933 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
15934 gen_helper_do_semihosting(cpu_env
);
15936 check_insn(ctx
, ISA_MIPS32
);
15937 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15938 generate_exception_end(ctx
, EXCP_RI
);
15940 generate_exception_end(ctx
, EXCP_DBp
);
15945 goto pool32axf_invalid
;
15949 switch (minor
& 3) {
15951 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
15954 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
15957 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
15960 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
15963 goto pool32axf_invalid
;
15967 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15970 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
15973 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
15976 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
15979 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
15982 goto pool32axf_invalid
;
15987 MIPS_INVAL("pool32axf");
15988 generate_exception_end(ctx
, EXCP_RI
);
15994 * Values for microMIPS fmt field. Variable-width, depending on which
15995 * formats the instruction supports.
16014 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
16016 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
16017 uint32_t mips32_op
;
16019 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
16020 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
16021 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
16023 switch (extension
) {
16024 case FLOAT_1BIT_FMT(CFC1
, 0):
16025 mips32_op
= OPC_CFC1
;
16027 case FLOAT_1BIT_FMT(CTC1
, 0):
16028 mips32_op
= OPC_CTC1
;
16030 case FLOAT_1BIT_FMT(MFC1
, 0):
16031 mips32_op
= OPC_MFC1
;
16033 case FLOAT_1BIT_FMT(MTC1
, 0):
16034 mips32_op
= OPC_MTC1
;
16036 case FLOAT_1BIT_FMT(MFHC1
, 0):
16037 mips32_op
= OPC_MFHC1
;
16039 case FLOAT_1BIT_FMT(MTHC1
, 0):
16040 mips32_op
= OPC_MTHC1
;
16042 gen_cp1(ctx
, mips32_op
, rt
, rs
);
16045 /* Reciprocal square root */
16046 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
16047 mips32_op
= OPC_RSQRT_S
;
16049 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
16050 mips32_op
= OPC_RSQRT_D
;
16054 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
16055 mips32_op
= OPC_SQRT_S
;
16057 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
16058 mips32_op
= OPC_SQRT_D
;
16062 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
16063 mips32_op
= OPC_RECIP_S
;
16065 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
16066 mips32_op
= OPC_RECIP_D
;
16070 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
16071 mips32_op
= OPC_FLOOR_L_S
;
16073 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
16074 mips32_op
= OPC_FLOOR_L_D
;
16076 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
16077 mips32_op
= OPC_FLOOR_W_S
;
16079 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
16080 mips32_op
= OPC_FLOOR_W_D
;
16084 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
16085 mips32_op
= OPC_CEIL_L_S
;
16087 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
16088 mips32_op
= OPC_CEIL_L_D
;
16090 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
16091 mips32_op
= OPC_CEIL_W_S
;
16093 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
16094 mips32_op
= OPC_CEIL_W_D
;
16098 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
16099 mips32_op
= OPC_TRUNC_L_S
;
16101 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
16102 mips32_op
= OPC_TRUNC_L_D
;
16104 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
16105 mips32_op
= OPC_TRUNC_W_S
;
16107 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
16108 mips32_op
= OPC_TRUNC_W_D
;
16112 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
16113 mips32_op
= OPC_ROUND_L_S
;
16115 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
16116 mips32_op
= OPC_ROUND_L_D
;
16118 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
16119 mips32_op
= OPC_ROUND_W_S
;
16121 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
16122 mips32_op
= OPC_ROUND_W_D
;
16125 /* Integer to floating-point conversion */
16126 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
16127 mips32_op
= OPC_CVT_L_S
;
16129 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
16130 mips32_op
= OPC_CVT_L_D
;
16132 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
16133 mips32_op
= OPC_CVT_W_S
;
16135 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
16136 mips32_op
= OPC_CVT_W_D
;
16139 /* Paired-foo conversions */
16140 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
16141 mips32_op
= OPC_CVT_S_PL
;
16143 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
16144 mips32_op
= OPC_CVT_S_PU
;
16146 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
16147 mips32_op
= OPC_CVT_PW_PS
;
16149 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
16150 mips32_op
= OPC_CVT_PS_PW
;
16153 /* Floating-point moves */
16154 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
16155 mips32_op
= OPC_MOV_S
;
16157 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
16158 mips32_op
= OPC_MOV_D
;
16160 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
16161 mips32_op
= OPC_MOV_PS
;
16164 /* Absolute value */
16165 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
16166 mips32_op
= OPC_ABS_S
;
16168 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
16169 mips32_op
= OPC_ABS_D
;
16171 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
16172 mips32_op
= OPC_ABS_PS
;
16176 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
16177 mips32_op
= OPC_NEG_S
;
16179 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
16180 mips32_op
= OPC_NEG_D
;
16182 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16183 mips32_op
= OPC_NEG_PS
;
16186 /* Reciprocal square root step */
16187 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16188 mips32_op
= OPC_RSQRT1_S
;
16190 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16191 mips32_op
= OPC_RSQRT1_D
;
16193 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16194 mips32_op
= OPC_RSQRT1_PS
;
16197 /* Reciprocal step */
16198 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16199 mips32_op
= OPC_RECIP1_S
;
16201 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16202 mips32_op
= OPC_RECIP1_S
;
16204 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16205 mips32_op
= OPC_RECIP1_PS
;
16208 /* Conversions from double */
16209 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16210 mips32_op
= OPC_CVT_D_S
;
16212 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16213 mips32_op
= OPC_CVT_D_W
;
16215 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16216 mips32_op
= OPC_CVT_D_L
;
16219 /* Conversions from single */
16220 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16221 mips32_op
= OPC_CVT_S_D
;
16223 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16224 mips32_op
= OPC_CVT_S_W
;
16226 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16227 mips32_op
= OPC_CVT_S_L
;
16229 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16232 /* Conditional moves on floating-point codes */
16233 case COND_FLOAT_MOV(MOVT
, 0):
16234 case COND_FLOAT_MOV(MOVT
, 1):
16235 case COND_FLOAT_MOV(MOVT
, 2):
16236 case COND_FLOAT_MOV(MOVT
, 3):
16237 case COND_FLOAT_MOV(MOVT
, 4):
16238 case COND_FLOAT_MOV(MOVT
, 5):
16239 case COND_FLOAT_MOV(MOVT
, 6):
16240 case COND_FLOAT_MOV(MOVT
, 7):
16241 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16242 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16244 case COND_FLOAT_MOV(MOVF
, 0):
16245 case COND_FLOAT_MOV(MOVF
, 1):
16246 case COND_FLOAT_MOV(MOVF
, 2):
16247 case COND_FLOAT_MOV(MOVF
, 3):
16248 case COND_FLOAT_MOV(MOVF
, 4):
16249 case COND_FLOAT_MOV(MOVF
, 5):
16250 case COND_FLOAT_MOV(MOVF
, 6):
16251 case COND_FLOAT_MOV(MOVF
, 7):
16252 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16253 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16256 MIPS_INVAL("pool32fxf");
16257 generate_exception_end(ctx
, EXCP_RI
);
16262 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16266 int rt
, rs
, rd
, rr
;
16268 uint32_t op
, minor
, minor2
, mips32_op
;
16269 uint32_t cond
, fmt
, cc
;
16271 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
16272 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16274 rt
= (ctx
->opcode
>> 21) & 0x1f;
16275 rs
= (ctx
->opcode
>> 16) & 0x1f;
16276 rd
= (ctx
->opcode
>> 11) & 0x1f;
16277 rr
= (ctx
->opcode
>> 6) & 0x1f;
16278 imm
= (int16_t) ctx
->opcode
;
16280 op
= (ctx
->opcode
>> 26) & 0x3f;
16283 minor
= ctx
->opcode
& 0x3f;
16286 minor
= (ctx
->opcode
>> 6) & 0xf;
16289 mips32_op
= OPC_SLL
;
16292 mips32_op
= OPC_SRA
;
16295 mips32_op
= OPC_SRL
;
16298 mips32_op
= OPC_ROTR
;
16300 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16303 check_insn(ctx
, ISA_MIPS32R6
);
16304 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16307 check_insn(ctx
, ISA_MIPS32R6
);
16308 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16311 check_insn(ctx
, ISA_MIPS32R6
);
16312 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16315 goto pool32a_invalid
;
16319 minor
= (ctx
->opcode
>> 6) & 0xf;
16323 mips32_op
= OPC_ADD
;
16326 mips32_op
= OPC_ADDU
;
16329 mips32_op
= OPC_SUB
;
16332 mips32_op
= OPC_SUBU
;
16335 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16336 mips32_op
= OPC_MUL
;
16338 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16342 mips32_op
= OPC_SLLV
;
16345 mips32_op
= OPC_SRLV
;
16348 mips32_op
= OPC_SRAV
;
16351 mips32_op
= OPC_ROTRV
;
16353 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16355 /* Logical operations */
16357 mips32_op
= OPC_AND
;
16360 mips32_op
= OPC_OR
;
16363 mips32_op
= OPC_NOR
;
16366 mips32_op
= OPC_XOR
;
16368 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16370 /* Set less than */
16372 mips32_op
= OPC_SLT
;
16375 mips32_op
= OPC_SLTU
;
16377 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16380 goto pool32a_invalid
;
16384 minor
= (ctx
->opcode
>> 6) & 0xf;
16386 /* Conditional moves */
16387 case MOVN
: /* MUL */
16388 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16390 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16393 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16396 case MOVZ
: /* MUH */
16397 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16399 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16402 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16406 check_insn(ctx
, ISA_MIPS32R6
);
16407 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16410 check_insn(ctx
, ISA_MIPS32R6
);
16411 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16413 case LWXS
: /* DIV */
16414 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16416 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16419 gen_ldxs(ctx
, rs
, rt
, rd
);
16423 check_insn(ctx
, ISA_MIPS32R6
);
16424 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16427 check_insn(ctx
, ISA_MIPS32R6
);
16428 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16431 check_insn(ctx
, ISA_MIPS32R6
);
16432 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16435 goto pool32a_invalid
;
16439 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16442 check_insn(ctx
, ISA_MIPS32R6
);
16443 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
16444 extract32(ctx
->opcode
, 9, 2));
16447 check_insn(ctx
, ISA_MIPS32R6
);
16448 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16451 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16454 gen_pool32axf(env
, ctx
, rt
, rs
);
16457 generate_exception_end(ctx
, EXCP_BREAK
);
16460 check_insn(ctx
, ISA_MIPS32R6
);
16461 generate_exception_end(ctx
, EXCP_RI
);
16465 MIPS_INVAL("pool32a");
16466 generate_exception_end(ctx
, EXCP_RI
);
16471 minor
= (ctx
->opcode
>> 12) & 0xf;
16474 check_cp0_enabled(ctx
);
16475 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16476 gen_cache_operation(ctx
, rt
, rs
, imm
);
16481 /* COP2: Not implemented. */
16482 generate_exception_err(ctx
, EXCP_CpU
, 2);
16484 #ifdef TARGET_MIPS64
16487 check_insn(ctx
, ISA_MIPS3
);
16488 check_mips_64(ctx
);
16493 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16495 #ifdef TARGET_MIPS64
16498 check_insn(ctx
, ISA_MIPS3
);
16499 check_mips_64(ctx
);
16504 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16507 MIPS_INVAL("pool32b");
16508 generate_exception_end(ctx
, EXCP_RI
);
16513 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16514 minor
= ctx
->opcode
& 0x3f;
16515 check_cp1_enabled(ctx
);
16518 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16519 mips32_op
= OPC_ALNV_PS
;
16522 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16523 mips32_op
= OPC_MADD_S
;
16526 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16527 mips32_op
= OPC_MADD_D
;
16530 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16531 mips32_op
= OPC_MADD_PS
;
16534 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16535 mips32_op
= OPC_MSUB_S
;
16538 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16539 mips32_op
= OPC_MSUB_D
;
16542 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16543 mips32_op
= OPC_MSUB_PS
;
16546 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16547 mips32_op
= OPC_NMADD_S
;
16550 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16551 mips32_op
= OPC_NMADD_D
;
16554 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16555 mips32_op
= OPC_NMADD_PS
;
16558 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16559 mips32_op
= OPC_NMSUB_S
;
16562 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16563 mips32_op
= OPC_NMSUB_D
;
16566 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16567 mips32_op
= OPC_NMSUB_PS
;
16569 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
16571 case CABS_COND_FMT
:
16572 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16573 cond
= (ctx
->opcode
>> 6) & 0xf;
16574 cc
= (ctx
->opcode
>> 13) & 0x7;
16575 fmt
= (ctx
->opcode
>> 10) & 0x3;
16578 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
16581 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
16584 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
16587 goto pool32f_invalid
;
16591 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16592 cond
= (ctx
->opcode
>> 6) & 0xf;
16593 cc
= (ctx
->opcode
>> 13) & 0x7;
16594 fmt
= (ctx
->opcode
>> 10) & 0x3;
16597 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
16600 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
16603 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
16606 goto pool32f_invalid
;
16610 check_insn(ctx
, ISA_MIPS32R6
);
16611 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16614 check_insn(ctx
, ISA_MIPS32R6
);
16615 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16618 gen_pool32fxf(ctx
, rt
, rs
);
16622 switch ((ctx
->opcode
>> 6) & 0x7) {
16624 mips32_op
= OPC_PLL_PS
;
16627 mips32_op
= OPC_PLU_PS
;
16630 mips32_op
= OPC_PUL_PS
;
16633 mips32_op
= OPC_PUU_PS
;
16636 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16637 mips32_op
= OPC_CVT_PS_S
;
16639 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16642 goto pool32f_invalid
;
16646 check_insn(ctx
, ISA_MIPS32R6
);
16647 switch ((ctx
->opcode
>> 9) & 0x3) {
16649 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
16652 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
16655 goto pool32f_invalid
;
16660 switch ((ctx
->opcode
>> 6) & 0x7) {
16662 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16663 mips32_op
= OPC_LWXC1
;
16666 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16667 mips32_op
= OPC_SWXC1
;
16670 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16671 mips32_op
= OPC_LDXC1
;
16674 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16675 mips32_op
= OPC_SDXC1
;
16678 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16679 mips32_op
= OPC_LUXC1
;
16682 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16683 mips32_op
= OPC_SUXC1
;
16685 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
16688 goto pool32f_invalid
;
16692 check_insn(ctx
, ISA_MIPS32R6
);
16693 switch ((ctx
->opcode
>> 9) & 0x3) {
16695 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
16698 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
16701 goto pool32f_invalid
;
16706 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16707 fmt
= (ctx
->opcode
>> 9) & 0x3;
16708 switch ((ctx
->opcode
>> 6) & 0x7) {
16712 mips32_op
= OPC_RSQRT2_S
;
16715 mips32_op
= OPC_RSQRT2_D
;
16718 mips32_op
= OPC_RSQRT2_PS
;
16721 goto pool32f_invalid
;
16727 mips32_op
= OPC_RECIP2_S
;
16730 mips32_op
= OPC_RECIP2_D
;
16733 mips32_op
= OPC_RECIP2_PS
;
16736 goto pool32f_invalid
;
16740 mips32_op
= OPC_ADDR_PS
;
16743 mips32_op
= OPC_MULR_PS
;
16745 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16748 goto pool32f_invalid
;
16752 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16753 cc
= (ctx
->opcode
>> 13) & 0x7;
16754 fmt
= (ctx
->opcode
>> 9) & 0x3;
16755 switch ((ctx
->opcode
>> 6) & 0x7) {
16756 case MOVF_FMT
: /* RINT_FMT */
16757 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16761 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
16764 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
16767 goto pool32f_invalid
;
16773 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
16776 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
16780 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
16783 goto pool32f_invalid
;
16787 case MOVT_FMT
: /* CLASS_FMT */
16788 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16792 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
16795 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
16798 goto pool32f_invalid
;
16804 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
16807 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
16811 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
16814 goto pool32f_invalid
;
16819 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16822 goto pool32f_invalid
;
16825 #define FINSN_3ARG_SDPS(prfx) \
16826 switch ((ctx->opcode >> 8) & 0x3) { \
16828 mips32_op = OPC_##prfx##_S; \
16831 mips32_op = OPC_##prfx##_D; \
16833 case FMT_SDPS_PS: \
16835 mips32_op = OPC_##prfx##_PS; \
16838 goto pool32f_invalid; \
16841 check_insn(ctx
, ISA_MIPS32R6
);
16842 switch ((ctx
->opcode
>> 9) & 0x3) {
16844 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
16847 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
16850 goto pool32f_invalid
;
16854 check_insn(ctx
, ISA_MIPS32R6
);
16855 switch ((ctx
->opcode
>> 9) & 0x3) {
16857 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
16860 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
16863 goto pool32f_invalid
;
16867 /* regular FP ops */
16868 switch ((ctx
->opcode
>> 6) & 0x3) {
16870 FINSN_3ARG_SDPS(ADD
);
16873 FINSN_3ARG_SDPS(SUB
);
16876 FINSN_3ARG_SDPS(MUL
);
16879 fmt
= (ctx
->opcode
>> 8) & 0x3;
16881 mips32_op
= OPC_DIV_D
;
16882 } else if (fmt
== 0) {
16883 mips32_op
= OPC_DIV_S
;
16885 goto pool32f_invalid
;
16889 goto pool32f_invalid
;
16894 switch ((ctx
->opcode
>> 6) & 0x7) {
16895 case MOVN_FMT
: /* SELEQZ_FMT */
16896 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16898 switch ((ctx
->opcode
>> 9) & 0x3) {
16900 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
16903 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
16906 goto pool32f_invalid
;
16910 FINSN_3ARG_SDPS(MOVN
);
16914 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16915 FINSN_3ARG_SDPS(MOVN
);
16917 case MOVZ_FMT
: /* SELNEZ_FMT */
16918 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16920 switch ((ctx
->opcode
>> 9) & 0x3) {
16922 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
16925 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
16928 goto pool32f_invalid
;
16932 FINSN_3ARG_SDPS(MOVZ
);
16936 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16937 FINSN_3ARG_SDPS(MOVZ
);
16940 check_insn(ctx
, ISA_MIPS32R6
);
16941 switch ((ctx
->opcode
>> 9) & 0x3) {
16943 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
16946 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
16949 goto pool32f_invalid
;
16953 check_insn(ctx
, ISA_MIPS32R6
);
16954 switch ((ctx
->opcode
>> 9) & 0x3) {
16956 mips32_op
= OPC_MADDF_S
;
16959 mips32_op
= OPC_MADDF_D
;
16962 goto pool32f_invalid
;
16966 check_insn(ctx
, ISA_MIPS32R6
);
16967 switch ((ctx
->opcode
>> 9) & 0x3) {
16969 mips32_op
= OPC_MSUBF_S
;
16972 mips32_op
= OPC_MSUBF_D
;
16975 goto pool32f_invalid
;
16979 goto pool32f_invalid
;
16983 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16987 MIPS_INVAL("pool32f");
16988 generate_exception_end(ctx
, EXCP_RI
);
16992 generate_exception_err(ctx
, EXCP_CpU
, 1);
16996 minor
= (ctx
->opcode
>> 21) & 0x1f;
16999 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17000 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
17003 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17004 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
17005 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17008 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17009 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
17010 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17013 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17014 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
17017 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17018 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
17019 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17022 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17023 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
17024 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17027 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17028 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
17031 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17032 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
17036 case TLTI
: /* BC1EQZC */
17037 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17039 check_cp1_enabled(ctx
);
17040 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
17043 mips32_op
= OPC_TLTI
;
17047 case TGEI
: /* BC1NEZC */
17048 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17050 check_cp1_enabled(ctx
);
17051 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
17054 mips32_op
= OPC_TGEI
;
17059 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17060 mips32_op
= OPC_TLTIU
;
17063 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17064 mips32_op
= OPC_TGEIU
;
17066 case TNEI
: /* SYNCI */
17067 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17070 * Break the TB to be able to sync copied instructions
17073 ctx
->base
.is_jmp
= DISAS_STOP
;
17076 mips32_op
= OPC_TNEI
;
17081 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17082 mips32_op
= OPC_TEQI
;
17084 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
17089 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17090 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
17091 4, rs
, 0, imm
<< 1, 0);
17093 * Compact branches don't have a delay slot, so just let
17094 * the normal delay slot handling take us to the branch
17099 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17100 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
17103 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17105 * Break the TB to be able to sync copied instructions
17108 ctx
->base
.is_jmp
= DISAS_STOP
;
17112 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17113 /* COP2: Not implemented. */
17114 generate_exception_err(ctx
, EXCP_CpU
, 2);
17117 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17118 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
17121 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17122 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
17125 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17126 mips32_op
= OPC_BC1FANY4
;
17129 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17130 mips32_op
= OPC_BC1TANY4
;
17133 check_insn(ctx
, ASE_MIPS3D
);
17136 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17137 check_cp1_enabled(ctx
);
17138 gen_compute_branch1(ctx
, mips32_op
,
17139 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
17141 generate_exception_err(ctx
, EXCP_CpU
, 1);
17146 /* MIPS DSP: not implemented */
17149 MIPS_INVAL("pool32i");
17150 generate_exception_end(ctx
, EXCP_RI
);
17155 minor
= (ctx
->opcode
>> 12) & 0xf;
17156 offset
= sextract32(ctx
->opcode
, 0,
17157 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
17160 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17161 mips32_op
= OPC_LWL
;
17164 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17165 mips32_op
= OPC_SWL
;
17168 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17169 mips32_op
= OPC_LWR
;
17172 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17173 mips32_op
= OPC_SWR
;
17175 #if defined(TARGET_MIPS64)
17177 check_insn(ctx
, ISA_MIPS3
);
17178 check_mips_64(ctx
);
17179 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17180 mips32_op
= OPC_LDL
;
17183 check_insn(ctx
, ISA_MIPS3
);
17184 check_mips_64(ctx
);
17185 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17186 mips32_op
= OPC_SDL
;
17189 check_insn(ctx
, ISA_MIPS3
);
17190 check_mips_64(ctx
);
17191 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17192 mips32_op
= OPC_LDR
;
17195 check_insn(ctx
, ISA_MIPS3
);
17196 check_mips_64(ctx
);
17197 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17198 mips32_op
= OPC_SDR
;
17201 check_insn(ctx
, ISA_MIPS3
);
17202 check_mips_64(ctx
);
17203 mips32_op
= OPC_LWU
;
17206 check_insn(ctx
, ISA_MIPS3
);
17207 check_mips_64(ctx
);
17208 mips32_op
= OPC_LLD
;
17212 mips32_op
= OPC_LL
;
17215 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17218 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17221 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17223 #if defined(TARGET_MIPS64)
17225 check_insn(ctx
, ISA_MIPS3
);
17226 check_mips_64(ctx
);
17227 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17232 MIPS_INVAL("pool32c ld-eva");
17233 generate_exception_end(ctx
, EXCP_RI
);
17236 check_cp0_enabled(ctx
);
17238 minor2
= (ctx
->opcode
>> 9) & 0x7;
17239 offset
= sextract32(ctx
->opcode
, 0, 9);
17242 mips32_op
= OPC_LBUE
;
17245 mips32_op
= OPC_LHUE
;
17248 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17249 mips32_op
= OPC_LWLE
;
17252 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17253 mips32_op
= OPC_LWRE
;
17256 mips32_op
= OPC_LBE
;
17259 mips32_op
= OPC_LHE
;
17262 mips32_op
= OPC_LLE
;
17265 mips32_op
= OPC_LWE
;
17271 MIPS_INVAL("pool32c st-eva");
17272 generate_exception_end(ctx
, EXCP_RI
);
17275 check_cp0_enabled(ctx
);
17277 minor2
= (ctx
->opcode
>> 9) & 0x7;
17278 offset
= sextract32(ctx
->opcode
, 0, 9);
17281 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17282 mips32_op
= OPC_SWLE
;
17285 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17286 mips32_op
= OPC_SWRE
;
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 /* Treat as no-op */
17297 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17298 gen_cache_operation(ctx
, rt
, rs
, offset
);
17302 mips32_op
= OPC_SBE
;
17305 mips32_op
= OPC_SHE
;
17308 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17311 mips32_op
= OPC_SWE
;
17316 /* Treat as no-op */
17317 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17318 /* hint codes 24-31 are reserved and signal RI */
17319 generate_exception(ctx
, EXCP_RI
);
17323 MIPS_INVAL("pool32c");
17324 generate_exception_end(ctx
, EXCP_RI
);
17328 case ADDI32
: /* AUI, LUI */
17329 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17331 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17334 mips32_op
= OPC_ADDI
;
17339 mips32_op
= OPC_ADDIU
;
17341 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17344 /* Logical operations */
17346 mips32_op
= OPC_ORI
;
17349 mips32_op
= OPC_XORI
;
17352 mips32_op
= OPC_ANDI
;
17354 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17357 /* Set less than immediate */
17359 mips32_op
= OPC_SLTI
;
17362 mips32_op
= OPC_SLTIU
;
17364 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17367 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17368 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17369 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17370 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17372 case JALS32
: /* BOVC, BEQC, BEQZALC */
17373 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17376 mips32_op
= OPC_BOVC
;
17377 } else if (rs
< rt
&& rs
== 0) {
17379 mips32_op
= OPC_BEQZALC
;
17382 mips32_op
= OPC_BEQC
;
17384 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17387 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17388 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17389 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17392 case BEQ32
: /* BC */
17393 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17395 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17396 sextract32(ctx
->opcode
<< 1, 0, 27));
17399 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17402 case BNE32
: /* BALC */
17403 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17405 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17406 sextract32(ctx
->opcode
<< 1, 0, 27));
17409 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17412 case J32
: /* BGTZC, BLTZC, BLTC */
17413 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17414 if (rs
== 0 && rt
!= 0) {
17416 mips32_op
= OPC_BGTZC
;
17417 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17419 mips32_op
= OPC_BLTZC
;
17422 mips32_op
= OPC_BLTC
;
17424 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17427 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17428 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17431 case JAL32
: /* BLEZC, BGEZC, BGEC */
17432 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17433 if (rs
== 0 && rt
!= 0) {
17435 mips32_op
= OPC_BLEZC
;
17436 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17438 mips32_op
= OPC_BGEZC
;
17441 mips32_op
= OPC_BGEC
;
17443 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17446 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17447 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17448 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17451 /* Floating point (COP1) */
17453 mips32_op
= OPC_LWC1
;
17456 mips32_op
= OPC_LDC1
;
17459 mips32_op
= OPC_SWC1
;
17462 mips32_op
= OPC_SDC1
;
17464 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17466 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17467 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17468 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17469 switch ((ctx
->opcode
>> 16) & 0x1f) {
17478 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17481 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17484 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17494 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17497 generate_exception(ctx
, EXCP_RI
);
17502 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17503 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17505 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17508 case BNVC
: /* BNEC, BNEZALC */
17509 check_insn(ctx
, ISA_MIPS32R6
);
17512 mips32_op
= OPC_BNVC
;
17513 } else if (rs
< rt
&& rs
== 0) {
17515 mips32_op
= OPC_BNEZALC
;
17518 mips32_op
= OPC_BNEC
;
17520 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17522 case R6_BNEZC
: /* JIALC */
17523 check_insn(ctx
, ISA_MIPS32R6
);
17526 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17527 sextract32(ctx
->opcode
<< 1, 0, 22));
17530 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17533 case R6_BEQZC
: /* JIC */
17534 check_insn(ctx
, ISA_MIPS32R6
);
17537 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17538 sextract32(ctx
->opcode
<< 1, 0, 22));
17541 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17544 case BLEZALC
: /* BGEZALC, BGEUC */
17545 check_insn(ctx
, ISA_MIPS32R6
);
17546 if (rs
== 0 && rt
!= 0) {
17548 mips32_op
= OPC_BLEZALC
;
17549 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17551 mips32_op
= OPC_BGEZALC
;
17554 mips32_op
= OPC_BGEUC
;
17556 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17558 case BGTZALC
: /* BLTZALC, BLTUC */
17559 check_insn(ctx
, ISA_MIPS32R6
);
17560 if (rs
== 0 && rt
!= 0) {
17562 mips32_op
= OPC_BGTZALC
;
17563 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17565 mips32_op
= OPC_BLTZALC
;
17568 mips32_op
= OPC_BLTUC
;
17570 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17572 /* Loads and stores */
17574 mips32_op
= OPC_LB
;
17577 mips32_op
= OPC_LBU
;
17580 mips32_op
= OPC_LH
;
17583 mips32_op
= OPC_LHU
;
17586 mips32_op
= OPC_LW
;
17588 #ifdef TARGET_MIPS64
17590 check_insn(ctx
, ISA_MIPS3
);
17591 check_mips_64(ctx
);
17592 mips32_op
= OPC_LD
;
17595 check_insn(ctx
, ISA_MIPS3
);
17596 check_mips_64(ctx
);
17597 mips32_op
= OPC_SD
;
17601 mips32_op
= OPC_SB
;
17604 mips32_op
= OPC_SH
;
17607 mips32_op
= OPC_SW
;
17610 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
17613 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
17616 generate_exception_end(ctx
, EXCP_RI
);
17621 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
17625 /* make sure instructions are on a halfword boundary */
17626 if (ctx
->base
.pc_next
& 0x1) {
17627 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
17628 generate_exception_end(ctx
, EXCP_AdEL
);
17632 op
= (ctx
->opcode
>> 10) & 0x3f;
17633 /* Enforce properly-sized instructions in a delay slot */
17634 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
17635 switch (op
& 0x7) { /* MSB-3..MSB-5 */
17637 /* POOL32A, POOL32B, POOL32I, POOL32C */
17639 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17641 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17643 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17645 /* LB32, LH32, LWC132, LDC132, LW32 */
17646 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
17647 generate_exception_end(ctx
, EXCP_RI
);
17652 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17654 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17656 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17657 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
17658 generate_exception_end(ctx
, EXCP_RI
);
17668 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17669 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
17670 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
17673 switch (ctx
->opcode
& 0x1) {
17681 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17683 * In the Release 6, the register number location in
17684 * the instruction encoding has changed.
17686 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
17688 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
17694 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17695 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
17696 int amount
= (ctx
->opcode
>> 1) & 0x7;
17698 amount
= amount
== 0 ? 8 : amount
;
17700 switch (ctx
->opcode
& 0x1) {
17709 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
17713 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17714 gen_pool16c_r6_insn(ctx
);
17716 gen_pool16c_insn(ctx
);
17721 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17722 int rb
= 28; /* GP */
17723 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
17725 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17729 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17730 if (ctx
->opcode
& 1) {
17731 generate_exception_end(ctx
, EXCP_RI
);
17734 int enc_dest
= uMIPS_RD(ctx
->opcode
);
17735 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
17736 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
17737 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
17742 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17743 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17744 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17745 offset
= (offset
== 0xf ? -1 : offset
);
17747 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
17752 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17753 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17754 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17756 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
17761 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17762 int rb
= 29; /* SP */
17763 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17765 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17770 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17771 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17772 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17774 gen_ld(ctx
, OPC_LW
, 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);
17783 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
17788 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17789 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17790 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17792 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
17797 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17798 int rb
= 29; /* SP */
17799 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17801 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17806 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17807 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17808 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17810 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17815 int rd
= uMIPS_RD5(ctx
->opcode
);
17816 int rs
= uMIPS_RS5(ctx
->opcode
);
17818 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
17825 switch (ctx
->opcode
& 0x1) {
17835 switch (ctx
->opcode
& 0x1) {
17840 gen_addiur1sp(ctx
);
17844 case B16
: /* BC16 */
17845 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
17846 sextract32(ctx
->opcode
, 0, 10) << 1,
17847 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
17849 case BNEZ16
: /* BNEZC16 */
17850 case BEQZ16
: /* BEQZC16 */
17851 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
17852 mmreg(uMIPS_RD(ctx
->opcode
)),
17853 0, sextract32(ctx
->opcode
, 0, 7) << 1,
17854 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
17859 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
17860 int imm
= ZIMM(ctx
->opcode
, 0, 7);
17862 imm
= (imm
== 0x7f ? -1 : imm
);
17863 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
17869 generate_exception_end(ctx
, EXCP_RI
);
17872 decode_micromips32_opc(env
, ctx
);
17885 /* MAJOR, P16, and P32 pools opcodes */
17889 NM_MOVE_BALC
= 0x02,
17897 NM_P16_SHIFT
= 0x0c,
17915 NM_P_LS_U12
= 0x21,
17925 NM_P16_ADDU
= 0x2c,
17939 NM_MOVEPREV
= 0x3f,
17942 /* POOL32A instruction pool */
17944 NM_POOL32A0
= 0x00,
17945 NM_SPECIAL2
= 0x01,
17948 NM_POOL32A5
= 0x05,
17949 NM_POOL32A7
= 0x07,
17952 /* P.GP.W instruction pool */
17954 NM_ADDIUGP_W
= 0x00,
17959 /* P48I instruction pool */
17963 NM_ADDIUGP48
= 0x02,
17964 NM_ADDIUPC48
= 0x03,
17969 /* P.U12 instruction pool */
17978 NM_ADDIUNEG
= 0x08,
17985 /* POOL32F instruction pool */
17987 NM_POOL32F_0
= 0x00,
17988 NM_POOL32F_3
= 0x03,
17989 NM_POOL32F_5
= 0x05,
17992 /* POOL32S instruction pool */
17994 NM_POOL32S_0
= 0x00,
17995 NM_POOL32S_4
= 0x04,
17998 /* P.LUI instruction pool */
18004 /* P.GP.BH instruction pool */
18009 NM_ADDIUGP_B
= 0x03,
18012 NM_P_GP_CP1
= 0x06,
18015 /* P.LS.U12 instruction pool */
18020 NM_P_PREFU12
= 0x03,
18033 /* P.LS.S9 instruction pool */
18039 NM_P_LS_UAWM
= 0x05,
18042 /* P.BAL instruction pool */
18048 /* P.J instruction pool */
18051 NM_JALRC_HB
= 0x01,
18052 NM_P_BALRSC
= 0x08,
18055 /* P.BR1 instruction pool */
18063 /* P.BR2 instruction pool */
18070 /* P.BRI instruction pool */
18082 /* P16.SHIFT instruction pool */
18088 /* POOL16C instruction pool */
18090 NM_POOL16C_0
= 0x00,
18094 /* P16.A1 instruction pool */
18096 NM_ADDIUR1SP
= 0x01,
18099 /* P16.A2 instruction pool */
18102 NM_P_ADDIURS5
= 0x01,
18105 /* P16.ADDU instruction pool */
18111 /* P16.SR instruction pool */
18114 NM_RESTORE_JRC16
= 0x01,
18117 /* P16.4X4 instruction pool */
18123 /* P16.LB instruction pool */
18130 /* P16.LH instruction pool */
18137 /* P.RI instruction pool */
18140 NM_P_SYSCALL
= 0x01,
18145 /* POOL32A0 instruction pool */
18180 NM_D_E_MT_VPE
= 0x56,
18188 /* CRC32 instruction pool */
18198 /* POOL32A5 instruction pool */
18200 NM_CMP_EQ_PH
= 0x00,
18201 NM_CMP_LT_PH
= 0x08,
18202 NM_CMP_LE_PH
= 0x10,
18203 NM_CMPGU_EQ_QB
= 0x18,
18204 NM_CMPGU_LT_QB
= 0x20,
18205 NM_CMPGU_LE_QB
= 0x28,
18206 NM_CMPGDU_EQ_QB
= 0x30,
18207 NM_CMPGDU_LT_QB
= 0x38,
18208 NM_CMPGDU_LE_QB
= 0x40,
18209 NM_CMPU_EQ_QB
= 0x48,
18210 NM_CMPU_LT_QB
= 0x50,
18211 NM_CMPU_LE_QB
= 0x58,
18212 NM_ADDQ_S_W
= 0x60,
18213 NM_SUBQ_S_W
= 0x68,
18217 NM_ADDQ_S_PH
= 0x01,
18218 NM_ADDQH_R_PH
= 0x09,
18219 NM_ADDQH_R_W
= 0x11,
18220 NM_ADDU_S_QB
= 0x19,
18221 NM_ADDU_S_PH
= 0x21,
18222 NM_ADDUH_R_QB
= 0x29,
18223 NM_SHRAV_R_PH
= 0x31,
18224 NM_SHRAV_R_QB
= 0x39,
18225 NM_SUBQ_S_PH
= 0x41,
18226 NM_SUBQH_R_PH
= 0x49,
18227 NM_SUBQH_R_W
= 0x51,
18228 NM_SUBU_S_QB
= 0x59,
18229 NM_SUBU_S_PH
= 0x61,
18230 NM_SUBUH_R_QB
= 0x69,
18231 NM_SHLLV_S_PH
= 0x71,
18232 NM_PRECR_SRA_R_PH_W
= 0x79,
18234 NM_MULEU_S_PH_QBL
= 0x12,
18235 NM_MULEU_S_PH_QBR
= 0x1a,
18236 NM_MULQ_RS_PH
= 0x22,
18237 NM_MULQ_S_PH
= 0x2a,
18238 NM_MULQ_RS_W
= 0x32,
18239 NM_MULQ_S_W
= 0x3a,
18242 NM_SHRAV_R_W
= 0x5a,
18243 NM_SHRLV_PH
= 0x62,
18244 NM_SHRLV_QB
= 0x6a,
18245 NM_SHLLV_QB
= 0x72,
18246 NM_SHLLV_S_W
= 0x7a,
18250 NM_MULEQ_S_W_PHL
= 0x04,
18251 NM_MULEQ_S_W_PHR
= 0x0c,
18253 NM_MUL_S_PH
= 0x05,
18254 NM_PRECR_QB_PH
= 0x0d,
18255 NM_PRECRQ_QB_PH
= 0x15,
18256 NM_PRECRQ_PH_W
= 0x1d,
18257 NM_PRECRQ_RS_PH_W
= 0x25,
18258 NM_PRECRQU_S_QB_PH
= 0x2d,
18259 NM_PACKRL_PH
= 0x35,
18263 NM_SHRA_R_W
= 0x5e,
18264 NM_SHRA_R_PH
= 0x66,
18265 NM_SHLL_S_PH
= 0x76,
18266 NM_SHLL_S_W
= 0x7e,
18271 /* POOL32A7 instruction pool */
18276 NM_POOL32AXF
= 0x07,
18279 /* P.SR instruction pool */
18285 /* P.SHIFT instruction pool */
18293 /* P.ROTX instruction pool */
18298 /* P.INS instruction pool */
18303 /* P.EXT instruction pool */
18308 /* POOL32F_0 (fmt) instruction pool */
18313 NM_SELEQZ_S
= 0x07,
18314 NM_SELEQZ_D
= 0x47,
18318 NM_SELNEZ_S
= 0x0f,
18319 NM_SELNEZ_D
= 0x4f,
18334 /* POOL32F_3 instruction pool */
18338 NM_MINA_FMT
= 0x04,
18339 NM_MAXA_FMT
= 0x05,
18340 NM_POOL32FXF
= 0x07,
18343 /* POOL32F_5 instruction pool */
18345 NM_CMP_CONDN_S
= 0x00,
18346 NM_CMP_CONDN_D
= 0x02,
18349 /* P.GP.LH instruction pool */
18355 /* P.GP.SH instruction pool */
18360 /* P.GP.CP1 instruction pool */
18368 /* P.LS.S0 instruction pool */
18385 NM_P_PREFS9
= 0x03,
18391 /* P.LS.S1 instruction pool */
18393 NM_ASET_ACLR
= 0x02,
18401 /* P.LS.E0 instruction pool */
18417 /* P.PREFE instruction pool */
18423 /* P.LLE instruction pool */
18429 /* P.SCE instruction pool */
18435 /* P.LS.WM instruction pool */
18441 /* P.LS.UAWM instruction pool */
18447 /* P.BR3A instruction pool */
18453 NM_BPOSGE32C
= 0x04,
18456 /* P16.RI instruction pool */
18458 NM_P16_SYSCALL
= 0x01,
18463 /* POOL16C_0 instruction pool */
18465 NM_POOL16C_00
= 0x00,
18468 /* P16.JRC instruction pool */
18474 /* P.SYSCALL instruction pool */
18480 /* P.TRAP instruction pool */
18486 /* P.CMOVE instruction pool */
18492 /* POOL32Axf instruction pool */
18494 NM_POOL32AXF_1
= 0x01,
18495 NM_POOL32AXF_2
= 0x02,
18496 NM_POOL32AXF_4
= 0x04,
18497 NM_POOL32AXF_5
= 0x05,
18498 NM_POOL32AXF_7
= 0x07,
18501 /* POOL32Axf_1 instruction pool */
18503 NM_POOL32AXF_1_0
= 0x00,
18504 NM_POOL32AXF_1_1
= 0x01,
18505 NM_POOL32AXF_1_3
= 0x03,
18506 NM_POOL32AXF_1_4
= 0x04,
18507 NM_POOL32AXF_1_5
= 0x05,
18508 NM_POOL32AXF_1_7
= 0x07,
18511 /* POOL32Axf_2 instruction pool */
18513 NM_POOL32AXF_2_0_7
= 0x00,
18514 NM_POOL32AXF_2_8_15
= 0x01,
18515 NM_POOL32AXF_2_16_23
= 0x02,
18516 NM_POOL32AXF_2_24_31
= 0x03,
18519 /* POOL32Axf_7 instruction pool */
18521 NM_SHRA_R_QB
= 0x0,
18526 /* POOL32Axf_1_0 instruction pool */
18534 /* POOL32Axf_1_1 instruction pool */
18540 /* POOL32Axf_1_3 instruction pool */
18548 /* POOL32Axf_1_4 instruction pool */
18554 /* POOL32Axf_1_5 instruction pool */
18556 NM_MAQ_S_W_PHR
= 0x0,
18557 NM_MAQ_S_W_PHL
= 0x1,
18558 NM_MAQ_SA_W_PHR
= 0x2,
18559 NM_MAQ_SA_W_PHL
= 0x3,
18562 /* POOL32Axf_1_7 instruction pool */
18566 NM_EXTR_RS_W
= 0x2,
18570 /* POOL32Axf_2_0_7 instruction pool */
18573 NM_DPAQ_S_W_PH
= 0x1,
18575 NM_DPSQ_S_W_PH
= 0x3,
18582 /* POOL32Axf_2_8_15 instruction pool */
18584 NM_DPAX_W_PH
= 0x0,
18585 NM_DPAQ_SA_L_W
= 0x1,
18586 NM_DPSX_W_PH
= 0x2,
18587 NM_DPSQ_SA_L_W
= 0x3,
18590 NM_EXTRV_R_W
= 0x7,
18593 /* POOL32Axf_2_16_23 instruction pool */
18595 NM_DPAU_H_QBL
= 0x0,
18596 NM_DPAQX_S_W_PH
= 0x1,
18597 NM_DPSU_H_QBL
= 0x2,
18598 NM_DPSQX_S_W_PH
= 0x3,
18601 NM_MULSA_W_PH
= 0x6,
18602 NM_EXTRV_RS_W
= 0x7,
18605 /* POOL32Axf_2_24_31 instruction pool */
18607 NM_DPAU_H_QBR
= 0x0,
18608 NM_DPAQX_SA_W_PH
= 0x1,
18609 NM_DPSU_H_QBR
= 0x2,
18610 NM_DPSQX_SA_W_PH
= 0x3,
18613 NM_MULSAQ_S_W_PH
= 0x6,
18614 NM_EXTRV_S_H
= 0x7,
18617 /* POOL32Axf_{4, 5} instruction pool */
18636 /* nanoMIPS DSP instructions */
18637 NM_ABSQ_S_QB
= 0x00,
18638 NM_ABSQ_S_PH
= 0x08,
18639 NM_ABSQ_S_W
= 0x10,
18640 NM_PRECEQ_W_PHL
= 0x28,
18641 NM_PRECEQ_W_PHR
= 0x30,
18642 NM_PRECEQU_PH_QBL
= 0x38,
18643 NM_PRECEQU_PH_QBR
= 0x48,
18644 NM_PRECEU_PH_QBL
= 0x58,
18645 NM_PRECEU_PH_QBR
= 0x68,
18646 NM_PRECEQU_PH_QBLA
= 0x39,
18647 NM_PRECEQU_PH_QBRA
= 0x49,
18648 NM_PRECEU_PH_QBLA
= 0x59,
18649 NM_PRECEU_PH_QBRA
= 0x69,
18650 NM_REPLV_PH
= 0x01,
18651 NM_REPLV_QB
= 0x09,
18654 NM_RADDU_W_QB
= 0x78,
18660 /* PP.SR instruction pool */
18664 NM_RESTORE_JRC
= 0x03,
18667 /* P.SR.F instruction pool */
18670 NM_RESTOREF
= 0x01,
18673 /* P16.SYSCALL instruction pool */
18675 NM_SYSCALL16
= 0x00,
18676 NM_HYPCALL16
= 0x01,
18679 /* POOL16C_00 instruction pool */
18687 /* PP.LSX and PP.LSXS instruction pool */
18725 /* ERETx instruction pool */
18731 /* POOL32FxF_{0, 1} insturction pool */
18740 NM_CVT_S_PL
= 0x84,
18741 NM_CVT_S_PU
= 0xa4,
18743 NM_CVT_L_S
= 0x004,
18744 NM_CVT_L_D
= 0x104,
18745 NM_CVT_W_S
= 0x024,
18746 NM_CVT_W_D
= 0x124,
18748 NM_RSQRT_S
= 0x008,
18749 NM_RSQRT_D
= 0x108,
18754 NM_RECIP_S
= 0x048,
18755 NM_RECIP_D
= 0x148,
18757 NM_FLOOR_L_S
= 0x00c,
18758 NM_FLOOR_L_D
= 0x10c,
18760 NM_FLOOR_W_S
= 0x02c,
18761 NM_FLOOR_W_D
= 0x12c,
18763 NM_CEIL_L_S
= 0x04c,
18764 NM_CEIL_L_D
= 0x14c,
18765 NM_CEIL_W_S
= 0x06c,
18766 NM_CEIL_W_D
= 0x16c,
18767 NM_TRUNC_L_S
= 0x08c,
18768 NM_TRUNC_L_D
= 0x18c,
18769 NM_TRUNC_W_S
= 0x0ac,
18770 NM_TRUNC_W_D
= 0x1ac,
18771 NM_ROUND_L_S
= 0x0cc,
18772 NM_ROUND_L_D
= 0x1cc,
18773 NM_ROUND_W_S
= 0x0ec,
18774 NM_ROUND_W_D
= 0x1ec,
18782 NM_CVT_D_S
= 0x04d,
18783 NM_CVT_D_W
= 0x0cd,
18784 NM_CVT_D_L
= 0x14d,
18785 NM_CVT_S_D
= 0x06d,
18786 NM_CVT_S_W
= 0x0ed,
18787 NM_CVT_S_L
= 0x16d,
18790 /* P.LL instruction pool */
18796 /* P.SC instruction pool */
18802 /* P.DVP instruction pool */
18811 * nanoMIPS decoding engine
18816 /* extraction utilities */
18818 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18819 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18820 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18821 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18822 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18824 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18825 static inline int decode_gpr_gpr3(int r
)
18827 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18829 return map
[r
& 0x7];
18832 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18833 static inline int decode_gpr_gpr3_src_store(int r
)
18835 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18837 return map
[r
& 0x7];
18840 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18841 static inline int decode_gpr_gpr4(int r
)
18843 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18844 16, 17, 18, 19, 20, 21, 22, 23 };
18846 return map
[r
& 0xf];
18849 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18850 static inline int decode_gpr_gpr4_zero(int r
)
18852 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18853 16, 17, 18, 19, 20, 21, 22, 23 };
18855 return map
[r
& 0xf];
18859 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
18861 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
18864 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18865 uint8_t gp
, uint16_t u
)
18868 TCGv va
= tcg_temp_new();
18869 TCGv t0
= tcg_temp_new();
18871 while (counter
!= count
) {
18872 bool use_gp
= gp
&& (counter
== count
- 1);
18873 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18874 int this_offset
= -((counter
+ 1) << 2);
18875 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18876 gen_load_gpr(t0
, this_rt
);
18877 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
18878 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
18882 /* adjust stack pointer */
18883 gen_adjust_sp(ctx
, -u
);
18889 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18890 uint8_t gp
, uint16_t u
)
18893 TCGv va
= tcg_temp_new();
18894 TCGv t0
= tcg_temp_new();
18896 while (counter
!= count
) {
18897 bool use_gp
= gp
&& (counter
== count
- 1);
18898 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18899 int this_offset
= u
- ((counter
+ 1) << 2);
18900 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18901 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
18902 ctx
->default_tcg_memop_mask
);
18903 tcg_gen_ext32s_tl(t0
, t0
);
18904 gen_store_gpr(t0
, this_rt
);
18908 /* adjust stack pointer */
18909 gen_adjust_sp(ctx
, u
);
18915 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
18917 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
18918 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
18920 switch (extract32(ctx
->opcode
, 2, 2)) {
18922 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
18925 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
18928 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
18931 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
18936 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18938 int rt
= extract32(ctx
->opcode
, 21, 5);
18939 int rs
= extract32(ctx
->opcode
, 16, 5);
18940 int rd
= extract32(ctx
->opcode
, 11, 5);
18942 switch (extract32(ctx
->opcode
, 3, 7)) {
18944 switch (extract32(ctx
->opcode
, 10, 1)) {
18947 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
18951 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
18957 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
18961 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
18964 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
18967 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
18970 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
18973 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
18976 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
18979 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
18982 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
18986 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
18989 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
18992 switch (extract32(ctx
->opcode
, 10, 1)) {
18994 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
18997 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
19002 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
19005 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
19008 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
19011 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
19014 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
19019 #ifndef CONFIG_USER_ONLY
19020 TCGv t0
= tcg_temp_new();
19021 switch (extract32(ctx
->opcode
, 10, 1)) {
19024 check_cp0_enabled(ctx
);
19025 gen_helper_dvp(t0
, cpu_env
);
19026 gen_store_gpr(t0
, rt
);
19031 check_cp0_enabled(ctx
);
19032 gen_helper_evp(t0
, cpu_env
);
19033 gen_store_gpr(t0
, rt
);
19040 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
19045 TCGv t0
= tcg_temp_new();
19046 TCGv t1
= tcg_temp_new();
19047 TCGv t2
= tcg_temp_new();
19049 gen_load_gpr(t1
, rs
);
19050 gen_load_gpr(t2
, rt
);
19051 tcg_gen_add_tl(t0
, t1
, t2
);
19052 tcg_gen_ext32s_tl(t0
, t0
);
19053 tcg_gen_xor_tl(t1
, t1
, t2
);
19054 tcg_gen_xor_tl(t2
, t0
, t2
);
19055 tcg_gen_andc_tl(t1
, t2
, t1
);
19057 /* operands of same sign, result different sign */
19058 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
19059 gen_store_gpr(t0
, rd
);
19067 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
19070 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
19073 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
19076 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
19079 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
19082 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
19085 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
19088 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
19090 #ifndef CONFIG_USER_ONLY
19092 check_cp0_enabled(ctx
);
19094 /* Treat as NOP. */
19097 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
19100 check_cp0_enabled(ctx
);
19102 TCGv t0
= tcg_temp_new();
19104 gen_load_gpr(t0
, rt
);
19105 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
19109 case NM_D_E_MT_VPE
:
19111 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
19112 TCGv t0
= tcg_temp_new();
19119 gen_helper_dmt(t0
);
19120 gen_store_gpr(t0
, rt
);
19121 } else if (rs
== 0) {
19124 gen_helper_dvpe(t0
, cpu_env
);
19125 gen_store_gpr(t0
, rt
);
19127 generate_exception_end(ctx
, EXCP_RI
);
19134 gen_helper_emt(t0
);
19135 gen_store_gpr(t0
, rt
);
19136 } else if (rs
== 0) {
19139 gen_helper_evpe(t0
, cpu_env
);
19140 gen_store_gpr(t0
, rt
);
19142 generate_exception_end(ctx
, EXCP_RI
);
19153 TCGv t0
= tcg_temp_new();
19154 TCGv t1
= tcg_temp_new();
19156 gen_load_gpr(t0
, rt
);
19157 gen_load_gpr(t1
, rs
);
19158 gen_helper_fork(t0
, t1
);
19165 check_cp0_enabled(ctx
);
19167 /* Treat as NOP. */
19170 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19171 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19175 check_cp0_enabled(ctx
);
19176 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19177 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19182 TCGv t0
= tcg_temp_new();
19184 gen_load_gpr(t0
, rs
);
19185 gen_helper_yield(t0
, cpu_env
, t0
);
19186 gen_store_gpr(t0
, rt
);
19192 generate_exception_end(ctx
, EXCP_RI
);
19198 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19199 int ret
, int v1
, int v2
)
19205 t0
= tcg_temp_new_i32();
19207 v0_t
= tcg_temp_new();
19208 v1_t
= tcg_temp_new();
19210 tcg_gen_movi_i32(t0
, v2
>> 3);
19212 gen_load_gpr(v0_t
, ret
);
19213 gen_load_gpr(v1_t
, v1
);
19216 case NM_MAQ_S_W_PHR
:
19218 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19220 case NM_MAQ_S_W_PHL
:
19222 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19224 case NM_MAQ_SA_W_PHR
:
19226 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19228 case NM_MAQ_SA_W_PHL
:
19230 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19233 generate_exception_end(ctx
, EXCP_RI
);
19237 tcg_temp_free_i32(t0
);
19239 tcg_temp_free(v0_t
);
19240 tcg_temp_free(v1_t
);
19244 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19245 int ret
, int v1
, int v2
)
19248 TCGv t0
= tcg_temp_new();
19249 TCGv t1
= tcg_temp_new();
19250 TCGv v0_t
= tcg_temp_new();
19252 gen_load_gpr(v0_t
, v1
);
19255 case NM_POOL32AXF_1_0
:
19257 switch (extract32(ctx
->opcode
, 12, 2)) {
19259 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19262 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19265 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19268 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19272 case NM_POOL32AXF_1_1
:
19274 switch (extract32(ctx
->opcode
, 12, 2)) {
19276 tcg_gen_movi_tl(t0
, v2
);
19277 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19280 tcg_gen_movi_tl(t0
, v2
>> 3);
19281 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19284 generate_exception_end(ctx
, EXCP_RI
);
19288 case NM_POOL32AXF_1_3
:
19290 imm
= extract32(ctx
->opcode
, 14, 7);
19291 switch (extract32(ctx
->opcode
, 12, 2)) {
19293 tcg_gen_movi_tl(t0
, imm
);
19294 gen_helper_rddsp(t0
, t0
, cpu_env
);
19295 gen_store_gpr(t0
, ret
);
19298 gen_load_gpr(t0
, ret
);
19299 tcg_gen_movi_tl(t1
, imm
);
19300 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19303 tcg_gen_movi_tl(t0
, v2
>> 3);
19304 tcg_gen_movi_tl(t1
, v1
);
19305 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19306 gen_store_gpr(t0
, ret
);
19309 tcg_gen_movi_tl(t0
, v2
>> 3);
19310 tcg_gen_movi_tl(t1
, v1
);
19311 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19312 gen_store_gpr(t0
, ret
);
19316 case NM_POOL32AXF_1_4
:
19318 tcg_gen_movi_tl(t0
, v2
>> 2);
19319 switch (extract32(ctx
->opcode
, 12, 1)) {
19321 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19322 gen_store_gpr(t0
, ret
);
19325 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19326 gen_store_gpr(t0
, ret
);
19330 case NM_POOL32AXF_1_5
:
19331 opc
= extract32(ctx
->opcode
, 12, 2);
19332 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19334 case NM_POOL32AXF_1_7
:
19336 tcg_gen_movi_tl(t0
, v2
>> 3);
19337 tcg_gen_movi_tl(t1
, v1
);
19338 switch (extract32(ctx
->opcode
, 12, 2)) {
19340 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19341 gen_store_gpr(t0
, ret
);
19344 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19345 gen_store_gpr(t0
, ret
);
19348 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19349 gen_store_gpr(t0
, ret
);
19352 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19353 gen_store_gpr(t0
, ret
);
19358 generate_exception_end(ctx
, EXCP_RI
);
19364 tcg_temp_free(v0_t
);
19367 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19368 TCGv v0
, TCGv v1
, int rd
)
19372 t0
= tcg_temp_new_i32();
19374 tcg_gen_movi_i32(t0
, rd
>> 3);
19377 case NM_POOL32AXF_2_0_7
:
19378 switch (extract32(ctx
->opcode
, 9, 3)) {
19381 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19383 case NM_DPAQ_S_W_PH
:
19385 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19389 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19391 case NM_DPSQ_S_W_PH
:
19393 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19396 generate_exception_end(ctx
, EXCP_RI
);
19400 case NM_POOL32AXF_2_8_15
:
19401 switch (extract32(ctx
->opcode
, 9, 3)) {
19404 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19406 case NM_DPAQ_SA_L_W
:
19408 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19412 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19414 case NM_DPSQ_SA_L_W
:
19416 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19419 generate_exception_end(ctx
, EXCP_RI
);
19423 case NM_POOL32AXF_2_16_23
:
19424 switch (extract32(ctx
->opcode
, 9, 3)) {
19425 case NM_DPAU_H_QBL
:
19427 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19429 case NM_DPAQX_S_W_PH
:
19431 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19433 case NM_DPSU_H_QBL
:
19435 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19437 case NM_DPSQX_S_W_PH
:
19439 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19441 case NM_MULSA_W_PH
:
19443 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19446 generate_exception_end(ctx
, EXCP_RI
);
19450 case NM_POOL32AXF_2_24_31
:
19451 switch (extract32(ctx
->opcode
, 9, 3)) {
19452 case NM_DPAU_H_QBR
:
19454 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19456 case NM_DPAQX_SA_W_PH
:
19458 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19460 case NM_DPSU_H_QBR
:
19462 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19464 case NM_DPSQX_SA_W_PH
:
19466 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19468 case NM_MULSAQ_S_W_PH
:
19470 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19473 generate_exception_end(ctx
, EXCP_RI
);
19478 generate_exception_end(ctx
, EXCP_RI
);
19482 tcg_temp_free_i32(t0
);
19485 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19486 int rt
, int rs
, int rd
)
19489 TCGv t0
= tcg_temp_new();
19490 TCGv t1
= tcg_temp_new();
19491 TCGv v0_t
= tcg_temp_new();
19492 TCGv v1_t
= tcg_temp_new();
19494 gen_load_gpr(v0_t
, rt
);
19495 gen_load_gpr(v1_t
, rs
);
19498 case NM_POOL32AXF_2_0_7
:
19499 switch (extract32(ctx
->opcode
, 9, 3)) {
19501 case NM_DPAQ_S_W_PH
:
19503 case NM_DPSQ_S_W_PH
:
19504 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19509 gen_load_gpr(t0
, rs
);
19511 if (rd
!= 0 && rd
!= 2) {
19512 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19513 tcg_gen_ext32u_tl(t0
, t0
);
19514 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19515 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19517 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19523 int acc
= extract32(ctx
->opcode
, 14, 2);
19524 TCGv_i64 t2
= tcg_temp_new_i64();
19525 TCGv_i64 t3
= tcg_temp_new_i64();
19527 gen_load_gpr(t0
, rt
);
19528 gen_load_gpr(t1
, rs
);
19529 tcg_gen_ext_tl_i64(t2
, t0
);
19530 tcg_gen_ext_tl_i64(t3
, t1
);
19531 tcg_gen_mul_i64(t2
, t2
, t3
);
19532 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19533 tcg_gen_add_i64(t2
, t2
, t3
);
19534 tcg_temp_free_i64(t3
);
19535 gen_move_low32(cpu_LO
[acc
], t2
);
19536 gen_move_high32(cpu_HI
[acc
], t2
);
19537 tcg_temp_free_i64(t2
);
19543 int acc
= extract32(ctx
->opcode
, 14, 2);
19544 TCGv_i32 t2
= tcg_temp_new_i32();
19545 TCGv_i32 t3
= tcg_temp_new_i32();
19547 gen_load_gpr(t0
, rs
);
19548 gen_load_gpr(t1
, rt
);
19549 tcg_gen_trunc_tl_i32(t2
, t0
);
19550 tcg_gen_trunc_tl_i32(t3
, t1
);
19551 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19552 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19553 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19554 tcg_temp_free_i32(t2
);
19555 tcg_temp_free_i32(t3
);
19560 gen_load_gpr(v1_t
, rs
);
19561 tcg_gen_movi_tl(t0
, rd
>> 3);
19562 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19563 gen_store_gpr(t0
, ret
);
19567 case NM_POOL32AXF_2_8_15
:
19568 switch (extract32(ctx
->opcode
, 9, 3)) {
19570 case NM_DPAQ_SA_L_W
:
19572 case NM_DPSQ_SA_L_W
:
19573 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19578 int acc
= extract32(ctx
->opcode
, 14, 2);
19579 TCGv_i64 t2
= tcg_temp_new_i64();
19580 TCGv_i64 t3
= tcg_temp_new_i64();
19582 gen_load_gpr(t0
, rs
);
19583 gen_load_gpr(t1
, rt
);
19584 tcg_gen_ext32u_tl(t0
, t0
);
19585 tcg_gen_ext32u_tl(t1
, t1
);
19586 tcg_gen_extu_tl_i64(t2
, t0
);
19587 tcg_gen_extu_tl_i64(t3
, t1
);
19588 tcg_gen_mul_i64(t2
, t2
, t3
);
19589 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19590 tcg_gen_add_i64(t2
, t2
, t3
);
19591 tcg_temp_free_i64(t3
);
19592 gen_move_low32(cpu_LO
[acc
], t2
);
19593 gen_move_high32(cpu_HI
[acc
], t2
);
19594 tcg_temp_free_i64(t2
);
19600 int acc
= extract32(ctx
->opcode
, 14, 2);
19601 TCGv_i32 t2
= tcg_temp_new_i32();
19602 TCGv_i32 t3
= tcg_temp_new_i32();
19604 gen_load_gpr(t0
, rs
);
19605 gen_load_gpr(t1
, rt
);
19606 tcg_gen_trunc_tl_i32(t2
, t0
);
19607 tcg_gen_trunc_tl_i32(t3
, t1
);
19608 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
19609 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19610 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19611 tcg_temp_free_i32(t2
);
19612 tcg_temp_free_i32(t3
);
19617 tcg_gen_movi_tl(t0
, rd
>> 3);
19618 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
19619 gen_store_gpr(t0
, ret
);
19622 generate_exception_end(ctx
, EXCP_RI
);
19626 case NM_POOL32AXF_2_16_23
:
19627 switch (extract32(ctx
->opcode
, 9, 3)) {
19628 case NM_DPAU_H_QBL
:
19629 case NM_DPAQX_S_W_PH
:
19630 case NM_DPSU_H_QBL
:
19631 case NM_DPSQX_S_W_PH
:
19632 case NM_MULSA_W_PH
:
19633 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19637 tcg_gen_movi_tl(t0
, rd
>> 3);
19638 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
19639 gen_store_gpr(t0
, ret
);
19644 int acc
= extract32(ctx
->opcode
, 14, 2);
19645 TCGv_i64 t2
= tcg_temp_new_i64();
19646 TCGv_i64 t3
= tcg_temp_new_i64();
19648 gen_load_gpr(t0
, rs
);
19649 gen_load_gpr(t1
, rt
);
19650 tcg_gen_ext_tl_i64(t2
, t0
);
19651 tcg_gen_ext_tl_i64(t3
, t1
);
19652 tcg_gen_mul_i64(t2
, t2
, t3
);
19653 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19654 tcg_gen_sub_i64(t2
, t3
, t2
);
19655 tcg_temp_free_i64(t3
);
19656 gen_move_low32(cpu_LO
[acc
], t2
);
19657 gen_move_high32(cpu_HI
[acc
], t2
);
19658 tcg_temp_free_i64(t2
);
19661 case NM_EXTRV_RS_W
:
19663 tcg_gen_movi_tl(t0
, rd
>> 3);
19664 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
19665 gen_store_gpr(t0
, ret
);
19669 case NM_POOL32AXF_2_24_31
:
19670 switch (extract32(ctx
->opcode
, 9, 3)) {
19671 case NM_DPAU_H_QBR
:
19672 case NM_DPAQX_SA_W_PH
:
19673 case NM_DPSU_H_QBR
:
19674 case NM_DPSQX_SA_W_PH
:
19675 case NM_MULSAQ_S_W_PH
:
19676 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19680 tcg_gen_movi_tl(t0
, rd
>> 3);
19681 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
19682 gen_store_gpr(t0
, ret
);
19687 int acc
= extract32(ctx
->opcode
, 14, 2);
19688 TCGv_i64 t2
= tcg_temp_new_i64();
19689 TCGv_i64 t3
= tcg_temp_new_i64();
19691 gen_load_gpr(t0
, rs
);
19692 gen_load_gpr(t1
, rt
);
19693 tcg_gen_ext32u_tl(t0
, t0
);
19694 tcg_gen_ext32u_tl(t1
, t1
);
19695 tcg_gen_extu_tl_i64(t2
, t0
);
19696 tcg_gen_extu_tl_i64(t3
, t1
);
19697 tcg_gen_mul_i64(t2
, t2
, t3
);
19698 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19699 tcg_gen_sub_i64(t2
, t3
, t2
);
19700 tcg_temp_free_i64(t3
);
19701 gen_move_low32(cpu_LO
[acc
], t2
);
19702 gen_move_high32(cpu_HI
[acc
], t2
);
19703 tcg_temp_free_i64(t2
);
19708 tcg_gen_movi_tl(t0
, rd
>> 3);
19709 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
19710 gen_store_gpr(t0
, ret
);
19715 generate_exception_end(ctx
, EXCP_RI
);
19722 tcg_temp_free(v0_t
);
19723 tcg_temp_free(v1_t
);
19726 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19730 TCGv t0
= tcg_temp_new();
19731 TCGv v0_t
= tcg_temp_new();
19733 gen_load_gpr(v0_t
, rs
);
19738 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
19739 gen_store_gpr(v0_t
, ret
);
19743 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
19744 gen_store_gpr(v0_t
, ret
);
19748 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
19749 gen_store_gpr(v0_t
, ret
);
19751 case NM_PRECEQ_W_PHL
:
19753 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
19754 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19755 gen_store_gpr(v0_t
, ret
);
19757 case NM_PRECEQ_W_PHR
:
19759 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
19760 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
19761 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19762 gen_store_gpr(v0_t
, ret
);
19764 case NM_PRECEQU_PH_QBL
:
19766 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
19767 gen_store_gpr(v0_t
, ret
);
19769 case NM_PRECEQU_PH_QBR
:
19771 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
19772 gen_store_gpr(v0_t
, ret
);
19774 case NM_PRECEQU_PH_QBLA
:
19776 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
19777 gen_store_gpr(v0_t
, ret
);
19779 case NM_PRECEQU_PH_QBRA
:
19781 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
19782 gen_store_gpr(v0_t
, ret
);
19784 case NM_PRECEU_PH_QBL
:
19786 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
19787 gen_store_gpr(v0_t
, ret
);
19789 case NM_PRECEU_PH_QBR
:
19791 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
19792 gen_store_gpr(v0_t
, ret
);
19794 case NM_PRECEU_PH_QBLA
:
19796 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
19797 gen_store_gpr(v0_t
, ret
);
19799 case NM_PRECEU_PH_QBRA
:
19801 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
19802 gen_store_gpr(v0_t
, ret
);
19806 tcg_gen_ext16u_tl(v0_t
, v0_t
);
19807 tcg_gen_shli_tl(t0
, v0_t
, 16);
19808 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19809 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19810 gen_store_gpr(v0_t
, ret
);
19814 tcg_gen_ext8u_tl(v0_t
, v0_t
);
19815 tcg_gen_shli_tl(t0
, v0_t
, 8);
19816 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19817 tcg_gen_shli_tl(t0
, v0_t
, 16);
19818 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19819 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19820 gen_store_gpr(v0_t
, ret
);
19824 gen_helper_bitrev(v0_t
, v0_t
);
19825 gen_store_gpr(v0_t
, ret
);
19830 TCGv tv0
= tcg_temp_new();
19832 gen_load_gpr(tv0
, rt
);
19833 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
19834 gen_store_gpr(v0_t
, ret
);
19835 tcg_temp_free(tv0
);
19838 case NM_RADDU_W_QB
:
19840 gen_helper_raddu_w_qb(v0_t
, v0_t
);
19841 gen_store_gpr(v0_t
, ret
);
19844 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
19848 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
19852 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
19855 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
19858 generate_exception_end(ctx
, EXCP_RI
);
19862 tcg_temp_free(v0_t
);
19866 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19867 int rt
, int rs
, int rd
)
19869 TCGv t0
= tcg_temp_new();
19870 TCGv rs_t
= tcg_temp_new();
19872 gen_load_gpr(rs_t
, rs
);
19877 tcg_gen_movi_tl(t0
, rd
>> 2);
19878 switch (extract32(ctx
->opcode
, 12, 1)) {
19881 gen_helper_shra_qb(t0
, t0
, rs_t
);
19882 gen_store_gpr(t0
, rt
);
19886 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
19887 gen_store_gpr(t0
, rt
);
19893 tcg_gen_movi_tl(t0
, rd
>> 1);
19894 gen_helper_shrl_ph(t0
, t0
, rs_t
);
19895 gen_store_gpr(t0
, rt
);
19901 target_long result
;
19902 imm
= extract32(ctx
->opcode
, 13, 8);
19903 result
= (uint32_t)imm
<< 24 |
19904 (uint32_t)imm
<< 16 |
19905 (uint32_t)imm
<< 8 |
19907 result
= (int32_t)result
;
19908 tcg_gen_movi_tl(t0
, result
);
19909 gen_store_gpr(t0
, rt
);
19913 generate_exception_end(ctx
, EXCP_RI
);
19917 tcg_temp_free(rs_t
);
19921 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19923 int rt
= extract32(ctx
->opcode
, 21, 5);
19924 int rs
= extract32(ctx
->opcode
, 16, 5);
19925 int rd
= extract32(ctx
->opcode
, 11, 5);
19927 switch (extract32(ctx
->opcode
, 6, 3)) {
19928 case NM_POOL32AXF_1
:
19930 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19931 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19934 case NM_POOL32AXF_2
:
19936 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
19937 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19940 case NM_POOL32AXF_4
:
19942 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
19943 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
19946 case NM_POOL32AXF_5
:
19947 switch (extract32(ctx
->opcode
, 9, 7)) {
19948 #ifndef CONFIG_USER_ONLY
19950 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
19953 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
19956 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
19959 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
19962 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
19965 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
19968 check_cp0_enabled(ctx
);
19970 TCGv t0
= tcg_temp_new();
19972 save_cpu_state(ctx
, 1);
19973 gen_helper_di(t0
, cpu_env
);
19974 gen_store_gpr(t0
, rt
);
19975 /* Stop translation as we may have switched the execution mode */
19976 ctx
->base
.is_jmp
= DISAS_STOP
;
19981 check_cp0_enabled(ctx
);
19983 TCGv t0
= tcg_temp_new();
19985 save_cpu_state(ctx
, 1);
19986 gen_helper_ei(t0
, cpu_env
);
19987 gen_store_gpr(t0
, rt
);
19988 /* Stop translation as we may have switched the execution mode */
19989 ctx
->base
.is_jmp
= DISAS_STOP
;
19994 gen_load_srsgpr(rs
, rt
);
19997 gen_store_srsgpr(rs
, rt
);
20000 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
20003 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
20006 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
20010 generate_exception_end(ctx
, EXCP_RI
);
20014 case NM_POOL32AXF_7
:
20016 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20017 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20021 generate_exception_end(ctx
, EXCP_RI
);
20026 /* Immediate Value Compact Branches */
20027 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
20028 int rt
, int32_t imm
, int32_t offset
)
20031 int bcond_compute
= 0;
20032 TCGv t0
= tcg_temp_new();
20033 TCGv t1
= tcg_temp_new();
20035 gen_load_gpr(t0
, rt
);
20036 tcg_gen_movi_tl(t1
, imm
);
20037 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20039 /* Load needed operands and calculate btarget */
20042 if (rt
== 0 && imm
== 0) {
20043 /* Unconditional branch */
20044 } else if (rt
== 0 && imm
!= 0) {
20049 cond
= TCG_COND_EQ
;
20055 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
20056 generate_exception_end(ctx
, EXCP_RI
);
20058 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
20059 /* Unconditional branch */
20060 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
20064 tcg_gen_shri_tl(t0
, t0
, imm
);
20065 tcg_gen_andi_tl(t0
, t0
, 1);
20066 tcg_gen_movi_tl(t1
, 0);
20068 if (opc
== NM_BBEQZC
) {
20069 cond
= TCG_COND_EQ
;
20071 cond
= TCG_COND_NE
;
20076 if (rt
== 0 && imm
== 0) {
20079 } else if (rt
== 0 && imm
!= 0) {
20080 /* Unconditional branch */
20083 cond
= TCG_COND_NE
;
20087 if (rt
== 0 && imm
== 0) {
20088 /* Unconditional branch */
20091 cond
= TCG_COND_GE
;
20096 cond
= TCG_COND_LT
;
20099 if (rt
== 0 && imm
== 0) {
20100 /* Unconditional branch */
20103 cond
= TCG_COND_GEU
;
20108 cond
= TCG_COND_LTU
;
20111 MIPS_INVAL("Immediate Value Compact branch");
20112 generate_exception_end(ctx
, EXCP_RI
);
20116 /* branch completion */
20117 clear_branch_hflags(ctx
);
20118 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20120 if (bcond_compute
== 0) {
20121 /* Uncoditional compact branch */
20122 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20124 /* Conditional compact branch */
20125 TCGLabel
*fs
= gen_new_label();
20127 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
20129 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20132 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20140 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20141 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
20144 TCGv t0
= tcg_temp_new();
20145 TCGv t1
= tcg_temp_new();
20148 gen_load_gpr(t0
, rs
);
20152 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
20155 /* calculate btarget */
20156 tcg_gen_shli_tl(t0
, t0
, 1);
20157 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
20158 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
20160 /* branch completion */
20161 clear_branch_hflags(ctx
);
20162 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20164 /* unconditional branch to register */
20165 tcg_gen_mov_tl(cpu_PC
, btarget
);
20166 tcg_gen_lookup_and_goto_ptr();
20172 /* nanoMIPS Branches */
20173 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
20174 int rs
, int rt
, int32_t offset
)
20176 int bcond_compute
= 0;
20177 TCGv t0
= tcg_temp_new();
20178 TCGv t1
= tcg_temp_new();
20180 /* Load needed operands and calculate btarget */
20182 /* compact branch */
20185 gen_load_gpr(t0
, rs
);
20186 gen_load_gpr(t1
, rt
);
20188 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20192 if (rs
== 0 || rs
== rt
) {
20193 /* OPC_BLEZALC, OPC_BGEZALC */
20194 /* OPC_BGTZALC, OPC_BLTZALC */
20195 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20197 gen_load_gpr(t0
, rs
);
20198 gen_load_gpr(t1
, rt
);
20200 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20203 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20207 /* OPC_BEQZC, OPC_BNEZC */
20208 gen_load_gpr(t0
, rs
);
20210 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20212 /* OPC_JIC, OPC_JIALC */
20213 TCGv tbase
= tcg_temp_new();
20214 TCGv toffset
= tcg_temp_new();
20216 gen_load_gpr(tbase
, rt
);
20217 tcg_gen_movi_tl(toffset
, offset
);
20218 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20219 tcg_temp_free(tbase
);
20220 tcg_temp_free(toffset
);
20224 MIPS_INVAL("Compact branch/jump");
20225 generate_exception_end(ctx
, EXCP_RI
);
20229 if (bcond_compute
== 0) {
20230 /* Uncoditional compact branch */
20233 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20236 MIPS_INVAL("Compact branch/jump");
20237 generate_exception_end(ctx
, EXCP_RI
);
20241 /* Conditional compact branch */
20242 TCGLabel
*fs
= gen_new_label();
20246 if (rs
== 0 && rt
!= 0) {
20248 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20249 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20251 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20254 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20258 if (rs
== 0 && rt
!= 0) {
20260 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20261 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20263 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20266 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20270 if (rs
== 0 && rt
!= 0) {
20272 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20273 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20275 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20278 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20282 if (rs
== 0 && rt
!= 0) {
20284 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20285 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20287 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20290 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20294 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20297 MIPS_INVAL("Compact conditional branch/jump");
20298 generate_exception_end(ctx
, EXCP_RI
);
20302 /* branch completion */
20303 clear_branch_hflags(ctx
);
20304 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20306 /* Generating branch here as compact branches don't have delay slot */
20307 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20310 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20319 /* nanoMIPS CP1 Branches */
20320 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20321 int32_t ft
, int32_t offset
)
20323 target_ulong btarget
;
20324 TCGv_i64 t0
= tcg_temp_new_i64();
20326 gen_load_fpr64(ctx
, t0
, ft
);
20327 tcg_gen_andi_i64(t0
, t0
, 1);
20329 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20333 tcg_gen_xori_i64(t0
, t0
, 1);
20334 ctx
->hflags
|= MIPS_HFLAG_BC
;
20337 /* t0 already set */
20338 ctx
->hflags
|= MIPS_HFLAG_BC
;
20341 MIPS_INVAL("cp1 cond branch");
20342 generate_exception_end(ctx
, EXCP_RI
);
20346 tcg_gen_trunc_i64_tl(bcond
, t0
);
20348 ctx
->btarget
= btarget
;
20351 tcg_temp_free_i64(t0
);
20355 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20358 t0
= tcg_temp_new();
20359 t1
= tcg_temp_new();
20361 gen_load_gpr(t0
, rs
);
20362 gen_load_gpr(t1
, rt
);
20364 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20365 /* PP.LSXS instructions require shifting */
20366 switch (extract32(ctx
->opcode
, 7, 4)) {
20372 tcg_gen_shli_tl(t0
, t0
, 1);
20380 tcg_gen_shli_tl(t0
, t0
, 2);
20384 tcg_gen_shli_tl(t0
, t0
, 3);
20388 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20390 switch (extract32(ctx
->opcode
, 7, 4)) {
20392 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20394 gen_store_gpr(t0
, rd
);
20398 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20400 gen_store_gpr(t0
, rd
);
20404 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20406 gen_store_gpr(t0
, rd
);
20409 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20411 gen_store_gpr(t0
, rd
);
20415 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20417 gen_store_gpr(t0
, rd
);
20421 gen_load_gpr(t1
, rd
);
20422 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20428 gen_load_gpr(t1
, rd
);
20429 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20435 gen_load_gpr(t1
, rd
);
20436 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20440 /*case NM_LWC1XS:*/
20442 /*case NM_LDC1XS:*/
20444 /*case NM_SWC1XS:*/
20446 /*case NM_SDC1XS:*/
20447 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20448 check_cp1_enabled(ctx
);
20449 switch (extract32(ctx
->opcode
, 7, 4)) {
20451 /*case NM_LWC1XS:*/
20452 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20455 /*case NM_LDC1XS:*/
20456 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20459 /*case NM_SWC1XS:*/
20460 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20463 /*case NM_SDC1XS:*/
20464 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20468 generate_exception_err(ctx
, EXCP_CpU
, 1);
20472 generate_exception_end(ctx
, EXCP_RI
);
20480 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20484 rt
= extract32(ctx
->opcode
, 21, 5);
20485 rs
= extract32(ctx
->opcode
, 16, 5);
20486 rd
= extract32(ctx
->opcode
, 11, 5);
20488 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20489 generate_exception_end(ctx
, EXCP_RI
);
20492 check_cp1_enabled(ctx
);
20493 switch (extract32(ctx
->opcode
, 0, 3)) {
20495 switch (extract32(ctx
->opcode
, 3, 7)) {
20497 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20500 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20503 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20506 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20509 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20512 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20515 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20518 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20521 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20524 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20527 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20530 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20533 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20536 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20539 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20542 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20545 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20548 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20551 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20554 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20557 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20560 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20563 generate_exception_end(ctx
, EXCP_RI
);
20568 switch (extract32(ctx
->opcode
, 3, 3)) {
20570 switch (extract32(ctx
->opcode
, 9, 1)) {
20572 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
20575 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
20580 switch (extract32(ctx
->opcode
, 9, 1)) {
20582 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
20585 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
20590 switch (extract32(ctx
->opcode
, 9, 1)) {
20592 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
20595 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
20600 switch (extract32(ctx
->opcode
, 9, 1)) {
20602 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
20605 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
20610 switch (extract32(ctx
->opcode
, 6, 8)) {
20612 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
20615 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
20618 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
20621 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
20624 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
20627 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
20630 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
20633 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
20636 switch (extract32(ctx
->opcode
, 6, 9)) {
20638 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
20641 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
20644 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
20647 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
20650 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
20653 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
20656 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
20659 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
20662 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
20665 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
20668 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
20671 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
20674 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
20677 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
20680 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
20683 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
20686 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
20689 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
20692 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
20695 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
20698 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
20701 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
20704 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
20707 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
20710 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
20713 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
20716 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
20719 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
20722 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
20725 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
20728 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
20731 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
20734 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
20737 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
20740 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
20743 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
20746 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
20749 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
20752 generate_exception_end(ctx
, EXCP_RI
);
20761 switch (extract32(ctx
->opcode
, 3, 3)) {
20762 case NM_CMP_CONDN_S
:
20763 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20765 case NM_CMP_CONDN_D
:
20766 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20769 generate_exception_end(ctx
, EXCP_RI
);
20774 generate_exception_end(ctx
, EXCP_RI
);
20779 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
20780 int rd
, int rs
, int rt
)
20783 TCGv t0
= tcg_temp_new();
20784 TCGv v1_t
= tcg_temp_new();
20785 TCGv v2_t
= tcg_temp_new();
20787 gen_load_gpr(v1_t
, rs
);
20788 gen_load_gpr(v2_t
, rt
);
20793 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
20797 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
20801 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
20803 case NM_CMPU_EQ_QB
:
20805 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
20807 case NM_CMPU_LT_QB
:
20809 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
20811 case NM_CMPU_LE_QB
:
20813 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
20815 case NM_CMPGU_EQ_QB
:
20817 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20818 gen_store_gpr(v1_t
, ret
);
20820 case NM_CMPGU_LT_QB
:
20822 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20823 gen_store_gpr(v1_t
, ret
);
20825 case NM_CMPGU_LE_QB
:
20827 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20828 gen_store_gpr(v1_t
, ret
);
20830 case NM_CMPGDU_EQ_QB
:
20832 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20833 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20834 gen_store_gpr(v1_t
, ret
);
20836 case NM_CMPGDU_LT_QB
:
20838 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20839 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20840 gen_store_gpr(v1_t
, ret
);
20842 case NM_CMPGDU_LE_QB
:
20844 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20845 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20846 gen_store_gpr(v1_t
, ret
);
20850 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
20851 gen_store_gpr(v1_t
, ret
);
20855 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20856 gen_store_gpr(v1_t
, ret
);
20860 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20861 gen_store_gpr(v1_t
, ret
);
20865 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20866 gen_store_gpr(v1_t
, ret
);
20870 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20871 gen_store_gpr(v1_t
, ret
);
20875 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
20876 gen_store_gpr(v1_t
, ret
);
20880 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
20881 gen_store_gpr(v1_t
, ret
);
20885 switch (extract32(ctx
->opcode
, 10, 1)) {
20888 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20889 gen_store_gpr(v1_t
, ret
);
20893 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20894 gen_store_gpr(v1_t
, ret
);
20898 case NM_ADDQH_R_PH
:
20900 switch (extract32(ctx
->opcode
, 10, 1)) {
20903 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
20904 gen_store_gpr(v1_t
, ret
);
20908 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
20909 gen_store_gpr(v1_t
, ret
);
20915 switch (extract32(ctx
->opcode
, 10, 1)) {
20918 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
20919 gen_store_gpr(v1_t
, ret
);
20923 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
20924 gen_store_gpr(v1_t
, ret
);
20930 switch (extract32(ctx
->opcode
, 10, 1)) {
20933 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20934 gen_store_gpr(v1_t
, ret
);
20938 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20939 gen_store_gpr(v1_t
, ret
);
20945 switch (extract32(ctx
->opcode
, 10, 1)) {
20948 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20949 gen_store_gpr(v1_t
, ret
);
20953 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20954 gen_store_gpr(v1_t
, ret
);
20958 case NM_ADDUH_R_QB
:
20960 switch (extract32(ctx
->opcode
, 10, 1)) {
20963 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
20964 gen_store_gpr(v1_t
, ret
);
20968 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
20969 gen_store_gpr(v1_t
, ret
);
20973 case NM_SHRAV_R_PH
:
20975 switch (extract32(ctx
->opcode
, 10, 1)) {
20978 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
20979 gen_store_gpr(v1_t
, ret
);
20983 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
20984 gen_store_gpr(v1_t
, ret
);
20988 case NM_SHRAV_R_QB
:
20990 switch (extract32(ctx
->opcode
, 10, 1)) {
20993 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
20994 gen_store_gpr(v1_t
, ret
);
20998 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
20999 gen_store_gpr(v1_t
, ret
);
21005 switch (extract32(ctx
->opcode
, 10, 1)) {
21008 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21009 gen_store_gpr(v1_t
, ret
);
21013 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21014 gen_store_gpr(v1_t
, ret
);
21018 case NM_SUBQH_R_PH
:
21020 switch (extract32(ctx
->opcode
, 10, 1)) {
21023 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
21024 gen_store_gpr(v1_t
, ret
);
21028 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
21029 gen_store_gpr(v1_t
, ret
);
21035 switch (extract32(ctx
->opcode
, 10, 1)) {
21038 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
21039 gen_store_gpr(v1_t
, ret
);
21043 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
21044 gen_store_gpr(v1_t
, ret
);
21050 switch (extract32(ctx
->opcode
, 10, 1)) {
21053 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21054 gen_store_gpr(v1_t
, ret
);
21058 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21059 gen_store_gpr(v1_t
, ret
);
21065 switch (extract32(ctx
->opcode
, 10, 1)) {
21068 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21069 gen_store_gpr(v1_t
, ret
);
21073 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21074 gen_store_gpr(v1_t
, ret
);
21078 case NM_SUBUH_R_QB
:
21080 switch (extract32(ctx
->opcode
, 10, 1)) {
21083 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
21084 gen_store_gpr(v1_t
, ret
);
21088 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
21089 gen_store_gpr(v1_t
, ret
);
21093 case NM_SHLLV_S_PH
:
21095 switch (extract32(ctx
->opcode
, 10, 1)) {
21098 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21099 gen_store_gpr(v1_t
, ret
);
21103 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21104 gen_store_gpr(v1_t
, ret
);
21108 case NM_PRECR_SRA_R_PH_W
:
21110 switch (extract32(ctx
->opcode
, 10, 1)) {
21112 /* PRECR_SRA_PH_W */
21114 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21115 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
21117 gen_store_gpr(v1_t
, rt
);
21118 tcg_temp_free_i32(sa_t
);
21122 /* PRECR_SRA_R_PH_W */
21124 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21125 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
21127 gen_store_gpr(v1_t
, rt
);
21128 tcg_temp_free_i32(sa_t
);
21133 case NM_MULEU_S_PH_QBL
:
21135 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
21136 gen_store_gpr(v1_t
, ret
);
21138 case NM_MULEU_S_PH_QBR
:
21140 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
21141 gen_store_gpr(v1_t
, ret
);
21143 case NM_MULQ_RS_PH
:
21145 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21146 gen_store_gpr(v1_t
, ret
);
21150 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21151 gen_store_gpr(v1_t
, ret
);
21155 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21156 gen_store_gpr(v1_t
, ret
);
21160 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21161 gen_store_gpr(v1_t
, ret
);
21165 gen_load_gpr(t0
, rs
);
21167 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
21169 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21173 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
21174 gen_store_gpr(v1_t
, ret
);
21178 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
21179 gen_store_gpr(v1_t
, ret
);
21183 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
21184 gen_store_gpr(v1_t
, ret
);
21188 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21189 gen_store_gpr(v1_t
, ret
);
21193 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21194 gen_store_gpr(v1_t
, ret
);
21198 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21199 gen_store_gpr(v1_t
, ret
);
21204 TCGv tv0
= tcg_temp_new();
21205 TCGv tv1
= tcg_temp_new();
21206 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21208 tcg_gen_movi_tl(tv0
, rd
>> 3);
21209 tcg_gen_movi_tl(tv1
, imm
);
21210 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21213 case NM_MULEQ_S_W_PHL
:
21215 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21216 gen_store_gpr(v1_t
, ret
);
21218 case NM_MULEQ_S_W_PHR
:
21220 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21221 gen_store_gpr(v1_t
, ret
);
21225 switch (extract32(ctx
->opcode
, 10, 1)) {
21228 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21229 gen_store_gpr(v1_t
, ret
);
21233 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21234 gen_store_gpr(v1_t
, ret
);
21238 case NM_PRECR_QB_PH
:
21240 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21241 gen_store_gpr(v1_t
, ret
);
21243 case NM_PRECRQ_QB_PH
:
21245 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21246 gen_store_gpr(v1_t
, ret
);
21248 case NM_PRECRQ_PH_W
:
21250 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21251 gen_store_gpr(v1_t
, ret
);
21253 case NM_PRECRQ_RS_PH_W
:
21255 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21256 gen_store_gpr(v1_t
, ret
);
21258 case NM_PRECRQU_S_QB_PH
:
21260 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21261 gen_store_gpr(v1_t
, ret
);
21265 tcg_gen_movi_tl(t0
, rd
);
21266 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21267 gen_store_gpr(v1_t
, rt
);
21271 tcg_gen_movi_tl(t0
, rd
>> 1);
21272 switch (extract32(ctx
->opcode
, 10, 1)) {
21275 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21276 gen_store_gpr(v1_t
, rt
);
21280 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21281 gen_store_gpr(v1_t
, rt
);
21287 tcg_gen_movi_tl(t0
, rd
>> 1);
21288 switch (extract32(ctx
->opcode
, 10, 2)) {
21291 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21292 gen_store_gpr(v1_t
, rt
);
21296 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21297 gen_store_gpr(v1_t
, rt
);
21300 generate_exception_end(ctx
, EXCP_RI
);
21306 tcg_gen_movi_tl(t0
, rd
);
21307 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21308 gen_store_gpr(v1_t
, rt
);
21314 imm
= sextract32(ctx
->opcode
, 11, 11);
21315 imm
= (int16_t)(imm
<< 6) >> 6;
21317 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21322 generate_exception_end(ctx
, EXCP_RI
);
21327 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21335 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
21336 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21338 rt
= extract32(ctx
->opcode
, 21, 5);
21339 rs
= extract32(ctx
->opcode
, 16, 5);
21340 rd
= extract32(ctx
->opcode
, 11, 5);
21342 op
= extract32(ctx
->opcode
, 26, 6);
21347 switch (extract32(ctx
->opcode
, 19, 2)) {
21350 generate_exception_end(ctx
, EXCP_RI
);
21353 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21354 generate_exception_end(ctx
, EXCP_SYSCALL
);
21356 generate_exception_end(ctx
, EXCP_RI
);
21360 generate_exception_end(ctx
, EXCP_BREAK
);
21363 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21364 gen_helper_do_semihosting(cpu_env
);
21366 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21367 generate_exception_end(ctx
, EXCP_RI
);
21369 generate_exception_end(ctx
, EXCP_DBp
);
21376 imm
= extract32(ctx
->opcode
, 0, 16);
21378 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21380 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21382 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21387 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21388 extract32(ctx
->opcode
, 1, 20) << 1;
21389 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21390 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21394 switch (ctx
->opcode
& 0x07) {
21396 gen_pool32a0_nanomips_insn(env
, ctx
);
21400 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21401 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21405 switch (extract32(ctx
->opcode
, 3, 3)) {
21407 gen_p_lsx(ctx
, rd
, rs
, rt
);
21411 * In nanoMIPS, the shift field directly encodes the shift
21412 * amount, meaning that the supported shift values are in
21413 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21415 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
21416 extract32(ctx
->opcode
, 9, 2) - 1);
21419 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21422 gen_pool32axf_nanomips_insn(env
, ctx
);
21425 generate_exception_end(ctx
, EXCP_RI
);
21430 generate_exception_end(ctx
, EXCP_RI
);
21435 switch (ctx
->opcode
& 0x03) {
21438 offset
= extract32(ctx
->opcode
, 0, 21);
21439 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21443 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21446 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21449 generate_exception_end(ctx
, EXCP_RI
);
21455 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 4);
21456 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21457 switch (extract32(ctx
->opcode
, 16, 5)) {
21461 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21467 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21468 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21474 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21480 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21483 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21490 t0
= tcg_temp_new();
21492 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21495 tcg_gen_movi_tl(t0
, addr
);
21496 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21504 t0
= tcg_temp_new();
21505 t1
= tcg_temp_new();
21507 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21510 tcg_gen_movi_tl(t0
, addr
);
21511 gen_load_gpr(t1
, rt
);
21513 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21520 generate_exception_end(ctx
, EXCP_RI
);
21526 switch (extract32(ctx
->opcode
, 12, 4)) {
21528 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21531 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21534 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21537 switch (extract32(ctx
->opcode
, 20, 1)) {
21539 switch (ctx
->opcode
& 3) {
21541 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21542 extract32(ctx
->opcode
, 2, 1),
21543 extract32(ctx
->opcode
, 3, 9) << 3);
21546 case NM_RESTORE_JRC
:
21547 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21548 extract32(ctx
->opcode
, 2, 1),
21549 extract32(ctx
->opcode
, 3, 9) << 3);
21550 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21551 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21555 generate_exception_end(ctx
, EXCP_RI
);
21560 generate_exception_end(ctx
, EXCP_RI
);
21565 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21568 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21572 TCGv t0
= tcg_temp_new();
21574 imm
= extract32(ctx
->opcode
, 0, 12);
21575 gen_load_gpr(t0
, rs
);
21576 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
21577 gen_store_gpr(t0
, rt
);
21583 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
21584 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
21588 int shift
= extract32(ctx
->opcode
, 0, 5);
21589 switch (extract32(ctx
->opcode
, 5, 4)) {
21591 if (rt
== 0 && shift
== 0) {
21593 } else if (rt
== 0 && shift
== 3) {
21594 /* EHB - treat as NOP */
21595 } else if (rt
== 0 && shift
== 5) {
21596 /* PAUSE - treat as NOP */
21597 } else if (rt
== 0 && shift
== 6) {
21599 gen_sync(extract32(ctx
->opcode
, 16, 5));
21602 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
21603 extract32(ctx
->opcode
, 0, 5));
21607 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
21608 extract32(ctx
->opcode
, 0, 5));
21611 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
21612 extract32(ctx
->opcode
, 0, 5));
21615 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
21616 extract32(ctx
->opcode
, 0, 5));
21624 TCGv t0
= tcg_temp_new();
21625 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
21626 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
21628 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
21630 gen_load_gpr(t0
, rs
);
21631 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
21634 tcg_temp_free_i32(shift
);
21635 tcg_temp_free_i32(shiftx
);
21636 tcg_temp_free_i32(stripe
);
21640 switch (((ctx
->opcode
>> 10) & 2) |
21641 (extract32(ctx
->opcode
, 5, 1))) {
21644 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21645 extract32(ctx
->opcode
, 6, 5));
21648 generate_exception_end(ctx
, EXCP_RI
);
21653 switch (((ctx
->opcode
>> 10) & 2) |
21654 (extract32(ctx
->opcode
, 5, 1))) {
21657 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21658 extract32(ctx
->opcode
, 6, 5));
21661 generate_exception_end(ctx
, EXCP_RI
);
21666 generate_exception_end(ctx
, EXCP_RI
);
21671 gen_pool32f_nanomips_insn(ctx
);
21676 switch (extract32(ctx
->opcode
, 1, 1)) {
21679 tcg_gen_movi_tl(cpu_gpr
[rt
],
21680 sextract32(ctx
->opcode
, 0, 1) << 31 |
21681 extract32(ctx
->opcode
, 2, 10) << 21 |
21682 extract32(ctx
->opcode
, 12, 9) << 12);
21687 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
21688 extract32(ctx
->opcode
, 2, 10) << 21 |
21689 extract32(ctx
->opcode
, 12, 9) << 12;
21691 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21692 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21699 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
21701 switch (extract32(ctx
->opcode
, 18, 3)) {
21703 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
21706 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
21709 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
21713 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
21718 switch (ctx
->opcode
& 1) {
21720 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
21723 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
21729 switch (ctx
->opcode
& 1) {
21731 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
21734 generate_exception_end(ctx
, EXCP_RI
);
21740 switch (ctx
->opcode
& 0x3) {
21742 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
21745 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
21748 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
21751 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
21756 generate_exception_end(ctx
, EXCP_RI
);
21763 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
21765 switch (extract32(ctx
->opcode
, 12, 4)) {
21770 * Break the TB to be able to sync copied instructions
21773 ctx
->base
.is_jmp
= DISAS_STOP
;
21776 /* Treat as NOP. */
21780 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
21783 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
21786 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
21789 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
21792 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
21795 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
21798 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
21801 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
21804 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
21807 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
21810 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
21813 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
21816 generate_exception_end(ctx
, EXCP_RI
);
21823 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
21824 extract32(ctx
->opcode
, 0, 8);
21826 switch (extract32(ctx
->opcode
, 8, 3)) {
21828 switch (extract32(ctx
->opcode
, 11, 4)) {
21830 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
21833 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
21836 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
21839 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
21842 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
21845 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
21848 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
21851 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
21854 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
21857 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
21860 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
21863 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
21869 * Break the TB to be able to sync copied instructions
21872 ctx
->base
.is_jmp
= DISAS_STOP
;
21875 /* Treat as NOP. */
21879 generate_exception_end(ctx
, EXCP_RI
);
21884 switch (extract32(ctx
->opcode
, 11, 4)) {
21889 TCGv t0
= tcg_temp_new();
21890 TCGv t1
= tcg_temp_new();
21892 gen_base_offset_addr(ctx
, t0
, rs
, s
);
21894 switch (extract32(ctx
->opcode
, 11, 4)) {
21896 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
21898 gen_store_gpr(t0
, rt
);
21901 gen_load_gpr(t1
, rt
);
21902 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
21911 switch (ctx
->opcode
& 0x03) {
21913 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
21917 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21922 switch (ctx
->opcode
& 0x03) {
21924 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
21928 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21934 check_cp0_enabled(ctx
);
21935 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
21936 gen_cache_operation(ctx
, rt
, rs
, s
);
21942 switch (extract32(ctx
->opcode
, 11, 4)) {
21945 check_cp0_enabled(ctx
);
21946 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
21950 check_cp0_enabled(ctx
);
21951 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
21955 check_cp0_enabled(ctx
);
21956 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
21960 /* case NM_SYNCIE */
21962 check_cp0_enabled(ctx
);
21964 * Break the TB to be able to sync copied instructions
21967 ctx
->base
.is_jmp
= DISAS_STOP
;
21969 /* case NM_PREFE */
21971 check_cp0_enabled(ctx
);
21972 /* Treat as NOP. */
21977 check_cp0_enabled(ctx
);
21978 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
21982 check_cp0_enabled(ctx
);
21983 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
21987 check_cp0_enabled(ctx
);
21988 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
21991 check_nms_dl_il_sl_tl_l2c(ctx
);
21992 gen_cache_operation(ctx
, rt
, rs
, s
);
21996 check_cp0_enabled(ctx
);
21997 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
22001 check_cp0_enabled(ctx
);
22002 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
22005 switch (extract32(ctx
->opcode
, 2, 2)) {
22009 check_cp0_enabled(ctx
);
22010 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
22015 check_cp0_enabled(ctx
);
22016 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22019 generate_exception_end(ctx
, EXCP_RI
);
22024 switch (extract32(ctx
->opcode
, 2, 2)) {
22028 check_cp0_enabled(ctx
);
22029 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
22034 check_cp0_enabled(ctx
);
22035 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22039 generate_exception_end(ctx
, EXCP_RI
);
22049 int count
= extract32(ctx
->opcode
, 12, 3);
22052 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
22053 extract32(ctx
->opcode
, 0, 8);
22054 TCGv va
= tcg_temp_new();
22055 TCGv t1
= tcg_temp_new();
22056 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
22057 NM_P_LS_UAWM
? MO_UNALN
: 0;
22059 count
= (count
== 0) ? 8 : count
;
22060 while (counter
!= count
) {
22061 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
22062 int this_offset
= offset
+ (counter
<< 2);
22064 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
22066 switch (extract32(ctx
->opcode
, 11, 1)) {
22068 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
22070 gen_store_gpr(t1
, this_rt
);
22071 if ((this_rt
== rs
) &&
22072 (counter
!= (count
- 1))) {
22073 /* UNPREDICTABLE */
22077 this_rt
= (rt
== 0) ? 0 : this_rt
;
22078 gen_load_gpr(t1
, this_rt
);
22079 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
22090 generate_exception_end(ctx
, EXCP_RI
);
22098 TCGv t0
= tcg_temp_new();
22099 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
22100 extract32(ctx
->opcode
, 1, 20) << 1;
22101 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
22102 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
22103 extract32(ctx
->opcode
, 21, 3));
22104 gen_load_gpr(t0
, rt
);
22105 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22106 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22112 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
22113 extract32(ctx
->opcode
, 1, 24) << 1;
22115 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
22117 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
22120 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22125 switch (extract32(ctx
->opcode
, 12, 4)) {
22128 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
22131 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
22134 generate_exception_end(ctx
, EXCP_RI
);
22140 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22141 extract32(ctx
->opcode
, 1, 13) << 1;
22142 switch (extract32(ctx
->opcode
, 14, 2)) {
22145 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
22148 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22149 extract32(ctx
->opcode
, 1, 13) << 1;
22150 check_cp1_enabled(ctx
);
22151 switch (extract32(ctx
->opcode
, 16, 5)) {
22153 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
22156 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
22161 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
22162 extract32(ctx
->opcode
, 0, 1) << 13;
22164 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
22169 generate_exception_end(ctx
, EXCP_RI
);
22175 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
22177 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
22181 if (rs
== rt
|| rt
== 0) {
22182 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
22183 } else if (rs
== 0) {
22184 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
22186 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22194 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22195 extract32(ctx
->opcode
, 1, 13) << 1;
22196 switch (extract32(ctx
->opcode
, 14, 2)) {
22199 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22202 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22204 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22206 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22210 if (rs
== 0 || rs
== rt
) {
22212 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22214 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22218 generate_exception_end(ctx
, EXCP_RI
);
22225 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22226 extract32(ctx
->opcode
, 1, 10) << 1;
22227 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22229 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22234 generate_exception_end(ctx
, EXCP_RI
);
22240 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22243 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22244 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22245 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22249 /* make sure instructions are on a halfword boundary */
22250 if (ctx
->base
.pc_next
& 0x1) {
22251 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22252 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22253 tcg_temp_free(tmp
);
22254 generate_exception_end(ctx
, EXCP_AdEL
);
22258 op
= extract32(ctx
->opcode
, 10, 6);
22261 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22264 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22265 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22268 switch (extract32(ctx
->opcode
, 3, 2)) {
22269 case NM_P16_SYSCALL
:
22270 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22271 generate_exception_end(ctx
, EXCP_SYSCALL
);
22273 generate_exception_end(ctx
, EXCP_RI
);
22277 generate_exception_end(ctx
, EXCP_BREAK
);
22280 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22281 gen_helper_do_semihosting(cpu_env
);
22283 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22284 generate_exception_end(ctx
, EXCP_RI
);
22286 generate_exception_end(ctx
, EXCP_DBp
);
22291 generate_exception_end(ctx
, EXCP_RI
);
22298 int shift
= extract32(ctx
->opcode
, 0, 3);
22300 shift
= (shift
== 0) ? 8 : shift
;
22302 switch (extract32(ctx
->opcode
, 3, 1)) {
22310 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22314 switch (ctx
->opcode
& 1) {
22316 gen_pool16c_nanomips_insn(ctx
);
22319 gen_ldxs(ctx
, rt
, rs
, rd
);
22324 switch (extract32(ctx
->opcode
, 6, 1)) {
22326 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22327 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22330 generate_exception_end(ctx
, EXCP_RI
);
22335 switch (extract32(ctx
->opcode
, 3, 1)) {
22337 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22338 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22340 case NM_P_ADDIURS5
:
22341 rt
= extract32(ctx
->opcode
, 5, 5);
22343 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22344 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22345 (extract32(ctx
->opcode
, 0, 3));
22346 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22352 switch (ctx
->opcode
& 0x1) {
22354 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22357 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22362 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22363 extract32(ctx
->opcode
, 5, 3);
22364 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22365 extract32(ctx
->opcode
, 0, 3);
22366 rt
= decode_gpr_gpr4(rt
);
22367 rs
= decode_gpr_gpr4(rs
);
22368 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22369 (extract32(ctx
->opcode
, 3, 1))) {
22372 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22376 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22379 generate_exception_end(ctx
, EXCP_RI
);
22385 int imm
= extract32(ctx
->opcode
, 0, 7);
22386 imm
= (imm
== 0x7f ? -1 : imm
);
22388 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22394 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22395 u
= (u
== 12) ? 0xff :
22396 (u
== 13) ? 0xffff : u
;
22397 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22401 offset
= extract32(ctx
->opcode
, 0, 2);
22402 switch (extract32(ctx
->opcode
, 2, 2)) {
22404 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22407 rt
= decode_gpr_gpr3_src_store(
22408 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22409 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22412 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22415 generate_exception_end(ctx
, EXCP_RI
);
22420 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22421 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22423 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22426 rt
= decode_gpr_gpr3_src_store(
22427 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22428 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22431 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22434 generate_exception_end(ctx
, EXCP_RI
);
22439 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22440 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22443 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22444 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22445 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22449 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22450 extract32(ctx
->opcode
, 5, 3);
22451 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22452 extract32(ctx
->opcode
, 0, 3);
22453 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22454 (extract32(ctx
->opcode
, 8, 1) << 2);
22455 rt
= decode_gpr_gpr4(rt
);
22456 rs
= decode_gpr_gpr4(rs
);
22457 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22461 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22462 extract32(ctx
->opcode
, 5, 3);
22463 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22464 extract32(ctx
->opcode
, 0, 3);
22465 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22466 (extract32(ctx
->opcode
, 8, 1) << 2);
22467 rt
= decode_gpr_gpr4_zero(rt
);
22468 rs
= decode_gpr_gpr4(rs
);
22469 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22472 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22473 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22476 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22477 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22478 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22481 rt
= decode_gpr_gpr3_src_store(
22482 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22483 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22484 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22485 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22488 rt
= decode_gpr_gpr3_src_store(
22489 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22490 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22491 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22494 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22495 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22496 (extract32(ctx
->opcode
, 1, 9) << 1));
22499 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22500 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22501 (extract32(ctx
->opcode
, 1, 9) << 1));
22504 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22505 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22506 (extract32(ctx
->opcode
, 1, 6) << 1));
22509 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22510 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22511 (extract32(ctx
->opcode
, 1, 6) << 1));
22514 switch (ctx
->opcode
& 0xf) {
22517 switch (extract32(ctx
->opcode
, 4, 1)) {
22519 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22520 extract32(ctx
->opcode
, 5, 5), 0, 0);
22523 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22524 extract32(ctx
->opcode
, 5, 5), 31, 0);
22531 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22532 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22533 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22534 extract32(ctx
->opcode
, 0, 4) << 1);
22541 int count
= extract32(ctx
->opcode
, 0, 4);
22542 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22544 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22545 switch (extract32(ctx
->opcode
, 8, 1)) {
22547 gen_save(ctx
, rt
, count
, 0, u
);
22549 case NM_RESTORE_JRC16
:
22550 gen_restore(ctx
, rt
, count
, 0, u
);
22551 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22560 static const int gpr2reg1
[] = {4, 5, 6, 7};
22561 static const int gpr2reg2
[] = {5, 6, 7, 8};
22563 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22564 extract32(ctx
->opcode
, 8, 1);
22565 int r1
= gpr2reg1
[rd2
];
22566 int r2
= gpr2reg2
[rd2
];
22567 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22568 extract32(ctx
->opcode
, 0, 3);
22569 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22570 extract32(ctx
->opcode
, 5, 3);
22571 TCGv t0
= tcg_temp_new();
22572 TCGv t1
= tcg_temp_new();
22573 if (op
== NM_MOVEP
) {
22576 rs
= decode_gpr_gpr4_zero(r3
);
22577 rt
= decode_gpr_gpr4_zero(r4
);
22579 rd
= decode_gpr_gpr4(r3
);
22580 re
= decode_gpr_gpr4(r4
);
22584 gen_load_gpr(t0
, rs
);
22585 gen_load_gpr(t1
, rt
);
22586 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22587 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
22593 return decode_nanomips_32_48_opc(env
, ctx
);
22600 /* SmartMIPS extension to MIPS32 */
22602 #if defined(TARGET_MIPS64)
22604 /* MDMX extension to MIPS64 */
22608 /* MIPSDSP functions. */
22609 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
22610 int rd
, int base
, int offset
)
22615 t0
= tcg_temp_new();
22618 gen_load_gpr(t0
, offset
);
22619 } else if (offset
== 0) {
22620 gen_load_gpr(t0
, base
);
22622 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
22627 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
22628 gen_store_gpr(t0
, rd
);
22631 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
22632 gen_store_gpr(t0
, rd
);
22635 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
22636 gen_store_gpr(t0
, rd
);
22638 #if defined(TARGET_MIPS64)
22640 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
22641 gen_store_gpr(t0
, rd
);
22648 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22649 int ret
, int v1
, int v2
)
22655 /* Treat as NOP. */
22659 v1_t
= tcg_temp_new();
22660 v2_t
= tcg_temp_new();
22662 gen_load_gpr(v1_t
, v1
);
22663 gen_load_gpr(v2_t
, v2
);
22666 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22667 case OPC_MULT_G_2E
:
22671 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22673 case OPC_ADDUH_R_QB
:
22674 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22677 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22679 case OPC_ADDQH_R_PH
:
22680 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22683 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22685 case OPC_ADDQH_R_W
:
22686 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22689 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22691 case OPC_SUBUH_R_QB
:
22692 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22695 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22697 case OPC_SUBQH_R_PH
:
22698 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22701 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22703 case OPC_SUBQH_R_W
:
22704 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22708 case OPC_ABSQ_S_PH_DSP
:
22710 case OPC_ABSQ_S_QB
:
22712 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
22714 case OPC_ABSQ_S_PH
:
22716 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
22720 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
22722 case OPC_PRECEQ_W_PHL
:
22724 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
22725 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22727 case OPC_PRECEQ_W_PHR
:
22729 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
22730 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
22731 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22733 case OPC_PRECEQU_PH_QBL
:
22735 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
22737 case OPC_PRECEQU_PH_QBR
:
22739 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
22741 case OPC_PRECEQU_PH_QBLA
:
22743 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
22745 case OPC_PRECEQU_PH_QBRA
:
22747 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
22749 case OPC_PRECEU_PH_QBL
:
22751 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
22753 case OPC_PRECEU_PH_QBR
:
22755 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
22757 case OPC_PRECEU_PH_QBLA
:
22759 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
22761 case OPC_PRECEU_PH_QBRA
:
22763 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
22767 case OPC_ADDU_QB_DSP
:
22771 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22773 case OPC_ADDQ_S_PH
:
22775 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22779 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22783 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22785 case OPC_ADDU_S_QB
:
22787 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22791 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22793 case OPC_ADDU_S_PH
:
22795 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22799 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22801 case OPC_SUBQ_S_PH
:
22803 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22807 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22811 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22813 case OPC_SUBU_S_QB
:
22815 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22819 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22821 case OPC_SUBU_S_PH
:
22823 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22827 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22831 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22835 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
22837 case OPC_RADDU_W_QB
:
22839 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
22843 case OPC_CMPU_EQ_QB_DSP
:
22845 case OPC_PRECR_QB_PH
:
22847 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22849 case OPC_PRECRQ_QB_PH
:
22851 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22853 case OPC_PRECR_SRA_PH_W
:
22856 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22857 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22859 tcg_temp_free_i32(sa_t
);
22862 case OPC_PRECR_SRA_R_PH_W
:
22865 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22866 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22868 tcg_temp_free_i32(sa_t
);
22871 case OPC_PRECRQ_PH_W
:
22873 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22875 case OPC_PRECRQ_RS_PH_W
:
22877 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22879 case OPC_PRECRQU_S_QB_PH
:
22881 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22885 #ifdef TARGET_MIPS64
22886 case OPC_ABSQ_S_QH_DSP
:
22888 case OPC_PRECEQ_L_PWL
:
22890 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
22892 case OPC_PRECEQ_L_PWR
:
22894 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
22896 case OPC_PRECEQ_PW_QHL
:
22898 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
22900 case OPC_PRECEQ_PW_QHR
:
22902 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
22904 case OPC_PRECEQ_PW_QHLA
:
22906 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
22908 case OPC_PRECEQ_PW_QHRA
:
22910 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
22912 case OPC_PRECEQU_QH_OBL
:
22914 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
22916 case OPC_PRECEQU_QH_OBR
:
22918 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
22920 case OPC_PRECEQU_QH_OBLA
:
22922 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
22924 case OPC_PRECEQU_QH_OBRA
:
22926 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
22928 case OPC_PRECEU_QH_OBL
:
22930 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
22932 case OPC_PRECEU_QH_OBR
:
22934 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
22936 case OPC_PRECEU_QH_OBLA
:
22938 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
22940 case OPC_PRECEU_QH_OBRA
:
22942 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
22944 case OPC_ABSQ_S_OB
:
22946 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
22948 case OPC_ABSQ_S_PW
:
22950 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
22952 case OPC_ABSQ_S_QH
:
22954 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
22958 case OPC_ADDU_OB_DSP
:
22960 case OPC_RADDU_L_OB
:
22962 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
22966 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22968 case OPC_SUBQ_S_PW
:
22970 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22974 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22976 case OPC_SUBQ_S_QH
:
22978 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22982 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22984 case OPC_SUBU_S_OB
:
22986 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22990 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22992 case OPC_SUBU_S_QH
:
22994 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22998 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23000 case OPC_SUBUH_R_OB
:
23002 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23006 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23008 case OPC_ADDQ_S_PW
:
23010 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23014 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23016 case OPC_ADDQ_S_QH
:
23018 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23022 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23024 case OPC_ADDU_S_OB
:
23026 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23030 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23032 case OPC_ADDU_S_QH
:
23034 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23038 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23040 case OPC_ADDUH_R_OB
:
23042 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23046 case OPC_CMPU_EQ_OB_DSP
:
23048 case OPC_PRECR_OB_QH
:
23050 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23052 case OPC_PRECR_SRA_QH_PW
:
23055 TCGv_i32 ret_t
= tcg_const_i32(ret
);
23056 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
23057 tcg_temp_free_i32(ret_t
);
23060 case OPC_PRECR_SRA_R_QH_PW
:
23063 TCGv_i32 sa_v
= tcg_const_i32(ret
);
23064 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
23065 tcg_temp_free_i32(sa_v
);
23068 case OPC_PRECRQ_OB_QH
:
23070 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23072 case OPC_PRECRQ_PW_L
:
23074 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
23076 case OPC_PRECRQ_QH_PW
:
23078 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23080 case OPC_PRECRQ_RS_QH_PW
:
23082 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23084 case OPC_PRECRQU_S_OB_QH
:
23086 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23093 tcg_temp_free(v1_t
);
23094 tcg_temp_free(v2_t
);
23097 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
23098 int ret
, int v1
, int v2
)
23106 /* Treat as NOP. */
23110 t0
= tcg_temp_new();
23111 v1_t
= tcg_temp_new();
23112 v2_t
= tcg_temp_new();
23114 tcg_gen_movi_tl(t0
, v1
);
23115 gen_load_gpr(v1_t
, v1
);
23116 gen_load_gpr(v2_t
, v2
);
23119 case OPC_SHLL_QB_DSP
:
23121 op2
= MASK_SHLL_QB(ctx
->opcode
);
23125 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23129 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23133 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23137 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23139 case OPC_SHLL_S_PH
:
23141 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23143 case OPC_SHLLV_S_PH
:
23145 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23149 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23151 case OPC_SHLLV_S_W
:
23153 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23157 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
23161 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23165 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
23169 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23173 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
23175 case OPC_SHRA_R_QB
:
23177 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
23181 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23183 case OPC_SHRAV_R_QB
:
23185 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23189 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23191 case OPC_SHRA_R_PH
:
23193 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23197 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23199 case OPC_SHRAV_R_PH
:
23201 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23205 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23207 case OPC_SHRAV_R_W
:
23209 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23211 default: /* Invalid */
23212 MIPS_INVAL("MASK SHLL.QB");
23213 generate_exception_end(ctx
, EXCP_RI
);
23218 #ifdef TARGET_MIPS64
23219 case OPC_SHLL_OB_DSP
:
23220 op2
= MASK_SHLL_OB(ctx
->opcode
);
23224 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23228 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23230 case OPC_SHLL_S_PW
:
23232 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23234 case OPC_SHLLV_S_PW
:
23236 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23240 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23244 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23248 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23252 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23254 case OPC_SHLL_S_QH
:
23256 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23258 case OPC_SHLLV_S_QH
:
23260 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23264 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23268 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23270 case OPC_SHRA_R_OB
:
23272 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23274 case OPC_SHRAV_R_OB
:
23276 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23280 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23284 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23286 case OPC_SHRA_R_PW
:
23288 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23290 case OPC_SHRAV_R_PW
:
23292 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23296 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23300 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23302 case OPC_SHRA_R_QH
:
23304 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23306 case OPC_SHRAV_R_QH
:
23308 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23312 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23316 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23320 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23324 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23326 default: /* Invalid */
23327 MIPS_INVAL("MASK SHLL.OB");
23328 generate_exception_end(ctx
, EXCP_RI
);
23336 tcg_temp_free(v1_t
);
23337 tcg_temp_free(v2_t
);
23340 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23341 int ret
, int v1
, int v2
, int check_ret
)
23347 if ((ret
== 0) && (check_ret
== 1)) {
23348 /* Treat as NOP. */
23352 t0
= tcg_temp_new_i32();
23353 v1_t
= tcg_temp_new();
23354 v2_t
= tcg_temp_new();
23356 tcg_gen_movi_i32(t0
, ret
);
23357 gen_load_gpr(v1_t
, v1
);
23358 gen_load_gpr(v2_t
, v2
);
23362 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23363 * the same mask and op1.
23365 case OPC_MULT_G_2E
:
23369 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23372 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23375 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23377 case OPC_MULQ_RS_W
:
23378 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23382 case OPC_DPA_W_PH_DSP
:
23384 case OPC_DPAU_H_QBL
:
23386 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23388 case OPC_DPAU_H_QBR
:
23390 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23392 case OPC_DPSU_H_QBL
:
23394 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23396 case OPC_DPSU_H_QBR
:
23398 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23402 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23404 case OPC_DPAX_W_PH
:
23406 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23408 case OPC_DPAQ_S_W_PH
:
23410 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23412 case OPC_DPAQX_S_W_PH
:
23414 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23416 case OPC_DPAQX_SA_W_PH
:
23418 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23422 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23424 case OPC_DPSX_W_PH
:
23426 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23428 case OPC_DPSQ_S_W_PH
:
23430 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23432 case OPC_DPSQX_S_W_PH
:
23434 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23436 case OPC_DPSQX_SA_W_PH
:
23438 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23440 case OPC_MULSAQ_S_W_PH
:
23442 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23444 case OPC_DPAQ_SA_L_W
:
23446 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23448 case OPC_DPSQ_SA_L_W
:
23450 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23452 case OPC_MAQ_S_W_PHL
:
23454 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23456 case OPC_MAQ_S_W_PHR
:
23458 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23460 case OPC_MAQ_SA_W_PHL
:
23462 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23464 case OPC_MAQ_SA_W_PHR
:
23466 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23468 case OPC_MULSA_W_PH
:
23470 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23474 #ifdef TARGET_MIPS64
23475 case OPC_DPAQ_W_QH_DSP
:
23477 int ac
= ret
& 0x03;
23478 tcg_gen_movi_i32(t0
, ac
);
23483 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23487 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23491 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23495 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23499 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23501 case OPC_DPAQ_S_W_QH
:
23503 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23505 case OPC_DPAQ_SA_L_PW
:
23507 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23509 case OPC_DPAU_H_OBL
:
23511 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23513 case OPC_DPAU_H_OBR
:
23515 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23519 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23521 case OPC_DPSQ_S_W_QH
:
23523 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23525 case OPC_DPSQ_SA_L_PW
:
23527 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23529 case OPC_DPSU_H_OBL
:
23531 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23533 case OPC_DPSU_H_OBR
:
23535 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23537 case OPC_MAQ_S_L_PWL
:
23539 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23541 case OPC_MAQ_S_L_PWR
:
23543 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23545 case OPC_MAQ_S_W_QHLL
:
23547 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23549 case OPC_MAQ_SA_W_QHLL
:
23551 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23553 case OPC_MAQ_S_W_QHLR
:
23555 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23557 case OPC_MAQ_SA_W_QHLR
:
23559 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23561 case OPC_MAQ_S_W_QHRL
:
23563 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23565 case OPC_MAQ_SA_W_QHRL
:
23567 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23569 case OPC_MAQ_S_W_QHRR
:
23571 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23573 case OPC_MAQ_SA_W_QHRR
:
23575 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23577 case OPC_MULSAQ_S_L_PW
:
23579 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23581 case OPC_MULSAQ_S_W_QH
:
23583 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23589 case OPC_ADDU_QB_DSP
:
23591 case OPC_MULEU_S_PH_QBL
:
23593 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23595 case OPC_MULEU_S_PH_QBR
:
23597 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23599 case OPC_MULQ_RS_PH
:
23601 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23603 case OPC_MULEQ_S_W_PHL
:
23605 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23607 case OPC_MULEQ_S_W_PHR
:
23609 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23611 case OPC_MULQ_S_PH
:
23613 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23617 #ifdef TARGET_MIPS64
23618 case OPC_ADDU_OB_DSP
:
23620 case OPC_MULEQ_S_PW_QHL
:
23622 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23624 case OPC_MULEQ_S_PW_QHR
:
23626 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23628 case OPC_MULEU_S_QH_OBL
:
23630 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23632 case OPC_MULEU_S_QH_OBR
:
23634 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23636 case OPC_MULQ_RS_QH
:
23638 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23645 tcg_temp_free_i32(t0
);
23646 tcg_temp_free(v1_t
);
23647 tcg_temp_free(v2_t
);
23650 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23658 /* Treat as NOP. */
23662 t0
= tcg_temp_new();
23663 val_t
= tcg_temp_new();
23664 gen_load_gpr(val_t
, val
);
23667 case OPC_ABSQ_S_PH_DSP
:
23671 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
23676 target_long result
;
23677 imm
= (ctx
->opcode
>> 16) & 0xFF;
23678 result
= (uint32_t)imm
<< 24 |
23679 (uint32_t)imm
<< 16 |
23680 (uint32_t)imm
<< 8 |
23682 result
= (int32_t)result
;
23683 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
23688 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23689 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23690 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23691 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23692 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23693 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23698 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23699 imm
= (int16_t)(imm
<< 6) >> 6;
23700 tcg_gen_movi_tl(cpu_gpr
[ret
], \
23701 (target_long
)((int32_t)imm
<< 16 | \
23707 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23708 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23709 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23710 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23714 #ifdef TARGET_MIPS64
23715 case OPC_ABSQ_S_QH_DSP
:
23722 imm
= (ctx
->opcode
>> 16) & 0xFF;
23723 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
23724 temp
= (temp
<< 16) | temp
;
23725 temp
= (temp
<< 32) | temp
;
23726 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23734 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23735 imm
= (int16_t)(imm
<< 6) >> 6;
23736 temp
= ((target_long
)imm
<< 32) \
23737 | ((target_long
)imm
& 0xFFFFFFFF);
23738 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23746 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23747 imm
= (int16_t)(imm
<< 6) >> 6;
23749 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
23750 ((uint64_t)(uint16_t)imm
<< 32) |
23751 ((uint64_t)(uint16_t)imm
<< 16) |
23752 (uint64_t)(uint16_t)imm
;
23753 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23758 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23759 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23760 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23761 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23762 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23763 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23764 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23768 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
23769 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23770 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23774 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23775 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23776 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23777 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23778 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23785 tcg_temp_free(val_t
);
23788 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
23789 uint32_t op1
, uint32_t op2
,
23790 int ret
, int v1
, int v2
, int check_ret
)
23796 if ((ret
== 0) && (check_ret
== 1)) {
23797 /* Treat as NOP. */
23801 t1
= tcg_temp_new();
23802 v1_t
= tcg_temp_new();
23803 v2_t
= tcg_temp_new();
23805 gen_load_gpr(v1_t
, v1
);
23806 gen_load_gpr(v2_t
, v2
);
23809 case OPC_CMPU_EQ_QB_DSP
:
23811 case OPC_CMPU_EQ_QB
:
23813 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
23815 case OPC_CMPU_LT_QB
:
23817 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
23819 case OPC_CMPU_LE_QB
:
23821 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
23823 case OPC_CMPGU_EQ_QB
:
23825 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23827 case OPC_CMPGU_LT_QB
:
23829 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23831 case OPC_CMPGU_LE_QB
:
23833 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23835 case OPC_CMPGDU_EQ_QB
:
23837 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
23838 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23839 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23840 tcg_gen_shli_tl(t1
, t1
, 24);
23841 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23843 case OPC_CMPGDU_LT_QB
:
23845 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
23846 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23847 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23848 tcg_gen_shli_tl(t1
, t1
, 24);
23849 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23851 case OPC_CMPGDU_LE_QB
:
23853 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
23854 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23855 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23856 tcg_gen_shli_tl(t1
, t1
, 24);
23857 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23859 case OPC_CMP_EQ_PH
:
23861 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
23863 case OPC_CMP_LT_PH
:
23865 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
23867 case OPC_CMP_LE_PH
:
23869 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
23873 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23877 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23879 case OPC_PACKRL_PH
:
23881 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23885 #ifdef TARGET_MIPS64
23886 case OPC_CMPU_EQ_OB_DSP
:
23888 case OPC_CMP_EQ_PW
:
23890 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
23892 case OPC_CMP_LT_PW
:
23894 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
23896 case OPC_CMP_LE_PW
:
23898 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
23900 case OPC_CMP_EQ_QH
:
23902 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
23904 case OPC_CMP_LT_QH
:
23906 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
23908 case OPC_CMP_LE_QH
:
23910 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
23912 case OPC_CMPGDU_EQ_OB
:
23914 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23916 case OPC_CMPGDU_LT_OB
:
23918 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23920 case OPC_CMPGDU_LE_OB
:
23922 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23924 case OPC_CMPGU_EQ_OB
:
23926 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23928 case OPC_CMPGU_LT_OB
:
23930 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23932 case OPC_CMPGU_LE_OB
:
23934 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23936 case OPC_CMPU_EQ_OB
:
23938 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
23940 case OPC_CMPU_LT_OB
:
23942 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
23944 case OPC_CMPU_LE_OB
:
23946 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
23948 case OPC_PACKRL_PW
:
23950 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23954 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23958 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23962 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23970 tcg_temp_free(v1_t
);
23971 tcg_temp_free(v2_t
);
23974 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
23975 uint32_t op1
, int rt
, int rs
, int sa
)
23982 /* Treat as NOP. */
23986 t0
= tcg_temp_new();
23987 gen_load_gpr(t0
, rs
);
23990 case OPC_APPEND_DSP
:
23991 switch (MASK_APPEND(ctx
->opcode
)) {
23994 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
23996 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24000 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24001 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24002 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
24003 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24005 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24009 if (sa
!= 0 && sa
!= 2) {
24010 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24011 tcg_gen_ext32u_tl(t0
, t0
);
24012 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
24013 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24015 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24017 default: /* Invalid */
24018 MIPS_INVAL("MASK APPEND");
24019 generate_exception_end(ctx
, EXCP_RI
);
24023 #ifdef TARGET_MIPS64
24024 case OPC_DAPPEND_DSP
:
24025 switch (MASK_DAPPEND(ctx
->opcode
)) {
24028 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
24032 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
24033 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
24034 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
24038 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24039 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
24040 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24045 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
24046 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24047 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
24048 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24051 default: /* Invalid */
24052 MIPS_INVAL("MASK DAPPEND");
24053 generate_exception_end(ctx
, EXCP_RI
);
24062 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24063 int ret
, int v1
, int v2
, int check_ret
)
24072 if ((ret
== 0) && (check_ret
== 1)) {
24073 /* Treat as NOP. */
24077 t0
= tcg_temp_new();
24078 t1
= tcg_temp_new();
24079 v1_t
= tcg_temp_new();
24080 v2_t
= tcg_temp_new();
24082 gen_load_gpr(v1_t
, v1
);
24083 gen_load_gpr(v2_t
, v2
);
24086 case OPC_EXTR_W_DSP
:
24090 tcg_gen_movi_tl(t0
, v2
);
24091 tcg_gen_movi_tl(t1
, v1
);
24092 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24095 tcg_gen_movi_tl(t0
, v2
);
24096 tcg_gen_movi_tl(t1
, v1
);
24097 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24099 case OPC_EXTR_RS_W
:
24100 tcg_gen_movi_tl(t0
, v2
);
24101 tcg_gen_movi_tl(t1
, v1
);
24102 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24105 tcg_gen_movi_tl(t0
, v2
);
24106 tcg_gen_movi_tl(t1
, v1
);
24107 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24109 case OPC_EXTRV_S_H
:
24110 tcg_gen_movi_tl(t0
, v2
);
24111 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24114 tcg_gen_movi_tl(t0
, v2
);
24115 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24117 case OPC_EXTRV_R_W
:
24118 tcg_gen_movi_tl(t0
, v2
);
24119 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24121 case OPC_EXTRV_RS_W
:
24122 tcg_gen_movi_tl(t0
, v2
);
24123 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24126 tcg_gen_movi_tl(t0
, v2
);
24127 tcg_gen_movi_tl(t1
, v1
);
24128 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24131 tcg_gen_movi_tl(t0
, v2
);
24132 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24135 tcg_gen_movi_tl(t0
, v2
);
24136 tcg_gen_movi_tl(t1
, v1
);
24137 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24140 tcg_gen_movi_tl(t0
, v2
);
24141 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24144 imm
= (ctx
->opcode
>> 20) & 0x3F;
24145 tcg_gen_movi_tl(t0
, ret
);
24146 tcg_gen_movi_tl(t1
, imm
);
24147 gen_helper_shilo(t0
, t1
, cpu_env
);
24150 tcg_gen_movi_tl(t0
, ret
);
24151 gen_helper_shilo(t0
, v1_t
, cpu_env
);
24154 tcg_gen_movi_tl(t0
, ret
);
24155 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
24158 imm
= (ctx
->opcode
>> 11) & 0x3FF;
24159 tcg_gen_movi_tl(t0
, imm
);
24160 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
24163 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24164 tcg_gen_movi_tl(t0
, imm
);
24165 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
24169 #ifdef TARGET_MIPS64
24170 case OPC_DEXTR_W_DSP
:
24174 tcg_gen_movi_tl(t0
, ret
);
24175 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
24179 int shift
= (ctx
->opcode
>> 19) & 0x7F;
24180 int ac
= (ctx
->opcode
>> 11) & 0x03;
24181 tcg_gen_movi_tl(t0
, shift
);
24182 tcg_gen_movi_tl(t1
, ac
);
24183 gen_helper_dshilo(t0
, t1
, cpu_env
);
24188 int ac
= (ctx
->opcode
>> 11) & 0x03;
24189 tcg_gen_movi_tl(t0
, ac
);
24190 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24194 tcg_gen_movi_tl(t0
, v2
);
24195 tcg_gen_movi_tl(t1
, v1
);
24197 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24200 tcg_gen_movi_tl(t0
, v2
);
24201 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24204 tcg_gen_movi_tl(t0
, v2
);
24205 tcg_gen_movi_tl(t1
, v1
);
24206 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24209 tcg_gen_movi_tl(t0
, v2
);
24210 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24213 tcg_gen_movi_tl(t0
, v2
);
24214 tcg_gen_movi_tl(t1
, v1
);
24215 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24217 case OPC_DEXTR_R_L
:
24218 tcg_gen_movi_tl(t0
, v2
);
24219 tcg_gen_movi_tl(t1
, v1
);
24220 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24222 case OPC_DEXTR_RS_L
:
24223 tcg_gen_movi_tl(t0
, v2
);
24224 tcg_gen_movi_tl(t1
, v1
);
24225 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24228 tcg_gen_movi_tl(t0
, v2
);
24229 tcg_gen_movi_tl(t1
, v1
);
24230 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24232 case OPC_DEXTR_R_W
:
24233 tcg_gen_movi_tl(t0
, v2
);
24234 tcg_gen_movi_tl(t1
, v1
);
24235 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24237 case OPC_DEXTR_RS_W
:
24238 tcg_gen_movi_tl(t0
, v2
);
24239 tcg_gen_movi_tl(t1
, v1
);
24240 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24242 case OPC_DEXTR_S_H
:
24243 tcg_gen_movi_tl(t0
, v2
);
24244 tcg_gen_movi_tl(t1
, v1
);
24245 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24247 case OPC_DEXTRV_S_H
:
24248 tcg_gen_movi_tl(t0
, v2
);
24249 tcg_gen_movi_tl(t1
, v1
);
24250 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24253 tcg_gen_movi_tl(t0
, v2
);
24254 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24256 case OPC_DEXTRV_R_L
:
24257 tcg_gen_movi_tl(t0
, v2
);
24258 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24260 case OPC_DEXTRV_RS_L
:
24261 tcg_gen_movi_tl(t0
, v2
);
24262 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24265 tcg_gen_movi_tl(t0
, v2
);
24266 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24268 case OPC_DEXTRV_R_W
:
24269 tcg_gen_movi_tl(t0
, v2
);
24270 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24272 case OPC_DEXTRV_RS_W
:
24273 tcg_gen_movi_tl(t0
, v2
);
24274 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24283 tcg_temp_free(v1_t
);
24284 tcg_temp_free(v2_t
);
24287 /* End MIPSDSP functions. */
24289 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24291 int rs
, rt
, rd
, sa
;
24294 rs
= (ctx
->opcode
>> 21) & 0x1f;
24295 rt
= (ctx
->opcode
>> 16) & 0x1f;
24296 rd
= (ctx
->opcode
>> 11) & 0x1f;
24297 sa
= (ctx
->opcode
>> 6) & 0x1f;
24299 op1
= MASK_SPECIAL(ctx
->opcode
);
24302 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24308 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24318 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24321 MIPS_INVAL("special_r6 muldiv");
24322 generate_exception_end(ctx
, EXCP_RI
);
24328 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24332 if (rt
== 0 && sa
== 1) {
24334 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24335 * We need additionally to check other fields.
24337 gen_cl(ctx
, op1
, rd
, rs
);
24339 generate_exception_end(ctx
, EXCP_RI
);
24343 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24344 gen_helper_do_semihosting(cpu_env
);
24346 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24347 generate_exception_end(ctx
, EXCP_RI
);
24349 generate_exception_end(ctx
, EXCP_DBp
);
24353 #if defined(TARGET_MIPS64)
24355 check_mips_64(ctx
);
24356 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24360 if (rt
== 0 && sa
== 1) {
24362 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24363 * We need additionally to check other fields.
24365 check_mips_64(ctx
);
24366 gen_cl(ctx
, op1
, rd
, rs
);
24368 generate_exception_end(ctx
, EXCP_RI
);
24376 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24386 check_mips_64(ctx
);
24387 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24390 MIPS_INVAL("special_r6 muldiv");
24391 generate_exception_end(ctx
, EXCP_RI
);
24396 default: /* Invalid */
24397 MIPS_INVAL("special_r6");
24398 generate_exception_end(ctx
, EXCP_RI
);
24403 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24405 int rs
= extract32(ctx
->opcode
, 21, 5);
24406 int rt
= extract32(ctx
->opcode
, 16, 5);
24407 int rd
= extract32(ctx
->opcode
, 11, 5);
24408 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24411 case OPC_MOVN
: /* Conditional move */
24413 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24415 case OPC_MFHI
: /* Move from HI/LO */
24417 gen_HILO(ctx
, op1
, 0, rd
);
24420 case OPC_MTLO
: /* Move to HI/LO */
24421 gen_HILO(ctx
, op1
, 0, rs
);
24425 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24429 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24431 #if defined(TARGET_MIPS64)
24436 check_insn_opc_user_only(ctx
, INSN_R5900
);
24437 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24441 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24443 default: /* Invalid */
24444 MIPS_INVAL("special_tx79");
24445 generate_exception_end(ctx
, EXCP_RI
);
24450 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24452 int rs
, rt
, rd
, sa
;
24455 rs
= (ctx
->opcode
>> 21) & 0x1f;
24456 rt
= (ctx
->opcode
>> 16) & 0x1f;
24457 rd
= (ctx
->opcode
>> 11) & 0x1f;
24458 sa
= (ctx
->opcode
>> 6) & 0x1f;
24460 op1
= MASK_SPECIAL(ctx
->opcode
);
24462 case OPC_MOVN
: /* Conditional move */
24464 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
24465 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24466 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24468 case OPC_MFHI
: /* Move from HI/LO */
24470 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24473 case OPC_MTLO
: /* Move to HI/LO */
24474 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24477 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
24478 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24479 check_cp1_enabled(ctx
);
24480 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24481 (ctx
->opcode
>> 16) & 1);
24483 generate_exception_err(ctx
, EXCP_CpU
, 1);
24489 check_insn(ctx
, INSN_VR54XX
);
24490 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24491 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24493 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24498 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24500 #if defined(TARGET_MIPS64)
24505 check_insn(ctx
, ISA_MIPS3
);
24506 check_mips_64(ctx
);
24507 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24511 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24514 #ifdef MIPS_STRICT_STANDARD
24515 MIPS_INVAL("SPIM");
24516 generate_exception_end(ctx
, EXCP_RI
);
24518 /* Implemented as RI exception for now. */
24519 MIPS_INVAL("spim (unofficial)");
24520 generate_exception_end(ctx
, EXCP_RI
);
24523 default: /* Invalid */
24524 MIPS_INVAL("special_legacy");
24525 generate_exception_end(ctx
, EXCP_RI
);
24530 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24532 int rs
, rt
, rd
, sa
;
24535 rs
= (ctx
->opcode
>> 21) & 0x1f;
24536 rt
= (ctx
->opcode
>> 16) & 0x1f;
24537 rd
= (ctx
->opcode
>> 11) & 0x1f;
24538 sa
= (ctx
->opcode
>> 6) & 0x1f;
24540 op1
= MASK_SPECIAL(ctx
->opcode
);
24542 case OPC_SLL
: /* Shift with immediate */
24543 if (sa
== 5 && rd
== 0 &&
24544 rs
== 0 && rt
== 0) { /* PAUSE */
24545 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
24546 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24547 generate_exception_end(ctx
, EXCP_RI
);
24553 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24556 switch ((ctx
->opcode
>> 21) & 0x1f) {
24558 /* rotr is decoded as srl on non-R2 CPUs */
24559 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24564 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24567 generate_exception_end(ctx
, EXCP_RI
);
24575 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24577 case OPC_SLLV
: /* Shifts */
24579 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24582 switch ((ctx
->opcode
>> 6) & 0x1f) {
24584 /* rotrv is decoded as srlv on non-R2 CPUs */
24585 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24590 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24593 generate_exception_end(ctx
, EXCP_RI
);
24597 case OPC_SLT
: /* Set on less than */
24599 gen_slt(ctx
, op1
, rd
, rs
, rt
);
24601 case OPC_AND
: /* Logic*/
24605 gen_logic(ctx
, op1
, rd
, rs
, rt
);
24608 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24610 case OPC_TGE
: /* Traps */
24616 check_insn(ctx
, ISA_MIPS2
);
24617 gen_trap(ctx
, op1
, rs
, rt
, -1);
24619 case OPC_LSA
: /* OPC_PMON */
24620 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
24621 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
24622 decode_opc_special_r6(env
, ctx
);
24624 /* Pmon entry point, also R4010 selsl */
24625 #ifdef MIPS_STRICT_STANDARD
24626 MIPS_INVAL("PMON / selsl");
24627 generate_exception_end(ctx
, EXCP_RI
);
24629 gen_helper_0e0i(pmon
, sa
);
24634 generate_exception_end(ctx
, EXCP_SYSCALL
);
24637 generate_exception_end(ctx
, EXCP_BREAK
);
24640 check_insn(ctx
, ISA_MIPS2
);
24641 gen_sync(extract32(ctx
->opcode
, 6, 5));
24644 #if defined(TARGET_MIPS64)
24645 /* MIPS64 specific opcodes */
24650 check_insn(ctx
, ISA_MIPS3
);
24651 check_mips_64(ctx
);
24652 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24655 switch ((ctx
->opcode
>> 21) & 0x1f) {
24657 /* drotr is decoded as dsrl on non-R2 CPUs */
24658 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24663 check_insn(ctx
, ISA_MIPS3
);
24664 check_mips_64(ctx
);
24665 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24668 generate_exception_end(ctx
, EXCP_RI
);
24673 switch ((ctx
->opcode
>> 21) & 0x1f) {
24675 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24676 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24681 check_insn(ctx
, ISA_MIPS3
);
24682 check_mips_64(ctx
);
24683 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24686 generate_exception_end(ctx
, EXCP_RI
);
24694 check_insn(ctx
, ISA_MIPS3
);
24695 check_mips_64(ctx
);
24696 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24700 check_insn(ctx
, ISA_MIPS3
);
24701 check_mips_64(ctx
);
24702 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24705 switch ((ctx
->opcode
>> 6) & 0x1f) {
24707 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24708 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24713 check_insn(ctx
, ISA_MIPS3
);
24714 check_mips_64(ctx
);
24715 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24718 generate_exception_end(ctx
, EXCP_RI
);
24723 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
24724 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
24725 decode_opc_special_r6(env
, ctx
);
24730 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
24731 decode_opc_special_r6(env
, ctx
);
24732 } else if (ctx
->insn_flags
& INSN_R5900
) {
24733 decode_opc_special_tx79(env
, ctx
);
24735 decode_opc_special_legacy(env
, ctx
);
24741 #if defined(TARGET_MIPS64)
24745 * MMI (MultiMedia Interface) ASE instructions
24746 * ===========================================
24750 * MMI instructions category: data communication
24751 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24753 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24754 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24755 * PCPYUD PEXEH PEXTLW PPACW
24764 * Parallel Copy Halfword
24766 * 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
24767 * +-----------+---------+---------+---------+---------+-----------+
24768 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
24769 * +-----------+---------+---------+---------+---------+-----------+
24771 static void gen_mmi_pcpyh(DisasContext
*ctx
)
24773 uint32_t pd
, rt
, rd
;
24776 opcode
= ctx
->opcode
;
24778 pd
= extract32(opcode
, 21, 5);
24779 rt
= extract32(opcode
, 16, 5);
24780 rd
= extract32(opcode
, 11, 5);
24782 if (unlikely(pd
!= 0)) {
24783 generate_exception_end(ctx
, EXCP_RI
);
24784 } else if (rd
== 0) {
24786 } else if (rt
== 0) {
24787 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24788 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24790 TCGv_i64 t0
= tcg_temp_new();
24791 TCGv_i64 t1
= tcg_temp_new();
24792 uint64_t mask
= (1ULL << 16) - 1;
24794 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
24795 tcg_gen_movi_i64(t1
, 0);
24796 tcg_gen_or_i64(t1
, t0
, t1
);
24797 tcg_gen_shli_i64(t0
, t0
, 16);
24798 tcg_gen_or_i64(t1
, t0
, t1
);
24799 tcg_gen_shli_i64(t0
, t0
, 16);
24800 tcg_gen_or_i64(t1
, t0
, t1
);
24801 tcg_gen_shli_i64(t0
, t0
, 16);
24802 tcg_gen_or_i64(t1
, t0
, t1
);
24804 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
24806 tcg_gen_andi_i64(t0
, cpu_mmr
[rt
], mask
);
24807 tcg_gen_movi_i64(t1
, 0);
24808 tcg_gen_or_i64(t1
, t0
, t1
);
24809 tcg_gen_shli_i64(t0
, t0
, 16);
24810 tcg_gen_or_i64(t1
, t0
, t1
);
24811 tcg_gen_shli_i64(t0
, t0
, 16);
24812 tcg_gen_or_i64(t1
, t0
, t1
);
24813 tcg_gen_shli_i64(t0
, t0
, 16);
24814 tcg_gen_or_i64(t1
, t0
, t1
);
24816 tcg_gen_mov_i64(cpu_mmr
[rd
], t1
);
24824 * PCPYLD rd, rs, rt
24826 * Parallel Copy Lower Doubleword
24828 * 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
24829 * +-----------+---------+---------+---------+---------+-----------+
24830 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
24831 * +-----------+---------+---------+---------+---------+-----------+
24833 static void gen_mmi_pcpyld(DisasContext
*ctx
)
24835 uint32_t rs
, rt
, rd
;
24838 opcode
= ctx
->opcode
;
24840 rs
= extract32(opcode
, 21, 5);
24841 rt
= extract32(opcode
, 16, 5);
24842 rd
= extract32(opcode
, 11, 5);
24848 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24850 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_gpr
[rs
]);
24853 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24856 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
24863 * PCPYUD rd, rs, rt
24865 * Parallel Copy Upper Doubleword
24867 * 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
24868 * +-----------+---------+---------+---------+---------+-----------+
24869 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
24870 * +-----------+---------+---------+---------+---------+-----------+
24872 static void gen_mmi_pcpyud(DisasContext
*ctx
)
24874 uint32_t rs
, rt
, rd
;
24877 opcode
= ctx
->opcode
;
24879 rs
= extract32(opcode
, 21, 5);
24880 rt
= extract32(opcode
, 16, 5);
24881 rd
= extract32(opcode
, 11, 5);
24887 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24889 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_mmr
[rs
]);
24892 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24895 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_mmr
[rt
]);
24904 #if !defined(TARGET_MIPS64)
24906 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24907 #define MXU_APTN1_A 0
24908 #define MXU_APTN1_S 1
24910 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24911 #define MXU_APTN2_AA 0
24912 #define MXU_APTN2_AS 1
24913 #define MXU_APTN2_SA 2
24914 #define MXU_APTN2_SS 3
24916 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24917 #define MXU_EPTN2_AA 0
24918 #define MXU_EPTN2_AS 1
24919 #define MXU_EPTN2_SA 2
24920 #define MXU_EPTN2_SS 3
24922 /* MXU operand getting pattern 'optn2' */
24923 #define MXU_OPTN2_PTN0 0
24924 #define MXU_OPTN2_PTN1 1
24925 #define MXU_OPTN2_PTN2 2
24926 #define MXU_OPTN2_PTN3 3
24927 /* alternative naming scheme for 'optn2' */
24928 #define MXU_OPTN2_WW 0
24929 #define MXU_OPTN2_LW 1
24930 #define MXU_OPTN2_HW 2
24931 #define MXU_OPTN2_XW 3
24933 /* MXU operand getting pattern 'optn3' */
24934 #define MXU_OPTN3_PTN0 0
24935 #define MXU_OPTN3_PTN1 1
24936 #define MXU_OPTN3_PTN2 2
24937 #define MXU_OPTN3_PTN3 3
24938 #define MXU_OPTN3_PTN4 4
24939 #define MXU_OPTN3_PTN5 5
24940 #define MXU_OPTN3_PTN6 6
24941 #define MXU_OPTN3_PTN7 7
24945 * S32I2M XRa, rb - Register move from GRF to XRF
24947 static void gen_mxu_s32i2m(DisasContext
*ctx
)
24952 t0
= tcg_temp_new();
24954 XRa
= extract32(ctx
->opcode
, 6, 5);
24955 Rb
= extract32(ctx
->opcode
, 16, 5);
24957 gen_load_gpr(t0
, Rb
);
24959 gen_store_mxu_gpr(t0
, XRa
);
24960 } else if (XRa
== 16) {
24961 gen_store_mxu_cr(t0
);
24968 * S32M2I XRa, rb - Register move from XRF to GRF
24970 static void gen_mxu_s32m2i(DisasContext
*ctx
)
24975 t0
= tcg_temp_new();
24977 XRa
= extract32(ctx
->opcode
, 6, 5);
24978 Rb
= extract32(ctx
->opcode
, 16, 5);
24981 gen_load_mxu_gpr(t0
, XRa
);
24982 } else if (XRa
== 16) {
24983 gen_load_mxu_cr(t0
);
24986 gen_store_gpr(t0
, Rb
);
24992 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24994 static void gen_mxu_s8ldd(DisasContext
*ctx
)
24997 uint32_t XRa
, Rb
, s8
, optn3
;
24999 t0
= tcg_temp_new();
25000 t1
= tcg_temp_new();
25002 XRa
= extract32(ctx
->opcode
, 6, 4);
25003 s8
= extract32(ctx
->opcode
, 10, 8);
25004 optn3
= extract32(ctx
->opcode
, 18, 3);
25005 Rb
= extract32(ctx
->opcode
, 21, 5);
25007 gen_load_gpr(t0
, Rb
);
25008 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
25011 /* XRa[7:0] = tmp8 */
25012 case MXU_OPTN3_PTN0
:
25013 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25014 gen_load_mxu_gpr(t0
, XRa
);
25015 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
25017 /* XRa[15:8] = tmp8 */
25018 case MXU_OPTN3_PTN1
:
25019 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25020 gen_load_mxu_gpr(t0
, XRa
);
25021 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
25023 /* XRa[23:16] = tmp8 */
25024 case MXU_OPTN3_PTN2
:
25025 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25026 gen_load_mxu_gpr(t0
, XRa
);
25027 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
25029 /* XRa[31:24] = tmp8 */
25030 case MXU_OPTN3_PTN3
:
25031 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25032 gen_load_mxu_gpr(t0
, XRa
);
25033 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
25035 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25036 case MXU_OPTN3_PTN4
:
25037 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25038 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25040 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25041 case MXU_OPTN3_PTN5
:
25042 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25043 tcg_gen_shli_tl(t1
, t1
, 8);
25044 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25046 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25047 case MXU_OPTN3_PTN6
:
25048 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
25049 tcg_gen_mov_tl(t0
, t1
);
25050 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
25051 tcg_gen_shli_tl(t1
, t1
, 16);
25052 tcg_gen_or_tl(t0
, t0
, t1
);
25054 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25055 case MXU_OPTN3_PTN7
:
25056 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25057 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
25058 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25062 gen_store_mxu_gpr(t0
, XRa
);
25069 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25071 static void gen_mxu_d16mul(DisasContext
*ctx
)
25073 TCGv t0
, t1
, t2
, t3
;
25074 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
25076 t0
= tcg_temp_new();
25077 t1
= tcg_temp_new();
25078 t2
= tcg_temp_new();
25079 t3
= tcg_temp_new();
25081 XRa
= extract32(ctx
->opcode
, 6, 4);
25082 XRb
= extract32(ctx
->opcode
, 10, 4);
25083 XRc
= extract32(ctx
->opcode
, 14, 4);
25084 XRd
= extract32(ctx
->opcode
, 18, 4);
25085 optn2
= extract32(ctx
->opcode
, 22, 2);
25087 gen_load_mxu_gpr(t1
, XRb
);
25088 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25089 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25090 gen_load_mxu_gpr(t3
, XRc
);
25091 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25092 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25095 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25096 tcg_gen_mul_tl(t3
, t1
, t3
);
25097 tcg_gen_mul_tl(t2
, t0
, t2
);
25099 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25100 tcg_gen_mul_tl(t3
, t0
, t3
);
25101 tcg_gen_mul_tl(t2
, t0
, t2
);
25103 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25104 tcg_gen_mul_tl(t3
, t1
, t3
);
25105 tcg_gen_mul_tl(t2
, t1
, t2
);
25107 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25108 tcg_gen_mul_tl(t3
, t0
, t3
);
25109 tcg_gen_mul_tl(t2
, t1
, t2
);
25112 gen_store_mxu_gpr(t3
, XRa
);
25113 gen_store_mxu_gpr(t2
, XRd
);
25122 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25125 static void gen_mxu_d16mac(DisasContext
*ctx
)
25127 TCGv t0
, t1
, t2
, t3
;
25128 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
25130 t0
= tcg_temp_new();
25131 t1
= tcg_temp_new();
25132 t2
= tcg_temp_new();
25133 t3
= tcg_temp_new();
25135 XRa
= extract32(ctx
->opcode
, 6, 4);
25136 XRb
= extract32(ctx
->opcode
, 10, 4);
25137 XRc
= extract32(ctx
->opcode
, 14, 4);
25138 XRd
= extract32(ctx
->opcode
, 18, 4);
25139 optn2
= extract32(ctx
->opcode
, 22, 2);
25140 aptn2
= extract32(ctx
->opcode
, 24, 2);
25142 gen_load_mxu_gpr(t1
, XRb
);
25143 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25144 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25146 gen_load_mxu_gpr(t3
, XRc
);
25147 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25148 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25151 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25152 tcg_gen_mul_tl(t3
, t1
, t3
);
25153 tcg_gen_mul_tl(t2
, t0
, t2
);
25155 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25156 tcg_gen_mul_tl(t3
, t0
, t3
);
25157 tcg_gen_mul_tl(t2
, t0
, t2
);
25159 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25160 tcg_gen_mul_tl(t3
, t1
, t3
);
25161 tcg_gen_mul_tl(t2
, t1
, t2
);
25163 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25164 tcg_gen_mul_tl(t3
, t0
, t3
);
25165 tcg_gen_mul_tl(t2
, t1
, t2
);
25168 gen_load_mxu_gpr(t0
, XRa
);
25169 gen_load_mxu_gpr(t1
, XRd
);
25173 tcg_gen_add_tl(t3
, t0
, t3
);
25174 tcg_gen_add_tl(t2
, t1
, t2
);
25177 tcg_gen_add_tl(t3
, t0
, t3
);
25178 tcg_gen_sub_tl(t2
, t1
, t2
);
25181 tcg_gen_sub_tl(t3
, t0
, t3
);
25182 tcg_gen_add_tl(t2
, t1
, t2
);
25185 tcg_gen_sub_tl(t3
, t0
, t3
);
25186 tcg_gen_sub_tl(t2
, t1
, t2
);
25189 gen_store_mxu_gpr(t3
, XRa
);
25190 gen_store_mxu_gpr(t2
, XRd
);
25199 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25200 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25202 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25204 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25205 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25207 t0
= tcg_temp_new();
25208 t1
= tcg_temp_new();
25209 t2
= tcg_temp_new();
25210 t3
= tcg_temp_new();
25211 t4
= tcg_temp_new();
25212 t5
= tcg_temp_new();
25213 t6
= tcg_temp_new();
25214 t7
= tcg_temp_new();
25216 XRa
= extract32(ctx
->opcode
, 6, 4);
25217 XRb
= extract32(ctx
->opcode
, 10, 4);
25218 XRc
= extract32(ctx
->opcode
, 14, 4);
25219 XRd
= extract32(ctx
->opcode
, 18, 4);
25220 sel
= extract32(ctx
->opcode
, 22, 2);
25222 gen_load_mxu_gpr(t3
, XRb
);
25223 gen_load_mxu_gpr(t7
, XRc
);
25227 tcg_gen_ext8s_tl(t0
, t3
);
25228 tcg_gen_shri_tl(t3
, t3
, 8);
25229 tcg_gen_ext8s_tl(t1
, t3
);
25230 tcg_gen_shri_tl(t3
, t3
, 8);
25231 tcg_gen_ext8s_tl(t2
, t3
);
25232 tcg_gen_shri_tl(t3
, t3
, 8);
25233 tcg_gen_ext8s_tl(t3
, t3
);
25236 tcg_gen_ext8u_tl(t0
, t3
);
25237 tcg_gen_shri_tl(t3
, t3
, 8);
25238 tcg_gen_ext8u_tl(t1
, t3
);
25239 tcg_gen_shri_tl(t3
, t3
, 8);
25240 tcg_gen_ext8u_tl(t2
, t3
);
25241 tcg_gen_shri_tl(t3
, t3
, 8);
25242 tcg_gen_ext8u_tl(t3
, t3
);
25245 tcg_gen_ext8u_tl(t4
, t7
);
25246 tcg_gen_shri_tl(t7
, t7
, 8);
25247 tcg_gen_ext8u_tl(t5
, t7
);
25248 tcg_gen_shri_tl(t7
, t7
, 8);
25249 tcg_gen_ext8u_tl(t6
, t7
);
25250 tcg_gen_shri_tl(t7
, t7
, 8);
25251 tcg_gen_ext8u_tl(t7
, t7
);
25253 tcg_gen_mul_tl(t0
, t0
, t4
);
25254 tcg_gen_mul_tl(t1
, t1
, t5
);
25255 tcg_gen_mul_tl(t2
, t2
, t6
);
25256 tcg_gen_mul_tl(t3
, t3
, t7
);
25258 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25259 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25260 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25261 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25263 tcg_gen_shli_tl(t1
, t1
, 16);
25264 tcg_gen_shli_tl(t3
, t3
, 16);
25266 tcg_gen_or_tl(t0
, t0
, t1
);
25267 tcg_gen_or_tl(t1
, t2
, t3
);
25269 gen_store_mxu_gpr(t0
, XRd
);
25270 gen_store_mxu_gpr(t1
, XRa
);
25283 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25284 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25286 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25289 uint32_t XRa
, Rb
, s12
, sel
;
25291 t0
= tcg_temp_new();
25292 t1
= tcg_temp_new();
25294 XRa
= extract32(ctx
->opcode
, 6, 4);
25295 s12
= extract32(ctx
->opcode
, 10, 10);
25296 sel
= extract32(ctx
->opcode
, 20, 1);
25297 Rb
= extract32(ctx
->opcode
, 21, 5);
25299 gen_load_gpr(t0
, Rb
);
25301 tcg_gen_movi_tl(t1
, s12
);
25302 tcg_gen_shli_tl(t1
, t1
, 2);
25304 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25306 tcg_gen_add_tl(t1
, t0
, t1
);
25307 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25311 tcg_gen_bswap32_tl(t1
, t1
);
25313 gen_store_mxu_gpr(t1
, XRa
);
25321 * MXU instruction category: logic
25322 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25324 * S32NOR S32AND S32OR S32XOR
25328 * S32NOR XRa, XRb, XRc
25329 * Update XRa with the result of logical bitwise 'nor' operation
25330 * applied to the content of XRb and XRc.
25332 * 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
25333 * +-----------+---------+-----+-------+-------+-------+-----------+
25334 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25335 * +-----------+---------+-----+-------+-------+-------+-----------+
25337 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25339 uint32_t pad
, XRc
, XRb
, XRa
;
25341 pad
= extract32(ctx
->opcode
, 21, 5);
25342 XRc
= extract32(ctx
->opcode
, 14, 4);
25343 XRb
= extract32(ctx
->opcode
, 10, 4);
25344 XRa
= extract32(ctx
->opcode
, 6, 4);
25346 if (unlikely(pad
!= 0)) {
25347 /* opcode padding incorrect -> do nothing */
25348 } else if (unlikely(XRa
== 0)) {
25349 /* destination is zero register -> do nothing */
25350 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25351 /* both operands zero registers -> just set destination to all 1s */
25352 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25353 } else if (unlikely(XRb
== 0)) {
25354 /* XRb zero register -> just set destination to the negation of XRc */
25355 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25356 } else if (unlikely(XRc
== 0)) {
25357 /* XRa zero register -> just set destination to the negation of XRb */
25358 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25359 } else if (unlikely(XRb
== XRc
)) {
25360 /* both operands same -> just set destination to the negation of XRb */
25361 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25363 /* the most general case */
25364 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25369 * S32AND XRa, XRb, XRc
25370 * Update XRa with the result of logical bitwise 'and' operation
25371 * applied to the content of XRb and XRc.
25373 * 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
25374 * +-----------+---------+-----+-------+-------+-------+-----------+
25375 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25376 * +-----------+---------+-----+-------+-------+-------+-----------+
25378 static void gen_mxu_S32AND(DisasContext
*ctx
)
25380 uint32_t pad
, XRc
, XRb
, XRa
;
25382 pad
= extract32(ctx
->opcode
, 21, 5);
25383 XRc
= extract32(ctx
->opcode
, 14, 4);
25384 XRb
= extract32(ctx
->opcode
, 10, 4);
25385 XRa
= extract32(ctx
->opcode
, 6, 4);
25387 if (unlikely(pad
!= 0)) {
25388 /* opcode padding incorrect -> do nothing */
25389 } else if (unlikely(XRa
== 0)) {
25390 /* destination is zero register -> do nothing */
25391 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25392 /* one of operands zero register -> just set destination to all 0s */
25393 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25394 } else if (unlikely(XRb
== XRc
)) {
25395 /* both operands same -> just set destination to one of them */
25396 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25398 /* the most general case */
25399 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25404 * S32OR XRa, XRb, XRc
25405 * Update XRa with the result of logical bitwise 'or' operation
25406 * applied to the content of XRb and XRc.
25408 * 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
25409 * +-----------+---------+-----+-------+-------+-------+-----------+
25410 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25411 * +-----------+---------+-----+-------+-------+-------+-----------+
25413 static void gen_mxu_S32OR(DisasContext
*ctx
)
25415 uint32_t pad
, XRc
, XRb
, XRa
;
25417 pad
= extract32(ctx
->opcode
, 21, 5);
25418 XRc
= extract32(ctx
->opcode
, 14, 4);
25419 XRb
= extract32(ctx
->opcode
, 10, 4);
25420 XRa
= extract32(ctx
->opcode
, 6, 4);
25422 if (unlikely(pad
!= 0)) {
25423 /* opcode padding incorrect -> do nothing */
25424 } else if (unlikely(XRa
== 0)) {
25425 /* destination is zero register -> do nothing */
25426 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25427 /* both operands zero registers -> just set destination to all 0s */
25428 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25429 } else if (unlikely(XRb
== 0)) {
25430 /* XRb zero register -> just set destination to the content of XRc */
25431 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25432 } else if (unlikely(XRc
== 0)) {
25433 /* XRc zero register -> just set destination to the content of XRb */
25434 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25435 } else if (unlikely(XRb
== XRc
)) {
25436 /* both operands same -> just set destination to one of them */
25437 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25439 /* the most general case */
25440 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25445 * S32XOR XRa, XRb, XRc
25446 * Update XRa with the result of logical bitwise 'xor' operation
25447 * applied to the content of XRb and XRc.
25449 * 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
25450 * +-----------+---------+-----+-------+-------+-------+-----------+
25451 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25452 * +-----------+---------+-----+-------+-------+-------+-----------+
25454 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25456 uint32_t pad
, XRc
, XRb
, XRa
;
25458 pad
= extract32(ctx
->opcode
, 21, 5);
25459 XRc
= extract32(ctx
->opcode
, 14, 4);
25460 XRb
= extract32(ctx
->opcode
, 10, 4);
25461 XRa
= extract32(ctx
->opcode
, 6, 4);
25463 if (unlikely(pad
!= 0)) {
25464 /* opcode padding incorrect -> do nothing */
25465 } else if (unlikely(XRa
== 0)) {
25466 /* destination is zero register -> do nothing */
25467 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25468 /* both operands zero registers -> just set destination to all 0s */
25469 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25470 } else if (unlikely(XRb
== 0)) {
25471 /* XRb zero register -> just set destination to the content of XRc */
25472 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25473 } else if (unlikely(XRc
== 0)) {
25474 /* XRc zero register -> just set destination to the content of XRb */
25475 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25476 } else if (unlikely(XRb
== XRc
)) {
25477 /* both operands same -> just set destination to all 0s */
25478 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25480 /* the most general case */
25481 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25487 * MXU instruction category max/min
25488 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25490 * S32MAX D16MAX Q8MAX
25491 * S32MIN D16MIN Q8MIN
25495 * S32MAX XRa, XRb, XRc
25496 * Update XRa with the maximum of signed 32-bit integers contained
25499 * S32MIN XRa, XRb, XRc
25500 * Update XRa with the minimum of signed 32-bit integers contained
25503 * 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
25504 * +-----------+---------+-----+-------+-------+-------+-----------+
25505 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25506 * +-----------+---------+-----+-------+-------+-------+-----------+
25508 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25510 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25512 pad
= extract32(ctx
->opcode
, 21, 5);
25513 opc
= extract32(ctx
->opcode
, 18, 3);
25514 XRc
= extract32(ctx
->opcode
, 14, 4);
25515 XRb
= extract32(ctx
->opcode
, 10, 4);
25516 XRa
= extract32(ctx
->opcode
, 6, 4);
25518 if (unlikely(pad
!= 0)) {
25519 /* opcode padding incorrect -> do nothing */
25520 } else if (unlikely(XRa
== 0)) {
25521 /* destination is zero register -> do nothing */
25522 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25523 /* both operands zero registers -> just set destination to zero */
25524 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25525 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25526 /* exactly one operand is zero register - find which one is not...*/
25527 uint32_t XRx
= XRb
? XRb
: XRc
;
25528 /* ...and do max/min operation with one operand 0 */
25529 if (opc
== OPC_MXU_S32MAX
) {
25530 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25532 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25534 } else if (unlikely(XRb
== XRc
)) {
25535 /* both operands same -> just set destination to one of them */
25536 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25538 /* the most general case */
25539 if (opc
== OPC_MXU_S32MAX
) {
25540 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25543 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25551 * Update XRa with the 16-bit-wise maximums of signed integers
25552 * contained in XRb and XRc.
25555 * Update XRa with the 16-bit-wise minimums of signed integers
25556 * contained in XRb and XRc.
25558 * 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
25559 * +-----------+---------+-----+-------+-------+-------+-----------+
25560 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25561 * +-----------+---------+-----+-------+-------+-------+-----------+
25563 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25565 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25567 pad
= extract32(ctx
->opcode
, 21, 5);
25568 opc
= extract32(ctx
->opcode
, 18, 3);
25569 XRc
= extract32(ctx
->opcode
, 14, 4);
25570 XRb
= extract32(ctx
->opcode
, 10, 4);
25571 XRa
= extract32(ctx
->opcode
, 6, 4);
25573 if (unlikely(pad
!= 0)) {
25574 /* opcode padding incorrect -> do nothing */
25575 } else if (unlikely(XRc
== 0)) {
25576 /* destination is zero register -> do nothing */
25577 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
25578 /* both operands zero registers -> just set destination to zero */
25579 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
25580 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
25581 /* exactly one operand is zero register - find which one is not...*/
25582 uint32_t XRx
= XRb
? XRb
: XRc
;
25583 /* ...and do half-word-wise max/min with one operand 0 */
25584 TCGv_i32 t0
= tcg_temp_new();
25585 TCGv_i32 t1
= tcg_const_i32(0);
25587 /* the left half-word first */
25588 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
25589 if (opc
== OPC_MXU_D16MAX
) {
25590 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25592 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25595 /* the right half-word */
25596 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
25597 /* move half-words to the leftmost position */
25598 tcg_gen_shli_i32(t0
, t0
, 16);
25599 /* t0 will be max/min of t0 and t1 */
25600 if (opc
== OPC_MXU_D16MAX
) {
25601 tcg_gen_smax_i32(t0
, t0
, t1
);
25603 tcg_gen_smin_i32(t0
, t0
, t1
);
25605 /* return resulting half-words to its original position */
25606 tcg_gen_shri_i32(t0
, t0
, 16);
25607 /* finaly update the destination */
25608 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25612 } else if (unlikely(XRb
== XRc
)) {
25613 /* both operands same -> just set destination to one of them */
25614 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25616 /* the most general case */
25617 TCGv_i32 t0
= tcg_temp_new();
25618 TCGv_i32 t1
= tcg_temp_new();
25620 /* the left half-word first */
25621 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
25622 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25623 if (opc
== OPC_MXU_D16MAX
) {
25624 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25626 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25629 /* the right half-word */
25630 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25631 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
25632 /* move half-words to the leftmost position */
25633 tcg_gen_shli_i32(t0
, t0
, 16);
25634 tcg_gen_shli_i32(t1
, t1
, 16);
25635 /* t0 will be max/min of t0 and t1 */
25636 if (opc
== OPC_MXU_D16MAX
) {
25637 tcg_gen_smax_i32(t0
, t0
, t1
);
25639 tcg_gen_smin_i32(t0
, t0
, t1
);
25641 /* return resulting half-words to its original position */
25642 tcg_gen_shri_i32(t0
, t0
, 16);
25643 /* finaly update the destination */
25644 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25653 * Update XRa with the 8-bit-wise maximums of signed integers
25654 * contained in XRb and XRc.
25657 * Update XRa with the 8-bit-wise minimums of signed integers
25658 * contained in XRb and XRc.
25660 * 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
25661 * +-----------+---------+-----+-------+-------+-------+-----------+
25662 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25663 * +-----------+---------+-----+-------+-------+-------+-----------+
25665 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
25667 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25669 pad
= extract32(ctx
->opcode
, 21, 5);
25670 opc
= extract32(ctx
->opcode
, 18, 3);
25671 XRc
= extract32(ctx
->opcode
, 14, 4);
25672 XRb
= extract32(ctx
->opcode
, 10, 4);
25673 XRa
= extract32(ctx
->opcode
, 6, 4);
25675 if (unlikely(pad
!= 0)) {
25676 /* opcode padding incorrect -> do nothing */
25677 } else if (unlikely(XRa
== 0)) {
25678 /* destination is zero register -> do nothing */
25679 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25680 /* both operands zero registers -> just set destination to zero */
25681 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25682 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25683 /* exactly one operand is zero register - make it be the first...*/
25684 uint32_t XRx
= XRb
? XRb
: XRc
;
25685 /* ...and do byte-wise max/min with one operand 0 */
25686 TCGv_i32 t0
= tcg_temp_new();
25687 TCGv_i32 t1
= tcg_const_i32(0);
25690 /* the leftmost byte (byte 3) first */
25691 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
25692 if (opc
== OPC_MXU_Q8MAX
) {
25693 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25695 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25698 /* bytes 2, 1, 0 */
25699 for (i
= 2; i
>= 0; i
--) {
25700 /* extract the byte */
25701 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
25702 /* move the byte to the leftmost position */
25703 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25704 /* t0 will be max/min of t0 and t1 */
25705 if (opc
== OPC_MXU_Q8MAX
) {
25706 tcg_gen_smax_i32(t0
, t0
, t1
);
25708 tcg_gen_smin_i32(t0
, t0
, t1
);
25710 /* return resulting byte to its original position */
25711 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25712 /* finaly update the destination */
25713 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25718 } else if (unlikely(XRb
== XRc
)) {
25719 /* both operands same -> just set destination to one of them */
25720 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25722 /* the most general case */
25723 TCGv_i32 t0
= tcg_temp_new();
25724 TCGv_i32 t1
= tcg_temp_new();
25727 /* the leftmost bytes (bytes 3) first */
25728 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
25729 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25730 if (opc
== OPC_MXU_Q8MAX
) {
25731 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25733 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25736 /* bytes 2, 1, 0 */
25737 for (i
= 2; i
>= 0; i
--) {
25738 /* extract corresponding bytes */
25739 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
25740 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
25741 /* move the bytes to the leftmost position */
25742 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25743 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
25744 /* t0 will be max/min of t0 and t1 */
25745 if (opc
== OPC_MXU_Q8MAX
) {
25746 tcg_gen_smax_i32(t0
, t0
, t1
);
25748 tcg_gen_smin_i32(t0
, t0
, t1
);
25750 /* return resulting byte to its original position */
25751 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25752 /* finaly update the destination */
25753 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25763 * MXU instruction category: align
25764 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25770 * S32ALNI XRc, XRb, XRa, optn3
25771 * Arrange bytes from XRb and XRc according to one of five sets of
25772 * rules determined by optn3, and place the result in XRa.
25774 * 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
25775 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25776 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25777 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25780 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
25782 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
25784 optn3
= extract32(ctx
->opcode
, 23, 3);
25785 pad
= extract32(ctx
->opcode
, 21, 2);
25786 XRc
= extract32(ctx
->opcode
, 14, 4);
25787 XRb
= extract32(ctx
->opcode
, 10, 4);
25788 XRa
= extract32(ctx
->opcode
, 6, 4);
25790 if (unlikely(pad
!= 0)) {
25791 /* opcode padding incorrect -> do nothing */
25792 } else if (unlikely(XRa
== 0)) {
25793 /* destination is zero register -> do nothing */
25794 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25795 /* both operands zero registers -> just set destination to all 0s */
25796 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25797 } else if (unlikely(XRb
== 0)) {
25798 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25800 case MXU_OPTN3_PTN0
:
25801 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25803 case MXU_OPTN3_PTN1
:
25804 case MXU_OPTN3_PTN2
:
25805 case MXU_OPTN3_PTN3
:
25806 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
25809 case MXU_OPTN3_PTN4
:
25810 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25813 } else if (unlikely(XRc
== 0)) {
25814 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25816 case MXU_OPTN3_PTN0
:
25817 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25819 case MXU_OPTN3_PTN1
:
25820 case MXU_OPTN3_PTN2
:
25821 case MXU_OPTN3_PTN3
:
25822 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25824 case MXU_OPTN3_PTN4
:
25825 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25828 } else if (unlikely(XRb
== XRc
)) {
25829 /* both operands same -> just rotation or moving from any of them */
25831 case MXU_OPTN3_PTN0
:
25832 case MXU_OPTN3_PTN4
:
25833 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25835 case MXU_OPTN3_PTN1
:
25836 case MXU_OPTN3_PTN2
:
25837 case MXU_OPTN3_PTN3
:
25838 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25842 /* the most general case */
25844 case MXU_OPTN3_PTN0
:
25848 /* +---------------+ */
25849 /* | A B C D | E F G H */
25850 /* +-------+-------+ */
25855 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25858 case MXU_OPTN3_PTN1
:
25862 /* +-------------------+ */
25863 /* A | B C D E | F G H */
25864 /* +---------+---------+ */
25869 TCGv_i32 t0
= tcg_temp_new();
25870 TCGv_i32 t1
= tcg_temp_new();
25872 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
25873 tcg_gen_shli_i32(t0
, t0
, 8);
25875 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25876 tcg_gen_shri_i32(t1
, t1
, 24);
25878 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25884 case MXU_OPTN3_PTN2
:
25888 /* +-------------------+ */
25889 /* A B | C D E F | G H */
25890 /* +---------+---------+ */
25895 TCGv_i32 t0
= tcg_temp_new();
25896 TCGv_i32 t1
= tcg_temp_new();
25898 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25899 tcg_gen_shli_i32(t0
, t0
, 16);
25901 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25902 tcg_gen_shri_i32(t1
, t1
, 16);
25904 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25910 case MXU_OPTN3_PTN3
:
25914 /* +-------------------+ */
25915 /* A B C | D E F G | H */
25916 /* +---------+---------+ */
25921 TCGv_i32 t0
= tcg_temp_new();
25922 TCGv_i32 t1
= tcg_temp_new();
25924 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
25925 tcg_gen_shli_i32(t0
, t0
, 24);
25927 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
25928 tcg_gen_shri_i32(t1
, t1
, 8);
25930 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25936 case MXU_OPTN3_PTN4
:
25940 /* +---------------+ */
25941 /* A B C D | E F G H | */
25942 /* +-------+-------+ */
25947 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25956 * Decoding engine for MXU
25957 * =======================
25962 * Decode MXU pool00
25964 * 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
25965 * +-----------+---------+-----+-------+-------+-------+-----------+
25966 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25967 * +-----------+---------+-----+-------+-------+-------+-----------+
25970 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
25972 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25975 case OPC_MXU_S32MAX
:
25976 case OPC_MXU_S32MIN
:
25977 gen_mxu_S32MAX_S32MIN(ctx
);
25979 case OPC_MXU_D16MAX
:
25980 case OPC_MXU_D16MIN
:
25981 gen_mxu_D16MAX_D16MIN(ctx
);
25983 case OPC_MXU_Q8MAX
:
25984 case OPC_MXU_Q8MIN
:
25985 gen_mxu_Q8MAX_Q8MIN(ctx
);
25987 case OPC_MXU_Q8SLT
:
25988 /* TODO: Implement emulation of Q8SLT instruction. */
25989 MIPS_INVAL("OPC_MXU_Q8SLT");
25990 generate_exception_end(ctx
, EXCP_RI
);
25992 case OPC_MXU_Q8SLTU
:
25993 /* TODO: Implement emulation of Q8SLTU instruction. */
25994 MIPS_INVAL("OPC_MXU_Q8SLTU");
25995 generate_exception_end(ctx
, EXCP_RI
);
25998 MIPS_INVAL("decode_opc_mxu");
25999 generate_exception_end(ctx
, EXCP_RI
);
26006 * Decode MXU pool01
26008 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26009 * 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
26010 * +-----------+---------+-----+-------+-------+-------+-----------+
26011 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26012 * +-----------+---------+-----+-------+-------+-------+-----------+
26015 * 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
26016 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26017 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26018 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26021 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
26023 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26026 case OPC_MXU_S32SLT
:
26027 /* TODO: Implement emulation of S32SLT instruction. */
26028 MIPS_INVAL("OPC_MXU_S32SLT");
26029 generate_exception_end(ctx
, EXCP_RI
);
26031 case OPC_MXU_D16SLT
:
26032 /* TODO: Implement emulation of D16SLT instruction. */
26033 MIPS_INVAL("OPC_MXU_D16SLT");
26034 generate_exception_end(ctx
, EXCP_RI
);
26036 case OPC_MXU_D16AVG
:
26037 /* TODO: Implement emulation of D16AVG instruction. */
26038 MIPS_INVAL("OPC_MXU_D16AVG");
26039 generate_exception_end(ctx
, EXCP_RI
);
26041 case OPC_MXU_D16AVGR
:
26042 /* TODO: Implement emulation of D16AVGR instruction. */
26043 MIPS_INVAL("OPC_MXU_D16AVGR");
26044 generate_exception_end(ctx
, EXCP_RI
);
26046 case OPC_MXU_Q8AVG
:
26047 /* TODO: Implement emulation of Q8AVG instruction. */
26048 MIPS_INVAL("OPC_MXU_Q8AVG");
26049 generate_exception_end(ctx
, EXCP_RI
);
26051 case OPC_MXU_Q8AVGR
:
26052 /* TODO: Implement emulation of Q8AVGR instruction. */
26053 MIPS_INVAL("OPC_MXU_Q8AVGR");
26054 generate_exception_end(ctx
, EXCP_RI
);
26056 case OPC_MXU_Q8ADD
:
26057 /* TODO: Implement emulation of Q8ADD instruction. */
26058 MIPS_INVAL("OPC_MXU_Q8ADD");
26059 generate_exception_end(ctx
, EXCP_RI
);
26062 MIPS_INVAL("decode_opc_mxu");
26063 generate_exception_end(ctx
, EXCP_RI
);
26070 * Decode MXU pool02
26072 * 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
26073 * +-----------+---------+-----+-------+-------+-------+-----------+
26074 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26075 * +-----------+---------+-----+-------+-------+-------+-----------+
26078 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
26080 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26083 case OPC_MXU_S32CPS
:
26084 /* TODO: Implement emulation of S32CPS instruction. */
26085 MIPS_INVAL("OPC_MXU_S32CPS");
26086 generate_exception_end(ctx
, EXCP_RI
);
26088 case OPC_MXU_D16CPS
:
26089 /* TODO: Implement emulation of D16CPS instruction. */
26090 MIPS_INVAL("OPC_MXU_D16CPS");
26091 generate_exception_end(ctx
, EXCP_RI
);
26093 case OPC_MXU_Q8ABD
:
26094 /* TODO: Implement emulation of Q8ABD instruction. */
26095 MIPS_INVAL("OPC_MXU_Q8ABD");
26096 generate_exception_end(ctx
, EXCP_RI
);
26098 case OPC_MXU_Q16SAT
:
26099 /* TODO: Implement emulation of Q16SAT instruction. */
26100 MIPS_INVAL("OPC_MXU_Q16SAT");
26101 generate_exception_end(ctx
, EXCP_RI
);
26104 MIPS_INVAL("decode_opc_mxu");
26105 generate_exception_end(ctx
, EXCP_RI
);
26112 * Decode MXU pool03
26115 * 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
26116 * +-----------+---+---+-------+-------+-------+-------+-----------+
26117 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26118 * +-----------+---+---+-------+-------+-------+-------+-----------+
26121 * 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
26122 * +-----------+---+---+-------+-------+-------+-------+-----------+
26123 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26124 * +-----------+---+---+-------+-------+-------+-------+-----------+
26127 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
26129 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
26132 case OPC_MXU_D16MULF
:
26133 /* TODO: Implement emulation of D16MULF instruction. */
26134 MIPS_INVAL("OPC_MXU_D16MULF");
26135 generate_exception_end(ctx
, EXCP_RI
);
26137 case OPC_MXU_D16MULE
:
26138 /* TODO: Implement emulation of D16MULE instruction. */
26139 MIPS_INVAL("OPC_MXU_D16MULE");
26140 generate_exception_end(ctx
, EXCP_RI
);
26143 MIPS_INVAL("decode_opc_mxu");
26144 generate_exception_end(ctx
, EXCP_RI
);
26151 * Decode MXU pool04
26153 * 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
26154 * +-----------+---------+-+-------------------+-------+-----------+
26155 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26156 * +-----------+---------+-+-------------------+-------+-----------+
26159 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
26161 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26164 case OPC_MXU_S32LDD
:
26165 case OPC_MXU_S32LDDR
:
26166 gen_mxu_s32ldd_s32lddr(ctx
);
26169 MIPS_INVAL("decode_opc_mxu");
26170 generate_exception_end(ctx
, EXCP_RI
);
26177 * Decode MXU pool05
26179 * 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
26180 * +-----------+---------+-+-------------------+-------+-----------+
26181 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26182 * +-----------+---------+-+-------------------+-------+-----------+
26185 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
26187 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26190 case OPC_MXU_S32STD
:
26191 /* TODO: Implement emulation of S32STD instruction. */
26192 MIPS_INVAL("OPC_MXU_S32STD");
26193 generate_exception_end(ctx
, EXCP_RI
);
26195 case OPC_MXU_S32STDR
:
26196 /* TODO: Implement emulation of S32STDR instruction. */
26197 MIPS_INVAL("OPC_MXU_S32STDR");
26198 generate_exception_end(ctx
, EXCP_RI
);
26201 MIPS_INVAL("decode_opc_mxu");
26202 generate_exception_end(ctx
, EXCP_RI
);
26209 * Decode MXU pool06
26211 * 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
26212 * +-----------+---------+---------+---+-------+-------+-----------+
26213 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26214 * +-----------+---------+---------+---+-------+-------+-----------+
26217 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26219 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26222 case OPC_MXU_S32LDDV
:
26223 /* TODO: Implement emulation of S32LDDV instruction. */
26224 MIPS_INVAL("OPC_MXU_S32LDDV");
26225 generate_exception_end(ctx
, EXCP_RI
);
26227 case OPC_MXU_S32LDDVR
:
26228 /* TODO: Implement emulation of S32LDDVR instruction. */
26229 MIPS_INVAL("OPC_MXU_S32LDDVR");
26230 generate_exception_end(ctx
, EXCP_RI
);
26233 MIPS_INVAL("decode_opc_mxu");
26234 generate_exception_end(ctx
, EXCP_RI
);
26241 * Decode MXU pool07
26243 * 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
26244 * +-----------+---------+---------+---+-------+-------+-----------+
26245 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26246 * +-----------+---------+---------+---+-------+-------+-----------+
26249 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26251 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26254 case OPC_MXU_S32STDV
:
26255 /* TODO: Implement emulation of S32TDV instruction. */
26256 MIPS_INVAL("OPC_MXU_S32TDV");
26257 generate_exception_end(ctx
, EXCP_RI
);
26259 case OPC_MXU_S32STDVR
:
26260 /* TODO: Implement emulation of S32TDVR instruction. */
26261 MIPS_INVAL("OPC_MXU_S32TDVR");
26262 generate_exception_end(ctx
, EXCP_RI
);
26265 MIPS_INVAL("decode_opc_mxu");
26266 generate_exception_end(ctx
, EXCP_RI
);
26273 * Decode MXU pool08
26275 * 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
26276 * +-----------+---------+-+-------------------+-------+-----------+
26277 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26278 * +-----------+---------+-+-------------------+-------+-----------+
26281 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26283 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26286 case OPC_MXU_S32LDI
:
26287 /* TODO: Implement emulation of S32LDI instruction. */
26288 MIPS_INVAL("OPC_MXU_S32LDI");
26289 generate_exception_end(ctx
, EXCP_RI
);
26291 case OPC_MXU_S32LDIR
:
26292 /* TODO: Implement emulation of S32LDIR instruction. */
26293 MIPS_INVAL("OPC_MXU_S32LDIR");
26294 generate_exception_end(ctx
, EXCP_RI
);
26297 MIPS_INVAL("decode_opc_mxu");
26298 generate_exception_end(ctx
, EXCP_RI
);
26305 * Decode MXU pool09
26307 * 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
26308 * +-----------+---------+-+-------------------+-------+-----------+
26309 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26310 * +-----------+---------+-+-------------------+-------+-----------+
26313 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26315 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26318 case OPC_MXU_S32SDI
:
26319 /* TODO: Implement emulation of S32SDI instruction. */
26320 MIPS_INVAL("OPC_MXU_S32SDI");
26321 generate_exception_end(ctx
, EXCP_RI
);
26323 case OPC_MXU_S32SDIR
:
26324 /* TODO: Implement emulation of S32SDIR instruction. */
26325 MIPS_INVAL("OPC_MXU_S32SDIR");
26326 generate_exception_end(ctx
, EXCP_RI
);
26329 MIPS_INVAL("decode_opc_mxu");
26330 generate_exception_end(ctx
, EXCP_RI
);
26337 * Decode MXU pool10
26339 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26340 * +-----------+---------+---------+---+-------+-------+-----------+
26341 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26342 * +-----------+---------+---------+---+-------+-------+-----------+
26345 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26347 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26350 case OPC_MXU_S32LDIV
:
26351 /* TODO: Implement emulation of S32LDIV instruction. */
26352 MIPS_INVAL("OPC_MXU_S32LDIV");
26353 generate_exception_end(ctx
, EXCP_RI
);
26355 case OPC_MXU_S32LDIVR
:
26356 /* TODO: Implement emulation of S32LDIVR instruction. */
26357 MIPS_INVAL("OPC_MXU_S32LDIVR");
26358 generate_exception_end(ctx
, EXCP_RI
);
26361 MIPS_INVAL("decode_opc_mxu");
26362 generate_exception_end(ctx
, EXCP_RI
);
26369 * Decode MXU pool11
26371 * 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
26372 * +-----------+---------+---------+---+-------+-------+-----------+
26373 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26374 * +-----------+---------+---------+---+-------+-------+-----------+
26377 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26379 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26382 case OPC_MXU_S32SDIV
:
26383 /* TODO: Implement emulation of S32SDIV instruction. */
26384 MIPS_INVAL("OPC_MXU_S32SDIV");
26385 generate_exception_end(ctx
, EXCP_RI
);
26387 case OPC_MXU_S32SDIVR
:
26388 /* TODO: Implement emulation of S32SDIVR instruction. */
26389 MIPS_INVAL("OPC_MXU_S32SDIVR");
26390 generate_exception_end(ctx
, EXCP_RI
);
26393 MIPS_INVAL("decode_opc_mxu");
26394 generate_exception_end(ctx
, EXCP_RI
);
26401 * Decode MXU pool12
26403 * 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
26404 * +-----------+---+---+-------+-------+-------+-------+-----------+
26405 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26406 * +-----------+---+---+-------+-------+-------+-------+-----------+
26409 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26411 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26414 case OPC_MXU_D32ACC
:
26415 /* TODO: Implement emulation of D32ACC instruction. */
26416 MIPS_INVAL("OPC_MXU_D32ACC");
26417 generate_exception_end(ctx
, EXCP_RI
);
26419 case OPC_MXU_D32ACCM
:
26420 /* TODO: Implement emulation of D32ACCM instruction. */
26421 MIPS_INVAL("OPC_MXU_D32ACCM");
26422 generate_exception_end(ctx
, EXCP_RI
);
26424 case OPC_MXU_D32ASUM
:
26425 /* TODO: Implement emulation of D32ASUM instruction. */
26426 MIPS_INVAL("OPC_MXU_D32ASUM");
26427 generate_exception_end(ctx
, EXCP_RI
);
26430 MIPS_INVAL("decode_opc_mxu");
26431 generate_exception_end(ctx
, EXCP_RI
);
26438 * Decode MXU pool13
26440 * 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
26441 * +-----------+---+---+-------+-------+-------+-------+-----------+
26442 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26443 * +-----------+---+---+-------+-------+-------+-------+-----------+
26446 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26448 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26451 case OPC_MXU_Q16ACC
:
26452 /* TODO: Implement emulation of Q16ACC instruction. */
26453 MIPS_INVAL("OPC_MXU_Q16ACC");
26454 generate_exception_end(ctx
, EXCP_RI
);
26456 case OPC_MXU_Q16ACCM
:
26457 /* TODO: Implement emulation of Q16ACCM instruction. */
26458 MIPS_INVAL("OPC_MXU_Q16ACCM");
26459 generate_exception_end(ctx
, EXCP_RI
);
26461 case OPC_MXU_Q16ASUM
:
26462 /* TODO: Implement emulation of Q16ASUM instruction. */
26463 MIPS_INVAL("OPC_MXU_Q16ASUM");
26464 generate_exception_end(ctx
, EXCP_RI
);
26467 MIPS_INVAL("decode_opc_mxu");
26468 generate_exception_end(ctx
, EXCP_RI
);
26475 * Decode MXU pool14
26478 * 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
26479 * +-----------+---+---+-------+-------+-------+-------+-----------+
26480 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26481 * +-----------+---+---+-------+-------+-------+-------+-----------+
26484 * 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
26485 * +-----------+---+---+-------+-------+-------+-------+-----------+
26486 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26487 * +-----------+---+---+-------+-------+-------+-------+-----------+
26490 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26492 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26495 case OPC_MXU_Q8ADDE
:
26496 /* TODO: Implement emulation of Q8ADDE instruction. */
26497 MIPS_INVAL("OPC_MXU_Q8ADDE");
26498 generate_exception_end(ctx
, EXCP_RI
);
26500 case OPC_MXU_D8SUM
:
26501 /* TODO: Implement emulation of D8SUM instruction. */
26502 MIPS_INVAL("OPC_MXU_D8SUM");
26503 generate_exception_end(ctx
, EXCP_RI
);
26505 case OPC_MXU_D8SUMC
:
26506 /* TODO: Implement emulation of D8SUMC instruction. */
26507 MIPS_INVAL("OPC_MXU_D8SUMC");
26508 generate_exception_end(ctx
, EXCP_RI
);
26511 MIPS_INVAL("decode_opc_mxu");
26512 generate_exception_end(ctx
, EXCP_RI
);
26519 * Decode MXU pool15
26521 * S32MUL, S32MULU, S32EXTRV:
26522 * 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
26523 * +-----------+---------+---------+---+-------+-------+-----------+
26524 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26525 * +-----------+---------+---------+---+-------+-------+-----------+
26528 * 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
26529 * +-----------+---------+---------+---+-------+-------+-----------+
26530 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26531 * +-----------+---------+---------+---+-------+-------+-----------+
26534 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26536 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26539 case OPC_MXU_S32MUL
:
26540 /* TODO: Implement emulation of S32MUL instruction. */
26541 MIPS_INVAL("OPC_MXU_S32MUL");
26542 generate_exception_end(ctx
, EXCP_RI
);
26544 case OPC_MXU_S32MULU
:
26545 /* TODO: Implement emulation of S32MULU instruction. */
26546 MIPS_INVAL("OPC_MXU_S32MULU");
26547 generate_exception_end(ctx
, EXCP_RI
);
26549 case OPC_MXU_S32EXTR
:
26550 /* TODO: Implement emulation of S32EXTR instruction. */
26551 MIPS_INVAL("OPC_MXU_S32EXTR");
26552 generate_exception_end(ctx
, EXCP_RI
);
26554 case OPC_MXU_S32EXTRV
:
26555 /* TODO: Implement emulation of S32EXTRV instruction. */
26556 MIPS_INVAL("OPC_MXU_S32EXTRV");
26557 generate_exception_end(ctx
, EXCP_RI
);
26560 MIPS_INVAL("decode_opc_mxu");
26561 generate_exception_end(ctx
, EXCP_RI
);
26568 * Decode MXU pool16
26571 * 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
26572 * +-----------+---------+-----+-------+-------+-------+-----------+
26573 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26574 * +-----------+---------+-----+-------+-------+-------+-----------+
26577 * 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
26578 * +-----------+---------+-----+-------+-------+-------+-----------+
26579 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26580 * +-----------+---------+-----+-------+-------+-------+-----------+
26583 * 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
26584 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26585 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26586 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26589 * 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
26590 * +-----------+-----+---+-----+-------+---------------+-----------+
26591 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26592 * +-----------+-----+---+-----+-------+---------------+-----------+
26594 * S32NOR, S32AND, S32OR, S32XOR:
26595 * 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
26596 * +-----------+---------+-----+-------+-------+-------+-----------+
26597 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26598 * +-----------+---------+-----+-------+-------+-------+-----------+
26601 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
26603 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26606 case OPC_MXU_D32SARW
:
26607 /* TODO: Implement emulation of D32SARW instruction. */
26608 MIPS_INVAL("OPC_MXU_D32SARW");
26609 generate_exception_end(ctx
, EXCP_RI
);
26611 case OPC_MXU_S32ALN
:
26612 /* TODO: Implement emulation of S32ALN instruction. */
26613 MIPS_INVAL("OPC_MXU_S32ALN");
26614 generate_exception_end(ctx
, EXCP_RI
);
26616 case OPC_MXU_S32ALNI
:
26617 gen_mxu_S32ALNI(ctx
);
26619 case OPC_MXU_S32LUI
:
26620 /* TODO: Implement emulation of S32LUI instruction. */
26621 MIPS_INVAL("OPC_MXU_S32LUI");
26622 generate_exception_end(ctx
, EXCP_RI
);
26624 case OPC_MXU_S32NOR
:
26625 gen_mxu_S32NOR(ctx
);
26627 case OPC_MXU_S32AND
:
26628 gen_mxu_S32AND(ctx
);
26630 case OPC_MXU_S32OR
:
26631 gen_mxu_S32OR(ctx
);
26633 case OPC_MXU_S32XOR
:
26634 gen_mxu_S32XOR(ctx
);
26637 MIPS_INVAL("decode_opc_mxu");
26638 generate_exception_end(ctx
, EXCP_RI
);
26645 * Decode MXU pool17
26647 * 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
26648 * +-----------+---------+---------+---+---------+-----+-----------+
26649 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26650 * +-----------+---------+---------+---+---------+-----+-----------+
26653 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
26655 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
26659 /* TODO: Implement emulation of LXW instruction. */
26660 MIPS_INVAL("OPC_MXU_LXW");
26661 generate_exception_end(ctx
, EXCP_RI
);
26664 /* TODO: Implement emulation of LXH instruction. */
26665 MIPS_INVAL("OPC_MXU_LXH");
26666 generate_exception_end(ctx
, EXCP_RI
);
26669 /* TODO: Implement emulation of LXHU instruction. */
26670 MIPS_INVAL("OPC_MXU_LXHU");
26671 generate_exception_end(ctx
, EXCP_RI
);
26674 /* TODO: Implement emulation of LXB instruction. */
26675 MIPS_INVAL("OPC_MXU_LXB");
26676 generate_exception_end(ctx
, EXCP_RI
);
26679 /* TODO: Implement emulation of LXBU instruction. */
26680 MIPS_INVAL("OPC_MXU_LXBU");
26681 generate_exception_end(ctx
, EXCP_RI
);
26684 MIPS_INVAL("decode_opc_mxu");
26685 generate_exception_end(ctx
, EXCP_RI
);
26691 * Decode MXU pool18
26693 * 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
26694 * +-----------+---------+-----+-------+-------+-------+-----------+
26695 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26696 * +-----------+---------+-----+-------+-------+-------+-----------+
26699 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
26701 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26704 case OPC_MXU_D32SLLV
:
26705 /* TODO: Implement emulation of D32SLLV instruction. */
26706 MIPS_INVAL("OPC_MXU_D32SLLV");
26707 generate_exception_end(ctx
, EXCP_RI
);
26709 case OPC_MXU_D32SLRV
:
26710 /* TODO: Implement emulation of D32SLRV instruction. */
26711 MIPS_INVAL("OPC_MXU_D32SLRV");
26712 generate_exception_end(ctx
, EXCP_RI
);
26714 case OPC_MXU_D32SARV
:
26715 /* TODO: Implement emulation of D32SARV instruction. */
26716 MIPS_INVAL("OPC_MXU_D32SARV");
26717 generate_exception_end(ctx
, EXCP_RI
);
26719 case OPC_MXU_Q16SLLV
:
26720 /* TODO: Implement emulation of Q16SLLV instruction. */
26721 MIPS_INVAL("OPC_MXU_Q16SLLV");
26722 generate_exception_end(ctx
, EXCP_RI
);
26724 case OPC_MXU_Q16SLRV
:
26725 /* TODO: Implement emulation of Q16SLRV instruction. */
26726 MIPS_INVAL("OPC_MXU_Q16SLRV");
26727 generate_exception_end(ctx
, EXCP_RI
);
26729 case OPC_MXU_Q16SARV
:
26730 /* TODO: Implement emulation of Q16SARV instruction. */
26731 MIPS_INVAL("OPC_MXU_Q16SARV");
26732 generate_exception_end(ctx
, EXCP_RI
);
26735 MIPS_INVAL("decode_opc_mxu");
26736 generate_exception_end(ctx
, EXCP_RI
);
26743 * Decode MXU pool19
26745 * 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
26746 * +-----------+---+---+-------+-------+-------+-------+-----------+
26747 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
26748 * +-----------+---+---+-------+-------+-------+-------+-----------+
26751 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
26753 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26756 case OPC_MXU_Q8MUL
:
26757 case OPC_MXU_Q8MULSU
:
26758 gen_mxu_q8mul_q8mulsu(ctx
);
26761 MIPS_INVAL("decode_opc_mxu");
26762 generate_exception_end(ctx
, EXCP_RI
);
26769 * Decode MXU pool20
26771 * 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
26772 * +-----------+---------+-----+-------+-------+-------+-----------+
26773 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
26774 * +-----------+---------+-----+-------+-------+-------+-----------+
26777 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
26779 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26782 case OPC_MXU_Q8MOVZ
:
26783 /* TODO: Implement emulation of Q8MOVZ instruction. */
26784 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26785 generate_exception_end(ctx
, EXCP_RI
);
26787 case OPC_MXU_Q8MOVN
:
26788 /* TODO: Implement emulation of Q8MOVN instruction. */
26789 MIPS_INVAL("OPC_MXU_Q8MOVN");
26790 generate_exception_end(ctx
, EXCP_RI
);
26792 case OPC_MXU_D16MOVZ
:
26793 /* TODO: Implement emulation of D16MOVZ instruction. */
26794 MIPS_INVAL("OPC_MXU_D16MOVZ");
26795 generate_exception_end(ctx
, EXCP_RI
);
26797 case OPC_MXU_D16MOVN
:
26798 /* TODO: Implement emulation of D16MOVN instruction. */
26799 MIPS_INVAL("OPC_MXU_D16MOVN");
26800 generate_exception_end(ctx
, EXCP_RI
);
26802 case OPC_MXU_S32MOVZ
:
26803 /* TODO: Implement emulation of S32MOVZ instruction. */
26804 MIPS_INVAL("OPC_MXU_S32MOVZ");
26805 generate_exception_end(ctx
, EXCP_RI
);
26807 case OPC_MXU_S32MOVN
:
26808 /* TODO: Implement emulation of S32MOVN instruction. */
26809 MIPS_INVAL("OPC_MXU_S32MOVN");
26810 generate_exception_end(ctx
, EXCP_RI
);
26813 MIPS_INVAL("decode_opc_mxu");
26814 generate_exception_end(ctx
, EXCP_RI
);
26821 * Decode MXU pool21
26823 * 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
26824 * +-----------+---+---+-------+-------+-------+-------+-----------+
26825 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
26826 * +-----------+---+---+-------+-------+-------+-------+-----------+
26829 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
26831 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26834 case OPC_MXU_Q8MAC
:
26835 /* TODO: Implement emulation of Q8MAC instruction. */
26836 MIPS_INVAL("OPC_MXU_Q8MAC");
26837 generate_exception_end(ctx
, EXCP_RI
);
26839 case OPC_MXU_Q8MACSU
:
26840 /* TODO: Implement emulation of Q8MACSU instruction. */
26841 MIPS_INVAL("OPC_MXU_Q8MACSU");
26842 generate_exception_end(ctx
, EXCP_RI
);
26845 MIPS_INVAL("decode_opc_mxu");
26846 generate_exception_end(ctx
, EXCP_RI
);
26853 * Main MXU decoding function
26855 * 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
26856 * +-----------+---------------------------------------+-----------+
26857 * | SPECIAL2 | |x x x x x x|
26858 * +-----------+---------------------------------------+-----------+
26861 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
26864 * TODO: Investigate necessity of including handling of
26865 * CLZ, CLO, SDBB in this function, as they belong to
26866 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26868 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
26870 if (opcode
== OPC__MXU_MUL
) {
26871 uint32_t rs
, rt
, rd
, op1
;
26873 rs
= extract32(ctx
->opcode
, 21, 5);
26874 rt
= extract32(ctx
->opcode
, 16, 5);
26875 rd
= extract32(ctx
->opcode
, 11, 5);
26876 op1
= MASK_SPECIAL2(ctx
->opcode
);
26878 gen_arith(ctx
, op1
, rd
, rs
, rt
);
26883 if (opcode
== OPC_MXU_S32M2I
) {
26884 gen_mxu_s32m2i(ctx
);
26888 if (opcode
== OPC_MXU_S32I2M
) {
26889 gen_mxu_s32i2m(ctx
);
26894 TCGv t_mxu_cr
= tcg_temp_new();
26895 TCGLabel
*l_exit
= gen_new_label();
26897 gen_load_mxu_cr(t_mxu_cr
);
26898 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
26899 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
26902 case OPC_MXU_S32MADD
:
26903 /* TODO: Implement emulation of S32MADD instruction. */
26904 MIPS_INVAL("OPC_MXU_S32MADD");
26905 generate_exception_end(ctx
, EXCP_RI
);
26907 case OPC_MXU_S32MADDU
:
26908 /* TODO: Implement emulation of S32MADDU instruction. */
26909 MIPS_INVAL("OPC_MXU_S32MADDU");
26910 generate_exception_end(ctx
, EXCP_RI
);
26912 case OPC_MXU__POOL00
:
26913 decode_opc_mxu__pool00(env
, ctx
);
26915 case OPC_MXU_S32MSUB
:
26916 /* TODO: Implement emulation of S32MSUB instruction. */
26917 MIPS_INVAL("OPC_MXU_S32MSUB");
26918 generate_exception_end(ctx
, EXCP_RI
);
26920 case OPC_MXU_S32MSUBU
:
26921 /* TODO: Implement emulation of S32MSUBU instruction. */
26922 MIPS_INVAL("OPC_MXU_S32MSUBU");
26923 generate_exception_end(ctx
, EXCP_RI
);
26925 case OPC_MXU__POOL01
:
26926 decode_opc_mxu__pool01(env
, ctx
);
26928 case OPC_MXU__POOL02
:
26929 decode_opc_mxu__pool02(env
, ctx
);
26931 case OPC_MXU_D16MUL
:
26932 gen_mxu_d16mul(ctx
);
26934 case OPC_MXU__POOL03
:
26935 decode_opc_mxu__pool03(env
, ctx
);
26937 case OPC_MXU_D16MAC
:
26938 gen_mxu_d16mac(ctx
);
26940 case OPC_MXU_D16MACF
:
26941 /* TODO: Implement emulation of D16MACF instruction. */
26942 MIPS_INVAL("OPC_MXU_D16MACF");
26943 generate_exception_end(ctx
, EXCP_RI
);
26945 case OPC_MXU_D16MADL
:
26946 /* TODO: Implement emulation of D16MADL instruction. */
26947 MIPS_INVAL("OPC_MXU_D16MADL");
26948 generate_exception_end(ctx
, EXCP_RI
);
26950 case OPC_MXU_S16MAD
:
26951 /* TODO: Implement emulation of S16MAD instruction. */
26952 MIPS_INVAL("OPC_MXU_S16MAD");
26953 generate_exception_end(ctx
, EXCP_RI
);
26955 case OPC_MXU_Q16ADD
:
26956 /* TODO: Implement emulation of Q16ADD instruction. */
26957 MIPS_INVAL("OPC_MXU_Q16ADD");
26958 generate_exception_end(ctx
, EXCP_RI
);
26960 case OPC_MXU_D16MACE
:
26961 /* TODO: Implement emulation of D16MACE instruction. */
26962 MIPS_INVAL("OPC_MXU_D16MACE");
26963 generate_exception_end(ctx
, EXCP_RI
);
26965 case OPC_MXU__POOL04
:
26966 decode_opc_mxu__pool04(env
, ctx
);
26968 case OPC_MXU__POOL05
:
26969 decode_opc_mxu__pool05(env
, ctx
);
26971 case OPC_MXU__POOL06
:
26972 decode_opc_mxu__pool06(env
, ctx
);
26974 case OPC_MXU__POOL07
:
26975 decode_opc_mxu__pool07(env
, ctx
);
26977 case OPC_MXU__POOL08
:
26978 decode_opc_mxu__pool08(env
, ctx
);
26980 case OPC_MXU__POOL09
:
26981 decode_opc_mxu__pool09(env
, ctx
);
26983 case OPC_MXU__POOL10
:
26984 decode_opc_mxu__pool10(env
, ctx
);
26986 case OPC_MXU__POOL11
:
26987 decode_opc_mxu__pool11(env
, ctx
);
26989 case OPC_MXU_D32ADD
:
26990 /* TODO: Implement emulation of D32ADD instruction. */
26991 MIPS_INVAL("OPC_MXU_D32ADD");
26992 generate_exception_end(ctx
, EXCP_RI
);
26994 case OPC_MXU__POOL12
:
26995 decode_opc_mxu__pool12(env
, ctx
);
26997 case OPC_MXU__POOL13
:
26998 decode_opc_mxu__pool13(env
, ctx
);
27000 case OPC_MXU__POOL14
:
27001 decode_opc_mxu__pool14(env
, ctx
);
27003 case OPC_MXU_Q8ACCE
:
27004 /* TODO: Implement emulation of Q8ACCE instruction. */
27005 MIPS_INVAL("OPC_MXU_Q8ACCE");
27006 generate_exception_end(ctx
, EXCP_RI
);
27008 case OPC_MXU_S8LDD
:
27009 gen_mxu_s8ldd(ctx
);
27011 case OPC_MXU_S8STD
:
27012 /* TODO: Implement emulation of S8STD instruction. */
27013 MIPS_INVAL("OPC_MXU_S8STD");
27014 generate_exception_end(ctx
, EXCP_RI
);
27016 case OPC_MXU_S8LDI
:
27017 /* TODO: Implement emulation of S8LDI instruction. */
27018 MIPS_INVAL("OPC_MXU_S8LDI");
27019 generate_exception_end(ctx
, EXCP_RI
);
27021 case OPC_MXU_S8SDI
:
27022 /* TODO: Implement emulation of S8SDI instruction. */
27023 MIPS_INVAL("OPC_MXU_S8SDI");
27024 generate_exception_end(ctx
, EXCP_RI
);
27026 case OPC_MXU__POOL15
:
27027 decode_opc_mxu__pool15(env
, ctx
);
27029 case OPC_MXU__POOL16
:
27030 decode_opc_mxu__pool16(env
, ctx
);
27032 case OPC_MXU__POOL17
:
27033 decode_opc_mxu__pool17(env
, ctx
);
27035 case OPC_MXU_S16LDD
:
27036 /* TODO: Implement emulation of S16LDD instruction. */
27037 MIPS_INVAL("OPC_MXU_S16LDD");
27038 generate_exception_end(ctx
, EXCP_RI
);
27040 case OPC_MXU_S16STD
:
27041 /* TODO: Implement emulation of S16STD instruction. */
27042 MIPS_INVAL("OPC_MXU_S16STD");
27043 generate_exception_end(ctx
, EXCP_RI
);
27045 case OPC_MXU_S16LDI
:
27046 /* TODO: Implement emulation of S16LDI instruction. */
27047 MIPS_INVAL("OPC_MXU_S16LDI");
27048 generate_exception_end(ctx
, EXCP_RI
);
27050 case OPC_MXU_S16SDI
:
27051 /* TODO: Implement emulation of S16SDI instruction. */
27052 MIPS_INVAL("OPC_MXU_S16SDI");
27053 generate_exception_end(ctx
, EXCP_RI
);
27055 case OPC_MXU_D32SLL
:
27056 /* TODO: Implement emulation of D32SLL instruction. */
27057 MIPS_INVAL("OPC_MXU_D32SLL");
27058 generate_exception_end(ctx
, EXCP_RI
);
27060 case OPC_MXU_D32SLR
:
27061 /* TODO: Implement emulation of D32SLR instruction. */
27062 MIPS_INVAL("OPC_MXU_D32SLR");
27063 generate_exception_end(ctx
, EXCP_RI
);
27065 case OPC_MXU_D32SARL
:
27066 /* TODO: Implement emulation of D32SARL instruction. */
27067 MIPS_INVAL("OPC_MXU_D32SARL");
27068 generate_exception_end(ctx
, EXCP_RI
);
27070 case OPC_MXU_D32SAR
:
27071 /* TODO: Implement emulation of D32SAR instruction. */
27072 MIPS_INVAL("OPC_MXU_D32SAR");
27073 generate_exception_end(ctx
, EXCP_RI
);
27075 case OPC_MXU_Q16SLL
:
27076 /* TODO: Implement emulation of Q16SLL instruction. */
27077 MIPS_INVAL("OPC_MXU_Q16SLL");
27078 generate_exception_end(ctx
, EXCP_RI
);
27080 case OPC_MXU_Q16SLR
:
27081 /* TODO: Implement emulation of Q16SLR instruction. */
27082 MIPS_INVAL("OPC_MXU_Q16SLR");
27083 generate_exception_end(ctx
, EXCP_RI
);
27085 case OPC_MXU__POOL18
:
27086 decode_opc_mxu__pool18(env
, ctx
);
27088 case OPC_MXU_Q16SAR
:
27089 /* TODO: Implement emulation of Q16SAR instruction. */
27090 MIPS_INVAL("OPC_MXU_Q16SAR");
27091 generate_exception_end(ctx
, EXCP_RI
);
27093 case OPC_MXU__POOL19
:
27094 decode_opc_mxu__pool19(env
, ctx
);
27096 case OPC_MXU__POOL20
:
27097 decode_opc_mxu__pool20(env
, ctx
);
27099 case OPC_MXU__POOL21
:
27100 decode_opc_mxu__pool21(env
, ctx
);
27102 case OPC_MXU_Q16SCOP
:
27103 /* TODO: Implement emulation of Q16SCOP instruction. */
27104 MIPS_INVAL("OPC_MXU_Q16SCOP");
27105 generate_exception_end(ctx
, EXCP_RI
);
27107 case OPC_MXU_Q8MADL
:
27108 /* TODO: Implement emulation of Q8MADL instruction. */
27109 MIPS_INVAL("OPC_MXU_Q8MADL");
27110 generate_exception_end(ctx
, EXCP_RI
);
27112 case OPC_MXU_S32SFL
:
27113 /* TODO: Implement emulation of S32SFL instruction. */
27114 MIPS_INVAL("OPC_MXU_S32SFL");
27115 generate_exception_end(ctx
, EXCP_RI
);
27117 case OPC_MXU_Q8SAD
:
27118 /* TODO: Implement emulation of Q8SAD instruction. */
27119 MIPS_INVAL("OPC_MXU_Q8SAD");
27120 generate_exception_end(ctx
, EXCP_RI
);
27123 MIPS_INVAL("decode_opc_mxu");
27124 generate_exception_end(ctx
, EXCP_RI
);
27127 gen_set_label(l_exit
);
27128 tcg_temp_free(t_mxu_cr
);
27132 #endif /* !defined(TARGET_MIPS64) */
27135 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27140 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
27142 rs
= (ctx
->opcode
>> 21) & 0x1f;
27143 rt
= (ctx
->opcode
>> 16) & 0x1f;
27144 rd
= (ctx
->opcode
>> 11) & 0x1f;
27146 op1
= MASK_SPECIAL2(ctx
->opcode
);
27148 case OPC_MADD
: /* Multiply and add/sub */
27152 check_insn(ctx
, ISA_MIPS32
);
27153 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
27156 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27159 case OPC_DIVU_G_2F
:
27160 case OPC_MULT_G_2F
:
27161 case OPC_MULTU_G_2F
:
27163 case OPC_MODU_G_2F
:
27164 check_insn(ctx
, INSN_LOONGSON2F
);
27165 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27169 check_insn(ctx
, ISA_MIPS32
);
27170 gen_cl(ctx
, op1
, rd
, rs
);
27173 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
27174 gen_helper_do_semihosting(cpu_env
);
27177 * XXX: not clear which exception should be raised
27178 * when in debug mode...
27180 check_insn(ctx
, ISA_MIPS32
);
27181 generate_exception_end(ctx
, EXCP_DBp
);
27184 #if defined(TARGET_MIPS64)
27187 check_insn(ctx
, ISA_MIPS64
);
27188 check_mips_64(ctx
);
27189 gen_cl(ctx
, op1
, rd
, rs
);
27191 case OPC_DMULT_G_2F
:
27192 case OPC_DMULTU_G_2F
:
27193 case OPC_DDIV_G_2F
:
27194 case OPC_DDIVU_G_2F
:
27195 case OPC_DMOD_G_2F
:
27196 case OPC_DMODU_G_2F
:
27197 check_insn(ctx
, INSN_LOONGSON2F
);
27198 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27201 default: /* Invalid */
27202 MIPS_INVAL("special2_legacy");
27203 generate_exception_end(ctx
, EXCP_RI
);
27208 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27210 int rs
, rt
, rd
, sa
;
27214 rs
= (ctx
->opcode
>> 21) & 0x1f;
27215 rt
= (ctx
->opcode
>> 16) & 0x1f;
27216 rd
= (ctx
->opcode
>> 11) & 0x1f;
27217 sa
= (ctx
->opcode
>> 6) & 0x1f;
27218 imm
= (int16_t)ctx
->opcode
>> 7;
27220 op1
= MASK_SPECIAL3(ctx
->opcode
);
27224 /* hint codes 24-31 are reserved and signal RI */
27225 generate_exception_end(ctx
, EXCP_RI
);
27227 /* Treat as NOP. */
27230 check_cp0_enabled(ctx
);
27231 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27232 gen_cache_operation(ctx
, rt
, rs
, imm
);
27236 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27239 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27244 /* Treat as NOP. */
27247 op2
= MASK_BSHFL(ctx
->opcode
);
27253 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27256 gen_bitswap(ctx
, op2
, rd
, rt
);
27261 #ifndef CONFIG_USER_ONLY
27263 if (unlikely(ctx
->gi
<= 1)) {
27264 generate_exception_end(ctx
, EXCP_RI
);
27266 check_cp0_enabled(ctx
);
27267 switch ((ctx
->opcode
>> 6) & 3) {
27268 case 0: /* GINVI */
27269 /* Treat as NOP. */
27271 case 2: /* GINVT */
27272 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
27275 generate_exception_end(ctx
, EXCP_RI
);
27280 #if defined(TARGET_MIPS64)
27282 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27285 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27288 check_mips_64(ctx
);
27291 /* Treat as NOP. */
27294 op2
= MASK_DBSHFL(ctx
->opcode
);
27304 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27307 gen_bitswap(ctx
, op2
, rd
, rt
);
27314 default: /* Invalid */
27315 MIPS_INVAL("special3_r6");
27316 generate_exception_end(ctx
, EXCP_RI
);
27321 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27326 rs
= (ctx
->opcode
>> 21) & 0x1f;
27327 rt
= (ctx
->opcode
>> 16) & 0x1f;
27328 rd
= (ctx
->opcode
>> 11) & 0x1f;
27330 op1
= MASK_SPECIAL3(ctx
->opcode
);
27333 case OPC_DIVU_G_2E
:
27335 case OPC_MODU_G_2E
:
27336 case OPC_MULT_G_2E
:
27337 case OPC_MULTU_G_2E
:
27339 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27340 * the same mask and op1.
27342 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27343 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27346 case OPC_ADDUH_R_QB
:
27348 case OPC_ADDQH_R_PH
:
27350 case OPC_ADDQH_R_W
:
27352 case OPC_SUBUH_R_QB
:
27354 case OPC_SUBQH_R_PH
:
27356 case OPC_SUBQH_R_W
:
27357 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27362 case OPC_MULQ_RS_W
:
27363 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27366 MIPS_INVAL("MASK ADDUH.QB");
27367 generate_exception_end(ctx
, EXCP_RI
);
27370 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27371 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27373 generate_exception_end(ctx
, EXCP_RI
);
27377 op2
= MASK_LX(ctx
->opcode
);
27379 #if defined(TARGET_MIPS64)
27385 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27387 default: /* Invalid */
27388 MIPS_INVAL("MASK LX");
27389 generate_exception_end(ctx
, EXCP_RI
);
27393 case OPC_ABSQ_S_PH_DSP
:
27394 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27396 case OPC_ABSQ_S_QB
:
27397 case OPC_ABSQ_S_PH
:
27399 case OPC_PRECEQ_W_PHL
:
27400 case OPC_PRECEQ_W_PHR
:
27401 case OPC_PRECEQU_PH_QBL
:
27402 case OPC_PRECEQU_PH_QBR
:
27403 case OPC_PRECEQU_PH_QBLA
:
27404 case OPC_PRECEQU_PH_QBRA
:
27405 case OPC_PRECEU_PH_QBL
:
27406 case OPC_PRECEU_PH_QBR
:
27407 case OPC_PRECEU_PH_QBLA
:
27408 case OPC_PRECEU_PH_QBRA
:
27409 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27416 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27419 MIPS_INVAL("MASK ABSQ_S.PH");
27420 generate_exception_end(ctx
, EXCP_RI
);
27424 case OPC_ADDU_QB_DSP
:
27425 op2
= MASK_ADDU_QB(ctx
->opcode
);
27428 case OPC_ADDQ_S_PH
:
27431 case OPC_ADDU_S_QB
:
27433 case OPC_ADDU_S_PH
:
27435 case OPC_SUBQ_S_PH
:
27438 case OPC_SUBU_S_QB
:
27440 case OPC_SUBU_S_PH
:
27444 case OPC_RADDU_W_QB
:
27445 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27447 case OPC_MULEU_S_PH_QBL
:
27448 case OPC_MULEU_S_PH_QBR
:
27449 case OPC_MULQ_RS_PH
:
27450 case OPC_MULEQ_S_W_PHL
:
27451 case OPC_MULEQ_S_W_PHR
:
27452 case OPC_MULQ_S_PH
:
27453 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27455 default: /* Invalid */
27456 MIPS_INVAL("MASK ADDU.QB");
27457 generate_exception_end(ctx
, EXCP_RI
);
27462 case OPC_CMPU_EQ_QB_DSP
:
27463 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27465 case OPC_PRECR_SRA_PH_W
:
27466 case OPC_PRECR_SRA_R_PH_W
:
27467 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27469 case OPC_PRECR_QB_PH
:
27470 case OPC_PRECRQ_QB_PH
:
27471 case OPC_PRECRQ_PH_W
:
27472 case OPC_PRECRQ_RS_PH_W
:
27473 case OPC_PRECRQU_S_QB_PH
:
27474 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27476 case OPC_CMPU_EQ_QB
:
27477 case OPC_CMPU_LT_QB
:
27478 case OPC_CMPU_LE_QB
:
27479 case OPC_CMP_EQ_PH
:
27480 case OPC_CMP_LT_PH
:
27481 case OPC_CMP_LE_PH
:
27482 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27484 case OPC_CMPGU_EQ_QB
:
27485 case OPC_CMPGU_LT_QB
:
27486 case OPC_CMPGU_LE_QB
:
27487 case OPC_CMPGDU_EQ_QB
:
27488 case OPC_CMPGDU_LT_QB
:
27489 case OPC_CMPGDU_LE_QB
:
27492 case OPC_PACKRL_PH
:
27493 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27495 default: /* Invalid */
27496 MIPS_INVAL("MASK CMPU.EQ.QB");
27497 generate_exception_end(ctx
, EXCP_RI
);
27501 case OPC_SHLL_QB_DSP
:
27502 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27504 case OPC_DPA_W_PH_DSP
:
27505 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27507 case OPC_DPAU_H_QBL
:
27508 case OPC_DPAU_H_QBR
:
27509 case OPC_DPSU_H_QBL
:
27510 case OPC_DPSU_H_QBR
:
27512 case OPC_DPAX_W_PH
:
27513 case OPC_DPAQ_S_W_PH
:
27514 case OPC_DPAQX_S_W_PH
:
27515 case OPC_DPAQX_SA_W_PH
:
27517 case OPC_DPSX_W_PH
:
27518 case OPC_DPSQ_S_W_PH
:
27519 case OPC_DPSQX_S_W_PH
:
27520 case OPC_DPSQX_SA_W_PH
:
27521 case OPC_MULSAQ_S_W_PH
:
27522 case OPC_DPAQ_SA_L_W
:
27523 case OPC_DPSQ_SA_L_W
:
27524 case OPC_MAQ_S_W_PHL
:
27525 case OPC_MAQ_S_W_PHR
:
27526 case OPC_MAQ_SA_W_PHL
:
27527 case OPC_MAQ_SA_W_PHR
:
27528 case OPC_MULSA_W_PH
:
27529 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27531 default: /* Invalid */
27532 MIPS_INVAL("MASK DPAW.PH");
27533 generate_exception_end(ctx
, EXCP_RI
);
27538 op2
= MASK_INSV(ctx
->opcode
);
27549 t0
= tcg_temp_new();
27550 t1
= tcg_temp_new();
27552 gen_load_gpr(t0
, rt
);
27553 gen_load_gpr(t1
, rs
);
27555 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27561 default: /* Invalid */
27562 MIPS_INVAL("MASK INSV");
27563 generate_exception_end(ctx
, EXCP_RI
);
27567 case OPC_APPEND_DSP
:
27568 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27570 case OPC_EXTR_W_DSP
:
27571 op2
= MASK_EXTR_W(ctx
->opcode
);
27575 case OPC_EXTR_RS_W
:
27577 case OPC_EXTRV_S_H
:
27579 case OPC_EXTRV_R_W
:
27580 case OPC_EXTRV_RS_W
:
27585 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27588 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27594 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27596 default: /* Invalid */
27597 MIPS_INVAL("MASK EXTR.W");
27598 generate_exception_end(ctx
, EXCP_RI
);
27602 #if defined(TARGET_MIPS64)
27603 case OPC_DDIV_G_2E
:
27604 case OPC_DDIVU_G_2E
:
27605 case OPC_DMULT_G_2E
:
27606 case OPC_DMULTU_G_2E
:
27607 case OPC_DMOD_G_2E
:
27608 case OPC_DMODU_G_2E
:
27609 check_insn(ctx
, INSN_LOONGSON2E
);
27610 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27612 case OPC_ABSQ_S_QH_DSP
:
27613 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
27615 case OPC_PRECEQ_L_PWL
:
27616 case OPC_PRECEQ_L_PWR
:
27617 case OPC_PRECEQ_PW_QHL
:
27618 case OPC_PRECEQ_PW_QHR
:
27619 case OPC_PRECEQ_PW_QHLA
:
27620 case OPC_PRECEQ_PW_QHRA
:
27621 case OPC_PRECEQU_QH_OBL
:
27622 case OPC_PRECEQU_QH_OBR
:
27623 case OPC_PRECEQU_QH_OBLA
:
27624 case OPC_PRECEQU_QH_OBRA
:
27625 case OPC_PRECEU_QH_OBL
:
27626 case OPC_PRECEU_QH_OBR
:
27627 case OPC_PRECEU_QH_OBLA
:
27628 case OPC_PRECEU_QH_OBRA
:
27629 case OPC_ABSQ_S_OB
:
27630 case OPC_ABSQ_S_PW
:
27631 case OPC_ABSQ_S_QH
:
27632 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27640 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27642 default: /* Invalid */
27643 MIPS_INVAL("MASK ABSQ_S.QH");
27644 generate_exception_end(ctx
, EXCP_RI
);
27648 case OPC_ADDU_OB_DSP
:
27649 op2
= MASK_ADDU_OB(ctx
->opcode
);
27651 case OPC_RADDU_L_OB
:
27653 case OPC_SUBQ_S_PW
:
27655 case OPC_SUBQ_S_QH
:
27657 case OPC_SUBU_S_OB
:
27659 case OPC_SUBU_S_QH
:
27661 case OPC_SUBUH_R_OB
:
27663 case OPC_ADDQ_S_PW
:
27665 case OPC_ADDQ_S_QH
:
27667 case OPC_ADDU_S_OB
:
27669 case OPC_ADDU_S_QH
:
27671 case OPC_ADDUH_R_OB
:
27672 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27674 case OPC_MULEQ_S_PW_QHL
:
27675 case OPC_MULEQ_S_PW_QHR
:
27676 case OPC_MULEU_S_QH_OBL
:
27677 case OPC_MULEU_S_QH_OBR
:
27678 case OPC_MULQ_RS_QH
:
27679 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27681 default: /* Invalid */
27682 MIPS_INVAL("MASK ADDU.OB");
27683 generate_exception_end(ctx
, EXCP_RI
);
27687 case OPC_CMPU_EQ_OB_DSP
:
27688 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
27690 case OPC_PRECR_SRA_QH_PW
:
27691 case OPC_PRECR_SRA_R_QH_PW
:
27692 /* Return value is rt. */
27693 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27695 case OPC_PRECR_OB_QH
:
27696 case OPC_PRECRQ_OB_QH
:
27697 case OPC_PRECRQ_PW_L
:
27698 case OPC_PRECRQ_QH_PW
:
27699 case OPC_PRECRQ_RS_QH_PW
:
27700 case OPC_PRECRQU_S_OB_QH
:
27701 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27703 case OPC_CMPU_EQ_OB
:
27704 case OPC_CMPU_LT_OB
:
27705 case OPC_CMPU_LE_OB
:
27706 case OPC_CMP_EQ_QH
:
27707 case OPC_CMP_LT_QH
:
27708 case OPC_CMP_LE_QH
:
27709 case OPC_CMP_EQ_PW
:
27710 case OPC_CMP_LT_PW
:
27711 case OPC_CMP_LE_PW
:
27712 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27714 case OPC_CMPGDU_EQ_OB
:
27715 case OPC_CMPGDU_LT_OB
:
27716 case OPC_CMPGDU_LE_OB
:
27717 case OPC_CMPGU_EQ_OB
:
27718 case OPC_CMPGU_LT_OB
:
27719 case OPC_CMPGU_LE_OB
:
27720 case OPC_PACKRL_PW
:
27724 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27726 default: /* Invalid */
27727 MIPS_INVAL("MASK CMPU_EQ.OB");
27728 generate_exception_end(ctx
, EXCP_RI
);
27732 case OPC_DAPPEND_DSP
:
27733 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27735 case OPC_DEXTR_W_DSP
:
27736 op2
= MASK_DEXTR_W(ctx
->opcode
);
27743 case OPC_DEXTR_R_L
:
27744 case OPC_DEXTR_RS_L
:
27746 case OPC_DEXTR_R_W
:
27747 case OPC_DEXTR_RS_W
:
27748 case OPC_DEXTR_S_H
:
27750 case OPC_DEXTRV_R_L
:
27751 case OPC_DEXTRV_RS_L
:
27752 case OPC_DEXTRV_S_H
:
27754 case OPC_DEXTRV_R_W
:
27755 case OPC_DEXTRV_RS_W
:
27756 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27761 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27763 default: /* Invalid */
27764 MIPS_INVAL("MASK EXTR.W");
27765 generate_exception_end(ctx
, EXCP_RI
);
27769 case OPC_DPAQ_W_QH_DSP
:
27770 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
27772 case OPC_DPAU_H_OBL
:
27773 case OPC_DPAU_H_OBR
:
27774 case OPC_DPSU_H_OBL
:
27775 case OPC_DPSU_H_OBR
:
27777 case OPC_DPAQ_S_W_QH
:
27779 case OPC_DPSQ_S_W_QH
:
27780 case OPC_MULSAQ_S_W_QH
:
27781 case OPC_DPAQ_SA_L_PW
:
27782 case OPC_DPSQ_SA_L_PW
:
27783 case OPC_MULSAQ_S_L_PW
:
27784 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27786 case OPC_MAQ_S_W_QHLL
:
27787 case OPC_MAQ_S_W_QHLR
:
27788 case OPC_MAQ_S_W_QHRL
:
27789 case OPC_MAQ_S_W_QHRR
:
27790 case OPC_MAQ_SA_W_QHLL
:
27791 case OPC_MAQ_SA_W_QHLR
:
27792 case OPC_MAQ_SA_W_QHRL
:
27793 case OPC_MAQ_SA_W_QHRR
:
27794 case OPC_MAQ_S_L_PWL
:
27795 case OPC_MAQ_S_L_PWR
:
27800 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27802 default: /* Invalid */
27803 MIPS_INVAL("MASK DPAQ.W.QH");
27804 generate_exception_end(ctx
, EXCP_RI
);
27808 case OPC_DINSV_DSP
:
27809 op2
= MASK_INSV(ctx
->opcode
);
27820 t0
= tcg_temp_new();
27821 t1
= tcg_temp_new();
27823 gen_load_gpr(t0
, rt
);
27824 gen_load_gpr(t1
, rs
);
27826 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27832 default: /* Invalid */
27833 MIPS_INVAL("MASK DINSV");
27834 generate_exception_end(ctx
, EXCP_RI
);
27838 case OPC_SHLL_OB_DSP
:
27839 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27842 default: /* Invalid */
27843 MIPS_INVAL("special3_legacy");
27844 generate_exception_end(ctx
, EXCP_RI
);
27850 #if defined(TARGET_MIPS64)
27852 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
27854 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
27857 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
27858 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
27859 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
27860 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
27861 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
27862 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
27863 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
27864 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
27865 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
27866 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
27867 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
27868 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
27869 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
27870 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
27871 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
27872 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
27873 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
27874 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
27875 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
27876 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
27877 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
27878 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
27879 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
27880 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
27881 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
27882 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI0 */
27885 MIPS_INVAL("TX79 MMI class MMI0");
27886 generate_exception_end(ctx
, EXCP_RI
);
27891 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
27893 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
27896 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
27897 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
27898 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
27899 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
27900 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
27901 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
27902 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
27903 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
27904 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
27905 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
27906 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
27907 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
27908 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
27909 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
27910 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
27911 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
27912 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
27913 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
27914 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI1 */
27917 MIPS_INVAL("TX79 MMI class MMI1");
27918 generate_exception_end(ctx
, EXCP_RI
);
27923 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
27925 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
27928 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
27929 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
27930 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
27931 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
27932 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
27933 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
27934 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
27935 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
27936 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
27937 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
27938 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
27939 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
27940 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
27941 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
27942 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
27943 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
27944 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
27945 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
27946 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
27947 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
27948 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
27949 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI2 */
27951 case MMI_OPC_2_PCPYLD
:
27952 gen_mmi_pcpyld(ctx
);
27955 MIPS_INVAL("TX79 MMI class MMI2");
27956 generate_exception_end(ctx
, EXCP_RI
);
27961 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
27963 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
27966 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
27967 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
27968 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
27969 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
27970 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
27971 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
27972 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
27973 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
27974 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
27975 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
27976 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
27977 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI3 */
27979 case MMI_OPC_3_PCPYH
:
27980 gen_mmi_pcpyh(ctx
);
27982 case MMI_OPC_3_PCPYUD
:
27983 gen_mmi_pcpyud(ctx
);
27986 MIPS_INVAL("TX79 MMI class MMI3");
27987 generate_exception_end(ctx
, EXCP_RI
);
27992 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
27994 uint32_t opc
= MASK_MMI(ctx
->opcode
);
27995 int rs
= extract32(ctx
->opcode
, 21, 5);
27996 int rt
= extract32(ctx
->opcode
, 16, 5);
27997 int rd
= extract32(ctx
->opcode
, 11, 5);
28000 case MMI_OPC_CLASS_MMI0
:
28001 decode_mmi0(env
, ctx
);
28003 case MMI_OPC_CLASS_MMI1
:
28004 decode_mmi1(env
, ctx
);
28006 case MMI_OPC_CLASS_MMI2
:
28007 decode_mmi2(env
, ctx
);
28009 case MMI_OPC_CLASS_MMI3
:
28010 decode_mmi3(env
, ctx
);
28012 case MMI_OPC_MULT1
:
28013 case MMI_OPC_MULTU1
:
28015 case MMI_OPC_MADDU
:
28016 case MMI_OPC_MADD1
:
28017 case MMI_OPC_MADDU1
:
28018 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
28021 case MMI_OPC_DIVU1
:
28022 gen_div1_tx79(ctx
, opc
, rs
, rt
);
28024 case MMI_OPC_MTLO1
:
28025 case MMI_OPC_MTHI1
:
28026 gen_HILO1_tx79(ctx
, opc
, rs
);
28028 case MMI_OPC_MFLO1
:
28029 case MMI_OPC_MFHI1
:
28030 gen_HILO1_tx79(ctx
, opc
, rd
);
28032 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
28033 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
28034 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
28035 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
28036 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
28037 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
28038 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
28039 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
28040 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
28041 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI */
28044 MIPS_INVAL("TX79 MMI class");
28045 generate_exception_end(ctx
, EXCP_RI
);
28050 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
28052 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_LQ */
28055 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
28057 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_SQ */
28061 * The TX79-specific instruction Store Quadword
28063 * +--------+-------+-------+------------------------+
28064 * | 011111 | base | rt | offset | SQ
28065 * +--------+-------+-------+------------------------+
28068 * has the same opcode as the Read Hardware Register instruction
28070 * +--------+-------+-------+-------+-------+--------+
28071 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28072 * +--------+-------+-------+-------+-------+--------+
28075 * that is required, trapped and emulated by the Linux kernel. However, all
28076 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28077 * offset is odd. Therefore all valid SQ instructions can execute normally.
28078 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28079 * between SQ and RDHWR, as the Linux kernel does.
28081 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
28083 int base
= extract32(ctx
->opcode
, 21, 5);
28084 int rt
= extract32(ctx
->opcode
, 16, 5);
28085 int offset
= extract32(ctx
->opcode
, 0, 16);
28087 #ifdef CONFIG_USER_ONLY
28088 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
28089 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
28091 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
28092 int rd
= extract32(ctx
->opcode
, 11, 5);
28094 gen_rdhwr(ctx
, rt
, rd
, 0);
28099 gen_mmi_sq(ctx
, base
, rt
, offset
);
28104 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
28106 int rs
, rt
, rd
, sa
;
28110 rs
= (ctx
->opcode
>> 21) & 0x1f;
28111 rt
= (ctx
->opcode
>> 16) & 0x1f;
28112 rd
= (ctx
->opcode
>> 11) & 0x1f;
28113 sa
= (ctx
->opcode
>> 6) & 0x1f;
28114 imm
= sextract32(ctx
->opcode
, 7, 9);
28116 op1
= MASK_SPECIAL3(ctx
->opcode
);
28119 * EVA loads and stores overlap Loongson 2E instructions decoded by
28120 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28127 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
28135 check_cp0_enabled(ctx
);
28136 gen_ld(ctx
, op1
, rt
, rs
, imm
);
28140 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
28145 check_cp0_enabled(ctx
);
28146 gen_st(ctx
, op1
, rt
, rs
, imm
);
28149 check_cp0_enabled(ctx
);
28150 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
28153 check_cp0_enabled(ctx
);
28154 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28155 gen_cache_operation(ctx
, rt
, rs
, imm
);
28157 /* Treat as NOP. */
28160 check_cp0_enabled(ctx
);
28161 /* Treat as NOP. */
28169 check_insn(ctx
, ISA_MIPS32R2
);
28170 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28173 op2
= MASK_BSHFL(ctx
->opcode
);
28180 check_insn(ctx
, ISA_MIPS32R6
);
28181 decode_opc_special3_r6(env
, ctx
);
28184 check_insn(ctx
, ISA_MIPS32R2
);
28185 gen_bshfl(ctx
, op2
, rt
, rd
);
28189 #if defined(TARGET_MIPS64)
28196 check_insn(ctx
, ISA_MIPS64R2
);
28197 check_mips_64(ctx
);
28198 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28201 op2
= MASK_DBSHFL(ctx
->opcode
);
28212 check_insn(ctx
, ISA_MIPS32R6
);
28213 decode_opc_special3_r6(env
, ctx
);
28216 check_insn(ctx
, ISA_MIPS64R2
);
28217 check_mips_64(ctx
);
28218 op2
= MASK_DBSHFL(ctx
->opcode
);
28219 gen_bshfl(ctx
, op2
, rt
, rd
);
28225 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28230 TCGv t0
= tcg_temp_new();
28231 TCGv t1
= tcg_temp_new();
28233 gen_load_gpr(t0
, rt
);
28234 gen_load_gpr(t1
, rs
);
28235 gen_helper_fork(t0
, t1
);
28243 TCGv t0
= tcg_temp_new();
28245 gen_load_gpr(t0
, rs
);
28246 gen_helper_yield(t0
, cpu_env
, t0
);
28247 gen_store_gpr(t0
, rd
);
28252 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
28253 decode_opc_special3_r6(env
, ctx
);
28255 decode_opc_special3_legacy(env
, ctx
);
28260 /* MIPS SIMD Architecture (MSA) */
28261 static inline int check_msa_access(DisasContext
*ctx
)
28263 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
28264 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
28265 generate_exception_end(ctx
, EXCP_RI
);
28269 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
28270 if (ctx
->insn_flags
& ASE_MSA
) {
28271 generate_exception_end(ctx
, EXCP_MSADIS
);
28274 generate_exception_end(ctx
, EXCP_RI
);
28281 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
28283 /* generates tcg ops to check if any element is 0 */
28284 /* Note this function only works with MSA_WRLEN = 128 */
28285 uint64_t eval_zero_or_big
= 0;
28286 uint64_t eval_big
= 0;
28287 TCGv_i64 t0
= tcg_temp_new_i64();
28288 TCGv_i64 t1
= tcg_temp_new_i64();
28291 eval_zero_or_big
= 0x0101010101010101ULL
;
28292 eval_big
= 0x8080808080808080ULL
;
28295 eval_zero_or_big
= 0x0001000100010001ULL
;
28296 eval_big
= 0x8000800080008000ULL
;
28299 eval_zero_or_big
= 0x0000000100000001ULL
;
28300 eval_big
= 0x8000000080000000ULL
;
28303 eval_zero_or_big
= 0x0000000000000001ULL
;
28304 eval_big
= 0x8000000000000000ULL
;
28307 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<< 1], eval_zero_or_big
);
28308 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<< 1]);
28309 tcg_gen_andi_i64(t0
, t0
, eval_big
);
28310 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<< 1) + 1], eval_zero_or_big
);
28311 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<< 1) + 1]);
28312 tcg_gen_andi_i64(t1
, t1
, eval_big
);
28313 tcg_gen_or_i64(t0
, t0
, t1
);
28314 /* if all bits are zero then all elements are not zero */
28315 /* if some bit is non-zero then some element is zero */
28316 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
28317 tcg_gen_trunc_i64_tl(tresult
, t0
);
28318 tcg_temp_free_i64(t0
);
28319 tcg_temp_free_i64(t1
);
28322 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
28324 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28325 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28326 int64_t s16
= (int16_t)ctx
->opcode
;
28328 check_msa_access(ctx
);
28330 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
28331 generate_exception_end(ctx
, EXCP_RI
);
28338 TCGv_i64 t0
= tcg_temp_new_i64();
28339 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<< 1], msa_wr_d
[(wt
<< 1) + 1]);
28340 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
28341 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
28342 tcg_gen_trunc_i64_tl(bcond
, t0
);
28343 tcg_temp_free_i64(t0
);
28350 gen_check_zero_element(bcond
, df
, wt
);
28356 gen_check_zero_element(bcond
, df
, wt
);
28357 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
28361 ctx
->btarget
= ctx
->base
.pc_next
+ (s16
<< 2) + 4;
28363 ctx
->hflags
|= MIPS_HFLAG_BC
;
28364 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
28367 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
28369 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28370 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
28371 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28372 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28374 TCGv_i32 twd
= tcg_const_i32(wd
);
28375 TCGv_i32 tws
= tcg_const_i32(ws
);
28376 TCGv_i32 ti8
= tcg_const_i32(i8
);
28378 switch (MASK_MSA_I8(ctx
->opcode
)) {
28380 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
28383 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
28386 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
28389 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
28392 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
28395 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
28398 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
28404 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
28405 if (df
== DF_DOUBLE
) {
28406 generate_exception_end(ctx
, EXCP_RI
);
28408 TCGv_i32 tdf
= tcg_const_i32(df
);
28409 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
28410 tcg_temp_free_i32(tdf
);
28415 MIPS_INVAL("MSA instruction");
28416 generate_exception_end(ctx
, EXCP_RI
);
28420 tcg_temp_free_i32(twd
);
28421 tcg_temp_free_i32(tws
);
28422 tcg_temp_free_i32(ti8
);
28425 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
28427 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28428 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28429 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
28430 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
28431 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28432 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28434 TCGv_i32 tdf
= tcg_const_i32(df
);
28435 TCGv_i32 twd
= tcg_const_i32(wd
);
28436 TCGv_i32 tws
= tcg_const_i32(ws
);
28437 TCGv_i32 timm
= tcg_temp_new_i32();
28438 tcg_gen_movi_i32(timm
, u5
);
28440 switch (MASK_MSA_I5(ctx
->opcode
)) {
28442 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28445 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28447 case OPC_MAXI_S_df
:
28448 tcg_gen_movi_i32(timm
, s5
);
28449 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28451 case OPC_MAXI_U_df
:
28452 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28454 case OPC_MINI_S_df
:
28455 tcg_gen_movi_i32(timm
, s5
);
28456 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28458 case OPC_MINI_U_df
:
28459 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28462 tcg_gen_movi_i32(timm
, s5
);
28463 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28465 case OPC_CLTI_S_df
:
28466 tcg_gen_movi_i32(timm
, s5
);
28467 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28469 case OPC_CLTI_U_df
:
28470 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28472 case OPC_CLEI_S_df
:
28473 tcg_gen_movi_i32(timm
, s5
);
28474 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28476 case OPC_CLEI_U_df
:
28477 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28481 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
28482 tcg_gen_movi_i32(timm
, s10
);
28483 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
28487 MIPS_INVAL("MSA instruction");
28488 generate_exception_end(ctx
, EXCP_RI
);
28492 tcg_temp_free_i32(tdf
);
28493 tcg_temp_free_i32(twd
);
28494 tcg_temp_free_i32(tws
);
28495 tcg_temp_free_i32(timm
);
28498 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
28500 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28501 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
28502 uint32_t df
= 0, m
= 0;
28503 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28504 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28511 if ((dfm
& 0x40) == 0x00) {
28514 } else if ((dfm
& 0x60) == 0x40) {
28517 } else if ((dfm
& 0x70) == 0x60) {
28520 } else if ((dfm
& 0x78) == 0x70) {
28524 generate_exception_end(ctx
, EXCP_RI
);
28528 tdf
= tcg_const_i32(df
);
28529 tm
= tcg_const_i32(m
);
28530 twd
= tcg_const_i32(wd
);
28531 tws
= tcg_const_i32(ws
);
28533 switch (MASK_MSA_BIT(ctx
->opcode
)) {
28535 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28538 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
28541 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28544 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28547 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
28550 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
28552 case OPC_BINSLI_df
:
28553 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28555 case OPC_BINSRI_df
:
28556 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28559 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
28562 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
28565 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
28568 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28571 MIPS_INVAL("MSA instruction");
28572 generate_exception_end(ctx
, EXCP_RI
);
28576 tcg_temp_free_i32(tdf
);
28577 tcg_temp_free_i32(tm
);
28578 tcg_temp_free_i32(twd
);
28579 tcg_temp_free_i32(tws
);
28582 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
28584 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28585 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28586 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28587 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28588 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28590 TCGv_i32 tdf
= tcg_const_i32(df
);
28591 TCGv_i32 twd
= tcg_const_i32(wd
);
28592 TCGv_i32 tws
= tcg_const_i32(ws
);
28593 TCGv_i32 twt
= tcg_const_i32(wt
);
28595 switch (MASK_MSA_3R(ctx
->opcode
)) {
28599 gen_helper_msa_binsl_b(cpu_env
, twd
, tws
, twt
);
28602 gen_helper_msa_binsl_h(cpu_env
, twd
, tws
, twt
);
28605 gen_helper_msa_binsl_w(cpu_env
, twd
, tws
, twt
);
28608 gen_helper_msa_binsl_d(cpu_env
, twd
, tws
, twt
);
28615 gen_helper_msa_binsr_b(cpu_env
, twd
, tws
, twt
);
28618 gen_helper_msa_binsr_h(cpu_env
, twd
, tws
, twt
);
28621 gen_helper_msa_binsr_w(cpu_env
, twd
, tws
, twt
);
28624 gen_helper_msa_binsr_d(cpu_env
, twd
, tws
, twt
);
28631 gen_helper_msa_bclr_b(cpu_env
, twd
, tws
, twt
);
28634 gen_helper_msa_bclr_h(cpu_env
, twd
, tws
, twt
);
28637 gen_helper_msa_bclr_w(cpu_env
, twd
, tws
, twt
);
28640 gen_helper_msa_bclr_d(cpu_env
, twd
, tws
, twt
);
28647 gen_helper_msa_bneg_b(cpu_env
, twd
, tws
, twt
);
28650 gen_helper_msa_bneg_h(cpu_env
, twd
, tws
, twt
);
28653 gen_helper_msa_bneg_w(cpu_env
, twd
, tws
, twt
);
28656 gen_helper_msa_bneg_d(cpu_env
, twd
, tws
, twt
);
28663 gen_helper_msa_bset_b(cpu_env
, twd
, tws
, twt
);
28666 gen_helper_msa_bset_h(cpu_env
, twd
, tws
, twt
);
28669 gen_helper_msa_bset_w(cpu_env
, twd
, tws
, twt
);
28672 gen_helper_msa_bset_d(cpu_env
, twd
, tws
, twt
);
28679 gen_helper_msa_add_a_b(cpu_env
, twd
, tws
, twt
);
28682 gen_helper_msa_add_a_h(cpu_env
, twd
, tws
, twt
);
28685 gen_helper_msa_add_a_w(cpu_env
, twd
, tws
, twt
);
28688 gen_helper_msa_add_a_d(cpu_env
, twd
, tws
, twt
);
28692 case OPC_ADDS_A_df
:
28695 gen_helper_msa_adds_a_b(cpu_env
, twd
, tws
, twt
);
28698 gen_helper_msa_adds_a_h(cpu_env
, twd
, tws
, twt
);
28701 gen_helper_msa_adds_a_w(cpu_env
, twd
, tws
, twt
);
28704 gen_helper_msa_adds_a_d(cpu_env
, twd
, tws
, twt
);
28708 case OPC_ADDS_S_df
:
28711 gen_helper_msa_adds_s_b(cpu_env
, twd
, tws
, twt
);
28714 gen_helper_msa_adds_s_h(cpu_env
, twd
, tws
, twt
);
28717 gen_helper_msa_adds_s_w(cpu_env
, twd
, tws
, twt
);
28720 gen_helper_msa_adds_s_d(cpu_env
, twd
, tws
, twt
);
28724 case OPC_ADDS_U_df
:
28727 gen_helper_msa_adds_u_b(cpu_env
, twd
, tws
, twt
);
28730 gen_helper_msa_adds_u_h(cpu_env
, twd
, tws
, twt
);
28733 gen_helper_msa_adds_u_w(cpu_env
, twd
, tws
, twt
);
28736 gen_helper_msa_adds_u_d(cpu_env
, twd
, tws
, twt
);
28743 gen_helper_msa_addv_b(cpu_env
, twd
, tws
, twt
);
28746 gen_helper_msa_addv_h(cpu_env
, twd
, tws
, twt
);
28749 gen_helper_msa_addv_w(cpu_env
, twd
, tws
, twt
);
28752 gen_helper_msa_addv_d(cpu_env
, twd
, tws
, twt
);
28759 gen_helper_msa_ave_s_b(cpu_env
, twd
, tws
, twt
);
28762 gen_helper_msa_ave_s_h(cpu_env
, twd
, tws
, twt
);
28765 gen_helper_msa_ave_s_w(cpu_env
, twd
, tws
, twt
);
28768 gen_helper_msa_ave_s_d(cpu_env
, twd
, tws
, twt
);
28775 gen_helper_msa_ave_u_b(cpu_env
, twd
, tws
, twt
);
28778 gen_helper_msa_ave_u_h(cpu_env
, twd
, tws
, twt
);
28781 gen_helper_msa_ave_u_w(cpu_env
, twd
, tws
, twt
);
28784 gen_helper_msa_ave_u_d(cpu_env
, twd
, tws
, twt
);
28788 case OPC_AVER_S_df
:
28791 gen_helper_msa_aver_s_b(cpu_env
, twd
, tws
, twt
);
28794 gen_helper_msa_aver_s_h(cpu_env
, twd
, tws
, twt
);
28797 gen_helper_msa_aver_s_w(cpu_env
, twd
, tws
, twt
);
28800 gen_helper_msa_aver_s_d(cpu_env
, twd
, tws
, twt
);
28804 case OPC_AVER_U_df
:
28807 gen_helper_msa_aver_u_b(cpu_env
, twd
, tws
, twt
);
28810 gen_helper_msa_aver_u_h(cpu_env
, twd
, tws
, twt
);
28813 gen_helper_msa_aver_u_w(cpu_env
, twd
, tws
, twt
);
28816 gen_helper_msa_aver_u_d(cpu_env
, twd
, tws
, twt
);
28823 gen_helper_msa_ceq_b(cpu_env
, twd
, tws
, twt
);
28826 gen_helper_msa_ceq_h(cpu_env
, twd
, tws
, twt
);
28829 gen_helper_msa_ceq_w(cpu_env
, twd
, tws
, twt
);
28832 gen_helper_msa_ceq_d(cpu_env
, twd
, tws
, twt
);
28839 gen_helper_msa_cle_s_b(cpu_env
, twd
, tws
, twt
);
28842 gen_helper_msa_cle_s_h(cpu_env
, twd
, tws
, twt
);
28845 gen_helper_msa_cle_s_w(cpu_env
, twd
, tws
, twt
);
28848 gen_helper_msa_cle_s_d(cpu_env
, twd
, tws
, twt
);
28855 gen_helper_msa_cle_u_b(cpu_env
, twd
, tws
, twt
);
28858 gen_helper_msa_cle_u_h(cpu_env
, twd
, tws
, twt
);
28861 gen_helper_msa_cle_u_w(cpu_env
, twd
, tws
, twt
);
28864 gen_helper_msa_cle_u_d(cpu_env
, twd
, tws
, twt
);
28871 gen_helper_msa_clt_s_b(cpu_env
, twd
, tws
, twt
);
28874 gen_helper_msa_clt_s_h(cpu_env
, twd
, tws
, twt
);
28877 gen_helper_msa_clt_s_w(cpu_env
, twd
, tws
, twt
);
28880 gen_helper_msa_clt_s_d(cpu_env
, twd
, tws
, twt
);
28887 gen_helper_msa_clt_u_b(cpu_env
, twd
, tws
, twt
);
28890 gen_helper_msa_clt_u_h(cpu_env
, twd
, tws
, twt
);
28893 gen_helper_msa_clt_u_w(cpu_env
, twd
, tws
, twt
);
28896 gen_helper_msa_clt_u_d(cpu_env
, twd
, tws
, twt
);
28903 gen_helper_msa_div_s_b(cpu_env
, twd
, tws
, twt
);
28906 gen_helper_msa_div_s_h(cpu_env
, twd
, tws
, twt
);
28909 gen_helper_msa_div_s_w(cpu_env
, twd
, tws
, twt
);
28912 gen_helper_msa_div_s_d(cpu_env
, twd
, tws
, twt
);
28919 gen_helper_msa_div_u_b(cpu_env
, twd
, tws
, twt
);
28922 gen_helper_msa_div_u_h(cpu_env
, twd
, tws
, twt
);
28925 gen_helper_msa_div_u_w(cpu_env
, twd
, tws
, twt
);
28928 gen_helper_msa_div_u_d(cpu_env
, twd
, tws
, twt
);
28935 gen_helper_msa_max_a_b(cpu_env
, twd
, tws
, twt
);
28938 gen_helper_msa_max_a_h(cpu_env
, twd
, tws
, twt
);
28941 gen_helper_msa_max_a_w(cpu_env
, twd
, tws
, twt
);
28944 gen_helper_msa_max_a_d(cpu_env
, twd
, tws
, twt
);
28951 gen_helper_msa_max_s_b(cpu_env
, twd
, tws
, twt
);
28954 gen_helper_msa_max_s_h(cpu_env
, twd
, tws
, twt
);
28957 gen_helper_msa_max_s_w(cpu_env
, twd
, tws
, twt
);
28960 gen_helper_msa_max_s_d(cpu_env
, twd
, tws
, twt
);
28967 gen_helper_msa_max_u_b(cpu_env
, twd
, tws
, twt
);
28970 gen_helper_msa_max_u_h(cpu_env
, twd
, tws
, twt
);
28973 gen_helper_msa_max_u_w(cpu_env
, twd
, tws
, twt
);
28976 gen_helper_msa_max_u_d(cpu_env
, twd
, tws
, twt
);
28983 gen_helper_msa_min_a_b(cpu_env
, twd
, tws
, twt
);
28986 gen_helper_msa_min_a_h(cpu_env
, twd
, tws
, twt
);
28989 gen_helper_msa_min_a_w(cpu_env
, twd
, tws
, twt
);
28992 gen_helper_msa_min_a_d(cpu_env
, twd
, tws
, twt
);
28999 gen_helper_msa_min_s_b(cpu_env
, twd
, tws
, twt
);
29002 gen_helper_msa_min_s_h(cpu_env
, twd
, tws
, twt
);
29005 gen_helper_msa_min_s_w(cpu_env
, twd
, tws
, twt
);
29008 gen_helper_msa_min_s_d(cpu_env
, twd
, tws
, twt
);
29015 gen_helper_msa_min_u_b(cpu_env
, twd
, tws
, twt
);
29018 gen_helper_msa_min_u_h(cpu_env
, twd
, tws
, twt
);
29021 gen_helper_msa_min_u_w(cpu_env
, twd
, tws
, twt
);
29024 gen_helper_msa_min_u_d(cpu_env
, twd
, tws
, twt
);
29031 gen_helper_msa_mod_s_b(cpu_env
, twd
, tws
, twt
);
29034 gen_helper_msa_mod_s_h(cpu_env
, twd
, tws
, twt
);
29037 gen_helper_msa_mod_s_w(cpu_env
, twd
, tws
, twt
);
29040 gen_helper_msa_mod_s_d(cpu_env
, twd
, tws
, twt
);
29047 gen_helper_msa_mod_u_b(cpu_env
, twd
, tws
, twt
);
29050 gen_helper_msa_mod_u_h(cpu_env
, twd
, tws
, twt
);
29053 gen_helper_msa_mod_u_w(cpu_env
, twd
, tws
, twt
);
29056 gen_helper_msa_mod_u_d(cpu_env
, twd
, tws
, twt
);
29060 case OPC_ASUB_S_df
:
29063 gen_helper_msa_asub_s_b(cpu_env
, twd
, tws
, twt
);
29066 gen_helper_msa_asub_s_h(cpu_env
, twd
, tws
, twt
);
29069 gen_helper_msa_asub_s_w(cpu_env
, twd
, tws
, twt
);
29072 gen_helper_msa_asub_s_d(cpu_env
, twd
, tws
, twt
);
29076 case OPC_ASUB_U_df
:
29079 gen_helper_msa_asub_u_b(cpu_env
, twd
, tws
, twt
);
29082 gen_helper_msa_asub_u_h(cpu_env
, twd
, tws
, twt
);
29085 gen_helper_msa_asub_u_w(cpu_env
, twd
, tws
, twt
);
29088 gen_helper_msa_asub_u_d(cpu_env
, twd
, tws
, twt
);
29095 gen_helper_msa_ilvev_b(cpu_env
, twd
, tws
, twt
);
29098 gen_helper_msa_ilvev_h(cpu_env
, twd
, tws
, twt
);
29101 gen_helper_msa_ilvev_w(cpu_env
, twd
, tws
, twt
);
29104 gen_helper_msa_ilvev_d(cpu_env
, twd
, tws
, twt
);
29111 gen_helper_msa_ilvod_b(cpu_env
, twd
, tws
, twt
);
29114 gen_helper_msa_ilvod_h(cpu_env
, twd
, tws
, twt
);
29117 gen_helper_msa_ilvod_w(cpu_env
, twd
, tws
, twt
);
29120 gen_helper_msa_ilvod_d(cpu_env
, twd
, tws
, twt
);
29127 gen_helper_msa_ilvl_b(cpu_env
, twd
, tws
, twt
);
29130 gen_helper_msa_ilvl_h(cpu_env
, twd
, tws
, twt
);
29133 gen_helper_msa_ilvl_w(cpu_env
, twd
, tws
, twt
);
29136 gen_helper_msa_ilvl_d(cpu_env
, twd
, tws
, twt
);
29143 gen_helper_msa_ilvr_b(cpu_env
, twd
, tws
, twt
);
29146 gen_helper_msa_ilvr_h(cpu_env
, twd
, tws
, twt
);
29149 gen_helper_msa_ilvr_w(cpu_env
, twd
, tws
, twt
);
29152 gen_helper_msa_ilvr_d(cpu_env
, twd
, tws
, twt
);
29159 gen_helper_msa_pckev_b(cpu_env
, twd
, tws
, twt
);
29162 gen_helper_msa_pckev_h(cpu_env
, twd
, tws
, twt
);
29165 gen_helper_msa_pckev_w(cpu_env
, twd
, tws
, twt
);
29168 gen_helper_msa_pckev_d(cpu_env
, twd
, tws
, twt
);
29175 gen_helper_msa_pckod_b(cpu_env
, twd
, tws
, twt
);
29178 gen_helper_msa_pckod_h(cpu_env
, twd
, tws
, twt
);
29181 gen_helper_msa_pckod_w(cpu_env
, twd
, tws
, twt
);
29184 gen_helper_msa_pckod_d(cpu_env
, twd
, tws
, twt
);
29191 gen_helper_msa_sll_b(cpu_env
, twd
, tws
, twt
);
29194 gen_helper_msa_sll_h(cpu_env
, twd
, tws
, twt
);
29197 gen_helper_msa_sll_w(cpu_env
, twd
, tws
, twt
);
29200 gen_helper_msa_sll_d(cpu_env
, twd
, tws
, twt
);
29207 gen_helper_msa_sra_b(cpu_env
, twd
, tws
, twt
);
29210 gen_helper_msa_sra_h(cpu_env
, twd
, tws
, twt
);
29213 gen_helper_msa_sra_w(cpu_env
, twd
, tws
, twt
);
29216 gen_helper_msa_sra_d(cpu_env
, twd
, tws
, twt
);
29223 gen_helper_msa_srar_b(cpu_env
, twd
, tws
, twt
);
29226 gen_helper_msa_srar_h(cpu_env
, twd
, tws
, twt
);
29229 gen_helper_msa_srar_w(cpu_env
, twd
, tws
, twt
);
29232 gen_helper_msa_srar_d(cpu_env
, twd
, tws
, twt
);
29239 gen_helper_msa_srl_b(cpu_env
, twd
, tws
, twt
);
29242 gen_helper_msa_srl_h(cpu_env
, twd
, tws
, twt
);
29245 gen_helper_msa_srl_w(cpu_env
, twd
, tws
, twt
);
29248 gen_helper_msa_srl_d(cpu_env
, twd
, tws
, twt
);
29255 gen_helper_msa_srlr_b(cpu_env
, twd
, tws
, twt
);
29258 gen_helper_msa_srlr_h(cpu_env
, twd
, tws
, twt
);
29261 gen_helper_msa_srlr_w(cpu_env
, twd
, tws
, twt
);
29264 gen_helper_msa_srlr_d(cpu_env
, twd
, tws
, twt
);
29268 case OPC_SUBS_S_df
:
29269 gen_helper_msa_subs_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29272 gen_helper_msa_mulv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29275 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
29278 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29281 gen_helper_msa_subv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29283 case OPC_SUBS_U_df
:
29284 gen_helper_msa_subs_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29287 gen_helper_msa_maddv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29290 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
29292 case OPC_SUBSUS_U_df
:
29293 gen_helper_msa_subsus_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29296 gen_helper_msa_msubv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29298 case OPC_SUBSUU_S_df
:
29299 gen_helper_msa_subsuu_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29302 case OPC_DOTP_S_df
:
29303 case OPC_DOTP_U_df
:
29304 case OPC_DPADD_S_df
:
29305 case OPC_DPADD_U_df
:
29306 case OPC_DPSUB_S_df
:
29307 case OPC_HADD_S_df
:
29308 case OPC_DPSUB_U_df
:
29309 case OPC_HADD_U_df
:
29310 case OPC_HSUB_S_df
:
29311 case OPC_HSUB_U_df
:
29312 if (df
== DF_BYTE
) {
29313 generate_exception_end(ctx
, EXCP_RI
);
29316 switch (MASK_MSA_3R(ctx
->opcode
)) {
29317 case OPC_HADD_S_df
:
29320 gen_helper_msa_hadd_s_h(cpu_env
, twd
, tws
, twt
);
29323 gen_helper_msa_hadd_s_w(cpu_env
, twd
, tws
, twt
);
29326 gen_helper_msa_hadd_s_d(cpu_env
, twd
, tws
, twt
);
29330 case OPC_HADD_U_df
:
29333 gen_helper_msa_hadd_u_h(cpu_env
, twd
, tws
, twt
);
29336 gen_helper_msa_hadd_u_w(cpu_env
, twd
, tws
, twt
);
29339 gen_helper_msa_hadd_u_d(cpu_env
, twd
, tws
, twt
);
29343 case OPC_HSUB_S_df
:
29346 gen_helper_msa_hsub_s_h(cpu_env
, twd
, tws
, twt
);
29349 gen_helper_msa_hsub_s_w(cpu_env
, twd
, tws
, twt
);
29352 gen_helper_msa_hsub_s_d(cpu_env
, twd
, tws
, twt
);
29356 case OPC_HSUB_U_df
:
29359 gen_helper_msa_hsub_u_h(cpu_env
, twd
, tws
, twt
);
29362 gen_helper_msa_hsub_u_w(cpu_env
, twd
, tws
, twt
);
29365 gen_helper_msa_hsub_u_d(cpu_env
, twd
, tws
, twt
);
29369 case OPC_DOTP_S_df
:
29370 gen_helper_msa_dotp_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29372 case OPC_DOTP_U_df
:
29373 gen_helper_msa_dotp_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29375 case OPC_DPADD_S_df
:
29376 gen_helper_msa_dpadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29378 case OPC_DPADD_U_df
:
29379 gen_helper_msa_dpadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29381 case OPC_DPSUB_S_df
:
29382 gen_helper_msa_dpsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29384 case OPC_DPSUB_U_df
:
29385 gen_helper_msa_dpsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29390 MIPS_INVAL("MSA instruction");
29391 generate_exception_end(ctx
, EXCP_RI
);
29394 tcg_temp_free_i32(twd
);
29395 tcg_temp_free_i32(tws
);
29396 tcg_temp_free_i32(twt
);
29397 tcg_temp_free_i32(tdf
);
29400 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
29402 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29403 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
29404 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
29405 TCGv telm
= tcg_temp_new();
29406 TCGv_i32 tsr
= tcg_const_i32(source
);
29407 TCGv_i32 tdt
= tcg_const_i32(dest
);
29409 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
29411 gen_load_gpr(telm
, source
);
29412 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
29415 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
29416 gen_store_gpr(telm
, dest
);
29419 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
29422 MIPS_INVAL("MSA instruction");
29423 generate_exception_end(ctx
, EXCP_RI
);
29427 tcg_temp_free(telm
);
29428 tcg_temp_free_i32(tdt
);
29429 tcg_temp_free_i32(tsr
);
29432 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
29435 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29436 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29437 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29439 TCGv_i32 tws
= tcg_const_i32(ws
);
29440 TCGv_i32 twd
= tcg_const_i32(wd
);
29441 TCGv_i32 tn
= tcg_const_i32(n
);
29442 TCGv_i32 tdf
= tcg_const_i32(df
);
29444 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29446 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
29448 case OPC_SPLATI_df
:
29449 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
29452 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
29454 case OPC_COPY_S_df
:
29455 case OPC_COPY_U_df
:
29456 case OPC_INSERT_df
:
29457 #if !defined(TARGET_MIPS64)
29458 /* Double format valid only for MIPS64 */
29459 if (df
== DF_DOUBLE
) {
29460 generate_exception_end(ctx
, EXCP_RI
);
29463 if ((MASK_MSA_ELM(ctx
->opcode
) == OPC_COPY_U_df
) &&
29465 generate_exception_end(ctx
, EXCP_RI
);
29469 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29470 case OPC_COPY_S_df
:
29471 if (likely(wd
!= 0)) {
29474 gen_helper_msa_copy_s_b(cpu_env
, twd
, tws
, tn
);
29477 gen_helper_msa_copy_s_h(cpu_env
, twd
, tws
, tn
);
29480 gen_helper_msa_copy_s_w(cpu_env
, twd
, tws
, tn
);
29482 #if defined(TARGET_MIPS64)
29484 gen_helper_msa_copy_s_d(cpu_env
, twd
, tws
, tn
);
29492 case OPC_COPY_U_df
:
29493 if (likely(wd
!= 0)) {
29496 gen_helper_msa_copy_u_b(cpu_env
, twd
, tws
, tn
);
29499 gen_helper_msa_copy_u_h(cpu_env
, twd
, tws
, tn
);
29501 #if defined(TARGET_MIPS64)
29503 gen_helper_msa_copy_u_w(cpu_env
, twd
, tws
, tn
);
29511 case OPC_INSERT_df
:
29514 gen_helper_msa_insert_b(cpu_env
, twd
, tws
, tn
);
29517 gen_helper_msa_insert_h(cpu_env
, twd
, tws
, tn
);
29520 gen_helper_msa_insert_w(cpu_env
, twd
, tws
, tn
);
29522 #if defined(TARGET_MIPS64)
29524 gen_helper_msa_insert_d(cpu_env
, twd
, tws
, tn
);
29534 MIPS_INVAL("MSA instruction");
29535 generate_exception_end(ctx
, EXCP_RI
);
29537 tcg_temp_free_i32(twd
);
29538 tcg_temp_free_i32(tws
);
29539 tcg_temp_free_i32(tn
);
29540 tcg_temp_free_i32(tdf
);
29543 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
29545 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
29546 uint32_t df
= 0, n
= 0;
29548 if ((dfn
& 0x30) == 0x00) {
29551 } else if ((dfn
& 0x38) == 0x20) {
29554 } else if ((dfn
& 0x3c) == 0x30) {
29557 } else if ((dfn
& 0x3e) == 0x38) {
29560 } else if (dfn
== 0x3E) {
29561 /* CTCMSA, CFCMSA, MOVE.V */
29562 gen_msa_elm_3e(env
, ctx
);
29565 generate_exception_end(ctx
, EXCP_RI
);
29569 gen_msa_elm_df(env
, ctx
, df
, n
);
29572 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
29574 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29575 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
29576 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29577 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29578 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29580 TCGv_i32 twd
= tcg_const_i32(wd
);
29581 TCGv_i32 tws
= tcg_const_i32(ws
);
29582 TCGv_i32 twt
= tcg_const_i32(wt
);
29583 TCGv_i32 tdf
= tcg_temp_new_i32();
29585 /* adjust df value for floating-point instruction */
29586 tcg_gen_movi_i32(tdf
, df
+ 2);
29588 switch (MASK_MSA_3RF(ctx
->opcode
)) {
29590 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29593 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
29596 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
29599 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
29602 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
29605 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29608 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
29611 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
29614 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29617 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29620 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
29623 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
29626 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
29629 tcg_gen_movi_i32(tdf
, df
+ 1);
29630 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29633 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
29636 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
29638 case OPC_MADD_Q_df
:
29639 tcg_gen_movi_i32(tdf
, df
+ 1);
29640 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29643 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
29645 case OPC_MSUB_Q_df
:
29646 tcg_gen_movi_i32(tdf
, df
+ 1);
29647 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29650 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
29653 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
29656 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29659 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
29662 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
29665 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
29668 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29671 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29674 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
29677 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29680 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
29683 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
29686 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
29688 case OPC_MULR_Q_df
:
29689 tcg_gen_movi_i32(tdf
, df
+ 1);
29690 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29693 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
29695 case OPC_FMIN_A_df
:
29696 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
29698 case OPC_MADDR_Q_df
:
29699 tcg_gen_movi_i32(tdf
, df
+ 1);
29700 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29703 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
29706 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
29708 case OPC_MSUBR_Q_df
:
29709 tcg_gen_movi_i32(tdf
, df
+ 1);
29710 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29713 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
29715 case OPC_FMAX_A_df
:
29716 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
29719 MIPS_INVAL("MSA instruction");
29720 generate_exception_end(ctx
, EXCP_RI
);
29724 tcg_temp_free_i32(twd
);
29725 tcg_temp_free_i32(tws
);
29726 tcg_temp_free_i32(twt
);
29727 tcg_temp_free_i32(tdf
);
29730 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
29732 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29733 (op & (0x7 << 18)))
29734 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29735 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29736 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29737 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
29738 TCGv_i32 twd
= tcg_const_i32(wd
);
29739 TCGv_i32 tws
= tcg_const_i32(ws
);
29740 TCGv_i32 twt
= tcg_const_i32(wt
);
29741 TCGv_i32 tdf
= tcg_const_i32(df
);
29743 switch (MASK_MSA_2R(ctx
->opcode
)) {
29745 #if !defined(TARGET_MIPS64)
29746 /* Double format valid only for MIPS64 */
29747 if (df
== DF_DOUBLE
) {
29748 generate_exception_end(ctx
, EXCP_RI
);
29752 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
29757 gen_helper_msa_nloc_b(cpu_env
, twd
, tws
);
29760 gen_helper_msa_nloc_h(cpu_env
, twd
, tws
);
29763 gen_helper_msa_nloc_w(cpu_env
, twd
, tws
);
29766 gen_helper_msa_nloc_d(cpu_env
, twd
, tws
);
29773 gen_helper_msa_nlzc_b(cpu_env
, twd
, tws
);
29776 gen_helper_msa_nlzc_h(cpu_env
, twd
, tws
);
29779 gen_helper_msa_nlzc_w(cpu_env
, twd
, tws
);
29782 gen_helper_msa_nlzc_d(cpu_env
, twd
, tws
);
29789 gen_helper_msa_pcnt_b(cpu_env
, twd
, tws
);
29792 gen_helper_msa_pcnt_h(cpu_env
, twd
, tws
);
29795 gen_helper_msa_pcnt_w(cpu_env
, twd
, tws
);
29798 gen_helper_msa_pcnt_d(cpu_env
, twd
, tws
);
29803 MIPS_INVAL("MSA instruction");
29804 generate_exception_end(ctx
, EXCP_RI
);
29808 tcg_temp_free_i32(twd
);
29809 tcg_temp_free_i32(tws
);
29810 tcg_temp_free_i32(twt
);
29811 tcg_temp_free_i32(tdf
);
29814 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
29816 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29817 (op & (0xf << 17)))
29818 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29819 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29820 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29821 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
29822 TCGv_i32 twd
= tcg_const_i32(wd
);
29823 TCGv_i32 tws
= tcg_const_i32(ws
);
29824 TCGv_i32 twt
= tcg_const_i32(wt
);
29825 /* adjust df value for floating-point instruction */
29826 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
29828 switch (MASK_MSA_2RF(ctx
->opcode
)) {
29829 case OPC_FCLASS_df
:
29830 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
29832 case OPC_FTRUNC_S_df
:
29833 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
29835 case OPC_FTRUNC_U_df
:
29836 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
29839 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
29841 case OPC_FRSQRT_df
:
29842 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
29845 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
29848 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
29851 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
29853 case OPC_FEXUPL_df
:
29854 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
29856 case OPC_FEXUPR_df
:
29857 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
29860 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
29863 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
29865 case OPC_FTINT_S_df
:
29866 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
29868 case OPC_FTINT_U_df
:
29869 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
29871 case OPC_FFINT_S_df
:
29872 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
29874 case OPC_FFINT_U_df
:
29875 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
29879 tcg_temp_free_i32(twd
);
29880 tcg_temp_free_i32(tws
);
29881 tcg_temp_free_i32(twt
);
29882 tcg_temp_free_i32(tdf
);
29885 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
29887 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
29888 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29889 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29890 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29891 TCGv_i32 twd
= tcg_const_i32(wd
);
29892 TCGv_i32 tws
= tcg_const_i32(ws
);
29893 TCGv_i32 twt
= tcg_const_i32(wt
);
29895 switch (MASK_MSA_VEC(ctx
->opcode
)) {
29897 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
29900 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
29903 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
29906 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
29909 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
29912 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
29915 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
29918 MIPS_INVAL("MSA instruction");
29919 generate_exception_end(ctx
, EXCP_RI
);
29923 tcg_temp_free_i32(twd
);
29924 tcg_temp_free_i32(tws
);
29925 tcg_temp_free_i32(twt
);
29928 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
29930 switch (MASK_MSA_VEC(ctx
->opcode
)) {
29938 gen_msa_vec_v(env
, ctx
);
29941 gen_msa_2r(env
, ctx
);
29944 gen_msa_2rf(env
, ctx
);
29947 MIPS_INVAL("MSA instruction");
29948 generate_exception_end(ctx
, EXCP_RI
);
29953 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
29955 uint32_t opcode
= ctx
->opcode
;
29956 check_insn(ctx
, ASE_MSA
);
29957 check_msa_access(ctx
);
29959 switch (MASK_MSA_MINOR(opcode
)) {
29960 case OPC_MSA_I8_00
:
29961 case OPC_MSA_I8_01
:
29962 case OPC_MSA_I8_02
:
29963 gen_msa_i8(env
, ctx
);
29965 case OPC_MSA_I5_06
:
29966 case OPC_MSA_I5_07
:
29967 gen_msa_i5(env
, ctx
);
29969 case OPC_MSA_BIT_09
:
29970 case OPC_MSA_BIT_0A
:
29971 gen_msa_bit(env
, ctx
);
29973 case OPC_MSA_3R_0D
:
29974 case OPC_MSA_3R_0E
:
29975 case OPC_MSA_3R_0F
:
29976 case OPC_MSA_3R_10
:
29977 case OPC_MSA_3R_11
:
29978 case OPC_MSA_3R_12
:
29979 case OPC_MSA_3R_13
:
29980 case OPC_MSA_3R_14
:
29981 case OPC_MSA_3R_15
:
29982 gen_msa_3r(env
, ctx
);
29985 gen_msa_elm(env
, ctx
);
29987 case OPC_MSA_3RF_1A
:
29988 case OPC_MSA_3RF_1B
:
29989 case OPC_MSA_3RF_1C
:
29990 gen_msa_3rf(env
, ctx
);
29993 gen_msa_vec(env
, ctx
);
30004 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
30005 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
30006 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30007 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
30009 TCGv_i32 twd
= tcg_const_i32(wd
);
30010 TCGv taddr
= tcg_temp_new();
30011 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
30013 switch (MASK_MSA_MINOR(opcode
)) {
30015 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
30018 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
30021 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
30024 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
30027 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
30030 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
30033 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
30036 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
30040 tcg_temp_free_i32(twd
);
30041 tcg_temp_free(taddr
);
30045 MIPS_INVAL("MSA instruction");
30046 generate_exception_end(ctx
, EXCP_RI
);
30052 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
30055 int rs
, rt
, rd
, sa
;
30059 /* make sure instructions are on a word boundary */
30060 if (ctx
->base
.pc_next
& 0x3) {
30061 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
30062 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
30066 /* Handle blikely not taken case */
30067 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
30068 TCGLabel
*l1
= gen_new_label();
30070 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
30071 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
30072 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
30076 op
= MASK_OP_MAJOR(ctx
->opcode
);
30077 rs
= (ctx
->opcode
>> 21) & 0x1f;
30078 rt
= (ctx
->opcode
>> 16) & 0x1f;
30079 rd
= (ctx
->opcode
>> 11) & 0x1f;
30080 sa
= (ctx
->opcode
>> 6) & 0x1f;
30081 imm
= (int16_t)ctx
->opcode
;
30084 decode_opc_special(env
, ctx
);
30087 #if defined(TARGET_MIPS64)
30088 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
30089 decode_mmi(env
, ctx
);
30091 if (ctx
->insn_flags
& ASE_MXU
) {
30092 decode_opc_mxu(env
, ctx
);
30095 decode_opc_special2_legacy(env
, ctx
);
30099 #if defined(TARGET_MIPS64)
30100 if (ctx
->insn_flags
& INSN_R5900
) {
30101 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
30103 decode_opc_special3(env
, ctx
);
30106 decode_opc_special3(env
, ctx
);
30110 op1
= MASK_REGIMM(ctx
->opcode
);
30112 case OPC_BLTZL
: /* REGIMM branches */
30116 check_insn(ctx
, ISA_MIPS2
);
30117 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30121 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30125 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30127 /* OPC_NAL, OPC_BAL */
30128 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
30130 generate_exception_end(ctx
, EXCP_RI
);
30133 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30136 case OPC_TGEI
: /* REGIMM traps */
30143 check_insn(ctx
, ISA_MIPS2
);
30144 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30145 gen_trap(ctx
, op1
, rs
, -1, imm
);
30148 check_insn(ctx
, ISA_MIPS32R6
);
30149 generate_exception_end(ctx
, EXCP_RI
);
30152 check_insn(ctx
, ISA_MIPS32R2
);
30154 * Break the TB to be able to sync copied instructions
30157 ctx
->base
.is_jmp
= DISAS_STOP
;
30159 case OPC_BPOSGE32
: /* MIPS DSP branch */
30160 #if defined(TARGET_MIPS64)
30164 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
30166 #if defined(TARGET_MIPS64)
30168 check_insn(ctx
, ISA_MIPS32R6
);
30169 check_mips_64(ctx
);
30171 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
30175 check_insn(ctx
, ISA_MIPS32R6
);
30176 check_mips_64(ctx
);
30178 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
30182 default: /* Invalid */
30183 MIPS_INVAL("regimm");
30184 generate_exception_end(ctx
, EXCP_RI
);
30189 check_cp0_enabled(ctx
);
30190 op1
= MASK_CP0(ctx
->opcode
);
30198 #if defined(TARGET_MIPS64)
30202 #ifndef CONFIG_USER_ONLY
30203 gen_cp0(env
, ctx
, op1
, rt
, rd
);
30204 #endif /* !CONFIG_USER_ONLY */
30222 #ifndef CONFIG_USER_ONLY
30223 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
30224 #endif /* !CONFIG_USER_ONLY */
30227 #ifndef CONFIG_USER_ONLY
30230 TCGv t0
= tcg_temp_new();
30232 op2
= MASK_MFMC0(ctx
->opcode
);
30236 gen_helper_dmt(t0
);
30237 gen_store_gpr(t0
, rt
);
30241 gen_helper_emt(t0
);
30242 gen_store_gpr(t0
, rt
);
30246 gen_helper_dvpe(t0
, cpu_env
);
30247 gen_store_gpr(t0
, rt
);
30251 gen_helper_evpe(t0
, cpu_env
);
30252 gen_store_gpr(t0
, rt
);
30255 check_insn(ctx
, ISA_MIPS32R6
);
30257 gen_helper_dvp(t0
, cpu_env
);
30258 gen_store_gpr(t0
, rt
);
30262 check_insn(ctx
, ISA_MIPS32R6
);
30264 gen_helper_evp(t0
, cpu_env
);
30265 gen_store_gpr(t0
, rt
);
30269 check_insn(ctx
, ISA_MIPS32R2
);
30270 save_cpu_state(ctx
, 1);
30271 gen_helper_di(t0
, cpu_env
);
30272 gen_store_gpr(t0
, rt
);
30274 * Stop translation as we may have switched
30275 * the execution mode.
30277 ctx
->base
.is_jmp
= DISAS_STOP
;
30280 check_insn(ctx
, ISA_MIPS32R2
);
30281 save_cpu_state(ctx
, 1);
30282 gen_helper_ei(t0
, cpu_env
);
30283 gen_store_gpr(t0
, rt
);
30285 * DISAS_STOP isn't sufficient, we need to ensure we break
30286 * out of translated code to check for pending interrupts.
30288 gen_save_pc(ctx
->base
.pc_next
+ 4);
30289 ctx
->base
.is_jmp
= DISAS_EXIT
;
30291 default: /* Invalid */
30292 MIPS_INVAL("mfmc0");
30293 generate_exception_end(ctx
, EXCP_RI
);
30298 #endif /* !CONFIG_USER_ONLY */
30301 check_insn(ctx
, ISA_MIPS32R2
);
30302 gen_load_srsgpr(rt
, rd
);
30305 check_insn(ctx
, ISA_MIPS32R2
);
30306 gen_store_srsgpr(rt
, rd
);
30310 generate_exception_end(ctx
, EXCP_RI
);
30314 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30315 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30316 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30317 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30320 /* Arithmetic with immediate opcode */
30321 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30325 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30327 case OPC_SLTI
: /* Set on less than with immediate opcode */
30329 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
30331 case OPC_ANDI
: /* Arithmetic with immediate opcode */
30332 case OPC_LUI
: /* OPC_AUI */
30335 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
30337 case OPC_J
: /* Jump */
30339 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30340 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30343 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30344 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30346 generate_exception_end(ctx
, EXCP_RI
);
30349 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30350 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30353 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30356 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30357 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30359 generate_exception_end(ctx
, EXCP_RI
);
30362 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30363 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30366 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30369 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30372 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30374 check_insn(ctx
, ISA_MIPS32R6
);
30375 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30376 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30379 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30382 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30384 check_insn(ctx
, ISA_MIPS32R6
);
30385 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30386 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30391 check_insn(ctx
, ISA_MIPS2
);
30392 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30396 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30398 case OPC_LL
: /* Load and stores */
30399 check_insn(ctx
, ISA_MIPS2
);
30400 if (ctx
->insn_flags
& INSN_R5900
) {
30401 check_insn_opc_user_only(ctx
, INSN_R5900
);
30406 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30414 gen_ld(ctx
, op
, rt
, rs
, imm
);
30418 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30423 gen_st(ctx
, op
, rt
, rs
, imm
);
30426 check_insn(ctx
, ISA_MIPS2
);
30427 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30428 if (ctx
->insn_flags
& INSN_R5900
) {
30429 check_insn_opc_user_only(ctx
, INSN_R5900
);
30431 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
30434 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30435 check_cp0_enabled(ctx
);
30436 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
30437 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
30438 gen_cache_operation(ctx
, rt
, rs
, imm
);
30440 /* Treat as NOP. */
30443 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30444 if (ctx
->insn_flags
& INSN_R5900
) {
30445 /* Treat as NOP. */
30447 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
30448 /* Treat as NOP. */
30452 /* Floating point (COP1). */
30457 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
30461 op1
= MASK_CP1(ctx
->opcode
);
30466 check_cp1_enabled(ctx
);
30467 check_insn(ctx
, ISA_MIPS32R2
);
30473 check_cp1_enabled(ctx
);
30474 gen_cp1(ctx
, op1
, rt
, rd
);
30476 #if defined(TARGET_MIPS64)
30479 check_cp1_enabled(ctx
);
30480 check_insn(ctx
, ISA_MIPS3
);
30481 check_mips_64(ctx
);
30482 gen_cp1(ctx
, op1
, rt
, rd
);
30485 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
30486 check_cp1_enabled(ctx
);
30487 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30489 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
30494 check_insn(ctx
, ASE_MIPS3D
);
30495 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
30496 (rt
>> 2) & 0x7, imm
<< 2);
30500 check_cp1_enabled(ctx
);
30501 check_insn(ctx
, ISA_MIPS32R6
);
30502 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
30506 check_cp1_enabled(ctx
);
30507 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30509 check_insn(ctx
, ASE_MIPS3D
);
30512 check_cp1_enabled(ctx
);
30513 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30514 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
30515 (rt
>> 2) & 0x7, imm
<< 2);
30522 check_cp1_enabled(ctx
);
30523 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
30529 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
30530 check_cp1_enabled(ctx
);
30531 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30533 case R6_OPC_CMP_AF_S
:
30534 case R6_OPC_CMP_UN_S
:
30535 case R6_OPC_CMP_EQ_S
:
30536 case R6_OPC_CMP_UEQ_S
:
30537 case R6_OPC_CMP_LT_S
:
30538 case R6_OPC_CMP_ULT_S
:
30539 case R6_OPC_CMP_LE_S
:
30540 case R6_OPC_CMP_ULE_S
:
30541 case R6_OPC_CMP_SAF_S
:
30542 case R6_OPC_CMP_SUN_S
:
30543 case R6_OPC_CMP_SEQ_S
:
30544 case R6_OPC_CMP_SEUQ_S
:
30545 case R6_OPC_CMP_SLT_S
:
30546 case R6_OPC_CMP_SULT_S
:
30547 case R6_OPC_CMP_SLE_S
:
30548 case R6_OPC_CMP_SULE_S
:
30549 case R6_OPC_CMP_OR_S
:
30550 case R6_OPC_CMP_UNE_S
:
30551 case R6_OPC_CMP_NE_S
:
30552 case R6_OPC_CMP_SOR_S
:
30553 case R6_OPC_CMP_SUNE_S
:
30554 case R6_OPC_CMP_SNE_S
:
30555 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
30557 case R6_OPC_CMP_AF_D
:
30558 case R6_OPC_CMP_UN_D
:
30559 case R6_OPC_CMP_EQ_D
:
30560 case R6_OPC_CMP_UEQ_D
:
30561 case R6_OPC_CMP_LT_D
:
30562 case R6_OPC_CMP_ULT_D
:
30563 case R6_OPC_CMP_LE_D
:
30564 case R6_OPC_CMP_ULE_D
:
30565 case R6_OPC_CMP_SAF_D
:
30566 case R6_OPC_CMP_SUN_D
:
30567 case R6_OPC_CMP_SEQ_D
:
30568 case R6_OPC_CMP_SEUQ_D
:
30569 case R6_OPC_CMP_SLT_D
:
30570 case R6_OPC_CMP_SULT_D
:
30571 case R6_OPC_CMP_SLE_D
:
30572 case R6_OPC_CMP_SULE_D
:
30573 case R6_OPC_CMP_OR_D
:
30574 case R6_OPC_CMP_UNE_D
:
30575 case R6_OPC_CMP_NE_D
:
30576 case R6_OPC_CMP_SOR_D
:
30577 case R6_OPC_CMP_SUNE_D
:
30578 case R6_OPC_CMP_SNE_D
:
30579 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
30582 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
30583 rt
, rd
, sa
, (imm
>> 8) & 0x7);
30588 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
30603 check_insn(ctx
, ASE_MSA
);
30604 gen_msa_branch(env
, ctx
, op1
);
30608 generate_exception_end(ctx
, EXCP_RI
);
30613 /* Compact branches [R6] and COP2 [non-R6] */
30614 case OPC_BC
: /* OPC_LWC2 */
30615 case OPC_BALC
: /* OPC_SWC2 */
30616 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30617 /* OPC_BC, OPC_BALC */
30618 gen_compute_compact_branch(ctx
, op
, 0, 0,
30619 sextract32(ctx
->opcode
<< 2, 0, 28));
30621 /* OPC_LWC2, OPC_SWC2 */
30622 /* COP2: Not implemented. */
30623 generate_exception_err(ctx
, EXCP_CpU
, 2);
30626 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
30627 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
30628 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30630 /* OPC_BEQZC, OPC_BNEZC */
30631 gen_compute_compact_branch(ctx
, op
, rs
, 0,
30632 sextract32(ctx
->opcode
<< 2, 0, 23));
30634 /* OPC_JIC, OPC_JIALC */
30635 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
30638 /* OPC_LWC2, OPC_SWC2 */
30639 /* COP2: Not implemented. */
30640 generate_exception_err(ctx
, EXCP_CpU
, 2);
30644 check_insn(ctx
, INSN_LOONGSON2F
);
30645 /* Note that these instructions use different fields. */
30646 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
30650 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30651 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
30652 check_cp1_enabled(ctx
);
30653 op1
= MASK_CP3(ctx
->opcode
);
30657 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
30663 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30664 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
30667 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30668 /* Treat as NOP. */
30671 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
30685 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30686 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
30690 generate_exception_end(ctx
, EXCP_RI
);
30694 generate_exception_err(ctx
, EXCP_CpU
, 1);
30698 #if defined(TARGET_MIPS64)
30699 /* MIPS64 opcodes */
30701 if (ctx
->insn_flags
& INSN_R5900
) {
30702 check_insn_opc_user_only(ctx
, INSN_R5900
);
30707 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30711 check_insn(ctx
, ISA_MIPS3
);
30712 check_mips_64(ctx
);
30713 gen_ld(ctx
, op
, rt
, rs
, imm
);
30717 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30720 check_insn(ctx
, ISA_MIPS3
);
30721 check_mips_64(ctx
);
30722 gen_st(ctx
, op
, rt
, rs
, imm
);
30725 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30726 check_insn(ctx
, ISA_MIPS3
);
30727 if (ctx
->insn_flags
& INSN_R5900
) {
30728 check_insn_opc_user_only(ctx
, INSN_R5900
);
30730 check_mips_64(ctx
);
30731 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
30733 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
30734 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30735 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
30736 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30739 check_insn(ctx
, ISA_MIPS3
);
30740 check_mips_64(ctx
);
30741 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30745 check_insn(ctx
, ISA_MIPS3
);
30746 check_mips_64(ctx
);
30747 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30750 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
30751 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30752 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30754 MIPS_INVAL("major opcode");
30755 generate_exception_end(ctx
, EXCP_RI
);
30759 case OPC_DAUI
: /* OPC_JALX */
30760 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30761 #if defined(TARGET_MIPS64)
30763 check_mips_64(ctx
);
30765 generate_exception(ctx
, EXCP_RI
);
30766 } else if (rt
!= 0) {
30767 TCGv t0
= tcg_temp_new();
30768 gen_load_gpr(t0
, rs
);
30769 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
30773 generate_exception_end(ctx
, EXCP_RI
);
30774 MIPS_INVAL("major opcode");
30778 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
30779 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30780 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30783 case OPC_MSA
: /* OPC_MDMX */
30784 if (ctx
->insn_flags
& INSN_R5900
) {
30785 #if defined(TARGET_MIPS64)
30786 gen_mmi_lq(env
, ctx
); /* MMI_OPC_LQ */
30789 /* MDMX: Not implemented. */
30794 check_insn(ctx
, ISA_MIPS32R6
);
30795 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
30797 default: /* Invalid */
30798 MIPS_INVAL("major opcode");
30799 generate_exception_end(ctx
, EXCP_RI
);
30804 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
30806 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30807 CPUMIPSState
*env
= cs
->env_ptr
;
30809 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
30810 ctx
->saved_pc
= -1;
30811 ctx
->insn_flags
= env
->insn_flags
;
30812 ctx
->CP0_Config1
= env
->CP0_Config1
;
30813 ctx
->CP0_Config2
= env
->CP0_Config2
;
30814 ctx
->CP0_Config3
= env
->CP0_Config3
;
30815 ctx
->CP0_Config5
= env
->CP0_Config5
;
30817 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
30818 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
30819 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
30820 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
30821 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
30822 ctx
->PAMask
= env
->PAMask
;
30823 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
30824 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
30825 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
30826 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
30827 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
30828 /* Restore delay slot state from the tb context. */
30829 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
30830 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
30831 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
30832 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
30833 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
30834 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
30835 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
30836 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
30837 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
30838 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
30839 restore_cpu_state(env
, ctx
);
30840 #ifdef CONFIG_USER_ONLY
30841 ctx
->mem_idx
= MIPS_HFLAG_UM
;
30843 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
30845 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& ISA_MIPS32R6
) ?
30846 MO_UNALN
: MO_ALIGN
;
30848 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
30852 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
30856 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
30858 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30860 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
30864 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
30865 const CPUBreakpoint
*bp
)
30867 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30869 save_cpu_state(ctx
, 1);
30870 ctx
->base
.is_jmp
= DISAS_NORETURN
;
30871 gen_helper_raise_exception_debug(cpu_env
);
30873 * The address covered by the breakpoint must be included in
30874 * [tb->pc, tb->pc + tb->size) in order to for it to be
30875 * properly cleared -- thus we increment the PC here so that
30876 * the logic setting tb->size below does the right thing.
30878 ctx
->base
.pc_next
+= 4;
30882 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
30884 CPUMIPSState
*env
= cs
->env_ptr
;
30885 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30889 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
30890 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
30891 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30892 insn_bytes
= decode_nanomips_opc(env
, ctx
);
30893 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
30894 ctx
->opcode
= cpu_ldl_code(env
, ctx
->base
.pc_next
);
30896 decode_opc(env
, ctx
);
30897 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
30898 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30899 insn_bytes
= decode_micromips_opc(env
, ctx
);
30900 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
30901 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30902 insn_bytes
= decode_mips16_opc(env
, ctx
);
30904 generate_exception_end(ctx
, EXCP_RI
);
30905 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
30909 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
30910 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
30911 MIPS_HFLAG_FBNSLOT
))) {
30913 * Force to generate branch as there is neither delay nor
30918 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
30919 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
30921 * Force to generate branch as microMIPS R6 doesn't restrict
30922 * branches in the forbidden slot.
30928 gen_branch(ctx
, insn_bytes
);
30930 ctx
->base
.pc_next
+= insn_bytes
;
30932 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
30936 * Execute a branch and its delay slot as a single instruction.
30937 * This is what GDB expects and is consistent with what the
30938 * hardware does (e.g. if a delay slot instruction faults, the
30939 * reported PC is the PC of the branch).
30941 if (ctx
->base
.singlestep_enabled
&&
30942 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
30943 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
30945 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
30946 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
30950 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
30952 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30954 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
30955 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
30956 gen_helper_raise_exception_debug(cpu_env
);
30958 switch (ctx
->base
.is_jmp
) {
30960 gen_save_pc(ctx
->base
.pc_next
);
30961 tcg_gen_lookup_and_goto_ptr();
30964 case DISAS_TOO_MANY
:
30965 save_cpu_state(ctx
, 0);
30966 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
30969 tcg_gen_exit_tb(NULL
, 0);
30971 case DISAS_NORETURN
:
30974 g_assert_not_reached();
30979 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
30981 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
30982 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
30985 static const TranslatorOps mips_tr_ops
= {
30986 .init_disas_context
= mips_tr_init_disas_context
,
30987 .tb_start
= mips_tr_tb_start
,
30988 .insn_start
= mips_tr_insn_start
,
30989 .breakpoint_check
= mips_tr_breakpoint_check
,
30990 .translate_insn
= mips_tr_translate_insn
,
30991 .tb_stop
= mips_tr_tb_stop
,
30992 .disas_log
= mips_tr_disas_log
,
30995 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
30999 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
31002 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
31005 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
31007 #define printfpr(fp) \
31010 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31011 " fd:%13g fs:%13g psu: %13g\n", \
31012 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
31013 (double)(fp)->fd, \
31014 (double)(fp)->fs[FP_ENDIAN_IDX], \
31015 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
31018 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
31019 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
31020 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31021 " fd:%13g fs:%13g psu:%13g\n", \
31022 tmp.w[FP_ENDIAN_IDX], tmp.d, \
31024 (double)tmp.fs[FP_ENDIAN_IDX], \
31025 (double)tmp.fs[!FP_ENDIAN_IDX]); \
31031 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
31032 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
31033 get_float_exception_flags(&env
->active_fpu
.fp_status
));
31034 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
31035 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
31036 printfpr(&env
->active_fpu
.fpr
[i
]);
31042 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
31044 MIPSCPU
*cpu
= MIPS_CPU(cs
);
31045 CPUMIPSState
*env
= &cpu
->env
;
31048 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
31049 " LO=0x" TARGET_FMT_lx
" ds %04x "
31050 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
31051 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
31052 env
->hflags
, env
->btarget
, env
->bcond
);
31053 for (i
= 0; i
< 32; i
++) {
31054 if ((i
& 3) == 0) {
31055 qemu_fprintf(f
, "GPR%02d:", i
);
31057 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
31058 regnames
[i
], env
->active_tc
.gpr
[i
]);
31059 if ((i
& 3) == 3) {
31060 qemu_fprintf(f
, "\n");
31064 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
31065 TARGET_FMT_lx
"\n",
31066 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
31067 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
31069 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
31070 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
31071 env
->CP0_Config2
, env
->CP0_Config3
);
31072 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
31073 env
->CP0_Config4
, env
->CP0_Config5
);
31074 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
31075 fpu_dump_state(env
, f
, flags
);
31079 void mips_tcg_init(void)
31084 for (i
= 1; i
< 32; i
++)
31085 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31086 offsetof(CPUMIPSState
,
31090 for (i
= 0; i
< 32; i
++) {
31091 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
31093 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
31095 * The scalar floating-point unit (FPU) registers are mapped on
31096 * the MSA vector registers.
31098 fpu_f64
[i
] = msa_wr_d
[i
* 2];
31099 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
31100 msa_wr_d
[i
* 2 + 1] =
31101 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
31104 cpu_PC
= tcg_global_mem_new(cpu_env
,
31105 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
31106 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
31107 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
31108 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
31110 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
31111 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
31114 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
31115 offsetof(CPUMIPSState
,
31116 active_tc
.DSPControl
),
31118 bcond
= tcg_global_mem_new(cpu_env
,
31119 offsetof(CPUMIPSState
, bcond
), "bcond");
31120 btarget
= tcg_global_mem_new(cpu_env
,
31121 offsetof(CPUMIPSState
, btarget
), "btarget");
31122 hflags
= tcg_global_mem_new_i32(cpu_env
,
31123 offsetof(CPUMIPSState
, hflags
), "hflags");
31125 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
31126 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
31128 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
31129 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
31131 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
31133 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
31136 #if defined(TARGET_MIPS64)
31138 for (i
= 1; i
< 32; i
++) {
31139 cpu_mmr
[i
] = tcg_global_mem_new_i64(cpu_env
,
31140 offsetof(CPUMIPSState
,
31146 #if !defined(TARGET_MIPS64)
31147 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
31148 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31149 offsetof(CPUMIPSState
,
31150 active_tc
.mxu_gpr
[i
]),
31154 mxu_CR
= tcg_global_mem_new(cpu_env
,
31155 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
31156 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
31160 #include "translate_init.inc.c"
31162 void cpu_mips_realize_env(CPUMIPSState
*env
)
31164 env
->exception_base
= (int32_t)0xBFC00000;
31166 #ifndef CONFIG_USER_ONLY
31167 mmu_init(env
, env
->cpu_model
);
31169 fpu_init(env
, env
->cpu_model
);
31170 mvp_init(env
, env
->cpu_model
);
31173 bool cpu_supports_cps_smp(const char *cpu_type
)
31175 const MIPSCPUClass
*mcc
= MIPS_CPU_CLASS(object_class_by_name(cpu_type
));
31176 return (mcc
->cpu_def
->CP0_Config3
& (1 << CP0C3_CMGCR
)) != 0;
31179 bool cpu_supports_isa(const char *cpu_type
, uint64_t isa
)
31181 const MIPSCPUClass
*mcc
= MIPS_CPU_CLASS(object_class_by_name(cpu_type
));
31182 return (mcc
->cpu_def
->insn_flags
& isa
) != 0;
31185 void cpu_set_exception_base(int vp_index
, target_ulong address
)
31187 MIPSCPU
*vp
= MIPS_CPU(qemu_get_cpu(vp_index
));
31188 vp
->env
.exception_base
= address
;
31191 void cpu_state_reset(CPUMIPSState
*env
)
31193 CPUState
*cs
= env_cpu(env
);
31195 /* Reset registers to their default values */
31196 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
31197 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
31198 #ifdef TARGET_WORDS_BIGENDIAN
31199 env
->CP0_Config0
|= (1 << CP0C0_BE
);
31201 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
31202 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
31203 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
31204 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
31205 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
31206 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
31207 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
31208 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
31209 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
31210 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
31211 << env
->cpu_model
->CP0_LLAddr_shift
;
31212 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
31213 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
31214 env
->CCRes
= env
->cpu_model
->CCRes
;
31215 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
31216 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
31217 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
31218 env
->current_tc
= 0;
31219 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
31220 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
31221 #if defined(TARGET_MIPS64)
31222 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
31223 env
->SEGMask
|= 3ULL << 62;
31226 env
->PABITS
= env
->cpu_model
->PABITS
;
31227 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
31228 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
31229 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
31230 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
31231 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
31232 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
31233 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
31234 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
31235 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
31236 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
31237 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
31238 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
31239 env
->CP0_EBaseWG_rw_bitmask
= env
->cpu_model
->CP0_EBaseWG_rw_bitmask
;
31240 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
31241 env
->active_fpu
.fcr31_rw_bitmask
= env
->cpu_model
->CP1_fcr31_rw_bitmask
;
31242 env
->active_fpu
.fcr31
= env
->cpu_model
->CP1_fcr31
;
31243 env
->msair
= env
->cpu_model
->MSAIR
;
31244 env
->insn_flags
= env
->cpu_model
->insn_flags
;
31246 #if defined(CONFIG_USER_ONLY)
31247 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
31248 # ifdef TARGET_MIPS64
31249 /* Enable 64-bit register mode. */
31250 env
->CP0_Status
|= (1 << CP0St_PX
);
31252 # ifdef TARGET_ABI_MIPSN64
31253 /* Enable 64-bit address mode. */
31254 env
->CP0_Status
|= (1 << CP0St_UX
);
31257 * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
31258 * hardware registers.
31260 env
->CP0_HWREna
|= 0x0000000F;
31261 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
31262 env
->CP0_Status
|= (1 << CP0St_CU1
);
31264 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
31265 env
->CP0_Status
|= (1 << CP0St_MX
);
31267 # if defined(TARGET_MIPS64)
31268 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
31269 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
31270 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
31271 env
->CP0_Status
|= (1 << CP0St_FR
);
31275 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
31277 * If the exception was raised from a delay slot,
31278 * come back to the jump.
31280 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
31281 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
31283 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
31285 env
->active_tc
.PC
= env
->exception_base
;
31286 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
31287 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
31288 env
->CP0_Wired
= 0;
31289 env
->CP0_GlobalNumber
= (cs
->cpu_index
& 0xFF) << CP0GN_VPId
;
31290 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
31291 if (mips_um_ksegs_enabled()) {
31292 env
->CP0_EBase
|= 0x40000000;
31294 env
->CP0_EBase
|= (int32_t)0x80000000;
31296 if (env
->CP0_Config3
& (1 << CP0C3_CMGCR
)) {
31297 env
->CP0_CMGCRBase
= 0x1fbf8000 >> 4;
31299 env
->CP0_EntryHi_ASID_mask
= (env
->CP0_Config5
& (1 << CP0C5_MI
)) ?
31300 0x0 : (env
->CP0_Config4
& (1 << CP0C4_AE
)) ? 0x3ff : 0xff;
31301 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
31303 * Vectored interrupts not implemented, timer on int 7,
31304 * no performance counters.
31306 env
->CP0_IntCtl
= 0xe0000000;
31310 for (i
= 0; i
< 7; i
++) {
31311 env
->CP0_WatchLo
[i
] = 0;
31312 env
->CP0_WatchHi
[i
] = 0x80000000;
31314 env
->CP0_WatchLo
[7] = 0;
31315 env
->CP0_WatchHi
[7] = 0;
31317 /* Count register increments in debug mode, EJTAG version 1 */
31318 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
31320 cpu_mips_store_count(env
, 1);
31322 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
31325 /* Only TC0 on VPE 0 starts as active. */
31326 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
31327 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
31328 env
->tcs
[i
].CP0_TCHalt
= 1;
31330 env
->active_tc
.CP0_TCHalt
= 1;
31333 if (cs
->cpu_index
== 0) {
31334 /* VPE0 starts up enabled. */
31335 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
31336 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
31338 /* TC0 starts up unhalted. */
31340 env
->active_tc
.CP0_TCHalt
= 0;
31341 env
->tcs
[0].CP0_TCHalt
= 0;
31342 /* With thread 0 active. */
31343 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
31344 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
31349 * Configure default legacy segmentation control. We use this regardless of
31350 * whether segmentation control is presented to the guest.
31352 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
31353 env
->CP0_SegCtl0
= (CP0SC_AM_MK
<< CP0SC_AM
);
31354 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
31355 env
->CP0_SegCtl0
|= ((CP0SC_AM_MSK
<< CP0SC_AM
)) << 16;
31356 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
31357 env
->CP0_SegCtl1
= (0 << CP0SC_PA
) | (CP0SC_AM_UK
<< CP0SC_AM
) |
31359 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
31360 env
->CP0_SegCtl1
|= ((0 << CP0SC_PA
) | (CP0SC_AM_UK
<< CP0SC_AM
) |
31361 (3 << CP0SC_C
)) << 16;
31362 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
31363 env
->CP0_SegCtl2
= (2 << CP0SC_PA
) | (CP0SC_AM_MUSK
<< CP0SC_AM
) |
31364 (1 << CP0SC_EU
) | (2 << CP0SC_C
);
31365 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
31366 env
->CP0_SegCtl2
|= ((0 << CP0SC_PA
) | (CP0SC_AM_MUSK
<< CP0SC_AM
) |
31367 (1 << CP0SC_EU
) | (2 << CP0SC_C
)) << 16;
31368 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
31369 env
->CP0_SegCtl1
|= (CP0SC_AM_UK
<< CP0SC1_XAM
);
31371 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
31372 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
31373 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
31374 env
->CP0_Status
|= (1 << CP0St_FR
);
31377 if (env
->insn_flags
& ISA_MIPS32R6
) {
31379 env
->CP0_PWSize
= 0x40;
31385 env
->CP0_PWField
= 0x0C30C302;
31392 env
->CP0_PWField
= 0x02;
31395 if (env
->CP0_Config3
& (1 << CP0C3_ISA
) & (1 << (CP0C3_ISA
+ 1))) {
31396 /* microMIPS on reset when Config3.ISA is 3 */
31397 env
->hflags
|= MIPS_HFLAG_M16
;
31401 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
31405 compute_hflags(env
);
31406 restore_fp_status(env
);
31407 restore_pamask(env
);
31408 cs
->exception_index
= EXCP_NONE
;
31410 if (semihosting_get_argc()) {
31411 /* UHI interface can be used to obtain argc and argv */
31412 env
->active_tc
.gpr
[4] = -1;
31416 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
31417 target_ulong
*data
)
31419 env
->active_tc
.PC
= data
[0];
31420 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
31421 env
->hflags
|= data
[1];
31422 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
31423 case MIPS_HFLAG_BR
:
31425 case MIPS_HFLAG_BC
:
31426 case MIPS_HFLAG_BL
:
31428 env
->btarget
= data
[2];