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_LMMI(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
|
3427 * Loongson CPU uses a load to zero register for prefetch.
3428 * We emulate it as a NOP. On other CPU we must perform the
3429 * actual memory access.
3434 t0
= tcg_temp_new();
3435 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3438 #if defined(TARGET_MIPS64)
3440 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
3441 ctx
->default_tcg_memop_mask
);
3442 gen_store_gpr(t0
, rt
);
3445 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
3446 ctx
->default_tcg_memop_mask
);
3447 gen_store_gpr(t0
, rt
);
3451 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
3452 gen_store_gpr(t0
, rt
);
3455 t1
= tcg_temp_new();
3457 * Do a byte access to possibly trigger a page
3458 * fault with the unaligned address.
3460 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3461 tcg_gen_andi_tl(t1
, t0
, 7);
3462 #ifndef TARGET_WORDS_BIGENDIAN
3463 tcg_gen_xori_tl(t1
, t1
, 7);
3465 tcg_gen_shli_tl(t1
, t1
, 3);
3466 tcg_gen_andi_tl(t0
, t0
, ~7);
3467 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3468 tcg_gen_shl_tl(t0
, t0
, t1
);
3469 t2
= tcg_const_tl(-1);
3470 tcg_gen_shl_tl(t2
, t2
, t1
);
3471 gen_load_gpr(t1
, rt
);
3472 tcg_gen_andc_tl(t1
, t1
, t2
);
3474 tcg_gen_or_tl(t0
, t0
, t1
);
3476 gen_store_gpr(t0
, rt
);
3479 t1
= tcg_temp_new();
3481 * Do a byte access to possibly trigger a page
3482 * fault with the unaligned address.
3484 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3485 tcg_gen_andi_tl(t1
, t0
, 7);
3486 #ifdef TARGET_WORDS_BIGENDIAN
3487 tcg_gen_xori_tl(t1
, t1
, 7);
3489 tcg_gen_shli_tl(t1
, t1
, 3);
3490 tcg_gen_andi_tl(t0
, t0
, ~7);
3491 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3492 tcg_gen_shr_tl(t0
, t0
, t1
);
3493 tcg_gen_xori_tl(t1
, t1
, 63);
3494 t2
= tcg_const_tl(0xfffffffffffffffeull
);
3495 tcg_gen_shl_tl(t2
, t2
, t1
);
3496 gen_load_gpr(t1
, rt
);
3497 tcg_gen_and_tl(t1
, t1
, t2
);
3499 tcg_gen_or_tl(t0
, t0
, t1
);
3501 gen_store_gpr(t0
, rt
);
3504 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3505 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3507 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3508 gen_store_gpr(t0
, rt
);
3512 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3513 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3515 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
3516 gen_store_gpr(t0
, rt
);
3519 mem_idx
= MIPS_HFLAG_UM
;
3522 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
3523 ctx
->default_tcg_memop_mask
);
3524 gen_store_gpr(t0
, rt
);
3527 mem_idx
= MIPS_HFLAG_UM
;
3530 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
3531 ctx
->default_tcg_memop_mask
);
3532 gen_store_gpr(t0
, rt
);
3535 mem_idx
= MIPS_HFLAG_UM
;
3538 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
3539 ctx
->default_tcg_memop_mask
);
3540 gen_store_gpr(t0
, rt
);
3543 mem_idx
= MIPS_HFLAG_UM
;
3546 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3547 gen_store_gpr(t0
, rt
);
3550 mem_idx
= MIPS_HFLAG_UM
;
3553 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3554 gen_store_gpr(t0
, rt
);
3557 mem_idx
= MIPS_HFLAG_UM
;
3560 t1
= tcg_temp_new();
3562 * Do a byte access to possibly trigger a page
3563 * fault with the unaligned address.
3565 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3566 tcg_gen_andi_tl(t1
, t0
, 3);
3567 #ifndef TARGET_WORDS_BIGENDIAN
3568 tcg_gen_xori_tl(t1
, t1
, 3);
3570 tcg_gen_shli_tl(t1
, t1
, 3);
3571 tcg_gen_andi_tl(t0
, t0
, ~3);
3572 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3573 tcg_gen_shl_tl(t0
, t0
, t1
);
3574 t2
= tcg_const_tl(-1);
3575 tcg_gen_shl_tl(t2
, t2
, t1
);
3576 gen_load_gpr(t1
, rt
);
3577 tcg_gen_andc_tl(t1
, t1
, t2
);
3579 tcg_gen_or_tl(t0
, t0
, t1
);
3581 tcg_gen_ext32s_tl(t0
, t0
);
3582 gen_store_gpr(t0
, rt
);
3585 mem_idx
= MIPS_HFLAG_UM
;
3588 t1
= tcg_temp_new();
3590 * Do a byte access to possibly trigger a page
3591 * fault with the unaligned address.
3593 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3594 tcg_gen_andi_tl(t1
, t0
, 3);
3595 #ifdef TARGET_WORDS_BIGENDIAN
3596 tcg_gen_xori_tl(t1
, t1
, 3);
3598 tcg_gen_shli_tl(t1
, t1
, 3);
3599 tcg_gen_andi_tl(t0
, t0
, ~3);
3600 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3601 tcg_gen_shr_tl(t0
, t0
, t1
);
3602 tcg_gen_xori_tl(t1
, t1
, 31);
3603 t2
= tcg_const_tl(0xfffffffeull
);
3604 tcg_gen_shl_tl(t2
, t2
, t1
);
3605 gen_load_gpr(t1
, rt
);
3606 tcg_gen_and_tl(t1
, t1
, t2
);
3608 tcg_gen_or_tl(t0
, t0
, t1
);
3610 tcg_gen_ext32s_tl(t0
, t0
);
3611 gen_store_gpr(t0
, rt
);
3614 mem_idx
= MIPS_HFLAG_UM
;
3618 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3619 gen_store_gpr(t0
, rt
);
3625 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3626 uint32_t reg1
, uint32_t reg2
)
3628 TCGv taddr
= tcg_temp_new();
3629 TCGv_i64 tval
= tcg_temp_new_i64();
3630 TCGv tmp1
= tcg_temp_new();
3631 TCGv tmp2
= tcg_temp_new();
3633 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3634 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3635 #ifdef TARGET_WORDS_BIGENDIAN
3636 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3638 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3640 gen_store_gpr(tmp1
, reg1
);
3641 tcg_temp_free(tmp1
);
3642 gen_store_gpr(tmp2
, reg2
);
3643 tcg_temp_free(tmp2
);
3644 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3645 tcg_temp_free_i64(tval
);
3646 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3647 tcg_temp_free(taddr
);
3651 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3652 int base
, int offset
)
3654 TCGv t0
= tcg_temp_new();
3655 TCGv t1
= tcg_temp_new();
3656 int mem_idx
= ctx
->mem_idx
;
3658 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3659 gen_load_gpr(t1
, rt
);
3661 #if defined(TARGET_MIPS64)
3663 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3664 ctx
->default_tcg_memop_mask
);
3667 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3670 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3674 mem_idx
= MIPS_HFLAG_UM
;
3677 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3678 ctx
->default_tcg_memop_mask
);
3681 mem_idx
= MIPS_HFLAG_UM
;
3684 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3685 ctx
->default_tcg_memop_mask
);
3688 mem_idx
= MIPS_HFLAG_UM
;
3691 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3694 mem_idx
= MIPS_HFLAG_UM
;
3697 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3700 mem_idx
= MIPS_HFLAG_UM
;
3703 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3711 /* Store conditional */
3712 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3713 MemOp tcg_mo
, bool eva
)
3716 TCGLabel
*l1
= gen_new_label();
3717 TCGLabel
*done
= gen_new_label();
3719 t0
= tcg_temp_new();
3720 addr
= tcg_temp_new();
3721 /* compare the address against that of the preceeding LL */
3722 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3723 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3724 tcg_temp_free(addr
);
3725 tcg_gen_movi_tl(t0
, 0);
3726 gen_store_gpr(t0
, rt
);
3730 /* generate cmpxchg */
3731 val
= tcg_temp_new();
3732 gen_load_gpr(val
, rt
);
3733 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3734 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3735 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3736 gen_store_gpr(t0
, rt
);
3739 gen_set_label(done
);
3744 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3745 uint32_t reg1
, uint32_t reg2
, bool eva
)
3747 TCGv taddr
= tcg_temp_local_new();
3748 TCGv lladdr
= tcg_temp_local_new();
3749 TCGv_i64 tval
= tcg_temp_new_i64();
3750 TCGv_i64 llval
= tcg_temp_new_i64();
3751 TCGv_i64 val
= tcg_temp_new_i64();
3752 TCGv tmp1
= tcg_temp_new();
3753 TCGv tmp2
= tcg_temp_new();
3754 TCGLabel
*lab_fail
= gen_new_label();
3755 TCGLabel
*lab_done
= gen_new_label();
3757 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3759 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3760 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3762 gen_load_gpr(tmp1
, reg1
);
3763 gen_load_gpr(tmp2
, reg2
);
3765 #ifdef TARGET_WORDS_BIGENDIAN
3766 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3768 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3771 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3772 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3773 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3775 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3777 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3779 gen_set_label(lab_fail
);
3782 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3784 gen_set_label(lab_done
);
3785 tcg_gen_movi_tl(lladdr
, -1);
3786 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3789 /* Load and store */
3790 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3794 * Don't do NOP if destination is zero: we must perform the actual
3800 TCGv_i32 fp0
= tcg_temp_new_i32();
3801 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3802 ctx
->default_tcg_memop_mask
);
3803 gen_store_fpr32(ctx
, fp0
, ft
);
3804 tcg_temp_free_i32(fp0
);
3809 TCGv_i32 fp0
= tcg_temp_new_i32();
3810 gen_load_fpr32(ctx
, fp0
, ft
);
3811 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3812 ctx
->default_tcg_memop_mask
);
3813 tcg_temp_free_i32(fp0
);
3818 TCGv_i64 fp0
= tcg_temp_new_i64();
3819 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3820 ctx
->default_tcg_memop_mask
);
3821 gen_store_fpr64(ctx
, fp0
, ft
);
3822 tcg_temp_free_i64(fp0
);
3827 TCGv_i64 fp0
= tcg_temp_new_i64();
3828 gen_load_fpr64(ctx
, fp0
, ft
);
3829 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3830 ctx
->default_tcg_memop_mask
);
3831 tcg_temp_free_i64(fp0
);
3835 MIPS_INVAL("flt_ldst");
3836 generate_exception_end(ctx
, EXCP_RI
);
3841 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3842 int rs
, int16_t imm
)
3844 TCGv t0
= tcg_temp_new();
3846 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3847 check_cp1_enabled(ctx
);
3851 check_insn(ctx
, ISA_MIPS2
);
3854 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3855 gen_flt_ldst(ctx
, op
, rt
, t0
);
3858 generate_exception_err(ctx
, EXCP_CpU
, 1);
3863 /* Arithmetic with immediate operand */
3864 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3865 int rt
, int rs
, int imm
)
3867 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3869 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3871 * If no destination, treat it as a NOP.
3872 * For addi, we must generate the overflow exception when needed.
3879 TCGv t0
= tcg_temp_local_new();
3880 TCGv t1
= tcg_temp_new();
3881 TCGv t2
= tcg_temp_new();
3882 TCGLabel
*l1
= gen_new_label();
3884 gen_load_gpr(t1
, rs
);
3885 tcg_gen_addi_tl(t0
, t1
, uimm
);
3886 tcg_gen_ext32s_tl(t0
, t0
);
3888 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3889 tcg_gen_xori_tl(t2
, t0
, uimm
);
3890 tcg_gen_and_tl(t1
, t1
, t2
);
3892 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3894 /* operands of same sign, result different sign */
3895 generate_exception(ctx
, EXCP_OVERFLOW
);
3897 tcg_gen_ext32s_tl(t0
, t0
);
3898 gen_store_gpr(t0
, rt
);
3904 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3905 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3907 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3910 #if defined(TARGET_MIPS64)
3913 TCGv t0
= tcg_temp_local_new();
3914 TCGv t1
= tcg_temp_new();
3915 TCGv t2
= tcg_temp_new();
3916 TCGLabel
*l1
= gen_new_label();
3918 gen_load_gpr(t1
, rs
);
3919 tcg_gen_addi_tl(t0
, t1
, uimm
);
3921 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3922 tcg_gen_xori_tl(t2
, t0
, uimm
);
3923 tcg_gen_and_tl(t1
, t1
, t2
);
3925 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3927 /* operands of same sign, result different sign */
3928 generate_exception(ctx
, EXCP_OVERFLOW
);
3930 gen_store_gpr(t0
, rt
);
3936 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3938 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3945 /* Logic with immediate operand */
3946 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3947 int rt
, int rs
, int16_t imm
)
3952 /* If no destination, treat it as a NOP. */
3955 uimm
= (uint16_t)imm
;
3958 if (likely(rs
!= 0)) {
3959 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3961 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
3966 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3968 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3972 if (likely(rs
!= 0)) {
3973 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3975 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3979 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
3981 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
3982 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3984 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
3993 /* Set on less than with immediate operand */
3994 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
3995 int rt
, int rs
, int16_t imm
)
3997 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
4001 /* If no destination, treat it as a NOP. */
4004 t0
= tcg_temp_new();
4005 gen_load_gpr(t0
, rs
);
4008 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
4011 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
4017 /* Shifts with immediate operand */
4018 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
4019 int rt
, int rs
, int16_t imm
)
4021 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
4025 /* If no destination, treat it as a NOP. */
4029 t0
= tcg_temp_new();
4030 gen_load_gpr(t0
, rs
);
4033 tcg_gen_shli_tl(t0
, t0
, uimm
);
4034 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4037 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4041 tcg_gen_ext32u_tl(t0
, t0
);
4042 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4044 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4049 TCGv_i32 t1
= tcg_temp_new_i32();
4051 tcg_gen_trunc_tl_i32(t1
, t0
);
4052 tcg_gen_rotri_i32(t1
, t1
, uimm
);
4053 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
4054 tcg_temp_free_i32(t1
);
4056 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4059 #if defined(TARGET_MIPS64)
4061 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
4064 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4067 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4071 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
4073 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
4077 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4080 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4083 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4086 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4094 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
4095 int rd
, int rs
, int rt
)
4097 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
4098 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
4100 * If no destination, treat it as a NOP.
4101 * For add & sub, we must generate the overflow exception when needed.
4109 TCGv t0
= tcg_temp_local_new();
4110 TCGv t1
= tcg_temp_new();
4111 TCGv t2
= tcg_temp_new();
4112 TCGLabel
*l1
= gen_new_label();
4114 gen_load_gpr(t1
, rs
);
4115 gen_load_gpr(t2
, rt
);
4116 tcg_gen_add_tl(t0
, t1
, t2
);
4117 tcg_gen_ext32s_tl(t0
, t0
);
4118 tcg_gen_xor_tl(t1
, t1
, t2
);
4119 tcg_gen_xor_tl(t2
, t0
, t2
);
4120 tcg_gen_andc_tl(t1
, t2
, t1
);
4122 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4124 /* operands of same sign, result different sign */
4125 generate_exception(ctx
, EXCP_OVERFLOW
);
4127 gen_store_gpr(t0
, rd
);
4132 if (rs
!= 0 && rt
!= 0) {
4133 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4134 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4135 } else if (rs
== 0 && rt
!= 0) {
4136 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4137 } else if (rs
!= 0 && rt
== 0) {
4138 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4140 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4145 TCGv t0
= tcg_temp_local_new();
4146 TCGv t1
= tcg_temp_new();
4147 TCGv t2
= tcg_temp_new();
4148 TCGLabel
*l1
= gen_new_label();
4150 gen_load_gpr(t1
, rs
);
4151 gen_load_gpr(t2
, rt
);
4152 tcg_gen_sub_tl(t0
, t1
, t2
);
4153 tcg_gen_ext32s_tl(t0
, t0
);
4154 tcg_gen_xor_tl(t2
, t1
, t2
);
4155 tcg_gen_xor_tl(t1
, t0
, t1
);
4156 tcg_gen_and_tl(t1
, t1
, t2
);
4158 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4161 * operands of different sign, first operand and the result
4164 generate_exception(ctx
, EXCP_OVERFLOW
);
4166 gen_store_gpr(t0
, rd
);
4171 if (rs
!= 0 && rt
!= 0) {
4172 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4173 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4174 } else if (rs
== 0 && rt
!= 0) {
4175 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4176 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4177 } else if (rs
!= 0 && rt
== 0) {
4178 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4180 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4183 #if defined(TARGET_MIPS64)
4186 TCGv t0
= tcg_temp_local_new();
4187 TCGv t1
= tcg_temp_new();
4188 TCGv t2
= tcg_temp_new();
4189 TCGLabel
*l1
= gen_new_label();
4191 gen_load_gpr(t1
, rs
);
4192 gen_load_gpr(t2
, rt
);
4193 tcg_gen_add_tl(t0
, t1
, t2
);
4194 tcg_gen_xor_tl(t1
, t1
, t2
);
4195 tcg_gen_xor_tl(t2
, t0
, t2
);
4196 tcg_gen_andc_tl(t1
, t2
, t1
);
4198 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4200 /* operands of same sign, result different sign */
4201 generate_exception(ctx
, EXCP_OVERFLOW
);
4203 gen_store_gpr(t0
, rd
);
4208 if (rs
!= 0 && rt
!= 0) {
4209 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4210 } else if (rs
== 0 && rt
!= 0) {
4211 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4212 } else if (rs
!= 0 && rt
== 0) {
4213 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4215 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4220 TCGv t0
= tcg_temp_local_new();
4221 TCGv t1
= tcg_temp_new();
4222 TCGv t2
= tcg_temp_new();
4223 TCGLabel
*l1
= gen_new_label();
4225 gen_load_gpr(t1
, rs
);
4226 gen_load_gpr(t2
, rt
);
4227 tcg_gen_sub_tl(t0
, t1
, t2
);
4228 tcg_gen_xor_tl(t2
, t1
, t2
);
4229 tcg_gen_xor_tl(t1
, t0
, t1
);
4230 tcg_gen_and_tl(t1
, t1
, t2
);
4232 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4235 * Operands of different sign, first operand and result different
4238 generate_exception(ctx
, EXCP_OVERFLOW
);
4240 gen_store_gpr(t0
, rd
);
4245 if (rs
!= 0 && rt
!= 0) {
4246 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4247 } else if (rs
== 0 && rt
!= 0) {
4248 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4249 } else if (rs
!= 0 && rt
== 0) {
4250 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4252 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4257 if (likely(rs
!= 0 && rt
!= 0)) {
4258 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4259 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4261 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4267 /* Conditional move */
4268 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
4269 int rd
, int rs
, int rt
)
4274 /* If no destination, treat it as a NOP. */
4278 t0
= tcg_temp_new();
4279 gen_load_gpr(t0
, rt
);
4280 t1
= tcg_const_tl(0);
4281 t2
= tcg_temp_new();
4282 gen_load_gpr(t2
, rs
);
4285 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4288 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4291 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4294 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4303 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
4304 int rd
, int rs
, int rt
)
4307 /* If no destination, treat it as a NOP. */
4313 if (likely(rs
!= 0 && rt
!= 0)) {
4314 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4316 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4320 if (rs
!= 0 && rt
!= 0) {
4321 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4322 } else if (rs
== 0 && rt
!= 0) {
4323 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4324 } else if (rs
!= 0 && rt
== 0) {
4325 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4327 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
4331 if (likely(rs
!= 0 && rt
!= 0)) {
4332 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4333 } else if (rs
== 0 && rt
!= 0) {
4334 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4335 } else if (rs
!= 0 && rt
== 0) {
4336 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4338 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4342 if (likely(rs
!= 0 && rt
!= 0)) {
4343 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4344 } else if (rs
== 0 && rt
!= 0) {
4345 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4346 } else if (rs
!= 0 && rt
== 0) {
4347 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4349 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4355 /* Set on lower than */
4356 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
4357 int rd
, int rs
, int rt
)
4362 /* If no destination, treat it as a NOP. */
4366 t0
= tcg_temp_new();
4367 t1
= tcg_temp_new();
4368 gen_load_gpr(t0
, rs
);
4369 gen_load_gpr(t1
, rt
);
4372 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
4375 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
4383 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
4384 int rd
, int rs
, int rt
)
4390 * If no destination, treat it as a NOP.
4391 * For add & sub, we must generate the overflow exception when needed.
4396 t0
= tcg_temp_new();
4397 t1
= tcg_temp_new();
4398 gen_load_gpr(t0
, rs
);
4399 gen_load_gpr(t1
, rt
);
4402 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4403 tcg_gen_shl_tl(t0
, t1
, t0
);
4404 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4407 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4408 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4411 tcg_gen_ext32u_tl(t1
, t1
);
4412 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4413 tcg_gen_shr_tl(t0
, t1
, t0
);
4414 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4418 TCGv_i32 t2
= tcg_temp_new_i32();
4419 TCGv_i32 t3
= tcg_temp_new_i32();
4421 tcg_gen_trunc_tl_i32(t2
, t0
);
4422 tcg_gen_trunc_tl_i32(t3
, t1
);
4423 tcg_gen_andi_i32(t2
, t2
, 0x1f);
4424 tcg_gen_rotr_i32(t2
, t3
, t2
);
4425 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4426 tcg_temp_free_i32(t2
);
4427 tcg_temp_free_i32(t3
);
4430 #if defined(TARGET_MIPS64)
4432 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4433 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
4436 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4437 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4440 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4441 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
4444 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4445 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
4453 #if defined(TARGET_MIPS64)
4454 /* Copy GPR to and from TX79 HI1/LO1 register. */
4455 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
4457 if (reg
== 0 && (opc
== MMI_OPC_MFHI1
|| opc
== MMI_OPC_MFLO1
)) {
4464 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[1]);
4467 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[1]);
4471 tcg_gen_mov_tl(cpu_HI
[1], cpu_gpr
[reg
]);
4473 tcg_gen_movi_tl(cpu_HI
[1], 0);
4478 tcg_gen_mov_tl(cpu_LO
[1], cpu_gpr
[reg
]);
4480 tcg_gen_movi_tl(cpu_LO
[1], 0);
4484 MIPS_INVAL("mfthilo1 TX79");
4485 generate_exception_end(ctx
, EXCP_RI
);
4491 /* Arithmetic on HI/LO registers */
4492 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
4494 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
4505 #if defined(TARGET_MIPS64)
4507 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4511 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4515 #if defined(TARGET_MIPS64)
4517 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4521 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4526 #if defined(TARGET_MIPS64)
4528 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4532 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4535 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
4540 #if defined(TARGET_MIPS64)
4542 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4546 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4549 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4555 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4558 TCGv t0
= tcg_const_tl(addr
);
4559 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4560 gen_store_gpr(t0
, reg
);
4564 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4570 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4573 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4574 addr
= addr_add(ctx
, pc
, offset
);
4575 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4579 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4580 addr
= addr_add(ctx
, pc
, offset
);
4581 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4583 #if defined(TARGET_MIPS64)
4586 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4587 addr
= addr_add(ctx
, pc
, offset
);
4588 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4592 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4595 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4596 addr
= addr_add(ctx
, pc
, offset
);
4597 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4602 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4603 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4604 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4607 #if defined(TARGET_MIPS64)
4608 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4609 case R6_OPC_LDPC
+ (1 << 16):
4610 case R6_OPC_LDPC
+ (2 << 16):
4611 case R6_OPC_LDPC
+ (3 << 16):
4613 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4614 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4615 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4619 MIPS_INVAL("OPC_PCREL");
4620 generate_exception_end(ctx
, EXCP_RI
);
4627 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4636 t0
= tcg_temp_new();
4637 t1
= tcg_temp_new();
4639 gen_load_gpr(t0
, rs
);
4640 gen_load_gpr(t1
, rt
);
4645 TCGv t2
= tcg_temp_new();
4646 TCGv t3
= tcg_temp_new();
4647 tcg_gen_ext32s_tl(t0
, t0
);
4648 tcg_gen_ext32s_tl(t1
, t1
);
4649 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4650 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4651 tcg_gen_and_tl(t2
, t2
, t3
);
4652 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4653 tcg_gen_or_tl(t2
, t2
, t3
);
4654 tcg_gen_movi_tl(t3
, 0);
4655 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4656 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4657 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4664 TCGv t2
= tcg_temp_new();
4665 TCGv t3
= tcg_temp_new();
4666 tcg_gen_ext32s_tl(t0
, t0
);
4667 tcg_gen_ext32s_tl(t1
, t1
);
4668 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4669 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4670 tcg_gen_and_tl(t2
, t2
, t3
);
4671 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4672 tcg_gen_or_tl(t2
, t2
, t3
);
4673 tcg_gen_movi_tl(t3
, 0);
4674 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4675 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4676 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4683 TCGv t2
= tcg_const_tl(0);
4684 TCGv t3
= tcg_const_tl(1);
4685 tcg_gen_ext32u_tl(t0
, t0
);
4686 tcg_gen_ext32u_tl(t1
, t1
);
4687 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4688 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4689 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4696 TCGv t2
= tcg_const_tl(0);
4697 TCGv t3
= tcg_const_tl(1);
4698 tcg_gen_ext32u_tl(t0
, t0
);
4699 tcg_gen_ext32u_tl(t1
, t1
);
4700 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4701 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4702 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4709 TCGv_i32 t2
= tcg_temp_new_i32();
4710 TCGv_i32 t3
= tcg_temp_new_i32();
4711 tcg_gen_trunc_tl_i32(t2
, t0
);
4712 tcg_gen_trunc_tl_i32(t3
, t1
);
4713 tcg_gen_mul_i32(t2
, t2
, t3
);
4714 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4715 tcg_temp_free_i32(t2
);
4716 tcg_temp_free_i32(t3
);
4721 TCGv_i32 t2
= tcg_temp_new_i32();
4722 TCGv_i32 t3
= tcg_temp_new_i32();
4723 tcg_gen_trunc_tl_i32(t2
, t0
);
4724 tcg_gen_trunc_tl_i32(t3
, t1
);
4725 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4726 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4727 tcg_temp_free_i32(t2
);
4728 tcg_temp_free_i32(t3
);
4733 TCGv_i32 t2
= tcg_temp_new_i32();
4734 TCGv_i32 t3
= tcg_temp_new_i32();
4735 tcg_gen_trunc_tl_i32(t2
, t0
);
4736 tcg_gen_trunc_tl_i32(t3
, t1
);
4737 tcg_gen_mul_i32(t2
, t2
, t3
);
4738 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4739 tcg_temp_free_i32(t2
);
4740 tcg_temp_free_i32(t3
);
4745 TCGv_i32 t2
= tcg_temp_new_i32();
4746 TCGv_i32 t3
= tcg_temp_new_i32();
4747 tcg_gen_trunc_tl_i32(t2
, t0
);
4748 tcg_gen_trunc_tl_i32(t3
, t1
);
4749 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4750 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4751 tcg_temp_free_i32(t2
);
4752 tcg_temp_free_i32(t3
);
4755 #if defined(TARGET_MIPS64)
4758 TCGv t2
= tcg_temp_new();
4759 TCGv t3
= tcg_temp_new();
4760 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4761 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4762 tcg_gen_and_tl(t2
, t2
, t3
);
4763 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4764 tcg_gen_or_tl(t2
, t2
, t3
);
4765 tcg_gen_movi_tl(t3
, 0);
4766 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4767 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4774 TCGv t2
= tcg_temp_new();
4775 TCGv t3
= tcg_temp_new();
4776 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4777 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4778 tcg_gen_and_tl(t2
, t2
, t3
);
4779 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4780 tcg_gen_or_tl(t2
, t2
, t3
);
4781 tcg_gen_movi_tl(t3
, 0);
4782 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4783 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4790 TCGv t2
= tcg_const_tl(0);
4791 TCGv t3
= tcg_const_tl(1);
4792 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4793 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4800 TCGv t2
= tcg_const_tl(0);
4801 TCGv t3
= tcg_const_tl(1);
4802 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4803 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4809 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4813 TCGv t2
= tcg_temp_new();
4814 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4819 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4823 TCGv t2
= tcg_temp_new();
4824 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4830 MIPS_INVAL("r6 mul/div");
4831 generate_exception_end(ctx
, EXCP_RI
);
4839 #if defined(TARGET_MIPS64)
4840 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4844 t0
= tcg_temp_new();
4845 t1
= tcg_temp_new();
4847 gen_load_gpr(t0
, rs
);
4848 gen_load_gpr(t1
, rt
);
4853 TCGv t2
= tcg_temp_new();
4854 TCGv t3
= tcg_temp_new();
4855 tcg_gen_ext32s_tl(t0
, t0
);
4856 tcg_gen_ext32s_tl(t1
, t1
);
4857 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4858 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4859 tcg_gen_and_tl(t2
, t2
, t3
);
4860 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4861 tcg_gen_or_tl(t2
, t2
, t3
);
4862 tcg_gen_movi_tl(t3
, 0);
4863 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4864 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4865 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4866 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4867 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4874 TCGv t2
= tcg_const_tl(0);
4875 TCGv t3
= tcg_const_tl(1);
4876 tcg_gen_ext32u_tl(t0
, t0
);
4877 tcg_gen_ext32u_tl(t1
, t1
);
4878 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4879 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4880 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4881 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4882 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4888 MIPS_INVAL("div1 TX79");
4889 generate_exception_end(ctx
, EXCP_RI
);
4898 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4899 int acc
, int rs
, int rt
)
4903 t0
= tcg_temp_new();
4904 t1
= tcg_temp_new();
4906 gen_load_gpr(t0
, rs
);
4907 gen_load_gpr(t1
, rt
);
4916 TCGv t2
= tcg_temp_new();
4917 TCGv t3
= tcg_temp_new();
4918 tcg_gen_ext32s_tl(t0
, t0
);
4919 tcg_gen_ext32s_tl(t1
, t1
);
4920 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4921 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4922 tcg_gen_and_tl(t2
, t2
, t3
);
4923 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4924 tcg_gen_or_tl(t2
, t2
, t3
);
4925 tcg_gen_movi_tl(t3
, 0);
4926 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4927 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4928 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4929 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4930 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4937 TCGv t2
= tcg_const_tl(0);
4938 TCGv t3
= tcg_const_tl(1);
4939 tcg_gen_ext32u_tl(t0
, t0
);
4940 tcg_gen_ext32u_tl(t1
, t1
);
4941 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4942 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4943 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4944 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4945 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4952 TCGv_i32 t2
= tcg_temp_new_i32();
4953 TCGv_i32 t3
= tcg_temp_new_i32();
4954 tcg_gen_trunc_tl_i32(t2
, t0
);
4955 tcg_gen_trunc_tl_i32(t3
, t1
);
4956 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4957 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4958 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4959 tcg_temp_free_i32(t2
);
4960 tcg_temp_free_i32(t3
);
4965 TCGv_i32 t2
= tcg_temp_new_i32();
4966 TCGv_i32 t3
= tcg_temp_new_i32();
4967 tcg_gen_trunc_tl_i32(t2
, t0
);
4968 tcg_gen_trunc_tl_i32(t3
, t1
);
4969 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4970 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4971 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4972 tcg_temp_free_i32(t2
);
4973 tcg_temp_free_i32(t3
);
4976 #if defined(TARGET_MIPS64)
4979 TCGv t2
= tcg_temp_new();
4980 TCGv t3
= tcg_temp_new();
4981 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4982 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4983 tcg_gen_and_tl(t2
, t2
, t3
);
4984 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4985 tcg_gen_or_tl(t2
, t2
, t3
);
4986 tcg_gen_movi_tl(t3
, 0);
4987 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4988 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4989 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4996 TCGv t2
= tcg_const_tl(0);
4997 TCGv t3
= tcg_const_tl(1);
4998 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4999 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
5000 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
5006 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
5009 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
5014 TCGv_i64 t2
= tcg_temp_new_i64();
5015 TCGv_i64 t3
= tcg_temp_new_i64();
5017 tcg_gen_ext_tl_i64(t2
, t0
);
5018 tcg_gen_ext_tl_i64(t3
, t1
);
5019 tcg_gen_mul_i64(t2
, t2
, t3
);
5020 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5021 tcg_gen_add_i64(t2
, t2
, t3
);
5022 tcg_temp_free_i64(t3
);
5023 gen_move_low32(cpu_LO
[acc
], t2
);
5024 gen_move_high32(cpu_HI
[acc
], t2
);
5025 tcg_temp_free_i64(t2
);
5030 TCGv_i64 t2
= tcg_temp_new_i64();
5031 TCGv_i64 t3
= tcg_temp_new_i64();
5033 tcg_gen_ext32u_tl(t0
, t0
);
5034 tcg_gen_ext32u_tl(t1
, t1
);
5035 tcg_gen_extu_tl_i64(t2
, t0
);
5036 tcg_gen_extu_tl_i64(t3
, t1
);
5037 tcg_gen_mul_i64(t2
, t2
, t3
);
5038 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5039 tcg_gen_add_i64(t2
, t2
, t3
);
5040 tcg_temp_free_i64(t3
);
5041 gen_move_low32(cpu_LO
[acc
], t2
);
5042 gen_move_high32(cpu_HI
[acc
], t2
);
5043 tcg_temp_free_i64(t2
);
5048 TCGv_i64 t2
= tcg_temp_new_i64();
5049 TCGv_i64 t3
= tcg_temp_new_i64();
5051 tcg_gen_ext_tl_i64(t2
, t0
);
5052 tcg_gen_ext_tl_i64(t3
, t1
);
5053 tcg_gen_mul_i64(t2
, t2
, t3
);
5054 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5055 tcg_gen_sub_i64(t2
, t3
, t2
);
5056 tcg_temp_free_i64(t3
);
5057 gen_move_low32(cpu_LO
[acc
], t2
);
5058 gen_move_high32(cpu_HI
[acc
], t2
);
5059 tcg_temp_free_i64(t2
);
5064 TCGv_i64 t2
= tcg_temp_new_i64();
5065 TCGv_i64 t3
= tcg_temp_new_i64();
5067 tcg_gen_ext32u_tl(t0
, t0
);
5068 tcg_gen_ext32u_tl(t1
, t1
);
5069 tcg_gen_extu_tl_i64(t2
, t0
);
5070 tcg_gen_extu_tl_i64(t3
, t1
);
5071 tcg_gen_mul_i64(t2
, t2
, t3
);
5072 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5073 tcg_gen_sub_i64(t2
, t3
, t2
);
5074 tcg_temp_free_i64(t3
);
5075 gen_move_low32(cpu_LO
[acc
], t2
);
5076 gen_move_high32(cpu_HI
[acc
], t2
);
5077 tcg_temp_free_i64(t2
);
5081 MIPS_INVAL("mul/div");
5082 generate_exception_end(ctx
, EXCP_RI
);
5091 * These MULT[U] and MADD[U] instructions implemented in for example
5092 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5093 * architectures are special three-operand variants with the syntax
5095 * MULT[U][1] rd, rs, rt
5099 * (rd, LO, HI) <- rs * rt
5103 * MADD[U][1] rd, rs, rt
5107 * (rd, LO, HI) <- (LO, HI) + rs * rt
5109 * where the low-order 32-bits of the result is placed into both the
5110 * GPR rd and the special register LO. The high-order 32-bits of the
5111 * result is placed into the special register HI.
5113 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5114 * which is the zero register that always reads as 0.
5116 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
5117 int rd
, int rs
, int rt
)
5119 TCGv t0
= tcg_temp_new();
5120 TCGv t1
= tcg_temp_new();
5123 gen_load_gpr(t0
, rs
);
5124 gen_load_gpr(t1
, rt
);
5132 TCGv_i32 t2
= tcg_temp_new_i32();
5133 TCGv_i32 t3
= tcg_temp_new_i32();
5134 tcg_gen_trunc_tl_i32(t2
, t0
);
5135 tcg_gen_trunc_tl_i32(t3
, t1
);
5136 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
5138 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5140 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5141 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5142 tcg_temp_free_i32(t2
);
5143 tcg_temp_free_i32(t3
);
5146 case MMI_OPC_MULTU1
:
5151 TCGv_i32 t2
= tcg_temp_new_i32();
5152 TCGv_i32 t3
= tcg_temp_new_i32();
5153 tcg_gen_trunc_tl_i32(t2
, t0
);
5154 tcg_gen_trunc_tl_i32(t3
, t1
);
5155 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
5157 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5159 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5160 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5161 tcg_temp_free_i32(t2
);
5162 tcg_temp_free_i32(t3
);
5170 TCGv_i64 t2
= tcg_temp_new_i64();
5171 TCGv_i64 t3
= tcg_temp_new_i64();
5173 tcg_gen_ext_tl_i64(t2
, t0
);
5174 tcg_gen_ext_tl_i64(t3
, t1
);
5175 tcg_gen_mul_i64(t2
, t2
, t3
);
5176 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5177 tcg_gen_add_i64(t2
, t2
, t3
);
5178 tcg_temp_free_i64(t3
);
5179 gen_move_low32(cpu_LO
[acc
], t2
);
5180 gen_move_high32(cpu_HI
[acc
], t2
);
5182 gen_move_low32(cpu_gpr
[rd
], t2
);
5184 tcg_temp_free_i64(t2
);
5187 case MMI_OPC_MADDU1
:
5192 TCGv_i64 t2
= tcg_temp_new_i64();
5193 TCGv_i64 t3
= tcg_temp_new_i64();
5195 tcg_gen_ext32u_tl(t0
, t0
);
5196 tcg_gen_ext32u_tl(t1
, t1
);
5197 tcg_gen_extu_tl_i64(t2
, t0
);
5198 tcg_gen_extu_tl_i64(t3
, t1
);
5199 tcg_gen_mul_i64(t2
, t2
, t3
);
5200 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5201 tcg_gen_add_i64(t2
, t2
, t3
);
5202 tcg_temp_free_i64(t3
);
5203 gen_move_low32(cpu_LO
[acc
], t2
);
5204 gen_move_high32(cpu_HI
[acc
], t2
);
5206 gen_move_low32(cpu_gpr
[rd
], t2
);
5208 tcg_temp_free_i64(t2
);
5212 MIPS_INVAL("mul/madd TXx9");
5213 generate_exception_end(ctx
, EXCP_RI
);
5222 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
5223 int rd
, int rs
, int rt
)
5225 TCGv t0
= tcg_temp_new();
5226 TCGv t1
= tcg_temp_new();
5228 gen_load_gpr(t0
, rs
);
5229 gen_load_gpr(t1
, rt
);
5232 case OPC_VR54XX_MULS
:
5233 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
5235 case OPC_VR54XX_MULSU
:
5236 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
5238 case OPC_VR54XX_MACC
:
5239 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
5241 case OPC_VR54XX_MACCU
:
5242 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
5244 case OPC_VR54XX_MSAC
:
5245 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
5247 case OPC_VR54XX_MSACU
:
5248 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
5250 case OPC_VR54XX_MULHI
:
5251 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
5253 case OPC_VR54XX_MULHIU
:
5254 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
5256 case OPC_VR54XX_MULSHI
:
5257 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
5259 case OPC_VR54XX_MULSHIU
:
5260 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
5262 case OPC_VR54XX_MACCHI
:
5263 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
5265 case OPC_VR54XX_MACCHIU
:
5266 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
5268 case OPC_VR54XX_MSACHI
:
5269 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
5271 case OPC_VR54XX_MSACHIU
:
5272 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
5275 MIPS_INVAL("mul vr54xx");
5276 generate_exception_end(ctx
, EXCP_RI
);
5279 gen_store_gpr(t0
, rd
);
5286 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
5296 gen_load_gpr(t0
, rs
);
5301 #if defined(TARGET_MIPS64)
5305 tcg_gen_not_tl(t0
, t0
);
5314 tcg_gen_ext32u_tl(t0
, t0
);
5315 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
5316 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
5318 #if defined(TARGET_MIPS64)
5323 tcg_gen_clzi_i64(t0
, t0
, 64);
5329 /* Godson integer instructions */
5330 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
5331 int rd
, int rs
, int rt
)
5343 case OPC_MULTU_G_2E
:
5344 case OPC_MULTU_G_2F
:
5345 #if defined(TARGET_MIPS64)
5346 case OPC_DMULT_G_2E
:
5347 case OPC_DMULT_G_2F
:
5348 case OPC_DMULTU_G_2E
:
5349 case OPC_DMULTU_G_2F
:
5351 t0
= tcg_temp_new();
5352 t1
= tcg_temp_new();
5355 t0
= tcg_temp_local_new();
5356 t1
= tcg_temp_local_new();
5360 gen_load_gpr(t0
, rs
);
5361 gen_load_gpr(t1
, rt
);
5366 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5367 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5369 case OPC_MULTU_G_2E
:
5370 case OPC_MULTU_G_2F
:
5371 tcg_gen_ext32u_tl(t0
, t0
);
5372 tcg_gen_ext32u_tl(t1
, t1
);
5373 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5374 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5379 TCGLabel
*l1
= gen_new_label();
5380 TCGLabel
*l2
= gen_new_label();
5381 TCGLabel
*l3
= gen_new_label();
5382 tcg_gen_ext32s_tl(t0
, t0
);
5383 tcg_gen_ext32s_tl(t1
, t1
);
5384 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5385 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5388 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5389 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5390 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5393 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5394 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5401 TCGLabel
*l1
= gen_new_label();
5402 TCGLabel
*l2
= gen_new_label();
5403 tcg_gen_ext32u_tl(t0
, t0
);
5404 tcg_gen_ext32u_tl(t1
, t1
);
5405 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5406 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5409 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5410 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5417 TCGLabel
*l1
= gen_new_label();
5418 TCGLabel
*l2
= gen_new_label();
5419 TCGLabel
*l3
= gen_new_label();
5420 tcg_gen_ext32u_tl(t0
, t0
);
5421 tcg_gen_ext32u_tl(t1
, t1
);
5422 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5423 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5424 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5426 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5429 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5430 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5437 TCGLabel
*l1
= gen_new_label();
5438 TCGLabel
*l2
= gen_new_label();
5439 tcg_gen_ext32u_tl(t0
, t0
);
5440 tcg_gen_ext32u_tl(t1
, t1
);
5441 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5442 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5445 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5446 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5450 #if defined(TARGET_MIPS64)
5451 case OPC_DMULT_G_2E
:
5452 case OPC_DMULT_G_2F
:
5453 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5455 case OPC_DMULTU_G_2E
:
5456 case OPC_DMULTU_G_2F
:
5457 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5462 TCGLabel
*l1
= gen_new_label();
5463 TCGLabel
*l2
= gen_new_label();
5464 TCGLabel
*l3
= gen_new_label();
5465 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5466 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5469 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5470 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5471 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5474 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5478 case OPC_DDIVU_G_2E
:
5479 case OPC_DDIVU_G_2F
:
5481 TCGLabel
*l1
= gen_new_label();
5482 TCGLabel
*l2
= gen_new_label();
5483 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5484 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5487 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5494 TCGLabel
*l1
= gen_new_label();
5495 TCGLabel
*l2
= gen_new_label();
5496 TCGLabel
*l3
= gen_new_label();
5497 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5498 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5499 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5501 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5504 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5508 case OPC_DMODU_G_2E
:
5509 case OPC_DMODU_G_2F
:
5511 TCGLabel
*l1
= gen_new_label();
5512 TCGLabel
*l2
= gen_new_label();
5513 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5514 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5517 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5528 /* Loongson multimedia instructions */
5529 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
5531 uint32_t opc
, shift_max
;
5535 opc
= MASK_LMMI(ctx
->opcode
);
5541 t0
= tcg_temp_local_new_i64();
5542 t1
= tcg_temp_local_new_i64();
5545 t0
= tcg_temp_new_i64();
5546 t1
= tcg_temp_new_i64();
5550 check_cp1_enabled(ctx
);
5551 gen_load_fpr64(ctx
, t0
, rs
);
5552 gen_load_fpr64(ctx
, t1
, rt
);
5556 gen_helper_paddsh(t0
, t0
, t1
);
5559 gen_helper_paddush(t0
, t0
, t1
);
5562 gen_helper_paddh(t0
, t0
, t1
);
5565 gen_helper_paddw(t0
, t0
, t1
);
5568 gen_helper_paddsb(t0
, t0
, t1
);
5571 gen_helper_paddusb(t0
, t0
, t1
);
5574 gen_helper_paddb(t0
, t0
, t1
);
5578 gen_helper_psubsh(t0
, t0
, t1
);
5581 gen_helper_psubush(t0
, t0
, t1
);
5584 gen_helper_psubh(t0
, t0
, t1
);
5587 gen_helper_psubw(t0
, t0
, t1
);
5590 gen_helper_psubsb(t0
, t0
, t1
);
5593 gen_helper_psubusb(t0
, t0
, t1
);
5596 gen_helper_psubb(t0
, t0
, t1
);
5600 gen_helper_pshufh(t0
, t0
, t1
);
5603 gen_helper_packsswh(t0
, t0
, t1
);
5606 gen_helper_packsshb(t0
, t0
, t1
);
5609 gen_helper_packushb(t0
, t0
, t1
);
5613 gen_helper_punpcklhw(t0
, t0
, t1
);
5616 gen_helper_punpckhhw(t0
, t0
, t1
);
5619 gen_helper_punpcklbh(t0
, t0
, t1
);
5622 gen_helper_punpckhbh(t0
, t0
, t1
);
5625 gen_helper_punpcklwd(t0
, t0
, t1
);
5628 gen_helper_punpckhwd(t0
, t0
, t1
);
5632 gen_helper_pavgh(t0
, t0
, t1
);
5635 gen_helper_pavgb(t0
, t0
, t1
);
5638 gen_helper_pmaxsh(t0
, t0
, t1
);
5641 gen_helper_pminsh(t0
, t0
, t1
);
5644 gen_helper_pmaxub(t0
, t0
, t1
);
5647 gen_helper_pminub(t0
, t0
, t1
);
5651 gen_helper_pcmpeqw(t0
, t0
, t1
);
5654 gen_helper_pcmpgtw(t0
, t0
, t1
);
5657 gen_helper_pcmpeqh(t0
, t0
, t1
);
5660 gen_helper_pcmpgth(t0
, t0
, t1
);
5663 gen_helper_pcmpeqb(t0
, t0
, t1
);
5666 gen_helper_pcmpgtb(t0
, t0
, t1
);
5670 gen_helper_psllw(t0
, t0
, t1
);
5673 gen_helper_psllh(t0
, t0
, t1
);
5676 gen_helper_psrlw(t0
, t0
, t1
);
5679 gen_helper_psrlh(t0
, t0
, t1
);
5682 gen_helper_psraw(t0
, t0
, t1
);
5685 gen_helper_psrah(t0
, t0
, t1
);
5689 gen_helper_pmullh(t0
, t0
, t1
);
5692 gen_helper_pmulhh(t0
, t0
, t1
);
5695 gen_helper_pmulhuh(t0
, t0
, t1
);
5698 gen_helper_pmaddhw(t0
, t0
, t1
);
5702 gen_helper_pasubub(t0
, t0
, t1
);
5705 gen_helper_biadd(t0
, t0
);
5708 gen_helper_pmovmskb(t0
, t0
);
5712 tcg_gen_add_i64(t0
, t0
, t1
);
5715 tcg_gen_sub_i64(t0
, t0
, t1
);
5718 tcg_gen_xor_i64(t0
, t0
, t1
);
5721 tcg_gen_nor_i64(t0
, t0
, t1
);
5724 tcg_gen_and_i64(t0
, t0
, t1
);
5727 tcg_gen_or_i64(t0
, t0
, t1
);
5731 tcg_gen_andc_i64(t0
, t1
, t0
);
5735 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5738 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5741 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5744 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5748 tcg_gen_andi_i64(t1
, t1
, 3);
5749 tcg_gen_shli_i64(t1
, t1
, 4);
5750 tcg_gen_shr_i64(t0
, t0
, t1
);
5751 tcg_gen_ext16u_i64(t0
, t0
);
5755 tcg_gen_add_i64(t0
, t0
, t1
);
5756 tcg_gen_ext32s_i64(t0
, t0
);
5759 tcg_gen_sub_i64(t0
, t0
, t1
);
5760 tcg_gen_ext32s_i64(t0
, t0
);
5782 /* Make sure shift count isn't TCG undefined behaviour. */
5783 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5788 tcg_gen_shl_i64(t0
, t0
, t1
);
5793 * Since SRA is UndefinedResult without sign-extended inputs,
5794 * we can treat SRA and DSRA the same.
5796 tcg_gen_sar_i64(t0
, t0
, t1
);
5799 /* We want to shift in zeros for SRL; zero-extend first. */
5800 tcg_gen_ext32u_i64(t0
, t0
);
5803 tcg_gen_shr_i64(t0
, t0
, t1
);
5807 if (shift_max
== 32) {
5808 tcg_gen_ext32s_i64(t0
, t0
);
5811 /* Shifts larger than MAX produce zero. */
5812 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5813 tcg_gen_neg_i64(t1
, t1
);
5814 tcg_gen_and_i64(t0
, t0
, t1
);
5820 TCGv_i64 t2
= tcg_temp_new_i64();
5821 TCGLabel
*lab
= gen_new_label();
5823 tcg_gen_mov_i64(t2
, t0
);
5824 tcg_gen_add_i64(t0
, t1
, t2
);
5825 if (opc
== OPC_ADD_CP2
) {
5826 tcg_gen_ext32s_i64(t0
, t0
);
5828 tcg_gen_xor_i64(t1
, t1
, t2
);
5829 tcg_gen_xor_i64(t2
, t2
, t0
);
5830 tcg_gen_andc_i64(t1
, t2
, t1
);
5831 tcg_temp_free_i64(t2
);
5832 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5833 generate_exception(ctx
, EXCP_OVERFLOW
);
5841 TCGv_i64 t2
= tcg_temp_new_i64();
5842 TCGLabel
*lab
= gen_new_label();
5844 tcg_gen_mov_i64(t2
, t0
);
5845 tcg_gen_sub_i64(t0
, t1
, t2
);
5846 if (opc
== OPC_SUB_CP2
) {
5847 tcg_gen_ext32s_i64(t0
, t0
);
5849 tcg_gen_xor_i64(t1
, t1
, t2
);
5850 tcg_gen_xor_i64(t2
, t2
, t0
);
5851 tcg_gen_and_i64(t1
, t1
, t2
);
5852 tcg_temp_free_i64(t2
);
5853 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5854 generate_exception(ctx
, EXCP_OVERFLOW
);
5860 tcg_gen_ext32u_i64(t0
, t0
);
5861 tcg_gen_ext32u_i64(t1
, t1
);
5862 tcg_gen_mul_i64(t0
, t0
, t1
);
5871 cond
= TCG_COND_LTU
;
5879 cond
= TCG_COND_LEU
;
5886 int cc
= (ctx
->opcode
>> 8) & 0x7;
5887 TCGv_i64 t64
= tcg_temp_new_i64();
5888 TCGv_i32 t32
= tcg_temp_new_i32();
5890 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
5891 tcg_gen_extrl_i64_i32(t32
, t64
);
5892 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
5895 tcg_temp_free_i32(t32
);
5896 tcg_temp_free_i64(t64
);
5901 MIPS_INVAL("loongson_cp2");
5902 generate_exception_end(ctx
, EXCP_RI
);
5906 gen_store_fpr64(ctx
, t0
, rd
);
5909 tcg_temp_free_i64(t0
);
5910 tcg_temp_free_i64(t1
);
5914 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
5915 int rs
, int rt
, int16_t imm
)
5918 TCGv t0
= tcg_temp_new();
5919 TCGv t1
= tcg_temp_new();
5922 /* Load needed operands */
5930 /* Compare two registers */
5932 gen_load_gpr(t0
, rs
);
5933 gen_load_gpr(t1
, rt
);
5943 /* Compare register to immediate */
5944 if (rs
!= 0 || imm
!= 0) {
5945 gen_load_gpr(t0
, rs
);
5946 tcg_gen_movi_tl(t1
, (int32_t)imm
);
5953 case OPC_TEQ
: /* rs == rs */
5954 case OPC_TEQI
: /* r0 == 0 */
5955 case OPC_TGE
: /* rs >= rs */
5956 case OPC_TGEI
: /* r0 >= 0 */
5957 case OPC_TGEU
: /* rs >= rs unsigned */
5958 case OPC_TGEIU
: /* r0 >= 0 unsigned */
5960 generate_exception_end(ctx
, EXCP_TRAP
);
5962 case OPC_TLT
: /* rs < rs */
5963 case OPC_TLTI
: /* r0 < 0 */
5964 case OPC_TLTU
: /* rs < rs unsigned */
5965 case OPC_TLTIU
: /* r0 < 0 unsigned */
5966 case OPC_TNE
: /* rs != rs */
5967 case OPC_TNEI
: /* r0 != 0 */
5968 /* Never trap: treat as NOP. */
5972 TCGLabel
*l1
= gen_new_label();
5977 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
5981 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
5985 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
5989 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
5993 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
5997 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
6000 generate_exception(ctx
, EXCP_TRAP
);
6007 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
6009 if (unlikely(ctx
->base
.singlestep_enabled
)) {
6013 #ifndef CONFIG_USER_ONLY
6014 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
6020 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
6022 if (use_goto_tb(ctx
, dest
)) {
6025 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
6028 if (ctx
->base
.singlestep_enabled
) {
6029 save_cpu_state(ctx
, 0);
6030 gen_helper_raise_exception_debug(cpu_env
);
6032 tcg_gen_lookup_and_goto_ptr();
6036 /* Branches (before delay slot) */
6037 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
6039 int rs
, int rt
, int32_t offset
,
6042 target_ulong btgt
= -1;
6044 int bcond_compute
= 0;
6045 TCGv t0
= tcg_temp_new();
6046 TCGv t1
= tcg_temp_new();
6048 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
6049 #ifdef MIPS_DEBUG_DISAS
6050 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6051 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
6053 generate_exception_end(ctx
, EXCP_RI
);
6057 /* Load needed operands */
6063 /* Compare two registers */
6065 gen_load_gpr(t0
, rs
);
6066 gen_load_gpr(t1
, rt
);
6069 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6083 /* Compare to zero */
6085 gen_load_gpr(t0
, rs
);
6088 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6091 #if defined(TARGET_MIPS64)
6093 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
6095 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6098 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6103 /* Jump to immediate */
6104 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
6109 /* Jump to register */
6110 if (offset
!= 0 && offset
!= 16) {
6112 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6113 * others are reserved.
6115 MIPS_INVAL("jump hint");
6116 generate_exception_end(ctx
, EXCP_RI
);
6119 gen_load_gpr(btarget
, rs
);
6122 MIPS_INVAL("branch/jump");
6123 generate_exception_end(ctx
, EXCP_RI
);
6126 if (bcond_compute
== 0) {
6127 /* No condition to be computed */
6129 case OPC_BEQ
: /* rx == rx */
6130 case OPC_BEQL
: /* rx == rx likely */
6131 case OPC_BGEZ
: /* 0 >= 0 */
6132 case OPC_BGEZL
: /* 0 >= 0 likely */
6133 case OPC_BLEZ
: /* 0 <= 0 */
6134 case OPC_BLEZL
: /* 0 <= 0 likely */
6136 ctx
->hflags
|= MIPS_HFLAG_B
;
6138 case OPC_BGEZAL
: /* 0 >= 0 */
6139 case OPC_BGEZALL
: /* 0 >= 0 likely */
6140 /* Always take and link */
6142 ctx
->hflags
|= MIPS_HFLAG_B
;
6144 case OPC_BNE
: /* rx != rx */
6145 case OPC_BGTZ
: /* 0 > 0 */
6146 case OPC_BLTZ
: /* 0 < 0 */
6149 case OPC_BLTZAL
: /* 0 < 0 */
6151 * Handle as an unconditional branch to get correct delay
6155 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6156 ctx
->hflags
|= MIPS_HFLAG_B
;
6158 case OPC_BLTZALL
: /* 0 < 0 likely */
6159 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6160 /* Skip the instruction in the delay slot */
6161 ctx
->base
.pc_next
+= 4;
6163 case OPC_BNEL
: /* rx != rx likely */
6164 case OPC_BGTZL
: /* 0 > 0 likely */
6165 case OPC_BLTZL
: /* 0 < 0 likely */
6166 /* Skip the instruction in the delay slot */
6167 ctx
->base
.pc_next
+= 4;
6170 ctx
->hflags
|= MIPS_HFLAG_B
;
6173 ctx
->hflags
|= MIPS_HFLAG_BX
;
6177 ctx
->hflags
|= MIPS_HFLAG_B
;
6180 ctx
->hflags
|= MIPS_HFLAG_BR
;
6184 ctx
->hflags
|= MIPS_HFLAG_BR
;
6187 MIPS_INVAL("branch/jump");
6188 generate_exception_end(ctx
, EXCP_RI
);
6194 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6197 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6200 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6203 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6206 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6209 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6212 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6216 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6220 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6223 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6226 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6229 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6232 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6235 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6238 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6240 #if defined(TARGET_MIPS64)
6242 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6246 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6249 ctx
->hflags
|= MIPS_HFLAG_BC
;
6252 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6255 ctx
->hflags
|= MIPS_HFLAG_BL
;
6258 MIPS_INVAL("conditional branch/jump");
6259 generate_exception_end(ctx
, EXCP_RI
);
6264 ctx
->btarget
= btgt
;
6266 switch (delayslot_size
) {
6268 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6271 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6276 int post_delay
= insn_bytes
+ delayslot_size
;
6277 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6279 tcg_gen_movi_tl(cpu_gpr
[blink
],
6280 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6284 if (insn_bytes
== 2) {
6285 ctx
->hflags
|= MIPS_HFLAG_B16
;
6292 /* nanoMIPS Branches */
6293 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6295 int rs
, int rt
, int32_t offset
)
6297 target_ulong btgt
= -1;
6298 int bcond_compute
= 0;
6299 TCGv t0
= tcg_temp_new();
6300 TCGv t1
= tcg_temp_new();
6302 /* Load needed operands */
6306 /* Compare two registers */
6308 gen_load_gpr(t0
, rs
);
6309 gen_load_gpr(t1
, rt
);
6312 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6315 /* Compare to zero */
6317 gen_load_gpr(t0
, rs
);
6320 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6323 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6325 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6329 /* Jump to register */
6330 if (offset
!= 0 && offset
!= 16) {
6332 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6333 * others are reserved.
6335 MIPS_INVAL("jump hint");
6336 generate_exception_end(ctx
, EXCP_RI
);
6339 gen_load_gpr(btarget
, rs
);
6342 MIPS_INVAL("branch/jump");
6343 generate_exception_end(ctx
, EXCP_RI
);
6346 if (bcond_compute
== 0) {
6347 /* No condition to be computed */
6349 case OPC_BEQ
: /* rx == rx */
6351 ctx
->hflags
|= MIPS_HFLAG_B
;
6353 case OPC_BGEZAL
: /* 0 >= 0 */
6354 /* Always take and link */
6355 tcg_gen_movi_tl(cpu_gpr
[31],
6356 ctx
->base
.pc_next
+ insn_bytes
);
6357 ctx
->hflags
|= MIPS_HFLAG_B
;
6359 case OPC_BNE
: /* rx != rx */
6360 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6361 /* Skip the instruction in the delay slot */
6362 ctx
->base
.pc_next
+= 4;
6365 ctx
->hflags
|= MIPS_HFLAG_BR
;
6369 tcg_gen_movi_tl(cpu_gpr
[rt
],
6370 ctx
->base
.pc_next
+ insn_bytes
);
6372 ctx
->hflags
|= MIPS_HFLAG_BR
;
6375 MIPS_INVAL("branch/jump");
6376 generate_exception_end(ctx
, EXCP_RI
);
6382 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6385 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6388 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6389 tcg_gen_movi_tl(cpu_gpr
[31],
6390 ctx
->base
.pc_next
+ insn_bytes
);
6393 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6395 ctx
->hflags
|= MIPS_HFLAG_BC
;
6398 MIPS_INVAL("conditional branch/jump");
6399 generate_exception_end(ctx
, EXCP_RI
);
6404 ctx
->btarget
= btgt
;
6407 if (insn_bytes
== 2) {
6408 ctx
->hflags
|= MIPS_HFLAG_B16
;
6415 /* special3 bitfield operations */
6416 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6417 int rs
, int lsb
, int msb
)
6419 TCGv t0
= tcg_temp_new();
6420 TCGv t1
= tcg_temp_new();
6422 gen_load_gpr(t1
, rs
);
6425 if (lsb
+ msb
> 31) {
6429 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6432 * The two checks together imply that lsb == 0,
6433 * so this is a simple sign-extension.
6435 tcg_gen_ext32s_tl(t0
, t1
);
6438 #if defined(TARGET_MIPS64)
6447 if (lsb
+ msb
> 63) {
6450 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6457 gen_load_gpr(t0
, rt
);
6458 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6459 tcg_gen_ext32s_tl(t0
, t0
);
6461 #if defined(TARGET_MIPS64)
6472 gen_load_gpr(t0
, rt
);
6473 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6478 MIPS_INVAL("bitops");
6479 generate_exception_end(ctx
, EXCP_RI
);
6484 gen_store_gpr(t0
, rt
);
6489 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6494 /* If no destination, treat it as a NOP. */
6498 t0
= tcg_temp_new();
6499 gen_load_gpr(t0
, rt
);
6503 TCGv t1
= tcg_temp_new();
6504 TCGv t2
= tcg_const_tl(0x00FF00FF);
6506 tcg_gen_shri_tl(t1
, t0
, 8);
6507 tcg_gen_and_tl(t1
, t1
, t2
);
6508 tcg_gen_and_tl(t0
, t0
, t2
);
6509 tcg_gen_shli_tl(t0
, t0
, 8);
6510 tcg_gen_or_tl(t0
, t0
, t1
);
6513 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6517 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6520 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6522 #if defined(TARGET_MIPS64)
6525 TCGv t1
= tcg_temp_new();
6526 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6528 tcg_gen_shri_tl(t1
, t0
, 8);
6529 tcg_gen_and_tl(t1
, t1
, t2
);
6530 tcg_gen_and_tl(t0
, t0
, t2
);
6531 tcg_gen_shli_tl(t0
, t0
, 8);
6532 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6539 TCGv t1
= tcg_temp_new();
6540 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6542 tcg_gen_shri_tl(t1
, t0
, 16);
6543 tcg_gen_and_tl(t1
, t1
, t2
);
6544 tcg_gen_and_tl(t0
, t0
, t2
);
6545 tcg_gen_shli_tl(t0
, t0
, 16);
6546 tcg_gen_or_tl(t0
, t0
, t1
);
6547 tcg_gen_shri_tl(t1
, t0
, 32);
6548 tcg_gen_shli_tl(t0
, t0
, 32);
6549 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6556 MIPS_INVAL("bsfhl");
6557 generate_exception_end(ctx
, EXCP_RI
);
6564 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
6573 t0
= tcg_temp_new();
6574 t1
= tcg_temp_new();
6575 gen_load_gpr(t0
, rs
);
6576 gen_load_gpr(t1
, rt
);
6577 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
6578 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
6579 if (opc
== OPC_LSA
) {
6580 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
6589 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
6597 t0
= tcg_temp_new();
6598 if (bits
== 0 || bits
== wordsz
) {
6600 gen_load_gpr(t0
, rt
);
6602 gen_load_gpr(t0
, rs
);
6606 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6608 #if defined(TARGET_MIPS64)
6610 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
6615 TCGv t1
= tcg_temp_new();
6616 gen_load_gpr(t0
, rt
);
6617 gen_load_gpr(t1
, rs
);
6621 TCGv_i64 t2
= tcg_temp_new_i64();
6622 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
6623 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
6624 gen_move_low32(cpu_gpr
[rd
], t2
);
6625 tcg_temp_free_i64(t2
);
6628 #if defined(TARGET_MIPS64)
6630 tcg_gen_shli_tl(t0
, t0
, bits
);
6631 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
6632 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
6642 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6645 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
6648 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6651 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
6654 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
6661 t0
= tcg_temp_new();
6662 gen_load_gpr(t0
, rt
);
6665 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
6667 #if defined(TARGET_MIPS64)
6669 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
6676 #ifndef CONFIG_USER_ONLY
6677 /* CP0 (MMU and control) */
6678 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
6680 TCGv_i64 t0
= tcg_temp_new_i64();
6681 TCGv_i64 t1
= tcg_temp_new_i64();
6683 tcg_gen_ext_tl_i64(t0
, arg
);
6684 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6685 #if defined(TARGET_MIPS64)
6686 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
6688 tcg_gen_concat32_i64(t1
, t1
, t0
);
6690 tcg_gen_st_i64(t1
, cpu_env
, off
);
6691 tcg_temp_free_i64(t1
);
6692 tcg_temp_free_i64(t0
);
6695 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
6697 TCGv_i64 t0
= tcg_temp_new_i64();
6698 TCGv_i64 t1
= tcg_temp_new_i64();
6700 tcg_gen_ext_tl_i64(t0
, arg
);
6701 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6702 tcg_gen_concat32_i64(t1
, t1
, t0
);
6703 tcg_gen_st_i64(t1
, cpu_env
, off
);
6704 tcg_temp_free_i64(t1
);
6705 tcg_temp_free_i64(t0
);
6708 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
6710 TCGv_i64 t0
= tcg_temp_new_i64();
6712 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6713 #if defined(TARGET_MIPS64)
6714 tcg_gen_shri_i64(t0
, t0
, 30);
6716 tcg_gen_shri_i64(t0
, t0
, 32);
6718 gen_move_low32(arg
, t0
);
6719 tcg_temp_free_i64(t0
);
6722 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
6724 TCGv_i64 t0
= tcg_temp_new_i64();
6726 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6727 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
6728 gen_move_low32(arg
, t0
);
6729 tcg_temp_free_i64(t0
);
6732 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
6734 TCGv_i32 t0
= tcg_temp_new_i32();
6736 tcg_gen_ld_i32(t0
, cpu_env
, off
);
6737 tcg_gen_ext_i32_tl(arg
, t0
);
6738 tcg_temp_free_i32(t0
);
6741 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
6743 tcg_gen_ld_tl(arg
, cpu_env
, off
);
6744 tcg_gen_ext32s_tl(arg
, arg
);
6747 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
6749 TCGv_i32 t0
= tcg_temp_new_i32();
6751 tcg_gen_trunc_tl_i32(t0
, arg
);
6752 tcg_gen_st_i32(t0
, cpu_env
, off
);
6753 tcg_temp_free_i32(t0
);
6756 #define CP0_CHECK(c) \
6759 goto cp0_unimplemented; \
6763 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6765 const char *register_name
= "invalid";
6768 case CP0_REGISTER_02
:
6771 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6772 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6773 register_name
= "EntryLo0";
6776 goto cp0_unimplemented
;
6779 case CP0_REGISTER_03
:
6781 case CP0_REG03__ENTRYLO1
:
6782 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6783 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6784 register_name
= "EntryLo1";
6787 goto cp0_unimplemented
;
6790 case CP0_REGISTER_09
:
6792 case CP0_REG09__SAAR
:
6793 CP0_CHECK(ctx
->saar
);
6794 gen_helper_mfhc0_saar(arg
, cpu_env
);
6795 register_name
= "SAAR";
6798 goto cp0_unimplemented
;
6801 case CP0_REGISTER_17
:
6803 case CP0_REG17__LLADDR
:
6804 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
6805 ctx
->CP0_LLAddr_shift
);
6806 register_name
= "LLAddr";
6808 case CP0_REG17__MAAR
:
6809 CP0_CHECK(ctx
->mrp
);
6810 gen_helper_mfhc0_maar(arg
, cpu_env
);
6811 register_name
= "MAAR";
6814 goto cp0_unimplemented
;
6817 case CP0_REGISTER_19
:
6819 case CP0_REG19__WATCHHI0
:
6820 case CP0_REG19__WATCHHI1
:
6821 case CP0_REG19__WATCHHI2
:
6822 case CP0_REG19__WATCHHI3
:
6823 case CP0_REG19__WATCHHI4
:
6824 case CP0_REG19__WATCHHI5
:
6825 case CP0_REG19__WATCHHI6
:
6826 case CP0_REG19__WATCHHI7
:
6827 /* upper 32 bits are only available when Config5MI != 0 */
6829 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
6830 register_name
= "WatchHi";
6833 goto cp0_unimplemented
;
6836 case CP0_REGISTER_28
:
6842 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
6843 register_name
= "TagLo";
6846 goto cp0_unimplemented
;
6850 goto cp0_unimplemented
;
6852 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
6856 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
6857 register_name
, reg
, sel
);
6858 tcg_gen_movi_tl(arg
, 0);
6861 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6863 const char *register_name
= "invalid";
6864 uint64_t mask
= ctx
->PAMask
>> 36;
6867 case CP0_REGISTER_02
:
6870 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6871 tcg_gen_andi_tl(arg
, arg
, mask
);
6872 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6873 register_name
= "EntryLo0";
6876 goto cp0_unimplemented
;
6879 case CP0_REGISTER_03
:
6881 case CP0_REG03__ENTRYLO1
:
6882 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6883 tcg_gen_andi_tl(arg
, arg
, mask
);
6884 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6885 register_name
= "EntryLo1";
6888 goto cp0_unimplemented
;
6891 case CP0_REGISTER_09
:
6893 case CP0_REG09__SAAR
:
6894 CP0_CHECK(ctx
->saar
);
6895 gen_helper_mthc0_saar(cpu_env
, arg
);
6896 register_name
= "SAAR";
6899 goto cp0_unimplemented
;
6902 case CP0_REGISTER_17
:
6904 case CP0_REG17__LLADDR
:
6906 * LLAddr is read-only (the only exception is bit 0 if LLB is
6907 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6908 * relevant for modern MIPS cores supporting MTHC0, therefore
6909 * treating MTHC0 to LLAddr as NOP.
6911 register_name
= "LLAddr";
6913 case CP0_REG17__MAAR
:
6914 CP0_CHECK(ctx
->mrp
);
6915 gen_helper_mthc0_maar(cpu_env
, arg
);
6916 register_name
= "MAAR";
6919 goto cp0_unimplemented
;
6922 case CP0_REGISTER_19
:
6924 case CP0_REG19__WATCHHI0
:
6925 case CP0_REG19__WATCHHI1
:
6926 case CP0_REG19__WATCHHI2
:
6927 case CP0_REG19__WATCHHI3
:
6928 case CP0_REG19__WATCHHI4
:
6929 case CP0_REG19__WATCHHI5
:
6930 case CP0_REG19__WATCHHI6
:
6931 case CP0_REG19__WATCHHI7
:
6932 /* upper 32 bits are only available when Config5MI != 0 */
6934 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
6935 register_name
= "WatchHi";
6938 goto cp0_unimplemented
;
6941 case CP0_REGISTER_28
:
6947 tcg_gen_andi_tl(arg
, arg
, mask
);
6948 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6949 register_name
= "TagLo";
6952 goto cp0_unimplemented
;
6956 goto cp0_unimplemented
;
6958 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
6961 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
6962 register_name
, reg
, sel
);
6965 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
6967 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
6968 tcg_gen_movi_tl(arg
, 0);
6970 tcg_gen_movi_tl(arg
, ~0);
6974 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6976 const char *register_name
= "invalid";
6979 check_insn(ctx
, ISA_MIPS32
);
6983 case CP0_REGISTER_00
:
6985 case CP0_REG00__INDEX
:
6986 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6987 register_name
= "Index";
6989 case CP0_REG00__MVPCONTROL
:
6990 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6991 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6992 register_name
= "MVPControl";
6994 case CP0_REG00__MVPCONF0
:
6995 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6996 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6997 register_name
= "MVPConf0";
6999 case CP0_REG00__MVPCONF1
:
7000 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7001 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7002 register_name
= "MVPConf1";
7004 case CP0_REG00__VPCONTROL
:
7006 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7007 register_name
= "VPControl";
7010 goto cp0_unimplemented
;
7013 case CP0_REGISTER_01
:
7015 case CP0_REG01__RANDOM
:
7016 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7017 gen_helper_mfc0_random(arg
, cpu_env
);
7018 register_name
= "Random";
7020 case CP0_REG01__VPECONTROL
:
7021 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7022 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7023 register_name
= "VPEControl";
7025 case CP0_REG01__VPECONF0
:
7026 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7027 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7028 register_name
= "VPEConf0";
7030 case CP0_REG01__VPECONF1
:
7031 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7032 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7033 register_name
= "VPEConf1";
7035 case CP0_REG01__YQMASK
:
7036 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7037 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
7038 register_name
= "YQMask";
7040 case CP0_REG01__VPESCHEDULE
:
7041 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7042 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7043 register_name
= "VPESchedule";
7045 case CP0_REG01__VPESCHEFBACK
:
7046 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7047 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7048 register_name
= "VPEScheFBack";
7050 case CP0_REG01__VPEOPT
:
7051 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7052 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7053 register_name
= "VPEOpt";
7056 goto cp0_unimplemented
;
7059 case CP0_REGISTER_02
:
7061 case CP0_REG02__ENTRYLO0
:
7063 TCGv_i64 tmp
= tcg_temp_new_i64();
7064 tcg_gen_ld_i64(tmp
, cpu_env
,
7065 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7066 #if defined(TARGET_MIPS64)
7068 /* Move RI/XI fields to bits 31:30 */
7069 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7070 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7073 gen_move_low32(arg
, tmp
);
7074 tcg_temp_free_i64(tmp
);
7076 register_name
= "EntryLo0";
7078 case CP0_REG02__TCSTATUS
:
7079 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7080 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7081 register_name
= "TCStatus";
7083 case CP0_REG02__TCBIND
:
7084 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7085 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7086 register_name
= "TCBind";
7088 case CP0_REG02__TCRESTART
:
7089 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7090 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
7091 register_name
= "TCRestart";
7093 case CP0_REG02__TCHALT
:
7094 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7095 gen_helper_mfc0_tchalt(arg
, cpu_env
);
7096 register_name
= "TCHalt";
7098 case CP0_REG02__TCCONTEXT
:
7099 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7100 gen_helper_mfc0_tccontext(arg
, cpu_env
);
7101 register_name
= "TCContext";
7103 case CP0_REG02__TCSCHEDULE
:
7104 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7105 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
7106 register_name
= "TCSchedule";
7108 case CP0_REG02__TCSCHEFBACK
:
7109 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7110 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
7111 register_name
= "TCScheFBack";
7114 goto cp0_unimplemented
;
7117 case CP0_REGISTER_03
:
7119 case CP0_REG03__ENTRYLO1
:
7121 TCGv_i64 tmp
= tcg_temp_new_i64();
7122 tcg_gen_ld_i64(tmp
, cpu_env
,
7123 offsetof(CPUMIPSState
, CP0_EntryLo1
));
7124 #if defined(TARGET_MIPS64)
7126 /* Move RI/XI fields to bits 31:30 */
7127 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7128 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7131 gen_move_low32(arg
, tmp
);
7132 tcg_temp_free_i64(tmp
);
7134 register_name
= "EntryLo1";
7136 case CP0_REG03__GLOBALNUM
:
7138 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7139 register_name
= "GlobalNumber";
7142 goto cp0_unimplemented
;
7145 case CP0_REGISTER_04
:
7147 case CP0_REG04__CONTEXT
:
7148 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7149 tcg_gen_ext32s_tl(arg
, arg
);
7150 register_name
= "Context";
7152 case CP0_REG04__CONTEXTCONFIG
:
7154 /* gen_helper_mfc0_contextconfig(arg); */
7155 register_name
= "ContextConfig";
7156 goto cp0_unimplemented
;
7157 case CP0_REG04__USERLOCAL
:
7158 CP0_CHECK(ctx
->ulri
);
7159 tcg_gen_ld_tl(arg
, cpu_env
,
7160 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7161 tcg_gen_ext32s_tl(arg
, arg
);
7162 register_name
= "UserLocal";
7164 case CP0_REG04__MMID
:
7166 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7167 register_name
= "MMID";
7170 goto cp0_unimplemented
;
7173 case CP0_REGISTER_05
:
7175 case CP0_REG05__PAGEMASK
:
7176 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7177 register_name
= "PageMask";
7179 case CP0_REG05__PAGEGRAIN
:
7180 check_insn(ctx
, ISA_MIPS32R2
);
7181 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7182 register_name
= "PageGrain";
7184 case CP0_REG05__SEGCTL0
:
7186 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7187 tcg_gen_ext32s_tl(arg
, arg
);
7188 register_name
= "SegCtl0";
7190 case CP0_REG05__SEGCTL1
:
7192 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7193 tcg_gen_ext32s_tl(arg
, arg
);
7194 register_name
= "SegCtl1";
7196 case CP0_REG05__SEGCTL2
:
7198 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7199 tcg_gen_ext32s_tl(arg
, arg
);
7200 register_name
= "SegCtl2";
7202 case CP0_REG05__PWBASE
:
7204 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7205 register_name
= "PWBase";
7207 case CP0_REG05__PWFIELD
:
7209 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7210 register_name
= "PWField";
7212 case CP0_REG05__PWSIZE
:
7214 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7215 register_name
= "PWSize";
7218 goto cp0_unimplemented
;
7221 case CP0_REGISTER_06
:
7223 case CP0_REG06__WIRED
:
7224 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7225 register_name
= "Wired";
7227 case CP0_REG06__SRSCONF0
:
7228 check_insn(ctx
, ISA_MIPS32R2
);
7229 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7230 register_name
= "SRSConf0";
7232 case CP0_REG06__SRSCONF1
:
7233 check_insn(ctx
, ISA_MIPS32R2
);
7234 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7235 register_name
= "SRSConf1";
7237 case CP0_REG06__SRSCONF2
:
7238 check_insn(ctx
, ISA_MIPS32R2
);
7239 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7240 register_name
= "SRSConf2";
7242 case CP0_REG06__SRSCONF3
:
7243 check_insn(ctx
, ISA_MIPS32R2
);
7244 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7245 register_name
= "SRSConf3";
7247 case CP0_REG06__SRSCONF4
:
7248 check_insn(ctx
, ISA_MIPS32R2
);
7249 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7250 register_name
= "SRSConf4";
7252 case CP0_REG06__PWCTL
:
7254 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7255 register_name
= "PWCtl";
7258 goto cp0_unimplemented
;
7261 case CP0_REGISTER_07
:
7263 case CP0_REG07__HWRENA
:
7264 check_insn(ctx
, ISA_MIPS32R2
);
7265 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7266 register_name
= "HWREna";
7269 goto cp0_unimplemented
;
7272 case CP0_REGISTER_08
:
7274 case CP0_REG08__BADVADDR
:
7275 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7276 tcg_gen_ext32s_tl(arg
, arg
);
7277 register_name
= "BadVAddr";
7279 case CP0_REG08__BADINSTR
:
7281 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7282 register_name
= "BadInstr";
7284 case CP0_REG08__BADINSTRP
:
7286 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7287 register_name
= "BadInstrP";
7289 case CP0_REG08__BADINSTRX
:
7291 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7292 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7293 register_name
= "BadInstrX";
7296 goto cp0_unimplemented
;
7299 case CP0_REGISTER_09
:
7301 case CP0_REG09__COUNT
:
7302 /* Mark as an IO operation because we read the time. */
7303 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7306 gen_helper_mfc0_count(arg
, cpu_env
);
7308 * Break the TB to be able to take timer interrupts immediately
7309 * after reading count. DISAS_STOP isn't sufficient, we need to
7310 * ensure we break completely out of translated code.
7312 gen_save_pc(ctx
->base
.pc_next
+ 4);
7313 ctx
->base
.is_jmp
= DISAS_EXIT
;
7314 register_name
= "Count";
7316 case CP0_REG09__SAARI
:
7317 CP0_CHECK(ctx
->saar
);
7318 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7319 register_name
= "SAARI";
7321 case CP0_REG09__SAAR
:
7322 CP0_CHECK(ctx
->saar
);
7323 gen_helper_mfc0_saar(arg
, cpu_env
);
7324 register_name
= "SAAR";
7327 goto cp0_unimplemented
;
7330 case CP0_REGISTER_10
:
7332 case CP0_REG10__ENTRYHI
:
7333 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7334 tcg_gen_ext32s_tl(arg
, arg
);
7335 register_name
= "EntryHi";
7338 goto cp0_unimplemented
;
7341 case CP0_REGISTER_11
:
7343 case CP0_REG11__COMPARE
:
7344 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7345 register_name
= "Compare";
7347 /* 6,7 are implementation dependent */
7349 goto cp0_unimplemented
;
7352 case CP0_REGISTER_12
:
7354 case CP0_REG12__STATUS
:
7355 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7356 register_name
= "Status";
7358 case CP0_REG12__INTCTL
:
7359 check_insn(ctx
, ISA_MIPS32R2
);
7360 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7361 register_name
= "IntCtl";
7363 case CP0_REG12__SRSCTL
:
7364 check_insn(ctx
, ISA_MIPS32R2
);
7365 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7366 register_name
= "SRSCtl";
7368 case CP0_REG12__SRSMAP
:
7369 check_insn(ctx
, ISA_MIPS32R2
);
7370 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7371 register_name
= "SRSMap";
7374 goto cp0_unimplemented
;
7377 case CP0_REGISTER_13
:
7379 case CP0_REG13__CAUSE
:
7380 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7381 register_name
= "Cause";
7384 goto cp0_unimplemented
;
7387 case CP0_REGISTER_14
:
7389 case CP0_REG14__EPC
:
7390 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7391 tcg_gen_ext32s_tl(arg
, arg
);
7392 register_name
= "EPC";
7395 goto cp0_unimplemented
;
7398 case CP0_REGISTER_15
:
7400 case CP0_REG15__PRID
:
7401 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7402 register_name
= "PRid";
7404 case CP0_REG15__EBASE
:
7405 check_insn(ctx
, ISA_MIPS32R2
);
7406 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7407 tcg_gen_ext32s_tl(arg
, arg
);
7408 register_name
= "EBase";
7410 case CP0_REG15__CMGCRBASE
:
7411 check_insn(ctx
, ISA_MIPS32R2
);
7412 CP0_CHECK(ctx
->cmgcr
);
7413 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7414 tcg_gen_ext32s_tl(arg
, arg
);
7415 register_name
= "CMGCRBase";
7418 goto cp0_unimplemented
;
7421 case CP0_REGISTER_16
:
7423 case CP0_REG16__CONFIG
:
7424 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7425 register_name
= "Config";
7427 case CP0_REG16__CONFIG1
:
7428 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7429 register_name
= "Config1";
7431 case CP0_REG16__CONFIG2
:
7432 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7433 register_name
= "Config2";
7435 case CP0_REG16__CONFIG3
:
7436 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7437 register_name
= "Config3";
7439 case CP0_REG16__CONFIG4
:
7440 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7441 register_name
= "Config4";
7443 case CP0_REG16__CONFIG5
:
7444 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7445 register_name
= "Config5";
7447 /* 6,7 are implementation dependent */
7448 case CP0_REG16__CONFIG6
:
7449 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7450 register_name
= "Config6";
7452 case CP0_REG16__CONFIG7
:
7453 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7454 register_name
= "Config7";
7457 goto cp0_unimplemented
;
7460 case CP0_REGISTER_17
:
7462 case CP0_REG17__LLADDR
:
7463 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7464 register_name
= "LLAddr";
7466 case CP0_REG17__MAAR
:
7467 CP0_CHECK(ctx
->mrp
);
7468 gen_helper_mfc0_maar(arg
, cpu_env
);
7469 register_name
= "MAAR";
7471 case CP0_REG17__MAARI
:
7472 CP0_CHECK(ctx
->mrp
);
7473 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7474 register_name
= "MAARI";
7477 goto cp0_unimplemented
;
7480 case CP0_REGISTER_18
:
7482 case CP0_REG18__WATCHLO0
:
7483 case CP0_REG18__WATCHLO1
:
7484 case CP0_REG18__WATCHLO2
:
7485 case CP0_REG18__WATCHLO3
:
7486 case CP0_REG18__WATCHLO4
:
7487 case CP0_REG18__WATCHLO5
:
7488 case CP0_REG18__WATCHLO6
:
7489 case CP0_REG18__WATCHLO7
:
7490 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7491 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7492 register_name
= "WatchLo";
7495 goto cp0_unimplemented
;
7498 case CP0_REGISTER_19
:
7500 case CP0_REG19__WATCHHI0
:
7501 case CP0_REG19__WATCHHI1
:
7502 case CP0_REG19__WATCHHI2
:
7503 case CP0_REG19__WATCHHI3
:
7504 case CP0_REG19__WATCHHI4
:
7505 case CP0_REG19__WATCHHI5
:
7506 case CP0_REG19__WATCHHI6
:
7507 case CP0_REG19__WATCHHI7
:
7508 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7509 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7510 register_name
= "WatchHi";
7513 goto cp0_unimplemented
;
7516 case CP0_REGISTER_20
:
7518 case CP0_REG20__XCONTEXT
:
7519 #if defined(TARGET_MIPS64)
7520 check_insn(ctx
, ISA_MIPS3
);
7521 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7522 tcg_gen_ext32s_tl(arg
, arg
);
7523 register_name
= "XContext";
7527 goto cp0_unimplemented
;
7530 case CP0_REGISTER_21
:
7531 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7532 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7535 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7536 register_name
= "Framemask";
7539 goto cp0_unimplemented
;
7542 case CP0_REGISTER_22
:
7543 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7544 register_name
= "'Diagnostic"; /* implementation dependent */
7546 case CP0_REGISTER_23
:
7548 case CP0_REG23__DEBUG
:
7549 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7550 register_name
= "Debug";
7552 case CP0_REG23__TRACECONTROL
:
7553 /* PDtrace support */
7554 /* gen_helper_mfc0_tracecontrol(arg); */
7555 register_name
= "TraceControl";
7556 goto cp0_unimplemented
;
7557 case CP0_REG23__TRACECONTROL2
:
7558 /* PDtrace support */
7559 /* gen_helper_mfc0_tracecontrol2(arg); */
7560 register_name
= "TraceControl2";
7561 goto cp0_unimplemented
;
7562 case CP0_REG23__USERTRACEDATA1
:
7563 /* PDtrace support */
7564 /* gen_helper_mfc0_usertracedata1(arg);*/
7565 register_name
= "UserTraceData1";
7566 goto cp0_unimplemented
;
7567 case CP0_REG23__TRACEIBPC
:
7568 /* PDtrace support */
7569 /* gen_helper_mfc0_traceibpc(arg); */
7570 register_name
= "TraceIBPC";
7571 goto cp0_unimplemented
;
7572 case CP0_REG23__TRACEDBPC
:
7573 /* PDtrace support */
7574 /* gen_helper_mfc0_tracedbpc(arg); */
7575 register_name
= "TraceDBPC";
7576 goto cp0_unimplemented
;
7578 goto cp0_unimplemented
;
7581 case CP0_REGISTER_24
:
7583 case CP0_REG24__DEPC
:
7585 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7586 tcg_gen_ext32s_tl(arg
, arg
);
7587 register_name
= "DEPC";
7590 goto cp0_unimplemented
;
7593 case CP0_REGISTER_25
:
7595 case CP0_REG25__PERFCTL0
:
7596 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
7597 register_name
= "Performance0";
7599 case CP0_REG25__PERFCNT0
:
7600 /* gen_helper_mfc0_performance1(arg); */
7601 register_name
= "Performance1";
7602 goto cp0_unimplemented
;
7603 case CP0_REG25__PERFCTL1
:
7604 /* gen_helper_mfc0_performance2(arg); */
7605 register_name
= "Performance2";
7606 goto cp0_unimplemented
;
7607 case CP0_REG25__PERFCNT1
:
7608 /* gen_helper_mfc0_performance3(arg); */
7609 register_name
= "Performance3";
7610 goto cp0_unimplemented
;
7611 case CP0_REG25__PERFCTL2
:
7612 /* gen_helper_mfc0_performance4(arg); */
7613 register_name
= "Performance4";
7614 goto cp0_unimplemented
;
7615 case CP0_REG25__PERFCNT2
:
7616 /* gen_helper_mfc0_performance5(arg); */
7617 register_name
= "Performance5";
7618 goto cp0_unimplemented
;
7619 case CP0_REG25__PERFCTL3
:
7620 /* gen_helper_mfc0_performance6(arg); */
7621 register_name
= "Performance6";
7622 goto cp0_unimplemented
;
7623 case CP0_REG25__PERFCNT3
:
7624 /* gen_helper_mfc0_performance7(arg); */
7625 register_name
= "Performance7";
7626 goto cp0_unimplemented
;
7628 goto cp0_unimplemented
;
7631 case CP0_REGISTER_26
:
7633 case CP0_REG26__ERRCTL
:
7634 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
7635 register_name
= "ErrCtl";
7638 goto cp0_unimplemented
;
7641 case CP0_REGISTER_27
:
7643 case CP0_REG27__CACHERR
:
7644 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7645 register_name
= "CacheErr";
7648 goto cp0_unimplemented
;
7651 case CP0_REGISTER_28
:
7653 case CP0_REG28__TAGLO
:
7654 case CP0_REG28__TAGLO1
:
7655 case CP0_REG28__TAGLO2
:
7656 case CP0_REG28__TAGLO3
:
7658 TCGv_i64 tmp
= tcg_temp_new_i64();
7659 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
7660 gen_move_low32(arg
, tmp
);
7661 tcg_temp_free_i64(tmp
);
7663 register_name
= "TagLo";
7665 case CP0_REG28__DATALO
:
7666 case CP0_REG28__DATALO1
:
7667 case CP0_REG28__DATALO2
:
7668 case CP0_REG28__DATALO3
:
7669 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7670 register_name
= "DataLo";
7673 goto cp0_unimplemented
;
7676 case CP0_REGISTER_29
:
7678 case CP0_REG29__TAGHI
:
7679 case CP0_REG29__TAGHI1
:
7680 case CP0_REG29__TAGHI2
:
7681 case CP0_REG29__TAGHI3
:
7682 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7683 register_name
= "TagHi";
7685 case CP0_REG29__DATAHI
:
7686 case CP0_REG29__DATAHI1
:
7687 case CP0_REG29__DATAHI2
:
7688 case CP0_REG29__DATAHI3
:
7689 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7690 register_name
= "DataHi";
7693 goto cp0_unimplemented
;
7696 case CP0_REGISTER_30
:
7698 case CP0_REG30__ERROREPC
:
7699 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7700 tcg_gen_ext32s_tl(arg
, arg
);
7701 register_name
= "ErrorEPC";
7704 goto cp0_unimplemented
;
7707 case CP0_REGISTER_31
:
7709 case CP0_REG31__DESAVE
:
7711 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7712 register_name
= "DESAVE";
7714 case CP0_REG31__KSCRATCH1
:
7715 case CP0_REG31__KSCRATCH2
:
7716 case CP0_REG31__KSCRATCH3
:
7717 case CP0_REG31__KSCRATCH4
:
7718 case CP0_REG31__KSCRATCH5
:
7719 case CP0_REG31__KSCRATCH6
:
7720 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7721 tcg_gen_ld_tl(arg
, cpu_env
,
7722 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7723 tcg_gen_ext32s_tl(arg
, arg
);
7724 register_name
= "KScratch";
7727 goto cp0_unimplemented
;
7731 goto cp0_unimplemented
;
7733 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
7737 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
7738 register_name
, reg
, sel
);
7739 gen_mfc0_unimplemented(ctx
, arg
);
7742 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7744 const char *register_name
= "invalid";
7747 check_insn(ctx
, ISA_MIPS32
);
7750 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7755 case CP0_REGISTER_00
:
7757 case CP0_REG00__INDEX
:
7758 gen_helper_mtc0_index(cpu_env
, arg
);
7759 register_name
= "Index";
7761 case CP0_REG00__MVPCONTROL
:
7762 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7763 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7764 register_name
= "MVPControl";
7766 case CP0_REG00__MVPCONF0
:
7767 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7769 register_name
= "MVPConf0";
7771 case CP0_REG00__MVPCONF1
:
7772 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7774 register_name
= "MVPConf1";
7776 case CP0_REG00__VPCONTROL
:
7779 register_name
= "VPControl";
7782 goto cp0_unimplemented
;
7785 case CP0_REGISTER_01
:
7787 case CP0_REG01__RANDOM
:
7789 register_name
= "Random";
7791 case CP0_REG01__VPECONTROL
:
7792 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7793 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7794 register_name
= "VPEControl";
7796 case CP0_REG01__VPECONF0
:
7797 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7798 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7799 register_name
= "VPEConf0";
7801 case CP0_REG01__VPECONF1
:
7802 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7803 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7804 register_name
= "VPEConf1";
7806 case CP0_REG01__YQMASK
:
7807 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7808 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7809 register_name
= "YQMask";
7811 case CP0_REG01__VPESCHEDULE
:
7812 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7813 tcg_gen_st_tl(arg
, cpu_env
,
7814 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7815 register_name
= "VPESchedule";
7817 case CP0_REG01__VPESCHEFBACK
:
7818 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7819 tcg_gen_st_tl(arg
, cpu_env
,
7820 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7821 register_name
= "VPEScheFBack";
7823 case CP0_REG01__VPEOPT
:
7824 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7825 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7826 register_name
= "VPEOpt";
7829 goto cp0_unimplemented
;
7832 case CP0_REGISTER_02
:
7834 case CP0_REG02__ENTRYLO0
:
7835 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
7836 register_name
= "EntryLo0";
7838 case CP0_REG02__TCSTATUS
:
7839 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7840 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7841 register_name
= "TCStatus";
7843 case CP0_REG02__TCBIND
:
7844 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7845 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7846 register_name
= "TCBind";
7848 case CP0_REG02__TCRESTART
:
7849 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7850 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7851 register_name
= "TCRestart";
7853 case CP0_REG02__TCHALT
:
7854 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7855 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7856 register_name
= "TCHalt";
7858 case CP0_REG02__TCCONTEXT
:
7859 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7860 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7861 register_name
= "TCContext";
7863 case CP0_REG02__TCSCHEDULE
:
7864 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7865 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7866 register_name
= "TCSchedule";
7868 case CP0_REG02__TCSCHEFBACK
:
7869 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7870 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7871 register_name
= "TCScheFBack";
7874 goto cp0_unimplemented
;
7877 case CP0_REGISTER_03
:
7879 case CP0_REG03__ENTRYLO1
:
7880 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
7881 register_name
= "EntryLo1";
7883 case CP0_REG03__GLOBALNUM
:
7886 register_name
= "GlobalNumber";
7889 goto cp0_unimplemented
;
7892 case CP0_REGISTER_04
:
7894 case CP0_REG04__CONTEXT
:
7895 gen_helper_mtc0_context(cpu_env
, arg
);
7896 register_name
= "Context";
7898 case CP0_REG04__CONTEXTCONFIG
:
7900 /* gen_helper_mtc0_contextconfig(arg); */
7901 register_name
= "ContextConfig";
7902 goto cp0_unimplemented
;
7903 case CP0_REG04__USERLOCAL
:
7904 CP0_CHECK(ctx
->ulri
);
7905 tcg_gen_st_tl(arg
, cpu_env
,
7906 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7907 register_name
= "UserLocal";
7909 case CP0_REG04__MMID
:
7911 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
7912 register_name
= "MMID";
7915 goto cp0_unimplemented
;
7918 case CP0_REGISTER_05
:
7920 case CP0_REG05__PAGEMASK
:
7921 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7922 register_name
= "PageMask";
7924 case CP0_REG05__PAGEGRAIN
:
7925 check_insn(ctx
, ISA_MIPS32R2
);
7926 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7927 register_name
= "PageGrain";
7928 ctx
->base
.is_jmp
= DISAS_STOP
;
7930 case CP0_REG05__SEGCTL0
:
7932 gen_helper_mtc0_segctl0(cpu_env
, arg
);
7933 register_name
= "SegCtl0";
7935 case CP0_REG05__SEGCTL1
:
7937 gen_helper_mtc0_segctl1(cpu_env
, arg
);
7938 register_name
= "SegCtl1";
7940 case CP0_REG05__SEGCTL2
:
7942 gen_helper_mtc0_segctl2(cpu_env
, arg
);
7943 register_name
= "SegCtl2";
7945 case CP0_REG05__PWBASE
:
7947 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7948 register_name
= "PWBase";
7950 case CP0_REG05__PWFIELD
:
7952 gen_helper_mtc0_pwfield(cpu_env
, arg
);
7953 register_name
= "PWField";
7955 case CP0_REG05__PWSIZE
:
7957 gen_helper_mtc0_pwsize(cpu_env
, arg
);
7958 register_name
= "PWSize";
7961 goto cp0_unimplemented
;
7964 case CP0_REGISTER_06
:
7966 case CP0_REG06__WIRED
:
7967 gen_helper_mtc0_wired(cpu_env
, arg
);
7968 register_name
= "Wired";
7970 case CP0_REG06__SRSCONF0
:
7971 check_insn(ctx
, ISA_MIPS32R2
);
7972 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7973 register_name
= "SRSConf0";
7975 case CP0_REG06__SRSCONF1
:
7976 check_insn(ctx
, ISA_MIPS32R2
);
7977 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7978 register_name
= "SRSConf1";
7980 case CP0_REG06__SRSCONF2
:
7981 check_insn(ctx
, ISA_MIPS32R2
);
7982 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7983 register_name
= "SRSConf2";
7985 case CP0_REG06__SRSCONF3
:
7986 check_insn(ctx
, ISA_MIPS32R2
);
7987 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7988 register_name
= "SRSConf3";
7990 case CP0_REG06__SRSCONF4
:
7991 check_insn(ctx
, ISA_MIPS32R2
);
7992 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7993 register_name
= "SRSConf4";
7995 case CP0_REG06__PWCTL
:
7997 gen_helper_mtc0_pwctl(cpu_env
, arg
);
7998 register_name
= "PWCtl";
8001 goto cp0_unimplemented
;
8004 case CP0_REGISTER_07
:
8006 case CP0_REG07__HWRENA
:
8007 check_insn(ctx
, ISA_MIPS32R2
);
8008 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8009 ctx
->base
.is_jmp
= DISAS_STOP
;
8010 register_name
= "HWREna";
8013 goto cp0_unimplemented
;
8016 case CP0_REGISTER_08
:
8018 case CP0_REG08__BADVADDR
:
8020 register_name
= "BadVAddr";
8022 case CP0_REG08__BADINSTR
:
8024 register_name
= "BadInstr";
8026 case CP0_REG08__BADINSTRP
:
8028 register_name
= "BadInstrP";
8030 case CP0_REG08__BADINSTRX
:
8032 register_name
= "BadInstrX";
8035 goto cp0_unimplemented
;
8038 case CP0_REGISTER_09
:
8040 case CP0_REG09__COUNT
:
8041 gen_helper_mtc0_count(cpu_env
, arg
);
8042 register_name
= "Count";
8044 case CP0_REG09__SAARI
:
8045 CP0_CHECK(ctx
->saar
);
8046 gen_helper_mtc0_saari(cpu_env
, arg
);
8047 register_name
= "SAARI";
8049 case CP0_REG09__SAAR
:
8050 CP0_CHECK(ctx
->saar
);
8051 gen_helper_mtc0_saar(cpu_env
, arg
);
8052 register_name
= "SAAR";
8055 goto cp0_unimplemented
;
8058 case CP0_REGISTER_10
:
8060 case CP0_REG10__ENTRYHI
:
8061 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8062 register_name
= "EntryHi";
8065 goto cp0_unimplemented
;
8068 case CP0_REGISTER_11
:
8070 case CP0_REG11__COMPARE
:
8071 gen_helper_mtc0_compare(cpu_env
, arg
);
8072 register_name
= "Compare";
8074 /* 6,7 are implementation dependent */
8076 goto cp0_unimplemented
;
8079 case CP0_REGISTER_12
:
8081 case CP0_REG12__STATUS
:
8082 save_cpu_state(ctx
, 1);
8083 gen_helper_mtc0_status(cpu_env
, arg
);
8084 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8085 gen_save_pc(ctx
->base
.pc_next
+ 4);
8086 ctx
->base
.is_jmp
= DISAS_EXIT
;
8087 register_name
= "Status";
8089 case CP0_REG12__INTCTL
:
8090 check_insn(ctx
, ISA_MIPS32R2
);
8091 gen_helper_mtc0_intctl(cpu_env
, arg
);
8092 /* Stop translation as we may have switched the execution mode */
8093 ctx
->base
.is_jmp
= DISAS_STOP
;
8094 register_name
= "IntCtl";
8096 case CP0_REG12__SRSCTL
:
8097 check_insn(ctx
, ISA_MIPS32R2
);
8098 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8099 /* Stop translation as we may have switched the execution mode */
8100 ctx
->base
.is_jmp
= DISAS_STOP
;
8101 register_name
= "SRSCtl";
8103 case CP0_REG12__SRSMAP
:
8104 check_insn(ctx
, ISA_MIPS32R2
);
8105 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8106 /* Stop translation as we may have switched the execution mode */
8107 ctx
->base
.is_jmp
= DISAS_STOP
;
8108 register_name
= "SRSMap";
8111 goto cp0_unimplemented
;
8114 case CP0_REGISTER_13
:
8116 case CP0_REG13__CAUSE
:
8117 save_cpu_state(ctx
, 1);
8118 gen_helper_mtc0_cause(cpu_env
, arg
);
8120 * Stop translation as we may have triggered an interrupt.
8121 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8122 * translated code to check for pending interrupts.
8124 gen_save_pc(ctx
->base
.pc_next
+ 4);
8125 ctx
->base
.is_jmp
= DISAS_EXIT
;
8126 register_name
= "Cause";
8129 goto cp0_unimplemented
;
8132 case CP0_REGISTER_14
:
8134 case CP0_REG14__EPC
:
8135 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8136 register_name
= "EPC";
8139 goto cp0_unimplemented
;
8142 case CP0_REGISTER_15
:
8144 case CP0_REG15__PRID
:
8146 register_name
= "PRid";
8148 case CP0_REG15__EBASE
:
8149 check_insn(ctx
, ISA_MIPS32R2
);
8150 gen_helper_mtc0_ebase(cpu_env
, arg
);
8151 register_name
= "EBase";
8154 goto cp0_unimplemented
;
8157 case CP0_REGISTER_16
:
8159 case CP0_REG16__CONFIG
:
8160 gen_helper_mtc0_config0(cpu_env
, arg
);
8161 register_name
= "Config";
8162 /* Stop translation as we may have switched the execution mode */
8163 ctx
->base
.is_jmp
= DISAS_STOP
;
8165 case CP0_REG16__CONFIG1
:
8166 /* ignored, read only */
8167 register_name
= "Config1";
8169 case CP0_REG16__CONFIG2
:
8170 gen_helper_mtc0_config2(cpu_env
, arg
);
8171 register_name
= "Config2";
8172 /* Stop translation as we may have switched the execution mode */
8173 ctx
->base
.is_jmp
= DISAS_STOP
;
8175 case CP0_REG16__CONFIG3
:
8176 gen_helper_mtc0_config3(cpu_env
, arg
);
8177 register_name
= "Config3";
8178 /* Stop translation as we may have switched the execution mode */
8179 ctx
->base
.is_jmp
= DISAS_STOP
;
8181 case CP0_REG16__CONFIG4
:
8182 gen_helper_mtc0_config4(cpu_env
, arg
);
8183 register_name
= "Config4";
8184 ctx
->base
.is_jmp
= DISAS_STOP
;
8186 case CP0_REG16__CONFIG5
:
8187 gen_helper_mtc0_config5(cpu_env
, arg
);
8188 register_name
= "Config5";
8189 /* Stop translation as we may have switched the execution mode */
8190 ctx
->base
.is_jmp
= DISAS_STOP
;
8192 /* 6,7 are implementation dependent */
8193 case CP0_REG16__CONFIG6
:
8195 register_name
= "Config6";
8197 case CP0_REG16__CONFIG7
:
8199 register_name
= "Config7";
8202 register_name
= "Invalid config selector";
8203 goto cp0_unimplemented
;
8206 case CP0_REGISTER_17
:
8208 case CP0_REG17__LLADDR
:
8209 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8210 register_name
= "LLAddr";
8212 case CP0_REG17__MAAR
:
8213 CP0_CHECK(ctx
->mrp
);
8214 gen_helper_mtc0_maar(cpu_env
, arg
);
8215 register_name
= "MAAR";
8217 case CP0_REG17__MAARI
:
8218 CP0_CHECK(ctx
->mrp
);
8219 gen_helper_mtc0_maari(cpu_env
, arg
);
8220 register_name
= "MAARI";
8223 goto cp0_unimplemented
;
8226 case CP0_REGISTER_18
:
8228 case CP0_REG18__WATCHLO0
:
8229 case CP0_REG18__WATCHLO1
:
8230 case CP0_REG18__WATCHLO2
:
8231 case CP0_REG18__WATCHLO3
:
8232 case CP0_REG18__WATCHLO4
:
8233 case CP0_REG18__WATCHLO5
:
8234 case CP0_REG18__WATCHLO6
:
8235 case CP0_REG18__WATCHLO7
:
8236 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8237 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8238 register_name
= "WatchLo";
8241 goto cp0_unimplemented
;
8244 case CP0_REGISTER_19
:
8246 case CP0_REG19__WATCHHI0
:
8247 case CP0_REG19__WATCHHI1
:
8248 case CP0_REG19__WATCHHI2
:
8249 case CP0_REG19__WATCHHI3
:
8250 case CP0_REG19__WATCHHI4
:
8251 case CP0_REG19__WATCHHI5
:
8252 case CP0_REG19__WATCHHI6
:
8253 case CP0_REG19__WATCHHI7
:
8254 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8255 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8256 register_name
= "WatchHi";
8259 goto cp0_unimplemented
;
8262 case CP0_REGISTER_20
:
8264 case CP0_REG20__XCONTEXT
:
8265 #if defined(TARGET_MIPS64)
8266 check_insn(ctx
, ISA_MIPS3
);
8267 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8268 register_name
= "XContext";
8272 goto cp0_unimplemented
;
8275 case CP0_REGISTER_21
:
8276 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8277 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8280 gen_helper_mtc0_framemask(cpu_env
, arg
);
8281 register_name
= "Framemask";
8284 goto cp0_unimplemented
;
8287 case CP0_REGISTER_22
:
8289 register_name
= "Diagnostic"; /* implementation dependent */
8291 case CP0_REGISTER_23
:
8293 case CP0_REG23__DEBUG
:
8294 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8295 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8296 gen_save_pc(ctx
->base
.pc_next
+ 4);
8297 ctx
->base
.is_jmp
= DISAS_EXIT
;
8298 register_name
= "Debug";
8300 case CP0_REG23__TRACECONTROL
:
8301 /* PDtrace support */
8302 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8303 register_name
= "TraceControl";
8304 /* Stop translation as we may have switched the execution mode */
8305 ctx
->base
.is_jmp
= DISAS_STOP
;
8306 goto cp0_unimplemented
;
8307 case CP0_REG23__TRACECONTROL2
:
8308 /* PDtrace support */
8309 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8310 register_name
= "TraceControl2";
8311 /* Stop translation as we may have switched the execution mode */
8312 ctx
->base
.is_jmp
= DISAS_STOP
;
8313 goto cp0_unimplemented
;
8314 case CP0_REG23__USERTRACEDATA1
:
8315 /* Stop translation as we may have switched the execution mode */
8316 ctx
->base
.is_jmp
= DISAS_STOP
;
8317 /* PDtrace support */
8318 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8319 register_name
= "UserTraceData";
8320 /* Stop translation as we may have switched the execution mode */
8321 ctx
->base
.is_jmp
= DISAS_STOP
;
8322 goto cp0_unimplemented
;
8323 case CP0_REG23__TRACEIBPC
:
8324 /* PDtrace support */
8325 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8326 /* Stop translation as we may have switched the execution mode */
8327 ctx
->base
.is_jmp
= DISAS_STOP
;
8328 register_name
= "TraceIBPC";
8329 goto cp0_unimplemented
;
8330 case CP0_REG23__TRACEDBPC
:
8331 /* PDtrace support */
8332 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8333 /* Stop translation as we may have switched the execution mode */
8334 ctx
->base
.is_jmp
= DISAS_STOP
;
8335 register_name
= "TraceDBPC";
8336 goto cp0_unimplemented
;
8338 goto cp0_unimplemented
;
8341 case CP0_REGISTER_24
:
8343 case CP0_REG24__DEPC
:
8345 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8346 register_name
= "DEPC";
8349 goto cp0_unimplemented
;
8352 case CP0_REGISTER_25
:
8354 case CP0_REG25__PERFCTL0
:
8355 gen_helper_mtc0_performance0(cpu_env
, arg
);
8356 register_name
= "Performance0";
8358 case CP0_REG25__PERFCNT0
:
8359 /* gen_helper_mtc0_performance1(arg); */
8360 register_name
= "Performance1";
8361 goto cp0_unimplemented
;
8362 case CP0_REG25__PERFCTL1
:
8363 /* gen_helper_mtc0_performance2(arg); */
8364 register_name
= "Performance2";
8365 goto cp0_unimplemented
;
8366 case CP0_REG25__PERFCNT1
:
8367 /* gen_helper_mtc0_performance3(arg); */
8368 register_name
= "Performance3";
8369 goto cp0_unimplemented
;
8370 case CP0_REG25__PERFCTL2
:
8371 /* gen_helper_mtc0_performance4(arg); */
8372 register_name
= "Performance4";
8373 goto cp0_unimplemented
;
8374 case CP0_REG25__PERFCNT2
:
8375 /* gen_helper_mtc0_performance5(arg); */
8376 register_name
= "Performance5";
8377 goto cp0_unimplemented
;
8378 case CP0_REG25__PERFCTL3
:
8379 /* gen_helper_mtc0_performance6(arg); */
8380 register_name
= "Performance6";
8381 goto cp0_unimplemented
;
8382 case CP0_REG25__PERFCNT3
:
8383 /* gen_helper_mtc0_performance7(arg); */
8384 register_name
= "Performance7";
8385 goto cp0_unimplemented
;
8387 goto cp0_unimplemented
;
8390 case CP0_REGISTER_26
:
8392 case CP0_REG26__ERRCTL
:
8393 gen_helper_mtc0_errctl(cpu_env
, arg
);
8394 ctx
->base
.is_jmp
= DISAS_STOP
;
8395 register_name
= "ErrCtl";
8398 goto cp0_unimplemented
;
8401 case CP0_REGISTER_27
:
8403 case CP0_REG27__CACHERR
:
8405 register_name
= "CacheErr";
8408 goto cp0_unimplemented
;
8411 case CP0_REGISTER_28
:
8413 case CP0_REG28__TAGLO
:
8414 case CP0_REG28__TAGLO1
:
8415 case CP0_REG28__TAGLO2
:
8416 case CP0_REG28__TAGLO3
:
8417 gen_helper_mtc0_taglo(cpu_env
, arg
);
8418 register_name
= "TagLo";
8420 case CP0_REG28__DATALO
:
8421 case CP0_REG28__DATALO1
:
8422 case CP0_REG28__DATALO2
:
8423 case CP0_REG28__DATALO3
:
8424 gen_helper_mtc0_datalo(cpu_env
, arg
);
8425 register_name
= "DataLo";
8428 goto cp0_unimplemented
;
8431 case CP0_REGISTER_29
:
8433 case CP0_REG29__TAGHI
:
8434 case CP0_REG29__TAGHI1
:
8435 case CP0_REG29__TAGHI2
:
8436 case CP0_REG29__TAGHI3
:
8437 gen_helper_mtc0_taghi(cpu_env
, arg
);
8438 register_name
= "TagHi";
8440 case CP0_REG29__DATAHI
:
8441 case CP0_REG29__DATAHI1
:
8442 case CP0_REG29__DATAHI2
:
8443 case CP0_REG29__DATAHI3
:
8444 gen_helper_mtc0_datahi(cpu_env
, arg
);
8445 register_name
= "DataHi";
8448 register_name
= "invalid sel";
8449 goto cp0_unimplemented
;
8452 case CP0_REGISTER_30
:
8454 case CP0_REG30__ERROREPC
:
8455 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8456 register_name
= "ErrorEPC";
8459 goto cp0_unimplemented
;
8462 case CP0_REGISTER_31
:
8464 case CP0_REG31__DESAVE
:
8466 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8467 register_name
= "DESAVE";
8469 case CP0_REG31__KSCRATCH1
:
8470 case CP0_REG31__KSCRATCH2
:
8471 case CP0_REG31__KSCRATCH3
:
8472 case CP0_REG31__KSCRATCH4
:
8473 case CP0_REG31__KSCRATCH5
:
8474 case CP0_REG31__KSCRATCH6
:
8475 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8476 tcg_gen_st_tl(arg
, cpu_env
,
8477 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8478 register_name
= "KScratch";
8481 goto cp0_unimplemented
;
8485 goto cp0_unimplemented
;
8487 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8489 /* For simplicity assume that all writes can cause interrupts. */
8490 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8492 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8493 * translated code to check for pending interrupts.
8495 gen_save_pc(ctx
->base
.pc_next
+ 4);
8496 ctx
->base
.is_jmp
= DISAS_EXIT
;
8501 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8502 register_name
, reg
, sel
);
8505 #if defined(TARGET_MIPS64)
8506 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8508 const char *register_name
= "invalid";
8511 check_insn(ctx
, ISA_MIPS64
);
8515 case CP0_REGISTER_00
:
8517 case CP0_REG00__INDEX
:
8518 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8519 register_name
= "Index";
8521 case CP0_REG00__MVPCONTROL
:
8522 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8523 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8524 register_name
= "MVPControl";
8526 case CP0_REG00__MVPCONF0
:
8527 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8528 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8529 register_name
= "MVPConf0";
8531 case CP0_REG00__MVPCONF1
:
8532 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8533 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8534 register_name
= "MVPConf1";
8536 case CP0_REG00__VPCONTROL
:
8538 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8539 register_name
= "VPControl";
8542 goto cp0_unimplemented
;
8545 case CP0_REGISTER_01
:
8547 case CP0_REG01__RANDOM
:
8548 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8549 gen_helper_mfc0_random(arg
, cpu_env
);
8550 register_name
= "Random";
8552 case CP0_REG01__VPECONTROL
:
8553 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8554 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8555 register_name
= "VPEControl";
8557 case CP0_REG01__VPECONF0
:
8558 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8559 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8560 register_name
= "VPEConf0";
8562 case CP0_REG01__VPECONF1
:
8563 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8564 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
8565 register_name
= "VPEConf1";
8567 case CP0_REG01__YQMASK
:
8568 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8569 tcg_gen_ld_tl(arg
, cpu_env
,
8570 offsetof(CPUMIPSState
, CP0_YQMask
));
8571 register_name
= "YQMask";
8573 case CP0_REG01__VPESCHEDULE
:
8574 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8575 tcg_gen_ld_tl(arg
, cpu_env
,
8576 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8577 register_name
= "VPESchedule";
8579 case CP0_REG01__VPESCHEFBACK
:
8580 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8581 tcg_gen_ld_tl(arg
, cpu_env
,
8582 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8583 register_name
= "VPEScheFBack";
8585 case CP0_REG01__VPEOPT
:
8586 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8587 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
8588 register_name
= "VPEOpt";
8591 goto cp0_unimplemented
;
8594 case CP0_REGISTER_02
:
8596 case CP0_REG02__ENTRYLO0
:
8597 tcg_gen_ld_tl(arg
, cpu_env
,
8598 offsetof(CPUMIPSState
, CP0_EntryLo0
));
8599 register_name
= "EntryLo0";
8601 case CP0_REG02__TCSTATUS
:
8602 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8603 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
8604 register_name
= "TCStatus";
8606 case CP0_REG02__TCBIND
:
8607 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8608 gen_helper_mfc0_tcbind(arg
, cpu_env
);
8609 register_name
= "TCBind";
8611 case CP0_REG02__TCRESTART
:
8612 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8613 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
8614 register_name
= "TCRestart";
8616 case CP0_REG02__TCHALT
:
8617 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8618 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
8619 register_name
= "TCHalt";
8621 case CP0_REG02__TCCONTEXT
:
8622 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8623 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
8624 register_name
= "TCContext";
8626 case CP0_REG02__TCSCHEDULE
:
8627 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8628 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
8629 register_name
= "TCSchedule";
8631 case CP0_REG02__TCSCHEFBACK
:
8632 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8633 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
8634 register_name
= "TCScheFBack";
8637 goto cp0_unimplemented
;
8640 case CP0_REGISTER_03
:
8642 case CP0_REG03__ENTRYLO1
:
8643 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
8644 register_name
= "EntryLo1";
8646 case CP0_REG03__GLOBALNUM
:
8648 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
8649 register_name
= "GlobalNumber";
8652 goto cp0_unimplemented
;
8655 case CP0_REGISTER_04
:
8657 case CP0_REG04__CONTEXT
:
8658 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
8659 register_name
= "Context";
8661 case CP0_REG04__CONTEXTCONFIG
:
8663 /* gen_helper_dmfc0_contextconfig(arg); */
8664 register_name
= "ContextConfig";
8665 goto cp0_unimplemented
;
8666 case CP0_REG04__USERLOCAL
:
8667 CP0_CHECK(ctx
->ulri
);
8668 tcg_gen_ld_tl(arg
, cpu_env
,
8669 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8670 register_name
= "UserLocal";
8672 case CP0_REG04__MMID
:
8674 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
8675 register_name
= "MMID";
8678 goto cp0_unimplemented
;
8681 case CP0_REGISTER_05
:
8683 case CP0_REG05__PAGEMASK
:
8684 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
8685 register_name
= "PageMask";
8687 case CP0_REG05__PAGEGRAIN
:
8688 check_insn(ctx
, ISA_MIPS32R2
);
8689 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
8690 register_name
= "PageGrain";
8692 case CP0_REG05__SEGCTL0
:
8694 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
8695 register_name
= "SegCtl0";
8697 case CP0_REG05__SEGCTL1
:
8699 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
8700 register_name
= "SegCtl1";
8702 case CP0_REG05__SEGCTL2
:
8704 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
8705 register_name
= "SegCtl2";
8707 case CP0_REG05__PWBASE
:
8709 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8710 register_name
= "PWBase";
8712 case CP0_REG05__PWFIELD
:
8714 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
8715 register_name
= "PWField";
8717 case CP0_REG05__PWSIZE
:
8719 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
8720 register_name
= "PWSize";
8723 goto cp0_unimplemented
;
8726 case CP0_REGISTER_06
:
8728 case CP0_REG06__WIRED
:
8729 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
8730 register_name
= "Wired";
8732 case CP0_REG06__SRSCONF0
:
8733 check_insn(ctx
, ISA_MIPS32R2
);
8734 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
8735 register_name
= "SRSConf0";
8737 case CP0_REG06__SRSCONF1
:
8738 check_insn(ctx
, ISA_MIPS32R2
);
8739 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
8740 register_name
= "SRSConf1";
8742 case CP0_REG06__SRSCONF2
:
8743 check_insn(ctx
, ISA_MIPS32R2
);
8744 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
8745 register_name
= "SRSConf2";
8747 case CP0_REG06__SRSCONF3
:
8748 check_insn(ctx
, ISA_MIPS32R2
);
8749 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
8750 register_name
= "SRSConf3";
8752 case CP0_REG06__SRSCONF4
:
8753 check_insn(ctx
, ISA_MIPS32R2
);
8754 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
8755 register_name
= "SRSConf4";
8757 case CP0_REG06__PWCTL
:
8759 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
8760 register_name
= "PWCtl";
8763 goto cp0_unimplemented
;
8766 case CP0_REGISTER_07
:
8768 case CP0_REG07__HWRENA
:
8769 check_insn(ctx
, ISA_MIPS32R2
);
8770 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
8771 register_name
= "HWREna";
8774 goto cp0_unimplemented
;
8777 case CP0_REGISTER_08
:
8779 case CP0_REG08__BADVADDR
:
8780 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
8781 register_name
= "BadVAddr";
8783 case CP0_REG08__BADINSTR
:
8785 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
8786 register_name
= "BadInstr";
8788 case CP0_REG08__BADINSTRP
:
8790 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
8791 register_name
= "BadInstrP";
8793 case CP0_REG08__BADINSTRX
:
8795 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
8796 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
8797 register_name
= "BadInstrX";
8800 goto cp0_unimplemented
;
8803 case CP0_REGISTER_09
:
8805 case CP0_REG09__COUNT
:
8806 /* Mark as an IO operation because we read the time. */
8807 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8810 gen_helper_mfc0_count(arg
, cpu_env
);
8812 * Break the TB to be able to take timer interrupts immediately
8813 * after reading count. DISAS_STOP isn't sufficient, we need to
8814 * ensure we break completely out of translated code.
8816 gen_save_pc(ctx
->base
.pc_next
+ 4);
8817 ctx
->base
.is_jmp
= DISAS_EXIT
;
8818 register_name
= "Count";
8820 case CP0_REG09__SAARI
:
8821 CP0_CHECK(ctx
->saar
);
8822 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
8823 register_name
= "SAARI";
8825 case CP0_REG09__SAAR
:
8826 CP0_CHECK(ctx
->saar
);
8827 gen_helper_dmfc0_saar(arg
, cpu_env
);
8828 register_name
= "SAAR";
8831 goto cp0_unimplemented
;
8834 case CP0_REGISTER_10
:
8836 case CP0_REG10__ENTRYHI
:
8837 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
8838 register_name
= "EntryHi";
8841 goto cp0_unimplemented
;
8844 case CP0_REGISTER_11
:
8846 case CP0_REG11__COMPARE
:
8847 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
8848 register_name
= "Compare";
8850 /* 6,7 are implementation dependent */
8852 goto cp0_unimplemented
;
8855 case CP0_REGISTER_12
:
8857 case CP0_REG12__STATUS
:
8858 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
8859 register_name
= "Status";
8861 case CP0_REG12__INTCTL
:
8862 check_insn(ctx
, ISA_MIPS32R2
);
8863 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
8864 register_name
= "IntCtl";
8866 case CP0_REG12__SRSCTL
:
8867 check_insn(ctx
, ISA_MIPS32R2
);
8868 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
8869 register_name
= "SRSCtl";
8871 case CP0_REG12__SRSMAP
:
8872 check_insn(ctx
, ISA_MIPS32R2
);
8873 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8874 register_name
= "SRSMap";
8877 goto cp0_unimplemented
;
8880 case CP0_REGISTER_13
:
8882 case CP0_REG13__CAUSE
:
8883 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
8884 register_name
= "Cause";
8887 goto cp0_unimplemented
;
8890 case CP0_REGISTER_14
:
8892 case CP0_REG14__EPC
:
8893 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8894 register_name
= "EPC";
8897 goto cp0_unimplemented
;
8900 case CP0_REGISTER_15
:
8902 case CP0_REG15__PRID
:
8903 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
8904 register_name
= "PRid";
8906 case CP0_REG15__EBASE
:
8907 check_insn(ctx
, ISA_MIPS32R2
);
8908 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
8909 register_name
= "EBase";
8911 case CP0_REG15__CMGCRBASE
:
8912 check_insn(ctx
, ISA_MIPS32R2
);
8913 CP0_CHECK(ctx
->cmgcr
);
8914 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
8915 register_name
= "CMGCRBase";
8918 goto cp0_unimplemented
;
8921 case CP0_REGISTER_16
:
8923 case CP0_REG16__CONFIG
:
8924 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
8925 register_name
= "Config";
8927 case CP0_REG16__CONFIG1
:
8928 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
8929 register_name
= "Config1";
8931 case CP0_REG16__CONFIG2
:
8932 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
8933 register_name
= "Config2";
8935 case CP0_REG16__CONFIG3
:
8936 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
8937 register_name
= "Config3";
8939 case CP0_REG16__CONFIG4
:
8940 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
8941 register_name
= "Config4";
8943 case CP0_REG16__CONFIG5
:
8944 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
8945 register_name
= "Config5";
8947 /* 6,7 are implementation dependent */
8948 case CP0_REG16__CONFIG6
:
8949 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
8950 register_name
= "Config6";
8952 case CP0_REG16__CONFIG7
:
8953 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
8954 register_name
= "Config7";
8957 goto cp0_unimplemented
;
8960 case CP0_REGISTER_17
:
8962 case CP0_REG17__LLADDR
:
8963 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
8964 register_name
= "LLAddr";
8966 case CP0_REG17__MAAR
:
8967 CP0_CHECK(ctx
->mrp
);
8968 gen_helper_dmfc0_maar(arg
, cpu_env
);
8969 register_name
= "MAAR";
8971 case CP0_REG17__MAARI
:
8972 CP0_CHECK(ctx
->mrp
);
8973 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
8974 register_name
= "MAARI";
8977 goto cp0_unimplemented
;
8980 case CP0_REGISTER_18
:
8982 case CP0_REG18__WATCHLO0
:
8983 case CP0_REG18__WATCHLO1
:
8984 case CP0_REG18__WATCHLO2
:
8985 case CP0_REG18__WATCHLO3
:
8986 case CP0_REG18__WATCHLO4
:
8987 case CP0_REG18__WATCHLO5
:
8988 case CP0_REG18__WATCHLO6
:
8989 case CP0_REG18__WATCHLO7
:
8990 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8991 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
8992 register_name
= "WatchLo";
8995 goto cp0_unimplemented
;
8998 case CP0_REGISTER_19
:
9000 case CP0_REG19__WATCHHI0
:
9001 case CP0_REG19__WATCHHI1
:
9002 case CP0_REG19__WATCHHI2
:
9003 case CP0_REG19__WATCHHI3
:
9004 case CP0_REG19__WATCHHI4
:
9005 case CP0_REG19__WATCHHI5
:
9006 case CP0_REG19__WATCHHI6
:
9007 case CP0_REG19__WATCHHI7
:
9008 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9009 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
9010 register_name
= "WatchHi";
9013 goto cp0_unimplemented
;
9016 case CP0_REGISTER_20
:
9018 case CP0_REG20__XCONTEXT
:
9019 check_insn(ctx
, ISA_MIPS3
);
9020 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
9021 register_name
= "XContext";
9024 goto cp0_unimplemented
;
9027 case CP0_REGISTER_21
:
9028 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9029 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
9032 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
9033 register_name
= "Framemask";
9036 goto cp0_unimplemented
;
9039 case CP0_REGISTER_22
:
9040 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9041 register_name
= "'Diagnostic"; /* implementation dependent */
9043 case CP0_REGISTER_23
:
9045 case CP0_REG23__DEBUG
:
9046 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
9047 register_name
= "Debug";
9049 case CP0_REG23__TRACECONTROL
:
9050 /* PDtrace support */
9051 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
9052 register_name
= "TraceControl";
9053 goto cp0_unimplemented
;
9054 case CP0_REG23__TRACECONTROL2
:
9055 /* PDtrace support */
9056 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9057 register_name
= "TraceControl2";
9058 goto cp0_unimplemented
;
9059 case CP0_REG23__USERTRACEDATA1
:
9060 /* PDtrace support */
9061 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9062 register_name
= "UserTraceData1";
9063 goto cp0_unimplemented
;
9064 case CP0_REG23__TRACEIBPC
:
9065 /* PDtrace support */
9066 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9067 register_name
= "TraceIBPC";
9068 goto cp0_unimplemented
;
9069 case CP0_REG23__TRACEDBPC
:
9070 /* PDtrace support */
9071 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9072 register_name
= "TraceDBPC";
9073 goto cp0_unimplemented
;
9075 goto cp0_unimplemented
;
9078 case CP0_REGISTER_24
:
9080 case CP0_REG24__DEPC
:
9082 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9083 register_name
= "DEPC";
9086 goto cp0_unimplemented
;
9089 case CP0_REGISTER_25
:
9091 case CP0_REG25__PERFCTL0
:
9092 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
9093 register_name
= "Performance0";
9095 case CP0_REG25__PERFCNT0
:
9096 /* gen_helper_dmfc0_performance1(arg); */
9097 register_name
= "Performance1";
9098 goto cp0_unimplemented
;
9099 case CP0_REG25__PERFCTL1
:
9100 /* gen_helper_dmfc0_performance2(arg); */
9101 register_name
= "Performance2";
9102 goto cp0_unimplemented
;
9103 case CP0_REG25__PERFCNT1
:
9104 /* gen_helper_dmfc0_performance3(arg); */
9105 register_name
= "Performance3";
9106 goto cp0_unimplemented
;
9107 case CP0_REG25__PERFCTL2
:
9108 /* gen_helper_dmfc0_performance4(arg); */
9109 register_name
= "Performance4";
9110 goto cp0_unimplemented
;
9111 case CP0_REG25__PERFCNT2
:
9112 /* gen_helper_dmfc0_performance5(arg); */
9113 register_name
= "Performance5";
9114 goto cp0_unimplemented
;
9115 case CP0_REG25__PERFCTL3
:
9116 /* gen_helper_dmfc0_performance6(arg); */
9117 register_name
= "Performance6";
9118 goto cp0_unimplemented
;
9119 case CP0_REG25__PERFCNT3
:
9120 /* gen_helper_dmfc0_performance7(arg); */
9121 register_name
= "Performance7";
9122 goto cp0_unimplemented
;
9124 goto cp0_unimplemented
;
9127 case CP0_REGISTER_26
:
9129 case CP0_REG26__ERRCTL
:
9130 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
9131 register_name
= "ErrCtl";
9134 goto cp0_unimplemented
;
9137 case CP0_REGISTER_27
:
9140 case CP0_REG27__CACHERR
:
9141 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9142 register_name
= "CacheErr";
9145 goto cp0_unimplemented
;
9148 case CP0_REGISTER_28
:
9150 case CP0_REG28__TAGLO
:
9151 case CP0_REG28__TAGLO1
:
9152 case CP0_REG28__TAGLO2
:
9153 case CP0_REG28__TAGLO3
:
9154 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
9155 register_name
= "TagLo";
9157 case CP0_REG28__DATALO
:
9158 case CP0_REG28__DATALO1
:
9159 case CP0_REG28__DATALO2
:
9160 case CP0_REG28__DATALO3
:
9161 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
9162 register_name
= "DataLo";
9165 goto cp0_unimplemented
;
9168 case CP0_REGISTER_29
:
9170 case CP0_REG29__TAGHI
:
9171 case CP0_REG29__TAGHI1
:
9172 case CP0_REG29__TAGHI2
:
9173 case CP0_REG29__TAGHI3
:
9174 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
9175 register_name
= "TagHi";
9177 case CP0_REG29__DATAHI
:
9178 case CP0_REG29__DATAHI1
:
9179 case CP0_REG29__DATAHI2
:
9180 case CP0_REG29__DATAHI3
:
9181 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
9182 register_name
= "DataHi";
9185 goto cp0_unimplemented
;
9188 case CP0_REGISTER_30
:
9190 case CP0_REG30__ERROREPC
:
9191 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9192 register_name
= "ErrorEPC";
9195 goto cp0_unimplemented
;
9198 case CP0_REGISTER_31
:
9200 case CP0_REG31__DESAVE
:
9202 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9203 register_name
= "DESAVE";
9205 case CP0_REG31__KSCRATCH1
:
9206 case CP0_REG31__KSCRATCH2
:
9207 case CP0_REG31__KSCRATCH3
:
9208 case CP0_REG31__KSCRATCH4
:
9209 case CP0_REG31__KSCRATCH5
:
9210 case CP0_REG31__KSCRATCH6
:
9211 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9212 tcg_gen_ld_tl(arg
, cpu_env
,
9213 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9214 register_name
= "KScratch";
9217 goto cp0_unimplemented
;
9221 goto cp0_unimplemented
;
9223 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9227 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9228 register_name
, reg
, sel
);
9229 gen_mfc0_unimplemented(ctx
, arg
);
9232 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9234 const char *register_name
= "invalid";
9237 check_insn(ctx
, ISA_MIPS64
);
9240 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9245 case CP0_REGISTER_00
:
9247 case CP0_REG00__INDEX
:
9248 gen_helper_mtc0_index(cpu_env
, arg
);
9249 register_name
= "Index";
9251 case CP0_REG00__MVPCONTROL
:
9252 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9253 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9254 register_name
= "MVPControl";
9256 case CP0_REG00__MVPCONF0
:
9257 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9259 register_name
= "MVPConf0";
9261 case CP0_REG00__MVPCONF1
:
9262 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9264 register_name
= "MVPConf1";
9266 case CP0_REG00__VPCONTROL
:
9269 register_name
= "VPControl";
9272 goto cp0_unimplemented
;
9275 case CP0_REGISTER_01
:
9277 case CP0_REG01__RANDOM
:
9279 register_name
= "Random";
9281 case CP0_REG01__VPECONTROL
:
9282 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9283 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9284 register_name
= "VPEControl";
9286 case CP0_REG01__VPECONF0
:
9287 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9288 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9289 register_name
= "VPEConf0";
9291 case CP0_REG01__VPECONF1
:
9292 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9293 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9294 register_name
= "VPEConf1";
9296 case CP0_REG01__YQMASK
:
9297 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9298 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9299 register_name
= "YQMask";
9301 case CP0_REG01__VPESCHEDULE
:
9302 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9303 tcg_gen_st_tl(arg
, cpu_env
,
9304 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9305 register_name
= "VPESchedule";
9307 case CP0_REG01__VPESCHEFBACK
:
9308 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9309 tcg_gen_st_tl(arg
, cpu_env
,
9310 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9311 register_name
= "VPEScheFBack";
9313 case CP0_REG01__VPEOPT
:
9314 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9315 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9316 register_name
= "VPEOpt";
9319 goto cp0_unimplemented
;
9322 case CP0_REGISTER_02
:
9324 case CP0_REG02__ENTRYLO0
:
9325 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9326 register_name
= "EntryLo0";
9328 case CP0_REG02__TCSTATUS
:
9329 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9330 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9331 register_name
= "TCStatus";
9333 case CP0_REG02__TCBIND
:
9334 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9335 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9336 register_name
= "TCBind";
9338 case CP0_REG02__TCRESTART
:
9339 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9340 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9341 register_name
= "TCRestart";
9343 case CP0_REG02__TCHALT
:
9344 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9345 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9346 register_name
= "TCHalt";
9348 case CP0_REG02__TCCONTEXT
:
9349 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9350 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9351 register_name
= "TCContext";
9353 case CP0_REG02__TCSCHEDULE
:
9354 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9355 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9356 register_name
= "TCSchedule";
9358 case CP0_REG02__TCSCHEFBACK
:
9359 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9360 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9361 register_name
= "TCScheFBack";
9364 goto cp0_unimplemented
;
9367 case CP0_REGISTER_03
:
9369 case CP0_REG03__ENTRYLO1
:
9370 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9371 register_name
= "EntryLo1";
9373 case CP0_REG03__GLOBALNUM
:
9376 register_name
= "GlobalNumber";
9379 goto cp0_unimplemented
;
9382 case CP0_REGISTER_04
:
9384 case CP0_REG04__CONTEXT
:
9385 gen_helper_mtc0_context(cpu_env
, arg
);
9386 register_name
= "Context";
9388 case CP0_REG04__CONTEXTCONFIG
:
9390 /* gen_helper_dmtc0_contextconfig(arg); */
9391 register_name
= "ContextConfig";
9392 goto cp0_unimplemented
;
9393 case CP0_REG04__USERLOCAL
:
9394 CP0_CHECK(ctx
->ulri
);
9395 tcg_gen_st_tl(arg
, cpu_env
,
9396 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9397 register_name
= "UserLocal";
9399 case CP0_REG04__MMID
:
9401 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9402 register_name
= "MMID";
9405 goto cp0_unimplemented
;
9408 case CP0_REGISTER_05
:
9410 case CP0_REG05__PAGEMASK
:
9411 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9412 register_name
= "PageMask";
9414 case CP0_REG05__PAGEGRAIN
:
9415 check_insn(ctx
, ISA_MIPS32R2
);
9416 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9417 register_name
= "PageGrain";
9419 case CP0_REG05__SEGCTL0
:
9421 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9422 register_name
= "SegCtl0";
9424 case CP0_REG05__SEGCTL1
:
9426 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9427 register_name
= "SegCtl1";
9429 case CP0_REG05__SEGCTL2
:
9431 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9432 register_name
= "SegCtl2";
9434 case CP0_REG05__PWBASE
:
9436 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9437 register_name
= "PWBase";
9439 case CP0_REG05__PWFIELD
:
9441 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9442 register_name
= "PWField";
9444 case CP0_REG05__PWSIZE
:
9446 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9447 register_name
= "PWSize";
9450 goto cp0_unimplemented
;
9453 case CP0_REGISTER_06
:
9455 case CP0_REG06__WIRED
:
9456 gen_helper_mtc0_wired(cpu_env
, arg
);
9457 register_name
= "Wired";
9459 case CP0_REG06__SRSCONF0
:
9460 check_insn(ctx
, ISA_MIPS32R2
);
9461 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9462 register_name
= "SRSConf0";
9464 case CP0_REG06__SRSCONF1
:
9465 check_insn(ctx
, ISA_MIPS32R2
);
9466 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9467 register_name
= "SRSConf1";
9469 case CP0_REG06__SRSCONF2
:
9470 check_insn(ctx
, ISA_MIPS32R2
);
9471 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9472 register_name
= "SRSConf2";
9474 case CP0_REG06__SRSCONF3
:
9475 check_insn(ctx
, ISA_MIPS32R2
);
9476 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9477 register_name
= "SRSConf3";
9479 case CP0_REG06__SRSCONF4
:
9480 check_insn(ctx
, ISA_MIPS32R2
);
9481 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9482 register_name
= "SRSConf4";
9484 case CP0_REG06__PWCTL
:
9486 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9487 register_name
= "PWCtl";
9490 goto cp0_unimplemented
;
9493 case CP0_REGISTER_07
:
9495 case CP0_REG07__HWRENA
:
9496 check_insn(ctx
, ISA_MIPS32R2
);
9497 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9498 ctx
->base
.is_jmp
= DISAS_STOP
;
9499 register_name
= "HWREna";
9502 goto cp0_unimplemented
;
9505 case CP0_REGISTER_08
:
9507 case CP0_REG08__BADVADDR
:
9509 register_name
= "BadVAddr";
9511 case CP0_REG08__BADINSTR
:
9513 register_name
= "BadInstr";
9515 case CP0_REG08__BADINSTRP
:
9517 register_name
= "BadInstrP";
9519 case CP0_REG08__BADINSTRX
:
9521 register_name
= "BadInstrX";
9524 goto cp0_unimplemented
;
9527 case CP0_REGISTER_09
:
9529 case CP0_REG09__COUNT
:
9530 gen_helper_mtc0_count(cpu_env
, arg
);
9531 register_name
= "Count";
9533 case CP0_REG09__SAARI
:
9534 CP0_CHECK(ctx
->saar
);
9535 gen_helper_mtc0_saari(cpu_env
, arg
);
9536 register_name
= "SAARI";
9538 case CP0_REG09__SAAR
:
9539 CP0_CHECK(ctx
->saar
);
9540 gen_helper_mtc0_saar(cpu_env
, arg
);
9541 register_name
= "SAAR";
9544 goto cp0_unimplemented
;
9546 /* Stop translation as we may have switched the execution mode */
9547 ctx
->base
.is_jmp
= DISAS_STOP
;
9549 case CP0_REGISTER_10
:
9551 case CP0_REG10__ENTRYHI
:
9552 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9553 register_name
= "EntryHi";
9556 goto cp0_unimplemented
;
9559 case CP0_REGISTER_11
:
9561 case CP0_REG11__COMPARE
:
9562 gen_helper_mtc0_compare(cpu_env
, arg
);
9563 register_name
= "Compare";
9565 /* 6,7 are implementation dependent */
9567 goto cp0_unimplemented
;
9569 /* Stop translation as we may have switched the execution mode */
9570 ctx
->base
.is_jmp
= DISAS_STOP
;
9572 case CP0_REGISTER_12
:
9574 case CP0_REG12__STATUS
:
9575 save_cpu_state(ctx
, 1);
9576 gen_helper_mtc0_status(cpu_env
, arg
);
9577 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9578 gen_save_pc(ctx
->base
.pc_next
+ 4);
9579 ctx
->base
.is_jmp
= DISAS_EXIT
;
9580 register_name
= "Status";
9582 case CP0_REG12__INTCTL
:
9583 check_insn(ctx
, ISA_MIPS32R2
);
9584 gen_helper_mtc0_intctl(cpu_env
, arg
);
9585 /* Stop translation as we may have switched the execution mode */
9586 ctx
->base
.is_jmp
= DISAS_STOP
;
9587 register_name
= "IntCtl";
9589 case CP0_REG12__SRSCTL
:
9590 check_insn(ctx
, ISA_MIPS32R2
);
9591 gen_helper_mtc0_srsctl(cpu_env
, arg
);
9592 /* Stop translation as we may have switched the execution mode */
9593 ctx
->base
.is_jmp
= DISAS_STOP
;
9594 register_name
= "SRSCtl";
9596 case CP0_REG12__SRSMAP
:
9597 check_insn(ctx
, ISA_MIPS32R2
);
9598 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9599 /* Stop translation as we may have switched the execution mode */
9600 ctx
->base
.is_jmp
= DISAS_STOP
;
9601 register_name
= "SRSMap";
9604 goto cp0_unimplemented
;
9607 case CP0_REGISTER_13
:
9609 case CP0_REG13__CAUSE
:
9610 save_cpu_state(ctx
, 1);
9611 gen_helper_mtc0_cause(cpu_env
, arg
);
9613 * Stop translation as we may have triggered an interrupt.
9614 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9615 * translated code to check for pending interrupts.
9617 gen_save_pc(ctx
->base
.pc_next
+ 4);
9618 ctx
->base
.is_jmp
= DISAS_EXIT
;
9619 register_name
= "Cause";
9622 goto cp0_unimplemented
;
9625 case CP0_REGISTER_14
:
9627 case CP0_REG14__EPC
:
9628 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9629 register_name
= "EPC";
9632 goto cp0_unimplemented
;
9635 case CP0_REGISTER_15
:
9637 case CP0_REG15__PRID
:
9639 register_name
= "PRid";
9641 case CP0_REG15__EBASE
:
9642 check_insn(ctx
, ISA_MIPS32R2
);
9643 gen_helper_mtc0_ebase(cpu_env
, arg
);
9644 register_name
= "EBase";
9647 goto cp0_unimplemented
;
9650 case CP0_REGISTER_16
:
9652 case CP0_REG16__CONFIG
:
9653 gen_helper_mtc0_config0(cpu_env
, arg
);
9654 register_name
= "Config";
9655 /* Stop translation as we may have switched the execution mode */
9656 ctx
->base
.is_jmp
= DISAS_STOP
;
9658 case CP0_REG16__CONFIG1
:
9659 /* ignored, read only */
9660 register_name
= "Config1";
9662 case CP0_REG16__CONFIG2
:
9663 gen_helper_mtc0_config2(cpu_env
, arg
);
9664 register_name
= "Config2";
9665 /* Stop translation as we may have switched the execution mode */
9666 ctx
->base
.is_jmp
= DISAS_STOP
;
9668 case CP0_REG16__CONFIG3
:
9669 gen_helper_mtc0_config3(cpu_env
, arg
);
9670 register_name
= "Config3";
9671 /* Stop translation as we may have switched the execution mode */
9672 ctx
->base
.is_jmp
= DISAS_STOP
;
9674 case CP0_REG16__CONFIG4
:
9675 /* currently ignored */
9676 register_name
= "Config4";
9678 case CP0_REG16__CONFIG5
:
9679 gen_helper_mtc0_config5(cpu_env
, arg
);
9680 register_name
= "Config5";
9681 /* Stop translation as we may have switched the execution mode */
9682 ctx
->base
.is_jmp
= DISAS_STOP
;
9684 /* 6,7 are implementation dependent */
9686 register_name
= "Invalid config selector";
9687 goto cp0_unimplemented
;
9690 case CP0_REGISTER_17
:
9692 case CP0_REG17__LLADDR
:
9693 gen_helper_mtc0_lladdr(cpu_env
, arg
);
9694 register_name
= "LLAddr";
9696 case CP0_REG17__MAAR
:
9697 CP0_CHECK(ctx
->mrp
);
9698 gen_helper_mtc0_maar(cpu_env
, arg
);
9699 register_name
= "MAAR";
9701 case CP0_REG17__MAARI
:
9702 CP0_CHECK(ctx
->mrp
);
9703 gen_helper_mtc0_maari(cpu_env
, arg
);
9704 register_name
= "MAARI";
9707 goto cp0_unimplemented
;
9710 case CP0_REGISTER_18
:
9712 case CP0_REG18__WATCHLO0
:
9713 case CP0_REG18__WATCHLO1
:
9714 case CP0_REG18__WATCHLO2
:
9715 case CP0_REG18__WATCHLO3
:
9716 case CP0_REG18__WATCHLO4
:
9717 case CP0_REG18__WATCHLO5
:
9718 case CP0_REG18__WATCHLO6
:
9719 case CP0_REG18__WATCHLO7
:
9720 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9721 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
9722 register_name
= "WatchLo";
9725 goto cp0_unimplemented
;
9728 case CP0_REGISTER_19
:
9730 case CP0_REG19__WATCHHI0
:
9731 case CP0_REG19__WATCHHI1
:
9732 case CP0_REG19__WATCHHI2
:
9733 case CP0_REG19__WATCHHI3
:
9734 case CP0_REG19__WATCHHI4
:
9735 case CP0_REG19__WATCHHI5
:
9736 case CP0_REG19__WATCHHI6
:
9737 case CP0_REG19__WATCHHI7
:
9738 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9739 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
9740 register_name
= "WatchHi";
9743 goto cp0_unimplemented
;
9746 case CP0_REGISTER_20
:
9748 case CP0_REG20__XCONTEXT
:
9749 check_insn(ctx
, ISA_MIPS3
);
9750 gen_helper_mtc0_xcontext(cpu_env
, arg
);
9751 register_name
= "XContext";
9754 goto cp0_unimplemented
;
9757 case CP0_REGISTER_21
:
9758 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9759 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
9762 gen_helper_mtc0_framemask(cpu_env
, arg
);
9763 register_name
= "Framemask";
9766 goto cp0_unimplemented
;
9769 case CP0_REGISTER_22
:
9771 register_name
= "Diagnostic"; /* implementation dependent */
9773 case CP0_REGISTER_23
:
9775 case CP0_REG23__DEBUG
:
9776 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
9777 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9778 gen_save_pc(ctx
->base
.pc_next
+ 4);
9779 ctx
->base
.is_jmp
= DISAS_EXIT
;
9780 register_name
= "Debug";
9782 case CP0_REG23__TRACECONTROL
:
9783 /* PDtrace support */
9784 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
9785 /* Stop translation as we may have switched the execution mode */
9786 ctx
->base
.is_jmp
= DISAS_STOP
;
9787 register_name
= "TraceControl";
9788 goto cp0_unimplemented
;
9789 case CP0_REG23__TRACECONTROL2
:
9790 /* PDtrace support */
9791 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
9792 /* Stop translation as we may have switched the execution mode */
9793 ctx
->base
.is_jmp
= DISAS_STOP
;
9794 register_name
= "TraceControl2";
9795 goto cp0_unimplemented
;
9796 case CP0_REG23__USERTRACEDATA1
:
9797 /* PDtrace support */
9798 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
9799 /* Stop translation as we may have switched the execution mode */
9800 ctx
->base
.is_jmp
= DISAS_STOP
;
9801 register_name
= "UserTraceData1";
9802 goto cp0_unimplemented
;
9803 case CP0_REG23__TRACEIBPC
:
9804 /* PDtrace support */
9805 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
9806 /* Stop translation as we may have switched the execution mode */
9807 ctx
->base
.is_jmp
= DISAS_STOP
;
9808 register_name
= "TraceIBPC";
9809 goto cp0_unimplemented
;
9810 case CP0_REG23__TRACEDBPC
:
9811 /* PDtrace support */
9812 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
9813 /* Stop translation as we may have switched the execution mode */
9814 ctx
->base
.is_jmp
= DISAS_STOP
;
9815 register_name
= "TraceDBPC";
9816 goto cp0_unimplemented
;
9818 goto cp0_unimplemented
;
9821 case CP0_REGISTER_24
:
9823 case CP0_REG24__DEPC
:
9825 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9826 register_name
= "DEPC";
9829 goto cp0_unimplemented
;
9832 case CP0_REGISTER_25
:
9834 case CP0_REG25__PERFCTL0
:
9835 gen_helper_mtc0_performance0(cpu_env
, arg
);
9836 register_name
= "Performance0";
9838 case CP0_REG25__PERFCNT0
:
9839 /* gen_helper_mtc0_performance1(cpu_env, arg); */
9840 register_name
= "Performance1";
9841 goto cp0_unimplemented
;
9842 case CP0_REG25__PERFCTL1
:
9843 /* gen_helper_mtc0_performance2(cpu_env, arg); */
9844 register_name
= "Performance2";
9845 goto cp0_unimplemented
;
9846 case CP0_REG25__PERFCNT1
:
9847 /* gen_helper_mtc0_performance3(cpu_env, arg); */
9848 register_name
= "Performance3";
9849 goto cp0_unimplemented
;
9850 case CP0_REG25__PERFCTL2
:
9851 /* gen_helper_mtc0_performance4(cpu_env, arg); */
9852 register_name
= "Performance4";
9853 goto cp0_unimplemented
;
9854 case CP0_REG25__PERFCNT2
:
9855 /* gen_helper_mtc0_performance5(cpu_env, arg); */
9856 register_name
= "Performance5";
9857 goto cp0_unimplemented
;
9858 case CP0_REG25__PERFCTL3
:
9859 /* gen_helper_mtc0_performance6(cpu_env, arg); */
9860 register_name
= "Performance6";
9861 goto cp0_unimplemented
;
9862 case CP0_REG25__PERFCNT3
:
9863 /* gen_helper_mtc0_performance7(cpu_env, arg); */
9864 register_name
= "Performance7";
9865 goto cp0_unimplemented
;
9867 goto cp0_unimplemented
;
9870 case CP0_REGISTER_26
:
9872 case CP0_REG26__ERRCTL
:
9873 gen_helper_mtc0_errctl(cpu_env
, arg
);
9874 ctx
->base
.is_jmp
= DISAS_STOP
;
9875 register_name
= "ErrCtl";
9878 goto cp0_unimplemented
;
9881 case CP0_REGISTER_27
:
9883 case CP0_REG27__CACHERR
:
9885 register_name
= "CacheErr";
9888 goto cp0_unimplemented
;
9891 case CP0_REGISTER_28
:
9893 case CP0_REG28__TAGLO
:
9894 case CP0_REG28__TAGLO1
:
9895 case CP0_REG28__TAGLO2
:
9896 case CP0_REG28__TAGLO3
:
9897 gen_helper_mtc0_taglo(cpu_env
, arg
);
9898 register_name
= "TagLo";
9900 case CP0_REG28__DATALO
:
9901 case CP0_REG28__DATALO1
:
9902 case CP0_REG28__DATALO2
:
9903 case CP0_REG28__DATALO3
:
9904 gen_helper_mtc0_datalo(cpu_env
, arg
);
9905 register_name
= "DataLo";
9908 goto cp0_unimplemented
;
9911 case CP0_REGISTER_29
:
9913 case CP0_REG29__TAGHI
:
9914 case CP0_REG29__TAGHI1
:
9915 case CP0_REG29__TAGHI2
:
9916 case CP0_REG29__TAGHI3
:
9917 gen_helper_mtc0_taghi(cpu_env
, arg
);
9918 register_name
= "TagHi";
9920 case CP0_REG29__DATAHI
:
9921 case CP0_REG29__DATAHI1
:
9922 case CP0_REG29__DATAHI2
:
9923 case CP0_REG29__DATAHI3
:
9924 gen_helper_mtc0_datahi(cpu_env
, arg
);
9925 register_name
= "DataHi";
9928 register_name
= "invalid sel";
9929 goto cp0_unimplemented
;
9932 case CP0_REGISTER_30
:
9934 case CP0_REG30__ERROREPC
:
9935 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9936 register_name
= "ErrorEPC";
9939 goto cp0_unimplemented
;
9942 case CP0_REGISTER_31
:
9944 case CP0_REG31__DESAVE
:
9946 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9947 register_name
= "DESAVE";
9949 case CP0_REG31__KSCRATCH1
:
9950 case CP0_REG31__KSCRATCH2
:
9951 case CP0_REG31__KSCRATCH3
:
9952 case CP0_REG31__KSCRATCH4
:
9953 case CP0_REG31__KSCRATCH5
:
9954 case CP0_REG31__KSCRATCH6
:
9955 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9956 tcg_gen_st_tl(arg
, cpu_env
,
9957 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9958 register_name
= "KScratch";
9961 goto cp0_unimplemented
;
9965 goto cp0_unimplemented
;
9967 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
9969 /* For simplicity assume that all writes can cause interrupts. */
9970 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9972 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9973 * translated code to check for pending interrupts.
9975 gen_save_pc(ctx
->base
.pc_next
+ 4);
9976 ctx
->base
.is_jmp
= DISAS_EXIT
;
9981 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
9982 register_name
, reg
, sel
);
9984 #endif /* TARGET_MIPS64 */
9986 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
9987 int u
, int sel
, int h
)
9989 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9990 TCGv t0
= tcg_temp_local_new();
9992 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9993 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9994 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9995 tcg_gen_movi_tl(t0
, -1);
9996 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9997 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9998 tcg_gen_movi_tl(t0
, -1);
9999 } else if (u
== 0) {
10004 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
10007 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
10017 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
10020 gen_helper_mftc0_tcbind(t0
, cpu_env
);
10023 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
10026 gen_helper_mftc0_tchalt(t0
, cpu_env
);
10029 gen_helper_mftc0_tccontext(t0
, cpu_env
);
10032 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
10035 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
10038 gen_mfc0(ctx
, t0
, rt
, sel
);
10045 gen_helper_mftc0_entryhi(t0
, cpu_env
);
10048 gen_mfc0(ctx
, t0
, rt
, sel
);
10055 gen_helper_mftc0_status(t0
, cpu_env
);
10058 gen_mfc0(ctx
, t0
, rt
, sel
);
10065 gen_helper_mftc0_cause(t0
, cpu_env
);
10075 gen_helper_mftc0_epc(t0
, cpu_env
);
10085 gen_helper_mftc0_ebase(t0
, cpu_env
);
10102 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
10112 gen_helper_mftc0_debug(t0
, cpu_env
);
10115 gen_mfc0(ctx
, t0
, rt
, sel
);
10120 gen_mfc0(ctx
, t0
, rt
, sel
);
10124 /* GPR registers. */
10126 gen_helper_1e0i(mftgpr
, t0
, rt
);
10128 /* Auxiliary CPU registers */
10132 gen_helper_1e0i(mftlo
, t0
, 0);
10135 gen_helper_1e0i(mfthi
, t0
, 0);
10138 gen_helper_1e0i(mftacx
, t0
, 0);
10141 gen_helper_1e0i(mftlo
, t0
, 1);
10144 gen_helper_1e0i(mfthi
, t0
, 1);
10147 gen_helper_1e0i(mftacx
, t0
, 1);
10150 gen_helper_1e0i(mftlo
, t0
, 2);
10153 gen_helper_1e0i(mfthi
, t0
, 2);
10156 gen_helper_1e0i(mftacx
, t0
, 2);
10159 gen_helper_1e0i(mftlo
, t0
, 3);
10162 gen_helper_1e0i(mfthi
, t0
, 3);
10165 gen_helper_1e0i(mftacx
, t0
, 3);
10168 gen_helper_mftdsp(t0
, cpu_env
);
10174 /* Floating point (COP1). */
10176 /* XXX: For now we support only a single FPU context. */
10178 TCGv_i32 fp0
= tcg_temp_new_i32();
10180 gen_load_fpr32(ctx
, fp0
, rt
);
10181 tcg_gen_ext_i32_tl(t0
, fp0
);
10182 tcg_temp_free_i32(fp0
);
10184 TCGv_i32 fp0
= tcg_temp_new_i32();
10186 gen_load_fpr32h(ctx
, fp0
, rt
);
10187 tcg_gen_ext_i32_tl(t0
, fp0
);
10188 tcg_temp_free_i32(fp0
);
10192 /* XXX: For now we support only a single FPU context. */
10193 gen_helper_1e0i(cfc1
, t0
, rt
);
10195 /* COP2: Not implemented. */
10203 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10204 gen_store_gpr(t0
, rd
);
10210 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10211 generate_exception_end(ctx
, EXCP_RI
);
10214 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10215 int u
, int sel
, int h
)
10217 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10218 TCGv t0
= tcg_temp_local_new();
10220 gen_load_gpr(t0
, rt
);
10221 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10222 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10223 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10226 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10227 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10230 } else if (u
== 0) {
10235 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10238 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10248 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10251 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10254 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10257 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10260 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10263 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10266 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10269 gen_mtc0(ctx
, t0
, rd
, sel
);
10276 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10279 gen_mtc0(ctx
, t0
, rd
, sel
);
10286 gen_helper_mttc0_status(cpu_env
, t0
);
10289 gen_mtc0(ctx
, t0
, rd
, sel
);
10296 gen_helper_mttc0_cause(cpu_env
, t0
);
10306 gen_helper_mttc0_ebase(cpu_env
, t0
);
10316 gen_helper_mttc0_debug(cpu_env
, t0
);
10319 gen_mtc0(ctx
, t0
, rd
, sel
);
10324 gen_mtc0(ctx
, t0
, rd
, sel
);
10328 /* GPR registers. */
10330 gen_helper_0e1i(mttgpr
, t0
, rd
);
10332 /* Auxiliary CPU registers */
10336 gen_helper_0e1i(mttlo
, t0
, 0);
10339 gen_helper_0e1i(mtthi
, t0
, 0);
10342 gen_helper_0e1i(mttacx
, t0
, 0);
10345 gen_helper_0e1i(mttlo
, t0
, 1);
10348 gen_helper_0e1i(mtthi
, t0
, 1);
10351 gen_helper_0e1i(mttacx
, t0
, 1);
10354 gen_helper_0e1i(mttlo
, t0
, 2);
10357 gen_helper_0e1i(mtthi
, t0
, 2);
10360 gen_helper_0e1i(mttacx
, t0
, 2);
10363 gen_helper_0e1i(mttlo
, t0
, 3);
10366 gen_helper_0e1i(mtthi
, t0
, 3);
10369 gen_helper_0e1i(mttacx
, t0
, 3);
10372 gen_helper_mttdsp(cpu_env
, t0
);
10378 /* Floating point (COP1). */
10380 /* XXX: For now we support only a single FPU context. */
10382 TCGv_i32 fp0
= tcg_temp_new_i32();
10384 tcg_gen_trunc_tl_i32(fp0
, t0
);
10385 gen_store_fpr32(ctx
, fp0
, rd
);
10386 tcg_temp_free_i32(fp0
);
10388 TCGv_i32 fp0
= tcg_temp_new_i32();
10390 tcg_gen_trunc_tl_i32(fp0
, t0
);
10391 gen_store_fpr32h(ctx
, fp0
, rd
);
10392 tcg_temp_free_i32(fp0
);
10396 /* XXX: For now we support only a single FPU context. */
10398 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10400 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10401 tcg_temp_free_i32(fs_tmp
);
10403 /* Stop translation as we may have changed hflags */
10404 ctx
->base
.is_jmp
= DISAS_STOP
;
10406 /* COP2: Not implemented. */
10414 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10420 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10421 generate_exception_end(ctx
, EXCP_RI
);
10424 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10427 const char *opn
= "ldst";
10429 check_cp0_enabled(ctx
);
10433 /* Treat as NOP. */
10436 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10441 TCGv t0
= tcg_temp_new();
10443 gen_load_gpr(t0
, rt
);
10444 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10449 #if defined(TARGET_MIPS64)
10451 check_insn(ctx
, ISA_MIPS3
);
10453 /* Treat as NOP. */
10456 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10460 check_insn(ctx
, ISA_MIPS3
);
10462 TCGv t0
= tcg_temp_new();
10464 gen_load_gpr(t0
, rt
);
10465 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10474 /* Treat as NOP. */
10477 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10483 TCGv t0
= tcg_temp_new();
10484 gen_load_gpr(t0
, rt
);
10485 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10491 check_cp0_enabled(ctx
);
10493 /* Treat as NOP. */
10496 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10497 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10501 check_cp0_enabled(ctx
);
10502 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10503 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10508 if (!env
->tlb
->helper_tlbwi
) {
10511 gen_helper_tlbwi(cpu_env
);
10515 if (ctx
->ie
>= 2) {
10516 if (!env
->tlb
->helper_tlbinv
) {
10519 gen_helper_tlbinv(cpu_env
);
10520 } /* treat as nop if TLBINV not supported */
10524 if (ctx
->ie
>= 2) {
10525 if (!env
->tlb
->helper_tlbinvf
) {
10528 gen_helper_tlbinvf(cpu_env
);
10529 } /* treat as nop if TLBINV not supported */
10533 if (!env
->tlb
->helper_tlbwr
) {
10536 gen_helper_tlbwr(cpu_env
);
10540 if (!env
->tlb
->helper_tlbp
) {
10543 gen_helper_tlbp(cpu_env
);
10547 if (!env
->tlb
->helper_tlbr
) {
10550 gen_helper_tlbr(cpu_env
);
10552 case OPC_ERET
: /* OPC_ERETNC */
10553 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10554 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10557 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10558 if (ctx
->opcode
& (1 << bit_shift
)) {
10561 check_insn(ctx
, ISA_MIPS32R5
);
10562 gen_helper_eretnc(cpu_env
);
10566 check_insn(ctx
, ISA_MIPS2
);
10567 gen_helper_eret(cpu_env
);
10569 ctx
->base
.is_jmp
= DISAS_EXIT
;
10574 check_insn(ctx
, ISA_MIPS32
);
10575 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10576 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10579 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10581 generate_exception_end(ctx
, EXCP_RI
);
10583 gen_helper_deret(cpu_env
);
10584 ctx
->base
.is_jmp
= DISAS_EXIT
;
10589 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
10590 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10591 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10594 /* If we get an exception, we want to restart at next instruction */
10595 ctx
->base
.pc_next
+= 4;
10596 save_cpu_state(ctx
, 1);
10597 ctx
->base
.pc_next
-= 4;
10598 gen_helper_wait(cpu_env
);
10599 ctx
->base
.is_jmp
= DISAS_NORETURN
;
10604 generate_exception_end(ctx
, EXCP_RI
);
10607 (void)opn
; /* avoid a compiler warning */
10609 #endif /* !CONFIG_USER_ONLY */
10611 /* CP1 Branches (before delay slot) */
10612 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
10613 int32_t cc
, int32_t offset
)
10615 target_ulong btarget
;
10616 TCGv_i32 t0
= tcg_temp_new_i32();
10618 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10619 generate_exception_end(ctx
, EXCP_RI
);
10624 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
10627 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
10631 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10632 tcg_gen_not_i32(t0
, t0
);
10633 tcg_gen_andi_i32(t0
, t0
, 1);
10634 tcg_gen_extu_i32_tl(bcond
, t0
);
10637 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10638 tcg_gen_not_i32(t0
, t0
);
10639 tcg_gen_andi_i32(t0
, t0
, 1);
10640 tcg_gen_extu_i32_tl(bcond
, t0
);
10643 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10644 tcg_gen_andi_i32(t0
, t0
, 1);
10645 tcg_gen_extu_i32_tl(bcond
, t0
);
10648 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10649 tcg_gen_andi_i32(t0
, t0
, 1);
10650 tcg_gen_extu_i32_tl(bcond
, t0
);
10652 ctx
->hflags
|= MIPS_HFLAG_BL
;
10656 TCGv_i32 t1
= tcg_temp_new_i32();
10657 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10658 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10659 tcg_gen_nand_i32(t0
, t0
, t1
);
10660 tcg_temp_free_i32(t1
);
10661 tcg_gen_andi_i32(t0
, t0
, 1);
10662 tcg_gen_extu_i32_tl(bcond
, t0
);
10667 TCGv_i32 t1
= tcg_temp_new_i32();
10668 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10669 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10670 tcg_gen_or_i32(t0
, t0
, t1
);
10671 tcg_temp_free_i32(t1
);
10672 tcg_gen_andi_i32(t0
, t0
, 1);
10673 tcg_gen_extu_i32_tl(bcond
, t0
);
10678 TCGv_i32 t1
= tcg_temp_new_i32();
10679 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10680 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10681 tcg_gen_and_i32(t0
, t0
, t1
);
10682 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10683 tcg_gen_and_i32(t0
, t0
, t1
);
10684 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10685 tcg_gen_nand_i32(t0
, t0
, t1
);
10686 tcg_temp_free_i32(t1
);
10687 tcg_gen_andi_i32(t0
, t0
, 1);
10688 tcg_gen_extu_i32_tl(bcond
, t0
);
10693 TCGv_i32 t1
= tcg_temp_new_i32();
10694 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10695 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10696 tcg_gen_or_i32(t0
, t0
, t1
);
10697 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10698 tcg_gen_or_i32(t0
, t0
, t1
);
10699 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10700 tcg_gen_or_i32(t0
, t0
, t1
);
10701 tcg_temp_free_i32(t1
);
10702 tcg_gen_andi_i32(t0
, t0
, 1);
10703 tcg_gen_extu_i32_tl(bcond
, t0
);
10706 ctx
->hflags
|= MIPS_HFLAG_BC
;
10709 MIPS_INVAL("cp1 cond branch");
10710 generate_exception_end(ctx
, EXCP_RI
);
10713 ctx
->btarget
= btarget
;
10714 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10716 tcg_temp_free_i32(t0
);
10719 /* R6 CP1 Branches */
10720 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
10721 int32_t ft
, int32_t offset
,
10722 int delayslot_size
)
10724 target_ulong btarget
;
10725 TCGv_i64 t0
= tcg_temp_new_i64();
10727 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10728 #ifdef MIPS_DEBUG_DISAS
10729 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10730 "\n", ctx
->base
.pc_next
);
10732 generate_exception_end(ctx
, EXCP_RI
);
10736 gen_load_fpr64(ctx
, t0
, ft
);
10737 tcg_gen_andi_i64(t0
, t0
, 1);
10739 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
10743 tcg_gen_xori_i64(t0
, t0
, 1);
10744 ctx
->hflags
|= MIPS_HFLAG_BC
;
10747 /* t0 already set */
10748 ctx
->hflags
|= MIPS_HFLAG_BC
;
10751 MIPS_INVAL("cp1 cond branch");
10752 generate_exception_end(ctx
, EXCP_RI
);
10756 tcg_gen_trunc_i64_tl(bcond
, t0
);
10758 ctx
->btarget
= btarget
;
10760 switch (delayslot_size
) {
10762 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
10765 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10770 tcg_temp_free_i64(t0
);
10773 /* Coprocessor 1 (FPU) */
10775 #define FOP(func, fmt) (((fmt) << 21) | (func))
10778 OPC_ADD_S
= FOP(0, FMT_S
),
10779 OPC_SUB_S
= FOP(1, FMT_S
),
10780 OPC_MUL_S
= FOP(2, FMT_S
),
10781 OPC_DIV_S
= FOP(3, FMT_S
),
10782 OPC_SQRT_S
= FOP(4, FMT_S
),
10783 OPC_ABS_S
= FOP(5, FMT_S
),
10784 OPC_MOV_S
= FOP(6, FMT_S
),
10785 OPC_NEG_S
= FOP(7, FMT_S
),
10786 OPC_ROUND_L_S
= FOP(8, FMT_S
),
10787 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
10788 OPC_CEIL_L_S
= FOP(10, FMT_S
),
10789 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
10790 OPC_ROUND_W_S
= FOP(12, FMT_S
),
10791 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
10792 OPC_CEIL_W_S
= FOP(14, FMT_S
),
10793 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
10794 OPC_SEL_S
= FOP(16, FMT_S
),
10795 OPC_MOVCF_S
= FOP(17, FMT_S
),
10796 OPC_MOVZ_S
= FOP(18, FMT_S
),
10797 OPC_MOVN_S
= FOP(19, FMT_S
),
10798 OPC_SELEQZ_S
= FOP(20, FMT_S
),
10799 OPC_RECIP_S
= FOP(21, FMT_S
),
10800 OPC_RSQRT_S
= FOP(22, FMT_S
),
10801 OPC_SELNEZ_S
= FOP(23, FMT_S
),
10802 OPC_MADDF_S
= FOP(24, FMT_S
),
10803 OPC_MSUBF_S
= FOP(25, FMT_S
),
10804 OPC_RINT_S
= FOP(26, FMT_S
),
10805 OPC_CLASS_S
= FOP(27, FMT_S
),
10806 OPC_MIN_S
= FOP(28, FMT_S
),
10807 OPC_RECIP2_S
= FOP(28, FMT_S
),
10808 OPC_MINA_S
= FOP(29, FMT_S
),
10809 OPC_RECIP1_S
= FOP(29, FMT_S
),
10810 OPC_MAX_S
= FOP(30, FMT_S
),
10811 OPC_RSQRT1_S
= FOP(30, FMT_S
),
10812 OPC_MAXA_S
= FOP(31, FMT_S
),
10813 OPC_RSQRT2_S
= FOP(31, FMT_S
),
10814 OPC_CVT_D_S
= FOP(33, FMT_S
),
10815 OPC_CVT_W_S
= FOP(36, FMT_S
),
10816 OPC_CVT_L_S
= FOP(37, FMT_S
),
10817 OPC_CVT_PS_S
= FOP(38, FMT_S
),
10818 OPC_CMP_F_S
= FOP(48, FMT_S
),
10819 OPC_CMP_UN_S
= FOP(49, FMT_S
),
10820 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
10821 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
10822 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
10823 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
10824 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
10825 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
10826 OPC_CMP_SF_S
= FOP(56, FMT_S
),
10827 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
10828 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
10829 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
10830 OPC_CMP_LT_S
= FOP(60, FMT_S
),
10831 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
10832 OPC_CMP_LE_S
= FOP(62, FMT_S
),
10833 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
10835 OPC_ADD_D
= FOP(0, FMT_D
),
10836 OPC_SUB_D
= FOP(1, FMT_D
),
10837 OPC_MUL_D
= FOP(2, FMT_D
),
10838 OPC_DIV_D
= FOP(3, FMT_D
),
10839 OPC_SQRT_D
= FOP(4, FMT_D
),
10840 OPC_ABS_D
= FOP(5, FMT_D
),
10841 OPC_MOV_D
= FOP(6, FMT_D
),
10842 OPC_NEG_D
= FOP(7, FMT_D
),
10843 OPC_ROUND_L_D
= FOP(8, FMT_D
),
10844 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
10845 OPC_CEIL_L_D
= FOP(10, FMT_D
),
10846 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
10847 OPC_ROUND_W_D
= FOP(12, FMT_D
),
10848 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
10849 OPC_CEIL_W_D
= FOP(14, FMT_D
),
10850 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
10851 OPC_SEL_D
= FOP(16, FMT_D
),
10852 OPC_MOVCF_D
= FOP(17, FMT_D
),
10853 OPC_MOVZ_D
= FOP(18, FMT_D
),
10854 OPC_MOVN_D
= FOP(19, FMT_D
),
10855 OPC_SELEQZ_D
= FOP(20, FMT_D
),
10856 OPC_RECIP_D
= FOP(21, FMT_D
),
10857 OPC_RSQRT_D
= FOP(22, FMT_D
),
10858 OPC_SELNEZ_D
= FOP(23, FMT_D
),
10859 OPC_MADDF_D
= FOP(24, FMT_D
),
10860 OPC_MSUBF_D
= FOP(25, FMT_D
),
10861 OPC_RINT_D
= FOP(26, FMT_D
),
10862 OPC_CLASS_D
= FOP(27, FMT_D
),
10863 OPC_MIN_D
= FOP(28, FMT_D
),
10864 OPC_RECIP2_D
= FOP(28, FMT_D
),
10865 OPC_MINA_D
= FOP(29, FMT_D
),
10866 OPC_RECIP1_D
= FOP(29, FMT_D
),
10867 OPC_MAX_D
= FOP(30, FMT_D
),
10868 OPC_RSQRT1_D
= FOP(30, FMT_D
),
10869 OPC_MAXA_D
= FOP(31, FMT_D
),
10870 OPC_RSQRT2_D
= FOP(31, FMT_D
),
10871 OPC_CVT_S_D
= FOP(32, FMT_D
),
10872 OPC_CVT_W_D
= FOP(36, FMT_D
),
10873 OPC_CVT_L_D
= FOP(37, FMT_D
),
10874 OPC_CMP_F_D
= FOP(48, FMT_D
),
10875 OPC_CMP_UN_D
= FOP(49, FMT_D
),
10876 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
10877 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
10878 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
10879 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
10880 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
10881 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
10882 OPC_CMP_SF_D
= FOP(56, FMT_D
),
10883 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
10884 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
10885 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
10886 OPC_CMP_LT_D
= FOP(60, FMT_D
),
10887 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
10888 OPC_CMP_LE_D
= FOP(62, FMT_D
),
10889 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
10891 OPC_CVT_S_W
= FOP(32, FMT_W
),
10892 OPC_CVT_D_W
= FOP(33, FMT_W
),
10893 OPC_CVT_S_L
= FOP(32, FMT_L
),
10894 OPC_CVT_D_L
= FOP(33, FMT_L
),
10895 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
10897 OPC_ADD_PS
= FOP(0, FMT_PS
),
10898 OPC_SUB_PS
= FOP(1, FMT_PS
),
10899 OPC_MUL_PS
= FOP(2, FMT_PS
),
10900 OPC_DIV_PS
= FOP(3, FMT_PS
),
10901 OPC_ABS_PS
= FOP(5, FMT_PS
),
10902 OPC_MOV_PS
= FOP(6, FMT_PS
),
10903 OPC_NEG_PS
= FOP(7, FMT_PS
),
10904 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
10905 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
10906 OPC_MOVN_PS
= FOP(19, FMT_PS
),
10907 OPC_ADDR_PS
= FOP(24, FMT_PS
),
10908 OPC_MULR_PS
= FOP(26, FMT_PS
),
10909 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
10910 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
10911 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
10912 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
10914 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
10915 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
10916 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
10917 OPC_PLL_PS
= FOP(44, FMT_PS
),
10918 OPC_PLU_PS
= FOP(45, FMT_PS
),
10919 OPC_PUL_PS
= FOP(46, FMT_PS
),
10920 OPC_PUU_PS
= FOP(47, FMT_PS
),
10921 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
10922 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
10923 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
10924 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
10925 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
10926 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
10927 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
10928 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
10929 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
10930 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
10931 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
10932 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
10933 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
10934 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
10935 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
10936 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
10940 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
10941 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
10942 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
10943 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
10944 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
10945 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
10946 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
10947 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
10948 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
10949 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
10950 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
10951 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
10952 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
10953 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
10954 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
10955 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
10956 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
10957 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
10958 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
10959 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
10960 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
10961 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
10963 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
10964 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
10965 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
10966 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
10967 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
10968 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
10969 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
10970 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
10971 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
10972 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
10973 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
10974 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
10975 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
10976 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
10977 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
10978 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
10979 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
10980 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
10981 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
10982 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
10983 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
10984 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
10987 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
10989 TCGv t0
= tcg_temp_new();
10994 TCGv_i32 fp0
= tcg_temp_new_i32();
10996 gen_load_fpr32(ctx
, fp0
, fs
);
10997 tcg_gen_ext_i32_tl(t0
, fp0
);
10998 tcg_temp_free_i32(fp0
);
11000 gen_store_gpr(t0
, rt
);
11003 gen_load_gpr(t0
, rt
);
11005 TCGv_i32 fp0
= tcg_temp_new_i32();
11007 tcg_gen_trunc_tl_i32(fp0
, t0
);
11008 gen_store_fpr32(ctx
, fp0
, fs
);
11009 tcg_temp_free_i32(fp0
);
11013 gen_helper_1e0i(cfc1
, t0
, fs
);
11014 gen_store_gpr(t0
, rt
);
11017 gen_load_gpr(t0
, rt
);
11018 save_cpu_state(ctx
, 0);
11020 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
11022 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
11023 tcg_temp_free_i32(fs_tmp
);
11025 /* Stop translation as we may have changed hflags */
11026 ctx
->base
.is_jmp
= DISAS_STOP
;
11028 #if defined(TARGET_MIPS64)
11030 gen_load_fpr64(ctx
, t0
, fs
);
11031 gen_store_gpr(t0
, rt
);
11034 gen_load_gpr(t0
, rt
);
11035 gen_store_fpr64(ctx
, t0
, fs
);
11040 TCGv_i32 fp0
= tcg_temp_new_i32();
11042 gen_load_fpr32h(ctx
, fp0
, fs
);
11043 tcg_gen_ext_i32_tl(t0
, fp0
);
11044 tcg_temp_free_i32(fp0
);
11046 gen_store_gpr(t0
, rt
);
11049 gen_load_gpr(t0
, rt
);
11051 TCGv_i32 fp0
= tcg_temp_new_i32();
11053 tcg_gen_trunc_tl_i32(fp0
, t0
);
11054 gen_store_fpr32h(ctx
, fp0
, fs
);
11055 tcg_temp_free_i32(fp0
);
11059 MIPS_INVAL("cp1 move");
11060 generate_exception_end(ctx
, EXCP_RI
);
11068 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
11075 /* Treat as NOP. */
11080 cond
= TCG_COND_EQ
;
11082 cond
= TCG_COND_NE
;
11085 l1
= gen_new_label();
11086 t0
= tcg_temp_new_i32();
11087 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11088 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11089 tcg_temp_free_i32(t0
);
11091 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
11093 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
11098 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11102 TCGv_i32 t0
= tcg_temp_new_i32();
11103 TCGLabel
*l1
= gen_new_label();
11106 cond
= TCG_COND_EQ
;
11108 cond
= TCG_COND_NE
;
11111 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11112 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11113 gen_load_fpr32(ctx
, t0
, fs
);
11114 gen_store_fpr32(ctx
, t0
, fd
);
11116 tcg_temp_free_i32(t0
);
11119 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11123 TCGv_i32 t0
= tcg_temp_new_i32();
11125 TCGLabel
*l1
= gen_new_label();
11128 cond
= TCG_COND_EQ
;
11130 cond
= TCG_COND_NE
;
11133 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11134 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11135 tcg_temp_free_i32(t0
);
11136 fp0
= tcg_temp_new_i64();
11137 gen_load_fpr64(ctx
, fp0
, fs
);
11138 gen_store_fpr64(ctx
, fp0
, fd
);
11139 tcg_temp_free_i64(fp0
);
11143 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
11147 TCGv_i32 t0
= tcg_temp_new_i32();
11148 TCGLabel
*l1
= gen_new_label();
11149 TCGLabel
*l2
= gen_new_label();
11152 cond
= TCG_COND_EQ
;
11154 cond
= TCG_COND_NE
;
11157 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11158 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11159 gen_load_fpr32(ctx
, t0
, fs
);
11160 gen_store_fpr32(ctx
, t0
, fd
);
11163 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
11164 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
11165 gen_load_fpr32h(ctx
, t0
, fs
);
11166 gen_store_fpr32h(ctx
, t0
, fd
);
11167 tcg_temp_free_i32(t0
);
11171 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11174 TCGv_i32 t1
= tcg_const_i32(0);
11175 TCGv_i32 fp0
= tcg_temp_new_i32();
11176 TCGv_i32 fp1
= tcg_temp_new_i32();
11177 TCGv_i32 fp2
= tcg_temp_new_i32();
11178 gen_load_fpr32(ctx
, fp0
, fd
);
11179 gen_load_fpr32(ctx
, fp1
, ft
);
11180 gen_load_fpr32(ctx
, fp2
, fs
);
11184 tcg_gen_andi_i32(fp0
, fp0
, 1);
11185 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11188 tcg_gen_andi_i32(fp1
, fp1
, 1);
11189 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11192 tcg_gen_andi_i32(fp1
, fp1
, 1);
11193 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11196 MIPS_INVAL("gen_sel_s");
11197 generate_exception_end(ctx
, EXCP_RI
);
11201 gen_store_fpr32(ctx
, fp0
, fd
);
11202 tcg_temp_free_i32(fp2
);
11203 tcg_temp_free_i32(fp1
);
11204 tcg_temp_free_i32(fp0
);
11205 tcg_temp_free_i32(t1
);
11208 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11211 TCGv_i64 t1
= tcg_const_i64(0);
11212 TCGv_i64 fp0
= tcg_temp_new_i64();
11213 TCGv_i64 fp1
= tcg_temp_new_i64();
11214 TCGv_i64 fp2
= tcg_temp_new_i64();
11215 gen_load_fpr64(ctx
, fp0
, fd
);
11216 gen_load_fpr64(ctx
, fp1
, ft
);
11217 gen_load_fpr64(ctx
, fp2
, fs
);
11221 tcg_gen_andi_i64(fp0
, fp0
, 1);
11222 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11225 tcg_gen_andi_i64(fp1
, fp1
, 1);
11226 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11229 tcg_gen_andi_i64(fp1
, fp1
, 1);
11230 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11233 MIPS_INVAL("gen_sel_d");
11234 generate_exception_end(ctx
, EXCP_RI
);
11238 gen_store_fpr64(ctx
, fp0
, fd
);
11239 tcg_temp_free_i64(fp2
);
11240 tcg_temp_free_i64(fp1
);
11241 tcg_temp_free_i64(fp0
);
11242 tcg_temp_free_i64(t1
);
11245 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11246 int ft
, int fs
, int fd
, int cc
)
11248 uint32_t func
= ctx
->opcode
& 0x3f;
11252 TCGv_i32 fp0
= tcg_temp_new_i32();
11253 TCGv_i32 fp1
= tcg_temp_new_i32();
11255 gen_load_fpr32(ctx
, fp0
, fs
);
11256 gen_load_fpr32(ctx
, fp1
, ft
);
11257 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11258 tcg_temp_free_i32(fp1
);
11259 gen_store_fpr32(ctx
, fp0
, fd
);
11260 tcg_temp_free_i32(fp0
);
11265 TCGv_i32 fp0
= tcg_temp_new_i32();
11266 TCGv_i32 fp1
= tcg_temp_new_i32();
11268 gen_load_fpr32(ctx
, fp0
, fs
);
11269 gen_load_fpr32(ctx
, fp1
, ft
);
11270 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11271 tcg_temp_free_i32(fp1
);
11272 gen_store_fpr32(ctx
, fp0
, fd
);
11273 tcg_temp_free_i32(fp0
);
11278 TCGv_i32 fp0
= tcg_temp_new_i32();
11279 TCGv_i32 fp1
= tcg_temp_new_i32();
11281 gen_load_fpr32(ctx
, fp0
, fs
);
11282 gen_load_fpr32(ctx
, fp1
, ft
);
11283 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11284 tcg_temp_free_i32(fp1
);
11285 gen_store_fpr32(ctx
, fp0
, fd
);
11286 tcg_temp_free_i32(fp0
);
11291 TCGv_i32 fp0
= tcg_temp_new_i32();
11292 TCGv_i32 fp1
= tcg_temp_new_i32();
11294 gen_load_fpr32(ctx
, fp0
, fs
);
11295 gen_load_fpr32(ctx
, fp1
, ft
);
11296 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11297 tcg_temp_free_i32(fp1
);
11298 gen_store_fpr32(ctx
, fp0
, fd
);
11299 tcg_temp_free_i32(fp0
);
11304 TCGv_i32 fp0
= tcg_temp_new_i32();
11306 gen_load_fpr32(ctx
, fp0
, fs
);
11307 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11308 gen_store_fpr32(ctx
, fp0
, fd
);
11309 tcg_temp_free_i32(fp0
);
11314 TCGv_i32 fp0
= tcg_temp_new_i32();
11316 gen_load_fpr32(ctx
, fp0
, fs
);
11317 if (ctx
->abs2008
) {
11318 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11320 gen_helper_float_abs_s(fp0
, fp0
);
11322 gen_store_fpr32(ctx
, fp0
, fd
);
11323 tcg_temp_free_i32(fp0
);
11328 TCGv_i32 fp0
= tcg_temp_new_i32();
11330 gen_load_fpr32(ctx
, fp0
, fs
);
11331 gen_store_fpr32(ctx
, fp0
, fd
);
11332 tcg_temp_free_i32(fp0
);
11337 TCGv_i32 fp0
= tcg_temp_new_i32();
11339 gen_load_fpr32(ctx
, fp0
, fs
);
11340 if (ctx
->abs2008
) {
11341 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11343 gen_helper_float_chs_s(fp0
, fp0
);
11345 gen_store_fpr32(ctx
, fp0
, fd
);
11346 tcg_temp_free_i32(fp0
);
11349 case OPC_ROUND_L_S
:
11350 check_cp1_64bitmode(ctx
);
11352 TCGv_i32 fp32
= tcg_temp_new_i32();
11353 TCGv_i64 fp64
= tcg_temp_new_i64();
11355 gen_load_fpr32(ctx
, fp32
, fs
);
11356 if (ctx
->nan2008
) {
11357 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11359 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11361 tcg_temp_free_i32(fp32
);
11362 gen_store_fpr64(ctx
, fp64
, fd
);
11363 tcg_temp_free_i64(fp64
);
11366 case OPC_TRUNC_L_S
:
11367 check_cp1_64bitmode(ctx
);
11369 TCGv_i32 fp32
= tcg_temp_new_i32();
11370 TCGv_i64 fp64
= tcg_temp_new_i64();
11372 gen_load_fpr32(ctx
, fp32
, fs
);
11373 if (ctx
->nan2008
) {
11374 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11376 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11378 tcg_temp_free_i32(fp32
);
11379 gen_store_fpr64(ctx
, fp64
, fd
);
11380 tcg_temp_free_i64(fp64
);
11384 check_cp1_64bitmode(ctx
);
11386 TCGv_i32 fp32
= tcg_temp_new_i32();
11387 TCGv_i64 fp64
= tcg_temp_new_i64();
11389 gen_load_fpr32(ctx
, fp32
, fs
);
11390 if (ctx
->nan2008
) {
11391 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11393 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11395 tcg_temp_free_i32(fp32
);
11396 gen_store_fpr64(ctx
, fp64
, fd
);
11397 tcg_temp_free_i64(fp64
);
11400 case OPC_FLOOR_L_S
:
11401 check_cp1_64bitmode(ctx
);
11403 TCGv_i32 fp32
= tcg_temp_new_i32();
11404 TCGv_i64 fp64
= tcg_temp_new_i64();
11406 gen_load_fpr32(ctx
, fp32
, fs
);
11407 if (ctx
->nan2008
) {
11408 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11410 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11412 tcg_temp_free_i32(fp32
);
11413 gen_store_fpr64(ctx
, fp64
, fd
);
11414 tcg_temp_free_i64(fp64
);
11417 case OPC_ROUND_W_S
:
11419 TCGv_i32 fp0
= tcg_temp_new_i32();
11421 gen_load_fpr32(ctx
, fp0
, fs
);
11422 if (ctx
->nan2008
) {
11423 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11425 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11427 gen_store_fpr32(ctx
, fp0
, fd
);
11428 tcg_temp_free_i32(fp0
);
11431 case OPC_TRUNC_W_S
:
11433 TCGv_i32 fp0
= tcg_temp_new_i32();
11435 gen_load_fpr32(ctx
, fp0
, fs
);
11436 if (ctx
->nan2008
) {
11437 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11439 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11441 gen_store_fpr32(ctx
, fp0
, fd
);
11442 tcg_temp_free_i32(fp0
);
11447 TCGv_i32 fp0
= tcg_temp_new_i32();
11449 gen_load_fpr32(ctx
, fp0
, fs
);
11450 if (ctx
->nan2008
) {
11451 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11453 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11455 gen_store_fpr32(ctx
, fp0
, fd
);
11456 tcg_temp_free_i32(fp0
);
11459 case OPC_FLOOR_W_S
:
11461 TCGv_i32 fp0
= tcg_temp_new_i32();
11463 gen_load_fpr32(ctx
, fp0
, fs
);
11464 if (ctx
->nan2008
) {
11465 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11467 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11469 gen_store_fpr32(ctx
, fp0
, fd
);
11470 tcg_temp_free_i32(fp0
);
11474 check_insn(ctx
, ISA_MIPS32R6
);
11475 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11478 check_insn(ctx
, ISA_MIPS32R6
);
11479 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11482 check_insn(ctx
, ISA_MIPS32R6
);
11483 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11486 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11487 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11490 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11492 TCGLabel
*l1
= gen_new_label();
11496 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11498 fp0
= tcg_temp_new_i32();
11499 gen_load_fpr32(ctx
, fp0
, fs
);
11500 gen_store_fpr32(ctx
, fp0
, fd
);
11501 tcg_temp_free_i32(fp0
);
11506 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11508 TCGLabel
*l1
= gen_new_label();
11512 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11513 fp0
= tcg_temp_new_i32();
11514 gen_load_fpr32(ctx
, fp0
, fs
);
11515 gen_store_fpr32(ctx
, fp0
, fd
);
11516 tcg_temp_free_i32(fp0
);
11523 TCGv_i32 fp0
= tcg_temp_new_i32();
11525 gen_load_fpr32(ctx
, fp0
, fs
);
11526 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11527 gen_store_fpr32(ctx
, fp0
, fd
);
11528 tcg_temp_free_i32(fp0
);
11533 TCGv_i32 fp0
= tcg_temp_new_i32();
11535 gen_load_fpr32(ctx
, fp0
, fs
);
11536 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11537 gen_store_fpr32(ctx
, fp0
, fd
);
11538 tcg_temp_free_i32(fp0
);
11542 check_insn(ctx
, ISA_MIPS32R6
);
11544 TCGv_i32 fp0
= tcg_temp_new_i32();
11545 TCGv_i32 fp1
= tcg_temp_new_i32();
11546 TCGv_i32 fp2
= tcg_temp_new_i32();
11547 gen_load_fpr32(ctx
, fp0
, fs
);
11548 gen_load_fpr32(ctx
, fp1
, ft
);
11549 gen_load_fpr32(ctx
, fp2
, fd
);
11550 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11551 gen_store_fpr32(ctx
, fp2
, fd
);
11552 tcg_temp_free_i32(fp2
);
11553 tcg_temp_free_i32(fp1
);
11554 tcg_temp_free_i32(fp0
);
11558 check_insn(ctx
, ISA_MIPS32R6
);
11560 TCGv_i32 fp0
= tcg_temp_new_i32();
11561 TCGv_i32 fp1
= tcg_temp_new_i32();
11562 TCGv_i32 fp2
= tcg_temp_new_i32();
11563 gen_load_fpr32(ctx
, fp0
, fs
);
11564 gen_load_fpr32(ctx
, fp1
, ft
);
11565 gen_load_fpr32(ctx
, fp2
, fd
);
11566 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11567 gen_store_fpr32(ctx
, fp2
, fd
);
11568 tcg_temp_free_i32(fp2
);
11569 tcg_temp_free_i32(fp1
);
11570 tcg_temp_free_i32(fp0
);
11574 check_insn(ctx
, ISA_MIPS32R6
);
11576 TCGv_i32 fp0
= tcg_temp_new_i32();
11577 gen_load_fpr32(ctx
, fp0
, fs
);
11578 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
11579 gen_store_fpr32(ctx
, fp0
, fd
);
11580 tcg_temp_free_i32(fp0
);
11584 check_insn(ctx
, ISA_MIPS32R6
);
11586 TCGv_i32 fp0
= tcg_temp_new_i32();
11587 gen_load_fpr32(ctx
, fp0
, fs
);
11588 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
11589 gen_store_fpr32(ctx
, fp0
, fd
);
11590 tcg_temp_free_i32(fp0
);
11593 case OPC_MIN_S
: /* OPC_RECIP2_S */
11594 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11596 TCGv_i32 fp0
= tcg_temp_new_i32();
11597 TCGv_i32 fp1
= tcg_temp_new_i32();
11598 TCGv_i32 fp2
= tcg_temp_new_i32();
11599 gen_load_fpr32(ctx
, fp0
, fs
);
11600 gen_load_fpr32(ctx
, fp1
, ft
);
11601 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
11602 gen_store_fpr32(ctx
, fp2
, fd
);
11603 tcg_temp_free_i32(fp2
);
11604 tcg_temp_free_i32(fp1
);
11605 tcg_temp_free_i32(fp0
);
11608 check_cp1_64bitmode(ctx
);
11610 TCGv_i32 fp0
= tcg_temp_new_i32();
11611 TCGv_i32 fp1
= tcg_temp_new_i32();
11613 gen_load_fpr32(ctx
, fp0
, fs
);
11614 gen_load_fpr32(ctx
, fp1
, ft
);
11615 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
11616 tcg_temp_free_i32(fp1
);
11617 gen_store_fpr32(ctx
, fp0
, fd
);
11618 tcg_temp_free_i32(fp0
);
11622 case OPC_MINA_S
: /* OPC_RECIP1_S */
11623 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11625 TCGv_i32 fp0
= tcg_temp_new_i32();
11626 TCGv_i32 fp1
= tcg_temp_new_i32();
11627 TCGv_i32 fp2
= tcg_temp_new_i32();
11628 gen_load_fpr32(ctx
, fp0
, fs
);
11629 gen_load_fpr32(ctx
, fp1
, ft
);
11630 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
11631 gen_store_fpr32(ctx
, fp2
, fd
);
11632 tcg_temp_free_i32(fp2
);
11633 tcg_temp_free_i32(fp1
);
11634 tcg_temp_free_i32(fp0
);
11637 check_cp1_64bitmode(ctx
);
11639 TCGv_i32 fp0
= tcg_temp_new_i32();
11641 gen_load_fpr32(ctx
, fp0
, fs
);
11642 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
11643 gen_store_fpr32(ctx
, fp0
, fd
);
11644 tcg_temp_free_i32(fp0
);
11648 case OPC_MAX_S
: /* OPC_RSQRT1_S */
11649 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11651 TCGv_i32 fp0
= tcg_temp_new_i32();
11652 TCGv_i32 fp1
= tcg_temp_new_i32();
11653 gen_load_fpr32(ctx
, fp0
, fs
);
11654 gen_load_fpr32(ctx
, fp1
, ft
);
11655 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
11656 gen_store_fpr32(ctx
, fp1
, fd
);
11657 tcg_temp_free_i32(fp1
);
11658 tcg_temp_free_i32(fp0
);
11661 check_cp1_64bitmode(ctx
);
11663 TCGv_i32 fp0
= tcg_temp_new_i32();
11665 gen_load_fpr32(ctx
, fp0
, fs
);
11666 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
11667 gen_store_fpr32(ctx
, fp0
, fd
);
11668 tcg_temp_free_i32(fp0
);
11672 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
11673 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11675 TCGv_i32 fp0
= tcg_temp_new_i32();
11676 TCGv_i32 fp1
= tcg_temp_new_i32();
11677 gen_load_fpr32(ctx
, fp0
, fs
);
11678 gen_load_fpr32(ctx
, fp1
, ft
);
11679 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
11680 gen_store_fpr32(ctx
, fp1
, fd
);
11681 tcg_temp_free_i32(fp1
);
11682 tcg_temp_free_i32(fp0
);
11685 check_cp1_64bitmode(ctx
);
11687 TCGv_i32 fp0
= tcg_temp_new_i32();
11688 TCGv_i32 fp1
= tcg_temp_new_i32();
11690 gen_load_fpr32(ctx
, fp0
, fs
);
11691 gen_load_fpr32(ctx
, fp1
, ft
);
11692 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
11693 tcg_temp_free_i32(fp1
);
11694 gen_store_fpr32(ctx
, fp0
, fd
);
11695 tcg_temp_free_i32(fp0
);
11700 check_cp1_registers(ctx
, fd
);
11702 TCGv_i32 fp32
= tcg_temp_new_i32();
11703 TCGv_i64 fp64
= tcg_temp_new_i64();
11705 gen_load_fpr32(ctx
, fp32
, fs
);
11706 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
11707 tcg_temp_free_i32(fp32
);
11708 gen_store_fpr64(ctx
, fp64
, fd
);
11709 tcg_temp_free_i64(fp64
);
11714 TCGv_i32 fp0
= tcg_temp_new_i32();
11716 gen_load_fpr32(ctx
, fp0
, fs
);
11717 if (ctx
->nan2008
) {
11718 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
11720 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
11722 gen_store_fpr32(ctx
, fp0
, fd
);
11723 tcg_temp_free_i32(fp0
);
11727 check_cp1_64bitmode(ctx
);
11729 TCGv_i32 fp32
= tcg_temp_new_i32();
11730 TCGv_i64 fp64
= tcg_temp_new_i64();
11732 gen_load_fpr32(ctx
, fp32
, fs
);
11733 if (ctx
->nan2008
) {
11734 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
11736 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
11738 tcg_temp_free_i32(fp32
);
11739 gen_store_fpr64(ctx
, fp64
, fd
);
11740 tcg_temp_free_i64(fp64
);
11746 TCGv_i64 fp64
= tcg_temp_new_i64();
11747 TCGv_i32 fp32_0
= tcg_temp_new_i32();
11748 TCGv_i32 fp32_1
= tcg_temp_new_i32();
11750 gen_load_fpr32(ctx
, fp32_0
, fs
);
11751 gen_load_fpr32(ctx
, fp32_1
, ft
);
11752 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
11753 tcg_temp_free_i32(fp32_1
);
11754 tcg_temp_free_i32(fp32_0
);
11755 gen_store_fpr64(ctx
, fp64
, fd
);
11756 tcg_temp_free_i64(fp64
);
11762 case OPC_CMP_UEQ_S
:
11763 case OPC_CMP_OLT_S
:
11764 case OPC_CMP_ULT_S
:
11765 case OPC_CMP_OLE_S
:
11766 case OPC_CMP_ULE_S
:
11768 case OPC_CMP_NGLE_S
:
11769 case OPC_CMP_SEQ_S
:
11770 case OPC_CMP_NGL_S
:
11772 case OPC_CMP_NGE_S
:
11774 case OPC_CMP_NGT_S
:
11775 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11776 if (ctx
->opcode
& (1 << 6)) {
11777 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
11779 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
11783 check_cp1_registers(ctx
, fs
| ft
| fd
);
11785 TCGv_i64 fp0
= tcg_temp_new_i64();
11786 TCGv_i64 fp1
= tcg_temp_new_i64();
11788 gen_load_fpr64(ctx
, fp0
, fs
);
11789 gen_load_fpr64(ctx
, fp1
, ft
);
11790 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
11791 tcg_temp_free_i64(fp1
);
11792 gen_store_fpr64(ctx
, fp0
, fd
);
11793 tcg_temp_free_i64(fp0
);
11797 check_cp1_registers(ctx
, fs
| ft
| fd
);
11799 TCGv_i64 fp0
= tcg_temp_new_i64();
11800 TCGv_i64 fp1
= tcg_temp_new_i64();
11802 gen_load_fpr64(ctx
, fp0
, fs
);
11803 gen_load_fpr64(ctx
, fp1
, ft
);
11804 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
11805 tcg_temp_free_i64(fp1
);
11806 gen_store_fpr64(ctx
, fp0
, fd
);
11807 tcg_temp_free_i64(fp0
);
11811 check_cp1_registers(ctx
, fs
| ft
| fd
);
11813 TCGv_i64 fp0
= tcg_temp_new_i64();
11814 TCGv_i64 fp1
= tcg_temp_new_i64();
11816 gen_load_fpr64(ctx
, fp0
, fs
);
11817 gen_load_fpr64(ctx
, fp1
, ft
);
11818 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
11819 tcg_temp_free_i64(fp1
);
11820 gen_store_fpr64(ctx
, fp0
, fd
);
11821 tcg_temp_free_i64(fp0
);
11825 check_cp1_registers(ctx
, fs
| ft
| fd
);
11827 TCGv_i64 fp0
= tcg_temp_new_i64();
11828 TCGv_i64 fp1
= tcg_temp_new_i64();
11830 gen_load_fpr64(ctx
, fp0
, fs
);
11831 gen_load_fpr64(ctx
, fp1
, ft
);
11832 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
11833 tcg_temp_free_i64(fp1
);
11834 gen_store_fpr64(ctx
, fp0
, fd
);
11835 tcg_temp_free_i64(fp0
);
11839 check_cp1_registers(ctx
, fs
| fd
);
11841 TCGv_i64 fp0
= tcg_temp_new_i64();
11843 gen_load_fpr64(ctx
, fp0
, fs
);
11844 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
11845 gen_store_fpr64(ctx
, fp0
, fd
);
11846 tcg_temp_free_i64(fp0
);
11850 check_cp1_registers(ctx
, fs
| fd
);
11852 TCGv_i64 fp0
= tcg_temp_new_i64();
11854 gen_load_fpr64(ctx
, fp0
, fs
);
11855 if (ctx
->abs2008
) {
11856 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
11858 gen_helper_float_abs_d(fp0
, fp0
);
11860 gen_store_fpr64(ctx
, fp0
, fd
);
11861 tcg_temp_free_i64(fp0
);
11865 check_cp1_registers(ctx
, fs
| fd
);
11867 TCGv_i64 fp0
= tcg_temp_new_i64();
11869 gen_load_fpr64(ctx
, fp0
, fs
);
11870 gen_store_fpr64(ctx
, fp0
, fd
);
11871 tcg_temp_free_i64(fp0
);
11875 check_cp1_registers(ctx
, fs
| fd
);
11877 TCGv_i64 fp0
= tcg_temp_new_i64();
11879 gen_load_fpr64(ctx
, fp0
, fs
);
11880 if (ctx
->abs2008
) {
11881 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
11883 gen_helper_float_chs_d(fp0
, fp0
);
11885 gen_store_fpr64(ctx
, fp0
, fd
);
11886 tcg_temp_free_i64(fp0
);
11889 case OPC_ROUND_L_D
:
11890 check_cp1_64bitmode(ctx
);
11892 TCGv_i64 fp0
= tcg_temp_new_i64();
11894 gen_load_fpr64(ctx
, fp0
, fs
);
11895 if (ctx
->nan2008
) {
11896 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
11898 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
11900 gen_store_fpr64(ctx
, fp0
, fd
);
11901 tcg_temp_free_i64(fp0
);
11904 case OPC_TRUNC_L_D
:
11905 check_cp1_64bitmode(ctx
);
11907 TCGv_i64 fp0
= tcg_temp_new_i64();
11909 gen_load_fpr64(ctx
, fp0
, fs
);
11910 if (ctx
->nan2008
) {
11911 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
11913 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
11915 gen_store_fpr64(ctx
, fp0
, fd
);
11916 tcg_temp_free_i64(fp0
);
11920 check_cp1_64bitmode(ctx
);
11922 TCGv_i64 fp0
= tcg_temp_new_i64();
11924 gen_load_fpr64(ctx
, fp0
, fs
);
11925 if (ctx
->nan2008
) {
11926 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
11928 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
11930 gen_store_fpr64(ctx
, fp0
, fd
);
11931 tcg_temp_free_i64(fp0
);
11934 case OPC_FLOOR_L_D
:
11935 check_cp1_64bitmode(ctx
);
11937 TCGv_i64 fp0
= tcg_temp_new_i64();
11939 gen_load_fpr64(ctx
, fp0
, fs
);
11940 if (ctx
->nan2008
) {
11941 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
11943 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
11945 gen_store_fpr64(ctx
, fp0
, fd
);
11946 tcg_temp_free_i64(fp0
);
11949 case OPC_ROUND_W_D
:
11950 check_cp1_registers(ctx
, fs
);
11952 TCGv_i32 fp32
= tcg_temp_new_i32();
11953 TCGv_i64 fp64
= tcg_temp_new_i64();
11955 gen_load_fpr64(ctx
, fp64
, fs
);
11956 if (ctx
->nan2008
) {
11957 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
11959 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
11961 tcg_temp_free_i64(fp64
);
11962 gen_store_fpr32(ctx
, fp32
, fd
);
11963 tcg_temp_free_i32(fp32
);
11966 case OPC_TRUNC_W_D
:
11967 check_cp1_registers(ctx
, fs
);
11969 TCGv_i32 fp32
= tcg_temp_new_i32();
11970 TCGv_i64 fp64
= tcg_temp_new_i64();
11972 gen_load_fpr64(ctx
, fp64
, fs
);
11973 if (ctx
->nan2008
) {
11974 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
11976 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
11978 tcg_temp_free_i64(fp64
);
11979 gen_store_fpr32(ctx
, fp32
, fd
);
11980 tcg_temp_free_i32(fp32
);
11984 check_cp1_registers(ctx
, fs
);
11986 TCGv_i32 fp32
= tcg_temp_new_i32();
11987 TCGv_i64 fp64
= tcg_temp_new_i64();
11989 gen_load_fpr64(ctx
, fp64
, fs
);
11990 if (ctx
->nan2008
) {
11991 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
11993 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
11995 tcg_temp_free_i64(fp64
);
11996 gen_store_fpr32(ctx
, fp32
, fd
);
11997 tcg_temp_free_i32(fp32
);
12000 case OPC_FLOOR_W_D
:
12001 check_cp1_registers(ctx
, fs
);
12003 TCGv_i32 fp32
= tcg_temp_new_i32();
12004 TCGv_i64 fp64
= tcg_temp_new_i64();
12006 gen_load_fpr64(ctx
, fp64
, fs
);
12007 if (ctx
->nan2008
) {
12008 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
12010 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
12012 tcg_temp_free_i64(fp64
);
12013 gen_store_fpr32(ctx
, fp32
, fd
);
12014 tcg_temp_free_i32(fp32
);
12018 check_insn(ctx
, ISA_MIPS32R6
);
12019 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12022 check_insn(ctx
, ISA_MIPS32R6
);
12023 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12026 check_insn(ctx
, ISA_MIPS32R6
);
12027 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12030 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12031 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12034 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12036 TCGLabel
*l1
= gen_new_label();
12040 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12042 fp0
= tcg_temp_new_i64();
12043 gen_load_fpr64(ctx
, fp0
, fs
);
12044 gen_store_fpr64(ctx
, fp0
, fd
);
12045 tcg_temp_free_i64(fp0
);
12050 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12052 TCGLabel
*l1
= gen_new_label();
12056 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12057 fp0
= tcg_temp_new_i64();
12058 gen_load_fpr64(ctx
, fp0
, fs
);
12059 gen_store_fpr64(ctx
, fp0
, fd
);
12060 tcg_temp_free_i64(fp0
);
12066 check_cp1_registers(ctx
, fs
| fd
);
12068 TCGv_i64 fp0
= tcg_temp_new_i64();
12070 gen_load_fpr64(ctx
, fp0
, fs
);
12071 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
12072 gen_store_fpr64(ctx
, fp0
, fd
);
12073 tcg_temp_free_i64(fp0
);
12077 check_cp1_registers(ctx
, fs
| fd
);
12079 TCGv_i64 fp0
= tcg_temp_new_i64();
12081 gen_load_fpr64(ctx
, fp0
, fs
);
12082 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
12083 gen_store_fpr64(ctx
, fp0
, fd
);
12084 tcg_temp_free_i64(fp0
);
12088 check_insn(ctx
, ISA_MIPS32R6
);
12090 TCGv_i64 fp0
= tcg_temp_new_i64();
12091 TCGv_i64 fp1
= tcg_temp_new_i64();
12092 TCGv_i64 fp2
= tcg_temp_new_i64();
12093 gen_load_fpr64(ctx
, fp0
, fs
);
12094 gen_load_fpr64(ctx
, fp1
, ft
);
12095 gen_load_fpr64(ctx
, fp2
, fd
);
12096 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12097 gen_store_fpr64(ctx
, fp2
, fd
);
12098 tcg_temp_free_i64(fp2
);
12099 tcg_temp_free_i64(fp1
);
12100 tcg_temp_free_i64(fp0
);
12104 check_insn(ctx
, ISA_MIPS32R6
);
12106 TCGv_i64 fp0
= tcg_temp_new_i64();
12107 TCGv_i64 fp1
= tcg_temp_new_i64();
12108 TCGv_i64 fp2
= tcg_temp_new_i64();
12109 gen_load_fpr64(ctx
, fp0
, fs
);
12110 gen_load_fpr64(ctx
, fp1
, ft
);
12111 gen_load_fpr64(ctx
, fp2
, fd
);
12112 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12113 gen_store_fpr64(ctx
, fp2
, fd
);
12114 tcg_temp_free_i64(fp2
);
12115 tcg_temp_free_i64(fp1
);
12116 tcg_temp_free_i64(fp0
);
12120 check_insn(ctx
, ISA_MIPS32R6
);
12122 TCGv_i64 fp0
= tcg_temp_new_i64();
12123 gen_load_fpr64(ctx
, fp0
, fs
);
12124 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
12125 gen_store_fpr64(ctx
, fp0
, fd
);
12126 tcg_temp_free_i64(fp0
);
12130 check_insn(ctx
, ISA_MIPS32R6
);
12132 TCGv_i64 fp0
= tcg_temp_new_i64();
12133 gen_load_fpr64(ctx
, fp0
, fs
);
12134 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
12135 gen_store_fpr64(ctx
, fp0
, fd
);
12136 tcg_temp_free_i64(fp0
);
12139 case OPC_MIN_D
: /* OPC_RECIP2_D */
12140 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12142 TCGv_i64 fp0
= tcg_temp_new_i64();
12143 TCGv_i64 fp1
= tcg_temp_new_i64();
12144 gen_load_fpr64(ctx
, fp0
, fs
);
12145 gen_load_fpr64(ctx
, fp1
, ft
);
12146 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
12147 gen_store_fpr64(ctx
, fp1
, fd
);
12148 tcg_temp_free_i64(fp1
);
12149 tcg_temp_free_i64(fp0
);
12152 check_cp1_64bitmode(ctx
);
12154 TCGv_i64 fp0
= tcg_temp_new_i64();
12155 TCGv_i64 fp1
= tcg_temp_new_i64();
12157 gen_load_fpr64(ctx
, fp0
, fs
);
12158 gen_load_fpr64(ctx
, fp1
, ft
);
12159 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
12160 tcg_temp_free_i64(fp1
);
12161 gen_store_fpr64(ctx
, fp0
, fd
);
12162 tcg_temp_free_i64(fp0
);
12166 case OPC_MINA_D
: /* OPC_RECIP1_D */
12167 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12169 TCGv_i64 fp0
= tcg_temp_new_i64();
12170 TCGv_i64 fp1
= tcg_temp_new_i64();
12171 gen_load_fpr64(ctx
, fp0
, fs
);
12172 gen_load_fpr64(ctx
, fp1
, ft
);
12173 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
12174 gen_store_fpr64(ctx
, fp1
, fd
);
12175 tcg_temp_free_i64(fp1
);
12176 tcg_temp_free_i64(fp0
);
12179 check_cp1_64bitmode(ctx
);
12181 TCGv_i64 fp0
= tcg_temp_new_i64();
12183 gen_load_fpr64(ctx
, fp0
, fs
);
12184 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12185 gen_store_fpr64(ctx
, fp0
, fd
);
12186 tcg_temp_free_i64(fp0
);
12190 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12191 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12193 TCGv_i64 fp0
= tcg_temp_new_i64();
12194 TCGv_i64 fp1
= tcg_temp_new_i64();
12195 gen_load_fpr64(ctx
, fp0
, fs
);
12196 gen_load_fpr64(ctx
, fp1
, ft
);
12197 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12198 gen_store_fpr64(ctx
, fp1
, fd
);
12199 tcg_temp_free_i64(fp1
);
12200 tcg_temp_free_i64(fp0
);
12203 check_cp1_64bitmode(ctx
);
12205 TCGv_i64 fp0
= tcg_temp_new_i64();
12207 gen_load_fpr64(ctx
, fp0
, fs
);
12208 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12209 gen_store_fpr64(ctx
, fp0
, fd
);
12210 tcg_temp_free_i64(fp0
);
12214 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12215 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12217 TCGv_i64 fp0
= tcg_temp_new_i64();
12218 TCGv_i64 fp1
= tcg_temp_new_i64();
12219 gen_load_fpr64(ctx
, fp0
, fs
);
12220 gen_load_fpr64(ctx
, fp1
, ft
);
12221 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12222 gen_store_fpr64(ctx
, fp1
, fd
);
12223 tcg_temp_free_i64(fp1
);
12224 tcg_temp_free_i64(fp0
);
12227 check_cp1_64bitmode(ctx
);
12229 TCGv_i64 fp0
= tcg_temp_new_i64();
12230 TCGv_i64 fp1
= tcg_temp_new_i64();
12232 gen_load_fpr64(ctx
, fp0
, fs
);
12233 gen_load_fpr64(ctx
, fp1
, ft
);
12234 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12235 tcg_temp_free_i64(fp1
);
12236 gen_store_fpr64(ctx
, fp0
, fd
);
12237 tcg_temp_free_i64(fp0
);
12244 case OPC_CMP_UEQ_D
:
12245 case OPC_CMP_OLT_D
:
12246 case OPC_CMP_ULT_D
:
12247 case OPC_CMP_OLE_D
:
12248 case OPC_CMP_ULE_D
:
12250 case OPC_CMP_NGLE_D
:
12251 case OPC_CMP_SEQ_D
:
12252 case OPC_CMP_NGL_D
:
12254 case OPC_CMP_NGE_D
:
12256 case OPC_CMP_NGT_D
:
12257 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12258 if (ctx
->opcode
& (1 << 6)) {
12259 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12261 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12265 check_cp1_registers(ctx
, fs
);
12267 TCGv_i32 fp32
= tcg_temp_new_i32();
12268 TCGv_i64 fp64
= tcg_temp_new_i64();
12270 gen_load_fpr64(ctx
, fp64
, fs
);
12271 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12272 tcg_temp_free_i64(fp64
);
12273 gen_store_fpr32(ctx
, fp32
, fd
);
12274 tcg_temp_free_i32(fp32
);
12278 check_cp1_registers(ctx
, fs
);
12280 TCGv_i32 fp32
= tcg_temp_new_i32();
12281 TCGv_i64 fp64
= tcg_temp_new_i64();
12283 gen_load_fpr64(ctx
, fp64
, fs
);
12284 if (ctx
->nan2008
) {
12285 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12287 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12289 tcg_temp_free_i64(fp64
);
12290 gen_store_fpr32(ctx
, fp32
, fd
);
12291 tcg_temp_free_i32(fp32
);
12295 check_cp1_64bitmode(ctx
);
12297 TCGv_i64 fp0
= tcg_temp_new_i64();
12299 gen_load_fpr64(ctx
, fp0
, fs
);
12300 if (ctx
->nan2008
) {
12301 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12303 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12305 gen_store_fpr64(ctx
, fp0
, fd
);
12306 tcg_temp_free_i64(fp0
);
12311 TCGv_i32 fp0
= tcg_temp_new_i32();
12313 gen_load_fpr32(ctx
, fp0
, fs
);
12314 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12315 gen_store_fpr32(ctx
, fp0
, fd
);
12316 tcg_temp_free_i32(fp0
);
12320 check_cp1_registers(ctx
, fd
);
12322 TCGv_i32 fp32
= tcg_temp_new_i32();
12323 TCGv_i64 fp64
= tcg_temp_new_i64();
12325 gen_load_fpr32(ctx
, fp32
, fs
);
12326 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12327 tcg_temp_free_i32(fp32
);
12328 gen_store_fpr64(ctx
, fp64
, fd
);
12329 tcg_temp_free_i64(fp64
);
12333 check_cp1_64bitmode(ctx
);
12335 TCGv_i32 fp32
= tcg_temp_new_i32();
12336 TCGv_i64 fp64
= tcg_temp_new_i64();
12338 gen_load_fpr64(ctx
, fp64
, fs
);
12339 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12340 tcg_temp_free_i64(fp64
);
12341 gen_store_fpr32(ctx
, fp32
, fd
);
12342 tcg_temp_free_i32(fp32
);
12346 check_cp1_64bitmode(ctx
);
12348 TCGv_i64 fp0
= tcg_temp_new_i64();
12350 gen_load_fpr64(ctx
, fp0
, fs
);
12351 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12352 gen_store_fpr64(ctx
, fp0
, fd
);
12353 tcg_temp_free_i64(fp0
);
12356 case OPC_CVT_PS_PW
:
12359 TCGv_i64 fp0
= tcg_temp_new_i64();
12361 gen_load_fpr64(ctx
, fp0
, fs
);
12362 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12363 gen_store_fpr64(ctx
, fp0
, fd
);
12364 tcg_temp_free_i64(fp0
);
12370 TCGv_i64 fp0
= tcg_temp_new_i64();
12371 TCGv_i64 fp1
= tcg_temp_new_i64();
12373 gen_load_fpr64(ctx
, fp0
, fs
);
12374 gen_load_fpr64(ctx
, fp1
, ft
);
12375 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12376 tcg_temp_free_i64(fp1
);
12377 gen_store_fpr64(ctx
, fp0
, fd
);
12378 tcg_temp_free_i64(fp0
);
12384 TCGv_i64 fp0
= tcg_temp_new_i64();
12385 TCGv_i64 fp1
= tcg_temp_new_i64();
12387 gen_load_fpr64(ctx
, fp0
, fs
);
12388 gen_load_fpr64(ctx
, fp1
, ft
);
12389 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12390 tcg_temp_free_i64(fp1
);
12391 gen_store_fpr64(ctx
, fp0
, fd
);
12392 tcg_temp_free_i64(fp0
);
12398 TCGv_i64 fp0
= tcg_temp_new_i64();
12399 TCGv_i64 fp1
= tcg_temp_new_i64();
12401 gen_load_fpr64(ctx
, fp0
, fs
);
12402 gen_load_fpr64(ctx
, fp1
, ft
);
12403 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12404 tcg_temp_free_i64(fp1
);
12405 gen_store_fpr64(ctx
, fp0
, fd
);
12406 tcg_temp_free_i64(fp0
);
12412 TCGv_i64 fp0
= tcg_temp_new_i64();
12414 gen_load_fpr64(ctx
, fp0
, fs
);
12415 gen_helper_float_abs_ps(fp0
, fp0
);
12416 gen_store_fpr64(ctx
, fp0
, fd
);
12417 tcg_temp_free_i64(fp0
);
12423 TCGv_i64 fp0
= tcg_temp_new_i64();
12425 gen_load_fpr64(ctx
, fp0
, fs
);
12426 gen_store_fpr64(ctx
, fp0
, fd
);
12427 tcg_temp_free_i64(fp0
);
12433 TCGv_i64 fp0
= tcg_temp_new_i64();
12435 gen_load_fpr64(ctx
, fp0
, fs
);
12436 gen_helper_float_chs_ps(fp0
, fp0
);
12437 gen_store_fpr64(ctx
, fp0
, fd
);
12438 tcg_temp_free_i64(fp0
);
12443 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12448 TCGLabel
*l1
= gen_new_label();
12452 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12454 fp0
= tcg_temp_new_i64();
12455 gen_load_fpr64(ctx
, fp0
, fs
);
12456 gen_store_fpr64(ctx
, fp0
, fd
);
12457 tcg_temp_free_i64(fp0
);
12464 TCGLabel
*l1
= gen_new_label();
12468 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12469 fp0
= tcg_temp_new_i64();
12470 gen_load_fpr64(ctx
, fp0
, fs
);
12471 gen_store_fpr64(ctx
, fp0
, fd
);
12472 tcg_temp_free_i64(fp0
);
12480 TCGv_i64 fp0
= tcg_temp_new_i64();
12481 TCGv_i64 fp1
= tcg_temp_new_i64();
12483 gen_load_fpr64(ctx
, fp0
, ft
);
12484 gen_load_fpr64(ctx
, fp1
, fs
);
12485 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12486 tcg_temp_free_i64(fp1
);
12487 gen_store_fpr64(ctx
, fp0
, fd
);
12488 tcg_temp_free_i64(fp0
);
12494 TCGv_i64 fp0
= tcg_temp_new_i64();
12495 TCGv_i64 fp1
= tcg_temp_new_i64();
12497 gen_load_fpr64(ctx
, fp0
, ft
);
12498 gen_load_fpr64(ctx
, fp1
, fs
);
12499 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12500 tcg_temp_free_i64(fp1
);
12501 gen_store_fpr64(ctx
, fp0
, fd
);
12502 tcg_temp_free_i64(fp0
);
12505 case OPC_RECIP2_PS
:
12508 TCGv_i64 fp0
= tcg_temp_new_i64();
12509 TCGv_i64 fp1
= tcg_temp_new_i64();
12511 gen_load_fpr64(ctx
, fp0
, fs
);
12512 gen_load_fpr64(ctx
, fp1
, ft
);
12513 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12514 tcg_temp_free_i64(fp1
);
12515 gen_store_fpr64(ctx
, fp0
, fd
);
12516 tcg_temp_free_i64(fp0
);
12519 case OPC_RECIP1_PS
:
12522 TCGv_i64 fp0
= tcg_temp_new_i64();
12524 gen_load_fpr64(ctx
, fp0
, fs
);
12525 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12526 gen_store_fpr64(ctx
, fp0
, fd
);
12527 tcg_temp_free_i64(fp0
);
12530 case OPC_RSQRT1_PS
:
12533 TCGv_i64 fp0
= tcg_temp_new_i64();
12535 gen_load_fpr64(ctx
, fp0
, fs
);
12536 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12537 gen_store_fpr64(ctx
, fp0
, fd
);
12538 tcg_temp_free_i64(fp0
);
12541 case OPC_RSQRT2_PS
:
12544 TCGv_i64 fp0
= tcg_temp_new_i64();
12545 TCGv_i64 fp1
= tcg_temp_new_i64();
12547 gen_load_fpr64(ctx
, fp0
, fs
);
12548 gen_load_fpr64(ctx
, fp1
, ft
);
12549 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12550 tcg_temp_free_i64(fp1
);
12551 gen_store_fpr64(ctx
, fp0
, fd
);
12552 tcg_temp_free_i64(fp0
);
12556 check_cp1_64bitmode(ctx
);
12558 TCGv_i32 fp0
= tcg_temp_new_i32();
12560 gen_load_fpr32h(ctx
, fp0
, fs
);
12561 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12562 gen_store_fpr32(ctx
, fp0
, fd
);
12563 tcg_temp_free_i32(fp0
);
12566 case OPC_CVT_PW_PS
:
12569 TCGv_i64 fp0
= tcg_temp_new_i64();
12571 gen_load_fpr64(ctx
, fp0
, fs
);
12572 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
12573 gen_store_fpr64(ctx
, fp0
, fd
);
12574 tcg_temp_free_i64(fp0
);
12578 check_cp1_64bitmode(ctx
);
12580 TCGv_i32 fp0
= tcg_temp_new_i32();
12582 gen_load_fpr32(ctx
, fp0
, fs
);
12583 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
12584 gen_store_fpr32(ctx
, fp0
, fd
);
12585 tcg_temp_free_i32(fp0
);
12591 TCGv_i32 fp0
= tcg_temp_new_i32();
12592 TCGv_i32 fp1
= tcg_temp_new_i32();
12594 gen_load_fpr32(ctx
, fp0
, fs
);
12595 gen_load_fpr32(ctx
, fp1
, ft
);
12596 gen_store_fpr32h(ctx
, fp0
, fd
);
12597 gen_store_fpr32(ctx
, fp1
, fd
);
12598 tcg_temp_free_i32(fp0
);
12599 tcg_temp_free_i32(fp1
);
12605 TCGv_i32 fp0
= tcg_temp_new_i32();
12606 TCGv_i32 fp1
= tcg_temp_new_i32();
12608 gen_load_fpr32(ctx
, fp0
, fs
);
12609 gen_load_fpr32h(ctx
, fp1
, ft
);
12610 gen_store_fpr32(ctx
, fp1
, fd
);
12611 gen_store_fpr32h(ctx
, fp0
, fd
);
12612 tcg_temp_free_i32(fp0
);
12613 tcg_temp_free_i32(fp1
);
12619 TCGv_i32 fp0
= tcg_temp_new_i32();
12620 TCGv_i32 fp1
= tcg_temp_new_i32();
12622 gen_load_fpr32h(ctx
, fp0
, fs
);
12623 gen_load_fpr32(ctx
, fp1
, ft
);
12624 gen_store_fpr32(ctx
, fp1
, fd
);
12625 gen_store_fpr32h(ctx
, fp0
, fd
);
12626 tcg_temp_free_i32(fp0
);
12627 tcg_temp_free_i32(fp1
);
12633 TCGv_i32 fp0
= tcg_temp_new_i32();
12634 TCGv_i32 fp1
= tcg_temp_new_i32();
12636 gen_load_fpr32h(ctx
, fp0
, fs
);
12637 gen_load_fpr32h(ctx
, fp1
, ft
);
12638 gen_store_fpr32(ctx
, fp1
, fd
);
12639 gen_store_fpr32h(ctx
, fp0
, fd
);
12640 tcg_temp_free_i32(fp0
);
12641 tcg_temp_free_i32(fp1
);
12645 case OPC_CMP_UN_PS
:
12646 case OPC_CMP_EQ_PS
:
12647 case OPC_CMP_UEQ_PS
:
12648 case OPC_CMP_OLT_PS
:
12649 case OPC_CMP_ULT_PS
:
12650 case OPC_CMP_OLE_PS
:
12651 case OPC_CMP_ULE_PS
:
12652 case OPC_CMP_SF_PS
:
12653 case OPC_CMP_NGLE_PS
:
12654 case OPC_CMP_SEQ_PS
:
12655 case OPC_CMP_NGL_PS
:
12656 case OPC_CMP_LT_PS
:
12657 case OPC_CMP_NGE_PS
:
12658 case OPC_CMP_LE_PS
:
12659 case OPC_CMP_NGT_PS
:
12660 if (ctx
->opcode
& (1 << 6)) {
12661 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
12663 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
12667 MIPS_INVAL("farith");
12668 generate_exception_end(ctx
, EXCP_RI
);
12673 /* Coprocessor 3 (FPU) */
12674 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
12675 int fd
, int fs
, int base
, int index
)
12677 TCGv t0
= tcg_temp_new();
12680 gen_load_gpr(t0
, index
);
12681 } else if (index
== 0) {
12682 gen_load_gpr(t0
, base
);
12684 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
12687 * Don't do NOP if destination is zero: we must perform the actual
12694 TCGv_i32 fp0
= tcg_temp_new_i32();
12696 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12697 tcg_gen_trunc_tl_i32(fp0
, t0
);
12698 gen_store_fpr32(ctx
, fp0
, fd
);
12699 tcg_temp_free_i32(fp0
);
12704 check_cp1_registers(ctx
, fd
);
12706 TCGv_i64 fp0
= tcg_temp_new_i64();
12707 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12708 gen_store_fpr64(ctx
, fp0
, fd
);
12709 tcg_temp_free_i64(fp0
);
12713 check_cp1_64bitmode(ctx
);
12714 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12716 TCGv_i64 fp0
= tcg_temp_new_i64();
12718 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12719 gen_store_fpr64(ctx
, fp0
, fd
);
12720 tcg_temp_free_i64(fp0
);
12726 TCGv_i32 fp0
= tcg_temp_new_i32();
12727 gen_load_fpr32(ctx
, fp0
, fs
);
12728 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
12729 tcg_temp_free_i32(fp0
);
12734 check_cp1_registers(ctx
, fs
);
12736 TCGv_i64 fp0
= tcg_temp_new_i64();
12737 gen_load_fpr64(ctx
, fp0
, fs
);
12738 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12739 tcg_temp_free_i64(fp0
);
12743 check_cp1_64bitmode(ctx
);
12744 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12746 TCGv_i64 fp0
= tcg_temp_new_i64();
12747 gen_load_fpr64(ctx
, fp0
, fs
);
12748 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12749 tcg_temp_free_i64(fp0
);
12756 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
12757 int fd
, int fr
, int fs
, int ft
)
12763 TCGv t0
= tcg_temp_local_new();
12764 TCGv_i32 fp
= tcg_temp_new_i32();
12765 TCGv_i32 fph
= tcg_temp_new_i32();
12766 TCGLabel
*l1
= gen_new_label();
12767 TCGLabel
*l2
= gen_new_label();
12769 gen_load_gpr(t0
, fr
);
12770 tcg_gen_andi_tl(t0
, t0
, 0x7);
12772 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
12773 gen_load_fpr32(ctx
, fp
, fs
);
12774 gen_load_fpr32h(ctx
, fph
, fs
);
12775 gen_store_fpr32(ctx
, fp
, fd
);
12776 gen_store_fpr32h(ctx
, fph
, fd
);
12779 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
12781 #ifdef TARGET_WORDS_BIGENDIAN
12782 gen_load_fpr32(ctx
, fp
, fs
);
12783 gen_load_fpr32h(ctx
, fph
, ft
);
12784 gen_store_fpr32h(ctx
, fp
, fd
);
12785 gen_store_fpr32(ctx
, fph
, fd
);
12787 gen_load_fpr32h(ctx
, fph
, fs
);
12788 gen_load_fpr32(ctx
, fp
, ft
);
12789 gen_store_fpr32(ctx
, fph
, fd
);
12790 gen_store_fpr32h(ctx
, fp
, fd
);
12793 tcg_temp_free_i32(fp
);
12794 tcg_temp_free_i32(fph
);
12800 TCGv_i32 fp0
= tcg_temp_new_i32();
12801 TCGv_i32 fp1
= tcg_temp_new_i32();
12802 TCGv_i32 fp2
= tcg_temp_new_i32();
12804 gen_load_fpr32(ctx
, fp0
, fs
);
12805 gen_load_fpr32(ctx
, fp1
, ft
);
12806 gen_load_fpr32(ctx
, fp2
, fr
);
12807 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12808 tcg_temp_free_i32(fp0
);
12809 tcg_temp_free_i32(fp1
);
12810 gen_store_fpr32(ctx
, fp2
, fd
);
12811 tcg_temp_free_i32(fp2
);
12816 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12818 TCGv_i64 fp0
= tcg_temp_new_i64();
12819 TCGv_i64 fp1
= tcg_temp_new_i64();
12820 TCGv_i64 fp2
= tcg_temp_new_i64();
12822 gen_load_fpr64(ctx
, fp0
, fs
);
12823 gen_load_fpr64(ctx
, fp1
, ft
);
12824 gen_load_fpr64(ctx
, fp2
, fr
);
12825 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12826 tcg_temp_free_i64(fp0
);
12827 tcg_temp_free_i64(fp1
);
12828 gen_store_fpr64(ctx
, fp2
, fd
);
12829 tcg_temp_free_i64(fp2
);
12835 TCGv_i64 fp0
= tcg_temp_new_i64();
12836 TCGv_i64 fp1
= tcg_temp_new_i64();
12837 TCGv_i64 fp2
= tcg_temp_new_i64();
12839 gen_load_fpr64(ctx
, fp0
, fs
);
12840 gen_load_fpr64(ctx
, fp1
, ft
);
12841 gen_load_fpr64(ctx
, fp2
, fr
);
12842 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12843 tcg_temp_free_i64(fp0
);
12844 tcg_temp_free_i64(fp1
);
12845 gen_store_fpr64(ctx
, fp2
, fd
);
12846 tcg_temp_free_i64(fp2
);
12852 TCGv_i32 fp0
= tcg_temp_new_i32();
12853 TCGv_i32 fp1
= tcg_temp_new_i32();
12854 TCGv_i32 fp2
= tcg_temp_new_i32();
12856 gen_load_fpr32(ctx
, fp0
, fs
);
12857 gen_load_fpr32(ctx
, fp1
, ft
);
12858 gen_load_fpr32(ctx
, fp2
, fr
);
12859 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12860 tcg_temp_free_i32(fp0
);
12861 tcg_temp_free_i32(fp1
);
12862 gen_store_fpr32(ctx
, fp2
, fd
);
12863 tcg_temp_free_i32(fp2
);
12868 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12870 TCGv_i64 fp0
= tcg_temp_new_i64();
12871 TCGv_i64 fp1
= tcg_temp_new_i64();
12872 TCGv_i64 fp2
= tcg_temp_new_i64();
12874 gen_load_fpr64(ctx
, fp0
, fs
);
12875 gen_load_fpr64(ctx
, fp1
, ft
);
12876 gen_load_fpr64(ctx
, fp2
, fr
);
12877 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12878 tcg_temp_free_i64(fp0
);
12879 tcg_temp_free_i64(fp1
);
12880 gen_store_fpr64(ctx
, fp2
, fd
);
12881 tcg_temp_free_i64(fp2
);
12887 TCGv_i64 fp0
= tcg_temp_new_i64();
12888 TCGv_i64 fp1
= tcg_temp_new_i64();
12889 TCGv_i64 fp2
= tcg_temp_new_i64();
12891 gen_load_fpr64(ctx
, fp0
, fs
);
12892 gen_load_fpr64(ctx
, fp1
, ft
);
12893 gen_load_fpr64(ctx
, fp2
, fr
);
12894 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12895 tcg_temp_free_i64(fp0
);
12896 tcg_temp_free_i64(fp1
);
12897 gen_store_fpr64(ctx
, fp2
, fd
);
12898 tcg_temp_free_i64(fp2
);
12904 TCGv_i32 fp0
= tcg_temp_new_i32();
12905 TCGv_i32 fp1
= tcg_temp_new_i32();
12906 TCGv_i32 fp2
= tcg_temp_new_i32();
12908 gen_load_fpr32(ctx
, fp0
, fs
);
12909 gen_load_fpr32(ctx
, fp1
, ft
);
12910 gen_load_fpr32(ctx
, fp2
, fr
);
12911 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12912 tcg_temp_free_i32(fp0
);
12913 tcg_temp_free_i32(fp1
);
12914 gen_store_fpr32(ctx
, fp2
, fd
);
12915 tcg_temp_free_i32(fp2
);
12920 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12922 TCGv_i64 fp0
= tcg_temp_new_i64();
12923 TCGv_i64 fp1
= tcg_temp_new_i64();
12924 TCGv_i64 fp2
= tcg_temp_new_i64();
12926 gen_load_fpr64(ctx
, fp0
, fs
);
12927 gen_load_fpr64(ctx
, fp1
, ft
);
12928 gen_load_fpr64(ctx
, fp2
, fr
);
12929 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12930 tcg_temp_free_i64(fp0
);
12931 tcg_temp_free_i64(fp1
);
12932 gen_store_fpr64(ctx
, fp2
, fd
);
12933 tcg_temp_free_i64(fp2
);
12939 TCGv_i64 fp0
= tcg_temp_new_i64();
12940 TCGv_i64 fp1
= tcg_temp_new_i64();
12941 TCGv_i64 fp2
= tcg_temp_new_i64();
12943 gen_load_fpr64(ctx
, fp0
, fs
);
12944 gen_load_fpr64(ctx
, fp1
, ft
);
12945 gen_load_fpr64(ctx
, fp2
, fr
);
12946 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12947 tcg_temp_free_i64(fp0
);
12948 tcg_temp_free_i64(fp1
);
12949 gen_store_fpr64(ctx
, fp2
, fd
);
12950 tcg_temp_free_i64(fp2
);
12956 TCGv_i32 fp0
= tcg_temp_new_i32();
12957 TCGv_i32 fp1
= tcg_temp_new_i32();
12958 TCGv_i32 fp2
= tcg_temp_new_i32();
12960 gen_load_fpr32(ctx
, fp0
, fs
);
12961 gen_load_fpr32(ctx
, fp1
, ft
);
12962 gen_load_fpr32(ctx
, fp2
, fr
);
12963 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12964 tcg_temp_free_i32(fp0
);
12965 tcg_temp_free_i32(fp1
);
12966 gen_store_fpr32(ctx
, fp2
, fd
);
12967 tcg_temp_free_i32(fp2
);
12972 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12974 TCGv_i64 fp0
= tcg_temp_new_i64();
12975 TCGv_i64 fp1
= tcg_temp_new_i64();
12976 TCGv_i64 fp2
= tcg_temp_new_i64();
12978 gen_load_fpr64(ctx
, fp0
, fs
);
12979 gen_load_fpr64(ctx
, fp1
, ft
);
12980 gen_load_fpr64(ctx
, fp2
, fr
);
12981 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12982 tcg_temp_free_i64(fp0
);
12983 tcg_temp_free_i64(fp1
);
12984 gen_store_fpr64(ctx
, fp2
, fd
);
12985 tcg_temp_free_i64(fp2
);
12991 TCGv_i64 fp0
= tcg_temp_new_i64();
12992 TCGv_i64 fp1
= tcg_temp_new_i64();
12993 TCGv_i64 fp2
= tcg_temp_new_i64();
12995 gen_load_fpr64(ctx
, fp0
, fs
);
12996 gen_load_fpr64(ctx
, fp1
, ft
);
12997 gen_load_fpr64(ctx
, fp2
, fr
);
12998 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12999 tcg_temp_free_i64(fp0
);
13000 tcg_temp_free_i64(fp1
);
13001 gen_store_fpr64(ctx
, fp2
, fd
);
13002 tcg_temp_free_i64(fp2
);
13006 MIPS_INVAL("flt3_arith");
13007 generate_exception_end(ctx
, EXCP_RI
);
13012 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
13016 #if !defined(CONFIG_USER_ONLY)
13018 * The Linux kernel will emulate rdhwr if it's not supported natively.
13019 * Therefore only check the ISA in system mode.
13021 check_insn(ctx
, ISA_MIPS32R2
);
13023 t0
= tcg_temp_new();
13027 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
13028 gen_store_gpr(t0
, rt
);
13031 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
13032 gen_store_gpr(t0
, rt
);
13035 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
13038 gen_helper_rdhwr_cc(t0
, cpu_env
);
13039 gen_store_gpr(t0
, rt
);
13041 * Break the TB to be able to take timer interrupts immediately
13042 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13043 * we break completely out of translated code.
13045 gen_save_pc(ctx
->base
.pc_next
+ 4);
13046 ctx
->base
.is_jmp
= DISAS_EXIT
;
13049 gen_helper_rdhwr_ccres(t0
, cpu_env
);
13050 gen_store_gpr(t0
, rt
);
13053 check_insn(ctx
, ISA_MIPS32R6
);
13056 * Performance counter registers are not implemented other than
13057 * control register 0.
13059 generate_exception(ctx
, EXCP_RI
);
13061 gen_helper_rdhwr_performance(t0
, cpu_env
);
13062 gen_store_gpr(t0
, rt
);
13065 check_insn(ctx
, ISA_MIPS32R6
);
13066 gen_helper_rdhwr_xnp(t0
, cpu_env
);
13067 gen_store_gpr(t0
, rt
);
13070 #if defined(CONFIG_USER_ONLY)
13071 tcg_gen_ld_tl(t0
, cpu_env
,
13072 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13073 gen_store_gpr(t0
, rt
);
13076 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
13077 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
13078 tcg_gen_ld_tl(t0
, cpu_env
,
13079 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13080 gen_store_gpr(t0
, rt
);
13082 generate_exception_end(ctx
, EXCP_RI
);
13086 default: /* Invalid */
13087 MIPS_INVAL("rdhwr");
13088 generate_exception_end(ctx
, EXCP_RI
);
13094 static inline void clear_branch_hflags(DisasContext
*ctx
)
13096 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
13097 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
13098 save_cpu_state(ctx
, 0);
13101 * It is not safe to save ctx->hflags as hflags may be changed
13102 * in execution time by the instruction in delay / forbidden slot.
13104 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
13108 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
13110 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13111 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
13112 /* Branches completion */
13113 clear_branch_hflags(ctx
);
13114 ctx
->base
.is_jmp
= DISAS_NORETURN
;
13115 /* FIXME: Need to clear can_do_io. */
13116 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
13117 case MIPS_HFLAG_FBNSLOT
:
13118 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
13121 /* unconditional branch */
13122 if (proc_hflags
& MIPS_HFLAG_BX
) {
13123 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
13125 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13127 case MIPS_HFLAG_BL
:
13128 /* blikely taken case */
13129 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13131 case MIPS_HFLAG_BC
:
13132 /* Conditional branch */
13134 TCGLabel
*l1
= gen_new_label();
13136 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
13137 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
13139 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13142 case MIPS_HFLAG_BR
:
13143 /* unconditional branch to register */
13144 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
13145 TCGv t0
= tcg_temp_new();
13146 TCGv_i32 t1
= tcg_temp_new_i32();
13148 tcg_gen_andi_tl(t0
, btarget
, 0x1);
13149 tcg_gen_trunc_tl_i32(t1
, t0
);
13151 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
13152 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
13153 tcg_gen_or_i32(hflags
, hflags
, t1
);
13154 tcg_temp_free_i32(t1
);
13156 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
13158 tcg_gen_mov_tl(cpu_PC
, btarget
);
13160 if (ctx
->base
.singlestep_enabled
) {
13161 save_cpu_state(ctx
, 0);
13162 gen_helper_raise_exception_debug(cpu_env
);
13164 tcg_gen_lookup_and_goto_ptr();
13167 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
13173 /* Compact Branches */
13174 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
13175 int rs
, int rt
, int32_t offset
)
13177 int bcond_compute
= 0;
13178 TCGv t0
= tcg_temp_new();
13179 TCGv t1
= tcg_temp_new();
13180 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
13182 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13183 #ifdef MIPS_DEBUG_DISAS
13184 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13185 "\n", ctx
->base
.pc_next
);
13187 generate_exception_end(ctx
, EXCP_RI
);
13191 /* Load needed operands and calculate btarget */
13193 /* compact branch */
13194 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13195 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13196 gen_load_gpr(t0
, rs
);
13197 gen_load_gpr(t1
, rt
);
13199 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13200 if (rs
<= rt
&& rs
== 0) {
13201 /* OPC_BEQZALC, OPC_BNEZALC */
13202 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13205 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13206 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13207 gen_load_gpr(t0
, rs
);
13208 gen_load_gpr(t1
, rt
);
13210 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13212 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13213 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13214 if (rs
== 0 || rs
== rt
) {
13215 /* OPC_BLEZALC, OPC_BGEZALC */
13216 /* OPC_BGTZALC, OPC_BLTZALC */
13217 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13219 gen_load_gpr(t0
, rs
);
13220 gen_load_gpr(t1
, rt
);
13222 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13226 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13231 /* OPC_BEQZC, OPC_BNEZC */
13232 gen_load_gpr(t0
, rs
);
13234 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13236 /* OPC_JIC, OPC_JIALC */
13237 TCGv tbase
= tcg_temp_new();
13238 TCGv toffset
= tcg_temp_new();
13240 gen_load_gpr(tbase
, rt
);
13241 tcg_gen_movi_tl(toffset
, offset
);
13242 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13243 tcg_temp_free(tbase
);
13244 tcg_temp_free(toffset
);
13248 MIPS_INVAL("Compact branch/jump");
13249 generate_exception_end(ctx
, EXCP_RI
);
13253 if (bcond_compute
== 0) {
13254 /* Uncoditional compact branch */
13257 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13260 ctx
->hflags
|= MIPS_HFLAG_BR
;
13263 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13266 ctx
->hflags
|= MIPS_HFLAG_B
;
13269 MIPS_INVAL("Compact branch/jump");
13270 generate_exception_end(ctx
, EXCP_RI
);
13274 /* Generating branch here as compact branches don't have delay slot */
13275 gen_branch(ctx
, 4);
13277 /* Conditional compact branch */
13278 TCGLabel
*fs
= gen_new_label();
13279 save_cpu_state(ctx
, 0);
13282 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13283 if (rs
== 0 && rt
!= 0) {
13285 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13286 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13288 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13291 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13294 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13295 if (rs
== 0 && rt
!= 0) {
13297 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13298 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13300 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13303 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13306 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13307 if (rs
== 0 && rt
!= 0) {
13309 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13310 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13312 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13315 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13318 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13319 if (rs
== 0 && rt
!= 0) {
13321 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13322 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13324 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13327 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13330 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13331 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13333 /* OPC_BOVC, OPC_BNVC */
13334 TCGv t2
= tcg_temp_new();
13335 TCGv t3
= tcg_temp_new();
13336 TCGv t4
= tcg_temp_new();
13337 TCGv input_overflow
= tcg_temp_new();
13339 gen_load_gpr(t0
, rs
);
13340 gen_load_gpr(t1
, rt
);
13341 tcg_gen_ext32s_tl(t2
, t0
);
13342 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13343 tcg_gen_ext32s_tl(t3
, t1
);
13344 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13345 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13347 tcg_gen_add_tl(t4
, t2
, t3
);
13348 tcg_gen_ext32s_tl(t4
, t4
);
13349 tcg_gen_xor_tl(t2
, t2
, t3
);
13350 tcg_gen_xor_tl(t3
, t4
, t3
);
13351 tcg_gen_andc_tl(t2
, t3
, t2
);
13352 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13353 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13354 if (opc
== OPC_BOVC
) {
13356 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13359 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13361 tcg_temp_free(input_overflow
);
13365 } else if (rs
< rt
&& rs
== 0) {
13366 /* OPC_BEQZALC, OPC_BNEZALC */
13367 if (opc
== OPC_BEQZALC
) {
13369 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13372 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13375 /* OPC_BEQC, OPC_BNEC */
13376 if (opc
== OPC_BEQC
) {
13378 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13381 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13386 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13389 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13392 MIPS_INVAL("Compact conditional branch/jump");
13393 generate_exception_end(ctx
, EXCP_RI
);
13397 /* Generating branch here as compact branches don't have delay slot */
13398 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13401 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13409 /* ISA extensions (ASEs) */
13410 /* MIPS16 extension to MIPS32 */
13412 /* MIPS16 major opcodes */
13414 M16_OPC_ADDIUSP
= 0x00,
13415 M16_OPC_ADDIUPC
= 0x01,
13417 M16_OPC_JAL
= 0x03,
13418 M16_OPC_BEQZ
= 0x04,
13419 M16_OPC_BNEQZ
= 0x05,
13420 M16_OPC_SHIFT
= 0x06,
13422 M16_OPC_RRIA
= 0x08,
13423 M16_OPC_ADDIU8
= 0x09,
13424 M16_OPC_SLTI
= 0x0a,
13425 M16_OPC_SLTIU
= 0x0b,
13428 M16_OPC_CMPI
= 0x0e,
13432 M16_OPC_LWSP
= 0x12,
13434 M16_OPC_LBU
= 0x14,
13435 M16_OPC_LHU
= 0x15,
13436 M16_OPC_LWPC
= 0x16,
13437 M16_OPC_LWU
= 0x17,
13440 M16_OPC_SWSP
= 0x1a,
13442 M16_OPC_RRR
= 0x1c,
13444 M16_OPC_EXTEND
= 0x1e,
13448 /* I8 funct field */
13467 /* RR funct field */
13501 /* I64 funct field */
13509 I64_DADDIUPC
= 0x6,
13513 /* RR ry field for CNVT */
13515 RR_RY_CNVT_ZEB
= 0x0,
13516 RR_RY_CNVT_ZEH
= 0x1,
13517 RR_RY_CNVT_ZEW
= 0x2,
13518 RR_RY_CNVT_SEB
= 0x4,
13519 RR_RY_CNVT_SEH
= 0x5,
13520 RR_RY_CNVT_SEW
= 0x6,
13523 static int xlat(int r
)
13525 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13530 static void gen_mips16_save(DisasContext
*ctx
,
13531 int xsregs
, int aregs
,
13532 int do_ra
, int do_s0
, int do_s1
,
13535 TCGv t0
= tcg_temp_new();
13536 TCGv t1
= tcg_temp_new();
13537 TCGv t2
= tcg_temp_new();
13567 generate_exception_end(ctx
, EXCP_RI
);
13573 gen_base_offset_addr(ctx
, t0
, 29, 12);
13574 gen_load_gpr(t1
, 7);
13575 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13578 gen_base_offset_addr(ctx
, t0
, 29, 8);
13579 gen_load_gpr(t1
, 6);
13580 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13583 gen_base_offset_addr(ctx
, t0
, 29, 4);
13584 gen_load_gpr(t1
, 5);
13585 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13588 gen_base_offset_addr(ctx
, t0
, 29, 0);
13589 gen_load_gpr(t1
, 4);
13590 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13593 gen_load_gpr(t0
, 29);
13595 #define DECR_AND_STORE(reg) do { \
13596 tcg_gen_movi_tl(t2, -4); \
13597 gen_op_addr_add(ctx, t0, t0, t2); \
13598 gen_load_gpr(t1, reg); \
13599 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13603 DECR_AND_STORE(31);
13608 DECR_AND_STORE(30);
13611 DECR_AND_STORE(23);
13614 DECR_AND_STORE(22);
13617 DECR_AND_STORE(21);
13620 DECR_AND_STORE(20);
13623 DECR_AND_STORE(19);
13626 DECR_AND_STORE(18);
13630 DECR_AND_STORE(17);
13633 DECR_AND_STORE(16);
13663 generate_exception_end(ctx
, EXCP_RI
);
13679 #undef DECR_AND_STORE
13681 tcg_gen_movi_tl(t2
, -framesize
);
13682 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13688 static void gen_mips16_restore(DisasContext
*ctx
,
13689 int xsregs
, int aregs
,
13690 int do_ra
, int do_s0
, int do_s1
,
13694 TCGv t0
= tcg_temp_new();
13695 TCGv t1
= tcg_temp_new();
13696 TCGv t2
= tcg_temp_new();
13698 tcg_gen_movi_tl(t2
, framesize
);
13699 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
13701 #define DECR_AND_LOAD(reg) do { \
13702 tcg_gen_movi_tl(t2, -4); \
13703 gen_op_addr_add(ctx, t0, t0, t2); \
13704 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13705 gen_store_gpr(t1, reg); \
13769 generate_exception_end(ctx
, EXCP_RI
);
13785 #undef DECR_AND_LOAD
13787 tcg_gen_movi_tl(t2
, framesize
);
13788 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13794 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
13795 int is_64_bit
, int extended
)
13799 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13800 generate_exception_end(ctx
, EXCP_RI
);
13804 t0
= tcg_temp_new();
13806 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
13807 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
13809 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13815 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
13818 TCGv_i32 t0
= tcg_const_i32(op
);
13819 TCGv t1
= tcg_temp_new();
13820 gen_base_offset_addr(ctx
, t1
, base
, offset
);
13821 gen_helper_cache(cpu_env
, t1
, t0
);
13824 #if defined(TARGET_MIPS64)
13825 static void decode_i64_mips16(DisasContext
*ctx
,
13826 int ry
, int funct
, int16_t offset
,
13831 check_insn(ctx
, ISA_MIPS3
);
13832 check_mips_64(ctx
);
13833 offset
= extended
? offset
: offset
<< 3;
13834 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
13837 check_insn(ctx
, ISA_MIPS3
);
13838 check_mips_64(ctx
);
13839 offset
= extended
? offset
: offset
<< 3;
13840 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
13843 check_insn(ctx
, ISA_MIPS3
);
13844 check_mips_64(ctx
);
13845 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
13846 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
13849 check_insn(ctx
, ISA_MIPS3
);
13850 check_mips_64(ctx
);
13851 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
13852 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
13855 check_insn(ctx
, ISA_MIPS3
);
13856 check_mips_64(ctx
);
13857 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13858 generate_exception_end(ctx
, EXCP_RI
);
13860 offset
= extended
? offset
: offset
<< 3;
13861 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
13865 check_insn(ctx
, ISA_MIPS3
);
13866 check_mips_64(ctx
);
13867 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
13868 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
13871 check_insn(ctx
, ISA_MIPS3
);
13872 check_mips_64(ctx
);
13873 offset
= extended
? offset
: offset
<< 2;
13874 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
13877 check_insn(ctx
, ISA_MIPS3
);
13878 check_mips_64(ctx
);
13879 offset
= extended
? offset
: offset
<< 2;
13880 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
13886 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13888 int extend
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
13889 int op
, rx
, ry
, funct
, sa
;
13890 int16_t imm
, offset
;
13892 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
13893 op
= (ctx
->opcode
>> 11) & 0x1f;
13894 sa
= (ctx
->opcode
>> 22) & 0x1f;
13895 funct
= (ctx
->opcode
>> 8) & 0x7;
13896 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13897 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13898 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
13899 | ((ctx
->opcode
>> 21) & 0x3f) << 5
13900 | (ctx
->opcode
& 0x1f));
13903 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13907 case M16_OPC_ADDIUSP
:
13908 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13910 case M16_OPC_ADDIUPC
:
13911 gen_addiupc(ctx
, rx
, imm
, 0, 1);
13914 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
13915 /* No delay slot, so just process as a normal instruction */
13918 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
13919 /* No delay slot, so just process as a normal instruction */
13921 case M16_OPC_BNEQZ
:
13922 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
13923 /* No delay slot, so just process as a normal instruction */
13925 case M16_OPC_SHIFT
:
13926 switch (ctx
->opcode
& 0x3) {
13928 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13931 #if defined(TARGET_MIPS64)
13932 check_mips_64(ctx
);
13933 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13935 generate_exception_end(ctx
, EXCP_RI
);
13939 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13942 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13946 #if defined(TARGET_MIPS64)
13948 check_insn(ctx
, ISA_MIPS3
);
13949 check_mips_64(ctx
);
13950 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
13954 imm
= ctx
->opcode
& 0xf;
13955 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
13956 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
13957 imm
= (int16_t) (imm
<< 1) >> 1;
13958 if ((ctx
->opcode
>> 4) & 0x1) {
13959 #if defined(TARGET_MIPS64)
13960 check_mips_64(ctx
);
13961 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13963 generate_exception_end(ctx
, EXCP_RI
);
13966 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13969 case M16_OPC_ADDIU8
:
13970 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13973 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13975 case M16_OPC_SLTIU
:
13976 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13981 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
13984 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
13987 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
13990 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
13993 check_insn(ctx
, ISA_MIPS32
);
13995 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
13996 int aregs
= (ctx
->opcode
>> 16) & 0xf;
13997 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
13998 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
13999 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
14000 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
14001 | (ctx
->opcode
& 0xf)) << 3;
14003 if (ctx
->opcode
& (1 << 7)) {
14004 gen_mips16_save(ctx
, xsregs
, aregs
,
14005 do_ra
, do_s0
, do_s1
,
14008 gen_mips16_restore(ctx
, xsregs
, aregs
,
14009 do_ra
, do_s0
, do_s1
,
14015 generate_exception_end(ctx
, EXCP_RI
);
14020 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
14023 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
14025 #if defined(TARGET_MIPS64)
14027 check_insn(ctx
, ISA_MIPS3
);
14028 check_mips_64(ctx
);
14029 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
14033 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14036 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
14039 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
14042 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
14045 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14048 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
14051 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
14053 #if defined(TARGET_MIPS64)
14055 check_insn(ctx
, ISA_MIPS3
);
14056 check_mips_64(ctx
);
14057 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
14061 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14064 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
14067 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
14070 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
14072 #if defined(TARGET_MIPS64)
14074 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
14078 generate_exception_end(ctx
, EXCP_RI
);
14085 static inline bool is_uhi(int sdbbp_code
)
14087 #ifdef CONFIG_USER_ONLY
14090 return semihosting_enabled() && sdbbp_code
== 1;
14094 #ifdef CONFIG_USER_ONLY
14095 /* The above should dead-code away any calls to this..*/
14096 static inline void gen_helper_do_semihosting(void *env
)
14098 g_assert_not_reached();
14102 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14106 int op
, cnvt_op
, op1
, offset
;
14110 op
= (ctx
->opcode
>> 11) & 0x1f;
14111 sa
= (ctx
->opcode
>> 2) & 0x7;
14112 sa
= sa
== 0 ? 8 : sa
;
14113 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14114 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
14115 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14116 op1
= offset
= ctx
->opcode
& 0x1f;
14121 case M16_OPC_ADDIUSP
:
14123 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
14125 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14128 case M16_OPC_ADDIUPC
:
14129 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
14132 offset
= (ctx
->opcode
& 0x7ff) << 1;
14133 offset
= (int16_t)(offset
<< 4) >> 4;
14134 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
14135 /* No delay slot, so just process as a normal instruction */
14138 offset
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14139 offset
= (((ctx
->opcode
& 0x1f) << 21)
14140 | ((ctx
->opcode
>> 5) & 0x1f) << 16
14142 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
14143 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
14147 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
14148 ((int8_t)ctx
->opcode
) << 1, 0);
14149 /* No delay slot, so just process as a normal instruction */
14151 case M16_OPC_BNEQZ
:
14152 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
14153 ((int8_t)ctx
->opcode
) << 1, 0);
14154 /* No delay slot, so just process as a normal instruction */
14156 case M16_OPC_SHIFT
:
14157 switch (ctx
->opcode
& 0x3) {
14159 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14162 #if defined(TARGET_MIPS64)
14163 check_insn(ctx
, ISA_MIPS3
);
14164 check_mips_64(ctx
);
14165 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14167 generate_exception_end(ctx
, EXCP_RI
);
14171 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14174 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14178 #if defined(TARGET_MIPS64)
14180 check_insn(ctx
, ISA_MIPS3
);
14181 check_mips_64(ctx
);
14182 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14187 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14189 if ((ctx
->opcode
>> 4) & 1) {
14190 #if defined(TARGET_MIPS64)
14191 check_insn(ctx
, ISA_MIPS3
);
14192 check_mips_64(ctx
);
14193 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14195 generate_exception_end(ctx
, EXCP_RI
);
14198 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14202 case M16_OPC_ADDIU8
:
14204 int16_t imm
= (int8_t) ctx
->opcode
;
14206 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14211 int16_t imm
= (uint8_t) ctx
->opcode
;
14212 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14215 case M16_OPC_SLTIU
:
14217 int16_t imm
= (uint8_t) ctx
->opcode
;
14218 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14225 funct
= (ctx
->opcode
>> 8) & 0x7;
14228 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14229 ((int8_t)ctx
->opcode
) << 1, 0);
14232 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14233 ((int8_t)ctx
->opcode
) << 1, 0);
14236 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14239 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14240 ((int8_t)ctx
->opcode
) << 3);
14243 check_insn(ctx
, ISA_MIPS32
);
14245 int do_ra
= ctx
->opcode
& (1 << 6);
14246 int do_s0
= ctx
->opcode
& (1 << 5);
14247 int do_s1
= ctx
->opcode
& (1 << 4);
14248 int framesize
= ctx
->opcode
& 0xf;
14250 if (framesize
== 0) {
14253 framesize
= framesize
<< 3;
14256 if (ctx
->opcode
& (1 << 7)) {
14257 gen_mips16_save(ctx
, 0, 0,
14258 do_ra
, do_s0
, do_s1
, framesize
);
14260 gen_mips16_restore(ctx
, 0, 0,
14261 do_ra
, do_s0
, do_s1
, framesize
);
14267 int rz
= xlat(ctx
->opcode
& 0x7);
14269 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14270 ((ctx
->opcode
>> 5) & 0x7);
14271 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14275 reg32
= ctx
->opcode
& 0x1f;
14276 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14279 generate_exception_end(ctx
, EXCP_RI
);
14286 int16_t imm
= (uint8_t) ctx
->opcode
;
14288 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14293 int16_t imm
= (uint8_t) ctx
->opcode
;
14294 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14297 #if defined(TARGET_MIPS64)
14299 check_insn(ctx
, ISA_MIPS3
);
14300 check_mips_64(ctx
);
14301 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14305 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14308 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14311 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14314 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14317 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14320 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14323 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14325 #if defined(TARGET_MIPS64)
14327 check_insn(ctx
, ISA_MIPS3
);
14328 check_mips_64(ctx
);
14329 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14333 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14336 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14339 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14342 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14346 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14349 switch (ctx
->opcode
& 0x3) {
14351 mips32_op
= OPC_ADDU
;
14354 mips32_op
= OPC_SUBU
;
14356 #if defined(TARGET_MIPS64)
14358 mips32_op
= OPC_DADDU
;
14359 check_insn(ctx
, ISA_MIPS3
);
14360 check_mips_64(ctx
);
14363 mips32_op
= OPC_DSUBU
;
14364 check_insn(ctx
, ISA_MIPS3
);
14365 check_mips_64(ctx
);
14369 generate_exception_end(ctx
, EXCP_RI
);
14373 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14382 int nd
= (ctx
->opcode
>> 7) & 0x1;
14383 int link
= (ctx
->opcode
>> 6) & 0x1;
14384 int ra
= (ctx
->opcode
>> 5) & 0x1;
14387 check_insn(ctx
, ISA_MIPS32
);
14396 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14401 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14402 gen_helper_do_semihosting(cpu_env
);
14405 * XXX: not clear which exception should be raised
14406 * when in debug mode...
14408 check_insn(ctx
, ISA_MIPS32
);
14409 generate_exception_end(ctx
, EXCP_DBp
);
14413 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14416 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14419 generate_exception_end(ctx
, EXCP_BREAK
);
14422 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14425 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14428 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14430 #if defined(TARGET_MIPS64)
14432 check_insn(ctx
, ISA_MIPS3
);
14433 check_mips_64(ctx
);
14434 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14438 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14441 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14444 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14447 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14450 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14453 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14456 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14459 check_insn(ctx
, ISA_MIPS32
);
14461 case RR_RY_CNVT_ZEB
:
14462 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14464 case RR_RY_CNVT_ZEH
:
14465 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14467 case RR_RY_CNVT_SEB
:
14468 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14470 case RR_RY_CNVT_SEH
:
14471 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14473 #if defined(TARGET_MIPS64)
14474 case RR_RY_CNVT_ZEW
:
14475 check_insn(ctx
, ISA_MIPS64
);
14476 check_mips_64(ctx
);
14477 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14479 case RR_RY_CNVT_SEW
:
14480 check_insn(ctx
, ISA_MIPS64
);
14481 check_mips_64(ctx
);
14482 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14486 generate_exception_end(ctx
, EXCP_RI
);
14491 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14493 #if defined(TARGET_MIPS64)
14495 check_insn(ctx
, ISA_MIPS3
);
14496 check_mips_64(ctx
);
14497 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14500 check_insn(ctx
, ISA_MIPS3
);
14501 check_mips_64(ctx
);
14502 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14505 check_insn(ctx
, ISA_MIPS3
);
14506 check_mips_64(ctx
);
14507 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14510 check_insn(ctx
, ISA_MIPS3
);
14511 check_mips_64(ctx
);
14512 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14516 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14519 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14522 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14525 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14527 #if defined(TARGET_MIPS64)
14529 check_insn(ctx
, ISA_MIPS3
);
14530 check_mips_64(ctx
);
14531 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14534 check_insn(ctx
, ISA_MIPS3
);
14535 check_mips_64(ctx
);
14536 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14539 check_insn(ctx
, ISA_MIPS3
);
14540 check_mips_64(ctx
);
14541 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14544 check_insn(ctx
, ISA_MIPS3
);
14545 check_mips_64(ctx
);
14546 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14550 generate_exception_end(ctx
, EXCP_RI
);
14554 case M16_OPC_EXTEND
:
14555 decode_extended_mips16_opc(env
, ctx
);
14558 #if defined(TARGET_MIPS64)
14560 funct
= (ctx
->opcode
>> 8) & 0x7;
14561 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
14565 generate_exception_end(ctx
, EXCP_RI
);
14572 /* microMIPS extension to MIPS32/MIPS64 */
14575 * microMIPS32/microMIPS64 major opcodes
14577 * 1. MIPS Architecture for Programmers Volume II-B:
14578 * The microMIPS32 Instruction Set (Revision 3.05)
14580 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14582 * 2. MIPS Architecture For Programmers Volume II-A:
14583 * The MIPS64 Instruction Set (Revision 3.51)
14613 POOL32S
= 0x16, /* MIPS64 */
14614 DADDIU32
= 0x17, /* MIPS64 */
14643 /* 0x29 is reserved */
14656 /* 0x31 is reserved */
14669 SD32
= 0x36, /* MIPS64 */
14670 LD32
= 0x37, /* MIPS64 */
14672 /* 0x39 is reserved */
14688 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14710 /* POOL32A encoding of minor opcode field */
14714 * These opcodes are distinguished only by bits 9..6; those bits are
14715 * what are recorded below.
14753 /* The following can be distinguished by their lower 6 bits. */
14763 /* POOL32AXF encoding of minor opcode field extension */
14766 * 1. MIPS Architecture for Programmers Volume II-B:
14767 * The microMIPS32 Instruction Set (Revision 3.05)
14769 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14771 * 2. MIPS Architecture for Programmers VolumeIV-e:
14772 * The MIPS DSP Application-Specific Extension
14773 * to the microMIPS32 Architecture (Revision 2.34)
14775 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14790 /* begin of microMIPS32 DSP */
14792 /* bits 13..12 for 0x01 */
14798 /* bits 13..12 for 0x2a */
14804 /* bits 13..12 for 0x32 */
14808 /* end of microMIPS32 DSP */
14810 /* bits 15..12 for 0x2c */
14827 /* bits 15..12 for 0x34 */
14835 /* bits 15..12 for 0x3c */
14837 JR
= 0x0, /* alias */
14845 /* bits 15..12 for 0x05 */
14849 /* bits 15..12 for 0x0d */
14861 /* bits 15..12 for 0x15 */
14867 /* bits 15..12 for 0x1d */
14871 /* bits 15..12 for 0x2d */
14876 /* bits 15..12 for 0x35 */
14883 /* POOL32B encoding of minor opcode field (bits 15..12) */
14899 /* POOL32C encoding of minor opcode field (bits 15..12) */
14920 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14933 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14946 /* POOL32F encoding of minor opcode field (bits 5..0) */
14949 /* These are the bit 7..6 values */
14958 /* These are the bit 8..6 values */
14983 MOVZ_FMT_05
= 0x05,
15017 CABS_COND_FMT
= 0x1c, /* MIPS3D */
15024 /* POOL32Fxf encoding of minor opcode extension field */
15062 /* POOL32I encoding of minor opcode field (bits 25..21) */
15092 /* These overlap and are distinguished by bit16 of the instruction */
15101 /* POOL16A encoding of minor opcode field */
15108 /* POOL16B encoding of minor opcode field */
15115 /* POOL16C encoding of minor opcode field */
15135 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15159 /* POOL16D encoding of minor opcode field */
15166 /* POOL16E encoding of minor opcode field */
15173 static int mmreg(int r
)
15175 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15180 /* Used for 16-bit store instructions. */
15181 static int mmreg2(int r
)
15183 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15188 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15189 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15190 #define uMIPS_RS2(op) uMIPS_RS(op)
15191 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15192 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15193 #define uMIPS_RS5(op) (op & 0x1f)
15195 /* Signed immediate */
15196 #define SIMM(op, start, width) \
15197 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15200 /* Zero-extended immediate */
15201 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15203 static void gen_addiur1sp(DisasContext
*ctx
)
15205 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15207 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15210 static void gen_addiur2(DisasContext
*ctx
)
15212 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15213 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15214 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15216 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15219 static void gen_addiusp(DisasContext
*ctx
)
15221 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15224 if (encoded
<= 1) {
15225 decoded
= 256 + encoded
;
15226 } else if (encoded
<= 255) {
15228 } else if (encoded
<= 509) {
15229 decoded
= encoded
- 512;
15231 decoded
= encoded
- 768;
15234 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15237 static void gen_addius5(DisasContext
*ctx
)
15239 int imm
= SIMM(ctx
->opcode
, 1, 4);
15240 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15242 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15245 static void gen_andi16(DisasContext
*ctx
)
15247 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15248 31, 32, 63, 64, 255, 32768, 65535 };
15249 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15250 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15251 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15253 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15256 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15257 int base
, int16_t offset
)
15262 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15263 generate_exception_end(ctx
, EXCP_RI
);
15267 t0
= tcg_temp_new();
15269 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15271 t1
= tcg_const_tl(reglist
);
15272 t2
= tcg_const_i32(ctx
->mem_idx
);
15274 save_cpu_state(ctx
, 1);
15277 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15280 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15282 #ifdef TARGET_MIPS64
15284 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15287 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15293 tcg_temp_free_i32(t2
);
15297 static void gen_pool16c_insn(DisasContext
*ctx
)
15299 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15300 int rs
= mmreg(ctx
->opcode
& 0x7);
15302 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15307 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15313 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15319 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15325 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15332 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15333 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15335 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15344 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15345 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15347 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15354 int reg
= ctx
->opcode
& 0x1f;
15356 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15362 int reg
= ctx
->opcode
& 0x1f;
15363 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15365 * Let normal delay slot handling in our caller take us
15366 * to the branch target.
15372 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15373 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15377 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15378 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15382 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15386 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15389 generate_exception_end(ctx
, EXCP_BREAK
);
15392 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15393 gen_helper_do_semihosting(cpu_env
);
15396 * XXX: not clear which exception should be raised
15397 * when in debug mode...
15399 check_insn(ctx
, ISA_MIPS32
);
15400 generate_exception_end(ctx
, EXCP_DBp
);
15403 case JRADDIUSP
+ 0:
15404 case JRADDIUSP
+ 1:
15406 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15407 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15408 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15410 * Let normal delay slot handling in our caller take us
15411 * to the branch target.
15416 generate_exception_end(ctx
, EXCP_RI
);
15421 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15424 int rd
, rs
, re
, rt
;
15425 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15426 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15427 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15428 rd
= rd_enc
[enc_dest
];
15429 re
= re_enc
[enc_dest
];
15430 rs
= rs_rt_enc
[enc_rs
];
15431 rt
= rs_rt_enc
[enc_rt
];
15433 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15435 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15438 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15440 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15444 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15446 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15447 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15449 switch (ctx
->opcode
& 0xf) {
15451 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15454 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15458 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15459 int offset
= extract32(ctx
->opcode
, 4, 4);
15460 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15463 case R6_JRC16
: /* JRCADDIUSP */
15464 if ((ctx
->opcode
>> 4) & 1) {
15466 int imm
= extract32(ctx
->opcode
, 5, 5);
15467 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15468 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15471 rs
= extract32(ctx
->opcode
, 5, 5);
15472 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15484 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15485 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15486 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15487 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15491 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15494 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15498 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15499 int offset
= extract32(ctx
->opcode
, 4, 4);
15500 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15503 case JALRC16
: /* BREAK16, SDBBP16 */
15504 switch (ctx
->opcode
& 0x3f) {
15506 case JALRC16
+ 0x20:
15508 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15513 generate_exception(ctx
, EXCP_BREAK
);
15517 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15518 gen_helper_do_semihosting(cpu_env
);
15520 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15521 generate_exception(ctx
, EXCP_RI
);
15523 generate_exception(ctx
, EXCP_DBp
);
15530 generate_exception(ctx
, EXCP_RI
);
15535 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15537 TCGv t0
= tcg_temp_new();
15538 TCGv t1
= tcg_temp_new();
15540 gen_load_gpr(t0
, base
);
15543 gen_load_gpr(t1
, index
);
15544 tcg_gen_shli_tl(t1
, t1
, 2);
15545 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15548 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15549 gen_store_gpr(t1
, rd
);
15555 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15556 int base
, int16_t offset
)
15560 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15561 generate_exception_end(ctx
, EXCP_RI
);
15565 t0
= tcg_temp_new();
15566 t1
= tcg_temp_new();
15568 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15573 generate_exception_end(ctx
, EXCP_RI
);
15576 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15577 gen_store_gpr(t1
, rd
);
15578 tcg_gen_movi_tl(t1
, 4);
15579 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15580 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15581 gen_store_gpr(t1
, rd
+ 1);
15584 gen_load_gpr(t1
, rd
);
15585 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15586 tcg_gen_movi_tl(t1
, 4);
15587 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15588 gen_load_gpr(t1
, rd
+ 1);
15589 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15591 #ifdef TARGET_MIPS64
15594 generate_exception_end(ctx
, EXCP_RI
);
15597 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15598 gen_store_gpr(t1
, rd
);
15599 tcg_gen_movi_tl(t1
, 8);
15600 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15601 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15602 gen_store_gpr(t1
, rd
+ 1);
15605 gen_load_gpr(t1
, rd
);
15606 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15607 tcg_gen_movi_tl(t1
, 8);
15608 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15609 gen_load_gpr(t1
, rd
+ 1);
15610 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15618 static void gen_sync(int stype
)
15620 TCGBar tcg_mo
= TCG_BAR_SC
;
15623 case 0x4: /* SYNC_WMB */
15624 tcg_mo
|= TCG_MO_ST_ST
;
15626 case 0x10: /* SYNC_MB */
15627 tcg_mo
|= TCG_MO_ALL
;
15629 case 0x11: /* SYNC_ACQUIRE */
15630 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
15632 case 0x12: /* SYNC_RELEASE */
15633 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
15635 case 0x13: /* SYNC_RMB */
15636 tcg_mo
|= TCG_MO_LD_LD
;
15639 tcg_mo
|= TCG_MO_ALL
;
15643 tcg_gen_mb(tcg_mo
);
15646 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
15648 int extension
= (ctx
->opcode
>> 6) & 0x3f;
15649 int minor
= (ctx
->opcode
>> 12) & 0xf;
15650 uint32_t mips32_op
;
15652 switch (extension
) {
15654 mips32_op
= OPC_TEQ
;
15657 mips32_op
= OPC_TGE
;
15660 mips32_op
= OPC_TGEU
;
15663 mips32_op
= OPC_TLT
;
15666 mips32_op
= OPC_TLTU
;
15669 mips32_op
= OPC_TNE
;
15671 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
15673 #ifndef CONFIG_USER_ONLY
15676 check_cp0_enabled(ctx
);
15678 /* Treat as NOP. */
15681 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
15685 check_cp0_enabled(ctx
);
15687 TCGv t0
= tcg_temp_new();
15689 gen_load_gpr(t0
, rt
);
15690 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
15696 switch (minor
& 3) {
15698 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15701 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15704 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15707 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15710 goto pool32axf_invalid
;
15714 switch (minor
& 3) {
15716 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15719 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15722 goto pool32axf_invalid
;
15728 check_insn(ctx
, ISA_MIPS32R6
);
15729 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
15732 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
15735 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
15738 mips32_op
= OPC_CLO
;
15741 mips32_op
= OPC_CLZ
;
15743 check_insn(ctx
, ISA_MIPS32
);
15744 gen_cl(ctx
, mips32_op
, rt
, rs
);
15747 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15748 gen_rdhwr(ctx
, rt
, rs
, 0);
15751 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
15754 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15755 mips32_op
= OPC_MULT
;
15758 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15759 mips32_op
= OPC_MULTU
;
15762 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15763 mips32_op
= OPC_DIV
;
15766 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15767 mips32_op
= OPC_DIVU
;
15770 check_insn(ctx
, ISA_MIPS32
);
15771 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15774 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15775 mips32_op
= OPC_MADD
;
15778 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15779 mips32_op
= OPC_MADDU
;
15782 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15783 mips32_op
= OPC_MSUB
;
15786 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15787 mips32_op
= OPC_MSUBU
;
15789 check_insn(ctx
, ISA_MIPS32
);
15790 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15793 goto pool32axf_invalid
;
15804 generate_exception_err(ctx
, EXCP_CpU
, 2);
15807 goto pool32axf_invalid
;
15812 case JALR
: /* JALRC */
15813 case JALR_HB
: /* JALRC_HB */
15814 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15815 /* JALRC, JALRC_HB */
15816 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
15818 /* JALR, JALR_HB */
15819 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
15820 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15825 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15826 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
15827 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15830 goto pool32axf_invalid
;
15836 check_cp0_enabled(ctx
);
15837 check_insn(ctx
, ISA_MIPS32R2
);
15838 gen_load_srsgpr(rs
, rt
);
15841 check_cp0_enabled(ctx
);
15842 check_insn(ctx
, ISA_MIPS32R2
);
15843 gen_store_srsgpr(rs
, rt
);
15846 goto pool32axf_invalid
;
15849 #ifndef CONFIG_USER_ONLY
15853 mips32_op
= OPC_TLBP
;
15856 mips32_op
= OPC_TLBR
;
15859 mips32_op
= OPC_TLBWI
;
15862 mips32_op
= OPC_TLBWR
;
15865 mips32_op
= OPC_TLBINV
;
15868 mips32_op
= OPC_TLBINVF
;
15871 mips32_op
= OPC_WAIT
;
15874 mips32_op
= OPC_DERET
;
15877 mips32_op
= OPC_ERET
;
15879 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
15882 goto pool32axf_invalid
;
15888 check_cp0_enabled(ctx
);
15890 TCGv t0
= tcg_temp_new();
15892 save_cpu_state(ctx
, 1);
15893 gen_helper_di(t0
, cpu_env
);
15894 gen_store_gpr(t0
, rs
);
15896 * Stop translation as we may have switched the execution
15899 ctx
->base
.is_jmp
= DISAS_STOP
;
15904 check_cp0_enabled(ctx
);
15906 TCGv t0
= tcg_temp_new();
15908 save_cpu_state(ctx
, 1);
15909 gen_helper_ei(t0
, cpu_env
);
15910 gen_store_gpr(t0
, rs
);
15912 * DISAS_STOP isn't sufficient, we need to ensure we break out
15913 * of translated code to check for pending interrupts.
15915 gen_save_pc(ctx
->base
.pc_next
+ 4);
15916 ctx
->base
.is_jmp
= DISAS_EXIT
;
15921 goto pool32axf_invalid
;
15928 gen_sync(extract32(ctx
->opcode
, 16, 5));
15931 generate_exception_end(ctx
, EXCP_SYSCALL
);
15934 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
15935 gen_helper_do_semihosting(cpu_env
);
15937 check_insn(ctx
, ISA_MIPS32
);
15938 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15939 generate_exception_end(ctx
, EXCP_RI
);
15941 generate_exception_end(ctx
, EXCP_DBp
);
15946 goto pool32axf_invalid
;
15950 switch (minor
& 3) {
15952 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
15955 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
15958 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
15961 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
15964 goto pool32axf_invalid
;
15968 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15971 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
15974 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
15977 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
15980 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
15983 goto pool32axf_invalid
;
15988 MIPS_INVAL("pool32axf");
15989 generate_exception_end(ctx
, EXCP_RI
);
15995 * Values for microMIPS fmt field. Variable-width, depending on which
15996 * formats the instruction supports.
16015 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
16017 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
16018 uint32_t mips32_op
;
16020 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
16021 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
16022 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
16024 switch (extension
) {
16025 case FLOAT_1BIT_FMT(CFC1
, 0):
16026 mips32_op
= OPC_CFC1
;
16028 case FLOAT_1BIT_FMT(CTC1
, 0):
16029 mips32_op
= OPC_CTC1
;
16031 case FLOAT_1BIT_FMT(MFC1
, 0):
16032 mips32_op
= OPC_MFC1
;
16034 case FLOAT_1BIT_FMT(MTC1
, 0):
16035 mips32_op
= OPC_MTC1
;
16037 case FLOAT_1BIT_FMT(MFHC1
, 0):
16038 mips32_op
= OPC_MFHC1
;
16040 case FLOAT_1BIT_FMT(MTHC1
, 0):
16041 mips32_op
= OPC_MTHC1
;
16043 gen_cp1(ctx
, mips32_op
, rt
, rs
);
16046 /* Reciprocal square root */
16047 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
16048 mips32_op
= OPC_RSQRT_S
;
16050 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
16051 mips32_op
= OPC_RSQRT_D
;
16055 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
16056 mips32_op
= OPC_SQRT_S
;
16058 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
16059 mips32_op
= OPC_SQRT_D
;
16063 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
16064 mips32_op
= OPC_RECIP_S
;
16066 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
16067 mips32_op
= OPC_RECIP_D
;
16071 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
16072 mips32_op
= OPC_FLOOR_L_S
;
16074 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
16075 mips32_op
= OPC_FLOOR_L_D
;
16077 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
16078 mips32_op
= OPC_FLOOR_W_S
;
16080 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
16081 mips32_op
= OPC_FLOOR_W_D
;
16085 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
16086 mips32_op
= OPC_CEIL_L_S
;
16088 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
16089 mips32_op
= OPC_CEIL_L_D
;
16091 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
16092 mips32_op
= OPC_CEIL_W_S
;
16094 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
16095 mips32_op
= OPC_CEIL_W_D
;
16099 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
16100 mips32_op
= OPC_TRUNC_L_S
;
16102 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
16103 mips32_op
= OPC_TRUNC_L_D
;
16105 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
16106 mips32_op
= OPC_TRUNC_W_S
;
16108 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
16109 mips32_op
= OPC_TRUNC_W_D
;
16113 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
16114 mips32_op
= OPC_ROUND_L_S
;
16116 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
16117 mips32_op
= OPC_ROUND_L_D
;
16119 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
16120 mips32_op
= OPC_ROUND_W_S
;
16122 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
16123 mips32_op
= OPC_ROUND_W_D
;
16126 /* Integer to floating-point conversion */
16127 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
16128 mips32_op
= OPC_CVT_L_S
;
16130 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
16131 mips32_op
= OPC_CVT_L_D
;
16133 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
16134 mips32_op
= OPC_CVT_W_S
;
16136 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
16137 mips32_op
= OPC_CVT_W_D
;
16140 /* Paired-foo conversions */
16141 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
16142 mips32_op
= OPC_CVT_S_PL
;
16144 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
16145 mips32_op
= OPC_CVT_S_PU
;
16147 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
16148 mips32_op
= OPC_CVT_PW_PS
;
16150 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
16151 mips32_op
= OPC_CVT_PS_PW
;
16154 /* Floating-point moves */
16155 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
16156 mips32_op
= OPC_MOV_S
;
16158 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
16159 mips32_op
= OPC_MOV_D
;
16161 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
16162 mips32_op
= OPC_MOV_PS
;
16165 /* Absolute value */
16166 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
16167 mips32_op
= OPC_ABS_S
;
16169 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
16170 mips32_op
= OPC_ABS_D
;
16172 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
16173 mips32_op
= OPC_ABS_PS
;
16177 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
16178 mips32_op
= OPC_NEG_S
;
16180 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
16181 mips32_op
= OPC_NEG_D
;
16183 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16184 mips32_op
= OPC_NEG_PS
;
16187 /* Reciprocal square root step */
16188 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16189 mips32_op
= OPC_RSQRT1_S
;
16191 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16192 mips32_op
= OPC_RSQRT1_D
;
16194 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16195 mips32_op
= OPC_RSQRT1_PS
;
16198 /* Reciprocal step */
16199 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16200 mips32_op
= OPC_RECIP1_S
;
16202 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16203 mips32_op
= OPC_RECIP1_S
;
16205 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16206 mips32_op
= OPC_RECIP1_PS
;
16209 /* Conversions from double */
16210 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16211 mips32_op
= OPC_CVT_D_S
;
16213 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16214 mips32_op
= OPC_CVT_D_W
;
16216 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16217 mips32_op
= OPC_CVT_D_L
;
16220 /* Conversions from single */
16221 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16222 mips32_op
= OPC_CVT_S_D
;
16224 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16225 mips32_op
= OPC_CVT_S_W
;
16227 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16228 mips32_op
= OPC_CVT_S_L
;
16230 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16233 /* Conditional moves on floating-point codes */
16234 case COND_FLOAT_MOV(MOVT
, 0):
16235 case COND_FLOAT_MOV(MOVT
, 1):
16236 case COND_FLOAT_MOV(MOVT
, 2):
16237 case COND_FLOAT_MOV(MOVT
, 3):
16238 case COND_FLOAT_MOV(MOVT
, 4):
16239 case COND_FLOAT_MOV(MOVT
, 5):
16240 case COND_FLOAT_MOV(MOVT
, 6):
16241 case COND_FLOAT_MOV(MOVT
, 7):
16242 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16243 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16245 case COND_FLOAT_MOV(MOVF
, 0):
16246 case COND_FLOAT_MOV(MOVF
, 1):
16247 case COND_FLOAT_MOV(MOVF
, 2):
16248 case COND_FLOAT_MOV(MOVF
, 3):
16249 case COND_FLOAT_MOV(MOVF
, 4):
16250 case COND_FLOAT_MOV(MOVF
, 5):
16251 case COND_FLOAT_MOV(MOVF
, 6):
16252 case COND_FLOAT_MOV(MOVF
, 7):
16253 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16254 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16257 MIPS_INVAL("pool32fxf");
16258 generate_exception_end(ctx
, EXCP_RI
);
16263 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16267 int rt
, rs
, rd
, rr
;
16269 uint32_t op
, minor
, minor2
, mips32_op
;
16270 uint32_t cond
, fmt
, cc
;
16272 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
16273 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16275 rt
= (ctx
->opcode
>> 21) & 0x1f;
16276 rs
= (ctx
->opcode
>> 16) & 0x1f;
16277 rd
= (ctx
->opcode
>> 11) & 0x1f;
16278 rr
= (ctx
->opcode
>> 6) & 0x1f;
16279 imm
= (int16_t) ctx
->opcode
;
16281 op
= (ctx
->opcode
>> 26) & 0x3f;
16284 minor
= ctx
->opcode
& 0x3f;
16287 minor
= (ctx
->opcode
>> 6) & 0xf;
16290 mips32_op
= OPC_SLL
;
16293 mips32_op
= OPC_SRA
;
16296 mips32_op
= OPC_SRL
;
16299 mips32_op
= OPC_ROTR
;
16301 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16304 check_insn(ctx
, ISA_MIPS32R6
);
16305 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16308 check_insn(ctx
, ISA_MIPS32R6
);
16309 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16312 check_insn(ctx
, ISA_MIPS32R6
);
16313 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16316 goto pool32a_invalid
;
16320 minor
= (ctx
->opcode
>> 6) & 0xf;
16324 mips32_op
= OPC_ADD
;
16327 mips32_op
= OPC_ADDU
;
16330 mips32_op
= OPC_SUB
;
16333 mips32_op
= OPC_SUBU
;
16336 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16337 mips32_op
= OPC_MUL
;
16339 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16343 mips32_op
= OPC_SLLV
;
16346 mips32_op
= OPC_SRLV
;
16349 mips32_op
= OPC_SRAV
;
16352 mips32_op
= OPC_ROTRV
;
16354 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16356 /* Logical operations */
16358 mips32_op
= OPC_AND
;
16361 mips32_op
= OPC_OR
;
16364 mips32_op
= OPC_NOR
;
16367 mips32_op
= OPC_XOR
;
16369 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16371 /* Set less than */
16373 mips32_op
= OPC_SLT
;
16376 mips32_op
= OPC_SLTU
;
16378 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16381 goto pool32a_invalid
;
16385 minor
= (ctx
->opcode
>> 6) & 0xf;
16387 /* Conditional moves */
16388 case MOVN
: /* MUL */
16389 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16391 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16394 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16397 case MOVZ
: /* MUH */
16398 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16400 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16403 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16407 check_insn(ctx
, ISA_MIPS32R6
);
16408 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16411 check_insn(ctx
, ISA_MIPS32R6
);
16412 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16414 case LWXS
: /* DIV */
16415 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16417 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16420 gen_ldxs(ctx
, rs
, rt
, rd
);
16424 check_insn(ctx
, ISA_MIPS32R6
);
16425 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16428 check_insn(ctx
, ISA_MIPS32R6
);
16429 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16432 check_insn(ctx
, ISA_MIPS32R6
);
16433 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16436 goto pool32a_invalid
;
16440 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16443 check_insn(ctx
, ISA_MIPS32R6
);
16444 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
16445 extract32(ctx
->opcode
, 9, 2));
16448 check_insn(ctx
, ISA_MIPS32R6
);
16449 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16452 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16455 gen_pool32axf(env
, ctx
, rt
, rs
);
16458 generate_exception_end(ctx
, EXCP_BREAK
);
16461 check_insn(ctx
, ISA_MIPS32R6
);
16462 generate_exception_end(ctx
, EXCP_RI
);
16466 MIPS_INVAL("pool32a");
16467 generate_exception_end(ctx
, EXCP_RI
);
16472 minor
= (ctx
->opcode
>> 12) & 0xf;
16475 check_cp0_enabled(ctx
);
16476 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16477 gen_cache_operation(ctx
, rt
, rs
, imm
);
16482 /* COP2: Not implemented. */
16483 generate_exception_err(ctx
, EXCP_CpU
, 2);
16485 #ifdef TARGET_MIPS64
16488 check_insn(ctx
, ISA_MIPS3
);
16489 check_mips_64(ctx
);
16494 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16496 #ifdef TARGET_MIPS64
16499 check_insn(ctx
, ISA_MIPS3
);
16500 check_mips_64(ctx
);
16505 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16508 MIPS_INVAL("pool32b");
16509 generate_exception_end(ctx
, EXCP_RI
);
16514 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16515 minor
= ctx
->opcode
& 0x3f;
16516 check_cp1_enabled(ctx
);
16519 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16520 mips32_op
= OPC_ALNV_PS
;
16523 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16524 mips32_op
= OPC_MADD_S
;
16527 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16528 mips32_op
= OPC_MADD_D
;
16531 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16532 mips32_op
= OPC_MADD_PS
;
16535 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16536 mips32_op
= OPC_MSUB_S
;
16539 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16540 mips32_op
= OPC_MSUB_D
;
16543 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16544 mips32_op
= OPC_MSUB_PS
;
16547 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16548 mips32_op
= OPC_NMADD_S
;
16551 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16552 mips32_op
= OPC_NMADD_D
;
16555 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16556 mips32_op
= OPC_NMADD_PS
;
16559 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16560 mips32_op
= OPC_NMSUB_S
;
16563 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16564 mips32_op
= OPC_NMSUB_D
;
16567 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16568 mips32_op
= OPC_NMSUB_PS
;
16570 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
16572 case CABS_COND_FMT
:
16573 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16574 cond
= (ctx
->opcode
>> 6) & 0xf;
16575 cc
= (ctx
->opcode
>> 13) & 0x7;
16576 fmt
= (ctx
->opcode
>> 10) & 0x3;
16579 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
16582 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
16585 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
16588 goto pool32f_invalid
;
16592 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16593 cond
= (ctx
->opcode
>> 6) & 0xf;
16594 cc
= (ctx
->opcode
>> 13) & 0x7;
16595 fmt
= (ctx
->opcode
>> 10) & 0x3;
16598 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
16601 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
16604 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
16607 goto pool32f_invalid
;
16611 check_insn(ctx
, ISA_MIPS32R6
);
16612 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16615 check_insn(ctx
, ISA_MIPS32R6
);
16616 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16619 gen_pool32fxf(ctx
, rt
, rs
);
16623 switch ((ctx
->opcode
>> 6) & 0x7) {
16625 mips32_op
= OPC_PLL_PS
;
16628 mips32_op
= OPC_PLU_PS
;
16631 mips32_op
= OPC_PUL_PS
;
16634 mips32_op
= OPC_PUU_PS
;
16637 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16638 mips32_op
= OPC_CVT_PS_S
;
16640 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16643 goto pool32f_invalid
;
16647 check_insn(ctx
, ISA_MIPS32R6
);
16648 switch ((ctx
->opcode
>> 9) & 0x3) {
16650 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
16653 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
16656 goto pool32f_invalid
;
16661 switch ((ctx
->opcode
>> 6) & 0x7) {
16663 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16664 mips32_op
= OPC_LWXC1
;
16667 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16668 mips32_op
= OPC_SWXC1
;
16671 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16672 mips32_op
= OPC_LDXC1
;
16675 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16676 mips32_op
= OPC_SDXC1
;
16679 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16680 mips32_op
= OPC_LUXC1
;
16683 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16684 mips32_op
= OPC_SUXC1
;
16686 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
16689 goto pool32f_invalid
;
16693 check_insn(ctx
, ISA_MIPS32R6
);
16694 switch ((ctx
->opcode
>> 9) & 0x3) {
16696 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
16699 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
16702 goto pool32f_invalid
;
16707 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16708 fmt
= (ctx
->opcode
>> 9) & 0x3;
16709 switch ((ctx
->opcode
>> 6) & 0x7) {
16713 mips32_op
= OPC_RSQRT2_S
;
16716 mips32_op
= OPC_RSQRT2_D
;
16719 mips32_op
= OPC_RSQRT2_PS
;
16722 goto pool32f_invalid
;
16728 mips32_op
= OPC_RECIP2_S
;
16731 mips32_op
= OPC_RECIP2_D
;
16734 mips32_op
= OPC_RECIP2_PS
;
16737 goto pool32f_invalid
;
16741 mips32_op
= OPC_ADDR_PS
;
16744 mips32_op
= OPC_MULR_PS
;
16746 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16749 goto pool32f_invalid
;
16753 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16754 cc
= (ctx
->opcode
>> 13) & 0x7;
16755 fmt
= (ctx
->opcode
>> 9) & 0x3;
16756 switch ((ctx
->opcode
>> 6) & 0x7) {
16757 case MOVF_FMT
: /* RINT_FMT */
16758 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16762 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
16765 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
16768 goto pool32f_invalid
;
16774 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
16777 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
16781 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
16784 goto pool32f_invalid
;
16788 case MOVT_FMT
: /* CLASS_FMT */
16789 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16793 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
16796 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
16799 goto pool32f_invalid
;
16805 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
16808 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
16812 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
16815 goto pool32f_invalid
;
16820 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16823 goto pool32f_invalid
;
16826 #define FINSN_3ARG_SDPS(prfx) \
16827 switch ((ctx->opcode >> 8) & 0x3) { \
16829 mips32_op = OPC_##prfx##_S; \
16832 mips32_op = OPC_##prfx##_D; \
16834 case FMT_SDPS_PS: \
16836 mips32_op = OPC_##prfx##_PS; \
16839 goto pool32f_invalid; \
16842 check_insn(ctx
, ISA_MIPS32R6
);
16843 switch ((ctx
->opcode
>> 9) & 0x3) {
16845 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
16848 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
16851 goto pool32f_invalid
;
16855 check_insn(ctx
, ISA_MIPS32R6
);
16856 switch ((ctx
->opcode
>> 9) & 0x3) {
16858 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
16861 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
16864 goto pool32f_invalid
;
16868 /* regular FP ops */
16869 switch ((ctx
->opcode
>> 6) & 0x3) {
16871 FINSN_3ARG_SDPS(ADD
);
16874 FINSN_3ARG_SDPS(SUB
);
16877 FINSN_3ARG_SDPS(MUL
);
16880 fmt
= (ctx
->opcode
>> 8) & 0x3;
16882 mips32_op
= OPC_DIV_D
;
16883 } else if (fmt
== 0) {
16884 mips32_op
= OPC_DIV_S
;
16886 goto pool32f_invalid
;
16890 goto pool32f_invalid
;
16895 switch ((ctx
->opcode
>> 6) & 0x7) {
16896 case MOVN_FMT
: /* SELEQZ_FMT */
16897 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16899 switch ((ctx
->opcode
>> 9) & 0x3) {
16901 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
16904 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
16907 goto pool32f_invalid
;
16911 FINSN_3ARG_SDPS(MOVN
);
16915 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16916 FINSN_3ARG_SDPS(MOVN
);
16918 case MOVZ_FMT
: /* SELNEZ_FMT */
16919 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16921 switch ((ctx
->opcode
>> 9) & 0x3) {
16923 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
16926 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
16929 goto pool32f_invalid
;
16933 FINSN_3ARG_SDPS(MOVZ
);
16937 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16938 FINSN_3ARG_SDPS(MOVZ
);
16941 check_insn(ctx
, ISA_MIPS32R6
);
16942 switch ((ctx
->opcode
>> 9) & 0x3) {
16944 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
16947 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
16950 goto pool32f_invalid
;
16954 check_insn(ctx
, ISA_MIPS32R6
);
16955 switch ((ctx
->opcode
>> 9) & 0x3) {
16957 mips32_op
= OPC_MADDF_S
;
16960 mips32_op
= OPC_MADDF_D
;
16963 goto pool32f_invalid
;
16967 check_insn(ctx
, ISA_MIPS32R6
);
16968 switch ((ctx
->opcode
>> 9) & 0x3) {
16970 mips32_op
= OPC_MSUBF_S
;
16973 mips32_op
= OPC_MSUBF_D
;
16976 goto pool32f_invalid
;
16980 goto pool32f_invalid
;
16984 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16988 MIPS_INVAL("pool32f");
16989 generate_exception_end(ctx
, EXCP_RI
);
16993 generate_exception_err(ctx
, EXCP_CpU
, 1);
16997 minor
= (ctx
->opcode
>> 21) & 0x1f;
17000 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17001 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
17004 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17005 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
17006 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17009 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17010 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
17011 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17014 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17015 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
17018 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17019 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
17020 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17023 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17024 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
17025 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17028 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17029 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
17032 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17033 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
17037 case TLTI
: /* BC1EQZC */
17038 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17040 check_cp1_enabled(ctx
);
17041 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
17044 mips32_op
= OPC_TLTI
;
17048 case TGEI
: /* BC1NEZC */
17049 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17051 check_cp1_enabled(ctx
);
17052 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
17055 mips32_op
= OPC_TGEI
;
17060 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17061 mips32_op
= OPC_TLTIU
;
17064 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17065 mips32_op
= OPC_TGEIU
;
17067 case TNEI
: /* SYNCI */
17068 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17071 * Break the TB to be able to sync copied instructions
17074 ctx
->base
.is_jmp
= DISAS_STOP
;
17077 mips32_op
= OPC_TNEI
;
17082 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17083 mips32_op
= OPC_TEQI
;
17085 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
17090 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17091 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
17092 4, rs
, 0, imm
<< 1, 0);
17094 * Compact branches don't have a delay slot, so just let
17095 * the normal delay slot handling take us to the branch
17100 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17101 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
17104 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17106 * Break the TB to be able to sync copied instructions
17109 ctx
->base
.is_jmp
= DISAS_STOP
;
17113 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17114 /* COP2: Not implemented. */
17115 generate_exception_err(ctx
, EXCP_CpU
, 2);
17118 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17119 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
17122 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17123 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
17126 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17127 mips32_op
= OPC_BC1FANY4
;
17130 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17131 mips32_op
= OPC_BC1TANY4
;
17134 check_insn(ctx
, ASE_MIPS3D
);
17137 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17138 check_cp1_enabled(ctx
);
17139 gen_compute_branch1(ctx
, mips32_op
,
17140 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
17142 generate_exception_err(ctx
, EXCP_CpU
, 1);
17147 /* MIPS DSP: not implemented */
17150 MIPS_INVAL("pool32i");
17151 generate_exception_end(ctx
, EXCP_RI
);
17156 minor
= (ctx
->opcode
>> 12) & 0xf;
17157 offset
= sextract32(ctx
->opcode
, 0,
17158 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
17161 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17162 mips32_op
= OPC_LWL
;
17165 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17166 mips32_op
= OPC_SWL
;
17169 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17170 mips32_op
= OPC_LWR
;
17173 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17174 mips32_op
= OPC_SWR
;
17176 #if defined(TARGET_MIPS64)
17178 check_insn(ctx
, ISA_MIPS3
);
17179 check_mips_64(ctx
);
17180 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17181 mips32_op
= OPC_LDL
;
17184 check_insn(ctx
, ISA_MIPS3
);
17185 check_mips_64(ctx
);
17186 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17187 mips32_op
= OPC_SDL
;
17190 check_insn(ctx
, ISA_MIPS3
);
17191 check_mips_64(ctx
);
17192 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17193 mips32_op
= OPC_LDR
;
17196 check_insn(ctx
, ISA_MIPS3
);
17197 check_mips_64(ctx
);
17198 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17199 mips32_op
= OPC_SDR
;
17202 check_insn(ctx
, ISA_MIPS3
);
17203 check_mips_64(ctx
);
17204 mips32_op
= OPC_LWU
;
17207 check_insn(ctx
, ISA_MIPS3
);
17208 check_mips_64(ctx
);
17209 mips32_op
= OPC_LLD
;
17213 mips32_op
= OPC_LL
;
17216 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17219 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17222 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17224 #if defined(TARGET_MIPS64)
17226 check_insn(ctx
, ISA_MIPS3
);
17227 check_mips_64(ctx
);
17228 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17233 MIPS_INVAL("pool32c ld-eva");
17234 generate_exception_end(ctx
, EXCP_RI
);
17237 check_cp0_enabled(ctx
);
17239 minor2
= (ctx
->opcode
>> 9) & 0x7;
17240 offset
= sextract32(ctx
->opcode
, 0, 9);
17243 mips32_op
= OPC_LBUE
;
17246 mips32_op
= OPC_LHUE
;
17249 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17250 mips32_op
= OPC_LWLE
;
17253 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17254 mips32_op
= OPC_LWRE
;
17257 mips32_op
= OPC_LBE
;
17260 mips32_op
= OPC_LHE
;
17263 mips32_op
= OPC_LLE
;
17266 mips32_op
= OPC_LWE
;
17272 MIPS_INVAL("pool32c st-eva");
17273 generate_exception_end(ctx
, EXCP_RI
);
17276 check_cp0_enabled(ctx
);
17278 minor2
= (ctx
->opcode
>> 9) & 0x7;
17279 offset
= sextract32(ctx
->opcode
, 0, 9);
17282 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17283 mips32_op
= OPC_SWLE
;
17286 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17287 mips32_op
= OPC_SWRE
;
17290 /* Treat as no-op */
17291 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17292 /* hint codes 24-31 are reserved and signal RI */
17293 generate_exception(ctx
, EXCP_RI
);
17297 /* Treat as no-op */
17298 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17299 gen_cache_operation(ctx
, rt
, rs
, offset
);
17303 mips32_op
= OPC_SBE
;
17306 mips32_op
= OPC_SHE
;
17309 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17312 mips32_op
= OPC_SWE
;
17317 /* Treat as no-op */
17318 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17319 /* hint codes 24-31 are reserved and signal RI */
17320 generate_exception(ctx
, EXCP_RI
);
17324 MIPS_INVAL("pool32c");
17325 generate_exception_end(ctx
, EXCP_RI
);
17329 case ADDI32
: /* AUI, LUI */
17330 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17332 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17335 mips32_op
= OPC_ADDI
;
17340 mips32_op
= OPC_ADDIU
;
17342 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17345 /* Logical operations */
17347 mips32_op
= OPC_ORI
;
17350 mips32_op
= OPC_XORI
;
17353 mips32_op
= OPC_ANDI
;
17355 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17358 /* Set less than immediate */
17360 mips32_op
= OPC_SLTI
;
17363 mips32_op
= OPC_SLTIU
;
17365 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17368 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17369 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17370 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17371 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17373 case JALS32
: /* BOVC, BEQC, BEQZALC */
17374 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17377 mips32_op
= OPC_BOVC
;
17378 } else if (rs
< rt
&& rs
== 0) {
17380 mips32_op
= OPC_BEQZALC
;
17383 mips32_op
= OPC_BEQC
;
17385 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17388 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17389 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17390 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17393 case BEQ32
: /* BC */
17394 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17396 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17397 sextract32(ctx
->opcode
<< 1, 0, 27));
17400 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17403 case BNE32
: /* BALC */
17404 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17406 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17407 sextract32(ctx
->opcode
<< 1, 0, 27));
17410 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17413 case J32
: /* BGTZC, BLTZC, BLTC */
17414 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17415 if (rs
== 0 && rt
!= 0) {
17417 mips32_op
= OPC_BGTZC
;
17418 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17420 mips32_op
= OPC_BLTZC
;
17423 mips32_op
= OPC_BLTC
;
17425 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17428 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17429 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17432 case JAL32
: /* BLEZC, BGEZC, BGEC */
17433 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17434 if (rs
== 0 && rt
!= 0) {
17436 mips32_op
= OPC_BLEZC
;
17437 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17439 mips32_op
= OPC_BGEZC
;
17442 mips32_op
= OPC_BGEC
;
17444 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17447 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17448 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17449 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17452 /* Floating point (COP1) */
17454 mips32_op
= OPC_LWC1
;
17457 mips32_op
= OPC_LDC1
;
17460 mips32_op
= OPC_SWC1
;
17463 mips32_op
= OPC_SDC1
;
17465 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17467 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17468 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17469 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17470 switch ((ctx
->opcode
>> 16) & 0x1f) {
17479 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17482 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17485 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17495 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17498 generate_exception(ctx
, EXCP_RI
);
17503 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17504 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17506 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17509 case BNVC
: /* BNEC, BNEZALC */
17510 check_insn(ctx
, ISA_MIPS32R6
);
17513 mips32_op
= OPC_BNVC
;
17514 } else if (rs
< rt
&& rs
== 0) {
17516 mips32_op
= OPC_BNEZALC
;
17519 mips32_op
= OPC_BNEC
;
17521 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17523 case R6_BNEZC
: /* JIALC */
17524 check_insn(ctx
, ISA_MIPS32R6
);
17527 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17528 sextract32(ctx
->opcode
<< 1, 0, 22));
17531 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17534 case R6_BEQZC
: /* JIC */
17535 check_insn(ctx
, ISA_MIPS32R6
);
17538 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17539 sextract32(ctx
->opcode
<< 1, 0, 22));
17542 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17545 case BLEZALC
: /* BGEZALC, BGEUC */
17546 check_insn(ctx
, ISA_MIPS32R6
);
17547 if (rs
== 0 && rt
!= 0) {
17549 mips32_op
= OPC_BLEZALC
;
17550 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17552 mips32_op
= OPC_BGEZALC
;
17555 mips32_op
= OPC_BGEUC
;
17557 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17559 case BGTZALC
: /* BLTZALC, BLTUC */
17560 check_insn(ctx
, ISA_MIPS32R6
);
17561 if (rs
== 0 && rt
!= 0) {
17563 mips32_op
= OPC_BGTZALC
;
17564 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17566 mips32_op
= OPC_BLTZALC
;
17569 mips32_op
= OPC_BLTUC
;
17571 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17573 /* Loads and stores */
17575 mips32_op
= OPC_LB
;
17578 mips32_op
= OPC_LBU
;
17581 mips32_op
= OPC_LH
;
17584 mips32_op
= OPC_LHU
;
17587 mips32_op
= OPC_LW
;
17589 #ifdef TARGET_MIPS64
17591 check_insn(ctx
, ISA_MIPS3
);
17592 check_mips_64(ctx
);
17593 mips32_op
= OPC_LD
;
17596 check_insn(ctx
, ISA_MIPS3
);
17597 check_mips_64(ctx
);
17598 mips32_op
= OPC_SD
;
17602 mips32_op
= OPC_SB
;
17605 mips32_op
= OPC_SH
;
17608 mips32_op
= OPC_SW
;
17611 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
17614 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
17617 generate_exception_end(ctx
, EXCP_RI
);
17622 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
17626 /* make sure instructions are on a halfword boundary */
17627 if (ctx
->base
.pc_next
& 0x1) {
17628 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
17629 generate_exception_end(ctx
, EXCP_AdEL
);
17633 op
= (ctx
->opcode
>> 10) & 0x3f;
17634 /* Enforce properly-sized instructions in a delay slot */
17635 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
17636 switch (op
& 0x7) { /* MSB-3..MSB-5 */
17638 /* POOL32A, POOL32B, POOL32I, POOL32C */
17640 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17642 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17644 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17646 /* LB32, LH32, LWC132, LDC132, LW32 */
17647 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
17648 generate_exception_end(ctx
, EXCP_RI
);
17653 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17655 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17657 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17658 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
17659 generate_exception_end(ctx
, EXCP_RI
);
17669 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17670 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
17671 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
17674 switch (ctx
->opcode
& 0x1) {
17682 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17684 * In the Release 6, the register number location in
17685 * the instruction encoding has changed.
17687 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
17689 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
17695 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17696 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
17697 int amount
= (ctx
->opcode
>> 1) & 0x7;
17699 amount
= amount
== 0 ? 8 : amount
;
17701 switch (ctx
->opcode
& 0x1) {
17710 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
17714 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17715 gen_pool16c_r6_insn(ctx
);
17717 gen_pool16c_insn(ctx
);
17722 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17723 int rb
= 28; /* GP */
17724 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
17726 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17730 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17731 if (ctx
->opcode
& 1) {
17732 generate_exception_end(ctx
, EXCP_RI
);
17735 int enc_dest
= uMIPS_RD(ctx
->opcode
);
17736 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
17737 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
17738 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
17743 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17744 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17745 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17746 offset
= (offset
== 0xf ? -1 : offset
);
17748 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
17753 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17754 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17755 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17757 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
17762 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17763 int rb
= 29; /* SP */
17764 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17766 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17771 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17772 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17773 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17775 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17780 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17781 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17782 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17784 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
17789 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17790 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17791 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17793 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
17798 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17799 int rb
= 29; /* SP */
17800 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17802 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17807 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17808 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17809 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17811 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17816 int rd
= uMIPS_RD5(ctx
->opcode
);
17817 int rs
= uMIPS_RS5(ctx
->opcode
);
17819 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
17826 switch (ctx
->opcode
& 0x1) {
17836 switch (ctx
->opcode
& 0x1) {
17841 gen_addiur1sp(ctx
);
17845 case B16
: /* BC16 */
17846 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
17847 sextract32(ctx
->opcode
, 0, 10) << 1,
17848 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
17850 case BNEZ16
: /* BNEZC16 */
17851 case BEQZ16
: /* BEQZC16 */
17852 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
17853 mmreg(uMIPS_RD(ctx
->opcode
)),
17854 0, sextract32(ctx
->opcode
, 0, 7) << 1,
17855 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
17860 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
17861 int imm
= ZIMM(ctx
->opcode
, 0, 7);
17863 imm
= (imm
== 0x7f ? -1 : imm
);
17864 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
17870 generate_exception_end(ctx
, EXCP_RI
);
17873 decode_micromips32_opc(env
, ctx
);
17886 /* MAJOR, P16, and P32 pools opcodes */
17890 NM_MOVE_BALC
= 0x02,
17898 NM_P16_SHIFT
= 0x0c,
17916 NM_P_LS_U12
= 0x21,
17926 NM_P16_ADDU
= 0x2c,
17940 NM_MOVEPREV
= 0x3f,
17943 /* POOL32A instruction pool */
17945 NM_POOL32A0
= 0x00,
17946 NM_SPECIAL2
= 0x01,
17949 NM_POOL32A5
= 0x05,
17950 NM_POOL32A7
= 0x07,
17953 /* P.GP.W instruction pool */
17955 NM_ADDIUGP_W
= 0x00,
17960 /* P48I instruction pool */
17964 NM_ADDIUGP48
= 0x02,
17965 NM_ADDIUPC48
= 0x03,
17970 /* P.U12 instruction pool */
17979 NM_ADDIUNEG
= 0x08,
17986 /* POOL32F instruction pool */
17988 NM_POOL32F_0
= 0x00,
17989 NM_POOL32F_3
= 0x03,
17990 NM_POOL32F_5
= 0x05,
17993 /* POOL32S instruction pool */
17995 NM_POOL32S_0
= 0x00,
17996 NM_POOL32S_4
= 0x04,
17999 /* P.LUI instruction pool */
18005 /* P.GP.BH instruction pool */
18010 NM_ADDIUGP_B
= 0x03,
18013 NM_P_GP_CP1
= 0x06,
18016 /* P.LS.U12 instruction pool */
18021 NM_P_PREFU12
= 0x03,
18034 /* P.LS.S9 instruction pool */
18040 NM_P_LS_UAWM
= 0x05,
18043 /* P.BAL instruction pool */
18049 /* P.J instruction pool */
18052 NM_JALRC_HB
= 0x01,
18053 NM_P_BALRSC
= 0x08,
18056 /* P.BR1 instruction pool */
18064 /* P.BR2 instruction pool */
18071 /* P.BRI instruction pool */
18083 /* P16.SHIFT instruction pool */
18089 /* POOL16C instruction pool */
18091 NM_POOL16C_0
= 0x00,
18095 /* P16.A1 instruction pool */
18097 NM_ADDIUR1SP
= 0x01,
18100 /* P16.A2 instruction pool */
18103 NM_P_ADDIURS5
= 0x01,
18106 /* P16.ADDU instruction pool */
18112 /* P16.SR instruction pool */
18115 NM_RESTORE_JRC16
= 0x01,
18118 /* P16.4X4 instruction pool */
18124 /* P16.LB instruction pool */
18131 /* P16.LH instruction pool */
18138 /* P.RI instruction pool */
18141 NM_P_SYSCALL
= 0x01,
18146 /* POOL32A0 instruction pool */
18181 NM_D_E_MT_VPE
= 0x56,
18189 /* CRC32 instruction pool */
18199 /* POOL32A5 instruction pool */
18201 NM_CMP_EQ_PH
= 0x00,
18202 NM_CMP_LT_PH
= 0x08,
18203 NM_CMP_LE_PH
= 0x10,
18204 NM_CMPGU_EQ_QB
= 0x18,
18205 NM_CMPGU_LT_QB
= 0x20,
18206 NM_CMPGU_LE_QB
= 0x28,
18207 NM_CMPGDU_EQ_QB
= 0x30,
18208 NM_CMPGDU_LT_QB
= 0x38,
18209 NM_CMPGDU_LE_QB
= 0x40,
18210 NM_CMPU_EQ_QB
= 0x48,
18211 NM_CMPU_LT_QB
= 0x50,
18212 NM_CMPU_LE_QB
= 0x58,
18213 NM_ADDQ_S_W
= 0x60,
18214 NM_SUBQ_S_W
= 0x68,
18218 NM_ADDQ_S_PH
= 0x01,
18219 NM_ADDQH_R_PH
= 0x09,
18220 NM_ADDQH_R_W
= 0x11,
18221 NM_ADDU_S_QB
= 0x19,
18222 NM_ADDU_S_PH
= 0x21,
18223 NM_ADDUH_R_QB
= 0x29,
18224 NM_SHRAV_R_PH
= 0x31,
18225 NM_SHRAV_R_QB
= 0x39,
18226 NM_SUBQ_S_PH
= 0x41,
18227 NM_SUBQH_R_PH
= 0x49,
18228 NM_SUBQH_R_W
= 0x51,
18229 NM_SUBU_S_QB
= 0x59,
18230 NM_SUBU_S_PH
= 0x61,
18231 NM_SUBUH_R_QB
= 0x69,
18232 NM_SHLLV_S_PH
= 0x71,
18233 NM_PRECR_SRA_R_PH_W
= 0x79,
18235 NM_MULEU_S_PH_QBL
= 0x12,
18236 NM_MULEU_S_PH_QBR
= 0x1a,
18237 NM_MULQ_RS_PH
= 0x22,
18238 NM_MULQ_S_PH
= 0x2a,
18239 NM_MULQ_RS_W
= 0x32,
18240 NM_MULQ_S_W
= 0x3a,
18243 NM_SHRAV_R_W
= 0x5a,
18244 NM_SHRLV_PH
= 0x62,
18245 NM_SHRLV_QB
= 0x6a,
18246 NM_SHLLV_QB
= 0x72,
18247 NM_SHLLV_S_W
= 0x7a,
18251 NM_MULEQ_S_W_PHL
= 0x04,
18252 NM_MULEQ_S_W_PHR
= 0x0c,
18254 NM_MUL_S_PH
= 0x05,
18255 NM_PRECR_QB_PH
= 0x0d,
18256 NM_PRECRQ_QB_PH
= 0x15,
18257 NM_PRECRQ_PH_W
= 0x1d,
18258 NM_PRECRQ_RS_PH_W
= 0x25,
18259 NM_PRECRQU_S_QB_PH
= 0x2d,
18260 NM_PACKRL_PH
= 0x35,
18264 NM_SHRA_R_W
= 0x5e,
18265 NM_SHRA_R_PH
= 0x66,
18266 NM_SHLL_S_PH
= 0x76,
18267 NM_SHLL_S_W
= 0x7e,
18272 /* POOL32A7 instruction pool */
18277 NM_POOL32AXF
= 0x07,
18280 /* P.SR instruction pool */
18286 /* P.SHIFT instruction pool */
18294 /* P.ROTX instruction pool */
18299 /* P.INS instruction pool */
18304 /* P.EXT instruction pool */
18309 /* POOL32F_0 (fmt) instruction pool */
18314 NM_SELEQZ_S
= 0x07,
18315 NM_SELEQZ_D
= 0x47,
18319 NM_SELNEZ_S
= 0x0f,
18320 NM_SELNEZ_D
= 0x4f,
18335 /* POOL32F_3 instruction pool */
18339 NM_MINA_FMT
= 0x04,
18340 NM_MAXA_FMT
= 0x05,
18341 NM_POOL32FXF
= 0x07,
18344 /* POOL32F_5 instruction pool */
18346 NM_CMP_CONDN_S
= 0x00,
18347 NM_CMP_CONDN_D
= 0x02,
18350 /* P.GP.LH instruction pool */
18356 /* P.GP.SH instruction pool */
18361 /* P.GP.CP1 instruction pool */
18369 /* P.LS.S0 instruction pool */
18386 NM_P_PREFS9
= 0x03,
18392 /* P.LS.S1 instruction pool */
18394 NM_ASET_ACLR
= 0x02,
18402 /* P.LS.E0 instruction pool */
18418 /* P.PREFE instruction pool */
18424 /* P.LLE instruction pool */
18430 /* P.SCE instruction pool */
18436 /* P.LS.WM instruction pool */
18442 /* P.LS.UAWM instruction pool */
18448 /* P.BR3A instruction pool */
18454 NM_BPOSGE32C
= 0x04,
18457 /* P16.RI instruction pool */
18459 NM_P16_SYSCALL
= 0x01,
18464 /* POOL16C_0 instruction pool */
18466 NM_POOL16C_00
= 0x00,
18469 /* P16.JRC instruction pool */
18475 /* P.SYSCALL instruction pool */
18481 /* P.TRAP instruction pool */
18487 /* P.CMOVE instruction pool */
18493 /* POOL32Axf instruction pool */
18495 NM_POOL32AXF_1
= 0x01,
18496 NM_POOL32AXF_2
= 0x02,
18497 NM_POOL32AXF_4
= 0x04,
18498 NM_POOL32AXF_5
= 0x05,
18499 NM_POOL32AXF_7
= 0x07,
18502 /* POOL32Axf_1 instruction pool */
18504 NM_POOL32AXF_1_0
= 0x00,
18505 NM_POOL32AXF_1_1
= 0x01,
18506 NM_POOL32AXF_1_3
= 0x03,
18507 NM_POOL32AXF_1_4
= 0x04,
18508 NM_POOL32AXF_1_5
= 0x05,
18509 NM_POOL32AXF_1_7
= 0x07,
18512 /* POOL32Axf_2 instruction pool */
18514 NM_POOL32AXF_2_0_7
= 0x00,
18515 NM_POOL32AXF_2_8_15
= 0x01,
18516 NM_POOL32AXF_2_16_23
= 0x02,
18517 NM_POOL32AXF_2_24_31
= 0x03,
18520 /* POOL32Axf_7 instruction pool */
18522 NM_SHRA_R_QB
= 0x0,
18527 /* POOL32Axf_1_0 instruction pool */
18535 /* POOL32Axf_1_1 instruction pool */
18541 /* POOL32Axf_1_3 instruction pool */
18549 /* POOL32Axf_1_4 instruction pool */
18555 /* POOL32Axf_1_5 instruction pool */
18557 NM_MAQ_S_W_PHR
= 0x0,
18558 NM_MAQ_S_W_PHL
= 0x1,
18559 NM_MAQ_SA_W_PHR
= 0x2,
18560 NM_MAQ_SA_W_PHL
= 0x3,
18563 /* POOL32Axf_1_7 instruction pool */
18567 NM_EXTR_RS_W
= 0x2,
18571 /* POOL32Axf_2_0_7 instruction pool */
18574 NM_DPAQ_S_W_PH
= 0x1,
18576 NM_DPSQ_S_W_PH
= 0x3,
18583 /* POOL32Axf_2_8_15 instruction pool */
18585 NM_DPAX_W_PH
= 0x0,
18586 NM_DPAQ_SA_L_W
= 0x1,
18587 NM_DPSX_W_PH
= 0x2,
18588 NM_DPSQ_SA_L_W
= 0x3,
18591 NM_EXTRV_R_W
= 0x7,
18594 /* POOL32Axf_2_16_23 instruction pool */
18596 NM_DPAU_H_QBL
= 0x0,
18597 NM_DPAQX_S_W_PH
= 0x1,
18598 NM_DPSU_H_QBL
= 0x2,
18599 NM_DPSQX_S_W_PH
= 0x3,
18602 NM_MULSA_W_PH
= 0x6,
18603 NM_EXTRV_RS_W
= 0x7,
18606 /* POOL32Axf_2_24_31 instruction pool */
18608 NM_DPAU_H_QBR
= 0x0,
18609 NM_DPAQX_SA_W_PH
= 0x1,
18610 NM_DPSU_H_QBR
= 0x2,
18611 NM_DPSQX_SA_W_PH
= 0x3,
18614 NM_MULSAQ_S_W_PH
= 0x6,
18615 NM_EXTRV_S_H
= 0x7,
18618 /* POOL32Axf_{4, 5} instruction pool */
18637 /* nanoMIPS DSP instructions */
18638 NM_ABSQ_S_QB
= 0x00,
18639 NM_ABSQ_S_PH
= 0x08,
18640 NM_ABSQ_S_W
= 0x10,
18641 NM_PRECEQ_W_PHL
= 0x28,
18642 NM_PRECEQ_W_PHR
= 0x30,
18643 NM_PRECEQU_PH_QBL
= 0x38,
18644 NM_PRECEQU_PH_QBR
= 0x48,
18645 NM_PRECEU_PH_QBL
= 0x58,
18646 NM_PRECEU_PH_QBR
= 0x68,
18647 NM_PRECEQU_PH_QBLA
= 0x39,
18648 NM_PRECEQU_PH_QBRA
= 0x49,
18649 NM_PRECEU_PH_QBLA
= 0x59,
18650 NM_PRECEU_PH_QBRA
= 0x69,
18651 NM_REPLV_PH
= 0x01,
18652 NM_REPLV_QB
= 0x09,
18655 NM_RADDU_W_QB
= 0x78,
18661 /* PP.SR instruction pool */
18665 NM_RESTORE_JRC
= 0x03,
18668 /* P.SR.F instruction pool */
18671 NM_RESTOREF
= 0x01,
18674 /* P16.SYSCALL instruction pool */
18676 NM_SYSCALL16
= 0x00,
18677 NM_HYPCALL16
= 0x01,
18680 /* POOL16C_00 instruction pool */
18688 /* PP.LSX and PP.LSXS instruction pool */
18726 /* ERETx instruction pool */
18732 /* POOL32FxF_{0, 1} insturction pool */
18741 NM_CVT_S_PL
= 0x84,
18742 NM_CVT_S_PU
= 0xa4,
18744 NM_CVT_L_S
= 0x004,
18745 NM_CVT_L_D
= 0x104,
18746 NM_CVT_W_S
= 0x024,
18747 NM_CVT_W_D
= 0x124,
18749 NM_RSQRT_S
= 0x008,
18750 NM_RSQRT_D
= 0x108,
18755 NM_RECIP_S
= 0x048,
18756 NM_RECIP_D
= 0x148,
18758 NM_FLOOR_L_S
= 0x00c,
18759 NM_FLOOR_L_D
= 0x10c,
18761 NM_FLOOR_W_S
= 0x02c,
18762 NM_FLOOR_W_D
= 0x12c,
18764 NM_CEIL_L_S
= 0x04c,
18765 NM_CEIL_L_D
= 0x14c,
18766 NM_CEIL_W_S
= 0x06c,
18767 NM_CEIL_W_D
= 0x16c,
18768 NM_TRUNC_L_S
= 0x08c,
18769 NM_TRUNC_L_D
= 0x18c,
18770 NM_TRUNC_W_S
= 0x0ac,
18771 NM_TRUNC_W_D
= 0x1ac,
18772 NM_ROUND_L_S
= 0x0cc,
18773 NM_ROUND_L_D
= 0x1cc,
18774 NM_ROUND_W_S
= 0x0ec,
18775 NM_ROUND_W_D
= 0x1ec,
18783 NM_CVT_D_S
= 0x04d,
18784 NM_CVT_D_W
= 0x0cd,
18785 NM_CVT_D_L
= 0x14d,
18786 NM_CVT_S_D
= 0x06d,
18787 NM_CVT_S_W
= 0x0ed,
18788 NM_CVT_S_L
= 0x16d,
18791 /* P.LL instruction pool */
18797 /* P.SC instruction pool */
18803 /* P.DVP instruction pool */
18812 * nanoMIPS decoding engine
18817 /* extraction utilities */
18819 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18820 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18821 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18822 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18823 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18825 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18826 static inline int decode_gpr_gpr3(int r
)
18828 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18830 return map
[r
& 0x7];
18833 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18834 static inline int decode_gpr_gpr3_src_store(int r
)
18836 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18838 return map
[r
& 0x7];
18841 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18842 static inline int decode_gpr_gpr4(int r
)
18844 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18845 16, 17, 18, 19, 20, 21, 22, 23 };
18847 return map
[r
& 0xf];
18850 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18851 static inline int decode_gpr_gpr4_zero(int r
)
18853 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18854 16, 17, 18, 19, 20, 21, 22, 23 };
18856 return map
[r
& 0xf];
18860 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
18862 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
18865 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18866 uint8_t gp
, uint16_t u
)
18869 TCGv va
= tcg_temp_new();
18870 TCGv t0
= tcg_temp_new();
18872 while (counter
!= count
) {
18873 bool use_gp
= gp
&& (counter
== count
- 1);
18874 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18875 int this_offset
= -((counter
+ 1) << 2);
18876 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18877 gen_load_gpr(t0
, this_rt
);
18878 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
18879 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
18883 /* adjust stack pointer */
18884 gen_adjust_sp(ctx
, -u
);
18890 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18891 uint8_t gp
, uint16_t u
)
18894 TCGv va
= tcg_temp_new();
18895 TCGv t0
= tcg_temp_new();
18897 while (counter
!= count
) {
18898 bool use_gp
= gp
&& (counter
== count
- 1);
18899 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18900 int this_offset
= u
- ((counter
+ 1) << 2);
18901 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18902 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
18903 ctx
->default_tcg_memop_mask
);
18904 tcg_gen_ext32s_tl(t0
, t0
);
18905 gen_store_gpr(t0
, this_rt
);
18909 /* adjust stack pointer */
18910 gen_adjust_sp(ctx
, u
);
18916 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
18918 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
18919 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
18921 switch (extract32(ctx
->opcode
, 2, 2)) {
18923 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
18926 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
18929 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
18932 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
18937 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18939 int rt
= extract32(ctx
->opcode
, 21, 5);
18940 int rs
= extract32(ctx
->opcode
, 16, 5);
18941 int rd
= extract32(ctx
->opcode
, 11, 5);
18943 switch (extract32(ctx
->opcode
, 3, 7)) {
18945 switch (extract32(ctx
->opcode
, 10, 1)) {
18948 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
18952 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
18958 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
18962 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
18965 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
18968 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
18971 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
18974 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
18977 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
18980 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
18983 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
18987 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
18990 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
18993 switch (extract32(ctx
->opcode
, 10, 1)) {
18995 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
18998 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
19003 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
19006 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
19009 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
19012 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
19015 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
19020 #ifndef CONFIG_USER_ONLY
19021 TCGv t0
= tcg_temp_new();
19022 switch (extract32(ctx
->opcode
, 10, 1)) {
19025 check_cp0_enabled(ctx
);
19026 gen_helper_dvp(t0
, cpu_env
);
19027 gen_store_gpr(t0
, rt
);
19032 check_cp0_enabled(ctx
);
19033 gen_helper_evp(t0
, cpu_env
);
19034 gen_store_gpr(t0
, rt
);
19041 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
19046 TCGv t0
= tcg_temp_new();
19047 TCGv t1
= tcg_temp_new();
19048 TCGv t2
= tcg_temp_new();
19050 gen_load_gpr(t1
, rs
);
19051 gen_load_gpr(t2
, rt
);
19052 tcg_gen_add_tl(t0
, t1
, t2
);
19053 tcg_gen_ext32s_tl(t0
, t0
);
19054 tcg_gen_xor_tl(t1
, t1
, t2
);
19055 tcg_gen_xor_tl(t2
, t0
, t2
);
19056 tcg_gen_andc_tl(t1
, t2
, t1
);
19058 /* operands of same sign, result different sign */
19059 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
19060 gen_store_gpr(t0
, rd
);
19068 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
19071 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
19074 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
19077 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
19080 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
19083 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
19086 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
19089 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
19091 #ifndef CONFIG_USER_ONLY
19093 check_cp0_enabled(ctx
);
19095 /* Treat as NOP. */
19098 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
19101 check_cp0_enabled(ctx
);
19103 TCGv t0
= tcg_temp_new();
19105 gen_load_gpr(t0
, rt
);
19106 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
19110 case NM_D_E_MT_VPE
:
19112 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
19113 TCGv t0
= tcg_temp_new();
19120 gen_helper_dmt(t0
);
19121 gen_store_gpr(t0
, rt
);
19122 } else if (rs
== 0) {
19125 gen_helper_dvpe(t0
, cpu_env
);
19126 gen_store_gpr(t0
, rt
);
19128 generate_exception_end(ctx
, EXCP_RI
);
19135 gen_helper_emt(t0
);
19136 gen_store_gpr(t0
, rt
);
19137 } else if (rs
== 0) {
19140 gen_helper_evpe(t0
, cpu_env
);
19141 gen_store_gpr(t0
, rt
);
19143 generate_exception_end(ctx
, EXCP_RI
);
19154 TCGv t0
= tcg_temp_new();
19155 TCGv t1
= tcg_temp_new();
19157 gen_load_gpr(t0
, rt
);
19158 gen_load_gpr(t1
, rs
);
19159 gen_helper_fork(t0
, t1
);
19166 check_cp0_enabled(ctx
);
19168 /* Treat as NOP. */
19171 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19172 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19176 check_cp0_enabled(ctx
);
19177 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19178 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19183 TCGv t0
= tcg_temp_new();
19185 gen_load_gpr(t0
, rs
);
19186 gen_helper_yield(t0
, cpu_env
, t0
);
19187 gen_store_gpr(t0
, rt
);
19193 generate_exception_end(ctx
, EXCP_RI
);
19199 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19200 int ret
, int v1
, int v2
)
19206 t0
= tcg_temp_new_i32();
19208 v0_t
= tcg_temp_new();
19209 v1_t
= tcg_temp_new();
19211 tcg_gen_movi_i32(t0
, v2
>> 3);
19213 gen_load_gpr(v0_t
, ret
);
19214 gen_load_gpr(v1_t
, v1
);
19217 case NM_MAQ_S_W_PHR
:
19219 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19221 case NM_MAQ_S_W_PHL
:
19223 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19225 case NM_MAQ_SA_W_PHR
:
19227 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19229 case NM_MAQ_SA_W_PHL
:
19231 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19234 generate_exception_end(ctx
, EXCP_RI
);
19238 tcg_temp_free_i32(t0
);
19240 tcg_temp_free(v0_t
);
19241 tcg_temp_free(v1_t
);
19245 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19246 int ret
, int v1
, int v2
)
19249 TCGv t0
= tcg_temp_new();
19250 TCGv t1
= tcg_temp_new();
19251 TCGv v0_t
= tcg_temp_new();
19253 gen_load_gpr(v0_t
, v1
);
19256 case NM_POOL32AXF_1_0
:
19258 switch (extract32(ctx
->opcode
, 12, 2)) {
19260 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19263 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19266 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19269 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19273 case NM_POOL32AXF_1_1
:
19275 switch (extract32(ctx
->opcode
, 12, 2)) {
19277 tcg_gen_movi_tl(t0
, v2
);
19278 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19281 tcg_gen_movi_tl(t0
, v2
>> 3);
19282 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19285 generate_exception_end(ctx
, EXCP_RI
);
19289 case NM_POOL32AXF_1_3
:
19291 imm
= extract32(ctx
->opcode
, 14, 7);
19292 switch (extract32(ctx
->opcode
, 12, 2)) {
19294 tcg_gen_movi_tl(t0
, imm
);
19295 gen_helper_rddsp(t0
, t0
, cpu_env
);
19296 gen_store_gpr(t0
, ret
);
19299 gen_load_gpr(t0
, ret
);
19300 tcg_gen_movi_tl(t1
, imm
);
19301 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19304 tcg_gen_movi_tl(t0
, v2
>> 3);
19305 tcg_gen_movi_tl(t1
, v1
);
19306 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19307 gen_store_gpr(t0
, ret
);
19310 tcg_gen_movi_tl(t0
, v2
>> 3);
19311 tcg_gen_movi_tl(t1
, v1
);
19312 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19313 gen_store_gpr(t0
, ret
);
19317 case NM_POOL32AXF_1_4
:
19319 tcg_gen_movi_tl(t0
, v2
>> 2);
19320 switch (extract32(ctx
->opcode
, 12, 1)) {
19322 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19323 gen_store_gpr(t0
, ret
);
19326 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19327 gen_store_gpr(t0
, ret
);
19331 case NM_POOL32AXF_1_5
:
19332 opc
= extract32(ctx
->opcode
, 12, 2);
19333 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19335 case NM_POOL32AXF_1_7
:
19337 tcg_gen_movi_tl(t0
, v2
>> 3);
19338 tcg_gen_movi_tl(t1
, v1
);
19339 switch (extract32(ctx
->opcode
, 12, 2)) {
19341 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19342 gen_store_gpr(t0
, ret
);
19345 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19346 gen_store_gpr(t0
, ret
);
19349 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19350 gen_store_gpr(t0
, ret
);
19353 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19354 gen_store_gpr(t0
, ret
);
19359 generate_exception_end(ctx
, EXCP_RI
);
19365 tcg_temp_free(v0_t
);
19368 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19369 TCGv v0
, TCGv v1
, int rd
)
19373 t0
= tcg_temp_new_i32();
19375 tcg_gen_movi_i32(t0
, rd
>> 3);
19378 case NM_POOL32AXF_2_0_7
:
19379 switch (extract32(ctx
->opcode
, 9, 3)) {
19382 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19384 case NM_DPAQ_S_W_PH
:
19386 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19390 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19392 case NM_DPSQ_S_W_PH
:
19394 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19397 generate_exception_end(ctx
, EXCP_RI
);
19401 case NM_POOL32AXF_2_8_15
:
19402 switch (extract32(ctx
->opcode
, 9, 3)) {
19405 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19407 case NM_DPAQ_SA_L_W
:
19409 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19413 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19415 case NM_DPSQ_SA_L_W
:
19417 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19420 generate_exception_end(ctx
, EXCP_RI
);
19424 case NM_POOL32AXF_2_16_23
:
19425 switch (extract32(ctx
->opcode
, 9, 3)) {
19426 case NM_DPAU_H_QBL
:
19428 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19430 case NM_DPAQX_S_W_PH
:
19432 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19434 case NM_DPSU_H_QBL
:
19436 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19438 case NM_DPSQX_S_W_PH
:
19440 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19442 case NM_MULSA_W_PH
:
19444 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19447 generate_exception_end(ctx
, EXCP_RI
);
19451 case NM_POOL32AXF_2_24_31
:
19452 switch (extract32(ctx
->opcode
, 9, 3)) {
19453 case NM_DPAU_H_QBR
:
19455 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19457 case NM_DPAQX_SA_W_PH
:
19459 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19461 case NM_DPSU_H_QBR
:
19463 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19465 case NM_DPSQX_SA_W_PH
:
19467 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19469 case NM_MULSAQ_S_W_PH
:
19471 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19474 generate_exception_end(ctx
, EXCP_RI
);
19479 generate_exception_end(ctx
, EXCP_RI
);
19483 tcg_temp_free_i32(t0
);
19486 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19487 int rt
, int rs
, int rd
)
19490 TCGv t0
= tcg_temp_new();
19491 TCGv t1
= tcg_temp_new();
19492 TCGv v0_t
= tcg_temp_new();
19493 TCGv v1_t
= tcg_temp_new();
19495 gen_load_gpr(v0_t
, rt
);
19496 gen_load_gpr(v1_t
, rs
);
19499 case NM_POOL32AXF_2_0_7
:
19500 switch (extract32(ctx
->opcode
, 9, 3)) {
19502 case NM_DPAQ_S_W_PH
:
19504 case NM_DPSQ_S_W_PH
:
19505 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19510 gen_load_gpr(t0
, rs
);
19512 if (rd
!= 0 && rd
!= 2) {
19513 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19514 tcg_gen_ext32u_tl(t0
, t0
);
19515 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19516 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19518 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19524 int acc
= extract32(ctx
->opcode
, 14, 2);
19525 TCGv_i64 t2
= tcg_temp_new_i64();
19526 TCGv_i64 t3
= tcg_temp_new_i64();
19528 gen_load_gpr(t0
, rt
);
19529 gen_load_gpr(t1
, rs
);
19530 tcg_gen_ext_tl_i64(t2
, t0
);
19531 tcg_gen_ext_tl_i64(t3
, t1
);
19532 tcg_gen_mul_i64(t2
, t2
, t3
);
19533 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19534 tcg_gen_add_i64(t2
, t2
, t3
);
19535 tcg_temp_free_i64(t3
);
19536 gen_move_low32(cpu_LO
[acc
], t2
);
19537 gen_move_high32(cpu_HI
[acc
], t2
);
19538 tcg_temp_free_i64(t2
);
19544 int acc
= extract32(ctx
->opcode
, 14, 2);
19545 TCGv_i32 t2
= tcg_temp_new_i32();
19546 TCGv_i32 t3
= tcg_temp_new_i32();
19548 gen_load_gpr(t0
, rs
);
19549 gen_load_gpr(t1
, rt
);
19550 tcg_gen_trunc_tl_i32(t2
, t0
);
19551 tcg_gen_trunc_tl_i32(t3
, t1
);
19552 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19553 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19554 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19555 tcg_temp_free_i32(t2
);
19556 tcg_temp_free_i32(t3
);
19561 gen_load_gpr(v1_t
, rs
);
19562 tcg_gen_movi_tl(t0
, rd
>> 3);
19563 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19564 gen_store_gpr(t0
, ret
);
19568 case NM_POOL32AXF_2_8_15
:
19569 switch (extract32(ctx
->opcode
, 9, 3)) {
19571 case NM_DPAQ_SA_L_W
:
19573 case NM_DPSQ_SA_L_W
:
19574 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19579 int acc
= extract32(ctx
->opcode
, 14, 2);
19580 TCGv_i64 t2
= tcg_temp_new_i64();
19581 TCGv_i64 t3
= tcg_temp_new_i64();
19583 gen_load_gpr(t0
, rs
);
19584 gen_load_gpr(t1
, rt
);
19585 tcg_gen_ext32u_tl(t0
, t0
);
19586 tcg_gen_ext32u_tl(t1
, t1
);
19587 tcg_gen_extu_tl_i64(t2
, t0
);
19588 tcg_gen_extu_tl_i64(t3
, t1
);
19589 tcg_gen_mul_i64(t2
, t2
, t3
);
19590 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19591 tcg_gen_add_i64(t2
, t2
, t3
);
19592 tcg_temp_free_i64(t3
);
19593 gen_move_low32(cpu_LO
[acc
], t2
);
19594 gen_move_high32(cpu_HI
[acc
], t2
);
19595 tcg_temp_free_i64(t2
);
19601 int acc
= extract32(ctx
->opcode
, 14, 2);
19602 TCGv_i32 t2
= tcg_temp_new_i32();
19603 TCGv_i32 t3
= tcg_temp_new_i32();
19605 gen_load_gpr(t0
, rs
);
19606 gen_load_gpr(t1
, rt
);
19607 tcg_gen_trunc_tl_i32(t2
, t0
);
19608 tcg_gen_trunc_tl_i32(t3
, t1
);
19609 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
19610 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19611 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19612 tcg_temp_free_i32(t2
);
19613 tcg_temp_free_i32(t3
);
19618 tcg_gen_movi_tl(t0
, rd
>> 3);
19619 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
19620 gen_store_gpr(t0
, ret
);
19623 generate_exception_end(ctx
, EXCP_RI
);
19627 case NM_POOL32AXF_2_16_23
:
19628 switch (extract32(ctx
->opcode
, 9, 3)) {
19629 case NM_DPAU_H_QBL
:
19630 case NM_DPAQX_S_W_PH
:
19631 case NM_DPSU_H_QBL
:
19632 case NM_DPSQX_S_W_PH
:
19633 case NM_MULSA_W_PH
:
19634 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19638 tcg_gen_movi_tl(t0
, rd
>> 3);
19639 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
19640 gen_store_gpr(t0
, ret
);
19645 int acc
= extract32(ctx
->opcode
, 14, 2);
19646 TCGv_i64 t2
= tcg_temp_new_i64();
19647 TCGv_i64 t3
= tcg_temp_new_i64();
19649 gen_load_gpr(t0
, rs
);
19650 gen_load_gpr(t1
, rt
);
19651 tcg_gen_ext_tl_i64(t2
, t0
);
19652 tcg_gen_ext_tl_i64(t3
, t1
);
19653 tcg_gen_mul_i64(t2
, t2
, t3
);
19654 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19655 tcg_gen_sub_i64(t2
, t3
, t2
);
19656 tcg_temp_free_i64(t3
);
19657 gen_move_low32(cpu_LO
[acc
], t2
);
19658 gen_move_high32(cpu_HI
[acc
], t2
);
19659 tcg_temp_free_i64(t2
);
19662 case NM_EXTRV_RS_W
:
19664 tcg_gen_movi_tl(t0
, rd
>> 3);
19665 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
19666 gen_store_gpr(t0
, ret
);
19670 case NM_POOL32AXF_2_24_31
:
19671 switch (extract32(ctx
->opcode
, 9, 3)) {
19672 case NM_DPAU_H_QBR
:
19673 case NM_DPAQX_SA_W_PH
:
19674 case NM_DPSU_H_QBR
:
19675 case NM_DPSQX_SA_W_PH
:
19676 case NM_MULSAQ_S_W_PH
:
19677 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19681 tcg_gen_movi_tl(t0
, rd
>> 3);
19682 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
19683 gen_store_gpr(t0
, ret
);
19688 int acc
= extract32(ctx
->opcode
, 14, 2);
19689 TCGv_i64 t2
= tcg_temp_new_i64();
19690 TCGv_i64 t3
= tcg_temp_new_i64();
19692 gen_load_gpr(t0
, rs
);
19693 gen_load_gpr(t1
, rt
);
19694 tcg_gen_ext32u_tl(t0
, t0
);
19695 tcg_gen_ext32u_tl(t1
, t1
);
19696 tcg_gen_extu_tl_i64(t2
, t0
);
19697 tcg_gen_extu_tl_i64(t3
, t1
);
19698 tcg_gen_mul_i64(t2
, t2
, t3
);
19699 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19700 tcg_gen_sub_i64(t2
, t3
, t2
);
19701 tcg_temp_free_i64(t3
);
19702 gen_move_low32(cpu_LO
[acc
], t2
);
19703 gen_move_high32(cpu_HI
[acc
], t2
);
19704 tcg_temp_free_i64(t2
);
19709 tcg_gen_movi_tl(t0
, rd
>> 3);
19710 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
19711 gen_store_gpr(t0
, ret
);
19716 generate_exception_end(ctx
, EXCP_RI
);
19723 tcg_temp_free(v0_t
);
19724 tcg_temp_free(v1_t
);
19727 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19731 TCGv t0
= tcg_temp_new();
19732 TCGv v0_t
= tcg_temp_new();
19734 gen_load_gpr(v0_t
, rs
);
19739 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
19740 gen_store_gpr(v0_t
, ret
);
19744 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
19745 gen_store_gpr(v0_t
, ret
);
19749 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
19750 gen_store_gpr(v0_t
, ret
);
19752 case NM_PRECEQ_W_PHL
:
19754 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
19755 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19756 gen_store_gpr(v0_t
, ret
);
19758 case NM_PRECEQ_W_PHR
:
19760 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
19761 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
19762 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19763 gen_store_gpr(v0_t
, ret
);
19765 case NM_PRECEQU_PH_QBL
:
19767 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
19768 gen_store_gpr(v0_t
, ret
);
19770 case NM_PRECEQU_PH_QBR
:
19772 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
19773 gen_store_gpr(v0_t
, ret
);
19775 case NM_PRECEQU_PH_QBLA
:
19777 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
19778 gen_store_gpr(v0_t
, ret
);
19780 case NM_PRECEQU_PH_QBRA
:
19782 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
19783 gen_store_gpr(v0_t
, ret
);
19785 case NM_PRECEU_PH_QBL
:
19787 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
19788 gen_store_gpr(v0_t
, ret
);
19790 case NM_PRECEU_PH_QBR
:
19792 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
19793 gen_store_gpr(v0_t
, ret
);
19795 case NM_PRECEU_PH_QBLA
:
19797 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
19798 gen_store_gpr(v0_t
, ret
);
19800 case NM_PRECEU_PH_QBRA
:
19802 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
19803 gen_store_gpr(v0_t
, ret
);
19807 tcg_gen_ext16u_tl(v0_t
, v0_t
);
19808 tcg_gen_shli_tl(t0
, v0_t
, 16);
19809 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19810 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19811 gen_store_gpr(v0_t
, ret
);
19815 tcg_gen_ext8u_tl(v0_t
, v0_t
);
19816 tcg_gen_shli_tl(t0
, v0_t
, 8);
19817 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19818 tcg_gen_shli_tl(t0
, v0_t
, 16);
19819 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19820 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19821 gen_store_gpr(v0_t
, ret
);
19825 gen_helper_bitrev(v0_t
, v0_t
);
19826 gen_store_gpr(v0_t
, ret
);
19831 TCGv tv0
= tcg_temp_new();
19833 gen_load_gpr(tv0
, rt
);
19834 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
19835 gen_store_gpr(v0_t
, ret
);
19836 tcg_temp_free(tv0
);
19839 case NM_RADDU_W_QB
:
19841 gen_helper_raddu_w_qb(v0_t
, v0_t
);
19842 gen_store_gpr(v0_t
, ret
);
19845 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
19849 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
19853 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
19856 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
19859 generate_exception_end(ctx
, EXCP_RI
);
19863 tcg_temp_free(v0_t
);
19867 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19868 int rt
, int rs
, int rd
)
19870 TCGv t0
= tcg_temp_new();
19871 TCGv rs_t
= tcg_temp_new();
19873 gen_load_gpr(rs_t
, rs
);
19878 tcg_gen_movi_tl(t0
, rd
>> 2);
19879 switch (extract32(ctx
->opcode
, 12, 1)) {
19882 gen_helper_shra_qb(t0
, t0
, rs_t
);
19883 gen_store_gpr(t0
, rt
);
19887 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
19888 gen_store_gpr(t0
, rt
);
19894 tcg_gen_movi_tl(t0
, rd
>> 1);
19895 gen_helper_shrl_ph(t0
, t0
, rs_t
);
19896 gen_store_gpr(t0
, rt
);
19902 target_long result
;
19903 imm
= extract32(ctx
->opcode
, 13, 8);
19904 result
= (uint32_t)imm
<< 24 |
19905 (uint32_t)imm
<< 16 |
19906 (uint32_t)imm
<< 8 |
19908 result
= (int32_t)result
;
19909 tcg_gen_movi_tl(t0
, result
);
19910 gen_store_gpr(t0
, rt
);
19914 generate_exception_end(ctx
, EXCP_RI
);
19918 tcg_temp_free(rs_t
);
19922 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19924 int rt
= extract32(ctx
->opcode
, 21, 5);
19925 int rs
= extract32(ctx
->opcode
, 16, 5);
19926 int rd
= extract32(ctx
->opcode
, 11, 5);
19928 switch (extract32(ctx
->opcode
, 6, 3)) {
19929 case NM_POOL32AXF_1
:
19931 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19932 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19935 case NM_POOL32AXF_2
:
19937 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
19938 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19941 case NM_POOL32AXF_4
:
19943 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
19944 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
19947 case NM_POOL32AXF_5
:
19948 switch (extract32(ctx
->opcode
, 9, 7)) {
19949 #ifndef CONFIG_USER_ONLY
19951 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
19954 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
19957 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
19960 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
19963 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
19966 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
19969 check_cp0_enabled(ctx
);
19971 TCGv t0
= tcg_temp_new();
19973 save_cpu_state(ctx
, 1);
19974 gen_helper_di(t0
, cpu_env
);
19975 gen_store_gpr(t0
, rt
);
19976 /* Stop translation as we may have switched the execution mode */
19977 ctx
->base
.is_jmp
= DISAS_STOP
;
19982 check_cp0_enabled(ctx
);
19984 TCGv t0
= tcg_temp_new();
19986 save_cpu_state(ctx
, 1);
19987 gen_helper_ei(t0
, cpu_env
);
19988 gen_store_gpr(t0
, rt
);
19989 /* Stop translation as we may have switched the execution mode */
19990 ctx
->base
.is_jmp
= DISAS_STOP
;
19995 gen_load_srsgpr(rs
, rt
);
19998 gen_store_srsgpr(rs
, rt
);
20001 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
20004 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
20007 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
20011 generate_exception_end(ctx
, EXCP_RI
);
20015 case NM_POOL32AXF_7
:
20017 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20018 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20022 generate_exception_end(ctx
, EXCP_RI
);
20027 /* Immediate Value Compact Branches */
20028 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
20029 int rt
, int32_t imm
, int32_t offset
)
20032 int bcond_compute
= 0;
20033 TCGv t0
= tcg_temp_new();
20034 TCGv t1
= tcg_temp_new();
20036 gen_load_gpr(t0
, rt
);
20037 tcg_gen_movi_tl(t1
, imm
);
20038 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20040 /* Load needed operands and calculate btarget */
20043 if (rt
== 0 && imm
== 0) {
20044 /* Unconditional branch */
20045 } else if (rt
== 0 && imm
!= 0) {
20050 cond
= TCG_COND_EQ
;
20056 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
20057 generate_exception_end(ctx
, EXCP_RI
);
20059 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
20060 /* Unconditional branch */
20061 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
20065 tcg_gen_shri_tl(t0
, t0
, imm
);
20066 tcg_gen_andi_tl(t0
, t0
, 1);
20067 tcg_gen_movi_tl(t1
, 0);
20069 if (opc
== NM_BBEQZC
) {
20070 cond
= TCG_COND_EQ
;
20072 cond
= TCG_COND_NE
;
20077 if (rt
== 0 && imm
== 0) {
20080 } else if (rt
== 0 && imm
!= 0) {
20081 /* Unconditional branch */
20084 cond
= TCG_COND_NE
;
20088 if (rt
== 0 && imm
== 0) {
20089 /* Unconditional branch */
20092 cond
= TCG_COND_GE
;
20097 cond
= TCG_COND_LT
;
20100 if (rt
== 0 && imm
== 0) {
20101 /* Unconditional branch */
20104 cond
= TCG_COND_GEU
;
20109 cond
= TCG_COND_LTU
;
20112 MIPS_INVAL("Immediate Value Compact branch");
20113 generate_exception_end(ctx
, EXCP_RI
);
20117 /* branch completion */
20118 clear_branch_hflags(ctx
);
20119 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20121 if (bcond_compute
== 0) {
20122 /* Uncoditional compact branch */
20123 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20125 /* Conditional compact branch */
20126 TCGLabel
*fs
= gen_new_label();
20128 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
20130 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20133 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20141 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20142 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
20145 TCGv t0
= tcg_temp_new();
20146 TCGv t1
= tcg_temp_new();
20149 gen_load_gpr(t0
, rs
);
20153 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
20156 /* calculate btarget */
20157 tcg_gen_shli_tl(t0
, t0
, 1);
20158 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
20159 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
20161 /* branch completion */
20162 clear_branch_hflags(ctx
);
20163 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20165 /* unconditional branch to register */
20166 tcg_gen_mov_tl(cpu_PC
, btarget
);
20167 tcg_gen_lookup_and_goto_ptr();
20173 /* nanoMIPS Branches */
20174 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
20175 int rs
, int rt
, int32_t offset
)
20177 int bcond_compute
= 0;
20178 TCGv t0
= tcg_temp_new();
20179 TCGv t1
= tcg_temp_new();
20181 /* Load needed operands and calculate btarget */
20183 /* compact branch */
20186 gen_load_gpr(t0
, rs
);
20187 gen_load_gpr(t1
, rt
);
20189 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20193 if (rs
== 0 || rs
== rt
) {
20194 /* OPC_BLEZALC, OPC_BGEZALC */
20195 /* OPC_BGTZALC, OPC_BLTZALC */
20196 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20198 gen_load_gpr(t0
, rs
);
20199 gen_load_gpr(t1
, rt
);
20201 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20204 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20208 /* OPC_BEQZC, OPC_BNEZC */
20209 gen_load_gpr(t0
, rs
);
20211 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20213 /* OPC_JIC, OPC_JIALC */
20214 TCGv tbase
= tcg_temp_new();
20215 TCGv toffset
= tcg_temp_new();
20217 gen_load_gpr(tbase
, rt
);
20218 tcg_gen_movi_tl(toffset
, offset
);
20219 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20220 tcg_temp_free(tbase
);
20221 tcg_temp_free(toffset
);
20225 MIPS_INVAL("Compact branch/jump");
20226 generate_exception_end(ctx
, EXCP_RI
);
20230 if (bcond_compute
== 0) {
20231 /* Uncoditional compact branch */
20234 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20237 MIPS_INVAL("Compact branch/jump");
20238 generate_exception_end(ctx
, EXCP_RI
);
20242 /* Conditional compact branch */
20243 TCGLabel
*fs
= gen_new_label();
20247 if (rs
== 0 && rt
!= 0) {
20249 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20250 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20252 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20255 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20259 if (rs
== 0 && rt
!= 0) {
20261 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20262 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20264 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20267 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20271 if (rs
== 0 && rt
!= 0) {
20273 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20274 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20276 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20279 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20283 if (rs
== 0 && rt
!= 0) {
20285 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20286 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20288 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20291 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20295 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20298 MIPS_INVAL("Compact conditional branch/jump");
20299 generate_exception_end(ctx
, EXCP_RI
);
20303 /* branch completion */
20304 clear_branch_hflags(ctx
);
20305 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20307 /* Generating branch here as compact branches don't have delay slot */
20308 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20311 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20320 /* nanoMIPS CP1 Branches */
20321 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20322 int32_t ft
, int32_t offset
)
20324 target_ulong btarget
;
20325 TCGv_i64 t0
= tcg_temp_new_i64();
20327 gen_load_fpr64(ctx
, t0
, ft
);
20328 tcg_gen_andi_i64(t0
, t0
, 1);
20330 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20334 tcg_gen_xori_i64(t0
, t0
, 1);
20335 ctx
->hflags
|= MIPS_HFLAG_BC
;
20338 /* t0 already set */
20339 ctx
->hflags
|= MIPS_HFLAG_BC
;
20342 MIPS_INVAL("cp1 cond branch");
20343 generate_exception_end(ctx
, EXCP_RI
);
20347 tcg_gen_trunc_i64_tl(bcond
, t0
);
20349 ctx
->btarget
= btarget
;
20352 tcg_temp_free_i64(t0
);
20356 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20359 t0
= tcg_temp_new();
20360 t1
= tcg_temp_new();
20362 gen_load_gpr(t0
, rs
);
20363 gen_load_gpr(t1
, rt
);
20365 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20366 /* PP.LSXS instructions require shifting */
20367 switch (extract32(ctx
->opcode
, 7, 4)) {
20373 tcg_gen_shli_tl(t0
, t0
, 1);
20381 tcg_gen_shli_tl(t0
, t0
, 2);
20385 tcg_gen_shli_tl(t0
, t0
, 3);
20389 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20391 switch (extract32(ctx
->opcode
, 7, 4)) {
20393 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20395 gen_store_gpr(t0
, rd
);
20399 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20401 gen_store_gpr(t0
, rd
);
20405 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20407 gen_store_gpr(t0
, rd
);
20410 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20412 gen_store_gpr(t0
, rd
);
20416 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20418 gen_store_gpr(t0
, rd
);
20422 gen_load_gpr(t1
, rd
);
20423 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20429 gen_load_gpr(t1
, rd
);
20430 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20436 gen_load_gpr(t1
, rd
);
20437 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20441 /*case NM_LWC1XS:*/
20443 /*case NM_LDC1XS:*/
20445 /*case NM_SWC1XS:*/
20447 /*case NM_SDC1XS:*/
20448 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20449 check_cp1_enabled(ctx
);
20450 switch (extract32(ctx
->opcode
, 7, 4)) {
20452 /*case NM_LWC1XS:*/
20453 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20456 /*case NM_LDC1XS:*/
20457 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20460 /*case NM_SWC1XS:*/
20461 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20464 /*case NM_SDC1XS:*/
20465 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20469 generate_exception_err(ctx
, EXCP_CpU
, 1);
20473 generate_exception_end(ctx
, EXCP_RI
);
20481 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20485 rt
= extract32(ctx
->opcode
, 21, 5);
20486 rs
= extract32(ctx
->opcode
, 16, 5);
20487 rd
= extract32(ctx
->opcode
, 11, 5);
20489 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20490 generate_exception_end(ctx
, EXCP_RI
);
20493 check_cp1_enabled(ctx
);
20494 switch (extract32(ctx
->opcode
, 0, 3)) {
20496 switch (extract32(ctx
->opcode
, 3, 7)) {
20498 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20501 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20504 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20507 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20510 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20513 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20516 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20519 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20522 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20525 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20528 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20531 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20534 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20537 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20540 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20543 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20546 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20549 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20552 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20555 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20558 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20561 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20564 generate_exception_end(ctx
, EXCP_RI
);
20569 switch (extract32(ctx
->opcode
, 3, 3)) {
20571 switch (extract32(ctx
->opcode
, 9, 1)) {
20573 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
20576 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
20581 switch (extract32(ctx
->opcode
, 9, 1)) {
20583 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
20586 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
20591 switch (extract32(ctx
->opcode
, 9, 1)) {
20593 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
20596 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
20601 switch (extract32(ctx
->opcode
, 9, 1)) {
20603 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
20606 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
20611 switch (extract32(ctx
->opcode
, 6, 8)) {
20613 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
20616 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
20619 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
20622 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
20625 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
20628 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
20631 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
20634 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
20637 switch (extract32(ctx
->opcode
, 6, 9)) {
20639 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
20642 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
20645 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
20648 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
20651 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
20654 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
20657 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
20660 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
20663 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
20666 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
20669 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
20672 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
20675 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
20678 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
20681 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
20684 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
20687 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
20690 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
20693 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
20696 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
20699 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
20702 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
20705 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
20708 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
20711 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
20714 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
20717 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
20720 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
20723 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
20726 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
20729 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
20732 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
20735 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
20738 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
20741 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
20744 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
20747 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
20750 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
20753 generate_exception_end(ctx
, EXCP_RI
);
20762 switch (extract32(ctx
->opcode
, 3, 3)) {
20763 case NM_CMP_CONDN_S
:
20764 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20766 case NM_CMP_CONDN_D
:
20767 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20770 generate_exception_end(ctx
, EXCP_RI
);
20775 generate_exception_end(ctx
, EXCP_RI
);
20780 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
20781 int rd
, int rs
, int rt
)
20784 TCGv t0
= tcg_temp_new();
20785 TCGv v1_t
= tcg_temp_new();
20786 TCGv v2_t
= tcg_temp_new();
20788 gen_load_gpr(v1_t
, rs
);
20789 gen_load_gpr(v2_t
, rt
);
20794 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
20798 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
20802 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
20804 case NM_CMPU_EQ_QB
:
20806 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
20808 case NM_CMPU_LT_QB
:
20810 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
20812 case NM_CMPU_LE_QB
:
20814 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
20816 case NM_CMPGU_EQ_QB
:
20818 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20819 gen_store_gpr(v1_t
, ret
);
20821 case NM_CMPGU_LT_QB
:
20823 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20824 gen_store_gpr(v1_t
, ret
);
20826 case NM_CMPGU_LE_QB
:
20828 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20829 gen_store_gpr(v1_t
, ret
);
20831 case NM_CMPGDU_EQ_QB
:
20833 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20834 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20835 gen_store_gpr(v1_t
, ret
);
20837 case NM_CMPGDU_LT_QB
:
20839 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20840 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20841 gen_store_gpr(v1_t
, ret
);
20843 case NM_CMPGDU_LE_QB
:
20845 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20846 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20847 gen_store_gpr(v1_t
, ret
);
20851 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
20852 gen_store_gpr(v1_t
, ret
);
20856 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20857 gen_store_gpr(v1_t
, ret
);
20861 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20862 gen_store_gpr(v1_t
, ret
);
20866 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20867 gen_store_gpr(v1_t
, ret
);
20871 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20872 gen_store_gpr(v1_t
, ret
);
20876 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
20877 gen_store_gpr(v1_t
, ret
);
20881 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
20882 gen_store_gpr(v1_t
, ret
);
20886 switch (extract32(ctx
->opcode
, 10, 1)) {
20889 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20890 gen_store_gpr(v1_t
, ret
);
20894 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20895 gen_store_gpr(v1_t
, ret
);
20899 case NM_ADDQH_R_PH
:
20901 switch (extract32(ctx
->opcode
, 10, 1)) {
20904 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
20905 gen_store_gpr(v1_t
, ret
);
20909 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
20910 gen_store_gpr(v1_t
, ret
);
20916 switch (extract32(ctx
->opcode
, 10, 1)) {
20919 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
20920 gen_store_gpr(v1_t
, ret
);
20924 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
20925 gen_store_gpr(v1_t
, ret
);
20931 switch (extract32(ctx
->opcode
, 10, 1)) {
20934 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20935 gen_store_gpr(v1_t
, ret
);
20939 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20940 gen_store_gpr(v1_t
, ret
);
20946 switch (extract32(ctx
->opcode
, 10, 1)) {
20949 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20950 gen_store_gpr(v1_t
, ret
);
20954 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20955 gen_store_gpr(v1_t
, ret
);
20959 case NM_ADDUH_R_QB
:
20961 switch (extract32(ctx
->opcode
, 10, 1)) {
20964 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
20965 gen_store_gpr(v1_t
, ret
);
20969 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
20970 gen_store_gpr(v1_t
, ret
);
20974 case NM_SHRAV_R_PH
:
20976 switch (extract32(ctx
->opcode
, 10, 1)) {
20979 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
20980 gen_store_gpr(v1_t
, ret
);
20984 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
20985 gen_store_gpr(v1_t
, ret
);
20989 case NM_SHRAV_R_QB
:
20991 switch (extract32(ctx
->opcode
, 10, 1)) {
20994 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
20995 gen_store_gpr(v1_t
, ret
);
20999 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
21000 gen_store_gpr(v1_t
, ret
);
21006 switch (extract32(ctx
->opcode
, 10, 1)) {
21009 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21010 gen_store_gpr(v1_t
, ret
);
21014 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21015 gen_store_gpr(v1_t
, ret
);
21019 case NM_SUBQH_R_PH
:
21021 switch (extract32(ctx
->opcode
, 10, 1)) {
21024 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
21025 gen_store_gpr(v1_t
, ret
);
21029 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
21030 gen_store_gpr(v1_t
, ret
);
21036 switch (extract32(ctx
->opcode
, 10, 1)) {
21039 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
21040 gen_store_gpr(v1_t
, ret
);
21044 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
21045 gen_store_gpr(v1_t
, ret
);
21051 switch (extract32(ctx
->opcode
, 10, 1)) {
21054 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21055 gen_store_gpr(v1_t
, ret
);
21059 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21060 gen_store_gpr(v1_t
, ret
);
21066 switch (extract32(ctx
->opcode
, 10, 1)) {
21069 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21070 gen_store_gpr(v1_t
, ret
);
21074 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21075 gen_store_gpr(v1_t
, ret
);
21079 case NM_SUBUH_R_QB
:
21081 switch (extract32(ctx
->opcode
, 10, 1)) {
21084 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
21085 gen_store_gpr(v1_t
, ret
);
21089 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
21090 gen_store_gpr(v1_t
, ret
);
21094 case NM_SHLLV_S_PH
:
21096 switch (extract32(ctx
->opcode
, 10, 1)) {
21099 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21100 gen_store_gpr(v1_t
, ret
);
21104 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21105 gen_store_gpr(v1_t
, ret
);
21109 case NM_PRECR_SRA_R_PH_W
:
21111 switch (extract32(ctx
->opcode
, 10, 1)) {
21113 /* PRECR_SRA_PH_W */
21115 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21116 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
21118 gen_store_gpr(v1_t
, rt
);
21119 tcg_temp_free_i32(sa_t
);
21123 /* PRECR_SRA_R_PH_W */
21125 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21126 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
21128 gen_store_gpr(v1_t
, rt
);
21129 tcg_temp_free_i32(sa_t
);
21134 case NM_MULEU_S_PH_QBL
:
21136 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
21137 gen_store_gpr(v1_t
, ret
);
21139 case NM_MULEU_S_PH_QBR
:
21141 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
21142 gen_store_gpr(v1_t
, ret
);
21144 case NM_MULQ_RS_PH
:
21146 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21147 gen_store_gpr(v1_t
, ret
);
21151 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21152 gen_store_gpr(v1_t
, ret
);
21156 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21157 gen_store_gpr(v1_t
, ret
);
21161 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21162 gen_store_gpr(v1_t
, ret
);
21166 gen_load_gpr(t0
, rs
);
21168 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
21170 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21174 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
21175 gen_store_gpr(v1_t
, ret
);
21179 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
21180 gen_store_gpr(v1_t
, ret
);
21184 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
21185 gen_store_gpr(v1_t
, ret
);
21189 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21190 gen_store_gpr(v1_t
, ret
);
21194 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21195 gen_store_gpr(v1_t
, ret
);
21199 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21200 gen_store_gpr(v1_t
, ret
);
21205 TCGv tv0
= tcg_temp_new();
21206 TCGv tv1
= tcg_temp_new();
21207 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21209 tcg_gen_movi_tl(tv0
, rd
>> 3);
21210 tcg_gen_movi_tl(tv1
, imm
);
21211 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21214 case NM_MULEQ_S_W_PHL
:
21216 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21217 gen_store_gpr(v1_t
, ret
);
21219 case NM_MULEQ_S_W_PHR
:
21221 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21222 gen_store_gpr(v1_t
, ret
);
21226 switch (extract32(ctx
->opcode
, 10, 1)) {
21229 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21230 gen_store_gpr(v1_t
, ret
);
21234 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21235 gen_store_gpr(v1_t
, ret
);
21239 case NM_PRECR_QB_PH
:
21241 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21242 gen_store_gpr(v1_t
, ret
);
21244 case NM_PRECRQ_QB_PH
:
21246 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21247 gen_store_gpr(v1_t
, ret
);
21249 case NM_PRECRQ_PH_W
:
21251 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21252 gen_store_gpr(v1_t
, ret
);
21254 case NM_PRECRQ_RS_PH_W
:
21256 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21257 gen_store_gpr(v1_t
, ret
);
21259 case NM_PRECRQU_S_QB_PH
:
21261 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21262 gen_store_gpr(v1_t
, ret
);
21266 tcg_gen_movi_tl(t0
, rd
);
21267 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21268 gen_store_gpr(v1_t
, rt
);
21272 tcg_gen_movi_tl(t0
, rd
>> 1);
21273 switch (extract32(ctx
->opcode
, 10, 1)) {
21276 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21277 gen_store_gpr(v1_t
, rt
);
21281 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21282 gen_store_gpr(v1_t
, rt
);
21288 tcg_gen_movi_tl(t0
, rd
>> 1);
21289 switch (extract32(ctx
->opcode
, 10, 2)) {
21292 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21293 gen_store_gpr(v1_t
, rt
);
21297 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21298 gen_store_gpr(v1_t
, rt
);
21301 generate_exception_end(ctx
, EXCP_RI
);
21307 tcg_gen_movi_tl(t0
, rd
);
21308 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21309 gen_store_gpr(v1_t
, rt
);
21315 imm
= sextract32(ctx
->opcode
, 11, 11);
21316 imm
= (int16_t)(imm
<< 6) >> 6;
21318 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21323 generate_exception_end(ctx
, EXCP_RI
);
21328 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21336 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
21337 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21339 rt
= extract32(ctx
->opcode
, 21, 5);
21340 rs
= extract32(ctx
->opcode
, 16, 5);
21341 rd
= extract32(ctx
->opcode
, 11, 5);
21343 op
= extract32(ctx
->opcode
, 26, 6);
21348 switch (extract32(ctx
->opcode
, 19, 2)) {
21351 generate_exception_end(ctx
, EXCP_RI
);
21354 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21355 generate_exception_end(ctx
, EXCP_SYSCALL
);
21357 generate_exception_end(ctx
, EXCP_RI
);
21361 generate_exception_end(ctx
, EXCP_BREAK
);
21364 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21365 gen_helper_do_semihosting(cpu_env
);
21367 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21368 generate_exception_end(ctx
, EXCP_RI
);
21370 generate_exception_end(ctx
, EXCP_DBp
);
21377 imm
= extract32(ctx
->opcode
, 0, 16);
21379 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21381 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21383 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21388 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21389 extract32(ctx
->opcode
, 1, 20) << 1;
21390 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21391 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21395 switch (ctx
->opcode
& 0x07) {
21397 gen_pool32a0_nanomips_insn(env
, ctx
);
21401 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21402 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21406 switch (extract32(ctx
->opcode
, 3, 3)) {
21408 gen_p_lsx(ctx
, rd
, rs
, rt
);
21412 * In nanoMIPS, the shift field directly encodes the shift
21413 * amount, meaning that the supported shift values are in
21414 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21416 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
21417 extract32(ctx
->opcode
, 9, 2) - 1);
21420 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21423 gen_pool32axf_nanomips_insn(env
, ctx
);
21426 generate_exception_end(ctx
, EXCP_RI
);
21431 generate_exception_end(ctx
, EXCP_RI
);
21436 switch (ctx
->opcode
& 0x03) {
21439 offset
= extract32(ctx
->opcode
, 0, 21);
21440 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21444 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21447 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21450 generate_exception_end(ctx
, EXCP_RI
);
21456 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 4);
21457 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21458 switch (extract32(ctx
->opcode
, 16, 5)) {
21462 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21468 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21469 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21475 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21481 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21484 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21491 t0
= tcg_temp_new();
21493 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21496 tcg_gen_movi_tl(t0
, addr
);
21497 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21505 t0
= tcg_temp_new();
21506 t1
= tcg_temp_new();
21508 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21511 tcg_gen_movi_tl(t0
, addr
);
21512 gen_load_gpr(t1
, rt
);
21514 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21521 generate_exception_end(ctx
, EXCP_RI
);
21527 switch (extract32(ctx
->opcode
, 12, 4)) {
21529 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21532 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21535 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21538 switch (extract32(ctx
->opcode
, 20, 1)) {
21540 switch (ctx
->opcode
& 3) {
21542 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21543 extract32(ctx
->opcode
, 2, 1),
21544 extract32(ctx
->opcode
, 3, 9) << 3);
21547 case NM_RESTORE_JRC
:
21548 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21549 extract32(ctx
->opcode
, 2, 1),
21550 extract32(ctx
->opcode
, 3, 9) << 3);
21551 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21552 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21556 generate_exception_end(ctx
, EXCP_RI
);
21561 generate_exception_end(ctx
, EXCP_RI
);
21566 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21569 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21573 TCGv t0
= tcg_temp_new();
21575 imm
= extract32(ctx
->opcode
, 0, 12);
21576 gen_load_gpr(t0
, rs
);
21577 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
21578 gen_store_gpr(t0
, rt
);
21584 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
21585 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
21589 int shift
= extract32(ctx
->opcode
, 0, 5);
21590 switch (extract32(ctx
->opcode
, 5, 4)) {
21592 if (rt
== 0 && shift
== 0) {
21594 } else if (rt
== 0 && shift
== 3) {
21595 /* EHB - treat as NOP */
21596 } else if (rt
== 0 && shift
== 5) {
21597 /* PAUSE - treat as NOP */
21598 } else if (rt
== 0 && shift
== 6) {
21600 gen_sync(extract32(ctx
->opcode
, 16, 5));
21603 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
21604 extract32(ctx
->opcode
, 0, 5));
21608 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
21609 extract32(ctx
->opcode
, 0, 5));
21612 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
21613 extract32(ctx
->opcode
, 0, 5));
21616 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
21617 extract32(ctx
->opcode
, 0, 5));
21625 TCGv t0
= tcg_temp_new();
21626 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
21627 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
21629 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
21631 gen_load_gpr(t0
, rs
);
21632 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
21635 tcg_temp_free_i32(shift
);
21636 tcg_temp_free_i32(shiftx
);
21637 tcg_temp_free_i32(stripe
);
21641 switch (((ctx
->opcode
>> 10) & 2) |
21642 (extract32(ctx
->opcode
, 5, 1))) {
21645 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21646 extract32(ctx
->opcode
, 6, 5));
21649 generate_exception_end(ctx
, EXCP_RI
);
21654 switch (((ctx
->opcode
>> 10) & 2) |
21655 (extract32(ctx
->opcode
, 5, 1))) {
21658 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21659 extract32(ctx
->opcode
, 6, 5));
21662 generate_exception_end(ctx
, EXCP_RI
);
21667 generate_exception_end(ctx
, EXCP_RI
);
21672 gen_pool32f_nanomips_insn(ctx
);
21677 switch (extract32(ctx
->opcode
, 1, 1)) {
21680 tcg_gen_movi_tl(cpu_gpr
[rt
],
21681 sextract32(ctx
->opcode
, 0, 1) << 31 |
21682 extract32(ctx
->opcode
, 2, 10) << 21 |
21683 extract32(ctx
->opcode
, 12, 9) << 12);
21688 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
21689 extract32(ctx
->opcode
, 2, 10) << 21 |
21690 extract32(ctx
->opcode
, 12, 9) << 12;
21692 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21693 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21700 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
21702 switch (extract32(ctx
->opcode
, 18, 3)) {
21704 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
21707 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
21710 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
21714 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
21719 switch (ctx
->opcode
& 1) {
21721 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
21724 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
21730 switch (ctx
->opcode
& 1) {
21732 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
21735 generate_exception_end(ctx
, EXCP_RI
);
21741 switch (ctx
->opcode
& 0x3) {
21743 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
21746 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
21749 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
21752 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
21757 generate_exception_end(ctx
, EXCP_RI
);
21764 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
21766 switch (extract32(ctx
->opcode
, 12, 4)) {
21771 * Break the TB to be able to sync copied instructions
21774 ctx
->base
.is_jmp
= DISAS_STOP
;
21777 /* Treat as NOP. */
21781 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
21784 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
21787 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
21790 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
21793 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
21796 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
21799 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
21802 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
21805 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
21808 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
21811 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
21814 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
21817 generate_exception_end(ctx
, EXCP_RI
);
21824 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
21825 extract32(ctx
->opcode
, 0, 8);
21827 switch (extract32(ctx
->opcode
, 8, 3)) {
21829 switch (extract32(ctx
->opcode
, 11, 4)) {
21831 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
21834 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
21837 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
21840 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
21843 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
21846 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
21849 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
21852 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
21855 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
21858 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
21861 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
21864 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
21870 * Break the TB to be able to sync copied instructions
21873 ctx
->base
.is_jmp
= DISAS_STOP
;
21876 /* Treat as NOP. */
21880 generate_exception_end(ctx
, EXCP_RI
);
21885 switch (extract32(ctx
->opcode
, 11, 4)) {
21890 TCGv t0
= tcg_temp_new();
21891 TCGv t1
= tcg_temp_new();
21893 gen_base_offset_addr(ctx
, t0
, rs
, s
);
21895 switch (extract32(ctx
->opcode
, 11, 4)) {
21897 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
21899 gen_store_gpr(t0
, rt
);
21902 gen_load_gpr(t1
, rt
);
21903 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
21912 switch (ctx
->opcode
& 0x03) {
21914 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
21918 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21923 switch (ctx
->opcode
& 0x03) {
21925 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
21929 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21935 check_cp0_enabled(ctx
);
21936 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
21937 gen_cache_operation(ctx
, rt
, rs
, s
);
21943 switch (extract32(ctx
->opcode
, 11, 4)) {
21946 check_cp0_enabled(ctx
);
21947 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
21951 check_cp0_enabled(ctx
);
21952 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
21956 check_cp0_enabled(ctx
);
21957 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
21961 /* case NM_SYNCIE */
21963 check_cp0_enabled(ctx
);
21965 * Break the TB to be able to sync copied instructions
21968 ctx
->base
.is_jmp
= DISAS_STOP
;
21970 /* case NM_PREFE */
21972 check_cp0_enabled(ctx
);
21973 /* Treat as NOP. */
21978 check_cp0_enabled(ctx
);
21979 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
21983 check_cp0_enabled(ctx
);
21984 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
21988 check_cp0_enabled(ctx
);
21989 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
21992 check_nms_dl_il_sl_tl_l2c(ctx
);
21993 gen_cache_operation(ctx
, rt
, rs
, s
);
21997 check_cp0_enabled(ctx
);
21998 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
22002 check_cp0_enabled(ctx
);
22003 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
22006 switch (extract32(ctx
->opcode
, 2, 2)) {
22010 check_cp0_enabled(ctx
);
22011 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
22016 check_cp0_enabled(ctx
);
22017 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22020 generate_exception_end(ctx
, EXCP_RI
);
22025 switch (extract32(ctx
->opcode
, 2, 2)) {
22029 check_cp0_enabled(ctx
);
22030 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
22035 check_cp0_enabled(ctx
);
22036 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22040 generate_exception_end(ctx
, EXCP_RI
);
22050 int count
= extract32(ctx
->opcode
, 12, 3);
22053 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
22054 extract32(ctx
->opcode
, 0, 8);
22055 TCGv va
= tcg_temp_new();
22056 TCGv t1
= tcg_temp_new();
22057 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
22058 NM_P_LS_UAWM
? MO_UNALN
: 0;
22060 count
= (count
== 0) ? 8 : count
;
22061 while (counter
!= count
) {
22062 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
22063 int this_offset
= offset
+ (counter
<< 2);
22065 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
22067 switch (extract32(ctx
->opcode
, 11, 1)) {
22069 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
22071 gen_store_gpr(t1
, this_rt
);
22072 if ((this_rt
== rs
) &&
22073 (counter
!= (count
- 1))) {
22074 /* UNPREDICTABLE */
22078 this_rt
= (rt
== 0) ? 0 : this_rt
;
22079 gen_load_gpr(t1
, this_rt
);
22080 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
22091 generate_exception_end(ctx
, EXCP_RI
);
22099 TCGv t0
= tcg_temp_new();
22100 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
22101 extract32(ctx
->opcode
, 1, 20) << 1;
22102 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
22103 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
22104 extract32(ctx
->opcode
, 21, 3));
22105 gen_load_gpr(t0
, rt
);
22106 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22107 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22113 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
22114 extract32(ctx
->opcode
, 1, 24) << 1;
22116 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
22118 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
22121 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22126 switch (extract32(ctx
->opcode
, 12, 4)) {
22129 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
22132 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
22135 generate_exception_end(ctx
, EXCP_RI
);
22141 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22142 extract32(ctx
->opcode
, 1, 13) << 1;
22143 switch (extract32(ctx
->opcode
, 14, 2)) {
22146 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
22149 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22150 extract32(ctx
->opcode
, 1, 13) << 1;
22151 check_cp1_enabled(ctx
);
22152 switch (extract32(ctx
->opcode
, 16, 5)) {
22154 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
22157 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
22162 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
22163 extract32(ctx
->opcode
, 0, 1) << 13;
22165 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
22170 generate_exception_end(ctx
, EXCP_RI
);
22176 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
22178 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
22182 if (rs
== rt
|| rt
== 0) {
22183 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
22184 } else if (rs
== 0) {
22185 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
22187 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22195 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22196 extract32(ctx
->opcode
, 1, 13) << 1;
22197 switch (extract32(ctx
->opcode
, 14, 2)) {
22200 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22203 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22205 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22207 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22211 if (rs
== 0 || rs
== rt
) {
22213 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22215 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22219 generate_exception_end(ctx
, EXCP_RI
);
22226 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22227 extract32(ctx
->opcode
, 1, 10) << 1;
22228 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22230 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22235 generate_exception_end(ctx
, EXCP_RI
);
22241 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22244 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22245 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22246 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22250 /* make sure instructions are on a halfword boundary */
22251 if (ctx
->base
.pc_next
& 0x1) {
22252 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22253 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22254 tcg_temp_free(tmp
);
22255 generate_exception_end(ctx
, EXCP_AdEL
);
22259 op
= extract32(ctx
->opcode
, 10, 6);
22262 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22265 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22266 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22269 switch (extract32(ctx
->opcode
, 3, 2)) {
22270 case NM_P16_SYSCALL
:
22271 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22272 generate_exception_end(ctx
, EXCP_SYSCALL
);
22274 generate_exception_end(ctx
, EXCP_RI
);
22278 generate_exception_end(ctx
, EXCP_BREAK
);
22281 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22282 gen_helper_do_semihosting(cpu_env
);
22284 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22285 generate_exception_end(ctx
, EXCP_RI
);
22287 generate_exception_end(ctx
, EXCP_DBp
);
22292 generate_exception_end(ctx
, EXCP_RI
);
22299 int shift
= extract32(ctx
->opcode
, 0, 3);
22301 shift
= (shift
== 0) ? 8 : shift
;
22303 switch (extract32(ctx
->opcode
, 3, 1)) {
22311 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22315 switch (ctx
->opcode
& 1) {
22317 gen_pool16c_nanomips_insn(ctx
);
22320 gen_ldxs(ctx
, rt
, rs
, rd
);
22325 switch (extract32(ctx
->opcode
, 6, 1)) {
22327 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22328 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22331 generate_exception_end(ctx
, EXCP_RI
);
22336 switch (extract32(ctx
->opcode
, 3, 1)) {
22338 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22339 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22341 case NM_P_ADDIURS5
:
22342 rt
= extract32(ctx
->opcode
, 5, 5);
22344 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22345 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22346 (extract32(ctx
->opcode
, 0, 3));
22347 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22353 switch (ctx
->opcode
& 0x1) {
22355 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22358 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22363 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22364 extract32(ctx
->opcode
, 5, 3);
22365 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22366 extract32(ctx
->opcode
, 0, 3);
22367 rt
= decode_gpr_gpr4(rt
);
22368 rs
= decode_gpr_gpr4(rs
);
22369 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22370 (extract32(ctx
->opcode
, 3, 1))) {
22373 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22377 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22380 generate_exception_end(ctx
, EXCP_RI
);
22386 int imm
= extract32(ctx
->opcode
, 0, 7);
22387 imm
= (imm
== 0x7f ? -1 : imm
);
22389 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22395 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22396 u
= (u
== 12) ? 0xff :
22397 (u
== 13) ? 0xffff : u
;
22398 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22402 offset
= extract32(ctx
->opcode
, 0, 2);
22403 switch (extract32(ctx
->opcode
, 2, 2)) {
22405 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22408 rt
= decode_gpr_gpr3_src_store(
22409 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22410 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22413 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22416 generate_exception_end(ctx
, EXCP_RI
);
22421 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22422 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22424 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22427 rt
= decode_gpr_gpr3_src_store(
22428 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22429 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22432 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22435 generate_exception_end(ctx
, EXCP_RI
);
22440 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22441 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22444 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22445 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22446 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22450 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22451 extract32(ctx
->opcode
, 5, 3);
22452 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22453 extract32(ctx
->opcode
, 0, 3);
22454 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22455 (extract32(ctx
->opcode
, 8, 1) << 2);
22456 rt
= decode_gpr_gpr4(rt
);
22457 rs
= decode_gpr_gpr4(rs
);
22458 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22462 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22463 extract32(ctx
->opcode
, 5, 3);
22464 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22465 extract32(ctx
->opcode
, 0, 3);
22466 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22467 (extract32(ctx
->opcode
, 8, 1) << 2);
22468 rt
= decode_gpr_gpr4_zero(rt
);
22469 rs
= decode_gpr_gpr4(rs
);
22470 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22473 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22474 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22477 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22478 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22479 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22482 rt
= decode_gpr_gpr3_src_store(
22483 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22484 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22485 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22486 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22489 rt
= decode_gpr_gpr3_src_store(
22490 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22491 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22492 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22495 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22496 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22497 (extract32(ctx
->opcode
, 1, 9) << 1));
22500 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22501 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22502 (extract32(ctx
->opcode
, 1, 9) << 1));
22505 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22506 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22507 (extract32(ctx
->opcode
, 1, 6) << 1));
22510 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22511 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22512 (extract32(ctx
->opcode
, 1, 6) << 1));
22515 switch (ctx
->opcode
& 0xf) {
22518 switch (extract32(ctx
->opcode
, 4, 1)) {
22520 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22521 extract32(ctx
->opcode
, 5, 5), 0, 0);
22524 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22525 extract32(ctx
->opcode
, 5, 5), 31, 0);
22532 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22533 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22534 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22535 extract32(ctx
->opcode
, 0, 4) << 1);
22542 int count
= extract32(ctx
->opcode
, 0, 4);
22543 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22545 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22546 switch (extract32(ctx
->opcode
, 8, 1)) {
22548 gen_save(ctx
, rt
, count
, 0, u
);
22550 case NM_RESTORE_JRC16
:
22551 gen_restore(ctx
, rt
, count
, 0, u
);
22552 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22561 static const int gpr2reg1
[] = {4, 5, 6, 7};
22562 static const int gpr2reg2
[] = {5, 6, 7, 8};
22564 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22565 extract32(ctx
->opcode
, 8, 1);
22566 int r1
= gpr2reg1
[rd2
];
22567 int r2
= gpr2reg2
[rd2
];
22568 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22569 extract32(ctx
->opcode
, 0, 3);
22570 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22571 extract32(ctx
->opcode
, 5, 3);
22572 TCGv t0
= tcg_temp_new();
22573 TCGv t1
= tcg_temp_new();
22574 if (op
== NM_MOVEP
) {
22577 rs
= decode_gpr_gpr4_zero(r3
);
22578 rt
= decode_gpr_gpr4_zero(r4
);
22580 rd
= decode_gpr_gpr4(r3
);
22581 re
= decode_gpr_gpr4(r4
);
22585 gen_load_gpr(t0
, rs
);
22586 gen_load_gpr(t1
, rt
);
22587 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22588 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
22594 return decode_nanomips_32_48_opc(env
, ctx
);
22601 /* SmartMIPS extension to MIPS32 */
22603 #if defined(TARGET_MIPS64)
22605 /* MDMX extension to MIPS64 */
22609 /* MIPSDSP functions. */
22610 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
22611 int rd
, int base
, int offset
)
22616 t0
= tcg_temp_new();
22619 gen_load_gpr(t0
, offset
);
22620 } else if (offset
== 0) {
22621 gen_load_gpr(t0
, base
);
22623 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
22628 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
22629 gen_store_gpr(t0
, rd
);
22632 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
22633 gen_store_gpr(t0
, rd
);
22636 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
22637 gen_store_gpr(t0
, rd
);
22639 #if defined(TARGET_MIPS64)
22641 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
22642 gen_store_gpr(t0
, rd
);
22649 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22650 int ret
, int v1
, int v2
)
22656 /* Treat as NOP. */
22660 v1_t
= tcg_temp_new();
22661 v2_t
= tcg_temp_new();
22663 gen_load_gpr(v1_t
, v1
);
22664 gen_load_gpr(v2_t
, v2
);
22667 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22668 case OPC_MULT_G_2E
:
22672 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22674 case OPC_ADDUH_R_QB
:
22675 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22678 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22680 case OPC_ADDQH_R_PH
:
22681 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22684 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22686 case OPC_ADDQH_R_W
:
22687 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22690 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22692 case OPC_SUBUH_R_QB
:
22693 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22696 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22698 case OPC_SUBQH_R_PH
:
22699 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22702 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22704 case OPC_SUBQH_R_W
:
22705 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22709 case OPC_ABSQ_S_PH_DSP
:
22711 case OPC_ABSQ_S_QB
:
22713 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
22715 case OPC_ABSQ_S_PH
:
22717 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
22721 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
22723 case OPC_PRECEQ_W_PHL
:
22725 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
22726 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22728 case OPC_PRECEQ_W_PHR
:
22730 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
22731 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
22732 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22734 case OPC_PRECEQU_PH_QBL
:
22736 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
22738 case OPC_PRECEQU_PH_QBR
:
22740 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
22742 case OPC_PRECEQU_PH_QBLA
:
22744 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
22746 case OPC_PRECEQU_PH_QBRA
:
22748 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
22750 case OPC_PRECEU_PH_QBL
:
22752 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
22754 case OPC_PRECEU_PH_QBR
:
22756 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
22758 case OPC_PRECEU_PH_QBLA
:
22760 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
22762 case OPC_PRECEU_PH_QBRA
:
22764 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
22768 case OPC_ADDU_QB_DSP
:
22772 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22774 case OPC_ADDQ_S_PH
:
22776 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22780 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22784 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22786 case OPC_ADDU_S_QB
:
22788 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22792 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22794 case OPC_ADDU_S_PH
:
22796 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22800 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22802 case OPC_SUBQ_S_PH
:
22804 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22808 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22812 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22814 case OPC_SUBU_S_QB
:
22816 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22820 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22822 case OPC_SUBU_S_PH
:
22824 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22828 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22832 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22836 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
22838 case OPC_RADDU_W_QB
:
22840 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
22844 case OPC_CMPU_EQ_QB_DSP
:
22846 case OPC_PRECR_QB_PH
:
22848 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22850 case OPC_PRECRQ_QB_PH
:
22852 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22854 case OPC_PRECR_SRA_PH_W
:
22857 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22858 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22860 tcg_temp_free_i32(sa_t
);
22863 case OPC_PRECR_SRA_R_PH_W
:
22866 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22867 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22869 tcg_temp_free_i32(sa_t
);
22872 case OPC_PRECRQ_PH_W
:
22874 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22876 case OPC_PRECRQ_RS_PH_W
:
22878 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22880 case OPC_PRECRQU_S_QB_PH
:
22882 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22886 #ifdef TARGET_MIPS64
22887 case OPC_ABSQ_S_QH_DSP
:
22889 case OPC_PRECEQ_L_PWL
:
22891 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
22893 case OPC_PRECEQ_L_PWR
:
22895 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
22897 case OPC_PRECEQ_PW_QHL
:
22899 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
22901 case OPC_PRECEQ_PW_QHR
:
22903 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
22905 case OPC_PRECEQ_PW_QHLA
:
22907 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
22909 case OPC_PRECEQ_PW_QHRA
:
22911 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
22913 case OPC_PRECEQU_QH_OBL
:
22915 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
22917 case OPC_PRECEQU_QH_OBR
:
22919 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
22921 case OPC_PRECEQU_QH_OBLA
:
22923 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
22925 case OPC_PRECEQU_QH_OBRA
:
22927 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
22929 case OPC_PRECEU_QH_OBL
:
22931 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
22933 case OPC_PRECEU_QH_OBR
:
22935 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
22937 case OPC_PRECEU_QH_OBLA
:
22939 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
22941 case OPC_PRECEU_QH_OBRA
:
22943 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
22945 case OPC_ABSQ_S_OB
:
22947 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
22949 case OPC_ABSQ_S_PW
:
22951 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
22953 case OPC_ABSQ_S_QH
:
22955 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
22959 case OPC_ADDU_OB_DSP
:
22961 case OPC_RADDU_L_OB
:
22963 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
22967 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22969 case OPC_SUBQ_S_PW
:
22971 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22975 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22977 case OPC_SUBQ_S_QH
:
22979 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22983 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22985 case OPC_SUBU_S_OB
:
22987 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22991 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22993 case OPC_SUBU_S_QH
:
22995 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22999 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23001 case OPC_SUBUH_R_OB
:
23003 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23007 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23009 case OPC_ADDQ_S_PW
:
23011 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23015 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23017 case OPC_ADDQ_S_QH
:
23019 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23023 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23025 case OPC_ADDU_S_OB
:
23027 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23031 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23033 case OPC_ADDU_S_QH
:
23035 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23039 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23041 case OPC_ADDUH_R_OB
:
23043 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23047 case OPC_CMPU_EQ_OB_DSP
:
23049 case OPC_PRECR_OB_QH
:
23051 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23053 case OPC_PRECR_SRA_QH_PW
:
23056 TCGv_i32 ret_t
= tcg_const_i32(ret
);
23057 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
23058 tcg_temp_free_i32(ret_t
);
23061 case OPC_PRECR_SRA_R_QH_PW
:
23064 TCGv_i32 sa_v
= tcg_const_i32(ret
);
23065 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
23066 tcg_temp_free_i32(sa_v
);
23069 case OPC_PRECRQ_OB_QH
:
23071 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23073 case OPC_PRECRQ_PW_L
:
23075 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
23077 case OPC_PRECRQ_QH_PW
:
23079 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23081 case OPC_PRECRQ_RS_QH_PW
:
23083 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23085 case OPC_PRECRQU_S_OB_QH
:
23087 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23094 tcg_temp_free(v1_t
);
23095 tcg_temp_free(v2_t
);
23098 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
23099 int ret
, int v1
, int v2
)
23107 /* Treat as NOP. */
23111 t0
= tcg_temp_new();
23112 v1_t
= tcg_temp_new();
23113 v2_t
= tcg_temp_new();
23115 tcg_gen_movi_tl(t0
, v1
);
23116 gen_load_gpr(v1_t
, v1
);
23117 gen_load_gpr(v2_t
, v2
);
23120 case OPC_SHLL_QB_DSP
:
23122 op2
= MASK_SHLL_QB(ctx
->opcode
);
23126 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23130 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23134 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23138 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23140 case OPC_SHLL_S_PH
:
23142 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23144 case OPC_SHLLV_S_PH
:
23146 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23150 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23152 case OPC_SHLLV_S_W
:
23154 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23158 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
23162 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23166 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
23170 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23174 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
23176 case OPC_SHRA_R_QB
:
23178 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
23182 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23184 case OPC_SHRAV_R_QB
:
23186 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23190 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23192 case OPC_SHRA_R_PH
:
23194 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23198 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23200 case OPC_SHRAV_R_PH
:
23202 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23206 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23208 case OPC_SHRAV_R_W
:
23210 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23212 default: /* Invalid */
23213 MIPS_INVAL("MASK SHLL.QB");
23214 generate_exception_end(ctx
, EXCP_RI
);
23219 #ifdef TARGET_MIPS64
23220 case OPC_SHLL_OB_DSP
:
23221 op2
= MASK_SHLL_OB(ctx
->opcode
);
23225 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23229 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23231 case OPC_SHLL_S_PW
:
23233 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23235 case OPC_SHLLV_S_PW
:
23237 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23241 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23245 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23249 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23253 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23255 case OPC_SHLL_S_QH
:
23257 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23259 case OPC_SHLLV_S_QH
:
23261 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23265 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23269 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23271 case OPC_SHRA_R_OB
:
23273 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23275 case OPC_SHRAV_R_OB
:
23277 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23281 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23285 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23287 case OPC_SHRA_R_PW
:
23289 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23291 case OPC_SHRAV_R_PW
:
23293 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23297 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23301 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23303 case OPC_SHRA_R_QH
:
23305 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23307 case OPC_SHRAV_R_QH
:
23309 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23313 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23317 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23321 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23325 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23327 default: /* Invalid */
23328 MIPS_INVAL("MASK SHLL.OB");
23329 generate_exception_end(ctx
, EXCP_RI
);
23337 tcg_temp_free(v1_t
);
23338 tcg_temp_free(v2_t
);
23341 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23342 int ret
, int v1
, int v2
, int check_ret
)
23348 if ((ret
== 0) && (check_ret
== 1)) {
23349 /* Treat as NOP. */
23353 t0
= tcg_temp_new_i32();
23354 v1_t
= tcg_temp_new();
23355 v2_t
= tcg_temp_new();
23357 tcg_gen_movi_i32(t0
, ret
);
23358 gen_load_gpr(v1_t
, v1
);
23359 gen_load_gpr(v2_t
, v2
);
23363 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23364 * the same mask and op1.
23366 case OPC_MULT_G_2E
:
23370 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23373 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23376 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23378 case OPC_MULQ_RS_W
:
23379 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23383 case OPC_DPA_W_PH_DSP
:
23385 case OPC_DPAU_H_QBL
:
23387 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23389 case OPC_DPAU_H_QBR
:
23391 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23393 case OPC_DPSU_H_QBL
:
23395 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23397 case OPC_DPSU_H_QBR
:
23399 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23403 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23405 case OPC_DPAX_W_PH
:
23407 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23409 case OPC_DPAQ_S_W_PH
:
23411 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23413 case OPC_DPAQX_S_W_PH
:
23415 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23417 case OPC_DPAQX_SA_W_PH
:
23419 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23423 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23425 case OPC_DPSX_W_PH
:
23427 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23429 case OPC_DPSQ_S_W_PH
:
23431 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23433 case OPC_DPSQX_S_W_PH
:
23435 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23437 case OPC_DPSQX_SA_W_PH
:
23439 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23441 case OPC_MULSAQ_S_W_PH
:
23443 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23445 case OPC_DPAQ_SA_L_W
:
23447 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23449 case OPC_DPSQ_SA_L_W
:
23451 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23453 case OPC_MAQ_S_W_PHL
:
23455 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23457 case OPC_MAQ_S_W_PHR
:
23459 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23461 case OPC_MAQ_SA_W_PHL
:
23463 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23465 case OPC_MAQ_SA_W_PHR
:
23467 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23469 case OPC_MULSA_W_PH
:
23471 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23475 #ifdef TARGET_MIPS64
23476 case OPC_DPAQ_W_QH_DSP
:
23478 int ac
= ret
& 0x03;
23479 tcg_gen_movi_i32(t0
, ac
);
23484 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23488 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23492 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23496 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23500 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23502 case OPC_DPAQ_S_W_QH
:
23504 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23506 case OPC_DPAQ_SA_L_PW
:
23508 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23510 case OPC_DPAU_H_OBL
:
23512 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23514 case OPC_DPAU_H_OBR
:
23516 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23520 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23522 case OPC_DPSQ_S_W_QH
:
23524 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23526 case OPC_DPSQ_SA_L_PW
:
23528 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23530 case OPC_DPSU_H_OBL
:
23532 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23534 case OPC_DPSU_H_OBR
:
23536 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23538 case OPC_MAQ_S_L_PWL
:
23540 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23542 case OPC_MAQ_S_L_PWR
:
23544 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23546 case OPC_MAQ_S_W_QHLL
:
23548 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23550 case OPC_MAQ_SA_W_QHLL
:
23552 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23554 case OPC_MAQ_S_W_QHLR
:
23556 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23558 case OPC_MAQ_SA_W_QHLR
:
23560 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23562 case OPC_MAQ_S_W_QHRL
:
23564 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23566 case OPC_MAQ_SA_W_QHRL
:
23568 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23570 case OPC_MAQ_S_W_QHRR
:
23572 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23574 case OPC_MAQ_SA_W_QHRR
:
23576 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23578 case OPC_MULSAQ_S_L_PW
:
23580 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23582 case OPC_MULSAQ_S_W_QH
:
23584 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23590 case OPC_ADDU_QB_DSP
:
23592 case OPC_MULEU_S_PH_QBL
:
23594 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23596 case OPC_MULEU_S_PH_QBR
:
23598 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23600 case OPC_MULQ_RS_PH
:
23602 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23604 case OPC_MULEQ_S_W_PHL
:
23606 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23608 case OPC_MULEQ_S_W_PHR
:
23610 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23612 case OPC_MULQ_S_PH
:
23614 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23618 #ifdef TARGET_MIPS64
23619 case OPC_ADDU_OB_DSP
:
23621 case OPC_MULEQ_S_PW_QHL
:
23623 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23625 case OPC_MULEQ_S_PW_QHR
:
23627 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23629 case OPC_MULEU_S_QH_OBL
:
23631 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23633 case OPC_MULEU_S_QH_OBR
:
23635 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23637 case OPC_MULQ_RS_QH
:
23639 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23646 tcg_temp_free_i32(t0
);
23647 tcg_temp_free(v1_t
);
23648 tcg_temp_free(v2_t
);
23651 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23659 /* Treat as NOP. */
23663 t0
= tcg_temp_new();
23664 val_t
= tcg_temp_new();
23665 gen_load_gpr(val_t
, val
);
23668 case OPC_ABSQ_S_PH_DSP
:
23672 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
23677 target_long result
;
23678 imm
= (ctx
->opcode
>> 16) & 0xFF;
23679 result
= (uint32_t)imm
<< 24 |
23680 (uint32_t)imm
<< 16 |
23681 (uint32_t)imm
<< 8 |
23683 result
= (int32_t)result
;
23684 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
23689 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23690 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23691 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23692 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23693 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23694 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23699 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23700 imm
= (int16_t)(imm
<< 6) >> 6;
23701 tcg_gen_movi_tl(cpu_gpr
[ret
], \
23702 (target_long
)((int32_t)imm
<< 16 | \
23708 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23709 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23710 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23711 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23715 #ifdef TARGET_MIPS64
23716 case OPC_ABSQ_S_QH_DSP
:
23723 imm
= (ctx
->opcode
>> 16) & 0xFF;
23724 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
23725 temp
= (temp
<< 16) | temp
;
23726 temp
= (temp
<< 32) | temp
;
23727 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23735 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23736 imm
= (int16_t)(imm
<< 6) >> 6;
23737 temp
= ((target_long
)imm
<< 32) \
23738 | ((target_long
)imm
& 0xFFFFFFFF);
23739 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23747 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23748 imm
= (int16_t)(imm
<< 6) >> 6;
23750 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
23751 ((uint64_t)(uint16_t)imm
<< 32) |
23752 ((uint64_t)(uint16_t)imm
<< 16) |
23753 (uint64_t)(uint16_t)imm
;
23754 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23759 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23760 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23761 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23762 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23763 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23764 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23765 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23769 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
23770 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23771 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23775 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23776 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23777 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23778 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23779 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23786 tcg_temp_free(val_t
);
23789 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
23790 uint32_t op1
, uint32_t op2
,
23791 int ret
, int v1
, int v2
, int check_ret
)
23797 if ((ret
== 0) && (check_ret
== 1)) {
23798 /* Treat as NOP. */
23802 t1
= tcg_temp_new();
23803 v1_t
= tcg_temp_new();
23804 v2_t
= tcg_temp_new();
23806 gen_load_gpr(v1_t
, v1
);
23807 gen_load_gpr(v2_t
, v2
);
23810 case OPC_CMPU_EQ_QB_DSP
:
23812 case OPC_CMPU_EQ_QB
:
23814 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
23816 case OPC_CMPU_LT_QB
:
23818 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
23820 case OPC_CMPU_LE_QB
:
23822 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
23824 case OPC_CMPGU_EQ_QB
:
23826 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23828 case OPC_CMPGU_LT_QB
:
23830 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23832 case OPC_CMPGU_LE_QB
:
23834 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23836 case OPC_CMPGDU_EQ_QB
:
23838 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
23839 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23840 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23841 tcg_gen_shli_tl(t1
, t1
, 24);
23842 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23844 case OPC_CMPGDU_LT_QB
:
23846 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
23847 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23848 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23849 tcg_gen_shli_tl(t1
, t1
, 24);
23850 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23852 case OPC_CMPGDU_LE_QB
:
23854 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
23855 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23856 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23857 tcg_gen_shli_tl(t1
, t1
, 24);
23858 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23860 case OPC_CMP_EQ_PH
:
23862 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
23864 case OPC_CMP_LT_PH
:
23866 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
23868 case OPC_CMP_LE_PH
:
23870 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
23874 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23878 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23880 case OPC_PACKRL_PH
:
23882 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23886 #ifdef TARGET_MIPS64
23887 case OPC_CMPU_EQ_OB_DSP
:
23889 case OPC_CMP_EQ_PW
:
23891 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
23893 case OPC_CMP_LT_PW
:
23895 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
23897 case OPC_CMP_LE_PW
:
23899 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
23901 case OPC_CMP_EQ_QH
:
23903 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
23905 case OPC_CMP_LT_QH
:
23907 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
23909 case OPC_CMP_LE_QH
:
23911 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
23913 case OPC_CMPGDU_EQ_OB
:
23915 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23917 case OPC_CMPGDU_LT_OB
:
23919 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23921 case OPC_CMPGDU_LE_OB
:
23923 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23925 case OPC_CMPGU_EQ_OB
:
23927 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23929 case OPC_CMPGU_LT_OB
:
23931 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23933 case OPC_CMPGU_LE_OB
:
23935 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23937 case OPC_CMPU_EQ_OB
:
23939 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
23941 case OPC_CMPU_LT_OB
:
23943 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
23945 case OPC_CMPU_LE_OB
:
23947 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
23949 case OPC_PACKRL_PW
:
23951 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23955 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23959 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23963 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23971 tcg_temp_free(v1_t
);
23972 tcg_temp_free(v2_t
);
23975 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
23976 uint32_t op1
, int rt
, int rs
, int sa
)
23983 /* Treat as NOP. */
23987 t0
= tcg_temp_new();
23988 gen_load_gpr(t0
, rs
);
23991 case OPC_APPEND_DSP
:
23992 switch (MASK_APPEND(ctx
->opcode
)) {
23995 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
23997 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24001 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24002 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24003 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
24004 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24006 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24010 if (sa
!= 0 && sa
!= 2) {
24011 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24012 tcg_gen_ext32u_tl(t0
, t0
);
24013 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
24014 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24016 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24018 default: /* Invalid */
24019 MIPS_INVAL("MASK APPEND");
24020 generate_exception_end(ctx
, EXCP_RI
);
24024 #ifdef TARGET_MIPS64
24025 case OPC_DAPPEND_DSP
:
24026 switch (MASK_DAPPEND(ctx
->opcode
)) {
24029 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
24033 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
24034 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
24035 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
24039 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24040 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
24041 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24046 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
24047 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24048 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
24049 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24052 default: /* Invalid */
24053 MIPS_INVAL("MASK DAPPEND");
24054 generate_exception_end(ctx
, EXCP_RI
);
24063 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24064 int ret
, int v1
, int v2
, int check_ret
)
24073 if ((ret
== 0) && (check_ret
== 1)) {
24074 /* Treat as NOP. */
24078 t0
= tcg_temp_new();
24079 t1
= tcg_temp_new();
24080 v1_t
= tcg_temp_new();
24081 v2_t
= tcg_temp_new();
24083 gen_load_gpr(v1_t
, v1
);
24084 gen_load_gpr(v2_t
, v2
);
24087 case OPC_EXTR_W_DSP
:
24091 tcg_gen_movi_tl(t0
, v2
);
24092 tcg_gen_movi_tl(t1
, v1
);
24093 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24096 tcg_gen_movi_tl(t0
, v2
);
24097 tcg_gen_movi_tl(t1
, v1
);
24098 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24100 case OPC_EXTR_RS_W
:
24101 tcg_gen_movi_tl(t0
, v2
);
24102 tcg_gen_movi_tl(t1
, v1
);
24103 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24106 tcg_gen_movi_tl(t0
, v2
);
24107 tcg_gen_movi_tl(t1
, v1
);
24108 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24110 case OPC_EXTRV_S_H
:
24111 tcg_gen_movi_tl(t0
, v2
);
24112 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24115 tcg_gen_movi_tl(t0
, v2
);
24116 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24118 case OPC_EXTRV_R_W
:
24119 tcg_gen_movi_tl(t0
, v2
);
24120 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24122 case OPC_EXTRV_RS_W
:
24123 tcg_gen_movi_tl(t0
, v2
);
24124 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24127 tcg_gen_movi_tl(t0
, v2
);
24128 tcg_gen_movi_tl(t1
, v1
);
24129 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24132 tcg_gen_movi_tl(t0
, v2
);
24133 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24136 tcg_gen_movi_tl(t0
, v2
);
24137 tcg_gen_movi_tl(t1
, v1
);
24138 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24141 tcg_gen_movi_tl(t0
, v2
);
24142 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24145 imm
= (ctx
->opcode
>> 20) & 0x3F;
24146 tcg_gen_movi_tl(t0
, ret
);
24147 tcg_gen_movi_tl(t1
, imm
);
24148 gen_helper_shilo(t0
, t1
, cpu_env
);
24151 tcg_gen_movi_tl(t0
, ret
);
24152 gen_helper_shilo(t0
, v1_t
, cpu_env
);
24155 tcg_gen_movi_tl(t0
, ret
);
24156 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
24159 imm
= (ctx
->opcode
>> 11) & 0x3FF;
24160 tcg_gen_movi_tl(t0
, imm
);
24161 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
24164 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24165 tcg_gen_movi_tl(t0
, imm
);
24166 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
24170 #ifdef TARGET_MIPS64
24171 case OPC_DEXTR_W_DSP
:
24175 tcg_gen_movi_tl(t0
, ret
);
24176 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
24180 int shift
= (ctx
->opcode
>> 19) & 0x7F;
24181 int ac
= (ctx
->opcode
>> 11) & 0x03;
24182 tcg_gen_movi_tl(t0
, shift
);
24183 tcg_gen_movi_tl(t1
, ac
);
24184 gen_helper_dshilo(t0
, t1
, cpu_env
);
24189 int ac
= (ctx
->opcode
>> 11) & 0x03;
24190 tcg_gen_movi_tl(t0
, ac
);
24191 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24195 tcg_gen_movi_tl(t0
, v2
);
24196 tcg_gen_movi_tl(t1
, v1
);
24198 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24201 tcg_gen_movi_tl(t0
, v2
);
24202 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24205 tcg_gen_movi_tl(t0
, v2
);
24206 tcg_gen_movi_tl(t1
, v1
);
24207 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24210 tcg_gen_movi_tl(t0
, v2
);
24211 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24214 tcg_gen_movi_tl(t0
, v2
);
24215 tcg_gen_movi_tl(t1
, v1
);
24216 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24218 case OPC_DEXTR_R_L
:
24219 tcg_gen_movi_tl(t0
, v2
);
24220 tcg_gen_movi_tl(t1
, v1
);
24221 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24223 case OPC_DEXTR_RS_L
:
24224 tcg_gen_movi_tl(t0
, v2
);
24225 tcg_gen_movi_tl(t1
, v1
);
24226 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24229 tcg_gen_movi_tl(t0
, v2
);
24230 tcg_gen_movi_tl(t1
, v1
);
24231 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24233 case OPC_DEXTR_R_W
:
24234 tcg_gen_movi_tl(t0
, v2
);
24235 tcg_gen_movi_tl(t1
, v1
);
24236 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24238 case OPC_DEXTR_RS_W
:
24239 tcg_gen_movi_tl(t0
, v2
);
24240 tcg_gen_movi_tl(t1
, v1
);
24241 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24243 case OPC_DEXTR_S_H
:
24244 tcg_gen_movi_tl(t0
, v2
);
24245 tcg_gen_movi_tl(t1
, v1
);
24246 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24248 case OPC_DEXTRV_S_H
:
24249 tcg_gen_movi_tl(t0
, v2
);
24250 tcg_gen_movi_tl(t1
, v1
);
24251 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24254 tcg_gen_movi_tl(t0
, v2
);
24255 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24257 case OPC_DEXTRV_R_L
:
24258 tcg_gen_movi_tl(t0
, v2
);
24259 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24261 case OPC_DEXTRV_RS_L
:
24262 tcg_gen_movi_tl(t0
, v2
);
24263 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24266 tcg_gen_movi_tl(t0
, v2
);
24267 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24269 case OPC_DEXTRV_R_W
:
24270 tcg_gen_movi_tl(t0
, v2
);
24271 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24273 case OPC_DEXTRV_RS_W
:
24274 tcg_gen_movi_tl(t0
, v2
);
24275 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24284 tcg_temp_free(v1_t
);
24285 tcg_temp_free(v2_t
);
24288 /* End MIPSDSP functions. */
24290 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24292 int rs
, rt
, rd
, sa
;
24295 rs
= (ctx
->opcode
>> 21) & 0x1f;
24296 rt
= (ctx
->opcode
>> 16) & 0x1f;
24297 rd
= (ctx
->opcode
>> 11) & 0x1f;
24298 sa
= (ctx
->opcode
>> 6) & 0x1f;
24300 op1
= MASK_SPECIAL(ctx
->opcode
);
24303 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24309 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24319 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24322 MIPS_INVAL("special_r6 muldiv");
24323 generate_exception_end(ctx
, EXCP_RI
);
24329 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24333 if (rt
== 0 && sa
== 1) {
24335 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24336 * We need additionally to check other fields.
24338 gen_cl(ctx
, op1
, rd
, rs
);
24340 generate_exception_end(ctx
, EXCP_RI
);
24344 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24345 gen_helper_do_semihosting(cpu_env
);
24347 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24348 generate_exception_end(ctx
, EXCP_RI
);
24350 generate_exception_end(ctx
, EXCP_DBp
);
24354 #if defined(TARGET_MIPS64)
24356 check_mips_64(ctx
);
24357 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24361 if (rt
== 0 && sa
== 1) {
24363 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24364 * We need additionally to check other fields.
24366 check_mips_64(ctx
);
24367 gen_cl(ctx
, op1
, rd
, rs
);
24369 generate_exception_end(ctx
, EXCP_RI
);
24377 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24387 check_mips_64(ctx
);
24388 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24391 MIPS_INVAL("special_r6 muldiv");
24392 generate_exception_end(ctx
, EXCP_RI
);
24397 default: /* Invalid */
24398 MIPS_INVAL("special_r6");
24399 generate_exception_end(ctx
, EXCP_RI
);
24404 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24406 int rs
= extract32(ctx
->opcode
, 21, 5);
24407 int rt
= extract32(ctx
->opcode
, 16, 5);
24408 int rd
= extract32(ctx
->opcode
, 11, 5);
24409 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24412 case OPC_MOVN
: /* Conditional move */
24414 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24416 case OPC_MFHI
: /* Move from HI/LO */
24418 gen_HILO(ctx
, op1
, 0, rd
);
24421 case OPC_MTLO
: /* Move to HI/LO */
24422 gen_HILO(ctx
, op1
, 0, rs
);
24426 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24430 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24432 #if defined(TARGET_MIPS64)
24437 check_insn_opc_user_only(ctx
, INSN_R5900
);
24438 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24442 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24444 default: /* Invalid */
24445 MIPS_INVAL("special_tx79");
24446 generate_exception_end(ctx
, EXCP_RI
);
24451 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24453 int rs
, rt
, rd
, sa
;
24456 rs
= (ctx
->opcode
>> 21) & 0x1f;
24457 rt
= (ctx
->opcode
>> 16) & 0x1f;
24458 rd
= (ctx
->opcode
>> 11) & 0x1f;
24459 sa
= (ctx
->opcode
>> 6) & 0x1f;
24461 op1
= MASK_SPECIAL(ctx
->opcode
);
24463 case OPC_MOVN
: /* Conditional move */
24465 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
24466 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24467 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24469 case OPC_MFHI
: /* Move from HI/LO */
24471 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24474 case OPC_MTLO
: /* Move to HI/LO */
24475 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24478 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
24479 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24480 check_cp1_enabled(ctx
);
24481 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24482 (ctx
->opcode
>> 16) & 1);
24484 generate_exception_err(ctx
, EXCP_CpU
, 1);
24490 check_insn(ctx
, INSN_VR54XX
);
24491 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24492 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24494 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24499 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24501 #if defined(TARGET_MIPS64)
24506 check_insn(ctx
, ISA_MIPS3
);
24507 check_mips_64(ctx
);
24508 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24512 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24515 #ifdef MIPS_STRICT_STANDARD
24516 MIPS_INVAL("SPIM");
24517 generate_exception_end(ctx
, EXCP_RI
);
24519 /* Implemented as RI exception for now. */
24520 MIPS_INVAL("spim (unofficial)");
24521 generate_exception_end(ctx
, EXCP_RI
);
24524 default: /* Invalid */
24525 MIPS_INVAL("special_legacy");
24526 generate_exception_end(ctx
, EXCP_RI
);
24531 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24533 int rs
, rt
, rd
, sa
;
24536 rs
= (ctx
->opcode
>> 21) & 0x1f;
24537 rt
= (ctx
->opcode
>> 16) & 0x1f;
24538 rd
= (ctx
->opcode
>> 11) & 0x1f;
24539 sa
= (ctx
->opcode
>> 6) & 0x1f;
24541 op1
= MASK_SPECIAL(ctx
->opcode
);
24543 case OPC_SLL
: /* Shift with immediate */
24544 if (sa
== 5 && rd
== 0 &&
24545 rs
== 0 && rt
== 0) { /* PAUSE */
24546 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
24547 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24548 generate_exception_end(ctx
, EXCP_RI
);
24554 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24557 switch ((ctx
->opcode
>> 21) & 0x1f) {
24559 /* rotr is decoded as srl on non-R2 CPUs */
24560 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24565 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24568 generate_exception_end(ctx
, EXCP_RI
);
24576 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24578 case OPC_SLLV
: /* Shifts */
24580 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24583 switch ((ctx
->opcode
>> 6) & 0x1f) {
24585 /* rotrv is decoded as srlv on non-R2 CPUs */
24586 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24591 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24594 generate_exception_end(ctx
, EXCP_RI
);
24598 case OPC_SLT
: /* Set on less than */
24600 gen_slt(ctx
, op1
, rd
, rs
, rt
);
24602 case OPC_AND
: /* Logic*/
24606 gen_logic(ctx
, op1
, rd
, rs
, rt
);
24609 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24611 case OPC_TGE
: /* Traps */
24617 check_insn(ctx
, ISA_MIPS2
);
24618 gen_trap(ctx
, op1
, rs
, rt
, -1);
24620 case OPC_LSA
: /* OPC_PMON */
24621 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
24622 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
24623 decode_opc_special_r6(env
, ctx
);
24625 /* Pmon entry point, also R4010 selsl */
24626 #ifdef MIPS_STRICT_STANDARD
24627 MIPS_INVAL("PMON / selsl");
24628 generate_exception_end(ctx
, EXCP_RI
);
24630 gen_helper_0e0i(pmon
, sa
);
24635 generate_exception_end(ctx
, EXCP_SYSCALL
);
24638 generate_exception_end(ctx
, EXCP_BREAK
);
24641 check_insn(ctx
, ISA_MIPS2
);
24642 gen_sync(extract32(ctx
->opcode
, 6, 5));
24645 #if defined(TARGET_MIPS64)
24646 /* MIPS64 specific opcodes */
24651 check_insn(ctx
, ISA_MIPS3
);
24652 check_mips_64(ctx
);
24653 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24656 switch ((ctx
->opcode
>> 21) & 0x1f) {
24658 /* drotr is decoded as dsrl on non-R2 CPUs */
24659 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24664 check_insn(ctx
, ISA_MIPS3
);
24665 check_mips_64(ctx
);
24666 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24669 generate_exception_end(ctx
, EXCP_RI
);
24674 switch ((ctx
->opcode
>> 21) & 0x1f) {
24676 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24677 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24682 check_insn(ctx
, ISA_MIPS3
);
24683 check_mips_64(ctx
);
24684 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24687 generate_exception_end(ctx
, EXCP_RI
);
24695 check_insn(ctx
, ISA_MIPS3
);
24696 check_mips_64(ctx
);
24697 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24701 check_insn(ctx
, ISA_MIPS3
);
24702 check_mips_64(ctx
);
24703 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24706 switch ((ctx
->opcode
>> 6) & 0x1f) {
24708 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24709 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24714 check_insn(ctx
, ISA_MIPS3
);
24715 check_mips_64(ctx
);
24716 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24719 generate_exception_end(ctx
, EXCP_RI
);
24724 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
24725 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
24726 decode_opc_special_r6(env
, ctx
);
24731 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
24732 decode_opc_special_r6(env
, ctx
);
24733 } else if (ctx
->insn_flags
& INSN_R5900
) {
24734 decode_opc_special_tx79(env
, ctx
);
24736 decode_opc_special_legacy(env
, ctx
);
24742 #if defined(TARGET_MIPS64)
24746 * MMI (MultiMedia Interface) ASE instructions
24747 * ===========================================
24751 * MMI instructions category: data communication
24752 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24754 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24755 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24756 * PCPYUD PEXEH PEXTLW PPACW
24765 * Parallel Copy Halfword
24767 * 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
24768 * +-----------+---------+---------+---------+---------+-----------+
24769 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
24770 * +-----------+---------+---------+---------+---------+-----------+
24772 static void gen_mmi_pcpyh(DisasContext
*ctx
)
24774 uint32_t pd
, rt
, rd
;
24777 opcode
= ctx
->opcode
;
24779 pd
= extract32(opcode
, 21, 5);
24780 rt
= extract32(opcode
, 16, 5);
24781 rd
= extract32(opcode
, 11, 5);
24783 if (unlikely(pd
!= 0)) {
24784 generate_exception_end(ctx
, EXCP_RI
);
24785 } else if (rd
== 0) {
24787 } else if (rt
== 0) {
24788 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24789 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24791 TCGv_i64 t0
= tcg_temp_new();
24792 TCGv_i64 t1
= tcg_temp_new();
24793 uint64_t mask
= (1ULL << 16) - 1;
24795 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
24796 tcg_gen_movi_i64(t1
, 0);
24797 tcg_gen_or_i64(t1
, t0
, t1
);
24798 tcg_gen_shli_i64(t0
, t0
, 16);
24799 tcg_gen_or_i64(t1
, t0
, t1
);
24800 tcg_gen_shli_i64(t0
, t0
, 16);
24801 tcg_gen_or_i64(t1
, t0
, t1
);
24802 tcg_gen_shli_i64(t0
, t0
, 16);
24803 tcg_gen_or_i64(t1
, t0
, t1
);
24805 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
24807 tcg_gen_andi_i64(t0
, cpu_mmr
[rt
], mask
);
24808 tcg_gen_movi_i64(t1
, 0);
24809 tcg_gen_or_i64(t1
, t0
, t1
);
24810 tcg_gen_shli_i64(t0
, t0
, 16);
24811 tcg_gen_or_i64(t1
, t0
, t1
);
24812 tcg_gen_shli_i64(t0
, t0
, 16);
24813 tcg_gen_or_i64(t1
, t0
, t1
);
24814 tcg_gen_shli_i64(t0
, t0
, 16);
24815 tcg_gen_or_i64(t1
, t0
, t1
);
24817 tcg_gen_mov_i64(cpu_mmr
[rd
], t1
);
24825 * PCPYLD rd, rs, rt
24827 * Parallel Copy Lower Doubleword
24829 * 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
24830 * +-----------+---------+---------+---------+---------+-----------+
24831 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
24832 * +-----------+---------+---------+---------+---------+-----------+
24834 static void gen_mmi_pcpyld(DisasContext
*ctx
)
24836 uint32_t rs
, rt
, rd
;
24839 opcode
= ctx
->opcode
;
24841 rs
= extract32(opcode
, 21, 5);
24842 rt
= extract32(opcode
, 16, 5);
24843 rd
= extract32(opcode
, 11, 5);
24849 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24851 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_gpr
[rs
]);
24854 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24857 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
24864 * PCPYUD rd, rs, rt
24866 * Parallel Copy Upper Doubleword
24868 * 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
24869 * +-----------+---------+---------+---------+---------+-----------+
24870 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
24871 * +-----------+---------+---------+---------+---------+-----------+
24873 static void gen_mmi_pcpyud(DisasContext
*ctx
)
24875 uint32_t rs
, rt
, rd
;
24878 opcode
= ctx
->opcode
;
24880 rs
= extract32(opcode
, 21, 5);
24881 rt
= extract32(opcode
, 16, 5);
24882 rd
= extract32(opcode
, 11, 5);
24888 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24890 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_mmr
[rs
]);
24893 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24896 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_mmr
[rt
]);
24905 #if !defined(TARGET_MIPS64)
24907 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24908 #define MXU_APTN1_A 0
24909 #define MXU_APTN1_S 1
24911 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24912 #define MXU_APTN2_AA 0
24913 #define MXU_APTN2_AS 1
24914 #define MXU_APTN2_SA 2
24915 #define MXU_APTN2_SS 3
24917 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24918 #define MXU_EPTN2_AA 0
24919 #define MXU_EPTN2_AS 1
24920 #define MXU_EPTN2_SA 2
24921 #define MXU_EPTN2_SS 3
24923 /* MXU operand getting pattern 'optn2' */
24924 #define MXU_OPTN2_PTN0 0
24925 #define MXU_OPTN2_PTN1 1
24926 #define MXU_OPTN2_PTN2 2
24927 #define MXU_OPTN2_PTN3 3
24928 /* alternative naming scheme for 'optn2' */
24929 #define MXU_OPTN2_WW 0
24930 #define MXU_OPTN2_LW 1
24931 #define MXU_OPTN2_HW 2
24932 #define MXU_OPTN2_XW 3
24934 /* MXU operand getting pattern 'optn3' */
24935 #define MXU_OPTN3_PTN0 0
24936 #define MXU_OPTN3_PTN1 1
24937 #define MXU_OPTN3_PTN2 2
24938 #define MXU_OPTN3_PTN3 3
24939 #define MXU_OPTN3_PTN4 4
24940 #define MXU_OPTN3_PTN5 5
24941 #define MXU_OPTN3_PTN6 6
24942 #define MXU_OPTN3_PTN7 7
24946 * S32I2M XRa, rb - Register move from GRF to XRF
24948 static void gen_mxu_s32i2m(DisasContext
*ctx
)
24953 t0
= tcg_temp_new();
24955 XRa
= extract32(ctx
->opcode
, 6, 5);
24956 Rb
= extract32(ctx
->opcode
, 16, 5);
24958 gen_load_gpr(t0
, Rb
);
24960 gen_store_mxu_gpr(t0
, XRa
);
24961 } else if (XRa
== 16) {
24962 gen_store_mxu_cr(t0
);
24969 * S32M2I XRa, rb - Register move from XRF to GRF
24971 static void gen_mxu_s32m2i(DisasContext
*ctx
)
24976 t0
= tcg_temp_new();
24978 XRa
= extract32(ctx
->opcode
, 6, 5);
24979 Rb
= extract32(ctx
->opcode
, 16, 5);
24982 gen_load_mxu_gpr(t0
, XRa
);
24983 } else if (XRa
== 16) {
24984 gen_load_mxu_cr(t0
);
24987 gen_store_gpr(t0
, Rb
);
24993 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24995 static void gen_mxu_s8ldd(DisasContext
*ctx
)
24998 uint32_t XRa
, Rb
, s8
, optn3
;
25000 t0
= tcg_temp_new();
25001 t1
= tcg_temp_new();
25003 XRa
= extract32(ctx
->opcode
, 6, 4);
25004 s8
= extract32(ctx
->opcode
, 10, 8);
25005 optn3
= extract32(ctx
->opcode
, 18, 3);
25006 Rb
= extract32(ctx
->opcode
, 21, 5);
25008 gen_load_gpr(t0
, Rb
);
25009 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
25012 /* XRa[7:0] = tmp8 */
25013 case MXU_OPTN3_PTN0
:
25014 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25015 gen_load_mxu_gpr(t0
, XRa
);
25016 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
25018 /* XRa[15:8] = tmp8 */
25019 case MXU_OPTN3_PTN1
:
25020 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25021 gen_load_mxu_gpr(t0
, XRa
);
25022 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
25024 /* XRa[23:16] = tmp8 */
25025 case MXU_OPTN3_PTN2
:
25026 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25027 gen_load_mxu_gpr(t0
, XRa
);
25028 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
25030 /* XRa[31:24] = tmp8 */
25031 case MXU_OPTN3_PTN3
:
25032 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25033 gen_load_mxu_gpr(t0
, XRa
);
25034 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
25036 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25037 case MXU_OPTN3_PTN4
:
25038 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25039 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25041 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25042 case MXU_OPTN3_PTN5
:
25043 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25044 tcg_gen_shli_tl(t1
, t1
, 8);
25045 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25047 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25048 case MXU_OPTN3_PTN6
:
25049 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
25050 tcg_gen_mov_tl(t0
, t1
);
25051 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
25052 tcg_gen_shli_tl(t1
, t1
, 16);
25053 tcg_gen_or_tl(t0
, t0
, t1
);
25055 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25056 case MXU_OPTN3_PTN7
:
25057 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25058 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
25059 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25063 gen_store_mxu_gpr(t0
, XRa
);
25070 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25072 static void gen_mxu_d16mul(DisasContext
*ctx
)
25074 TCGv t0
, t1
, t2
, t3
;
25075 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
25077 t0
= tcg_temp_new();
25078 t1
= tcg_temp_new();
25079 t2
= tcg_temp_new();
25080 t3
= tcg_temp_new();
25082 XRa
= extract32(ctx
->opcode
, 6, 4);
25083 XRb
= extract32(ctx
->opcode
, 10, 4);
25084 XRc
= extract32(ctx
->opcode
, 14, 4);
25085 XRd
= extract32(ctx
->opcode
, 18, 4);
25086 optn2
= extract32(ctx
->opcode
, 22, 2);
25088 gen_load_mxu_gpr(t1
, XRb
);
25089 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25090 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25091 gen_load_mxu_gpr(t3
, XRc
);
25092 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25093 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25096 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25097 tcg_gen_mul_tl(t3
, t1
, t3
);
25098 tcg_gen_mul_tl(t2
, t0
, t2
);
25100 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25101 tcg_gen_mul_tl(t3
, t0
, t3
);
25102 tcg_gen_mul_tl(t2
, t0
, t2
);
25104 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25105 tcg_gen_mul_tl(t3
, t1
, t3
);
25106 tcg_gen_mul_tl(t2
, t1
, t2
);
25108 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25109 tcg_gen_mul_tl(t3
, t0
, t3
);
25110 tcg_gen_mul_tl(t2
, t1
, t2
);
25113 gen_store_mxu_gpr(t3
, XRa
);
25114 gen_store_mxu_gpr(t2
, XRd
);
25123 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25126 static void gen_mxu_d16mac(DisasContext
*ctx
)
25128 TCGv t0
, t1
, t2
, t3
;
25129 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
25131 t0
= tcg_temp_new();
25132 t1
= tcg_temp_new();
25133 t2
= tcg_temp_new();
25134 t3
= tcg_temp_new();
25136 XRa
= extract32(ctx
->opcode
, 6, 4);
25137 XRb
= extract32(ctx
->opcode
, 10, 4);
25138 XRc
= extract32(ctx
->opcode
, 14, 4);
25139 XRd
= extract32(ctx
->opcode
, 18, 4);
25140 optn2
= extract32(ctx
->opcode
, 22, 2);
25141 aptn2
= extract32(ctx
->opcode
, 24, 2);
25143 gen_load_mxu_gpr(t1
, XRb
);
25144 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25145 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25147 gen_load_mxu_gpr(t3
, XRc
);
25148 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25149 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25152 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25153 tcg_gen_mul_tl(t3
, t1
, t3
);
25154 tcg_gen_mul_tl(t2
, t0
, t2
);
25156 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25157 tcg_gen_mul_tl(t3
, t0
, t3
);
25158 tcg_gen_mul_tl(t2
, t0
, t2
);
25160 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25161 tcg_gen_mul_tl(t3
, t1
, t3
);
25162 tcg_gen_mul_tl(t2
, t1
, t2
);
25164 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25165 tcg_gen_mul_tl(t3
, t0
, t3
);
25166 tcg_gen_mul_tl(t2
, t1
, t2
);
25169 gen_load_mxu_gpr(t0
, XRa
);
25170 gen_load_mxu_gpr(t1
, XRd
);
25174 tcg_gen_add_tl(t3
, t0
, t3
);
25175 tcg_gen_add_tl(t2
, t1
, t2
);
25178 tcg_gen_add_tl(t3
, t0
, t3
);
25179 tcg_gen_sub_tl(t2
, t1
, t2
);
25182 tcg_gen_sub_tl(t3
, t0
, t3
);
25183 tcg_gen_add_tl(t2
, t1
, t2
);
25186 tcg_gen_sub_tl(t3
, t0
, t3
);
25187 tcg_gen_sub_tl(t2
, t1
, t2
);
25190 gen_store_mxu_gpr(t3
, XRa
);
25191 gen_store_mxu_gpr(t2
, XRd
);
25200 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25201 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25203 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25205 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25206 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25208 t0
= tcg_temp_new();
25209 t1
= tcg_temp_new();
25210 t2
= tcg_temp_new();
25211 t3
= tcg_temp_new();
25212 t4
= tcg_temp_new();
25213 t5
= tcg_temp_new();
25214 t6
= tcg_temp_new();
25215 t7
= tcg_temp_new();
25217 XRa
= extract32(ctx
->opcode
, 6, 4);
25218 XRb
= extract32(ctx
->opcode
, 10, 4);
25219 XRc
= extract32(ctx
->opcode
, 14, 4);
25220 XRd
= extract32(ctx
->opcode
, 18, 4);
25221 sel
= extract32(ctx
->opcode
, 22, 2);
25223 gen_load_mxu_gpr(t3
, XRb
);
25224 gen_load_mxu_gpr(t7
, XRc
);
25228 tcg_gen_ext8s_tl(t0
, t3
);
25229 tcg_gen_shri_tl(t3
, t3
, 8);
25230 tcg_gen_ext8s_tl(t1
, t3
);
25231 tcg_gen_shri_tl(t3
, t3
, 8);
25232 tcg_gen_ext8s_tl(t2
, t3
);
25233 tcg_gen_shri_tl(t3
, t3
, 8);
25234 tcg_gen_ext8s_tl(t3
, t3
);
25237 tcg_gen_ext8u_tl(t0
, t3
);
25238 tcg_gen_shri_tl(t3
, t3
, 8);
25239 tcg_gen_ext8u_tl(t1
, t3
);
25240 tcg_gen_shri_tl(t3
, t3
, 8);
25241 tcg_gen_ext8u_tl(t2
, t3
);
25242 tcg_gen_shri_tl(t3
, t3
, 8);
25243 tcg_gen_ext8u_tl(t3
, t3
);
25246 tcg_gen_ext8u_tl(t4
, t7
);
25247 tcg_gen_shri_tl(t7
, t7
, 8);
25248 tcg_gen_ext8u_tl(t5
, t7
);
25249 tcg_gen_shri_tl(t7
, t7
, 8);
25250 tcg_gen_ext8u_tl(t6
, t7
);
25251 tcg_gen_shri_tl(t7
, t7
, 8);
25252 tcg_gen_ext8u_tl(t7
, t7
);
25254 tcg_gen_mul_tl(t0
, t0
, t4
);
25255 tcg_gen_mul_tl(t1
, t1
, t5
);
25256 tcg_gen_mul_tl(t2
, t2
, t6
);
25257 tcg_gen_mul_tl(t3
, t3
, t7
);
25259 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25260 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25261 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25262 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25264 tcg_gen_shli_tl(t1
, t1
, 16);
25265 tcg_gen_shli_tl(t3
, t3
, 16);
25267 tcg_gen_or_tl(t0
, t0
, t1
);
25268 tcg_gen_or_tl(t1
, t2
, t3
);
25270 gen_store_mxu_gpr(t0
, XRd
);
25271 gen_store_mxu_gpr(t1
, XRa
);
25284 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25285 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25287 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25290 uint32_t XRa
, Rb
, s12
, sel
;
25292 t0
= tcg_temp_new();
25293 t1
= tcg_temp_new();
25295 XRa
= extract32(ctx
->opcode
, 6, 4);
25296 s12
= extract32(ctx
->opcode
, 10, 10);
25297 sel
= extract32(ctx
->opcode
, 20, 1);
25298 Rb
= extract32(ctx
->opcode
, 21, 5);
25300 gen_load_gpr(t0
, Rb
);
25302 tcg_gen_movi_tl(t1
, s12
);
25303 tcg_gen_shli_tl(t1
, t1
, 2);
25305 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25307 tcg_gen_add_tl(t1
, t0
, t1
);
25308 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25312 tcg_gen_bswap32_tl(t1
, t1
);
25314 gen_store_mxu_gpr(t1
, XRa
);
25322 * MXU instruction category: logic
25323 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25325 * S32NOR S32AND S32OR S32XOR
25329 * S32NOR XRa, XRb, XRc
25330 * Update XRa with the result of logical bitwise 'nor' operation
25331 * applied to the content of XRb and XRc.
25333 * 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
25334 * +-----------+---------+-----+-------+-------+-------+-----------+
25335 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25336 * +-----------+---------+-----+-------+-------+-------+-----------+
25338 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25340 uint32_t pad
, XRc
, XRb
, XRa
;
25342 pad
= extract32(ctx
->opcode
, 21, 5);
25343 XRc
= extract32(ctx
->opcode
, 14, 4);
25344 XRb
= extract32(ctx
->opcode
, 10, 4);
25345 XRa
= extract32(ctx
->opcode
, 6, 4);
25347 if (unlikely(pad
!= 0)) {
25348 /* opcode padding incorrect -> do nothing */
25349 } else if (unlikely(XRa
== 0)) {
25350 /* destination is zero register -> do nothing */
25351 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25352 /* both operands zero registers -> just set destination to all 1s */
25353 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25354 } else if (unlikely(XRb
== 0)) {
25355 /* XRb zero register -> just set destination to the negation of XRc */
25356 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25357 } else if (unlikely(XRc
== 0)) {
25358 /* XRa zero register -> just set destination to the negation of XRb */
25359 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25360 } else if (unlikely(XRb
== XRc
)) {
25361 /* both operands same -> just set destination to the negation of XRb */
25362 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25364 /* the most general case */
25365 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25370 * S32AND XRa, XRb, XRc
25371 * Update XRa with the result of logical bitwise 'and' operation
25372 * applied to the content of XRb and XRc.
25374 * 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
25375 * +-----------+---------+-----+-------+-------+-------+-----------+
25376 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25377 * +-----------+---------+-----+-------+-------+-------+-----------+
25379 static void gen_mxu_S32AND(DisasContext
*ctx
)
25381 uint32_t pad
, XRc
, XRb
, XRa
;
25383 pad
= extract32(ctx
->opcode
, 21, 5);
25384 XRc
= extract32(ctx
->opcode
, 14, 4);
25385 XRb
= extract32(ctx
->opcode
, 10, 4);
25386 XRa
= extract32(ctx
->opcode
, 6, 4);
25388 if (unlikely(pad
!= 0)) {
25389 /* opcode padding incorrect -> do nothing */
25390 } else if (unlikely(XRa
== 0)) {
25391 /* destination is zero register -> do nothing */
25392 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25393 /* one of operands zero register -> just set destination to all 0s */
25394 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25395 } else if (unlikely(XRb
== XRc
)) {
25396 /* both operands same -> just set destination to one of them */
25397 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25399 /* the most general case */
25400 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25405 * S32OR XRa, XRb, XRc
25406 * Update XRa with the result of logical bitwise 'or' operation
25407 * applied to the content of XRb and XRc.
25409 * 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
25410 * +-----------+---------+-----+-------+-------+-------+-----------+
25411 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25412 * +-----------+---------+-----+-------+-------+-------+-----------+
25414 static void gen_mxu_S32OR(DisasContext
*ctx
)
25416 uint32_t pad
, XRc
, XRb
, XRa
;
25418 pad
= extract32(ctx
->opcode
, 21, 5);
25419 XRc
= extract32(ctx
->opcode
, 14, 4);
25420 XRb
= extract32(ctx
->opcode
, 10, 4);
25421 XRa
= extract32(ctx
->opcode
, 6, 4);
25423 if (unlikely(pad
!= 0)) {
25424 /* opcode padding incorrect -> do nothing */
25425 } else if (unlikely(XRa
== 0)) {
25426 /* destination is zero register -> do nothing */
25427 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25428 /* both operands zero registers -> just set destination to all 0s */
25429 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25430 } else if (unlikely(XRb
== 0)) {
25431 /* XRb zero register -> just set destination to the content of XRc */
25432 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25433 } else if (unlikely(XRc
== 0)) {
25434 /* XRc zero register -> just set destination to the content of XRb */
25435 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25436 } else if (unlikely(XRb
== XRc
)) {
25437 /* both operands same -> just set destination to one of them */
25438 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25440 /* the most general case */
25441 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25446 * S32XOR XRa, XRb, XRc
25447 * Update XRa with the result of logical bitwise 'xor' operation
25448 * applied to the content of XRb and XRc.
25450 * 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
25451 * +-----------+---------+-----+-------+-------+-------+-----------+
25452 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25453 * +-----------+---------+-----+-------+-------+-------+-----------+
25455 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25457 uint32_t pad
, XRc
, XRb
, XRa
;
25459 pad
= extract32(ctx
->opcode
, 21, 5);
25460 XRc
= extract32(ctx
->opcode
, 14, 4);
25461 XRb
= extract32(ctx
->opcode
, 10, 4);
25462 XRa
= extract32(ctx
->opcode
, 6, 4);
25464 if (unlikely(pad
!= 0)) {
25465 /* opcode padding incorrect -> do nothing */
25466 } else if (unlikely(XRa
== 0)) {
25467 /* destination is zero register -> do nothing */
25468 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25469 /* both operands zero registers -> just set destination to all 0s */
25470 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25471 } else if (unlikely(XRb
== 0)) {
25472 /* XRb zero register -> just set destination to the content of XRc */
25473 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25474 } else if (unlikely(XRc
== 0)) {
25475 /* XRc zero register -> just set destination to the content of XRb */
25476 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25477 } else if (unlikely(XRb
== XRc
)) {
25478 /* both operands same -> just set destination to all 0s */
25479 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25481 /* the most general case */
25482 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25488 * MXU instruction category max/min
25489 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25491 * S32MAX D16MAX Q8MAX
25492 * S32MIN D16MIN Q8MIN
25496 * S32MAX XRa, XRb, XRc
25497 * Update XRa with the maximum of signed 32-bit integers contained
25500 * S32MIN XRa, XRb, XRc
25501 * Update XRa with the minimum of signed 32-bit integers contained
25504 * 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
25505 * +-----------+---------+-----+-------+-------+-------+-----------+
25506 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25507 * +-----------+---------+-----+-------+-------+-------+-----------+
25509 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25511 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25513 pad
= extract32(ctx
->opcode
, 21, 5);
25514 opc
= extract32(ctx
->opcode
, 18, 3);
25515 XRc
= extract32(ctx
->opcode
, 14, 4);
25516 XRb
= extract32(ctx
->opcode
, 10, 4);
25517 XRa
= extract32(ctx
->opcode
, 6, 4);
25519 if (unlikely(pad
!= 0)) {
25520 /* opcode padding incorrect -> do nothing */
25521 } else if (unlikely(XRa
== 0)) {
25522 /* destination is zero register -> do nothing */
25523 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25524 /* both operands zero registers -> just set destination to zero */
25525 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25526 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25527 /* exactly one operand is zero register - find which one is not...*/
25528 uint32_t XRx
= XRb
? XRb
: XRc
;
25529 /* ...and do max/min operation with one operand 0 */
25530 if (opc
== OPC_MXU_S32MAX
) {
25531 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25533 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25535 } else if (unlikely(XRb
== XRc
)) {
25536 /* both operands same -> just set destination to one of them */
25537 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25539 /* the most general case */
25540 if (opc
== OPC_MXU_S32MAX
) {
25541 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25544 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25552 * Update XRa with the 16-bit-wise maximums of signed integers
25553 * contained in XRb and XRc.
25556 * Update XRa with the 16-bit-wise minimums of signed integers
25557 * contained in XRb and XRc.
25559 * 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
25560 * +-----------+---------+-----+-------+-------+-------+-----------+
25561 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25562 * +-----------+---------+-----+-------+-------+-------+-----------+
25564 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25566 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25568 pad
= extract32(ctx
->opcode
, 21, 5);
25569 opc
= extract32(ctx
->opcode
, 18, 3);
25570 XRc
= extract32(ctx
->opcode
, 14, 4);
25571 XRb
= extract32(ctx
->opcode
, 10, 4);
25572 XRa
= extract32(ctx
->opcode
, 6, 4);
25574 if (unlikely(pad
!= 0)) {
25575 /* opcode padding incorrect -> do nothing */
25576 } else if (unlikely(XRc
== 0)) {
25577 /* destination is zero register -> do nothing */
25578 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
25579 /* both operands zero registers -> just set destination to zero */
25580 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
25581 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
25582 /* exactly one operand is zero register - find which one is not...*/
25583 uint32_t XRx
= XRb
? XRb
: XRc
;
25584 /* ...and do half-word-wise max/min with one operand 0 */
25585 TCGv_i32 t0
= tcg_temp_new();
25586 TCGv_i32 t1
= tcg_const_i32(0);
25588 /* the left half-word first */
25589 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
25590 if (opc
== OPC_MXU_D16MAX
) {
25591 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25593 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25596 /* the right half-word */
25597 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
25598 /* move half-words to the leftmost position */
25599 tcg_gen_shli_i32(t0
, t0
, 16);
25600 /* t0 will be max/min of t0 and t1 */
25601 if (opc
== OPC_MXU_D16MAX
) {
25602 tcg_gen_smax_i32(t0
, t0
, t1
);
25604 tcg_gen_smin_i32(t0
, t0
, t1
);
25606 /* return resulting half-words to its original position */
25607 tcg_gen_shri_i32(t0
, t0
, 16);
25608 /* finaly update the destination */
25609 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25613 } else if (unlikely(XRb
== XRc
)) {
25614 /* both operands same -> just set destination to one of them */
25615 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25617 /* the most general case */
25618 TCGv_i32 t0
= tcg_temp_new();
25619 TCGv_i32 t1
= tcg_temp_new();
25621 /* the left half-word first */
25622 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
25623 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25624 if (opc
== OPC_MXU_D16MAX
) {
25625 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25627 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25630 /* the right half-word */
25631 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25632 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
25633 /* move half-words to the leftmost position */
25634 tcg_gen_shli_i32(t0
, t0
, 16);
25635 tcg_gen_shli_i32(t1
, t1
, 16);
25636 /* t0 will be max/min of t0 and t1 */
25637 if (opc
== OPC_MXU_D16MAX
) {
25638 tcg_gen_smax_i32(t0
, t0
, t1
);
25640 tcg_gen_smin_i32(t0
, t0
, t1
);
25642 /* return resulting half-words to its original position */
25643 tcg_gen_shri_i32(t0
, t0
, 16);
25644 /* finaly update the destination */
25645 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25654 * Update XRa with the 8-bit-wise maximums of signed integers
25655 * contained in XRb and XRc.
25658 * Update XRa with the 8-bit-wise minimums of signed integers
25659 * contained in XRb and XRc.
25661 * 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
25662 * +-----------+---------+-----+-------+-------+-------+-----------+
25663 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25664 * +-----------+---------+-----+-------+-------+-------+-----------+
25666 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
25668 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25670 pad
= extract32(ctx
->opcode
, 21, 5);
25671 opc
= extract32(ctx
->opcode
, 18, 3);
25672 XRc
= extract32(ctx
->opcode
, 14, 4);
25673 XRb
= extract32(ctx
->opcode
, 10, 4);
25674 XRa
= extract32(ctx
->opcode
, 6, 4);
25676 if (unlikely(pad
!= 0)) {
25677 /* opcode padding incorrect -> do nothing */
25678 } else if (unlikely(XRa
== 0)) {
25679 /* destination is zero register -> do nothing */
25680 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25681 /* both operands zero registers -> just set destination to zero */
25682 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25683 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25684 /* exactly one operand is zero register - make it be the first...*/
25685 uint32_t XRx
= XRb
? XRb
: XRc
;
25686 /* ...and do byte-wise max/min with one operand 0 */
25687 TCGv_i32 t0
= tcg_temp_new();
25688 TCGv_i32 t1
= tcg_const_i32(0);
25691 /* the leftmost byte (byte 3) first */
25692 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
25693 if (opc
== OPC_MXU_Q8MAX
) {
25694 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25696 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25699 /* bytes 2, 1, 0 */
25700 for (i
= 2; i
>= 0; i
--) {
25701 /* extract the byte */
25702 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
25703 /* move the byte to the leftmost position */
25704 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25705 /* t0 will be max/min of t0 and t1 */
25706 if (opc
== OPC_MXU_Q8MAX
) {
25707 tcg_gen_smax_i32(t0
, t0
, t1
);
25709 tcg_gen_smin_i32(t0
, t0
, t1
);
25711 /* return resulting byte to its original position */
25712 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25713 /* finaly update the destination */
25714 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25719 } else if (unlikely(XRb
== XRc
)) {
25720 /* both operands same -> just set destination to one of them */
25721 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25723 /* the most general case */
25724 TCGv_i32 t0
= tcg_temp_new();
25725 TCGv_i32 t1
= tcg_temp_new();
25728 /* the leftmost bytes (bytes 3) first */
25729 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
25730 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25731 if (opc
== OPC_MXU_Q8MAX
) {
25732 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25734 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25737 /* bytes 2, 1, 0 */
25738 for (i
= 2; i
>= 0; i
--) {
25739 /* extract corresponding bytes */
25740 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
25741 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
25742 /* move the bytes to the leftmost position */
25743 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25744 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
25745 /* t0 will be max/min of t0 and t1 */
25746 if (opc
== OPC_MXU_Q8MAX
) {
25747 tcg_gen_smax_i32(t0
, t0
, t1
);
25749 tcg_gen_smin_i32(t0
, t0
, t1
);
25751 /* return resulting byte to its original position */
25752 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25753 /* finaly update the destination */
25754 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25764 * MXU instruction category: align
25765 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25771 * S32ALNI XRc, XRb, XRa, optn3
25772 * Arrange bytes from XRb and XRc according to one of five sets of
25773 * rules determined by optn3, and place the result in XRa.
25775 * 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
25776 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25777 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25778 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25781 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
25783 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
25785 optn3
= extract32(ctx
->opcode
, 23, 3);
25786 pad
= extract32(ctx
->opcode
, 21, 2);
25787 XRc
= extract32(ctx
->opcode
, 14, 4);
25788 XRb
= extract32(ctx
->opcode
, 10, 4);
25789 XRa
= extract32(ctx
->opcode
, 6, 4);
25791 if (unlikely(pad
!= 0)) {
25792 /* opcode padding incorrect -> do nothing */
25793 } else if (unlikely(XRa
== 0)) {
25794 /* destination is zero register -> do nothing */
25795 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25796 /* both operands zero registers -> just set destination to all 0s */
25797 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25798 } else if (unlikely(XRb
== 0)) {
25799 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25801 case MXU_OPTN3_PTN0
:
25802 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25804 case MXU_OPTN3_PTN1
:
25805 case MXU_OPTN3_PTN2
:
25806 case MXU_OPTN3_PTN3
:
25807 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
25810 case MXU_OPTN3_PTN4
:
25811 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25814 } else if (unlikely(XRc
== 0)) {
25815 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25817 case MXU_OPTN3_PTN0
:
25818 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25820 case MXU_OPTN3_PTN1
:
25821 case MXU_OPTN3_PTN2
:
25822 case MXU_OPTN3_PTN3
:
25823 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25825 case MXU_OPTN3_PTN4
:
25826 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25829 } else if (unlikely(XRb
== XRc
)) {
25830 /* both operands same -> just rotation or moving from any of them */
25832 case MXU_OPTN3_PTN0
:
25833 case MXU_OPTN3_PTN4
:
25834 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25836 case MXU_OPTN3_PTN1
:
25837 case MXU_OPTN3_PTN2
:
25838 case MXU_OPTN3_PTN3
:
25839 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25843 /* the most general case */
25845 case MXU_OPTN3_PTN0
:
25849 /* +---------------+ */
25850 /* | A B C D | E F G H */
25851 /* +-------+-------+ */
25856 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25859 case MXU_OPTN3_PTN1
:
25863 /* +-------------------+ */
25864 /* A | B C D E | F G H */
25865 /* +---------+---------+ */
25870 TCGv_i32 t0
= tcg_temp_new();
25871 TCGv_i32 t1
= tcg_temp_new();
25873 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
25874 tcg_gen_shli_i32(t0
, t0
, 8);
25876 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25877 tcg_gen_shri_i32(t1
, t1
, 24);
25879 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25885 case MXU_OPTN3_PTN2
:
25889 /* +-------------------+ */
25890 /* A B | C D E F | G H */
25891 /* +---------+---------+ */
25896 TCGv_i32 t0
= tcg_temp_new();
25897 TCGv_i32 t1
= tcg_temp_new();
25899 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25900 tcg_gen_shli_i32(t0
, t0
, 16);
25902 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25903 tcg_gen_shri_i32(t1
, t1
, 16);
25905 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25911 case MXU_OPTN3_PTN3
:
25915 /* +-------------------+ */
25916 /* A B C | D E F G | H */
25917 /* +---------+---------+ */
25922 TCGv_i32 t0
= tcg_temp_new();
25923 TCGv_i32 t1
= tcg_temp_new();
25925 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
25926 tcg_gen_shli_i32(t0
, t0
, 24);
25928 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
25929 tcg_gen_shri_i32(t1
, t1
, 8);
25931 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25937 case MXU_OPTN3_PTN4
:
25941 /* +---------------+ */
25942 /* A B C D | E F G H | */
25943 /* +-------+-------+ */
25948 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25957 * Decoding engine for MXU
25958 * =======================
25963 * Decode MXU pool00
25965 * 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
25966 * +-----------+---------+-----+-------+-------+-------+-----------+
25967 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25968 * +-----------+---------+-----+-------+-------+-------+-----------+
25971 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
25973 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25976 case OPC_MXU_S32MAX
:
25977 case OPC_MXU_S32MIN
:
25978 gen_mxu_S32MAX_S32MIN(ctx
);
25980 case OPC_MXU_D16MAX
:
25981 case OPC_MXU_D16MIN
:
25982 gen_mxu_D16MAX_D16MIN(ctx
);
25984 case OPC_MXU_Q8MAX
:
25985 case OPC_MXU_Q8MIN
:
25986 gen_mxu_Q8MAX_Q8MIN(ctx
);
25988 case OPC_MXU_Q8SLT
:
25989 /* TODO: Implement emulation of Q8SLT instruction. */
25990 MIPS_INVAL("OPC_MXU_Q8SLT");
25991 generate_exception_end(ctx
, EXCP_RI
);
25993 case OPC_MXU_Q8SLTU
:
25994 /* TODO: Implement emulation of Q8SLTU instruction. */
25995 MIPS_INVAL("OPC_MXU_Q8SLTU");
25996 generate_exception_end(ctx
, EXCP_RI
);
25999 MIPS_INVAL("decode_opc_mxu");
26000 generate_exception_end(ctx
, EXCP_RI
);
26007 * Decode MXU pool01
26009 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26010 * 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
26011 * +-----------+---------+-----+-------+-------+-------+-----------+
26012 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26013 * +-----------+---------+-----+-------+-------+-------+-----------+
26016 * 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
26017 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26018 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26019 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26022 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
26024 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26027 case OPC_MXU_S32SLT
:
26028 /* TODO: Implement emulation of S32SLT instruction. */
26029 MIPS_INVAL("OPC_MXU_S32SLT");
26030 generate_exception_end(ctx
, EXCP_RI
);
26032 case OPC_MXU_D16SLT
:
26033 /* TODO: Implement emulation of D16SLT instruction. */
26034 MIPS_INVAL("OPC_MXU_D16SLT");
26035 generate_exception_end(ctx
, EXCP_RI
);
26037 case OPC_MXU_D16AVG
:
26038 /* TODO: Implement emulation of D16AVG instruction. */
26039 MIPS_INVAL("OPC_MXU_D16AVG");
26040 generate_exception_end(ctx
, EXCP_RI
);
26042 case OPC_MXU_D16AVGR
:
26043 /* TODO: Implement emulation of D16AVGR instruction. */
26044 MIPS_INVAL("OPC_MXU_D16AVGR");
26045 generate_exception_end(ctx
, EXCP_RI
);
26047 case OPC_MXU_Q8AVG
:
26048 /* TODO: Implement emulation of Q8AVG instruction. */
26049 MIPS_INVAL("OPC_MXU_Q8AVG");
26050 generate_exception_end(ctx
, EXCP_RI
);
26052 case OPC_MXU_Q8AVGR
:
26053 /* TODO: Implement emulation of Q8AVGR instruction. */
26054 MIPS_INVAL("OPC_MXU_Q8AVGR");
26055 generate_exception_end(ctx
, EXCP_RI
);
26057 case OPC_MXU_Q8ADD
:
26058 /* TODO: Implement emulation of Q8ADD instruction. */
26059 MIPS_INVAL("OPC_MXU_Q8ADD");
26060 generate_exception_end(ctx
, EXCP_RI
);
26063 MIPS_INVAL("decode_opc_mxu");
26064 generate_exception_end(ctx
, EXCP_RI
);
26071 * Decode MXU pool02
26073 * 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
26074 * +-----------+---------+-----+-------+-------+-------+-----------+
26075 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26076 * +-----------+---------+-----+-------+-------+-------+-----------+
26079 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
26081 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26084 case OPC_MXU_S32CPS
:
26085 /* TODO: Implement emulation of S32CPS instruction. */
26086 MIPS_INVAL("OPC_MXU_S32CPS");
26087 generate_exception_end(ctx
, EXCP_RI
);
26089 case OPC_MXU_D16CPS
:
26090 /* TODO: Implement emulation of D16CPS instruction. */
26091 MIPS_INVAL("OPC_MXU_D16CPS");
26092 generate_exception_end(ctx
, EXCP_RI
);
26094 case OPC_MXU_Q8ABD
:
26095 /* TODO: Implement emulation of Q8ABD instruction. */
26096 MIPS_INVAL("OPC_MXU_Q8ABD");
26097 generate_exception_end(ctx
, EXCP_RI
);
26099 case OPC_MXU_Q16SAT
:
26100 /* TODO: Implement emulation of Q16SAT instruction. */
26101 MIPS_INVAL("OPC_MXU_Q16SAT");
26102 generate_exception_end(ctx
, EXCP_RI
);
26105 MIPS_INVAL("decode_opc_mxu");
26106 generate_exception_end(ctx
, EXCP_RI
);
26113 * Decode MXU pool03
26116 * 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
26117 * +-----------+---+---+-------+-------+-------+-------+-----------+
26118 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26119 * +-----------+---+---+-------+-------+-------+-------+-----------+
26122 * 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
26123 * +-----------+---+---+-------+-------+-------+-------+-----------+
26124 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26125 * +-----------+---+---+-------+-------+-------+-------+-----------+
26128 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
26130 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
26133 case OPC_MXU_D16MULF
:
26134 /* TODO: Implement emulation of D16MULF instruction. */
26135 MIPS_INVAL("OPC_MXU_D16MULF");
26136 generate_exception_end(ctx
, EXCP_RI
);
26138 case OPC_MXU_D16MULE
:
26139 /* TODO: Implement emulation of D16MULE instruction. */
26140 MIPS_INVAL("OPC_MXU_D16MULE");
26141 generate_exception_end(ctx
, EXCP_RI
);
26144 MIPS_INVAL("decode_opc_mxu");
26145 generate_exception_end(ctx
, EXCP_RI
);
26152 * Decode MXU pool04
26154 * 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
26155 * +-----------+---------+-+-------------------+-------+-----------+
26156 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26157 * +-----------+---------+-+-------------------+-------+-----------+
26160 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
26162 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26165 case OPC_MXU_S32LDD
:
26166 case OPC_MXU_S32LDDR
:
26167 gen_mxu_s32ldd_s32lddr(ctx
);
26170 MIPS_INVAL("decode_opc_mxu");
26171 generate_exception_end(ctx
, EXCP_RI
);
26178 * Decode MXU pool05
26180 * 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
26181 * +-----------+---------+-+-------------------+-------+-----------+
26182 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26183 * +-----------+---------+-+-------------------+-------+-----------+
26186 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
26188 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26191 case OPC_MXU_S32STD
:
26192 /* TODO: Implement emulation of S32STD instruction. */
26193 MIPS_INVAL("OPC_MXU_S32STD");
26194 generate_exception_end(ctx
, EXCP_RI
);
26196 case OPC_MXU_S32STDR
:
26197 /* TODO: Implement emulation of S32STDR instruction. */
26198 MIPS_INVAL("OPC_MXU_S32STDR");
26199 generate_exception_end(ctx
, EXCP_RI
);
26202 MIPS_INVAL("decode_opc_mxu");
26203 generate_exception_end(ctx
, EXCP_RI
);
26210 * Decode MXU pool06
26212 * 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
26213 * +-----------+---------+---------+---+-------+-------+-----------+
26214 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26215 * +-----------+---------+---------+---+-------+-------+-----------+
26218 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26220 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26223 case OPC_MXU_S32LDDV
:
26224 /* TODO: Implement emulation of S32LDDV instruction. */
26225 MIPS_INVAL("OPC_MXU_S32LDDV");
26226 generate_exception_end(ctx
, EXCP_RI
);
26228 case OPC_MXU_S32LDDVR
:
26229 /* TODO: Implement emulation of S32LDDVR instruction. */
26230 MIPS_INVAL("OPC_MXU_S32LDDVR");
26231 generate_exception_end(ctx
, EXCP_RI
);
26234 MIPS_INVAL("decode_opc_mxu");
26235 generate_exception_end(ctx
, EXCP_RI
);
26242 * Decode MXU pool07
26244 * 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
26245 * +-----------+---------+---------+---+-------+-------+-----------+
26246 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26247 * +-----------+---------+---------+---+-------+-------+-----------+
26250 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26252 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26255 case OPC_MXU_S32STDV
:
26256 /* TODO: Implement emulation of S32TDV instruction. */
26257 MIPS_INVAL("OPC_MXU_S32TDV");
26258 generate_exception_end(ctx
, EXCP_RI
);
26260 case OPC_MXU_S32STDVR
:
26261 /* TODO: Implement emulation of S32TDVR instruction. */
26262 MIPS_INVAL("OPC_MXU_S32TDVR");
26263 generate_exception_end(ctx
, EXCP_RI
);
26266 MIPS_INVAL("decode_opc_mxu");
26267 generate_exception_end(ctx
, EXCP_RI
);
26274 * Decode MXU pool08
26276 * 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
26277 * +-----------+---------+-+-------------------+-------+-----------+
26278 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26279 * +-----------+---------+-+-------------------+-------+-----------+
26282 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26284 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26287 case OPC_MXU_S32LDI
:
26288 /* TODO: Implement emulation of S32LDI instruction. */
26289 MIPS_INVAL("OPC_MXU_S32LDI");
26290 generate_exception_end(ctx
, EXCP_RI
);
26292 case OPC_MXU_S32LDIR
:
26293 /* TODO: Implement emulation of S32LDIR instruction. */
26294 MIPS_INVAL("OPC_MXU_S32LDIR");
26295 generate_exception_end(ctx
, EXCP_RI
);
26298 MIPS_INVAL("decode_opc_mxu");
26299 generate_exception_end(ctx
, EXCP_RI
);
26306 * Decode MXU pool09
26308 * 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
26309 * +-----------+---------+-+-------------------+-------+-----------+
26310 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26311 * +-----------+---------+-+-------------------+-------+-----------+
26314 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26316 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26319 case OPC_MXU_S32SDI
:
26320 /* TODO: Implement emulation of S32SDI instruction. */
26321 MIPS_INVAL("OPC_MXU_S32SDI");
26322 generate_exception_end(ctx
, EXCP_RI
);
26324 case OPC_MXU_S32SDIR
:
26325 /* TODO: Implement emulation of S32SDIR instruction. */
26326 MIPS_INVAL("OPC_MXU_S32SDIR");
26327 generate_exception_end(ctx
, EXCP_RI
);
26330 MIPS_INVAL("decode_opc_mxu");
26331 generate_exception_end(ctx
, EXCP_RI
);
26338 * Decode MXU pool10
26340 * 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
26341 * +-----------+---------+---------+---+-------+-------+-----------+
26342 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26343 * +-----------+---------+---------+---+-------+-------+-----------+
26346 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26348 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26351 case OPC_MXU_S32LDIV
:
26352 /* TODO: Implement emulation of S32LDIV instruction. */
26353 MIPS_INVAL("OPC_MXU_S32LDIV");
26354 generate_exception_end(ctx
, EXCP_RI
);
26356 case OPC_MXU_S32LDIVR
:
26357 /* TODO: Implement emulation of S32LDIVR instruction. */
26358 MIPS_INVAL("OPC_MXU_S32LDIVR");
26359 generate_exception_end(ctx
, EXCP_RI
);
26362 MIPS_INVAL("decode_opc_mxu");
26363 generate_exception_end(ctx
, EXCP_RI
);
26370 * Decode MXU pool11
26372 * 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
26373 * +-----------+---------+---------+---+-------+-------+-----------+
26374 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26375 * +-----------+---------+---------+---+-------+-------+-----------+
26378 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26380 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26383 case OPC_MXU_S32SDIV
:
26384 /* TODO: Implement emulation of S32SDIV instruction. */
26385 MIPS_INVAL("OPC_MXU_S32SDIV");
26386 generate_exception_end(ctx
, EXCP_RI
);
26388 case OPC_MXU_S32SDIVR
:
26389 /* TODO: Implement emulation of S32SDIVR instruction. */
26390 MIPS_INVAL("OPC_MXU_S32SDIVR");
26391 generate_exception_end(ctx
, EXCP_RI
);
26394 MIPS_INVAL("decode_opc_mxu");
26395 generate_exception_end(ctx
, EXCP_RI
);
26402 * Decode MXU pool12
26404 * 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
26405 * +-----------+---+---+-------+-------+-------+-------+-----------+
26406 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26407 * +-----------+---+---+-------+-------+-------+-------+-----------+
26410 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26412 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26415 case OPC_MXU_D32ACC
:
26416 /* TODO: Implement emulation of D32ACC instruction. */
26417 MIPS_INVAL("OPC_MXU_D32ACC");
26418 generate_exception_end(ctx
, EXCP_RI
);
26420 case OPC_MXU_D32ACCM
:
26421 /* TODO: Implement emulation of D32ACCM instruction. */
26422 MIPS_INVAL("OPC_MXU_D32ACCM");
26423 generate_exception_end(ctx
, EXCP_RI
);
26425 case OPC_MXU_D32ASUM
:
26426 /* TODO: Implement emulation of D32ASUM instruction. */
26427 MIPS_INVAL("OPC_MXU_D32ASUM");
26428 generate_exception_end(ctx
, EXCP_RI
);
26431 MIPS_INVAL("decode_opc_mxu");
26432 generate_exception_end(ctx
, EXCP_RI
);
26439 * Decode MXU pool13
26441 * 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
26442 * +-----------+---+---+-------+-------+-------+-------+-----------+
26443 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26444 * +-----------+---+---+-------+-------+-------+-------+-----------+
26447 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26449 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26452 case OPC_MXU_Q16ACC
:
26453 /* TODO: Implement emulation of Q16ACC instruction. */
26454 MIPS_INVAL("OPC_MXU_Q16ACC");
26455 generate_exception_end(ctx
, EXCP_RI
);
26457 case OPC_MXU_Q16ACCM
:
26458 /* TODO: Implement emulation of Q16ACCM instruction. */
26459 MIPS_INVAL("OPC_MXU_Q16ACCM");
26460 generate_exception_end(ctx
, EXCP_RI
);
26462 case OPC_MXU_Q16ASUM
:
26463 /* TODO: Implement emulation of Q16ASUM instruction. */
26464 MIPS_INVAL("OPC_MXU_Q16ASUM");
26465 generate_exception_end(ctx
, EXCP_RI
);
26468 MIPS_INVAL("decode_opc_mxu");
26469 generate_exception_end(ctx
, EXCP_RI
);
26476 * Decode MXU pool14
26479 * 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
26480 * +-----------+---+---+-------+-------+-------+-------+-----------+
26481 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26482 * +-----------+---+---+-------+-------+-------+-------+-----------+
26485 * 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
26486 * +-----------+---+---+-------+-------+-------+-------+-----------+
26487 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26488 * +-----------+---+---+-------+-------+-------+-------+-----------+
26491 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26493 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26496 case OPC_MXU_Q8ADDE
:
26497 /* TODO: Implement emulation of Q8ADDE instruction. */
26498 MIPS_INVAL("OPC_MXU_Q8ADDE");
26499 generate_exception_end(ctx
, EXCP_RI
);
26501 case OPC_MXU_D8SUM
:
26502 /* TODO: Implement emulation of D8SUM instruction. */
26503 MIPS_INVAL("OPC_MXU_D8SUM");
26504 generate_exception_end(ctx
, EXCP_RI
);
26506 case OPC_MXU_D8SUMC
:
26507 /* TODO: Implement emulation of D8SUMC instruction. */
26508 MIPS_INVAL("OPC_MXU_D8SUMC");
26509 generate_exception_end(ctx
, EXCP_RI
);
26512 MIPS_INVAL("decode_opc_mxu");
26513 generate_exception_end(ctx
, EXCP_RI
);
26520 * Decode MXU pool15
26522 * S32MUL, S32MULU, S32EXTRV:
26523 * 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
26524 * +-----------+---------+---------+---+-------+-------+-----------+
26525 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26526 * +-----------+---------+---------+---+-------+-------+-----------+
26529 * 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
26530 * +-----------+---------+---------+---+-------+-------+-----------+
26531 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26532 * +-----------+---------+---------+---+-------+-------+-----------+
26535 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26537 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26540 case OPC_MXU_S32MUL
:
26541 /* TODO: Implement emulation of S32MUL instruction. */
26542 MIPS_INVAL("OPC_MXU_S32MUL");
26543 generate_exception_end(ctx
, EXCP_RI
);
26545 case OPC_MXU_S32MULU
:
26546 /* TODO: Implement emulation of S32MULU instruction. */
26547 MIPS_INVAL("OPC_MXU_S32MULU");
26548 generate_exception_end(ctx
, EXCP_RI
);
26550 case OPC_MXU_S32EXTR
:
26551 /* TODO: Implement emulation of S32EXTR instruction. */
26552 MIPS_INVAL("OPC_MXU_S32EXTR");
26553 generate_exception_end(ctx
, EXCP_RI
);
26555 case OPC_MXU_S32EXTRV
:
26556 /* TODO: Implement emulation of S32EXTRV instruction. */
26557 MIPS_INVAL("OPC_MXU_S32EXTRV");
26558 generate_exception_end(ctx
, EXCP_RI
);
26561 MIPS_INVAL("decode_opc_mxu");
26562 generate_exception_end(ctx
, EXCP_RI
);
26569 * Decode MXU pool16
26572 * 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
26573 * +-----------+---------+-----+-------+-------+-------+-----------+
26574 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26575 * +-----------+---------+-----+-------+-------+-------+-----------+
26578 * 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
26579 * +-----------+---------+-----+-------+-------+-------+-----------+
26580 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26581 * +-----------+---------+-----+-------+-------+-------+-----------+
26584 * 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
26585 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26586 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26587 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26590 * 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
26591 * +-----------+-----+---+-----+-------+---------------+-----------+
26592 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26593 * +-----------+-----+---+-----+-------+---------------+-----------+
26595 * S32NOR, S32AND, S32OR, S32XOR:
26596 * 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
26597 * +-----------+---------+-----+-------+-------+-------+-----------+
26598 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26599 * +-----------+---------+-----+-------+-------+-------+-----------+
26602 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
26604 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26607 case OPC_MXU_D32SARW
:
26608 /* TODO: Implement emulation of D32SARW instruction. */
26609 MIPS_INVAL("OPC_MXU_D32SARW");
26610 generate_exception_end(ctx
, EXCP_RI
);
26612 case OPC_MXU_S32ALN
:
26613 /* TODO: Implement emulation of S32ALN instruction. */
26614 MIPS_INVAL("OPC_MXU_S32ALN");
26615 generate_exception_end(ctx
, EXCP_RI
);
26617 case OPC_MXU_S32ALNI
:
26618 gen_mxu_S32ALNI(ctx
);
26620 case OPC_MXU_S32LUI
:
26621 /* TODO: Implement emulation of S32LUI instruction. */
26622 MIPS_INVAL("OPC_MXU_S32LUI");
26623 generate_exception_end(ctx
, EXCP_RI
);
26625 case OPC_MXU_S32NOR
:
26626 gen_mxu_S32NOR(ctx
);
26628 case OPC_MXU_S32AND
:
26629 gen_mxu_S32AND(ctx
);
26631 case OPC_MXU_S32OR
:
26632 gen_mxu_S32OR(ctx
);
26634 case OPC_MXU_S32XOR
:
26635 gen_mxu_S32XOR(ctx
);
26638 MIPS_INVAL("decode_opc_mxu");
26639 generate_exception_end(ctx
, EXCP_RI
);
26646 * Decode MXU pool17
26648 * 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
26649 * +-----------+---------+---------+---+---------+-----+-----------+
26650 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26651 * +-----------+---------+---------+---+---------+-----+-----------+
26654 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
26656 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
26660 /* TODO: Implement emulation of LXW instruction. */
26661 MIPS_INVAL("OPC_MXU_LXW");
26662 generate_exception_end(ctx
, EXCP_RI
);
26665 /* TODO: Implement emulation of LXH instruction. */
26666 MIPS_INVAL("OPC_MXU_LXH");
26667 generate_exception_end(ctx
, EXCP_RI
);
26670 /* TODO: Implement emulation of LXHU instruction. */
26671 MIPS_INVAL("OPC_MXU_LXHU");
26672 generate_exception_end(ctx
, EXCP_RI
);
26675 /* TODO: Implement emulation of LXB instruction. */
26676 MIPS_INVAL("OPC_MXU_LXB");
26677 generate_exception_end(ctx
, EXCP_RI
);
26680 /* TODO: Implement emulation of LXBU instruction. */
26681 MIPS_INVAL("OPC_MXU_LXBU");
26682 generate_exception_end(ctx
, EXCP_RI
);
26685 MIPS_INVAL("decode_opc_mxu");
26686 generate_exception_end(ctx
, EXCP_RI
);
26692 * Decode MXU pool18
26694 * 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
26695 * +-----------+---------+-----+-------+-------+-------+-----------+
26696 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26697 * +-----------+---------+-----+-------+-------+-------+-----------+
26700 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
26702 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26705 case OPC_MXU_D32SLLV
:
26706 /* TODO: Implement emulation of D32SLLV instruction. */
26707 MIPS_INVAL("OPC_MXU_D32SLLV");
26708 generate_exception_end(ctx
, EXCP_RI
);
26710 case OPC_MXU_D32SLRV
:
26711 /* TODO: Implement emulation of D32SLRV instruction. */
26712 MIPS_INVAL("OPC_MXU_D32SLRV");
26713 generate_exception_end(ctx
, EXCP_RI
);
26715 case OPC_MXU_D32SARV
:
26716 /* TODO: Implement emulation of D32SARV instruction. */
26717 MIPS_INVAL("OPC_MXU_D32SARV");
26718 generate_exception_end(ctx
, EXCP_RI
);
26720 case OPC_MXU_Q16SLLV
:
26721 /* TODO: Implement emulation of Q16SLLV instruction. */
26722 MIPS_INVAL("OPC_MXU_Q16SLLV");
26723 generate_exception_end(ctx
, EXCP_RI
);
26725 case OPC_MXU_Q16SLRV
:
26726 /* TODO: Implement emulation of Q16SLRV instruction. */
26727 MIPS_INVAL("OPC_MXU_Q16SLRV");
26728 generate_exception_end(ctx
, EXCP_RI
);
26730 case OPC_MXU_Q16SARV
:
26731 /* TODO: Implement emulation of Q16SARV instruction. */
26732 MIPS_INVAL("OPC_MXU_Q16SARV");
26733 generate_exception_end(ctx
, EXCP_RI
);
26736 MIPS_INVAL("decode_opc_mxu");
26737 generate_exception_end(ctx
, EXCP_RI
);
26744 * Decode MXU pool19
26746 * 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
26747 * +-----------+---+---+-------+-------+-------+-------+-----------+
26748 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
26749 * +-----------+---+---+-------+-------+-------+-------+-----------+
26752 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
26754 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26757 case OPC_MXU_Q8MUL
:
26758 case OPC_MXU_Q8MULSU
:
26759 gen_mxu_q8mul_q8mulsu(ctx
);
26762 MIPS_INVAL("decode_opc_mxu");
26763 generate_exception_end(ctx
, EXCP_RI
);
26770 * Decode MXU pool20
26772 * 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
26773 * +-----------+---------+-----+-------+-------+-------+-----------+
26774 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
26775 * +-----------+---------+-----+-------+-------+-------+-----------+
26778 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
26780 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26783 case OPC_MXU_Q8MOVZ
:
26784 /* TODO: Implement emulation of Q8MOVZ instruction. */
26785 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26786 generate_exception_end(ctx
, EXCP_RI
);
26788 case OPC_MXU_Q8MOVN
:
26789 /* TODO: Implement emulation of Q8MOVN instruction. */
26790 MIPS_INVAL("OPC_MXU_Q8MOVN");
26791 generate_exception_end(ctx
, EXCP_RI
);
26793 case OPC_MXU_D16MOVZ
:
26794 /* TODO: Implement emulation of D16MOVZ instruction. */
26795 MIPS_INVAL("OPC_MXU_D16MOVZ");
26796 generate_exception_end(ctx
, EXCP_RI
);
26798 case OPC_MXU_D16MOVN
:
26799 /* TODO: Implement emulation of D16MOVN instruction. */
26800 MIPS_INVAL("OPC_MXU_D16MOVN");
26801 generate_exception_end(ctx
, EXCP_RI
);
26803 case OPC_MXU_S32MOVZ
:
26804 /* TODO: Implement emulation of S32MOVZ instruction. */
26805 MIPS_INVAL("OPC_MXU_S32MOVZ");
26806 generate_exception_end(ctx
, EXCP_RI
);
26808 case OPC_MXU_S32MOVN
:
26809 /* TODO: Implement emulation of S32MOVN instruction. */
26810 MIPS_INVAL("OPC_MXU_S32MOVN");
26811 generate_exception_end(ctx
, EXCP_RI
);
26814 MIPS_INVAL("decode_opc_mxu");
26815 generate_exception_end(ctx
, EXCP_RI
);
26822 * Decode MXU pool21
26824 * 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
26825 * +-----------+---+---+-------+-------+-------+-------+-----------+
26826 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
26827 * +-----------+---+---+-------+-------+-------+-------+-----------+
26830 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
26832 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26835 case OPC_MXU_Q8MAC
:
26836 /* TODO: Implement emulation of Q8MAC instruction. */
26837 MIPS_INVAL("OPC_MXU_Q8MAC");
26838 generate_exception_end(ctx
, EXCP_RI
);
26840 case OPC_MXU_Q8MACSU
:
26841 /* TODO: Implement emulation of Q8MACSU instruction. */
26842 MIPS_INVAL("OPC_MXU_Q8MACSU");
26843 generate_exception_end(ctx
, EXCP_RI
);
26846 MIPS_INVAL("decode_opc_mxu");
26847 generate_exception_end(ctx
, EXCP_RI
);
26854 * Main MXU decoding function
26856 * 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
26857 * +-----------+---------------------------------------+-----------+
26858 * | SPECIAL2 | |x x x x x x|
26859 * +-----------+---------------------------------------+-----------+
26862 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
26865 * TODO: Investigate necessity of including handling of
26866 * CLZ, CLO, SDBB in this function, as they belong to
26867 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26869 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
26871 if (opcode
== OPC__MXU_MUL
) {
26872 uint32_t rs
, rt
, rd
, op1
;
26874 rs
= extract32(ctx
->opcode
, 21, 5);
26875 rt
= extract32(ctx
->opcode
, 16, 5);
26876 rd
= extract32(ctx
->opcode
, 11, 5);
26877 op1
= MASK_SPECIAL2(ctx
->opcode
);
26879 gen_arith(ctx
, op1
, rd
, rs
, rt
);
26884 if (opcode
== OPC_MXU_S32M2I
) {
26885 gen_mxu_s32m2i(ctx
);
26889 if (opcode
== OPC_MXU_S32I2M
) {
26890 gen_mxu_s32i2m(ctx
);
26895 TCGv t_mxu_cr
= tcg_temp_new();
26896 TCGLabel
*l_exit
= gen_new_label();
26898 gen_load_mxu_cr(t_mxu_cr
);
26899 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
26900 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
26903 case OPC_MXU_S32MADD
:
26904 /* TODO: Implement emulation of S32MADD instruction. */
26905 MIPS_INVAL("OPC_MXU_S32MADD");
26906 generate_exception_end(ctx
, EXCP_RI
);
26908 case OPC_MXU_S32MADDU
:
26909 /* TODO: Implement emulation of S32MADDU instruction. */
26910 MIPS_INVAL("OPC_MXU_S32MADDU");
26911 generate_exception_end(ctx
, EXCP_RI
);
26913 case OPC_MXU__POOL00
:
26914 decode_opc_mxu__pool00(env
, ctx
);
26916 case OPC_MXU_S32MSUB
:
26917 /* TODO: Implement emulation of S32MSUB instruction. */
26918 MIPS_INVAL("OPC_MXU_S32MSUB");
26919 generate_exception_end(ctx
, EXCP_RI
);
26921 case OPC_MXU_S32MSUBU
:
26922 /* TODO: Implement emulation of S32MSUBU instruction. */
26923 MIPS_INVAL("OPC_MXU_S32MSUBU");
26924 generate_exception_end(ctx
, EXCP_RI
);
26926 case OPC_MXU__POOL01
:
26927 decode_opc_mxu__pool01(env
, ctx
);
26929 case OPC_MXU__POOL02
:
26930 decode_opc_mxu__pool02(env
, ctx
);
26932 case OPC_MXU_D16MUL
:
26933 gen_mxu_d16mul(ctx
);
26935 case OPC_MXU__POOL03
:
26936 decode_opc_mxu__pool03(env
, ctx
);
26938 case OPC_MXU_D16MAC
:
26939 gen_mxu_d16mac(ctx
);
26941 case OPC_MXU_D16MACF
:
26942 /* TODO: Implement emulation of D16MACF instruction. */
26943 MIPS_INVAL("OPC_MXU_D16MACF");
26944 generate_exception_end(ctx
, EXCP_RI
);
26946 case OPC_MXU_D16MADL
:
26947 /* TODO: Implement emulation of D16MADL instruction. */
26948 MIPS_INVAL("OPC_MXU_D16MADL");
26949 generate_exception_end(ctx
, EXCP_RI
);
26951 case OPC_MXU_S16MAD
:
26952 /* TODO: Implement emulation of S16MAD instruction. */
26953 MIPS_INVAL("OPC_MXU_S16MAD");
26954 generate_exception_end(ctx
, EXCP_RI
);
26956 case OPC_MXU_Q16ADD
:
26957 /* TODO: Implement emulation of Q16ADD instruction. */
26958 MIPS_INVAL("OPC_MXU_Q16ADD");
26959 generate_exception_end(ctx
, EXCP_RI
);
26961 case OPC_MXU_D16MACE
:
26962 /* TODO: Implement emulation of D16MACE instruction. */
26963 MIPS_INVAL("OPC_MXU_D16MACE");
26964 generate_exception_end(ctx
, EXCP_RI
);
26966 case OPC_MXU__POOL04
:
26967 decode_opc_mxu__pool04(env
, ctx
);
26969 case OPC_MXU__POOL05
:
26970 decode_opc_mxu__pool05(env
, ctx
);
26972 case OPC_MXU__POOL06
:
26973 decode_opc_mxu__pool06(env
, ctx
);
26975 case OPC_MXU__POOL07
:
26976 decode_opc_mxu__pool07(env
, ctx
);
26978 case OPC_MXU__POOL08
:
26979 decode_opc_mxu__pool08(env
, ctx
);
26981 case OPC_MXU__POOL09
:
26982 decode_opc_mxu__pool09(env
, ctx
);
26984 case OPC_MXU__POOL10
:
26985 decode_opc_mxu__pool10(env
, ctx
);
26987 case OPC_MXU__POOL11
:
26988 decode_opc_mxu__pool11(env
, ctx
);
26990 case OPC_MXU_D32ADD
:
26991 /* TODO: Implement emulation of D32ADD instruction. */
26992 MIPS_INVAL("OPC_MXU_D32ADD");
26993 generate_exception_end(ctx
, EXCP_RI
);
26995 case OPC_MXU__POOL12
:
26996 decode_opc_mxu__pool12(env
, ctx
);
26998 case OPC_MXU__POOL13
:
26999 decode_opc_mxu__pool13(env
, ctx
);
27001 case OPC_MXU__POOL14
:
27002 decode_opc_mxu__pool14(env
, ctx
);
27004 case OPC_MXU_Q8ACCE
:
27005 /* TODO: Implement emulation of Q8ACCE instruction. */
27006 MIPS_INVAL("OPC_MXU_Q8ACCE");
27007 generate_exception_end(ctx
, EXCP_RI
);
27009 case OPC_MXU_S8LDD
:
27010 gen_mxu_s8ldd(ctx
);
27012 case OPC_MXU_S8STD
:
27013 /* TODO: Implement emulation of S8STD instruction. */
27014 MIPS_INVAL("OPC_MXU_S8STD");
27015 generate_exception_end(ctx
, EXCP_RI
);
27017 case OPC_MXU_S8LDI
:
27018 /* TODO: Implement emulation of S8LDI instruction. */
27019 MIPS_INVAL("OPC_MXU_S8LDI");
27020 generate_exception_end(ctx
, EXCP_RI
);
27022 case OPC_MXU_S8SDI
:
27023 /* TODO: Implement emulation of S8SDI instruction. */
27024 MIPS_INVAL("OPC_MXU_S8SDI");
27025 generate_exception_end(ctx
, EXCP_RI
);
27027 case OPC_MXU__POOL15
:
27028 decode_opc_mxu__pool15(env
, ctx
);
27030 case OPC_MXU__POOL16
:
27031 decode_opc_mxu__pool16(env
, ctx
);
27033 case OPC_MXU__POOL17
:
27034 decode_opc_mxu__pool17(env
, ctx
);
27036 case OPC_MXU_S16LDD
:
27037 /* TODO: Implement emulation of S16LDD instruction. */
27038 MIPS_INVAL("OPC_MXU_S16LDD");
27039 generate_exception_end(ctx
, EXCP_RI
);
27041 case OPC_MXU_S16STD
:
27042 /* TODO: Implement emulation of S16STD instruction. */
27043 MIPS_INVAL("OPC_MXU_S16STD");
27044 generate_exception_end(ctx
, EXCP_RI
);
27046 case OPC_MXU_S16LDI
:
27047 /* TODO: Implement emulation of S16LDI instruction. */
27048 MIPS_INVAL("OPC_MXU_S16LDI");
27049 generate_exception_end(ctx
, EXCP_RI
);
27051 case OPC_MXU_S16SDI
:
27052 /* TODO: Implement emulation of S16SDI instruction. */
27053 MIPS_INVAL("OPC_MXU_S16SDI");
27054 generate_exception_end(ctx
, EXCP_RI
);
27056 case OPC_MXU_D32SLL
:
27057 /* TODO: Implement emulation of D32SLL instruction. */
27058 MIPS_INVAL("OPC_MXU_D32SLL");
27059 generate_exception_end(ctx
, EXCP_RI
);
27061 case OPC_MXU_D32SLR
:
27062 /* TODO: Implement emulation of D32SLR instruction. */
27063 MIPS_INVAL("OPC_MXU_D32SLR");
27064 generate_exception_end(ctx
, EXCP_RI
);
27066 case OPC_MXU_D32SARL
:
27067 /* TODO: Implement emulation of D32SARL instruction. */
27068 MIPS_INVAL("OPC_MXU_D32SARL");
27069 generate_exception_end(ctx
, EXCP_RI
);
27071 case OPC_MXU_D32SAR
:
27072 /* TODO: Implement emulation of D32SAR instruction. */
27073 MIPS_INVAL("OPC_MXU_D32SAR");
27074 generate_exception_end(ctx
, EXCP_RI
);
27076 case OPC_MXU_Q16SLL
:
27077 /* TODO: Implement emulation of Q16SLL instruction. */
27078 MIPS_INVAL("OPC_MXU_Q16SLL");
27079 generate_exception_end(ctx
, EXCP_RI
);
27081 case OPC_MXU_Q16SLR
:
27082 /* TODO: Implement emulation of Q16SLR instruction. */
27083 MIPS_INVAL("OPC_MXU_Q16SLR");
27084 generate_exception_end(ctx
, EXCP_RI
);
27086 case OPC_MXU__POOL18
:
27087 decode_opc_mxu__pool18(env
, ctx
);
27089 case OPC_MXU_Q16SAR
:
27090 /* TODO: Implement emulation of Q16SAR instruction. */
27091 MIPS_INVAL("OPC_MXU_Q16SAR");
27092 generate_exception_end(ctx
, EXCP_RI
);
27094 case OPC_MXU__POOL19
:
27095 decode_opc_mxu__pool19(env
, ctx
);
27097 case OPC_MXU__POOL20
:
27098 decode_opc_mxu__pool20(env
, ctx
);
27100 case OPC_MXU__POOL21
:
27101 decode_opc_mxu__pool21(env
, ctx
);
27103 case OPC_MXU_Q16SCOP
:
27104 /* TODO: Implement emulation of Q16SCOP instruction. */
27105 MIPS_INVAL("OPC_MXU_Q16SCOP");
27106 generate_exception_end(ctx
, EXCP_RI
);
27108 case OPC_MXU_Q8MADL
:
27109 /* TODO: Implement emulation of Q8MADL instruction. */
27110 MIPS_INVAL("OPC_MXU_Q8MADL");
27111 generate_exception_end(ctx
, EXCP_RI
);
27113 case OPC_MXU_S32SFL
:
27114 /* TODO: Implement emulation of S32SFL instruction. */
27115 MIPS_INVAL("OPC_MXU_S32SFL");
27116 generate_exception_end(ctx
, EXCP_RI
);
27118 case OPC_MXU_Q8SAD
:
27119 /* TODO: Implement emulation of Q8SAD instruction. */
27120 MIPS_INVAL("OPC_MXU_Q8SAD");
27121 generate_exception_end(ctx
, EXCP_RI
);
27124 MIPS_INVAL("decode_opc_mxu");
27125 generate_exception_end(ctx
, EXCP_RI
);
27128 gen_set_label(l_exit
);
27129 tcg_temp_free(t_mxu_cr
);
27133 #endif /* !defined(TARGET_MIPS64) */
27136 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27141 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
27143 rs
= (ctx
->opcode
>> 21) & 0x1f;
27144 rt
= (ctx
->opcode
>> 16) & 0x1f;
27145 rd
= (ctx
->opcode
>> 11) & 0x1f;
27147 op1
= MASK_SPECIAL2(ctx
->opcode
);
27149 case OPC_MADD
: /* Multiply and add/sub */
27153 check_insn(ctx
, ISA_MIPS32
);
27154 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
27157 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27160 case OPC_DIVU_G_2F
:
27161 case OPC_MULT_G_2F
:
27162 case OPC_MULTU_G_2F
:
27164 case OPC_MODU_G_2F
:
27165 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27166 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27170 check_insn(ctx
, ISA_MIPS32
);
27171 gen_cl(ctx
, op1
, rd
, rs
);
27174 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
27175 gen_helper_do_semihosting(cpu_env
);
27178 * XXX: not clear which exception should be raised
27179 * when in debug mode...
27181 check_insn(ctx
, ISA_MIPS32
);
27182 generate_exception_end(ctx
, EXCP_DBp
);
27185 #if defined(TARGET_MIPS64)
27188 check_insn(ctx
, ISA_MIPS64
);
27189 check_mips_64(ctx
);
27190 gen_cl(ctx
, op1
, rd
, rs
);
27192 case OPC_DMULT_G_2F
:
27193 case OPC_DMULTU_G_2F
:
27194 case OPC_DDIV_G_2F
:
27195 case OPC_DDIVU_G_2F
:
27196 case OPC_DMOD_G_2F
:
27197 case OPC_DMODU_G_2F
:
27198 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27199 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27202 default: /* Invalid */
27203 MIPS_INVAL("special2_legacy");
27204 generate_exception_end(ctx
, EXCP_RI
);
27209 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27211 int rs
, rt
, rd
, sa
;
27215 rs
= (ctx
->opcode
>> 21) & 0x1f;
27216 rt
= (ctx
->opcode
>> 16) & 0x1f;
27217 rd
= (ctx
->opcode
>> 11) & 0x1f;
27218 sa
= (ctx
->opcode
>> 6) & 0x1f;
27219 imm
= (int16_t)ctx
->opcode
>> 7;
27221 op1
= MASK_SPECIAL3(ctx
->opcode
);
27225 /* hint codes 24-31 are reserved and signal RI */
27226 generate_exception_end(ctx
, EXCP_RI
);
27228 /* Treat as NOP. */
27231 check_cp0_enabled(ctx
);
27232 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27233 gen_cache_operation(ctx
, rt
, rs
, imm
);
27237 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27240 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27245 /* Treat as NOP. */
27248 op2
= MASK_BSHFL(ctx
->opcode
);
27254 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27257 gen_bitswap(ctx
, op2
, rd
, rt
);
27262 #ifndef CONFIG_USER_ONLY
27264 if (unlikely(ctx
->gi
<= 1)) {
27265 generate_exception_end(ctx
, EXCP_RI
);
27267 check_cp0_enabled(ctx
);
27268 switch ((ctx
->opcode
>> 6) & 3) {
27269 case 0: /* GINVI */
27270 /* Treat as NOP. */
27272 case 2: /* GINVT */
27273 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
27276 generate_exception_end(ctx
, EXCP_RI
);
27281 #if defined(TARGET_MIPS64)
27283 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27286 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27289 check_mips_64(ctx
);
27292 /* Treat as NOP. */
27295 op2
= MASK_DBSHFL(ctx
->opcode
);
27305 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27308 gen_bitswap(ctx
, op2
, rd
, rt
);
27315 default: /* Invalid */
27316 MIPS_INVAL("special3_r6");
27317 generate_exception_end(ctx
, EXCP_RI
);
27322 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27327 rs
= (ctx
->opcode
>> 21) & 0x1f;
27328 rt
= (ctx
->opcode
>> 16) & 0x1f;
27329 rd
= (ctx
->opcode
>> 11) & 0x1f;
27331 op1
= MASK_SPECIAL3(ctx
->opcode
);
27334 case OPC_DIVU_G_2E
:
27336 case OPC_MODU_G_2E
:
27337 case OPC_MULT_G_2E
:
27338 case OPC_MULTU_G_2E
:
27340 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27341 * the same mask and op1.
27343 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27344 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27347 case OPC_ADDUH_R_QB
:
27349 case OPC_ADDQH_R_PH
:
27351 case OPC_ADDQH_R_W
:
27353 case OPC_SUBUH_R_QB
:
27355 case OPC_SUBQH_R_PH
:
27357 case OPC_SUBQH_R_W
:
27358 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27363 case OPC_MULQ_RS_W
:
27364 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27367 MIPS_INVAL("MASK ADDUH.QB");
27368 generate_exception_end(ctx
, EXCP_RI
);
27371 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27372 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27374 generate_exception_end(ctx
, EXCP_RI
);
27378 op2
= MASK_LX(ctx
->opcode
);
27380 #if defined(TARGET_MIPS64)
27386 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27388 default: /* Invalid */
27389 MIPS_INVAL("MASK LX");
27390 generate_exception_end(ctx
, EXCP_RI
);
27394 case OPC_ABSQ_S_PH_DSP
:
27395 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27397 case OPC_ABSQ_S_QB
:
27398 case OPC_ABSQ_S_PH
:
27400 case OPC_PRECEQ_W_PHL
:
27401 case OPC_PRECEQ_W_PHR
:
27402 case OPC_PRECEQU_PH_QBL
:
27403 case OPC_PRECEQU_PH_QBR
:
27404 case OPC_PRECEQU_PH_QBLA
:
27405 case OPC_PRECEQU_PH_QBRA
:
27406 case OPC_PRECEU_PH_QBL
:
27407 case OPC_PRECEU_PH_QBR
:
27408 case OPC_PRECEU_PH_QBLA
:
27409 case OPC_PRECEU_PH_QBRA
:
27410 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27417 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27420 MIPS_INVAL("MASK ABSQ_S.PH");
27421 generate_exception_end(ctx
, EXCP_RI
);
27425 case OPC_ADDU_QB_DSP
:
27426 op2
= MASK_ADDU_QB(ctx
->opcode
);
27429 case OPC_ADDQ_S_PH
:
27432 case OPC_ADDU_S_QB
:
27434 case OPC_ADDU_S_PH
:
27436 case OPC_SUBQ_S_PH
:
27439 case OPC_SUBU_S_QB
:
27441 case OPC_SUBU_S_PH
:
27445 case OPC_RADDU_W_QB
:
27446 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27448 case OPC_MULEU_S_PH_QBL
:
27449 case OPC_MULEU_S_PH_QBR
:
27450 case OPC_MULQ_RS_PH
:
27451 case OPC_MULEQ_S_W_PHL
:
27452 case OPC_MULEQ_S_W_PHR
:
27453 case OPC_MULQ_S_PH
:
27454 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27456 default: /* Invalid */
27457 MIPS_INVAL("MASK ADDU.QB");
27458 generate_exception_end(ctx
, EXCP_RI
);
27463 case OPC_CMPU_EQ_QB_DSP
:
27464 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27466 case OPC_PRECR_SRA_PH_W
:
27467 case OPC_PRECR_SRA_R_PH_W
:
27468 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27470 case OPC_PRECR_QB_PH
:
27471 case OPC_PRECRQ_QB_PH
:
27472 case OPC_PRECRQ_PH_W
:
27473 case OPC_PRECRQ_RS_PH_W
:
27474 case OPC_PRECRQU_S_QB_PH
:
27475 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27477 case OPC_CMPU_EQ_QB
:
27478 case OPC_CMPU_LT_QB
:
27479 case OPC_CMPU_LE_QB
:
27480 case OPC_CMP_EQ_PH
:
27481 case OPC_CMP_LT_PH
:
27482 case OPC_CMP_LE_PH
:
27483 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27485 case OPC_CMPGU_EQ_QB
:
27486 case OPC_CMPGU_LT_QB
:
27487 case OPC_CMPGU_LE_QB
:
27488 case OPC_CMPGDU_EQ_QB
:
27489 case OPC_CMPGDU_LT_QB
:
27490 case OPC_CMPGDU_LE_QB
:
27493 case OPC_PACKRL_PH
:
27494 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27496 default: /* Invalid */
27497 MIPS_INVAL("MASK CMPU.EQ.QB");
27498 generate_exception_end(ctx
, EXCP_RI
);
27502 case OPC_SHLL_QB_DSP
:
27503 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27505 case OPC_DPA_W_PH_DSP
:
27506 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27508 case OPC_DPAU_H_QBL
:
27509 case OPC_DPAU_H_QBR
:
27510 case OPC_DPSU_H_QBL
:
27511 case OPC_DPSU_H_QBR
:
27513 case OPC_DPAX_W_PH
:
27514 case OPC_DPAQ_S_W_PH
:
27515 case OPC_DPAQX_S_W_PH
:
27516 case OPC_DPAQX_SA_W_PH
:
27518 case OPC_DPSX_W_PH
:
27519 case OPC_DPSQ_S_W_PH
:
27520 case OPC_DPSQX_S_W_PH
:
27521 case OPC_DPSQX_SA_W_PH
:
27522 case OPC_MULSAQ_S_W_PH
:
27523 case OPC_DPAQ_SA_L_W
:
27524 case OPC_DPSQ_SA_L_W
:
27525 case OPC_MAQ_S_W_PHL
:
27526 case OPC_MAQ_S_W_PHR
:
27527 case OPC_MAQ_SA_W_PHL
:
27528 case OPC_MAQ_SA_W_PHR
:
27529 case OPC_MULSA_W_PH
:
27530 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27532 default: /* Invalid */
27533 MIPS_INVAL("MASK DPAW.PH");
27534 generate_exception_end(ctx
, EXCP_RI
);
27539 op2
= MASK_INSV(ctx
->opcode
);
27550 t0
= tcg_temp_new();
27551 t1
= tcg_temp_new();
27553 gen_load_gpr(t0
, rt
);
27554 gen_load_gpr(t1
, rs
);
27556 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27562 default: /* Invalid */
27563 MIPS_INVAL("MASK INSV");
27564 generate_exception_end(ctx
, EXCP_RI
);
27568 case OPC_APPEND_DSP
:
27569 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27571 case OPC_EXTR_W_DSP
:
27572 op2
= MASK_EXTR_W(ctx
->opcode
);
27576 case OPC_EXTR_RS_W
:
27578 case OPC_EXTRV_S_H
:
27580 case OPC_EXTRV_R_W
:
27581 case OPC_EXTRV_RS_W
:
27586 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27589 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27595 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27597 default: /* Invalid */
27598 MIPS_INVAL("MASK EXTR.W");
27599 generate_exception_end(ctx
, EXCP_RI
);
27603 #if defined(TARGET_MIPS64)
27604 case OPC_DDIV_G_2E
:
27605 case OPC_DDIVU_G_2E
:
27606 case OPC_DMULT_G_2E
:
27607 case OPC_DMULTU_G_2E
:
27608 case OPC_DMOD_G_2E
:
27609 case OPC_DMODU_G_2E
:
27610 check_insn(ctx
, INSN_LOONGSON2E
);
27611 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27613 case OPC_ABSQ_S_QH_DSP
:
27614 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
27616 case OPC_PRECEQ_L_PWL
:
27617 case OPC_PRECEQ_L_PWR
:
27618 case OPC_PRECEQ_PW_QHL
:
27619 case OPC_PRECEQ_PW_QHR
:
27620 case OPC_PRECEQ_PW_QHLA
:
27621 case OPC_PRECEQ_PW_QHRA
:
27622 case OPC_PRECEQU_QH_OBL
:
27623 case OPC_PRECEQU_QH_OBR
:
27624 case OPC_PRECEQU_QH_OBLA
:
27625 case OPC_PRECEQU_QH_OBRA
:
27626 case OPC_PRECEU_QH_OBL
:
27627 case OPC_PRECEU_QH_OBR
:
27628 case OPC_PRECEU_QH_OBLA
:
27629 case OPC_PRECEU_QH_OBRA
:
27630 case OPC_ABSQ_S_OB
:
27631 case OPC_ABSQ_S_PW
:
27632 case OPC_ABSQ_S_QH
:
27633 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27641 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27643 default: /* Invalid */
27644 MIPS_INVAL("MASK ABSQ_S.QH");
27645 generate_exception_end(ctx
, EXCP_RI
);
27649 case OPC_ADDU_OB_DSP
:
27650 op2
= MASK_ADDU_OB(ctx
->opcode
);
27652 case OPC_RADDU_L_OB
:
27654 case OPC_SUBQ_S_PW
:
27656 case OPC_SUBQ_S_QH
:
27658 case OPC_SUBU_S_OB
:
27660 case OPC_SUBU_S_QH
:
27662 case OPC_SUBUH_R_OB
:
27664 case OPC_ADDQ_S_PW
:
27666 case OPC_ADDQ_S_QH
:
27668 case OPC_ADDU_S_OB
:
27670 case OPC_ADDU_S_QH
:
27672 case OPC_ADDUH_R_OB
:
27673 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27675 case OPC_MULEQ_S_PW_QHL
:
27676 case OPC_MULEQ_S_PW_QHR
:
27677 case OPC_MULEU_S_QH_OBL
:
27678 case OPC_MULEU_S_QH_OBR
:
27679 case OPC_MULQ_RS_QH
:
27680 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27682 default: /* Invalid */
27683 MIPS_INVAL("MASK ADDU.OB");
27684 generate_exception_end(ctx
, EXCP_RI
);
27688 case OPC_CMPU_EQ_OB_DSP
:
27689 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
27691 case OPC_PRECR_SRA_QH_PW
:
27692 case OPC_PRECR_SRA_R_QH_PW
:
27693 /* Return value is rt. */
27694 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27696 case OPC_PRECR_OB_QH
:
27697 case OPC_PRECRQ_OB_QH
:
27698 case OPC_PRECRQ_PW_L
:
27699 case OPC_PRECRQ_QH_PW
:
27700 case OPC_PRECRQ_RS_QH_PW
:
27701 case OPC_PRECRQU_S_OB_QH
:
27702 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27704 case OPC_CMPU_EQ_OB
:
27705 case OPC_CMPU_LT_OB
:
27706 case OPC_CMPU_LE_OB
:
27707 case OPC_CMP_EQ_QH
:
27708 case OPC_CMP_LT_QH
:
27709 case OPC_CMP_LE_QH
:
27710 case OPC_CMP_EQ_PW
:
27711 case OPC_CMP_LT_PW
:
27712 case OPC_CMP_LE_PW
:
27713 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27715 case OPC_CMPGDU_EQ_OB
:
27716 case OPC_CMPGDU_LT_OB
:
27717 case OPC_CMPGDU_LE_OB
:
27718 case OPC_CMPGU_EQ_OB
:
27719 case OPC_CMPGU_LT_OB
:
27720 case OPC_CMPGU_LE_OB
:
27721 case OPC_PACKRL_PW
:
27725 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27727 default: /* Invalid */
27728 MIPS_INVAL("MASK CMPU_EQ.OB");
27729 generate_exception_end(ctx
, EXCP_RI
);
27733 case OPC_DAPPEND_DSP
:
27734 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27736 case OPC_DEXTR_W_DSP
:
27737 op2
= MASK_DEXTR_W(ctx
->opcode
);
27744 case OPC_DEXTR_R_L
:
27745 case OPC_DEXTR_RS_L
:
27747 case OPC_DEXTR_R_W
:
27748 case OPC_DEXTR_RS_W
:
27749 case OPC_DEXTR_S_H
:
27751 case OPC_DEXTRV_R_L
:
27752 case OPC_DEXTRV_RS_L
:
27753 case OPC_DEXTRV_S_H
:
27755 case OPC_DEXTRV_R_W
:
27756 case OPC_DEXTRV_RS_W
:
27757 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27762 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27764 default: /* Invalid */
27765 MIPS_INVAL("MASK EXTR.W");
27766 generate_exception_end(ctx
, EXCP_RI
);
27770 case OPC_DPAQ_W_QH_DSP
:
27771 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
27773 case OPC_DPAU_H_OBL
:
27774 case OPC_DPAU_H_OBR
:
27775 case OPC_DPSU_H_OBL
:
27776 case OPC_DPSU_H_OBR
:
27778 case OPC_DPAQ_S_W_QH
:
27780 case OPC_DPSQ_S_W_QH
:
27781 case OPC_MULSAQ_S_W_QH
:
27782 case OPC_DPAQ_SA_L_PW
:
27783 case OPC_DPSQ_SA_L_PW
:
27784 case OPC_MULSAQ_S_L_PW
:
27785 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27787 case OPC_MAQ_S_W_QHLL
:
27788 case OPC_MAQ_S_W_QHLR
:
27789 case OPC_MAQ_S_W_QHRL
:
27790 case OPC_MAQ_S_W_QHRR
:
27791 case OPC_MAQ_SA_W_QHLL
:
27792 case OPC_MAQ_SA_W_QHLR
:
27793 case OPC_MAQ_SA_W_QHRL
:
27794 case OPC_MAQ_SA_W_QHRR
:
27795 case OPC_MAQ_S_L_PWL
:
27796 case OPC_MAQ_S_L_PWR
:
27801 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27803 default: /* Invalid */
27804 MIPS_INVAL("MASK DPAQ.W.QH");
27805 generate_exception_end(ctx
, EXCP_RI
);
27809 case OPC_DINSV_DSP
:
27810 op2
= MASK_INSV(ctx
->opcode
);
27821 t0
= tcg_temp_new();
27822 t1
= tcg_temp_new();
27824 gen_load_gpr(t0
, rt
);
27825 gen_load_gpr(t1
, rs
);
27827 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27833 default: /* Invalid */
27834 MIPS_INVAL("MASK DINSV");
27835 generate_exception_end(ctx
, EXCP_RI
);
27839 case OPC_SHLL_OB_DSP
:
27840 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27843 default: /* Invalid */
27844 MIPS_INVAL("special3_legacy");
27845 generate_exception_end(ctx
, EXCP_RI
);
27851 #if defined(TARGET_MIPS64)
27853 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
27855 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
27858 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
27859 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
27860 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
27861 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
27862 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
27863 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
27864 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
27865 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
27866 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
27867 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
27868 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
27869 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
27870 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
27871 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
27872 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
27873 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
27874 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
27875 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
27876 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
27877 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
27878 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
27879 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
27880 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
27881 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
27882 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
27883 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI0 */
27886 MIPS_INVAL("TX79 MMI class MMI0");
27887 generate_exception_end(ctx
, EXCP_RI
);
27892 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
27894 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
27897 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
27898 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
27899 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
27900 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
27901 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
27902 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
27903 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
27904 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
27905 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
27906 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
27907 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
27908 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
27909 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
27910 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
27911 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
27912 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
27913 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
27914 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
27915 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI1 */
27918 MIPS_INVAL("TX79 MMI class MMI1");
27919 generate_exception_end(ctx
, EXCP_RI
);
27924 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
27926 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
27929 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
27930 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
27931 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
27932 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
27933 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
27934 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
27935 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
27936 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
27937 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
27938 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
27939 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
27940 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
27941 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
27942 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
27943 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
27944 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
27945 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
27946 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
27947 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
27948 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
27949 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
27950 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI2 */
27952 case MMI_OPC_2_PCPYLD
:
27953 gen_mmi_pcpyld(ctx
);
27956 MIPS_INVAL("TX79 MMI class MMI2");
27957 generate_exception_end(ctx
, EXCP_RI
);
27962 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
27964 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
27967 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
27968 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
27969 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
27970 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
27971 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
27972 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
27973 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
27974 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
27975 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
27976 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
27977 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
27978 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI3 */
27980 case MMI_OPC_3_PCPYH
:
27981 gen_mmi_pcpyh(ctx
);
27983 case MMI_OPC_3_PCPYUD
:
27984 gen_mmi_pcpyud(ctx
);
27987 MIPS_INVAL("TX79 MMI class MMI3");
27988 generate_exception_end(ctx
, EXCP_RI
);
27993 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
27995 uint32_t opc
= MASK_MMI(ctx
->opcode
);
27996 int rs
= extract32(ctx
->opcode
, 21, 5);
27997 int rt
= extract32(ctx
->opcode
, 16, 5);
27998 int rd
= extract32(ctx
->opcode
, 11, 5);
28001 case MMI_OPC_CLASS_MMI0
:
28002 decode_mmi0(env
, ctx
);
28004 case MMI_OPC_CLASS_MMI1
:
28005 decode_mmi1(env
, ctx
);
28007 case MMI_OPC_CLASS_MMI2
:
28008 decode_mmi2(env
, ctx
);
28010 case MMI_OPC_CLASS_MMI3
:
28011 decode_mmi3(env
, ctx
);
28013 case MMI_OPC_MULT1
:
28014 case MMI_OPC_MULTU1
:
28016 case MMI_OPC_MADDU
:
28017 case MMI_OPC_MADD1
:
28018 case MMI_OPC_MADDU1
:
28019 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
28022 case MMI_OPC_DIVU1
:
28023 gen_div1_tx79(ctx
, opc
, rs
, rt
);
28025 case MMI_OPC_MTLO1
:
28026 case MMI_OPC_MTHI1
:
28027 gen_HILO1_tx79(ctx
, opc
, rs
);
28029 case MMI_OPC_MFLO1
:
28030 case MMI_OPC_MFHI1
:
28031 gen_HILO1_tx79(ctx
, opc
, rd
);
28033 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
28034 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
28035 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
28036 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
28037 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
28038 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
28039 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
28040 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
28041 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
28042 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI */
28045 MIPS_INVAL("TX79 MMI class");
28046 generate_exception_end(ctx
, EXCP_RI
);
28051 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
28053 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_LQ */
28056 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
28058 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_SQ */
28062 * The TX79-specific instruction Store Quadword
28064 * +--------+-------+-------+------------------------+
28065 * | 011111 | base | rt | offset | SQ
28066 * +--------+-------+-------+------------------------+
28069 * has the same opcode as the Read Hardware Register instruction
28071 * +--------+-------+-------+-------+-------+--------+
28072 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28073 * +--------+-------+-------+-------+-------+--------+
28076 * that is required, trapped and emulated by the Linux kernel. However, all
28077 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28078 * offset is odd. Therefore all valid SQ instructions can execute normally.
28079 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28080 * between SQ and RDHWR, as the Linux kernel does.
28082 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
28084 int base
= extract32(ctx
->opcode
, 21, 5);
28085 int rt
= extract32(ctx
->opcode
, 16, 5);
28086 int offset
= extract32(ctx
->opcode
, 0, 16);
28088 #ifdef CONFIG_USER_ONLY
28089 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
28090 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
28092 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
28093 int rd
= extract32(ctx
->opcode
, 11, 5);
28095 gen_rdhwr(ctx
, rt
, rd
, 0);
28100 gen_mmi_sq(ctx
, base
, rt
, offset
);
28105 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
28107 int rs
, rt
, rd
, sa
;
28111 rs
= (ctx
->opcode
>> 21) & 0x1f;
28112 rt
= (ctx
->opcode
>> 16) & 0x1f;
28113 rd
= (ctx
->opcode
>> 11) & 0x1f;
28114 sa
= (ctx
->opcode
>> 6) & 0x1f;
28115 imm
= sextract32(ctx
->opcode
, 7, 9);
28117 op1
= MASK_SPECIAL3(ctx
->opcode
);
28120 * EVA loads and stores overlap Loongson 2E instructions decoded by
28121 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28128 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
28136 check_cp0_enabled(ctx
);
28137 gen_ld(ctx
, op1
, rt
, rs
, imm
);
28141 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
28146 check_cp0_enabled(ctx
);
28147 gen_st(ctx
, op1
, rt
, rs
, imm
);
28150 check_cp0_enabled(ctx
);
28151 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
28154 check_cp0_enabled(ctx
);
28155 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28156 gen_cache_operation(ctx
, rt
, rs
, imm
);
28158 /* Treat as NOP. */
28161 check_cp0_enabled(ctx
);
28162 /* Treat as NOP. */
28170 check_insn(ctx
, ISA_MIPS32R2
);
28171 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28174 op2
= MASK_BSHFL(ctx
->opcode
);
28181 check_insn(ctx
, ISA_MIPS32R6
);
28182 decode_opc_special3_r6(env
, ctx
);
28185 check_insn(ctx
, ISA_MIPS32R2
);
28186 gen_bshfl(ctx
, op2
, rt
, rd
);
28190 #if defined(TARGET_MIPS64)
28197 check_insn(ctx
, ISA_MIPS64R2
);
28198 check_mips_64(ctx
);
28199 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28202 op2
= MASK_DBSHFL(ctx
->opcode
);
28213 check_insn(ctx
, ISA_MIPS32R6
);
28214 decode_opc_special3_r6(env
, ctx
);
28217 check_insn(ctx
, ISA_MIPS64R2
);
28218 check_mips_64(ctx
);
28219 op2
= MASK_DBSHFL(ctx
->opcode
);
28220 gen_bshfl(ctx
, op2
, rt
, rd
);
28226 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28231 TCGv t0
= tcg_temp_new();
28232 TCGv t1
= tcg_temp_new();
28234 gen_load_gpr(t0
, rt
);
28235 gen_load_gpr(t1
, rs
);
28236 gen_helper_fork(t0
, t1
);
28244 TCGv t0
= tcg_temp_new();
28246 gen_load_gpr(t0
, rs
);
28247 gen_helper_yield(t0
, cpu_env
, t0
);
28248 gen_store_gpr(t0
, rd
);
28253 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
28254 decode_opc_special3_r6(env
, ctx
);
28256 decode_opc_special3_legacy(env
, ctx
);
28261 /* MIPS SIMD Architecture (MSA) */
28262 static inline int check_msa_access(DisasContext
*ctx
)
28264 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
28265 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
28266 generate_exception_end(ctx
, EXCP_RI
);
28270 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
28271 if (ctx
->insn_flags
& ASE_MSA
) {
28272 generate_exception_end(ctx
, EXCP_MSADIS
);
28275 generate_exception_end(ctx
, EXCP_RI
);
28282 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
28284 /* generates tcg ops to check if any element is 0 */
28285 /* Note this function only works with MSA_WRLEN = 128 */
28286 uint64_t eval_zero_or_big
= 0;
28287 uint64_t eval_big
= 0;
28288 TCGv_i64 t0
= tcg_temp_new_i64();
28289 TCGv_i64 t1
= tcg_temp_new_i64();
28292 eval_zero_or_big
= 0x0101010101010101ULL
;
28293 eval_big
= 0x8080808080808080ULL
;
28296 eval_zero_or_big
= 0x0001000100010001ULL
;
28297 eval_big
= 0x8000800080008000ULL
;
28300 eval_zero_or_big
= 0x0000000100000001ULL
;
28301 eval_big
= 0x8000000080000000ULL
;
28304 eval_zero_or_big
= 0x0000000000000001ULL
;
28305 eval_big
= 0x8000000000000000ULL
;
28308 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<< 1], eval_zero_or_big
);
28309 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<< 1]);
28310 tcg_gen_andi_i64(t0
, t0
, eval_big
);
28311 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<< 1) + 1], eval_zero_or_big
);
28312 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<< 1) + 1]);
28313 tcg_gen_andi_i64(t1
, t1
, eval_big
);
28314 tcg_gen_or_i64(t0
, t0
, t1
);
28315 /* if all bits are zero then all elements are not zero */
28316 /* if some bit is non-zero then some element is zero */
28317 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
28318 tcg_gen_trunc_i64_tl(tresult
, t0
);
28319 tcg_temp_free_i64(t0
);
28320 tcg_temp_free_i64(t1
);
28323 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
28325 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28326 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28327 int64_t s16
= (int16_t)ctx
->opcode
;
28329 check_msa_access(ctx
);
28331 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
28332 generate_exception_end(ctx
, EXCP_RI
);
28339 TCGv_i64 t0
= tcg_temp_new_i64();
28340 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<< 1], msa_wr_d
[(wt
<< 1) + 1]);
28341 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
28342 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
28343 tcg_gen_trunc_i64_tl(bcond
, t0
);
28344 tcg_temp_free_i64(t0
);
28351 gen_check_zero_element(bcond
, df
, wt
);
28357 gen_check_zero_element(bcond
, df
, wt
);
28358 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
28362 ctx
->btarget
= ctx
->base
.pc_next
+ (s16
<< 2) + 4;
28364 ctx
->hflags
|= MIPS_HFLAG_BC
;
28365 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
28368 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
28370 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28371 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
28372 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28373 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28375 TCGv_i32 twd
= tcg_const_i32(wd
);
28376 TCGv_i32 tws
= tcg_const_i32(ws
);
28377 TCGv_i32 ti8
= tcg_const_i32(i8
);
28379 switch (MASK_MSA_I8(ctx
->opcode
)) {
28381 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
28384 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
28387 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
28390 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
28393 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
28396 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
28399 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
28405 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
28406 if (df
== DF_DOUBLE
) {
28407 generate_exception_end(ctx
, EXCP_RI
);
28409 TCGv_i32 tdf
= tcg_const_i32(df
);
28410 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
28411 tcg_temp_free_i32(tdf
);
28416 MIPS_INVAL("MSA instruction");
28417 generate_exception_end(ctx
, EXCP_RI
);
28421 tcg_temp_free_i32(twd
);
28422 tcg_temp_free_i32(tws
);
28423 tcg_temp_free_i32(ti8
);
28426 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
28428 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28429 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28430 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
28431 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
28432 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28433 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28435 TCGv_i32 tdf
= tcg_const_i32(df
);
28436 TCGv_i32 twd
= tcg_const_i32(wd
);
28437 TCGv_i32 tws
= tcg_const_i32(ws
);
28438 TCGv_i32 timm
= tcg_temp_new_i32();
28439 tcg_gen_movi_i32(timm
, u5
);
28441 switch (MASK_MSA_I5(ctx
->opcode
)) {
28443 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28446 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28448 case OPC_MAXI_S_df
:
28449 tcg_gen_movi_i32(timm
, s5
);
28450 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28452 case OPC_MAXI_U_df
:
28453 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28455 case OPC_MINI_S_df
:
28456 tcg_gen_movi_i32(timm
, s5
);
28457 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28459 case OPC_MINI_U_df
:
28460 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28463 tcg_gen_movi_i32(timm
, s5
);
28464 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28466 case OPC_CLTI_S_df
:
28467 tcg_gen_movi_i32(timm
, s5
);
28468 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28470 case OPC_CLTI_U_df
:
28471 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28473 case OPC_CLEI_S_df
:
28474 tcg_gen_movi_i32(timm
, s5
);
28475 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28477 case OPC_CLEI_U_df
:
28478 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28482 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
28483 tcg_gen_movi_i32(timm
, s10
);
28484 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
28488 MIPS_INVAL("MSA instruction");
28489 generate_exception_end(ctx
, EXCP_RI
);
28493 tcg_temp_free_i32(tdf
);
28494 tcg_temp_free_i32(twd
);
28495 tcg_temp_free_i32(tws
);
28496 tcg_temp_free_i32(timm
);
28499 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
28501 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28502 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
28503 uint32_t df
= 0, m
= 0;
28504 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28505 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28512 if ((dfm
& 0x40) == 0x00) {
28515 } else if ((dfm
& 0x60) == 0x40) {
28518 } else if ((dfm
& 0x70) == 0x60) {
28521 } else if ((dfm
& 0x78) == 0x70) {
28525 generate_exception_end(ctx
, EXCP_RI
);
28529 tdf
= tcg_const_i32(df
);
28530 tm
= tcg_const_i32(m
);
28531 twd
= tcg_const_i32(wd
);
28532 tws
= tcg_const_i32(ws
);
28534 switch (MASK_MSA_BIT(ctx
->opcode
)) {
28536 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28539 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
28542 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28545 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28548 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
28551 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
28553 case OPC_BINSLI_df
:
28554 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28556 case OPC_BINSRI_df
:
28557 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28560 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
28563 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
28566 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
28569 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28572 MIPS_INVAL("MSA instruction");
28573 generate_exception_end(ctx
, EXCP_RI
);
28577 tcg_temp_free_i32(tdf
);
28578 tcg_temp_free_i32(tm
);
28579 tcg_temp_free_i32(twd
);
28580 tcg_temp_free_i32(tws
);
28583 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
28585 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28586 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28587 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28588 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28589 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28591 TCGv_i32 tdf
= tcg_const_i32(df
);
28592 TCGv_i32 twd
= tcg_const_i32(wd
);
28593 TCGv_i32 tws
= tcg_const_i32(ws
);
28594 TCGv_i32 twt
= tcg_const_i32(wt
);
28596 switch (MASK_MSA_3R(ctx
->opcode
)) {
28600 gen_helper_msa_binsl_b(cpu_env
, twd
, tws
, twt
);
28603 gen_helper_msa_binsl_h(cpu_env
, twd
, tws
, twt
);
28606 gen_helper_msa_binsl_w(cpu_env
, twd
, tws
, twt
);
28609 gen_helper_msa_binsl_d(cpu_env
, twd
, tws
, twt
);
28616 gen_helper_msa_binsr_b(cpu_env
, twd
, tws
, twt
);
28619 gen_helper_msa_binsr_h(cpu_env
, twd
, tws
, twt
);
28622 gen_helper_msa_binsr_w(cpu_env
, twd
, tws
, twt
);
28625 gen_helper_msa_binsr_d(cpu_env
, twd
, tws
, twt
);
28632 gen_helper_msa_bclr_b(cpu_env
, twd
, tws
, twt
);
28635 gen_helper_msa_bclr_h(cpu_env
, twd
, tws
, twt
);
28638 gen_helper_msa_bclr_w(cpu_env
, twd
, tws
, twt
);
28641 gen_helper_msa_bclr_d(cpu_env
, twd
, tws
, twt
);
28648 gen_helper_msa_bneg_b(cpu_env
, twd
, tws
, twt
);
28651 gen_helper_msa_bneg_h(cpu_env
, twd
, tws
, twt
);
28654 gen_helper_msa_bneg_w(cpu_env
, twd
, tws
, twt
);
28657 gen_helper_msa_bneg_d(cpu_env
, twd
, tws
, twt
);
28664 gen_helper_msa_bset_b(cpu_env
, twd
, tws
, twt
);
28667 gen_helper_msa_bset_h(cpu_env
, twd
, tws
, twt
);
28670 gen_helper_msa_bset_w(cpu_env
, twd
, tws
, twt
);
28673 gen_helper_msa_bset_d(cpu_env
, twd
, tws
, twt
);
28680 gen_helper_msa_add_a_b(cpu_env
, twd
, tws
, twt
);
28683 gen_helper_msa_add_a_h(cpu_env
, twd
, tws
, twt
);
28686 gen_helper_msa_add_a_w(cpu_env
, twd
, tws
, twt
);
28689 gen_helper_msa_add_a_d(cpu_env
, twd
, tws
, twt
);
28693 case OPC_ADDS_A_df
:
28696 gen_helper_msa_adds_a_b(cpu_env
, twd
, tws
, twt
);
28699 gen_helper_msa_adds_a_h(cpu_env
, twd
, tws
, twt
);
28702 gen_helper_msa_adds_a_w(cpu_env
, twd
, tws
, twt
);
28705 gen_helper_msa_adds_a_d(cpu_env
, twd
, tws
, twt
);
28709 case OPC_ADDS_S_df
:
28712 gen_helper_msa_adds_s_b(cpu_env
, twd
, tws
, twt
);
28715 gen_helper_msa_adds_s_h(cpu_env
, twd
, tws
, twt
);
28718 gen_helper_msa_adds_s_w(cpu_env
, twd
, tws
, twt
);
28721 gen_helper_msa_adds_s_d(cpu_env
, twd
, tws
, twt
);
28725 case OPC_ADDS_U_df
:
28728 gen_helper_msa_adds_u_b(cpu_env
, twd
, tws
, twt
);
28731 gen_helper_msa_adds_u_h(cpu_env
, twd
, tws
, twt
);
28734 gen_helper_msa_adds_u_w(cpu_env
, twd
, tws
, twt
);
28737 gen_helper_msa_adds_u_d(cpu_env
, twd
, tws
, twt
);
28744 gen_helper_msa_addv_b(cpu_env
, twd
, tws
, twt
);
28747 gen_helper_msa_addv_h(cpu_env
, twd
, tws
, twt
);
28750 gen_helper_msa_addv_w(cpu_env
, twd
, tws
, twt
);
28753 gen_helper_msa_addv_d(cpu_env
, twd
, tws
, twt
);
28760 gen_helper_msa_ave_s_b(cpu_env
, twd
, tws
, twt
);
28763 gen_helper_msa_ave_s_h(cpu_env
, twd
, tws
, twt
);
28766 gen_helper_msa_ave_s_w(cpu_env
, twd
, tws
, twt
);
28769 gen_helper_msa_ave_s_d(cpu_env
, twd
, tws
, twt
);
28776 gen_helper_msa_ave_u_b(cpu_env
, twd
, tws
, twt
);
28779 gen_helper_msa_ave_u_h(cpu_env
, twd
, tws
, twt
);
28782 gen_helper_msa_ave_u_w(cpu_env
, twd
, tws
, twt
);
28785 gen_helper_msa_ave_u_d(cpu_env
, twd
, tws
, twt
);
28789 case OPC_AVER_S_df
:
28792 gen_helper_msa_aver_s_b(cpu_env
, twd
, tws
, twt
);
28795 gen_helper_msa_aver_s_h(cpu_env
, twd
, tws
, twt
);
28798 gen_helper_msa_aver_s_w(cpu_env
, twd
, tws
, twt
);
28801 gen_helper_msa_aver_s_d(cpu_env
, twd
, tws
, twt
);
28805 case OPC_AVER_U_df
:
28808 gen_helper_msa_aver_u_b(cpu_env
, twd
, tws
, twt
);
28811 gen_helper_msa_aver_u_h(cpu_env
, twd
, tws
, twt
);
28814 gen_helper_msa_aver_u_w(cpu_env
, twd
, tws
, twt
);
28817 gen_helper_msa_aver_u_d(cpu_env
, twd
, tws
, twt
);
28824 gen_helper_msa_ceq_b(cpu_env
, twd
, tws
, twt
);
28827 gen_helper_msa_ceq_h(cpu_env
, twd
, tws
, twt
);
28830 gen_helper_msa_ceq_w(cpu_env
, twd
, tws
, twt
);
28833 gen_helper_msa_ceq_d(cpu_env
, twd
, tws
, twt
);
28840 gen_helper_msa_cle_s_b(cpu_env
, twd
, tws
, twt
);
28843 gen_helper_msa_cle_s_h(cpu_env
, twd
, tws
, twt
);
28846 gen_helper_msa_cle_s_w(cpu_env
, twd
, tws
, twt
);
28849 gen_helper_msa_cle_s_d(cpu_env
, twd
, tws
, twt
);
28856 gen_helper_msa_cle_u_b(cpu_env
, twd
, tws
, twt
);
28859 gen_helper_msa_cle_u_h(cpu_env
, twd
, tws
, twt
);
28862 gen_helper_msa_cle_u_w(cpu_env
, twd
, tws
, twt
);
28865 gen_helper_msa_cle_u_d(cpu_env
, twd
, tws
, twt
);
28872 gen_helper_msa_clt_s_b(cpu_env
, twd
, tws
, twt
);
28875 gen_helper_msa_clt_s_h(cpu_env
, twd
, tws
, twt
);
28878 gen_helper_msa_clt_s_w(cpu_env
, twd
, tws
, twt
);
28881 gen_helper_msa_clt_s_d(cpu_env
, twd
, tws
, twt
);
28888 gen_helper_msa_clt_u_b(cpu_env
, twd
, tws
, twt
);
28891 gen_helper_msa_clt_u_h(cpu_env
, twd
, tws
, twt
);
28894 gen_helper_msa_clt_u_w(cpu_env
, twd
, tws
, twt
);
28897 gen_helper_msa_clt_u_d(cpu_env
, twd
, tws
, twt
);
28904 gen_helper_msa_div_s_b(cpu_env
, twd
, tws
, twt
);
28907 gen_helper_msa_div_s_h(cpu_env
, twd
, tws
, twt
);
28910 gen_helper_msa_div_s_w(cpu_env
, twd
, tws
, twt
);
28913 gen_helper_msa_div_s_d(cpu_env
, twd
, tws
, twt
);
28920 gen_helper_msa_div_u_b(cpu_env
, twd
, tws
, twt
);
28923 gen_helper_msa_div_u_h(cpu_env
, twd
, tws
, twt
);
28926 gen_helper_msa_div_u_w(cpu_env
, twd
, tws
, twt
);
28929 gen_helper_msa_div_u_d(cpu_env
, twd
, tws
, twt
);
28936 gen_helper_msa_max_a_b(cpu_env
, twd
, tws
, twt
);
28939 gen_helper_msa_max_a_h(cpu_env
, twd
, tws
, twt
);
28942 gen_helper_msa_max_a_w(cpu_env
, twd
, tws
, twt
);
28945 gen_helper_msa_max_a_d(cpu_env
, twd
, tws
, twt
);
28952 gen_helper_msa_max_s_b(cpu_env
, twd
, tws
, twt
);
28955 gen_helper_msa_max_s_h(cpu_env
, twd
, tws
, twt
);
28958 gen_helper_msa_max_s_w(cpu_env
, twd
, tws
, twt
);
28961 gen_helper_msa_max_s_d(cpu_env
, twd
, tws
, twt
);
28968 gen_helper_msa_max_u_b(cpu_env
, twd
, tws
, twt
);
28971 gen_helper_msa_max_u_h(cpu_env
, twd
, tws
, twt
);
28974 gen_helper_msa_max_u_w(cpu_env
, twd
, tws
, twt
);
28977 gen_helper_msa_max_u_d(cpu_env
, twd
, tws
, twt
);
28984 gen_helper_msa_min_a_b(cpu_env
, twd
, tws
, twt
);
28987 gen_helper_msa_min_a_h(cpu_env
, twd
, tws
, twt
);
28990 gen_helper_msa_min_a_w(cpu_env
, twd
, tws
, twt
);
28993 gen_helper_msa_min_a_d(cpu_env
, twd
, tws
, twt
);
29000 gen_helper_msa_min_s_b(cpu_env
, twd
, tws
, twt
);
29003 gen_helper_msa_min_s_h(cpu_env
, twd
, tws
, twt
);
29006 gen_helper_msa_min_s_w(cpu_env
, twd
, tws
, twt
);
29009 gen_helper_msa_min_s_d(cpu_env
, twd
, tws
, twt
);
29016 gen_helper_msa_min_u_b(cpu_env
, twd
, tws
, twt
);
29019 gen_helper_msa_min_u_h(cpu_env
, twd
, tws
, twt
);
29022 gen_helper_msa_min_u_w(cpu_env
, twd
, tws
, twt
);
29025 gen_helper_msa_min_u_d(cpu_env
, twd
, tws
, twt
);
29032 gen_helper_msa_mod_s_b(cpu_env
, twd
, tws
, twt
);
29035 gen_helper_msa_mod_s_h(cpu_env
, twd
, tws
, twt
);
29038 gen_helper_msa_mod_s_w(cpu_env
, twd
, tws
, twt
);
29041 gen_helper_msa_mod_s_d(cpu_env
, twd
, tws
, twt
);
29048 gen_helper_msa_mod_u_b(cpu_env
, twd
, tws
, twt
);
29051 gen_helper_msa_mod_u_h(cpu_env
, twd
, tws
, twt
);
29054 gen_helper_msa_mod_u_w(cpu_env
, twd
, tws
, twt
);
29057 gen_helper_msa_mod_u_d(cpu_env
, twd
, tws
, twt
);
29061 case OPC_ASUB_S_df
:
29064 gen_helper_msa_asub_s_b(cpu_env
, twd
, tws
, twt
);
29067 gen_helper_msa_asub_s_h(cpu_env
, twd
, tws
, twt
);
29070 gen_helper_msa_asub_s_w(cpu_env
, twd
, tws
, twt
);
29073 gen_helper_msa_asub_s_d(cpu_env
, twd
, tws
, twt
);
29077 case OPC_ASUB_U_df
:
29080 gen_helper_msa_asub_u_b(cpu_env
, twd
, tws
, twt
);
29083 gen_helper_msa_asub_u_h(cpu_env
, twd
, tws
, twt
);
29086 gen_helper_msa_asub_u_w(cpu_env
, twd
, tws
, twt
);
29089 gen_helper_msa_asub_u_d(cpu_env
, twd
, tws
, twt
);
29096 gen_helper_msa_ilvev_b(cpu_env
, twd
, tws
, twt
);
29099 gen_helper_msa_ilvev_h(cpu_env
, twd
, tws
, twt
);
29102 gen_helper_msa_ilvev_w(cpu_env
, twd
, tws
, twt
);
29105 gen_helper_msa_ilvev_d(cpu_env
, twd
, tws
, twt
);
29112 gen_helper_msa_ilvod_b(cpu_env
, twd
, tws
, twt
);
29115 gen_helper_msa_ilvod_h(cpu_env
, twd
, tws
, twt
);
29118 gen_helper_msa_ilvod_w(cpu_env
, twd
, tws
, twt
);
29121 gen_helper_msa_ilvod_d(cpu_env
, twd
, tws
, twt
);
29128 gen_helper_msa_ilvl_b(cpu_env
, twd
, tws
, twt
);
29131 gen_helper_msa_ilvl_h(cpu_env
, twd
, tws
, twt
);
29134 gen_helper_msa_ilvl_w(cpu_env
, twd
, tws
, twt
);
29137 gen_helper_msa_ilvl_d(cpu_env
, twd
, tws
, twt
);
29144 gen_helper_msa_ilvr_b(cpu_env
, twd
, tws
, twt
);
29147 gen_helper_msa_ilvr_h(cpu_env
, twd
, tws
, twt
);
29150 gen_helper_msa_ilvr_w(cpu_env
, twd
, tws
, twt
);
29153 gen_helper_msa_ilvr_d(cpu_env
, twd
, tws
, twt
);
29160 gen_helper_msa_pckev_b(cpu_env
, twd
, tws
, twt
);
29163 gen_helper_msa_pckev_h(cpu_env
, twd
, tws
, twt
);
29166 gen_helper_msa_pckev_w(cpu_env
, twd
, tws
, twt
);
29169 gen_helper_msa_pckev_d(cpu_env
, twd
, tws
, twt
);
29176 gen_helper_msa_pckod_b(cpu_env
, twd
, tws
, twt
);
29179 gen_helper_msa_pckod_h(cpu_env
, twd
, tws
, twt
);
29182 gen_helper_msa_pckod_w(cpu_env
, twd
, tws
, twt
);
29185 gen_helper_msa_pckod_d(cpu_env
, twd
, tws
, twt
);
29192 gen_helper_msa_sll_b(cpu_env
, twd
, tws
, twt
);
29195 gen_helper_msa_sll_h(cpu_env
, twd
, tws
, twt
);
29198 gen_helper_msa_sll_w(cpu_env
, twd
, tws
, twt
);
29201 gen_helper_msa_sll_d(cpu_env
, twd
, tws
, twt
);
29208 gen_helper_msa_sra_b(cpu_env
, twd
, tws
, twt
);
29211 gen_helper_msa_sra_h(cpu_env
, twd
, tws
, twt
);
29214 gen_helper_msa_sra_w(cpu_env
, twd
, tws
, twt
);
29217 gen_helper_msa_sra_d(cpu_env
, twd
, tws
, twt
);
29224 gen_helper_msa_srar_b(cpu_env
, twd
, tws
, twt
);
29227 gen_helper_msa_srar_h(cpu_env
, twd
, tws
, twt
);
29230 gen_helper_msa_srar_w(cpu_env
, twd
, tws
, twt
);
29233 gen_helper_msa_srar_d(cpu_env
, twd
, tws
, twt
);
29240 gen_helper_msa_srl_b(cpu_env
, twd
, tws
, twt
);
29243 gen_helper_msa_srl_h(cpu_env
, twd
, tws
, twt
);
29246 gen_helper_msa_srl_w(cpu_env
, twd
, tws
, twt
);
29249 gen_helper_msa_srl_d(cpu_env
, twd
, tws
, twt
);
29256 gen_helper_msa_srlr_b(cpu_env
, twd
, tws
, twt
);
29259 gen_helper_msa_srlr_h(cpu_env
, twd
, tws
, twt
);
29262 gen_helper_msa_srlr_w(cpu_env
, twd
, tws
, twt
);
29265 gen_helper_msa_srlr_d(cpu_env
, twd
, tws
, twt
);
29269 case OPC_SUBS_S_df
:
29270 gen_helper_msa_subs_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29273 gen_helper_msa_mulv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29276 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
29279 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29282 gen_helper_msa_subv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29284 case OPC_SUBS_U_df
:
29285 gen_helper_msa_subs_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29288 gen_helper_msa_maddv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29291 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
29293 case OPC_SUBSUS_U_df
:
29294 gen_helper_msa_subsus_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29297 gen_helper_msa_msubv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29299 case OPC_SUBSUU_S_df
:
29300 gen_helper_msa_subsuu_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29303 case OPC_DOTP_S_df
:
29304 case OPC_DOTP_U_df
:
29305 case OPC_DPADD_S_df
:
29306 case OPC_DPADD_U_df
:
29307 case OPC_DPSUB_S_df
:
29308 case OPC_HADD_S_df
:
29309 case OPC_DPSUB_U_df
:
29310 case OPC_HADD_U_df
:
29311 case OPC_HSUB_S_df
:
29312 case OPC_HSUB_U_df
:
29313 if (df
== DF_BYTE
) {
29314 generate_exception_end(ctx
, EXCP_RI
);
29317 switch (MASK_MSA_3R(ctx
->opcode
)) {
29318 case OPC_HADD_S_df
:
29321 gen_helper_msa_hadd_s_h(cpu_env
, twd
, tws
, twt
);
29324 gen_helper_msa_hadd_s_w(cpu_env
, twd
, tws
, twt
);
29327 gen_helper_msa_hadd_s_d(cpu_env
, twd
, tws
, twt
);
29331 case OPC_HADD_U_df
:
29334 gen_helper_msa_hadd_u_h(cpu_env
, twd
, tws
, twt
);
29337 gen_helper_msa_hadd_u_w(cpu_env
, twd
, tws
, twt
);
29340 gen_helper_msa_hadd_u_d(cpu_env
, twd
, tws
, twt
);
29344 case OPC_HSUB_S_df
:
29347 gen_helper_msa_hsub_s_h(cpu_env
, twd
, tws
, twt
);
29350 gen_helper_msa_hsub_s_w(cpu_env
, twd
, tws
, twt
);
29353 gen_helper_msa_hsub_s_d(cpu_env
, twd
, tws
, twt
);
29357 case OPC_HSUB_U_df
:
29360 gen_helper_msa_hsub_u_h(cpu_env
, twd
, tws
, twt
);
29363 gen_helper_msa_hsub_u_w(cpu_env
, twd
, tws
, twt
);
29366 gen_helper_msa_hsub_u_d(cpu_env
, twd
, tws
, twt
);
29370 case OPC_DOTP_S_df
:
29371 gen_helper_msa_dotp_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29373 case OPC_DOTP_U_df
:
29374 gen_helper_msa_dotp_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29376 case OPC_DPADD_S_df
:
29377 gen_helper_msa_dpadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29379 case OPC_DPADD_U_df
:
29380 gen_helper_msa_dpadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29382 case OPC_DPSUB_S_df
:
29383 gen_helper_msa_dpsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
29385 case OPC_DPSUB_U_df
:
29386 gen_helper_msa_dpsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
29391 MIPS_INVAL("MSA instruction");
29392 generate_exception_end(ctx
, EXCP_RI
);
29395 tcg_temp_free_i32(twd
);
29396 tcg_temp_free_i32(tws
);
29397 tcg_temp_free_i32(twt
);
29398 tcg_temp_free_i32(tdf
);
29401 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
29403 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29404 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
29405 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
29406 TCGv telm
= tcg_temp_new();
29407 TCGv_i32 tsr
= tcg_const_i32(source
);
29408 TCGv_i32 tdt
= tcg_const_i32(dest
);
29410 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
29412 gen_load_gpr(telm
, source
);
29413 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
29416 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
29417 gen_store_gpr(telm
, dest
);
29420 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
29423 MIPS_INVAL("MSA instruction");
29424 generate_exception_end(ctx
, EXCP_RI
);
29428 tcg_temp_free(telm
);
29429 tcg_temp_free_i32(tdt
);
29430 tcg_temp_free_i32(tsr
);
29433 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
29436 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29437 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29438 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29440 TCGv_i32 tws
= tcg_const_i32(ws
);
29441 TCGv_i32 twd
= tcg_const_i32(wd
);
29442 TCGv_i32 tn
= tcg_const_i32(n
);
29443 TCGv_i32 tdf
= tcg_const_i32(df
);
29445 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29447 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
29449 case OPC_SPLATI_df
:
29450 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
29453 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
29455 case OPC_COPY_S_df
:
29456 case OPC_COPY_U_df
:
29457 case OPC_INSERT_df
:
29458 #if !defined(TARGET_MIPS64)
29459 /* Double format valid only for MIPS64 */
29460 if (df
== DF_DOUBLE
) {
29461 generate_exception_end(ctx
, EXCP_RI
);
29464 if ((MASK_MSA_ELM(ctx
->opcode
) == OPC_COPY_U_df
) &&
29466 generate_exception_end(ctx
, EXCP_RI
);
29470 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29471 case OPC_COPY_S_df
:
29472 if (likely(wd
!= 0)) {
29475 gen_helper_msa_copy_s_b(cpu_env
, twd
, tws
, tn
);
29478 gen_helper_msa_copy_s_h(cpu_env
, twd
, tws
, tn
);
29481 gen_helper_msa_copy_s_w(cpu_env
, twd
, tws
, tn
);
29483 #if defined(TARGET_MIPS64)
29485 gen_helper_msa_copy_s_d(cpu_env
, twd
, tws
, tn
);
29493 case OPC_COPY_U_df
:
29494 if (likely(wd
!= 0)) {
29497 gen_helper_msa_copy_u_b(cpu_env
, twd
, tws
, tn
);
29500 gen_helper_msa_copy_u_h(cpu_env
, twd
, tws
, tn
);
29502 #if defined(TARGET_MIPS64)
29504 gen_helper_msa_copy_u_w(cpu_env
, twd
, tws
, tn
);
29512 case OPC_INSERT_df
:
29515 gen_helper_msa_insert_b(cpu_env
, twd
, tws
, tn
);
29518 gen_helper_msa_insert_h(cpu_env
, twd
, tws
, tn
);
29521 gen_helper_msa_insert_w(cpu_env
, twd
, tws
, tn
);
29523 #if defined(TARGET_MIPS64)
29525 gen_helper_msa_insert_d(cpu_env
, twd
, tws
, tn
);
29535 MIPS_INVAL("MSA instruction");
29536 generate_exception_end(ctx
, EXCP_RI
);
29538 tcg_temp_free_i32(twd
);
29539 tcg_temp_free_i32(tws
);
29540 tcg_temp_free_i32(tn
);
29541 tcg_temp_free_i32(tdf
);
29544 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
29546 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
29547 uint32_t df
= 0, n
= 0;
29549 if ((dfn
& 0x30) == 0x00) {
29552 } else if ((dfn
& 0x38) == 0x20) {
29555 } else if ((dfn
& 0x3c) == 0x30) {
29558 } else if ((dfn
& 0x3e) == 0x38) {
29561 } else if (dfn
== 0x3E) {
29562 /* CTCMSA, CFCMSA, MOVE.V */
29563 gen_msa_elm_3e(env
, ctx
);
29566 generate_exception_end(ctx
, EXCP_RI
);
29570 gen_msa_elm_df(env
, ctx
, df
, n
);
29573 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
29575 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29576 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
29577 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29578 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29579 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29581 TCGv_i32 twd
= tcg_const_i32(wd
);
29582 TCGv_i32 tws
= tcg_const_i32(ws
);
29583 TCGv_i32 twt
= tcg_const_i32(wt
);
29584 TCGv_i32 tdf
= tcg_temp_new_i32();
29586 /* adjust df value for floating-point instruction */
29587 tcg_gen_movi_i32(tdf
, df
+ 2);
29589 switch (MASK_MSA_3RF(ctx
->opcode
)) {
29591 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29594 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
29597 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
29600 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
29603 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
29606 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29609 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
29612 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
29615 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29618 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29621 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
29624 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
29627 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
29630 tcg_gen_movi_i32(tdf
, df
+ 1);
29631 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29634 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
29637 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
29639 case OPC_MADD_Q_df
:
29640 tcg_gen_movi_i32(tdf
, df
+ 1);
29641 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29644 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
29646 case OPC_MSUB_Q_df
:
29647 tcg_gen_movi_i32(tdf
, df
+ 1);
29648 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29651 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
29654 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
29657 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29660 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
29663 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
29666 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
29669 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29672 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29675 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
29678 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29681 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
29684 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
29687 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
29689 case OPC_MULR_Q_df
:
29690 tcg_gen_movi_i32(tdf
, df
+ 1);
29691 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29694 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
29696 case OPC_FMIN_A_df
:
29697 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
29699 case OPC_MADDR_Q_df
:
29700 tcg_gen_movi_i32(tdf
, df
+ 1);
29701 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29704 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
29707 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
29709 case OPC_MSUBR_Q_df
:
29710 tcg_gen_movi_i32(tdf
, df
+ 1);
29711 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29714 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
29716 case OPC_FMAX_A_df
:
29717 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
29720 MIPS_INVAL("MSA instruction");
29721 generate_exception_end(ctx
, EXCP_RI
);
29725 tcg_temp_free_i32(twd
);
29726 tcg_temp_free_i32(tws
);
29727 tcg_temp_free_i32(twt
);
29728 tcg_temp_free_i32(tdf
);
29731 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
29733 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29734 (op & (0x7 << 18)))
29735 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29736 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29737 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29738 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
29739 TCGv_i32 twd
= tcg_const_i32(wd
);
29740 TCGv_i32 tws
= tcg_const_i32(ws
);
29741 TCGv_i32 twt
= tcg_const_i32(wt
);
29742 TCGv_i32 tdf
= tcg_const_i32(df
);
29744 switch (MASK_MSA_2R(ctx
->opcode
)) {
29746 #if !defined(TARGET_MIPS64)
29747 /* Double format valid only for MIPS64 */
29748 if (df
== DF_DOUBLE
) {
29749 generate_exception_end(ctx
, EXCP_RI
);
29753 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
29758 gen_helper_msa_nloc_b(cpu_env
, twd
, tws
);
29761 gen_helper_msa_nloc_h(cpu_env
, twd
, tws
);
29764 gen_helper_msa_nloc_w(cpu_env
, twd
, tws
);
29767 gen_helper_msa_nloc_d(cpu_env
, twd
, tws
);
29774 gen_helper_msa_nlzc_b(cpu_env
, twd
, tws
);
29777 gen_helper_msa_nlzc_h(cpu_env
, twd
, tws
);
29780 gen_helper_msa_nlzc_w(cpu_env
, twd
, tws
);
29783 gen_helper_msa_nlzc_d(cpu_env
, twd
, tws
);
29790 gen_helper_msa_pcnt_b(cpu_env
, twd
, tws
);
29793 gen_helper_msa_pcnt_h(cpu_env
, twd
, tws
);
29796 gen_helper_msa_pcnt_w(cpu_env
, twd
, tws
);
29799 gen_helper_msa_pcnt_d(cpu_env
, twd
, tws
);
29804 MIPS_INVAL("MSA instruction");
29805 generate_exception_end(ctx
, EXCP_RI
);
29809 tcg_temp_free_i32(twd
);
29810 tcg_temp_free_i32(tws
);
29811 tcg_temp_free_i32(twt
);
29812 tcg_temp_free_i32(tdf
);
29815 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
29817 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29818 (op & (0xf << 17)))
29819 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29820 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29821 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29822 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
29823 TCGv_i32 twd
= tcg_const_i32(wd
);
29824 TCGv_i32 tws
= tcg_const_i32(ws
);
29825 TCGv_i32 twt
= tcg_const_i32(wt
);
29826 /* adjust df value for floating-point instruction */
29827 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
29829 switch (MASK_MSA_2RF(ctx
->opcode
)) {
29830 case OPC_FCLASS_df
:
29831 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
29833 case OPC_FTRUNC_S_df
:
29834 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
29836 case OPC_FTRUNC_U_df
:
29837 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
29840 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
29842 case OPC_FRSQRT_df
:
29843 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
29846 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
29849 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
29852 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
29854 case OPC_FEXUPL_df
:
29855 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
29857 case OPC_FEXUPR_df
:
29858 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
29861 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
29864 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
29866 case OPC_FTINT_S_df
:
29867 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
29869 case OPC_FTINT_U_df
:
29870 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
29872 case OPC_FFINT_S_df
:
29873 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
29875 case OPC_FFINT_U_df
:
29876 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
29880 tcg_temp_free_i32(twd
);
29881 tcg_temp_free_i32(tws
);
29882 tcg_temp_free_i32(twt
);
29883 tcg_temp_free_i32(tdf
);
29886 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
29888 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
29889 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29890 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29891 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29892 TCGv_i32 twd
= tcg_const_i32(wd
);
29893 TCGv_i32 tws
= tcg_const_i32(ws
);
29894 TCGv_i32 twt
= tcg_const_i32(wt
);
29896 switch (MASK_MSA_VEC(ctx
->opcode
)) {
29898 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
29901 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
29904 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
29907 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
29910 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
29913 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
29916 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
29919 MIPS_INVAL("MSA instruction");
29920 generate_exception_end(ctx
, EXCP_RI
);
29924 tcg_temp_free_i32(twd
);
29925 tcg_temp_free_i32(tws
);
29926 tcg_temp_free_i32(twt
);
29929 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
29931 switch (MASK_MSA_VEC(ctx
->opcode
)) {
29939 gen_msa_vec_v(env
, ctx
);
29942 gen_msa_2r(env
, ctx
);
29945 gen_msa_2rf(env
, ctx
);
29948 MIPS_INVAL("MSA instruction");
29949 generate_exception_end(ctx
, EXCP_RI
);
29954 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
29956 uint32_t opcode
= ctx
->opcode
;
29957 check_insn(ctx
, ASE_MSA
);
29958 check_msa_access(ctx
);
29960 switch (MASK_MSA_MINOR(opcode
)) {
29961 case OPC_MSA_I8_00
:
29962 case OPC_MSA_I8_01
:
29963 case OPC_MSA_I8_02
:
29964 gen_msa_i8(env
, ctx
);
29966 case OPC_MSA_I5_06
:
29967 case OPC_MSA_I5_07
:
29968 gen_msa_i5(env
, ctx
);
29970 case OPC_MSA_BIT_09
:
29971 case OPC_MSA_BIT_0A
:
29972 gen_msa_bit(env
, ctx
);
29974 case OPC_MSA_3R_0D
:
29975 case OPC_MSA_3R_0E
:
29976 case OPC_MSA_3R_0F
:
29977 case OPC_MSA_3R_10
:
29978 case OPC_MSA_3R_11
:
29979 case OPC_MSA_3R_12
:
29980 case OPC_MSA_3R_13
:
29981 case OPC_MSA_3R_14
:
29982 case OPC_MSA_3R_15
:
29983 gen_msa_3r(env
, ctx
);
29986 gen_msa_elm(env
, ctx
);
29988 case OPC_MSA_3RF_1A
:
29989 case OPC_MSA_3RF_1B
:
29990 case OPC_MSA_3RF_1C
:
29991 gen_msa_3rf(env
, ctx
);
29994 gen_msa_vec(env
, ctx
);
30005 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
30006 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
30007 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30008 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
30010 TCGv_i32 twd
= tcg_const_i32(wd
);
30011 TCGv taddr
= tcg_temp_new();
30012 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
30014 switch (MASK_MSA_MINOR(opcode
)) {
30016 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
30019 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
30022 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
30025 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
30028 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
30031 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
30034 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
30037 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
30041 tcg_temp_free_i32(twd
);
30042 tcg_temp_free(taddr
);
30046 MIPS_INVAL("MSA instruction");
30047 generate_exception_end(ctx
, EXCP_RI
);
30053 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
30056 int rs
, rt
, rd
, sa
;
30060 /* make sure instructions are on a word boundary */
30061 if (ctx
->base
.pc_next
& 0x3) {
30062 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
30063 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
30067 /* Handle blikely not taken case */
30068 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
30069 TCGLabel
*l1
= gen_new_label();
30071 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
30072 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
30073 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
30077 op
= MASK_OP_MAJOR(ctx
->opcode
);
30078 rs
= (ctx
->opcode
>> 21) & 0x1f;
30079 rt
= (ctx
->opcode
>> 16) & 0x1f;
30080 rd
= (ctx
->opcode
>> 11) & 0x1f;
30081 sa
= (ctx
->opcode
>> 6) & 0x1f;
30082 imm
= (int16_t)ctx
->opcode
;
30085 decode_opc_special(env
, ctx
);
30088 #if defined(TARGET_MIPS64)
30089 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
30090 decode_mmi(env
, ctx
);
30092 if (ctx
->insn_flags
& ASE_MXU
) {
30093 decode_opc_mxu(env
, ctx
);
30096 decode_opc_special2_legacy(env
, ctx
);
30100 #if defined(TARGET_MIPS64)
30101 if (ctx
->insn_flags
& INSN_R5900
) {
30102 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
30104 decode_opc_special3(env
, ctx
);
30107 decode_opc_special3(env
, ctx
);
30111 op1
= MASK_REGIMM(ctx
->opcode
);
30113 case OPC_BLTZL
: /* REGIMM branches */
30117 check_insn(ctx
, ISA_MIPS2
);
30118 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30122 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30126 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30128 /* OPC_NAL, OPC_BAL */
30129 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
30131 generate_exception_end(ctx
, EXCP_RI
);
30134 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30137 case OPC_TGEI
: /* REGIMM traps */
30144 check_insn(ctx
, ISA_MIPS2
);
30145 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30146 gen_trap(ctx
, op1
, rs
, -1, imm
);
30149 check_insn(ctx
, ISA_MIPS32R6
);
30150 generate_exception_end(ctx
, EXCP_RI
);
30153 check_insn(ctx
, ISA_MIPS32R2
);
30155 * Break the TB to be able to sync copied instructions
30158 ctx
->base
.is_jmp
= DISAS_STOP
;
30160 case OPC_BPOSGE32
: /* MIPS DSP branch */
30161 #if defined(TARGET_MIPS64)
30165 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
30167 #if defined(TARGET_MIPS64)
30169 check_insn(ctx
, ISA_MIPS32R6
);
30170 check_mips_64(ctx
);
30172 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
30176 check_insn(ctx
, ISA_MIPS32R6
);
30177 check_mips_64(ctx
);
30179 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
30183 default: /* Invalid */
30184 MIPS_INVAL("regimm");
30185 generate_exception_end(ctx
, EXCP_RI
);
30190 check_cp0_enabled(ctx
);
30191 op1
= MASK_CP0(ctx
->opcode
);
30199 #if defined(TARGET_MIPS64)
30203 #ifndef CONFIG_USER_ONLY
30204 gen_cp0(env
, ctx
, op1
, rt
, rd
);
30205 #endif /* !CONFIG_USER_ONLY */
30223 #ifndef CONFIG_USER_ONLY
30224 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
30225 #endif /* !CONFIG_USER_ONLY */
30228 #ifndef CONFIG_USER_ONLY
30231 TCGv t0
= tcg_temp_new();
30233 op2
= MASK_MFMC0(ctx
->opcode
);
30237 gen_helper_dmt(t0
);
30238 gen_store_gpr(t0
, rt
);
30242 gen_helper_emt(t0
);
30243 gen_store_gpr(t0
, rt
);
30247 gen_helper_dvpe(t0
, cpu_env
);
30248 gen_store_gpr(t0
, rt
);
30252 gen_helper_evpe(t0
, cpu_env
);
30253 gen_store_gpr(t0
, rt
);
30256 check_insn(ctx
, ISA_MIPS32R6
);
30258 gen_helper_dvp(t0
, cpu_env
);
30259 gen_store_gpr(t0
, rt
);
30263 check_insn(ctx
, ISA_MIPS32R6
);
30265 gen_helper_evp(t0
, cpu_env
);
30266 gen_store_gpr(t0
, rt
);
30270 check_insn(ctx
, ISA_MIPS32R2
);
30271 save_cpu_state(ctx
, 1);
30272 gen_helper_di(t0
, cpu_env
);
30273 gen_store_gpr(t0
, rt
);
30275 * Stop translation as we may have switched
30276 * the execution mode.
30278 ctx
->base
.is_jmp
= DISAS_STOP
;
30281 check_insn(ctx
, ISA_MIPS32R2
);
30282 save_cpu_state(ctx
, 1);
30283 gen_helper_ei(t0
, cpu_env
);
30284 gen_store_gpr(t0
, rt
);
30286 * DISAS_STOP isn't sufficient, we need to ensure we break
30287 * out of translated code to check for pending interrupts.
30289 gen_save_pc(ctx
->base
.pc_next
+ 4);
30290 ctx
->base
.is_jmp
= DISAS_EXIT
;
30292 default: /* Invalid */
30293 MIPS_INVAL("mfmc0");
30294 generate_exception_end(ctx
, EXCP_RI
);
30299 #endif /* !CONFIG_USER_ONLY */
30302 check_insn(ctx
, ISA_MIPS32R2
);
30303 gen_load_srsgpr(rt
, rd
);
30306 check_insn(ctx
, ISA_MIPS32R2
);
30307 gen_store_srsgpr(rt
, rd
);
30311 generate_exception_end(ctx
, EXCP_RI
);
30315 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30316 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30317 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30318 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30321 /* Arithmetic with immediate opcode */
30322 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30326 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30328 case OPC_SLTI
: /* Set on less than with immediate opcode */
30330 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
30332 case OPC_ANDI
: /* Arithmetic with immediate opcode */
30333 case OPC_LUI
: /* OPC_AUI */
30336 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
30338 case OPC_J
: /* Jump */
30340 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30341 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30344 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30345 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30347 generate_exception_end(ctx
, EXCP_RI
);
30350 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30351 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30354 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30357 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30358 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30360 generate_exception_end(ctx
, EXCP_RI
);
30363 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30364 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30367 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30370 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30373 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30375 check_insn(ctx
, ISA_MIPS32R6
);
30376 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30377 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30380 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30383 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30385 check_insn(ctx
, ISA_MIPS32R6
);
30386 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30387 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30392 check_insn(ctx
, ISA_MIPS2
);
30393 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30397 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30399 case OPC_LL
: /* Load and stores */
30400 check_insn(ctx
, ISA_MIPS2
);
30401 if (ctx
->insn_flags
& INSN_R5900
) {
30402 check_insn_opc_user_only(ctx
, INSN_R5900
);
30407 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30415 gen_ld(ctx
, op
, rt
, rs
, imm
);
30419 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30424 gen_st(ctx
, op
, rt
, rs
, imm
);
30427 check_insn(ctx
, ISA_MIPS2
);
30428 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30429 if (ctx
->insn_flags
& INSN_R5900
) {
30430 check_insn_opc_user_only(ctx
, INSN_R5900
);
30432 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
30435 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30436 check_cp0_enabled(ctx
);
30437 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
30438 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
30439 gen_cache_operation(ctx
, rt
, rs
, imm
);
30441 /* Treat as NOP. */
30444 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30445 if (ctx
->insn_flags
& INSN_R5900
) {
30446 /* Treat as NOP. */
30448 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
30449 /* Treat as NOP. */
30453 /* Floating point (COP1). */
30458 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
30462 op1
= MASK_CP1(ctx
->opcode
);
30467 check_cp1_enabled(ctx
);
30468 check_insn(ctx
, ISA_MIPS32R2
);
30474 check_cp1_enabled(ctx
);
30475 gen_cp1(ctx
, op1
, rt
, rd
);
30477 #if defined(TARGET_MIPS64)
30480 check_cp1_enabled(ctx
);
30481 check_insn(ctx
, ISA_MIPS3
);
30482 check_mips_64(ctx
);
30483 gen_cp1(ctx
, op1
, rt
, rd
);
30486 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
30487 check_cp1_enabled(ctx
);
30488 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30490 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
30495 check_insn(ctx
, ASE_MIPS3D
);
30496 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
30497 (rt
>> 2) & 0x7, imm
<< 2);
30501 check_cp1_enabled(ctx
);
30502 check_insn(ctx
, ISA_MIPS32R6
);
30503 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
30507 check_cp1_enabled(ctx
);
30508 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30510 check_insn(ctx
, ASE_MIPS3D
);
30513 check_cp1_enabled(ctx
);
30514 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30515 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
30516 (rt
>> 2) & 0x7, imm
<< 2);
30523 check_cp1_enabled(ctx
);
30524 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
30530 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
30531 check_cp1_enabled(ctx
);
30532 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30534 case R6_OPC_CMP_AF_S
:
30535 case R6_OPC_CMP_UN_S
:
30536 case R6_OPC_CMP_EQ_S
:
30537 case R6_OPC_CMP_UEQ_S
:
30538 case R6_OPC_CMP_LT_S
:
30539 case R6_OPC_CMP_ULT_S
:
30540 case R6_OPC_CMP_LE_S
:
30541 case R6_OPC_CMP_ULE_S
:
30542 case R6_OPC_CMP_SAF_S
:
30543 case R6_OPC_CMP_SUN_S
:
30544 case R6_OPC_CMP_SEQ_S
:
30545 case R6_OPC_CMP_SEUQ_S
:
30546 case R6_OPC_CMP_SLT_S
:
30547 case R6_OPC_CMP_SULT_S
:
30548 case R6_OPC_CMP_SLE_S
:
30549 case R6_OPC_CMP_SULE_S
:
30550 case R6_OPC_CMP_OR_S
:
30551 case R6_OPC_CMP_UNE_S
:
30552 case R6_OPC_CMP_NE_S
:
30553 case R6_OPC_CMP_SOR_S
:
30554 case R6_OPC_CMP_SUNE_S
:
30555 case R6_OPC_CMP_SNE_S
:
30556 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
30558 case R6_OPC_CMP_AF_D
:
30559 case R6_OPC_CMP_UN_D
:
30560 case R6_OPC_CMP_EQ_D
:
30561 case R6_OPC_CMP_UEQ_D
:
30562 case R6_OPC_CMP_LT_D
:
30563 case R6_OPC_CMP_ULT_D
:
30564 case R6_OPC_CMP_LE_D
:
30565 case R6_OPC_CMP_ULE_D
:
30566 case R6_OPC_CMP_SAF_D
:
30567 case R6_OPC_CMP_SUN_D
:
30568 case R6_OPC_CMP_SEQ_D
:
30569 case R6_OPC_CMP_SEUQ_D
:
30570 case R6_OPC_CMP_SLT_D
:
30571 case R6_OPC_CMP_SULT_D
:
30572 case R6_OPC_CMP_SLE_D
:
30573 case R6_OPC_CMP_SULE_D
:
30574 case R6_OPC_CMP_OR_D
:
30575 case R6_OPC_CMP_UNE_D
:
30576 case R6_OPC_CMP_NE_D
:
30577 case R6_OPC_CMP_SOR_D
:
30578 case R6_OPC_CMP_SUNE_D
:
30579 case R6_OPC_CMP_SNE_D
:
30580 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
30583 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
30584 rt
, rd
, sa
, (imm
>> 8) & 0x7);
30589 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
30604 check_insn(ctx
, ASE_MSA
);
30605 gen_msa_branch(env
, ctx
, op1
);
30609 generate_exception_end(ctx
, EXCP_RI
);
30614 /* Compact branches [R6] and COP2 [non-R6] */
30615 case OPC_BC
: /* OPC_LWC2 */
30616 case OPC_BALC
: /* OPC_SWC2 */
30617 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30618 /* OPC_BC, OPC_BALC */
30619 gen_compute_compact_branch(ctx
, op
, 0, 0,
30620 sextract32(ctx
->opcode
<< 2, 0, 28));
30622 /* OPC_LWC2, OPC_SWC2 */
30623 /* COP2: Not implemented. */
30624 generate_exception_err(ctx
, EXCP_CpU
, 2);
30627 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
30628 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
30629 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30631 /* OPC_BEQZC, OPC_BNEZC */
30632 gen_compute_compact_branch(ctx
, op
, rs
, 0,
30633 sextract32(ctx
->opcode
<< 2, 0, 23));
30635 /* OPC_JIC, OPC_JIALC */
30636 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
30639 /* OPC_LWC2, OPC_SWC2 */
30640 /* COP2: Not implemented. */
30641 generate_exception_err(ctx
, EXCP_CpU
, 2);
30645 check_insn(ctx
, ASE_LMMI
);
30646 /* Note that these instructions use different fields. */
30647 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
30651 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30652 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
30653 check_cp1_enabled(ctx
);
30654 op1
= MASK_CP3(ctx
->opcode
);
30658 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
30664 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30665 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
30668 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30669 /* Treat as NOP. */
30672 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
30686 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30687 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
30691 generate_exception_end(ctx
, EXCP_RI
);
30695 generate_exception_err(ctx
, EXCP_CpU
, 1);
30699 #if defined(TARGET_MIPS64)
30700 /* MIPS64 opcodes */
30702 if (ctx
->insn_flags
& INSN_R5900
) {
30703 check_insn_opc_user_only(ctx
, INSN_R5900
);
30708 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30712 check_insn(ctx
, ISA_MIPS3
);
30713 check_mips_64(ctx
);
30714 gen_ld(ctx
, op
, rt
, rs
, imm
);
30718 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30721 check_insn(ctx
, ISA_MIPS3
);
30722 check_mips_64(ctx
);
30723 gen_st(ctx
, op
, rt
, rs
, imm
);
30726 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30727 check_insn(ctx
, ISA_MIPS3
);
30728 if (ctx
->insn_flags
& INSN_R5900
) {
30729 check_insn_opc_user_only(ctx
, INSN_R5900
);
30731 check_mips_64(ctx
);
30732 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
30734 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
30735 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30736 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
30737 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30740 check_insn(ctx
, ISA_MIPS3
);
30741 check_mips_64(ctx
);
30742 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30746 check_insn(ctx
, ISA_MIPS3
);
30747 check_mips_64(ctx
);
30748 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30751 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
30752 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30753 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30755 MIPS_INVAL("major opcode");
30756 generate_exception_end(ctx
, EXCP_RI
);
30760 case OPC_DAUI
: /* OPC_JALX */
30761 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30762 #if defined(TARGET_MIPS64)
30764 check_mips_64(ctx
);
30766 generate_exception(ctx
, EXCP_RI
);
30767 } else if (rt
!= 0) {
30768 TCGv t0
= tcg_temp_new();
30769 gen_load_gpr(t0
, rs
);
30770 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
30774 generate_exception_end(ctx
, EXCP_RI
);
30775 MIPS_INVAL("major opcode");
30779 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
30780 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30781 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30784 case OPC_MSA
: /* OPC_MDMX */
30785 if (ctx
->insn_flags
& INSN_R5900
) {
30786 #if defined(TARGET_MIPS64)
30787 gen_mmi_lq(env
, ctx
); /* MMI_OPC_LQ */
30790 /* MDMX: Not implemented. */
30795 check_insn(ctx
, ISA_MIPS32R6
);
30796 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
30798 default: /* Invalid */
30799 MIPS_INVAL("major opcode");
30800 generate_exception_end(ctx
, EXCP_RI
);
30805 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
30807 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30808 CPUMIPSState
*env
= cs
->env_ptr
;
30810 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
30811 ctx
->saved_pc
= -1;
30812 ctx
->insn_flags
= env
->insn_flags
;
30813 ctx
->CP0_Config1
= env
->CP0_Config1
;
30814 ctx
->CP0_Config2
= env
->CP0_Config2
;
30815 ctx
->CP0_Config3
= env
->CP0_Config3
;
30816 ctx
->CP0_Config5
= env
->CP0_Config5
;
30818 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
30819 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
30820 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
30821 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
30822 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
30823 ctx
->PAMask
= env
->PAMask
;
30824 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
30825 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
30826 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
30827 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
30828 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
30829 /* Restore delay slot state from the tb context. */
30830 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
30831 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
30832 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
30833 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
30834 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
30835 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
30836 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
30837 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
30838 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
30839 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
30840 restore_cpu_state(env
, ctx
);
30841 #ifdef CONFIG_USER_ONLY
30842 ctx
->mem_idx
= MIPS_HFLAG_UM
;
30844 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
30846 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& ISA_MIPS32R6
) ?
30847 MO_UNALN
: MO_ALIGN
;
30849 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
30853 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
30857 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
30859 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30861 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
30865 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
30866 const CPUBreakpoint
*bp
)
30868 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30870 save_cpu_state(ctx
, 1);
30871 ctx
->base
.is_jmp
= DISAS_NORETURN
;
30872 gen_helper_raise_exception_debug(cpu_env
);
30874 * The address covered by the breakpoint must be included in
30875 * [tb->pc, tb->pc + tb->size) in order to for it to be
30876 * properly cleared -- thus we increment the PC here so that
30877 * the logic setting tb->size below does the right thing.
30879 ctx
->base
.pc_next
+= 4;
30883 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
30885 CPUMIPSState
*env
= cs
->env_ptr
;
30886 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30890 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
30891 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
30892 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30893 insn_bytes
= decode_nanomips_opc(env
, ctx
);
30894 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
30895 ctx
->opcode
= cpu_ldl_code(env
, ctx
->base
.pc_next
);
30897 decode_opc(env
, ctx
);
30898 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
30899 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30900 insn_bytes
= decode_micromips_opc(env
, ctx
);
30901 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
30902 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30903 insn_bytes
= decode_mips16_opc(env
, ctx
);
30905 generate_exception_end(ctx
, EXCP_RI
);
30906 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
30910 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
30911 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
30912 MIPS_HFLAG_FBNSLOT
))) {
30914 * Force to generate branch as there is neither delay nor
30919 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
30920 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
30922 * Force to generate branch as microMIPS R6 doesn't restrict
30923 * branches in the forbidden slot.
30929 gen_branch(ctx
, insn_bytes
);
30931 ctx
->base
.pc_next
+= insn_bytes
;
30933 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
30937 * Execute a branch and its delay slot as a single instruction.
30938 * This is what GDB expects and is consistent with what the
30939 * hardware does (e.g. if a delay slot instruction faults, the
30940 * reported PC is the PC of the branch).
30942 if (ctx
->base
.singlestep_enabled
&&
30943 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
30944 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
30946 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
30947 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
30951 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
30953 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30955 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
30956 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
30957 gen_helper_raise_exception_debug(cpu_env
);
30959 switch (ctx
->base
.is_jmp
) {
30961 gen_save_pc(ctx
->base
.pc_next
);
30962 tcg_gen_lookup_and_goto_ptr();
30965 case DISAS_TOO_MANY
:
30966 save_cpu_state(ctx
, 0);
30967 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
30970 tcg_gen_exit_tb(NULL
, 0);
30972 case DISAS_NORETURN
:
30975 g_assert_not_reached();
30980 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
30982 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
30983 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
30986 static const TranslatorOps mips_tr_ops
= {
30987 .init_disas_context
= mips_tr_init_disas_context
,
30988 .tb_start
= mips_tr_tb_start
,
30989 .insn_start
= mips_tr_insn_start
,
30990 .breakpoint_check
= mips_tr_breakpoint_check
,
30991 .translate_insn
= mips_tr_translate_insn
,
30992 .tb_stop
= mips_tr_tb_stop
,
30993 .disas_log
= mips_tr_disas_log
,
30996 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
31000 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
31003 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
31006 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
31008 #define printfpr(fp) \
31011 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31012 " fd:%13g fs:%13g psu: %13g\n", \
31013 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
31014 (double)(fp)->fd, \
31015 (double)(fp)->fs[FP_ENDIAN_IDX], \
31016 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
31019 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
31020 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
31021 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31022 " fd:%13g fs:%13g psu:%13g\n", \
31023 tmp.w[FP_ENDIAN_IDX], tmp.d, \
31025 (double)tmp.fs[FP_ENDIAN_IDX], \
31026 (double)tmp.fs[!FP_ENDIAN_IDX]); \
31032 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
31033 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
31034 get_float_exception_flags(&env
->active_fpu
.fp_status
));
31035 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
31036 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
31037 printfpr(&env
->active_fpu
.fpr
[i
]);
31043 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
31045 MIPSCPU
*cpu
= MIPS_CPU(cs
);
31046 CPUMIPSState
*env
= &cpu
->env
;
31049 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
31050 " LO=0x" TARGET_FMT_lx
" ds %04x "
31051 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
31052 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
31053 env
->hflags
, env
->btarget
, env
->bcond
);
31054 for (i
= 0; i
< 32; i
++) {
31055 if ((i
& 3) == 0) {
31056 qemu_fprintf(f
, "GPR%02d:", i
);
31058 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
31059 regnames
[i
], env
->active_tc
.gpr
[i
]);
31060 if ((i
& 3) == 3) {
31061 qemu_fprintf(f
, "\n");
31065 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
31066 TARGET_FMT_lx
"\n",
31067 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
31068 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
31070 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
31071 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
31072 env
->CP0_Config2
, env
->CP0_Config3
);
31073 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
31074 env
->CP0_Config4
, env
->CP0_Config5
);
31075 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
31076 fpu_dump_state(env
, f
, flags
);
31080 void mips_tcg_init(void)
31085 for (i
= 1; i
< 32; i
++)
31086 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31087 offsetof(CPUMIPSState
,
31091 for (i
= 0; i
< 32; i
++) {
31092 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
31094 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
31096 * The scalar floating-point unit (FPU) registers are mapped on
31097 * the MSA vector registers.
31099 fpu_f64
[i
] = msa_wr_d
[i
* 2];
31100 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
31101 msa_wr_d
[i
* 2 + 1] =
31102 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
31105 cpu_PC
= tcg_global_mem_new(cpu_env
,
31106 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
31107 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
31108 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
31109 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
31111 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
31112 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
31115 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
31116 offsetof(CPUMIPSState
,
31117 active_tc
.DSPControl
),
31119 bcond
= tcg_global_mem_new(cpu_env
,
31120 offsetof(CPUMIPSState
, bcond
), "bcond");
31121 btarget
= tcg_global_mem_new(cpu_env
,
31122 offsetof(CPUMIPSState
, btarget
), "btarget");
31123 hflags
= tcg_global_mem_new_i32(cpu_env
,
31124 offsetof(CPUMIPSState
, hflags
), "hflags");
31126 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
31127 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
31129 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
31130 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
31132 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
31134 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
31137 #if defined(TARGET_MIPS64)
31139 for (i
= 1; i
< 32; i
++) {
31140 cpu_mmr
[i
] = tcg_global_mem_new_i64(cpu_env
,
31141 offsetof(CPUMIPSState
,
31147 #if !defined(TARGET_MIPS64)
31148 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
31149 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31150 offsetof(CPUMIPSState
,
31151 active_tc
.mxu_gpr
[i
]),
31155 mxu_CR
= tcg_global_mem_new(cpu_env
,
31156 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
31157 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
31161 #include "translate_init.inc.c"
31163 void cpu_mips_realize_env(CPUMIPSState
*env
)
31165 env
->exception_base
= (int32_t)0xBFC00000;
31167 #ifndef CONFIG_USER_ONLY
31168 mmu_init(env
, env
->cpu_model
);
31170 fpu_init(env
, env
->cpu_model
);
31171 mvp_init(env
, env
->cpu_model
);
31174 bool cpu_supports_cps_smp(const char *cpu_type
)
31176 const MIPSCPUClass
*mcc
= MIPS_CPU_CLASS(object_class_by_name(cpu_type
));
31177 return (mcc
->cpu_def
->CP0_Config3
& (1 << CP0C3_CMGCR
)) != 0;
31180 bool cpu_supports_isa(const char *cpu_type
, uint64_t isa
)
31182 const MIPSCPUClass
*mcc
= MIPS_CPU_CLASS(object_class_by_name(cpu_type
));
31183 return (mcc
->cpu_def
->insn_flags
& isa
) != 0;
31186 void cpu_set_exception_base(int vp_index
, target_ulong address
)
31188 MIPSCPU
*vp
= MIPS_CPU(qemu_get_cpu(vp_index
));
31189 vp
->env
.exception_base
= address
;
31192 void cpu_state_reset(CPUMIPSState
*env
)
31194 CPUState
*cs
= env_cpu(env
);
31196 /* Reset registers to their default values */
31197 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
31198 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
31199 #ifdef TARGET_WORDS_BIGENDIAN
31200 env
->CP0_Config0
|= (1 << CP0C0_BE
);
31202 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
31203 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
31204 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
31205 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
31206 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
31207 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
31208 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
31209 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
31210 env
->CP0_Config6_rw_bitmask
= env
->cpu_model
->CP0_Config6_rw_bitmask
;
31211 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
31212 env
->CP0_Config7_rw_bitmask
= env
->cpu_model
->CP0_Config7_rw_bitmask
;
31213 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
31214 << env
->cpu_model
->CP0_LLAddr_shift
;
31215 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
31216 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
31217 env
->CCRes
= env
->cpu_model
->CCRes
;
31218 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
31219 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
31220 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
31221 env
->current_tc
= 0;
31222 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
31223 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
31224 #if defined(TARGET_MIPS64)
31225 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
31226 env
->SEGMask
|= 3ULL << 62;
31229 env
->PABITS
= env
->cpu_model
->PABITS
;
31230 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
31231 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
31232 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
31233 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
31234 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
31235 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
31236 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
31237 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
31238 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
31239 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
31240 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
31241 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
31242 env
->CP0_EBaseWG_rw_bitmask
= env
->cpu_model
->CP0_EBaseWG_rw_bitmask
;
31243 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
31244 env
->active_fpu
.fcr31_rw_bitmask
= env
->cpu_model
->CP1_fcr31_rw_bitmask
;
31245 env
->active_fpu
.fcr31
= env
->cpu_model
->CP1_fcr31
;
31246 env
->msair
= env
->cpu_model
->MSAIR
;
31247 env
->insn_flags
= env
->cpu_model
->insn_flags
;
31249 #if defined(CONFIG_USER_ONLY)
31250 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
31251 # ifdef TARGET_MIPS64
31252 /* Enable 64-bit register mode. */
31253 env
->CP0_Status
|= (1 << CP0St_PX
);
31255 # ifdef TARGET_ABI_MIPSN64
31256 /* Enable 64-bit address mode. */
31257 env
->CP0_Status
|= (1 << CP0St_UX
);
31260 * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
31261 * hardware registers.
31263 env
->CP0_HWREna
|= 0x0000000F;
31264 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
31265 env
->CP0_Status
|= (1 << CP0St_CU1
);
31267 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
31268 env
->CP0_Status
|= (1 << CP0St_MX
);
31270 # if defined(TARGET_MIPS64)
31271 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
31272 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
31273 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
31274 env
->CP0_Status
|= (1 << CP0St_FR
);
31278 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
31280 * If the exception was raised from a delay slot,
31281 * come back to the jump.
31283 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
31284 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
31286 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
31288 env
->active_tc
.PC
= env
->exception_base
;
31289 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
31290 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
31291 env
->CP0_Wired
= 0;
31292 env
->CP0_GlobalNumber
= (cs
->cpu_index
& 0xFF) << CP0GN_VPId
;
31293 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
31294 if (mips_um_ksegs_enabled()) {
31295 env
->CP0_EBase
|= 0x40000000;
31297 env
->CP0_EBase
|= (int32_t)0x80000000;
31299 if (env
->CP0_Config3
& (1 << CP0C3_CMGCR
)) {
31300 env
->CP0_CMGCRBase
= 0x1fbf8000 >> 4;
31302 env
->CP0_EntryHi_ASID_mask
= (env
->CP0_Config5
& (1 << CP0C5_MI
)) ?
31303 0x0 : (env
->CP0_Config4
& (1 << CP0C4_AE
)) ? 0x3ff : 0xff;
31304 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
31306 * Vectored interrupts not implemented, timer on int 7,
31307 * no performance counters.
31309 env
->CP0_IntCtl
= 0xe0000000;
31313 for (i
= 0; i
< 7; i
++) {
31314 env
->CP0_WatchLo
[i
] = 0;
31315 env
->CP0_WatchHi
[i
] = 0x80000000;
31317 env
->CP0_WatchLo
[7] = 0;
31318 env
->CP0_WatchHi
[7] = 0;
31320 /* Count register increments in debug mode, EJTAG version 1 */
31321 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
31323 cpu_mips_store_count(env
, 1);
31325 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
31328 /* Only TC0 on VPE 0 starts as active. */
31329 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
31330 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
31331 env
->tcs
[i
].CP0_TCHalt
= 1;
31333 env
->active_tc
.CP0_TCHalt
= 1;
31336 if (cs
->cpu_index
== 0) {
31337 /* VPE0 starts up enabled. */
31338 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
31339 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
31341 /* TC0 starts up unhalted. */
31343 env
->active_tc
.CP0_TCHalt
= 0;
31344 env
->tcs
[0].CP0_TCHalt
= 0;
31345 /* With thread 0 active. */
31346 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
31347 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
31352 * Configure default legacy segmentation control. We use this regardless of
31353 * whether segmentation control is presented to the guest.
31355 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
31356 env
->CP0_SegCtl0
= (CP0SC_AM_MK
<< CP0SC_AM
);
31357 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
31358 env
->CP0_SegCtl0
|= ((CP0SC_AM_MSK
<< CP0SC_AM
)) << 16;
31359 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
31360 env
->CP0_SegCtl1
= (0 << CP0SC_PA
) | (CP0SC_AM_UK
<< CP0SC_AM
) |
31362 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
31363 env
->CP0_SegCtl1
|= ((0 << CP0SC_PA
) | (CP0SC_AM_UK
<< CP0SC_AM
) |
31364 (3 << CP0SC_C
)) << 16;
31365 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
31366 env
->CP0_SegCtl2
= (2 << CP0SC_PA
) | (CP0SC_AM_MUSK
<< CP0SC_AM
) |
31367 (1 << CP0SC_EU
) | (2 << CP0SC_C
);
31368 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
31369 env
->CP0_SegCtl2
|= ((0 << CP0SC_PA
) | (CP0SC_AM_MUSK
<< CP0SC_AM
) |
31370 (1 << CP0SC_EU
) | (2 << CP0SC_C
)) << 16;
31371 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
31372 env
->CP0_SegCtl1
|= (CP0SC_AM_UK
<< CP0SC1_XAM
);
31374 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
31375 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
31376 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
31377 env
->CP0_Status
|= (1 << CP0St_FR
);
31380 if (env
->insn_flags
& ISA_MIPS32R6
) {
31382 env
->CP0_PWSize
= 0x40;
31388 env
->CP0_PWField
= 0x0C30C302;
31395 env
->CP0_PWField
= 0x02;
31398 if (env
->CP0_Config3
& (1 << CP0C3_ISA
) & (1 << (CP0C3_ISA
+ 1))) {
31399 /* microMIPS on reset when Config3.ISA is 3 */
31400 env
->hflags
|= MIPS_HFLAG_M16
;
31404 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
31408 compute_hflags(env
);
31409 restore_fp_status(env
);
31410 restore_pamask(env
);
31411 cs
->exception_index
= EXCP_NONE
;
31413 if (semihosting_get_argc()) {
31414 /* UHI interface can be used to obtain argc and argv */
31415 env
->active_tc
.gpr
[4] = -1;
31419 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
31420 target_ulong
*data
)
31422 env
->active_tc
.PC
= data
[0];
31423 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
31424 env
->hflags
|= data
[1];
31425 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
31426 case MIPS_HFLAG_BR
:
31428 case MIPS_HFLAG_BC
:
31429 case MIPS_HFLAG_BL
:
31431 env
->btarget
= data
[2];