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
,
463 /* Loongson EXT load/store quad word opcodes */
464 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
466 OPC_GSLQ
= 0x0020 | OPC_LWC2
,
467 OPC_GSLQC1
= 0x8020 | OPC_LWC2
,
468 OPC_GSSHFL
= OPC_LWC2
,
469 OPC_GSSQ
= 0x0020 | OPC_SWC2
,
470 OPC_GSSQC1
= 0x8020 | OPC_SWC2
,
471 OPC_GSSHFS
= OPC_SWC2
,
474 /* Loongson EXT shifted load/store opcodes */
475 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
477 OPC_GSLWLC1
= 0x4 | OPC_GSSHFL
,
478 OPC_GSLWRC1
= 0x5 | OPC_GSSHFL
,
479 OPC_GSLDLC1
= 0x6 | OPC_GSSHFL
,
480 OPC_GSLDRC1
= 0x7 | OPC_GSSHFL
,
481 OPC_GSSWLC1
= 0x4 | OPC_GSSHFS
,
482 OPC_GSSWRC1
= 0x5 | OPC_GSSHFS
,
483 OPC_GSSDLC1
= 0x6 | OPC_GSSHFS
,
484 OPC_GSSDRC1
= 0x7 | OPC_GSSHFS
,
487 /* Loongson EXT LDC2/SDC2 opcodes */
488 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
491 OPC_GSLBX
= 0x0 | OPC_LDC2
,
492 OPC_GSLHX
= 0x1 | OPC_LDC2
,
493 OPC_GSLWX
= 0x2 | OPC_LDC2
,
494 OPC_GSLDX
= 0x3 | OPC_LDC2
,
495 OPC_GSLWXC1
= 0x6 | OPC_LDC2
,
496 OPC_GSLDXC1
= 0x7 | OPC_LDC2
,
497 OPC_GSSBX
= 0x0 | OPC_SDC2
,
498 OPC_GSSHX
= 0x1 | OPC_SDC2
,
499 OPC_GSSWX
= 0x2 | OPC_SDC2
,
500 OPC_GSSDX
= 0x3 | OPC_SDC2
,
501 OPC_GSSWXC1
= 0x6 | OPC_SDC2
,
502 OPC_GSSDXC1
= 0x7 | OPC_SDC2
,
506 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
509 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
510 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
511 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
512 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp (010.00 to 010.11) */
513 OPC_ALIGN_1
= (0x09 << 6) | OPC_BSHFL
,
514 OPC_ALIGN_2
= (0x0A << 6) | OPC_BSHFL
,
515 OPC_ALIGN_3
= (0x0B << 6) | OPC_BSHFL
,
516 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
520 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
523 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
524 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
525 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp (01.000 to 01.111) */
526 OPC_DALIGN_1
= (0x09 << 6) | OPC_DBSHFL
,
527 OPC_DALIGN_2
= (0x0A << 6) | OPC_DBSHFL
,
528 OPC_DALIGN_3
= (0x0B << 6) | OPC_DBSHFL
,
529 OPC_DALIGN_4
= (0x0C << 6) | OPC_DBSHFL
,
530 OPC_DALIGN_5
= (0x0D << 6) | OPC_DBSHFL
,
531 OPC_DALIGN_6
= (0x0E << 6) | OPC_DBSHFL
,
532 OPC_DALIGN_7
= (0x0F << 6) | OPC_DBSHFL
,
533 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
536 /* MIPS DSP REGIMM opcodes */
538 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
539 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
542 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
546 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
547 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
548 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
551 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 /* MIPS DSP Arithmetic Sub-class */
554 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
555 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
556 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
557 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
558 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
559 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
560 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
561 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
562 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
563 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
564 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
565 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
566 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
567 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
568 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
569 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
570 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
571 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
572 /* MIPS DSP Multiply Sub-class insns */
573 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
574 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
575 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
576 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
577 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
578 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
581 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
582 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
584 /* MIPS DSP Arithmetic Sub-class */
585 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
586 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
587 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
588 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
589 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
590 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
591 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
592 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
593 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
594 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
595 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
596 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
597 /* MIPS DSP Multiply Sub-class insns */
598 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
599 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
600 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
601 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
604 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
606 /* MIPS DSP Arithmetic Sub-class */
607 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
608 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
609 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
610 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
611 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
612 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
613 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
614 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
615 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
616 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
617 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
618 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
619 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
620 /* DSP Bit/Manipulation Sub-class */
621 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
622 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
623 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
624 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
625 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
628 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
630 /* MIPS DSP Arithmetic Sub-class */
631 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
632 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
633 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
634 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
635 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
636 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
637 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
638 /* DSP Compare-Pick Sub-class */
639 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
640 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
641 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
642 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
643 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
644 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
645 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
646 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
647 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
648 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
649 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
650 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
651 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
652 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
653 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
656 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
658 /* MIPS DSP GPR-Based Shift Sub-class */
659 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
660 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
661 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
662 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
663 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
664 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
665 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
666 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
667 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
668 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
669 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
670 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
671 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
672 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
673 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
674 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
675 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
676 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
677 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
678 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
679 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
680 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
683 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
685 /* MIPS DSP Multiply Sub-class insns */
686 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
687 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
688 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
689 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
690 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
691 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
692 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
693 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
694 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
695 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
696 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
697 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
698 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
699 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
700 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
701 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
702 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
703 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
704 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
705 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
706 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
707 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
710 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
712 /* DSP Bit/Manipulation Sub-class */
713 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
716 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
718 /* MIPS DSP Append Sub-class */
719 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
720 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
721 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
724 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
726 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
727 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
728 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
729 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
730 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
731 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
732 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
733 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
734 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
735 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
736 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
737 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
738 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
739 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
740 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
741 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
742 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
743 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
746 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
748 /* MIPS DSP Arithmetic Sub-class */
749 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
750 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
751 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
752 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
753 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
754 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
755 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
756 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
757 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
758 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
759 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
760 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
761 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
762 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
763 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
764 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
765 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
766 /* DSP Bit/Manipulation Sub-class */
767 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
768 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
769 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
770 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
771 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
772 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
775 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
777 /* MIPS DSP Multiply Sub-class insns */
778 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
779 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
780 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
781 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
782 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
783 /* MIPS DSP Arithmetic Sub-class */
784 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
785 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
786 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
787 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
788 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
789 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
790 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
791 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
792 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
793 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
794 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
795 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
796 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
797 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
798 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
799 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
800 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
801 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
802 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
803 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
804 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
807 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
809 /* DSP Compare-Pick Sub-class */
810 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
811 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
812 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
813 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
814 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
815 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
816 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
817 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
818 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
819 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
820 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
821 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
822 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
823 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
824 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
825 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
826 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
827 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
828 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
829 /* MIPS DSP Arithmetic Sub-class */
830 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
831 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
832 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
833 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
834 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
835 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
836 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
837 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
840 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
842 /* DSP Append Sub-class */
843 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
844 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
845 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
846 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
849 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
851 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
852 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
853 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
854 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
855 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
856 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
857 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
858 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
859 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
860 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
861 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
862 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
863 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
864 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
865 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
866 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
867 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
868 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
869 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
870 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
871 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
872 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
875 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
877 /* DSP Bit/Manipulation Sub-class */
878 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
881 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
883 /* MIPS DSP Multiply Sub-class insns */
884 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
885 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
886 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
887 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
888 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
889 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
890 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
891 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
892 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
893 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
894 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
895 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
896 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
897 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
898 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
899 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
900 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
901 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
902 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
903 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
904 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
905 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
906 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
907 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
908 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
909 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
912 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
914 /* MIPS DSP GPR-Based Shift Sub-class */
915 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
916 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
917 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
918 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
919 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
920 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
921 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
922 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
923 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
924 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
925 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
926 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
927 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
928 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
929 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
930 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
931 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
932 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
933 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
934 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
935 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
936 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
937 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
938 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
939 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
940 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
943 /* Coprocessor 0 (rs field) */
944 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
947 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
948 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
949 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
950 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
951 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
952 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
953 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
954 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
955 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
956 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
957 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
958 OPC_C0
= (0x10 << 21) | OPC_CP0
,
959 OPC_C0_1
= (0x11 << 21) | OPC_CP0
,
960 OPC_C0_2
= (0x12 << 21) | OPC_CP0
,
961 OPC_C0_3
= (0x13 << 21) | OPC_CP0
,
962 OPC_C0_4
= (0x14 << 21) | OPC_CP0
,
963 OPC_C0_5
= (0x15 << 21) | OPC_CP0
,
964 OPC_C0_6
= (0x16 << 21) | OPC_CP0
,
965 OPC_C0_7
= (0x17 << 21) | OPC_CP0
,
966 OPC_C0_8
= (0x18 << 21) | OPC_CP0
,
967 OPC_C0_9
= (0x19 << 21) | OPC_CP0
,
968 OPC_C0_A
= (0x1A << 21) | OPC_CP0
,
969 OPC_C0_B
= (0x1B << 21) | OPC_CP0
,
970 OPC_C0_C
= (0x1C << 21) | OPC_CP0
,
971 OPC_C0_D
= (0x1D << 21) | OPC_CP0
,
972 OPC_C0_E
= (0x1E << 21) | OPC_CP0
,
973 OPC_C0_F
= (0x1F << 21) | OPC_CP0
,
977 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
980 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
981 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
982 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
983 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
984 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
985 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
986 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
987 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
990 /* Coprocessor 0 (with rs == C0) */
991 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
994 OPC_TLBR
= 0x01 | OPC_C0
,
995 OPC_TLBWI
= 0x02 | OPC_C0
,
996 OPC_TLBINV
= 0x03 | OPC_C0
,
997 OPC_TLBINVF
= 0x04 | OPC_C0
,
998 OPC_TLBWR
= 0x06 | OPC_C0
,
999 OPC_TLBP
= 0x08 | OPC_C0
,
1000 OPC_RFE
= 0x10 | OPC_C0
,
1001 OPC_ERET
= 0x18 | OPC_C0
,
1002 OPC_DERET
= 0x1F | OPC_C0
,
1003 OPC_WAIT
= 0x20 | OPC_C0
,
1006 /* Coprocessor 1 (rs field) */
1007 #define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1009 /* Values for the fmt field in FP instructions */
1011 /* 0 - 15 are reserved */
1012 FMT_S
= 16, /* single fp */
1013 FMT_D
= 17, /* double fp */
1014 FMT_E
= 18, /* extended fp */
1015 FMT_Q
= 19, /* quad fp */
1016 FMT_W
= 20, /* 32-bit fixed */
1017 FMT_L
= 21, /* 64-bit fixed */
1018 FMT_PS
= 22, /* paired single fp */
1019 /* 23 - 31 are reserved */
1023 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
1024 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
1025 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
1026 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
1027 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
1028 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
1029 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
1030 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
1031 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
1032 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
1033 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
1034 OPC_BZ_V
= (0x0B << 21) | OPC_CP1
,
1035 OPC_BNZ_V
= (0x0F << 21) | OPC_CP1
,
1036 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
1037 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
1038 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
1039 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
1040 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
1041 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
1042 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
1043 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
1044 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
1045 OPC_BZ_B
= (0x18 << 21) | OPC_CP1
,
1046 OPC_BZ_H
= (0x19 << 21) | OPC_CP1
,
1047 OPC_BZ_W
= (0x1A << 21) | OPC_CP1
,
1048 OPC_BZ_D
= (0x1B << 21) | OPC_CP1
,
1049 OPC_BNZ_B
= (0x1C << 21) | OPC_CP1
,
1050 OPC_BNZ_H
= (0x1D << 21) | OPC_CP1
,
1051 OPC_BNZ_W
= (0x1E << 21) | OPC_CP1
,
1052 OPC_BNZ_D
= (0x1F << 21) | OPC_CP1
,
1055 #define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F))
1056 #define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16)))
1059 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
1060 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
1061 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
1062 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
1066 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
1067 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
1071 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
1072 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
1075 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1078 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
1079 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
1080 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
1081 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
1082 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
1083 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
1084 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
1085 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
1086 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
1087 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1088 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1091 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1094 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1095 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1096 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1097 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1098 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1099 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1100 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1101 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1103 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1104 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1105 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1106 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1107 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1108 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1109 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1110 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1112 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1113 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1114 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1115 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1116 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1117 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1118 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1119 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1121 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1122 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1123 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1124 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1125 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1126 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1127 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1128 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1130 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1131 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1132 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1133 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1134 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1135 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1137 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1138 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1139 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1140 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1141 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1142 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1144 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1145 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1146 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1147 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1148 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1149 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1151 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1152 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1153 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1154 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1155 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1156 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1158 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1159 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1160 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1161 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1162 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1163 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1165 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1166 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1167 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1168 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1169 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1170 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1172 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1173 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1174 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1175 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1176 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1177 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1179 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1180 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1181 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1182 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1183 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1184 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1188 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1191 OPC_LWXC1
= 0x00 | OPC_CP3
,
1192 OPC_LDXC1
= 0x01 | OPC_CP3
,
1193 OPC_LUXC1
= 0x05 | OPC_CP3
,
1194 OPC_SWXC1
= 0x08 | OPC_CP3
,
1195 OPC_SDXC1
= 0x09 | OPC_CP3
,
1196 OPC_SUXC1
= 0x0D | OPC_CP3
,
1197 OPC_PREFX
= 0x0F | OPC_CP3
,
1198 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1199 OPC_MADD_S
= 0x20 | OPC_CP3
,
1200 OPC_MADD_D
= 0x21 | OPC_CP3
,
1201 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1202 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1203 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1204 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1205 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1206 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1207 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1208 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1209 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1210 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1214 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1216 OPC_MSA_I8_00
= 0x00 | OPC_MSA
,
1217 OPC_MSA_I8_01
= 0x01 | OPC_MSA
,
1218 OPC_MSA_I8_02
= 0x02 | OPC_MSA
,
1219 OPC_MSA_I5_06
= 0x06 | OPC_MSA
,
1220 OPC_MSA_I5_07
= 0x07 | OPC_MSA
,
1221 OPC_MSA_BIT_09
= 0x09 | OPC_MSA
,
1222 OPC_MSA_BIT_0A
= 0x0A | OPC_MSA
,
1223 OPC_MSA_3R_0D
= 0x0D | OPC_MSA
,
1224 OPC_MSA_3R_0E
= 0x0E | OPC_MSA
,
1225 OPC_MSA_3R_0F
= 0x0F | OPC_MSA
,
1226 OPC_MSA_3R_10
= 0x10 | OPC_MSA
,
1227 OPC_MSA_3R_11
= 0x11 | OPC_MSA
,
1228 OPC_MSA_3R_12
= 0x12 | OPC_MSA
,
1229 OPC_MSA_3R_13
= 0x13 | OPC_MSA
,
1230 OPC_MSA_3R_14
= 0x14 | OPC_MSA
,
1231 OPC_MSA_3R_15
= 0x15 | OPC_MSA
,
1232 OPC_MSA_ELM
= 0x19 | OPC_MSA
,
1233 OPC_MSA_3RF_1A
= 0x1A | OPC_MSA
,
1234 OPC_MSA_3RF_1B
= 0x1B | OPC_MSA
,
1235 OPC_MSA_3RF_1C
= 0x1C | OPC_MSA
,
1236 OPC_MSA_VEC
= 0x1E | OPC_MSA
,
1238 /* MI10 instruction */
1239 OPC_LD_B
= (0x20) | OPC_MSA
,
1240 OPC_LD_H
= (0x21) | OPC_MSA
,
1241 OPC_LD_W
= (0x22) | OPC_MSA
,
1242 OPC_LD_D
= (0x23) | OPC_MSA
,
1243 OPC_ST_B
= (0x24) | OPC_MSA
,
1244 OPC_ST_H
= (0x25) | OPC_MSA
,
1245 OPC_ST_W
= (0x26) | OPC_MSA
,
1246 OPC_ST_D
= (0x27) | OPC_MSA
,
1250 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1251 OPC_ADDVI_df
= (0x0 << 23) | OPC_MSA_I5_06
,
1252 OPC_CEQI_df
= (0x0 << 23) | OPC_MSA_I5_07
,
1253 OPC_SUBVI_df
= (0x1 << 23) | OPC_MSA_I5_06
,
1254 OPC_MAXI_S_df
= (0x2 << 23) | OPC_MSA_I5_06
,
1255 OPC_CLTI_S_df
= (0x2 << 23) | OPC_MSA_I5_07
,
1256 OPC_MAXI_U_df
= (0x3 << 23) | OPC_MSA_I5_06
,
1257 OPC_CLTI_U_df
= (0x3 << 23) | OPC_MSA_I5_07
,
1258 OPC_MINI_S_df
= (0x4 << 23) | OPC_MSA_I5_06
,
1259 OPC_CLEI_S_df
= (0x4 << 23) | OPC_MSA_I5_07
,
1260 OPC_MINI_U_df
= (0x5 << 23) | OPC_MSA_I5_06
,
1261 OPC_CLEI_U_df
= (0x5 << 23) | OPC_MSA_I5_07
,
1262 OPC_LDI_df
= (0x6 << 23) | OPC_MSA_I5_07
,
1264 /* I8 instruction */
1265 OPC_ANDI_B
= (0x0 << 24) | OPC_MSA_I8_00
,
1266 OPC_BMNZI_B
= (0x0 << 24) | OPC_MSA_I8_01
,
1267 OPC_SHF_B
= (0x0 << 24) | OPC_MSA_I8_02
,
1268 OPC_ORI_B
= (0x1 << 24) | OPC_MSA_I8_00
,
1269 OPC_BMZI_B
= (0x1 << 24) | OPC_MSA_I8_01
,
1270 OPC_SHF_H
= (0x1 << 24) | OPC_MSA_I8_02
,
1271 OPC_NORI_B
= (0x2 << 24) | OPC_MSA_I8_00
,
1272 OPC_BSELI_B
= (0x2 << 24) | OPC_MSA_I8_01
,
1273 OPC_SHF_W
= (0x2 << 24) | OPC_MSA_I8_02
,
1274 OPC_XORI_B
= (0x3 << 24) | OPC_MSA_I8_00
,
1276 /* VEC/2R/2RF instruction */
1277 OPC_AND_V
= (0x00 << 21) | OPC_MSA_VEC
,
1278 OPC_OR_V
= (0x01 << 21) | OPC_MSA_VEC
,
1279 OPC_NOR_V
= (0x02 << 21) | OPC_MSA_VEC
,
1280 OPC_XOR_V
= (0x03 << 21) | OPC_MSA_VEC
,
1281 OPC_BMNZ_V
= (0x04 << 21) | OPC_MSA_VEC
,
1282 OPC_BMZ_V
= (0x05 << 21) | OPC_MSA_VEC
,
1283 OPC_BSEL_V
= (0x06 << 21) | OPC_MSA_VEC
,
1285 OPC_MSA_2R
= (0x18 << 21) | OPC_MSA_VEC
,
1286 OPC_MSA_2RF
= (0x19 << 21) | OPC_MSA_VEC
,
1288 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1289 OPC_FILL_df
= (0x00 << 18) | OPC_MSA_2R
,
1290 OPC_PCNT_df
= (0x01 << 18) | OPC_MSA_2R
,
1291 OPC_NLOC_df
= (0x02 << 18) | OPC_MSA_2R
,
1292 OPC_NLZC_df
= (0x03 << 18) | OPC_MSA_2R
,
1294 /* 2RF instruction df(bit 16) = _w, _d */
1295 OPC_FCLASS_df
= (0x00 << 17) | OPC_MSA_2RF
,
1296 OPC_FTRUNC_S_df
= (0x01 << 17) | OPC_MSA_2RF
,
1297 OPC_FTRUNC_U_df
= (0x02 << 17) | OPC_MSA_2RF
,
1298 OPC_FSQRT_df
= (0x03 << 17) | OPC_MSA_2RF
,
1299 OPC_FRSQRT_df
= (0x04 << 17) | OPC_MSA_2RF
,
1300 OPC_FRCP_df
= (0x05 << 17) | OPC_MSA_2RF
,
1301 OPC_FRINT_df
= (0x06 << 17) | OPC_MSA_2RF
,
1302 OPC_FLOG2_df
= (0x07 << 17) | OPC_MSA_2RF
,
1303 OPC_FEXUPL_df
= (0x08 << 17) | OPC_MSA_2RF
,
1304 OPC_FEXUPR_df
= (0x09 << 17) | OPC_MSA_2RF
,
1305 OPC_FFQL_df
= (0x0A << 17) | OPC_MSA_2RF
,
1306 OPC_FFQR_df
= (0x0B << 17) | OPC_MSA_2RF
,
1307 OPC_FTINT_S_df
= (0x0C << 17) | OPC_MSA_2RF
,
1308 OPC_FTINT_U_df
= (0x0D << 17) | OPC_MSA_2RF
,
1309 OPC_FFINT_S_df
= (0x0E << 17) | OPC_MSA_2RF
,
1310 OPC_FFINT_U_df
= (0x0F << 17) | OPC_MSA_2RF
,
1312 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1313 OPC_SLL_df
= (0x0 << 23) | OPC_MSA_3R_0D
,
1314 OPC_ADDV_df
= (0x0 << 23) | OPC_MSA_3R_0E
,
1315 OPC_CEQ_df
= (0x0 << 23) | OPC_MSA_3R_0F
,
1316 OPC_ADD_A_df
= (0x0 << 23) | OPC_MSA_3R_10
,
1317 OPC_SUBS_S_df
= (0x0 << 23) | OPC_MSA_3R_11
,
1318 OPC_MULV_df
= (0x0 << 23) | OPC_MSA_3R_12
,
1319 OPC_DOTP_S_df
= (0x0 << 23) | OPC_MSA_3R_13
,
1320 OPC_SLD_df
= (0x0 << 23) | OPC_MSA_3R_14
,
1321 OPC_VSHF_df
= (0x0 << 23) | OPC_MSA_3R_15
,
1322 OPC_SRA_df
= (0x1 << 23) | OPC_MSA_3R_0D
,
1323 OPC_SUBV_df
= (0x1 << 23) | OPC_MSA_3R_0E
,
1324 OPC_ADDS_A_df
= (0x1 << 23) | OPC_MSA_3R_10
,
1325 OPC_SUBS_U_df
= (0x1 << 23) | OPC_MSA_3R_11
,
1326 OPC_MADDV_df
= (0x1 << 23) | OPC_MSA_3R_12
,
1327 OPC_DOTP_U_df
= (0x1 << 23) | OPC_MSA_3R_13
,
1328 OPC_SPLAT_df
= (0x1 << 23) | OPC_MSA_3R_14
,
1329 OPC_SRAR_df
= (0x1 << 23) | OPC_MSA_3R_15
,
1330 OPC_SRL_df
= (0x2 << 23) | OPC_MSA_3R_0D
,
1331 OPC_MAX_S_df
= (0x2 << 23) | OPC_MSA_3R_0E
,
1332 OPC_CLT_S_df
= (0x2 << 23) | OPC_MSA_3R_0F
,
1333 OPC_ADDS_S_df
= (0x2 << 23) | OPC_MSA_3R_10
,
1334 OPC_SUBSUS_U_df
= (0x2 << 23) | OPC_MSA_3R_11
,
1335 OPC_MSUBV_df
= (0x2 << 23) | OPC_MSA_3R_12
,
1336 OPC_DPADD_S_df
= (0x2 << 23) | OPC_MSA_3R_13
,
1337 OPC_PCKEV_df
= (0x2 << 23) | OPC_MSA_3R_14
,
1338 OPC_SRLR_df
= (0x2 << 23) | OPC_MSA_3R_15
,
1339 OPC_BCLR_df
= (0x3 << 23) | OPC_MSA_3R_0D
,
1340 OPC_MAX_U_df
= (0x3 << 23) | OPC_MSA_3R_0E
,
1341 OPC_CLT_U_df
= (0x3 << 23) | OPC_MSA_3R_0F
,
1342 OPC_ADDS_U_df
= (0x3 << 23) | OPC_MSA_3R_10
,
1343 OPC_SUBSUU_S_df
= (0x3 << 23) | OPC_MSA_3R_11
,
1344 OPC_DPADD_U_df
= (0x3 << 23) | OPC_MSA_3R_13
,
1345 OPC_PCKOD_df
= (0x3 << 23) | OPC_MSA_3R_14
,
1346 OPC_BSET_df
= (0x4 << 23) | OPC_MSA_3R_0D
,
1347 OPC_MIN_S_df
= (0x4 << 23) | OPC_MSA_3R_0E
,
1348 OPC_CLE_S_df
= (0x4 << 23) | OPC_MSA_3R_0F
,
1349 OPC_AVE_S_df
= (0x4 << 23) | OPC_MSA_3R_10
,
1350 OPC_ASUB_S_df
= (0x4 << 23) | OPC_MSA_3R_11
,
1351 OPC_DIV_S_df
= (0x4 << 23) | OPC_MSA_3R_12
,
1352 OPC_DPSUB_S_df
= (0x4 << 23) | OPC_MSA_3R_13
,
1353 OPC_ILVL_df
= (0x4 << 23) | OPC_MSA_3R_14
,
1354 OPC_HADD_S_df
= (0x4 << 23) | OPC_MSA_3R_15
,
1355 OPC_BNEG_df
= (0x5 << 23) | OPC_MSA_3R_0D
,
1356 OPC_MIN_U_df
= (0x5 << 23) | OPC_MSA_3R_0E
,
1357 OPC_CLE_U_df
= (0x5 << 23) | OPC_MSA_3R_0F
,
1358 OPC_AVE_U_df
= (0x5 << 23) | OPC_MSA_3R_10
,
1359 OPC_ASUB_U_df
= (0x5 << 23) | OPC_MSA_3R_11
,
1360 OPC_DIV_U_df
= (0x5 << 23) | OPC_MSA_3R_12
,
1361 OPC_DPSUB_U_df
= (0x5 << 23) | OPC_MSA_3R_13
,
1362 OPC_ILVR_df
= (0x5 << 23) | OPC_MSA_3R_14
,
1363 OPC_HADD_U_df
= (0x5 << 23) | OPC_MSA_3R_15
,
1364 OPC_BINSL_df
= (0x6 << 23) | OPC_MSA_3R_0D
,
1365 OPC_MAX_A_df
= (0x6 << 23) | OPC_MSA_3R_0E
,
1366 OPC_AVER_S_df
= (0x6 << 23) | OPC_MSA_3R_10
,
1367 OPC_MOD_S_df
= (0x6 << 23) | OPC_MSA_3R_12
,
1368 OPC_ILVEV_df
= (0x6 << 23) | OPC_MSA_3R_14
,
1369 OPC_HSUB_S_df
= (0x6 << 23) | OPC_MSA_3R_15
,
1370 OPC_BINSR_df
= (0x7 << 23) | OPC_MSA_3R_0D
,
1371 OPC_MIN_A_df
= (0x7 << 23) | OPC_MSA_3R_0E
,
1372 OPC_AVER_U_df
= (0x7 << 23) | OPC_MSA_3R_10
,
1373 OPC_MOD_U_df
= (0x7 << 23) | OPC_MSA_3R_12
,
1374 OPC_ILVOD_df
= (0x7 << 23) | OPC_MSA_3R_14
,
1375 OPC_HSUB_U_df
= (0x7 << 23) | OPC_MSA_3R_15
,
1377 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1378 OPC_SLDI_df
= (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1379 OPC_CTCMSA
= (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1380 OPC_SPLATI_df
= (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1381 OPC_CFCMSA
= (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1382 OPC_COPY_S_df
= (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1383 OPC_MOVE_V
= (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1384 OPC_COPY_U_df
= (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1385 OPC_INSERT_df
= (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1386 OPC_INSVE_df
= (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1388 /* 3RF instruction _df(bit 21) = _w, _d */
1389 OPC_FCAF_df
= (0x0 << 22) | OPC_MSA_3RF_1A
,
1390 OPC_FADD_df
= (0x0 << 22) | OPC_MSA_3RF_1B
,
1391 OPC_FCUN_df
= (0x1 << 22) | OPC_MSA_3RF_1A
,
1392 OPC_FSUB_df
= (0x1 << 22) | OPC_MSA_3RF_1B
,
1393 OPC_FCOR_df
= (0x1 << 22) | OPC_MSA_3RF_1C
,
1394 OPC_FCEQ_df
= (0x2 << 22) | OPC_MSA_3RF_1A
,
1395 OPC_FMUL_df
= (0x2 << 22) | OPC_MSA_3RF_1B
,
1396 OPC_FCUNE_df
= (0x2 << 22) | OPC_MSA_3RF_1C
,
1397 OPC_FCUEQ_df
= (0x3 << 22) | OPC_MSA_3RF_1A
,
1398 OPC_FDIV_df
= (0x3 << 22) | OPC_MSA_3RF_1B
,
1399 OPC_FCNE_df
= (0x3 << 22) | OPC_MSA_3RF_1C
,
1400 OPC_FCLT_df
= (0x4 << 22) | OPC_MSA_3RF_1A
,
1401 OPC_FMADD_df
= (0x4 << 22) | OPC_MSA_3RF_1B
,
1402 OPC_MUL_Q_df
= (0x4 << 22) | OPC_MSA_3RF_1C
,
1403 OPC_FCULT_df
= (0x5 << 22) | OPC_MSA_3RF_1A
,
1404 OPC_FMSUB_df
= (0x5 << 22) | OPC_MSA_3RF_1B
,
1405 OPC_MADD_Q_df
= (0x5 << 22) | OPC_MSA_3RF_1C
,
1406 OPC_FCLE_df
= (0x6 << 22) | OPC_MSA_3RF_1A
,
1407 OPC_MSUB_Q_df
= (0x6 << 22) | OPC_MSA_3RF_1C
,
1408 OPC_FCULE_df
= (0x7 << 22) | OPC_MSA_3RF_1A
,
1409 OPC_FEXP2_df
= (0x7 << 22) | OPC_MSA_3RF_1B
,
1410 OPC_FSAF_df
= (0x8 << 22) | OPC_MSA_3RF_1A
,
1411 OPC_FEXDO_df
= (0x8 << 22) | OPC_MSA_3RF_1B
,
1412 OPC_FSUN_df
= (0x9 << 22) | OPC_MSA_3RF_1A
,
1413 OPC_FSOR_df
= (0x9 << 22) | OPC_MSA_3RF_1C
,
1414 OPC_FSEQ_df
= (0xA << 22) | OPC_MSA_3RF_1A
,
1415 OPC_FTQ_df
= (0xA << 22) | OPC_MSA_3RF_1B
,
1416 OPC_FSUNE_df
= (0xA << 22) | OPC_MSA_3RF_1C
,
1417 OPC_FSUEQ_df
= (0xB << 22) | OPC_MSA_3RF_1A
,
1418 OPC_FSNE_df
= (0xB << 22) | OPC_MSA_3RF_1C
,
1419 OPC_FSLT_df
= (0xC << 22) | OPC_MSA_3RF_1A
,
1420 OPC_FMIN_df
= (0xC << 22) | OPC_MSA_3RF_1B
,
1421 OPC_MULR_Q_df
= (0xC << 22) | OPC_MSA_3RF_1C
,
1422 OPC_FSULT_df
= (0xD << 22) | OPC_MSA_3RF_1A
,
1423 OPC_FMIN_A_df
= (0xD << 22) | OPC_MSA_3RF_1B
,
1424 OPC_MADDR_Q_df
= (0xD << 22) | OPC_MSA_3RF_1C
,
1425 OPC_FSLE_df
= (0xE << 22) | OPC_MSA_3RF_1A
,
1426 OPC_FMAX_df
= (0xE << 22) | OPC_MSA_3RF_1B
,
1427 OPC_MSUBR_Q_df
= (0xE << 22) | OPC_MSA_3RF_1C
,
1428 OPC_FSULE_df
= (0xF << 22) | OPC_MSA_3RF_1A
,
1429 OPC_FMAX_A_df
= (0xF << 22) | OPC_MSA_3RF_1B
,
1431 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1432 OPC_SLLI_df
= (0x0 << 23) | OPC_MSA_BIT_09
,
1433 OPC_SAT_S_df
= (0x0 << 23) | OPC_MSA_BIT_0A
,
1434 OPC_SRAI_df
= (0x1 << 23) | OPC_MSA_BIT_09
,
1435 OPC_SAT_U_df
= (0x1 << 23) | OPC_MSA_BIT_0A
,
1436 OPC_SRLI_df
= (0x2 << 23) | OPC_MSA_BIT_09
,
1437 OPC_SRARI_df
= (0x2 << 23) | OPC_MSA_BIT_0A
,
1438 OPC_BCLRI_df
= (0x3 << 23) | OPC_MSA_BIT_09
,
1439 OPC_SRLRI_df
= (0x3 << 23) | OPC_MSA_BIT_0A
,
1440 OPC_BSETI_df
= (0x4 << 23) | OPC_MSA_BIT_09
,
1441 OPC_BNEGI_df
= (0x5 << 23) | OPC_MSA_BIT_09
,
1442 OPC_BINSLI_df
= (0x6 << 23) | OPC_MSA_BIT_09
,
1443 OPC_BINSRI_df
= (0x7 << 23) | OPC_MSA_BIT_09
,
1449 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1450 * ============================================
1453 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1454 * instructions set. It is designed to fit the needs of signal, graphical and
1455 * video processing applications. MXU instruction set is used in Xburst family
1456 * of microprocessors by Ingenic.
1458 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1459 * the control register.
1462 * The notation used in MXU assembler mnemonics
1463 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1465 * Register operands:
1467 * XRa, XRb, XRc, XRd - MXU registers
1468 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1470 * Non-register operands:
1472 * aptn1 - 1-bit accumulate add/subtract pattern
1473 * aptn2 - 2-bit accumulate add/subtract pattern
1474 * eptn2 - 2-bit execute add/subtract pattern
1475 * optn2 - 2-bit operand pattern
1476 * optn3 - 3-bit operand pattern
1477 * sft4 - 4-bit shift amount
1478 * strd2 - 2-bit stride amount
1482 * Level of parallelism: Operand size:
1483 * S - single operation at a time 32 - word
1484 * D - two operations in parallel 16 - half word
1485 * Q - four operations in parallel 8 - byte
1489 * ADD - Add or subtract
1490 * ADDC - Add with carry-in
1492 * ASUM - Sum together then accumulate (add or subtract)
1493 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1494 * AVG - Average between 2 operands
1495 * ABD - Absolute difference
1497 * AND - Logical bitwise 'and' operation
1499 * EXTR - Extract bits
1500 * I2M - Move from GPR register to MXU register
1501 * LDD - Load data from memory to XRF
1502 * LDI - Load data from memory to XRF (and increase the address base)
1503 * LUI - Load unsigned immediate
1505 * MULU - Unsigned multiply
1506 * MADD - 64-bit operand add 32x32 product
1507 * MSUB - 64-bit operand subtract 32x32 product
1508 * MAC - Multiply and accumulate (add or subtract)
1509 * MAD - Multiply and add or subtract
1510 * MAX - Maximum between 2 operands
1511 * MIN - Minimum between 2 operands
1512 * M2I - Move from MXU register to GPR register
1513 * MOVZ - Move if zero
1514 * MOVN - Move if non-zero
1515 * NOR - Logical bitwise 'nor' operation
1516 * OR - Logical bitwise 'or' operation
1517 * STD - Store data from XRF to memory
1518 * SDI - Store data from XRF to memory (and increase the address base)
1519 * SLT - Set of less than comparison
1520 * SAD - Sum of absolute differences
1521 * SLL - Logical shift left
1522 * SLR - Logical shift right
1523 * SAR - Arithmetic shift right
1526 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1527 * XOR - Logical bitwise 'exclusive or' operation
1531 * E - Expand results
1532 * F - Fixed point multiplication
1533 * L - Low part result
1534 * R - Doing rounding
1535 * V - Variable instead of immediate
1536 * W - Combine above L and V
1539 * The list of MXU instructions grouped by functionality
1540 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1542 * Load/Store instructions Multiplication instructions
1543 * ----------------------- ---------------------------
1545 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1546 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1547 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1548 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1549 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1550 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1551 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1552 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1553 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1554 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1555 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1556 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1557 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1558 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1559 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1560 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1561 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1562 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1563 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1564 * S16SDI XRa, Rb, s10, eptn2
1565 * S8LDD XRa, Rb, s8, eptn3
1566 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1567 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1568 * S8SDI XRa, Rb, s8, eptn3
1569 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1570 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1571 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1572 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1573 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1574 * S32CPS XRa, XRb, XRc
1575 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1576 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1577 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1578 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1579 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1580 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1581 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1582 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1583 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1584 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1585 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1586 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1587 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1588 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1589 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1590 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1591 * Q8SLT XRa, XRb, XRc
1592 * Q8SLTU XRa, XRb, XRc
1593 * Q8MOVZ XRa, XRb, XRc Shift instructions
1594 * Q8MOVN XRa, XRb, XRc ------------------
1596 * D32SLL XRa, XRb, XRc, XRd, sft4
1597 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1598 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1599 * D32SARL XRa, XRb, XRc, sft4
1600 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1601 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1602 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1603 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1604 * Q16SLL XRa, XRb, XRc, XRd, sft4
1605 * Q16SLR XRa, XRb, XRc, XRd, sft4
1606 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1607 * ------------------------- Q16SLLV XRa, XRb, Rb
1608 * Q16SLRV XRa, XRb, Rb
1609 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1610 * S32ALN XRa, XRb, XRc, Rb
1611 * S32ALNI XRa, XRb, XRc, s3
1612 * S32LUI XRa, s8, optn3 Move instructions
1613 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1614 * S32EXTRV XRa, XRb, Rs, Rt
1615 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1616 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1619 * The opcode organization of MXU instructions
1620 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1622 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1623 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1624 * other bits up to the instruction level is as follows:
1629 * ┌─ 000000 ─ OPC_MXU_S32MADD
1630 * ├─ 000001 ─ OPC_MXU_S32MADDU
1631 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1634 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1635 * │ ├─ 001 ─ OPC_MXU_S32MIN
1636 * │ ├─ 010 ─ OPC_MXU_D16MAX
1637 * │ ├─ 011 ─ OPC_MXU_D16MIN
1638 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1639 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1640 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1641 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1642 * ├─ 000100 ─ OPC_MXU_S32MSUB
1643 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1644 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1645 * │ ├─ 001 ─ OPC_MXU_D16SLT
1646 * │ ├─ 010 ─ OPC_MXU_D16AVG
1647 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1648 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1649 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1650 * │ └─ 111 ─ OPC_MXU_Q8ADD
1653 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1654 * │ ├─ 010 ─ OPC_MXU_D16CPS
1655 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1656 * │ └─ 110 ─ OPC_MXU_Q16SAT
1657 * ├─ 001000 ─ OPC_MXU_D16MUL
1659 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1660 * │ └─ 01 ─ OPC_MXU_D16MULE
1661 * ├─ 001010 ─ OPC_MXU_D16MAC
1662 * ├─ 001011 ─ OPC_MXU_D16MACF
1663 * ├─ 001100 ─ OPC_MXU_D16MADL
1664 * ├─ 001101 ─ OPC_MXU_S16MAD
1665 * ├─ 001110 ─ OPC_MXU_Q16ADD
1666 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1667 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1668 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1671 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1672 * │ └─ 1 ─ OPC_MXU_S32STDR
1675 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1676 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1679 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1680 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1683 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1684 * │ └─ 1 ─ OPC_MXU_S32LDIR
1687 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1688 * │ └─ 1 ─ OPC_MXU_S32SDIR
1691 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1692 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1695 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1696 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1697 * ├─ 011000 ─ OPC_MXU_D32ADD
1699 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1700 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1701 * │ └─ 10 ─ OPC_MXU_D32ASUM
1702 * ├─ 011010 ─ <not assigned>
1704 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1705 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1706 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1709 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1710 * │ ├─ 01 ─ OPC_MXU_D8SUM
1711 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1712 * ├─ 011110 ─ <not assigned>
1713 * ├─ 011111 ─ <not assigned>
1714 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1715 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1716 * ├─ 100010 ─ OPC_MXU_S8LDD
1717 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1718 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1719 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1720 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1721 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1724 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1725 * │ ├─ 001 ─ OPC_MXU_S32ALN
1726 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1727 * │ ├─ 011 ─ OPC_MXU_S32LUI
1728 * │ ├─ 100 ─ OPC_MXU_S32NOR
1729 * │ ├─ 101 ─ OPC_MXU_S32AND
1730 * │ ├─ 110 ─ OPC_MXU_S32OR
1731 * │ └─ 111 ─ OPC_MXU_S32XOR
1734 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1735 * │ ├─ 001 ─ OPC_MXU_LXH
1736 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1737 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1738 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1739 * ├─ 101100 ─ OPC_MXU_S16LDI
1740 * ├─ 101101 ─ OPC_MXU_S16SDI
1741 * ├─ 101110 ─ OPC_MXU_S32M2I
1742 * ├─ 101111 ─ OPC_MXU_S32I2M
1743 * ├─ 110000 ─ OPC_MXU_D32SLL
1744 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1745 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1746 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1747 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1748 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1749 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1750 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1752 * ├─ 110111 ─ OPC_MXU_Q16SAR
1754 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1755 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1758 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1759 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1760 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1761 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1762 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1763 * │ └─ 101 ─ OPC_MXU_S32MOVN
1766 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1767 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1768 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1769 * ├─ 111100 ─ OPC_MXU_Q8MADL
1770 * ├─ 111101 ─ OPC_MXU_S32SFL
1771 * ├─ 111110 ─ OPC_MXU_Q8SAD
1772 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1777 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1778 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1782 OPC_MXU_S32MADD
= 0x00,
1783 OPC_MXU_S32MADDU
= 0x01,
1784 OPC__MXU_MUL
= 0x02,
1785 OPC_MXU__POOL00
= 0x03,
1786 OPC_MXU_S32MSUB
= 0x04,
1787 OPC_MXU_S32MSUBU
= 0x05,
1788 OPC_MXU__POOL01
= 0x06,
1789 OPC_MXU__POOL02
= 0x07,
1790 OPC_MXU_D16MUL
= 0x08,
1791 OPC_MXU__POOL03
= 0x09,
1792 OPC_MXU_D16MAC
= 0x0A,
1793 OPC_MXU_D16MACF
= 0x0B,
1794 OPC_MXU_D16MADL
= 0x0C,
1795 OPC_MXU_S16MAD
= 0x0D,
1796 OPC_MXU_Q16ADD
= 0x0E,
1797 OPC_MXU_D16MACE
= 0x0F,
1798 OPC_MXU__POOL04
= 0x10,
1799 OPC_MXU__POOL05
= 0x11,
1800 OPC_MXU__POOL06
= 0x12,
1801 OPC_MXU__POOL07
= 0x13,
1802 OPC_MXU__POOL08
= 0x14,
1803 OPC_MXU__POOL09
= 0x15,
1804 OPC_MXU__POOL10
= 0x16,
1805 OPC_MXU__POOL11
= 0x17,
1806 OPC_MXU_D32ADD
= 0x18,
1807 OPC_MXU__POOL12
= 0x19,
1808 /* not assigned 0x1A */
1809 OPC_MXU__POOL13
= 0x1B,
1810 OPC_MXU__POOL14
= 0x1C,
1811 OPC_MXU_Q8ACCE
= 0x1D,
1812 /* not assigned 0x1E */
1813 /* not assigned 0x1F */
1814 /* not assigned 0x20 */
1815 /* not assigned 0x21 */
1816 OPC_MXU_S8LDD
= 0x22,
1817 OPC_MXU_S8STD
= 0x23,
1818 OPC_MXU_S8LDI
= 0x24,
1819 OPC_MXU_S8SDI
= 0x25,
1820 OPC_MXU__POOL15
= 0x26,
1821 OPC_MXU__POOL16
= 0x27,
1822 OPC_MXU__POOL17
= 0x28,
1823 /* not assigned 0x29 */
1824 OPC_MXU_S16LDD
= 0x2A,
1825 OPC_MXU_S16STD
= 0x2B,
1826 OPC_MXU_S16LDI
= 0x2C,
1827 OPC_MXU_S16SDI
= 0x2D,
1828 OPC_MXU_S32M2I
= 0x2E,
1829 OPC_MXU_S32I2M
= 0x2F,
1830 OPC_MXU_D32SLL
= 0x30,
1831 OPC_MXU_D32SLR
= 0x31,
1832 OPC_MXU_D32SARL
= 0x32,
1833 OPC_MXU_D32SAR
= 0x33,
1834 OPC_MXU_Q16SLL
= 0x34,
1835 OPC_MXU_Q16SLR
= 0x35,
1836 OPC_MXU__POOL18
= 0x36,
1837 OPC_MXU_Q16SAR
= 0x37,
1838 OPC_MXU__POOL19
= 0x38,
1839 OPC_MXU__POOL20
= 0x39,
1840 OPC_MXU__POOL21
= 0x3A,
1841 OPC_MXU_Q16SCOP
= 0x3B,
1842 OPC_MXU_Q8MADL
= 0x3C,
1843 OPC_MXU_S32SFL
= 0x3D,
1844 OPC_MXU_Q8SAD
= 0x3E,
1845 /* not assigned 0x3F */
1853 OPC_MXU_S32MAX
= 0x00,
1854 OPC_MXU_S32MIN
= 0x01,
1855 OPC_MXU_D16MAX
= 0x02,
1856 OPC_MXU_D16MIN
= 0x03,
1857 OPC_MXU_Q8MAX
= 0x04,
1858 OPC_MXU_Q8MIN
= 0x05,
1859 OPC_MXU_Q8SLT
= 0x06,
1860 OPC_MXU_Q8SLTU
= 0x07,
1867 OPC_MXU_S32SLT
= 0x00,
1868 OPC_MXU_D16SLT
= 0x01,
1869 OPC_MXU_D16AVG
= 0x02,
1870 OPC_MXU_D16AVGR
= 0x03,
1871 OPC_MXU_Q8AVG
= 0x04,
1872 OPC_MXU_Q8AVGR
= 0x05,
1873 OPC_MXU_Q8ADD
= 0x07,
1880 OPC_MXU_S32CPS
= 0x00,
1881 OPC_MXU_D16CPS
= 0x02,
1882 OPC_MXU_Q8ABD
= 0x04,
1883 OPC_MXU_Q16SAT
= 0x06,
1890 OPC_MXU_D16MULF
= 0x00,
1891 OPC_MXU_D16MULE
= 0x01,
1898 OPC_MXU_S32LDD
= 0x00,
1899 OPC_MXU_S32LDDR
= 0x01,
1906 OPC_MXU_S32STD
= 0x00,
1907 OPC_MXU_S32STDR
= 0x01,
1914 OPC_MXU_S32LDDV
= 0x00,
1915 OPC_MXU_S32LDDVR
= 0x01,
1922 OPC_MXU_S32STDV
= 0x00,
1923 OPC_MXU_S32STDVR
= 0x01,
1930 OPC_MXU_S32LDI
= 0x00,
1931 OPC_MXU_S32LDIR
= 0x01,
1938 OPC_MXU_S32SDI
= 0x00,
1939 OPC_MXU_S32SDIR
= 0x01,
1946 OPC_MXU_S32LDIV
= 0x00,
1947 OPC_MXU_S32LDIVR
= 0x01,
1954 OPC_MXU_S32SDIV
= 0x00,
1955 OPC_MXU_S32SDIVR
= 0x01,
1962 OPC_MXU_D32ACC
= 0x00,
1963 OPC_MXU_D32ACCM
= 0x01,
1964 OPC_MXU_D32ASUM
= 0x02,
1971 OPC_MXU_Q16ACC
= 0x00,
1972 OPC_MXU_Q16ACCM
= 0x01,
1973 OPC_MXU_Q16ASUM
= 0x02,
1980 OPC_MXU_Q8ADDE
= 0x00,
1981 OPC_MXU_D8SUM
= 0x01,
1982 OPC_MXU_D8SUMC
= 0x02,
1989 OPC_MXU_S32MUL
= 0x00,
1990 OPC_MXU_S32MULU
= 0x01,
1991 OPC_MXU_S32EXTR
= 0x02,
1992 OPC_MXU_S32EXTRV
= 0x03,
1999 OPC_MXU_D32SARW
= 0x00,
2000 OPC_MXU_S32ALN
= 0x01,
2001 OPC_MXU_S32ALNI
= 0x02,
2002 OPC_MXU_S32LUI
= 0x03,
2003 OPC_MXU_S32NOR
= 0x04,
2004 OPC_MXU_S32AND
= 0x05,
2005 OPC_MXU_S32OR
= 0x06,
2006 OPC_MXU_S32XOR
= 0x07,
2016 OPC_MXU_LXBU
= 0x04,
2017 OPC_MXU_LXHU
= 0x05,
2024 OPC_MXU_D32SLLV
= 0x00,
2025 OPC_MXU_D32SLRV
= 0x01,
2026 OPC_MXU_D32SARV
= 0x03,
2027 OPC_MXU_Q16SLLV
= 0x04,
2028 OPC_MXU_Q16SLRV
= 0x05,
2029 OPC_MXU_Q16SARV
= 0x07,
2036 OPC_MXU_Q8MUL
= 0x00,
2037 OPC_MXU_Q8MULSU
= 0x01,
2044 OPC_MXU_Q8MOVZ
= 0x00,
2045 OPC_MXU_Q8MOVN
= 0x01,
2046 OPC_MXU_D16MOVZ
= 0x02,
2047 OPC_MXU_D16MOVN
= 0x03,
2048 OPC_MXU_S32MOVZ
= 0x04,
2049 OPC_MXU_S32MOVN
= 0x05,
2056 OPC_MXU_Q8MAC
= 0x00,
2057 OPC_MXU_Q8MACSU
= 0x01,
2061 * Overview of the TX79-specific instruction set
2062 * =============================================
2064 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2065 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2066 * instructions and certain multimedia instructions (MMIs). These MMIs
2067 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2068 * or sixteen 8-bit paths.
2072 * The Toshiba TX System RISC TX79 Core Architecture manual,
2073 * https://wiki.qemu.org/File:C790.pdf
2075 * Three-Operand Multiply and Multiply-Add (4 instructions)
2076 * --------------------------------------------------------
2077 * MADD [rd,] rs, rt Multiply/Add
2078 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2079 * MULT [rd,] rs, rt Multiply (3-operand)
2080 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2082 * Multiply Instructions for Pipeline 1 (10 instructions)
2083 * ------------------------------------------------------
2084 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2085 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2086 * DIV1 rs, rt Divide Pipeline 1
2087 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2088 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2089 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2090 * MFHI1 rd Move From HI1 Register
2091 * MFLO1 rd Move From LO1 Register
2092 * MTHI1 rs Move To HI1 Register
2093 * MTLO1 rs Move To LO1 Register
2095 * Arithmetic (19 instructions)
2096 * ----------------------------
2097 * PADDB rd, rs, rt Parallel Add Byte
2098 * PSUBB rd, rs, rt Parallel Subtract Byte
2099 * PADDH rd, rs, rt Parallel Add Halfword
2100 * PSUBH rd, rs, rt Parallel Subtract Halfword
2101 * PADDW rd, rs, rt Parallel Add Word
2102 * PSUBW rd, rs, rt Parallel Subtract Word
2103 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2104 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2105 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2106 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2107 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2108 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2109 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2110 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2111 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2112 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2113 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2114 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2115 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2117 * Min/Max (4 instructions)
2118 * ------------------------
2119 * PMAXH rd, rs, rt Parallel Maximum Halfword
2120 * PMINH rd, rs, rt Parallel Minimum Halfword
2121 * PMAXW rd, rs, rt Parallel Maximum Word
2122 * PMINW rd, rs, rt Parallel Minimum Word
2124 * Absolute (2 instructions)
2125 * -------------------------
2126 * PABSH rd, rt Parallel Absolute Halfword
2127 * PABSW rd, rt Parallel Absolute Word
2129 * Logical (4 instructions)
2130 * ------------------------
2131 * PAND rd, rs, rt Parallel AND
2132 * POR rd, rs, rt Parallel OR
2133 * PXOR rd, rs, rt Parallel XOR
2134 * PNOR rd, rs, rt Parallel NOR
2136 * Shift (9 instructions)
2137 * ----------------------
2138 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2139 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2140 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2141 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2142 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2143 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2144 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2145 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2146 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2148 * Compare (6 instructions)
2149 * ------------------------
2150 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2151 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2152 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2153 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2154 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2155 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2157 * LZC (1 instruction)
2158 * -------------------
2159 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2161 * Quadword Load and Store (2 instructions)
2162 * ----------------------------------------
2163 * LQ rt, offset(base) Load Quadword
2164 * SQ rt, offset(base) Store Quadword
2166 * Multiply and Divide (19 instructions)
2167 * -------------------------------------
2168 * PMULTW rd, rs, rt Parallel Multiply Word
2169 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2170 * PDIVW rs, rt Parallel Divide Word
2171 * PDIVUW rs, rt Parallel Divide Unsigned Word
2172 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2173 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2174 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2175 * PMULTH rd, rs, rt Parallel Multiply Halfword
2176 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2177 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2178 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2179 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2180 * PDIVBW rs, rt Parallel Divide Broadcast Word
2181 * PMFHI rd Parallel Move From HI Register
2182 * PMFLO rd Parallel Move From LO Register
2183 * PMTHI rs Parallel Move To HI Register
2184 * PMTLO rs Parallel Move To LO Register
2185 * PMFHL rd Parallel Move From HI/LO Register
2186 * PMTHL rs Parallel Move To HI/LO Register
2188 * Pack/Extend (11 instructions)
2189 * -----------------------------
2190 * PPAC5 rd, rt Parallel Pack to 5 bits
2191 * PPACB rd, rs, rt Parallel Pack to Byte
2192 * PPACH rd, rs, rt Parallel Pack to Halfword
2193 * PPACW rd, rs, rt Parallel Pack to Word
2194 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2195 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2196 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2197 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2198 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2199 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2200 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2202 * Others (16 instructions)
2203 * ------------------------
2204 * PCPYH rd, rt Parallel Copy Halfword
2205 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2206 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2207 * PREVH rd, rt Parallel Reverse Halfword
2208 * PINTH rd, rs, rt Parallel Interleave Halfword
2209 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2210 * PEXEH rd, rt Parallel Exchange Even Halfword
2211 * PEXCH rd, rt Parallel Exchange Center Halfword
2212 * PEXEW rd, rt Parallel Exchange Even Word
2213 * PEXCW rd, rt Parallel Exchange Center Word
2214 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2215 * MFSA rd Move from Shift Amount Register
2216 * MTSA rs Move to Shift Amount Register
2217 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2218 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2219 * PROT3W rd, rt Parallel Rotate 3 Words
2221 * MMI (MultiMedia Instruction) encodings
2222 * ======================================
2224 * MMI instructions encoding table keys:
2226 * * This code is reserved for future use. An attempt to execute it
2227 * causes a Reserved Instruction exception.
2228 * % This code indicates an instruction class. The instruction word
2229 * must be further decoded by examining additional tables that show
2230 * the values for other instruction fields.
2231 * # This code is reserved for the unsupported instructions DMULT,
2232 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2233 * to execute it causes a Reserved Instruction exception.
2235 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2238 * +--------+----------------------------------------+
2240 * +--------+----------------------------------------+
2242 * opcode bits 28..26
2243 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2244 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2245 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2246 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2247 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2248 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2249 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2250 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2251 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2252 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2253 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2257 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
2258 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
2259 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
2263 * MMI instructions with opcode field = MMI:
2266 * +--------+-------------------------------+--------+
2267 * | MMI | |function|
2268 * +--------+-------------------------------+--------+
2270 * function bits 2..0
2271 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2272 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2273 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2274 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2275 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2276 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2277 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2278 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2279 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2280 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2281 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2284 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2286 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
2287 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
2288 MMI_OPC_PLZCW
= 0x04 | MMI_OPC_CLASS_MMI
,
2289 MMI_OPC_CLASS_MMI0
= 0x08 | MMI_OPC_CLASS_MMI
,
2290 MMI_OPC_CLASS_MMI2
= 0x09 | MMI_OPC_CLASS_MMI
,
2291 MMI_OPC_MFHI1
= 0x10 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFHI */
2292 MMI_OPC_MTHI1
= 0x11 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTHI */
2293 MMI_OPC_MFLO1
= 0x12 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFLO */
2294 MMI_OPC_MTLO1
= 0x13 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTLO */
2295 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
2296 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
2297 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
2298 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
2299 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
2300 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
2301 MMI_OPC_CLASS_MMI1
= 0x28 | MMI_OPC_CLASS_MMI
,
2302 MMI_OPC_CLASS_MMI3
= 0x29 | MMI_OPC_CLASS_MMI
,
2303 MMI_OPC_PMFHL
= 0x30 | MMI_OPC_CLASS_MMI
,
2304 MMI_OPC_PMTHL
= 0x31 | MMI_OPC_CLASS_MMI
,
2305 MMI_OPC_PSLLH
= 0x34 | MMI_OPC_CLASS_MMI
,
2306 MMI_OPC_PSRLH
= 0x36 | MMI_OPC_CLASS_MMI
,
2307 MMI_OPC_PSRAH
= 0x37 | MMI_OPC_CLASS_MMI
,
2308 MMI_OPC_PSLLW
= 0x3C | MMI_OPC_CLASS_MMI
,
2309 MMI_OPC_PSRLW
= 0x3E | MMI_OPC_CLASS_MMI
,
2310 MMI_OPC_PSRAW
= 0x3F | MMI_OPC_CLASS_MMI
,
2314 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2317 * +--------+----------------------+--------+--------+
2318 * | MMI | |function| MMI0 |
2319 * +--------+----------------------+--------+--------+
2321 * function bits 7..6
2322 * bits | 0 | 1 | 2 | 3
2323 * 10..8 | 00 | 01 | 10 | 11
2324 * -------+-------+-------+-------+-------
2325 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2326 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2327 * 2 010 | PADDB | PSUBB | PCGTB | *
2328 * 3 011 | * | * | * | *
2329 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2330 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2331 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2332 * 7 111 | * | * | PEXT5 | PPAC5
2335 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2337 MMI_OPC_0_PADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI0
,
2338 MMI_OPC_0_PSUBW
= (0x01 << 6) | MMI_OPC_CLASS_MMI0
,
2339 MMI_OPC_0_PCGTW
= (0x02 << 6) | MMI_OPC_CLASS_MMI0
,
2340 MMI_OPC_0_PMAXW
= (0x03 << 6) | MMI_OPC_CLASS_MMI0
,
2341 MMI_OPC_0_PADDH
= (0x04 << 6) | MMI_OPC_CLASS_MMI0
,
2342 MMI_OPC_0_PSUBH
= (0x05 << 6) | MMI_OPC_CLASS_MMI0
,
2343 MMI_OPC_0_PCGTH
= (0x06 << 6) | MMI_OPC_CLASS_MMI0
,
2344 MMI_OPC_0_PMAXH
= (0x07 << 6) | MMI_OPC_CLASS_MMI0
,
2345 MMI_OPC_0_PADDB
= (0x08 << 6) | MMI_OPC_CLASS_MMI0
,
2346 MMI_OPC_0_PSUBB
= (0x09 << 6) | MMI_OPC_CLASS_MMI0
,
2347 MMI_OPC_0_PCGTB
= (0x0A << 6) | MMI_OPC_CLASS_MMI0
,
2348 MMI_OPC_0_PADDSW
= (0x10 << 6) | MMI_OPC_CLASS_MMI0
,
2349 MMI_OPC_0_PSUBSW
= (0x11 << 6) | MMI_OPC_CLASS_MMI0
,
2350 MMI_OPC_0_PEXTLW
= (0x12 << 6) | MMI_OPC_CLASS_MMI0
,
2351 MMI_OPC_0_PPACW
= (0x13 << 6) | MMI_OPC_CLASS_MMI0
,
2352 MMI_OPC_0_PADDSH
= (0x14 << 6) | MMI_OPC_CLASS_MMI0
,
2353 MMI_OPC_0_PSUBSH
= (0x15 << 6) | MMI_OPC_CLASS_MMI0
,
2354 MMI_OPC_0_PEXTLH
= (0x16 << 6) | MMI_OPC_CLASS_MMI0
,
2355 MMI_OPC_0_PPACH
= (0x17 << 6) | MMI_OPC_CLASS_MMI0
,
2356 MMI_OPC_0_PADDSB
= (0x18 << 6) | MMI_OPC_CLASS_MMI0
,
2357 MMI_OPC_0_PSUBSB
= (0x19 << 6) | MMI_OPC_CLASS_MMI0
,
2358 MMI_OPC_0_PEXTLB
= (0x1A << 6) | MMI_OPC_CLASS_MMI0
,
2359 MMI_OPC_0_PPACB
= (0x1B << 6) | MMI_OPC_CLASS_MMI0
,
2360 MMI_OPC_0_PEXT5
= (0x1E << 6) | MMI_OPC_CLASS_MMI0
,
2361 MMI_OPC_0_PPAC5
= (0x1F << 6) | MMI_OPC_CLASS_MMI0
,
2365 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2368 * +--------+----------------------+--------+--------+
2369 * | MMI | |function| MMI1 |
2370 * +--------+----------------------+--------+--------+
2372 * function bits 7..6
2373 * bits | 0 | 1 | 2 | 3
2374 * 10..8 | 00 | 01 | 10 | 11
2375 * -------+-------+-------+-------+-------
2376 * 0 000 | * | PABSW | PCEQW | PMINW
2377 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2378 * 2 010 | * | * | PCEQB | *
2379 * 3 011 | * | * | * | *
2380 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2381 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2382 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2383 * 7 111 | * | * | * | *
2386 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2388 MMI_OPC_1_PABSW
= (0x01 << 6) | MMI_OPC_CLASS_MMI1
,
2389 MMI_OPC_1_PCEQW
= (0x02 << 6) | MMI_OPC_CLASS_MMI1
,
2390 MMI_OPC_1_PMINW
= (0x03 << 6) | MMI_OPC_CLASS_MMI1
,
2391 MMI_OPC_1_PADSBH
= (0x04 << 6) | MMI_OPC_CLASS_MMI1
,
2392 MMI_OPC_1_PABSH
= (0x05 << 6) | MMI_OPC_CLASS_MMI1
,
2393 MMI_OPC_1_PCEQH
= (0x06 << 6) | MMI_OPC_CLASS_MMI1
,
2394 MMI_OPC_1_PMINH
= (0x07 << 6) | MMI_OPC_CLASS_MMI1
,
2395 MMI_OPC_1_PCEQB
= (0x0A << 6) | MMI_OPC_CLASS_MMI1
,
2396 MMI_OPC_1_PADDUW
= (0x10 << 6) | MMI_OPC_CLASS_MMI1
,
2397 MMI_OPC_1_PSUBUW
= (0x11 << 6) | MMI_OPC_CLASS_MMI1
,
2398 MMI_OPC_1_PEXTUW
= (0x12 << 6) | MMI_OPC_CLASS_MMI1
,
2399 MMI_OPC_1_PADDUH
= (0x14 << 6) | MMI_OPC_CLASS_MMI1
,
2400 MMI_OPC_1_PSUBUH
= (0x15 << 6) | MMI_OPC_CLASS_MMI1
,
2401 MMI_OPC_1_PEXTUH
= (0x16 << 6) | MMI_OPC_CLASS_MMI1
,
2402 MMI_OPC_1_PADDUB
= (0x18 << 6) | MMI_OPC_CLASS_MMI1
,
2403 MMI_OPC_1_PSUBUB
= (0x19 << 6) | MMI_OPC_CLASS_MMI1
,
2404 MMI_OPC_1_PEXTUB
= (0x1A << 6) | MMI_OPC_CLASS_MMI1
,
2405 MMI_OPC_1_QFSRV
= (0x1B << 6) | MMI_OPC_CLASS_MMI1
,
2409 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2412 * +--------+----------------------+--------+--------+
2413 * | MMI | |function| MMI2 |
2414 * +--------+----------------------+--------+--------+
2416 * function bits 7..6
2417 * bits | 0 | 1 | 2 | 3
2418 * 10..8 | 00 | 01 | 10 | 11
2419 * -------+-------+-------+-------+-------
2420 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2421 * 1 001 | PMSUBW| * | * | *
2422 * 2 010 | PMFHI | PMFLO | PINTH | *
2423 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2424 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2425 * 5 101 | PMSUBH| PHMSBH| * | *
2426 * 6 110 | * | * | PEXEH | PREVH
2427 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2430 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2432 MMI_OPC_2_PMADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI2
,
2433 MMI_OPC_2_PSLLVW
= (0x02 << 6) | MMI_OPC_CLASS_MMI2
,
2434 MMI_OPC_2_PSRLVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI2
,
2435 MMI_OPC_2_PMSUBW
= (0x04 << 6) | MMI_OPC_CLASS_MMI2
,
2436 MMI_OPC_2_PMFHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI2
,
2437 MMI_OPC_2_PMFLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI2
,
2438 MMI_OPC_2_PINTH
= (0x0A << 6) | MMI_OPC_CLASS_MMI2
,
2439 MMI_OPC_2_PMULTW
= (0x0C << 6) | MMI_OPC_CLASS_MMI2
,
2440 MMI_OPC_2_PDIVW
= (0x0D << 6) | MMI_OPC_CLASS_MMI2
,
2441 MMI_OPC_2_PCPYLD
= (0x0E << 6) | MMI_OPC_CLASS_MMI2
,
2442 MMI_OPC_2_PMADDH
= (0x10 << 6) | MMI_OPC_CLASS_MMI2
,
2443 MMI_OPC_2_PHMADH
= (0x11 << 6) | MMI_OPC_CLASS_MMI2
,
2444 MMI_OPC_2_PAND
= (0x12 << 6) | MMI_OPC_CLASS_MMI2
,
2445 MMI_OPC_2_PXOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI2
,
2446 MMI_OPC_2_PMSUBH
= (0x14 << 6) | MMI_OPC_CLASS_MMI2
,
2447 MMI_OPC_2_PHMSBH
= (0x15 << 6) | MMI_OPC_CLASS_MMI2
,
2448 MMI_OPC_2_PEXEH
= (0x1A << 6) | MMI_OPC_CLASS_MMI2
,
2449 MMI_OPC_2_PREVH
= (0x1B << 6) | MMI_OPC_CLASS_MMI2
,
2450 MMI_OPC_2_PMULTH
= (0x1C << 6) | MMI_OPC_CLASS_MMI2
,
2451 MMI_OPC_2_PDIVBW
= (0x1D << 6) | MMI_OPC_CLASS_MMI2
,
2452 MMI_OPC_2_PEXEW
= (0x1E << 6) | MMI_OPC_CLASS_MMI2
,
2453 MMI_OPC_2_PROT3W
= (0x1F << 6) | MMI_OPC_CLASS_MMI2
,
2457 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2460 * +--------+----------------------+--------+--------+
2461 * | MMI | |function| MMI3 |
2462 * +--------+----------------------+--------+--------+
2464 * function bits 7..6
2465 * bits | 0 | 1 | 2 | 3
2466 * 10..8 | 00 | 01 | 10 | 11
2467 * -------+-------+-------+-------+-------
2468 * 0 000 |PMADDUW| * | * | PSRAVW
2469 * 1 001 | * | * | * | *
2470 * 2 010 | PMTHI | PMTLO | PINTEH| *
2471 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2472 * 4 100 | * | * | POR | PNOR
2473 * 5 101 | * | * | * | *
2474 * 6 110 | * | * | PEXCH | PCPYH
2475 * 7 111 | * | * | PEXCW | *
2478 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2480 MMI_OPC_3_PMADDUW
= (0x00 << 6) | MMI_OPC_CLASS_MMI3
,
2481 MMI_OPC_3_PSRAVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI3
,
2482 MMI_OPC_3_PMTHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI3
,
2483 MMI_OPC_3_PMTLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI3
,
2484 MMI_OPC_3_PINTEH
= (0x0A << 6) | MMI_OPC_CLASS_MMI3
,
2485 MMI_OPC_3_PMULTUW
= (0x0C << 6) | MMI_OPC_CLASS_MMI3
,
2486 MMI_OPC_3_PDIVUW
= (0x0D << 6) | MMI_OPC_CLASS_MMI3
,
2487 MMI_OPC_3_PCPYUD
= (0x0E << 6) | MMI_OPC_CLASS_MMI3
,
2488 MMI_OPC_3_POR
= (0x12 << 6) | MMI_OPC_CLASS_MMI3
,
2489 MMI_OPC_3_PNOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI3
,
2490 MMI_OPC_3_PEXCH
= (0x1A << 6) | MMI_OPC_CLASS_MMI3
,
2491 MMI_OPC_3_PCPYH
= (0x1B << 6) | MMI_OPC_CLASS_MMI3
,
2492 MMI_OPC_3_PEXCW
= (0x1E << 6) | MMI_OPC_CLASS_MMI3
,
2495 /* global register indices */
2496 static TCGv cpu_gpr
[32], cpu_PC
;
2497 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
2498 static TCGv cpu_dspctrl
, btarget
, bcond
;
2499 static TCGv cpu_lladdr
, cpu_llval
;
2500 static TCGv_i32 hflags
;
2501 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
2502 static TCGv_i64 fpu_f64
[32];
2503 static TCGv_i64 msa_wr_d
[64];
2505 #if defined(TARGET_MIPS64)
2506 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2507 static TCGv_i64 cpu_mmr
[32];
2510 #if !defined(TARGET_MIPS64)
2512 static TCGv mxu_gpr
[NUMBER_OF_MXU_REGISTERS
- 1];
2516 #include "exec/gen-icount.h"
2518 #define gen_helper_0e0i(name, arg) do { \
2519 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2520 gen_helper_##name(cpu_env, helper_tmp); \
2521 tcg_temp_free_i32(helper_tmp); \
2524 #define gen_helper_0e1i(name, arg1, arg2) do { \
2525 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2526 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2527 tcg_temp_free_i32(helper_tmp); \
2530 #define gen_helper_1e0i(name, ret, arg1) do { \
2531 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2532 gen_helper_##name(ret, cpu_env, helper_tmp); \
2533 tcg_temp_free_i32(helper_tmp); \
2536 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2537 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2538 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2539 tcg_temp_free_i32(helper_tmp); \
2542 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2543 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2544 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2545 tcg_temp_free_i32(helper_tmp); \
2548 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2549 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2550 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2551 tcg_temp_free_i32(helper_tmp); \
2554 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2555 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2556 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2557 tcg_temp_free_i32(helper_tmp); \
2560 typedef struct DisasContext
{
2561 DisasContextBase base
;
2562 target_ulong saved_pc
;
2563 target_ulong page_start
;
2565 uint64_t insn_flags
;
2566 int32_t CP0_Config1
;
2567 int32_t CP0_Config2
;
2568 int32_t CP0_Config3
;
2569 int32_t CP0_Config5
;
2570 /* Routine used to access memory */
2572 MemOp default_tcg_memop_mask
;
2573 uint32_t hflags
, saved_hflags
;
2574 target_ulong btarget
;
2585 int CP0_LLAddr_shift
;
2597 #define DISAS_STOP DISAS_TARGET_0
2598 #define DISAS_EXIT DISAS_TARGET_1
2600 static const char * const regnames
[] = {
2601 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2602 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2603 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2604 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2607 static const char * const regnames_HI
[] = {
2608 "HI0", "HI1", "HI2", "HI3",
2611 static const char * const regnames_LO
[] = {
2612 "LO0", "LO1", "LO2", "LO3",
2615 static const char * const fregnames
[] = {
2616 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2617 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2618 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2619 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2622 static const char * const msaregnames
[] = {
2623 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2624 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2625 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2626 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2627 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2628 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2629 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2630 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2631 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2632 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2633 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2634 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2635 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2636 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2637 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2638 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2641 #if !defined(TARGET_MIPS64)
2642 static const char * const mxuregnames
[] = {
2643 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2644 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2648 #define LOG_DISAS(...) \
2650 if (MIPS_DEBUG_DISAS) { \
2651 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2655 #define MIPS_INVAL(op) \
2657 if (MIPS_DEBUG_DISAS) { \
2658 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2659 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2660 ctx->base.pc_next, ctx->opcode, op, \
2661 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2662 ((ctx->opcode >> 16) & 0x1F)); \
2666 /* General purpose registers moves. */
2667 static inline void gen_load_gpr(TCGv t
, int reg
)
2670 tcg_gen_movi_tl(t
, 0);
2672 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
2676 static inline void gen_store_gpr(TCGv t
, int reg
)
2679 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
2683 /* Moves to/from shadow registers. */
2684 static inline void gen_load_srsgpr(int from
, int to
)
2686 TCGv t0
= tcg_temp_new();
2689 tcg_gen_movi_tl(t0
, 0);
2691 TCGv_i32 t2
= tcg_temp_new_i32();
2692 TCGv_ptr addr
= tcg_temp_new_ptr();
2694 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2695 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2696 tcg_gen_andi_i32(t2
, t2
, 0xf);
2697 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2698 tcg_gen_ext_i32_ptr(addr
, t2
);
2699 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2701 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
2702 tcg_temp_free_ptr(addr
);
2703 tcg_temp_free_i32(t2
);
2705 gen_store_gpr(t0
, to
);
2709 static inline void gen_store_srsgpr(int from
, int to
)
2712 TCGv t0
= tcg_temp_new();
2713 TCGv_i32 t2
= tcg_temp_new_i32();
2714 TCGv_ptr addr
= tcg_temp_new_ptr();
2716 gen_load_gpr(t0
, from
);
2717 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2718 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2719 tcg_gen_andi_i32(t2
, t2
, 0xf);
2720 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2721 tcg_gen_ext_i32_ptr(addr
, t2
);
2722 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2724 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
2725 tcg_temp_free_ptr(addr
);
2726 tcg_temp_free_i32(t2
);
2731 #if !defined(TARGET_MIPS64)
2732 /* MXU General purpose registers moves. */
2733 static inline void gen_load_mxu_gpr(TCGv t
, unsigned int reg
)
2736 tcg_gen_movi_tl(t
, 0);
2737 } else if (reg
<= 15) {
2738 tcg_gen_mov_tl(t
, mxu_gpr
[reg
- 1]);
2742 static inline void gen_store_mxu_gpr(TCGv t
, unsigned int reg
)
2744 if (reg
> 0 && reg
<= 15) {
2745 tcg_gen_mov_tl(mxu_gpr
[reg
- 1], t
);
2749 /* MXU control register moves. */
2750 static inline void gen_load_mxu_cr(TCGv t
)
2752 tcg_gen_mov_tl(t
, mxu_CR
);
2755 static inline void gen_store_mxu_cr(TCGv t
)
2757 /* TODO: Add handling of RW rules for MXU_CR. */
2758 tcg_gen_mov_tl(mxu_CR
, t
);
2764 static inline void gen_save_pc(target_ulong pc
)
2766 tcg_gen_movi_tl(cpu_PC
, pc
);
2769 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
2771 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
2772 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
2773 gen_save_pc(ctx
->base
.pc_next
);
2774 ctx
->saved_pc
= ctx
->base
.pc_next
;
2776 if (ctx
->hflags
!= ctx
->saved_hflags
) {
2777 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
2778 ctx
->saved_hflags
= ctx
->hflags
;
2779 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2785 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
2791 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
2793 ctx
->saved_hflags
= ctx
->hflags
;
2794 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2800 ctx
->btarget
= env
->btarget
;
2805 static inline void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
2807 TCGv_i32 texcp
= tcg_const_i32(excp
);
2808 TCGv_i32 terr
= tcg_const_i32(err
);
2809 save_cpu_state(ctx
, 1);
2810 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
2811 tcg_temp_free_i32(terr
);
2812 tcg_temp_free_i32(texcp
);
2813 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2816 static inline void generate_exception(DisasContext
*ctx
, int excp
)
2818 gen_helper_0e0i(raise_exception
, excp
);
2821 static inline void generate_exception_end(DisasContext
*ctx
, int excp
)
2823 generate_exception_err(ctx
, excp
, 0);
2826 /* Floating point register moves. */
2827 static void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2829 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2830 generate_exception(ctx
, EXCP_RI
);
2832 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
2835 static void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2838 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2839 generate_exception(ctx
, EXCP_RI
);
2841 t64
= tcg_temp_new_i64();
2842 tcg_gen_extu_i32_i64(t64
, t
);
2843 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
2844 tcg_temp_free_i64(t64
);
2847 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2849 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2850 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
2852 gen_load_fpr32(ctx
, t
, reg
| 1);
2856 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2858 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2859 TCGv_i64 t64
= tcg_temp_new_i64();
2860 tcg_gen_extu_i32_i64(t64
, t
);
2861 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
2862 tcg_temp_free_i64(t64
);
2864 gen_store_fpr32(ctx
, t
, reg
| 1);
2868 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2870 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2871 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
2873 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
2877 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2879 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2880 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
2883 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
2884 t0
= tcg_temp_new_i64();
2885 tcg_gen_shri_i64(t0
, t
, 32);
2886 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
2887 tcg_temp_free_i64(t0
);
2891 static inline int get_fp_bit(int cc
)
2900 /* Addresses computation */
2901 static inline void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
,
2904 tcg_gen_add_tl(ret
, arg0
, arg1
);
2906 #if defined(TARGET_MIPS64)
2907 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2908 tcg_gen_ext32s_i64(ret
, ret
);
2913 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
2916 tcg_gen_addi_tl(ret
, base
, ofs
);
2918 #if defined(TARGET_MIPS64)
2919 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2920 tcg_gen_ext32s_i64(ret
, ret
);
2925 /* Addresses computation (translation time) */
2926 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
2929 target_long sum
= base
+ offset
;
2931 #if defined(TARGET_MIPS64)
2932 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2939 /* Sign-extract the low 32-bits to a target_long. */
2940 static inline void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
2942 #if defined(TARGET_MIPS64)
2943 tcg_gen_ext32s_i64(ret
, arg
);
2945 tcg_gen_extrl_i64_i32(ret
, arg
);
2949 /* Sign-extract the high 32-bits to a target_long. */
2950 static inline void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
2952 #if defined(TARGET_MIPS64)
2953 tcg_gen_sari_i64(ret
, arg
, 32);
2955 tcg_gen_extrh_i64_i32(ret
, arg
);
2959 static inline void check_cp0_enabled(DisasContext
*ctx
)
2961 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2962 generate_exception_err(ctx
, EXCP_CpU
, 0);
2966 static inline void check_cp1_enabled(DisasContext
*ctx
)
2968 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
2969 generate_exception_err(ctx
, EXCP_CpU
, 1);
2974 * Verify that the processor is running with COP1X instructions enabled.
2975 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2978 static inline void check_cop1x(DisasContext
*ctx
)
2980 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
2981 generate_exception_end(ctx
, EXCP_RI
);
2986 * Verify that the processor is running with 64-bit floating-point
2987 * operations enabled.
2989 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
2991 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
2992 generate_exception_end(ctx
, EXCP_RI
);
2997 * Verify if floating point register is valid; an operation is not defined
2998 * if bit 0 of any register specification is set and the FR bit in the
2999 * Status register equals zero, since the register numbers specify an
3000 * even-odd pair of adjacent coprocessor general registers. When the FR bit
3001 * in the Status register equals one, both even and odd register numbers
3002 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
3004 * Multiple 64 bit wide registers can be checked by calling
3005 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
3007 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
3009 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
3010 generate_exception_end(ctx
, EXCP_RI
);
3015 * Verify that the processor is running with DSP instructions enabled.
3016 * This is enabled by CP0 Status register MX(24) bit.
3018 static inline void check_dsp(DisasContext
*ctx
)
3020 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
3021 if (ctx
->insn_flags
& ASE_DSP
) {
3022 generate_exception_end(ctx
, EXCP_DSPDIS
);
3024 generate_exception_end(ctx
, EXCP_RI
);
3029 static inline void check_dsp_r2(DisasContext
*ctx
)
3031 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
3032 if (ctx
->insn_flags
& ASE_DSP
) {
3033 generate_exception_end(ctx
, EXCP_DSPDIS
);
3035 generate_exception_end(ctx
, EXCP_RI
);
3040 static inline void check_dsp_r3(DisasContext
*ctx
)
3042 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
3043 if (ctx
->insn_flags
& ASE_DSP
) {
3044 generate_exception_end(ctx
, EXCP_DSPDIS
);
3046 generate_exception_end(ctx
, EXCP_RI
);
3052 * This code generates a "reserved instruction" exception if the
3053 * CPU does not support the instruction set corresponding to flags.
3055 static inline void check_insn(DisasContext
*ctx
, uint64_t flags
)
3057 if (unlikely(!(ctx
->insn_flags
& flags
))) {
3058 generate_exception_end(ctx
, EXCP_RI
);
3063 * This code generates a "reserved instruction" exception if the
3064 * CPU has corresponding flag set which indicates that the instruction
3067 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
3069 if (unlikely(ctx
->insn_flags
& flags
)) {
3070 generate_exception_end(ctx
, EXCP_RI
);
3075 * The Linux kernel traps certain reserved instruction exceptions to
3076 * emulate the corresponding instructions. QEMU is the kernel in user
3077 * mode, so those traps are emulated by accepting the instructions.
3079 * A reserved instruction exception is generated for flagged CPUs if
3080 * QEMU runs in system mode.
3082 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
3084 #ifndef CONFIG_USER_ONLY
3085 check_insn_opc_removed(ctx
, flags
);
3090 * This code generates a "reserved instruction" exception if the
3091 * CPU does not support 64-bit paired-single (PS) floating point data type.
3093 static inline void check_ps(DisasContext
*ctx
)
3095 if (unlikely(!ctx
->ps
)) {
3096 generate_exception(ctx
, EXCP_RI
);
3098 check_cp1_64bitmode(ctx
);
3101 #ifdef TARGET_MIPS64
3103 * This code generates a "reserved instruction" exception if 64-bit
3104 * instructions are not enabled.
3106 static inline void check_mips_64(DisasContext
*ctx
)
3108 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
))) {
3109 generate_exception_end(ctx
, EXCP_RI
);
3114 #ifndef CONFIG_USER_ONLY
3115 static inline void check_mvh(DisasContext
*ctx
)
3117 if (unlikely(!ctx
->mvh
)) {
3118 generate_exception(ctx
, EXCP_RI
);
3124 * This code generates a "reserved instruction" exception if the
3125 * Config5 XNP bit is set.
3127 static inline void check_xnp(DisasContext
*ctx
)
3129 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
3130 generate_exception_end(ctx
, EXCP_RI
);
3134 #ifndef CONFIG_USER_ONLY
3136 * This code generates a "reserved instruction" exception if the
3137 * Config3 PW bit is NOT set.
3139 static inline void check_pw(DisasContext
*ctx
)
3141 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
3142 generate_exception_end(ctx
, EXCP_RI
);
3148 * This code generates a "reserved instruction" exception if the
3149 * Config3 MT bit is NOT set.
3151 static inline void check_mt(DisasContext
*ctx
)
3153 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3154 generate_exception_end(ctx
, EXCP_RI
);
3158 #ifndef CONFIG_USER_ONLY
3160 * This code generates a "coprocessor unusable" exception if CP0 is not
3161 * available, and, if that is not the case, generates a "reserved instruction"
3162 * exception if the Config5 MT bit is NOT set. This is needed for availability
3163 * control of some of MT ASE instructions.
3165 static inline void check_cp0_mt(DisasContext
*ctx
)
3167 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
3168 generate_exception_err(ctx
, EXCP_CpU
, 0);
3170 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3171 generate_exception_err(ctx
, EXCP_RI
, 0);
3178 * This code generates a "reserved instruction" exception if the
3179 * Config5 NMS bit is set.
3181 static inline void check_nms(DisasContext
*ctx
)
3183 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
3184 generate_exception_end(ctx
, EXCP_RI
);
3189 * This code generates a "reserved instruction" exception if the
3190 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3191 * Config2 TL, and Config5 L2C are unset.
3193 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
3195 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
3196 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
3197 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
3198 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
3199 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
3200 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
3201 generate_exception_end(ctx
, EXCP_RI
);
3206 * This code generates a "reserved instruction" exception if the
3207 * Config5 EVA bit is NOT set.
3209 static inline void check_eva(DisasContext
*ctx
)
3211 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
3212 generate_exception_end(ctx
, EXCP_RI
);
3218 * Define small wrappers for gen_load_fpr* so that we have a uniform
3219 * calling interface for 32 and 64-bit FPRs. No sense in changing
3220 * all callers for gen_load_fpr32 when we need the CTX parameter for
3223 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3224 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3225 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3226 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3227 int ft, int fs, int cc) \
3229 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
3230 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
3239 check_cp1_registers(ctx, fs | ft); \
3247 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
3248 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
3251 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
3254 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
3257 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
3260 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
3263 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
3266 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
3269 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
3272 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
3275 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
3278 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
3281 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
3284 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
3287 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
3290 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
3293 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
3296 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
3301 tcg_temp_free_i##bits(fp0); \
3302 tcg_temp_free_i##bits(fp1); \
3305 FOP_CONDS(, 0, d
, FMT_D
, 64)
3306 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
3307 FOP_CONDS(, 0, s
, FMT_S
, 32)
3308 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
3309 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
3310 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
3313 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3314 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
3315 int ft, int fs, int fd) \
3317 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3318 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3319 if (ifmt == FMT_D) { \
3320 check_cp1_registers(ctx, fs | ft | fd); \
3322 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3323 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3326 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3329 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3332 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3335 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3338 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3341 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3344 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3347 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3350 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3353 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3356 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3359 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3362 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3365 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3368 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3371 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3374 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3377 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3380 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3383 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3386 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3389 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3395 tcg_temp_free_i ## bits(fp0); \
3396 tcg_temp_free_i ## bits(fp1); \
3399 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
3400 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
3402 #undef gen_ldcmp_fpr32
3403 #undef gen_ldcmp_fpr64
3405 /* load/store instructions. */
3406 #ifdef CONFIG_USER_ONLY
3407 #define OP_LD_ATOMIC(insn, fname) \
3408 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3409 DisasContext *ctx) \
3411 TCGv t0 = tcg_temp_new(); \
3412 tcg_gen_mov_tl(t0, arg1); \
3413 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3414 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3415 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3416 tcg_temp_free(t0); \
3419 #define OP_LD_ATOMIC(insn, fname) \
3420 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3421 DisasContext *ctx) \
3423 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3426 OP_LD_ATOMIC(ll
, ld32s
);
3427 #if defined(TARGET_MIPS64)
3428 OP_LD_ATOMIC(lld
, ld64
);
3432 static void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
,
3433 int base
, int offset
)
3436 tcg_gen_movi_tl(addr
, offset
);
3437 } else if (offset
== 0) {
3438 gen_load_gpr(addr
, base
);
3440 tcg_gen_movi_tl(addr
, offset
);
3441 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
3445 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
3447 target_ulong pc
= ctx
->base
.pc_next
;
3449 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3450 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
3455 pc
&= ~(target_ulong
)3;
3460 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
3461 int rt
, int base
, int offset
)
3464 int mem_idx
= ctx
->mem_idx
;
3466 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
3469 * Loongson CPU uses a load to zero register for prefetch.
3470 * We emulate it as a NOP. On other CPU we must perform the
3471 * actual memory access.
3476 t0
= tcg_temp_new();
3477 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3480 #if defined(TARGET_MIPS64)
3482 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
3483 ctx
->default_tcg_memop_mask
);
3484 gen_store_gpr(t0
, rt
);
3487 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
3488 ctx
->default_tcg_memop_mask
);
3489 gen_store_gpr(t0
, rt
);
3493 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
3494 gen_store_gpr(t0
, rt
);
3497 t1
= tcg_temp_new();
3499 * Do a byte access to possibly trigger a page
3500 * fault with the unaligned address.
3502 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3503 tcg_gen_andi_tl(t1
, t0
, 7);
3504 #ifndef TARGET_WORDS_BIGENDIAN
3505 tcg_gen_xori_tl(t1
, t1
, 7);
3507 tcg_gen_shli_tl(t1
, t1
, 3);
3508 tcg_gen_andi_tl(t0
, t0
, ~7);
3509 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3510 tcg_gen_shl_tl(t0
, t0
, t1
);
3511 t2
= tcg_const_tl(-1);
3512 tcg_gen_shl_tl(t2
, t2
, t1
);
3513 gen_load_gpr(t1
, rt
);
3514 tcg_gen_andc_tl(t1
, t1
, t2
);
3516 tcg_gen_or_tl(t0
, t0
, t1
);
3518 gen_store_gpr(t0
, rt
);
3521 t1
= tcg_temp_new();
3523 * Do a byte access to possibly trigger a page
3524 * fault with the unaligned address.
3526 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3527 tcg_gen_andi_tl(t1
, t0
, 7);
3528 #ifdef TARGET_WORDS_BIGENDIAN
3529 tcg_gen_xori_tl(t1
, t1
, 7);
3531 tcg_gen_shli_tl(t1
, t1
, 3);
3532 tcg_gen_andi_tl(t0
, t0
, ~7);
3533 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3534 tcg_gen_shr_tl(t0
, t0
, t1
);
3535 tcg_gen_xori_tl(t1
, t1
, 63);
3536 t2
= tcg_const_tl(0xfffffffffffffffeull
);
3537 tcg_gen_shl_tl(t2
, t2
, t1
);
3538 gen_load_gpr(t1
, rt
);
3539 tcg_gen_and_tl(t1
, t1
, t2
);
3541 tcg_gen_or_tl(t0
, t0
, t1
);
3543 gen_store_gpr(t0
, rt
);
3546 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3547 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3549 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3550 gen_store_gpr(t0
, rt
);
3554 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3555 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3557 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
3558 gen_store_gpr(t0
, rt
);
3561 mem_idx
= MIPS_HFLAG_UM
;
3564 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
3565 ctx
->default_tcg_memop_mask
);
3566 gen_store_gpr(t0
, rt
);
3569 mem_idx
= MIPS_HFLAG_UM
;
3572 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
3573 ctx
->default_tcg_memop_mask
);
3574 gen_store_gpr(t0
, rt
);
3577 mem_idx
= MIPS_HFLAG_UM
;
3580 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
3581 ctx
->default_tcg_memop_mask
);
3582 gen_store_gpr(t0
, rt
);
3585 mem_idx
= MIPS_HFLAG_UM
;
3588 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3589 gen_store_gpr(t0
, rt
);
3592 mem_idx
= MIPS_HFLAG_UM
;
3595 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3596 gen_store_gpr(t0
, rt
);
3599 mem_idx
= MIPS_HFLAG_UM
;
3602 t1
= tcg_temp_new();
3604 * Do a byte access to possibly trigger a page
3605 * fault with the unaligned address.
3607 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3608 tcg_gen_andi_tl(t1
, t0
, 3);
3609 #ifndef TARGET_WORDS_BIGENDIAN
3610 tcg_gen_xori_tl(t1
, t1
, 3);
3612 tcg_gen_shli_tl(t1
, t1
, 3);
3613 tcg_gen_andi_tl(t0
, t0
, ~3);
3614 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3615 tcg_gen_shl_tl(t0
, t0
, t1
);
3616 t2
= tcg_const_tl(-1);
3617 tcg_gen_shl_tl(t2
, t2
, t1
);
3618 gen_load_gpr(t1
, rt
);
3619 tcg_gen_andc_tl(t1
, t1
, t2
);
3621 tcg_gen_or_tl(t0
, t0
, t1
);
3623 tcg_gen_ext32s_tl(t0
, t0
);
3624 gen_store_gpr(t0
, rt
);
3627 mem_idx
= MIPS_HFLAG_UM
;
3630 t1
= tcg_temp_new();
3632 * Do a byte access to possibly trigger a page
3633 * fault with the unaligned address.
3635 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3636 tcg_gen_andi_tl(t1
, t0
, 3);
3637 #ifdef TARGET_WORDS_BIGENDIAN
3638 tcg_gen_xori_tl(t1
, t1
, 3);
3640 tcg_gen_shli_tl(t1
, t1
, 3);
3641 tcg_gen_andi_tl(t0
, t0
, ~3);
3642 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3643 tcg_gen_shr_tl(t0
, t0
, t1
);
3644 tcg_gen_xori_tl(t1
, t1
, 31);
3645 t2
= tcg_const_tl(0xfffffffeull
);
3646 tcg_gen_shl_tl(t2
, t2
, t1
);
3647 gen_load_gpr(t1
, rt
);
3648 tcg_gen_and_tl(t1
, t1
, t2
);
3650 tcg_gen_or_tl(t0
, t0
, t1
);
3652 tcg_gen_ext32s_tl(t0
, t0
);
3653 gen_store_gpr(t0
, rt
);
3656 mem_idx
= MIPS_HFLAG_UM
;
3660 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3661 gen_store_gpr(t0
, rt
);
3667 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3668 uint32_t reg1
, uint32_t reg2
)
3670 TCGv taddr
= tcg_temp_new();
3671 TCGv_i64 tval
= tcg_temp_new_i64();
3672 TCGv tmp1
= tcg_temp_new();
3673 TCGv tmp2
= tcg_temp_new();
3675 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3676 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3677 #ifdef TARGET_WORDS_BIGENDIAN
3678 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3680 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3682 gen_store_gpr(tmp1
, reg1
);
3683 tcg_temp_free(tmp1
);
3684 gen_store_gpr(tmp2
, reg2
);
3685 tcg_temp_free(tmp2
);
3686 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3687 tcg_temp_free_i64(tval
);
3688 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3689 tcg_temp_free(taddr
);
3693 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3694 int base
, int offset
)
3696 TCGv t0
= tcg_temp_new();
3697 TCGv t1
= tcg_temp_new();
3698 int mem_idx
= ctx
->mem_idx
;
3700 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3701 gen_load_gpr(t1
, rt
);
3703 #if defined(TARGET_MIPS64)
3705 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3706 ctx
->default_tcg_memop_mask
);
3709 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3712 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3716 mem_idx
= MIPS_HFLAG_UM
;
3719 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3720 ctx
->default_tcg_memop_mask
);
3723 mem_idx
= MIPS_HFLAG_UM
;
3726 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3727 ctx
->default_tcg_memop_mask
);
3730 mem_idx
= MIPS_HFLAG_UM
;
3733 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3736 mem_idx
= MIPS_HFLAG_UM
;
3739 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3742 mem_idx
= MIPS_HFLAG_UM
;
3745 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3753 /* Store conditional */
3754 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3755 MemOp tcg_mo
, bool eva
)
3758 TCGLabel
*l1
= gen_new_label();
3759 TCGLabel
*done
= gen_new_label();
3761 t0
= tcg_temp_new();
3762 addr
= tcg_temp_new();
3763 /* compare the address against that of the preceding LL */
3764 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3765 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3766 tcg_temp_free(addr
);
3767 tcg_gen_movi_tl(t0
, 0);
3768 gen_store_gpr(t0
, rt
);
3772 /* generate cmpxchg */
3773 val
= tcg_temp_new();
3774 gen_load_gpr(val
, rt
);
3775 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3776 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3777 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3778 gen_store_gpr(t0
, rt
);
3781 gen_set_label(done
);
3786 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3787 uint32_t reg1
, uint32_t reg2
, bool eva
)
3789 TCGv taddr
= tcg_temp_local_new();
3790 TCGv lladdr
= tcg_temp_local_new();
3791 TCGv_i64 tval
= tcg_temp_new_i64();
3792 TCGv_i64 llval
= tcg_temp_new_i64();
3793 TCGv_i64 val
= tcg_temp_new_i64();
3794 TCGv tmp1
= tcg_temp_new();
3795 TCGv tmp2
= tcg_temp_new();
3796 TCGLabel
*lab_fail
= gen_new_label();
3797 TCGLabel
*lab_done
= gen_new_label();
3799 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3801 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3802 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3804 gen_load_gpr(tmp1
, reg1
);
3805 gen_load_gpr(tmp2
, reg2
);
3807 #ifdef TARGET_WORDS_BIGENDIAN
3808 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3810 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3813 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3814 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3815 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3817 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3819 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3821 gen_set_label(lab_fail
);
3824 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3826 gen_set_label(lab_done
);
3827 tcg_gen_movi_tl(lladdr
, -1);
3828 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3831 /* Load and store */
3832 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3836 * Don't do NOP if destination is zero: we must perform the actual
3842 TCGv_i32 fp0
= tcg_temp_new_i32();
3843 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3844 ctx
->default_tcg_memop_mask
);
3845 gen_store_fpr32(ctx
, fp0
, ft
);
3846 tcg_temp_free_i32(fp0
);
3851 TCGv_i32 fp0
= tcg_temp_new_i32();
3852 gen_load_fpr32(ctx
, fp0
, ft
);
3853 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3854 ctx
->default_tcg_memop_mask
);
3855 tcg_temp_free_i32(fp0
);
3860 TCGv_i64 fp0
= tcg_temp_new_i64();
3861 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3862 ctx
->default_tcg_memop_mask
);
3863 gen_store_fpr64(ctx
, fp0
, ft
);
3864 tcg_temp_free_i64(fp0
);
3869 TCGv_i64 fp0
= tcg_temp_new_i64();
3870 gen_load_fpr64(ctx
, fp0
, ft
);
3871 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3872 ctx
->default_tcg_memop_mask
);
3873 tcg_temp_free_i64(fp0
);
3877 MIPS_INVAL("flt_ldst");
3878 generate_exception_end(ctx
, EXCP_RI
);
3883 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3884 int rs
, int16_t imm
)
3886 TCGv t0
= tcg_temp_new();
3888 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3889 check_cp1_enabled(ctx
);
3893 check_insn(ctx
, ISA_MIPS2
);
3896 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3897 gen_flt_ldst(ctx
, op
, rt
, t0
);
3900 generate_exception_err(ctx
, EXCP_CpU
, 1);
3905 /* Arithmetic with immediate operand */
3906 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3907 int rt
, int rs
, int imm
)
3909 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3911 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3913 * If no destination, treat it as a NOP.
3914 * For addi, we must generate the overflow exception when needed.
3921 TCGv t0
= tcg_temp_local_new();
3922 TCGv t1
= tcg_temp_new();
3923 TCGv t2
= tcg_temp_new();
3924 TCGLabel
*l1
= gen_new_label();
3926 gen_load_gpr(t1
, rs
);
3927 tcg_gen_addi_tl(t0
, t1
, uimm
);
3928 tcg_gen_ext32s_tl(t0
, t0
);
3930 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3931 tcg_gen_xori_tl(t2
, t0
, uimm
);
3932 tcg_gen_and_tl(t1
, t1
, t2
);
3934 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3936 /* operands of same sign, result different sign */
3937 generate_exception(ctx
, EXCP_OVERFLOW
);
3939 tcg_gen_ext32s_tl(t0
, t0
);
3940 gen_store_gpr(t0
, rt
);
3946 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3947 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3949 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3952 #if defined(TARGET_MIPS64)
3955 TCGv t0
= tcg_temp_local_new();
3956 TCGv t1
= tcg_temp_new();
3957 TCGv t2
= tcg_temp_new();
3958 TCGLabel
*l1
= gen_new_label();
3960 gen_load_gpr(t1
, rs
);
3961 tcg_gen_addi_tl(t0
, t1
, uimm
);
3963 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3964 tcg_gen_xori_tl(t2
, t0
, uimm
);
3965 tcg_gen_and_tl(t1
, t1
, t2
);
3967 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3969 /* operands of same sign, result different sign */
3970 generate_exception(ctx
, EXCP_OVERFLOW
);
3972 gen_store_gpr(t0
, rt
);
3978 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3980 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3987 /* Logic with immediate operand */
3988 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3989 int rt
, int rs
, int16_t imm
)
3994 /* If no destination, treat it as a NOP. */
3997 uimm
= (uint16_t)imm
;
4000 if (likely(rs
!= 0)) {
4001 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
4003 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
4008 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
4010 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
4014 if (likely(rs
!= 0)) {
4015 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
4017 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
4021 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
4023 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
4024 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
4026 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
4035 /* Set on less than with immediate operand */
4036 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
4037 int rt
, int rs
, int16_t imm
)
4039 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
4043 /* If no destination, treat it as a NOP. */
4046 t0
= tcg_temp_new();
4047 gen_load_gpr(t0
, rs
);
4050 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
4053 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
4059 /* Shifts with immediate operand */
4060 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
4061 int rt
, int rs
, int16_t imm
)
4063 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
4067 /* If no destination, treat it as a NOP. */
4071 t0
= tcg_temp_new();
4072 gen_load_gpr(t0
, rs
);
4075 tcg_gen_shli_tl(t0
, t0
, uimm
);
4076 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4079 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4083 tcg_gen_ext32u_tl(t0
, t0
);
4084 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4086 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4091 TCGv_i32 t1
= tcg_temp_new_i32();
4093 tcg_gen_trunc_tl_i32(t1
, t0
);
4094 tcg_gen_rotri_i32(t1
, t1
, uimm
);
4095 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
4096 tcg_temp_free_i32(t1
);
4098 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4101 #if defined(TARGET_MIPS64)
4103 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
4106 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4109 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4113 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
4115 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
4119 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4122 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4125 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4128 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4136 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
4137 int rd
, int rs
, int rt
)
4139 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
4140 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
4142 * If no destination, treat it as a NOP.
4143 * For add & sub, we must generate the overflow exception when needed.
4151 TCGv t0
= tcg_temp_local_new();
4152 TCGv t1
= tcg_temp_new();
4153 TCGv t2
= tcg_temp_new();
4154 TCGLabel
*l1
= gen_new_label();
4156 gen_load_gpr(t1
, rs
);
4157 gen_load_gpr(t2
, rt
);
4158 tcg_gen_add_tl(t0
, t1
, t2
);
4159 tcg_gen_ext32s_tl(t0
, t0
);
4160 tcg_gen_xor_tl(t1
, t1
, t2
);
4161 tcg_gen_xor_tl(t2
, t0
, t2
);
4162 tcg_gen_andc_tl(t1
, t2
, t1
);
4164 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4166 /* operands of same sign, result different sign */
4167 generate_exception(ctx
, EXCP_OVERFLOW
);
4169 gen_store_gpr(t0
, rd
);
4174 if (rs
!= 0 && rt
!= 0) {
4175 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], 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
[rt
]);
4179 } else if (rs
!= 0 && rt
== 0) {
4180 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4182 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4187 TCGv t0
= tcg_temp_local_new();
4188 TCGv t1
= tcg_temp_new();
4189 TCGv t2
= tcg_temp_new();
4190 TCGLabel
*l1
= gen_new_label();
4192 gen_load_gpr(t1
, rs
);
4193 gen_load_gpr(t2
, rt
);
4194 tcg_gen_sub_tl(t0
, t1
, t2
);
4195 tcg_gen_ext32s_tl(t0
, t0
);
4196 tcg_gen_xor_tl(t2
, t1
, t2
);
4197 tcg_gen_xor_tl(t1
, t0
, t1
);
4198 tcg_gen_and_tl(t1
, t1
, t2
);
4200 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4203 * operands of different sign, first operand and the result
4206 generate_exception(ctx
, EXCP_OVERFLOW
);
4208 gen_store_gpr(t0
, rd
);
4213 if (rs
!= 0 && rt
!= 0) {
4214 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4215 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4216 } else if (rs
== 0 && rt
!= 0) {
4217 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4218 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4219 } else if (rs
!= 0 && rt
== 0) {
4220 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4222 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4225 #if defined(TARGET_MIPS64)
4228 TCGv t0
= tcg_temp_local_new();
4229 TCGv t1
= tcg_temp_new();
4230 TCGv t2
= tcg_temp_new();
4231 TCGLabel
*l1
= gen_new_label();
4233 gen_load_gpr(t1
, rs
);
4234 gen_load_gpr(t2
, rt
);
4235 tcg_gen_add_tl(t0
, t1
, t2
);
4236 tcg_gen_xor_tl(t1
, t1
, t2
);
4237 tcg_gen_xor_tl(t2
, t0
, t2
);
4238 tcg_gen_andc_tl(t1
, t2
, t1
);
4240 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4242 /* operands of same sign, result different sign */
4243 generate_exception(ctx
, EXCP_OVERFLOW
);
4245 gen_store_gpr(t0
, rd
);
4250 if (rs
!= 0 && rt
!= 0) {
4251 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4252 } else if (rs
== 0 && rt
!= 0) {
4253 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4254 } else if (rs
!= 0 && rt
== 0) {
4255 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4257 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4262 TCGv t0
= tcg_temp_local_new();
4263 TCGv t1
= tcg_temp_new();
4264 TCGv t2
= tcg_temp_new();
4265 TCGLabel
*l1
= gen_new_label();
4267 gen_load_gpr(t1
, rs
);
4268 gen_load_gpr(t2
, rt
);
4269 tcg_gen_sub_tl(t0
, t1
, t2
);
4270 tcg_gen_xor_tl(t2
, t1
, t2
);
4271 tcg_gen_xor_tl(t1
, t0
, t1
);
4272 tcg_gen_and_tl(t1
, t1
, t2
);
4274 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4277 * Operands of different sign, first operand and result different
4280 generate_exception(ctx
, EXCP_OVERFLOW
);
4282 gen_store_gpr(t0
, rd
);
4287 if (rs
!= 0 && rt
!= 0) {
4288 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4289 } else if (rs
== 0 && rt
!= 0) {
4290 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4291 } else if (rs
!= 0 && rt
== 0) {
4292 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4294 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4299 if (likely(rs
!= 0 && rt
!= 0)) {
4300 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4301 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4303 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4309 /* Conditional move */
4310 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
4311 int rd
, int rs
, int rt
)
4316 /* If no destination, treat it as a NOP. */
4320 t0
= tcg_temp_new();
4321 gen_load_gpr(t0
, rt
);
4322 t1
= tcg_const_tl(0);
4323 t2
= tcg_temp_new();
4324 gen_load_gpr(t2
, rs
);
4327 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4330 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4333 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4336 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4345 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
4346 int rd
, int rs
, int rt
)
4349 /* If no destination, treat it as a NOP. */
4355 if (likely(rs
!= 0 && rt
!= 0)) {
4356 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4358 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4362 if (rs
!= 0 && rt
!= 0) {
4363 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4364 } else if (rs
== 0 && rt
!= 0) {
4365 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4366 } else if (rs
!= 0 && rt
== 0) {
4367 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4369 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
4373 if (likely(rs
!= 0 && rt
!= 0)) {
4374 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4375 } else if (rs
== 0 && rt
!= 0) {
4376 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4377 } else if (rs
!= 0 && rt
== 0) {
4378 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4380 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4384 if (likely(rs
!= 0 && rt
!= 0)) {
4385 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4386 } else if (rs
== 0 && rt
!= 0) {
4387 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4388 } else if (rs
!= 0 && rt
== 0) {
4389 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4391 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4397 /* Set on lower than */
4398 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
4399 int rd
, int rs
, int rt
)
4404 /* If no destination, treat it as a NOP. */
4408 t0
= tcg_temp_new();
4409 t1
= tcg_temp_new();
4410 gen_load_gpr(t0
, rs
);
4411 gen_load_gpr(t1
, rt
);
4414 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
4417 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
4425 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
4426 int rd
, int rs
, int rt
)
4432 * If no destination, treat it as a NOP.
4433 * For add & sub, we must generate the overflow exception when needed.
4438 t0
= tcg_temp_new();
4439 t1
= tcg_temp_new();
4440 gen_load_gpr(t0
, rs
);
4441 gen_load_gpr(t1
, rt
);
4444 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4445 tcg_gen_shl_tl(t0
, t1
, t0
);
4446 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4449 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4450 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4453 tcg_gen_ext32u_tl(t1
, t1
);
4454 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4455 tcg_gen_shr_tl(t0
, t1
, t0
);
4456 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4460 TCGv_i32 t2
= tcg_temp_new_i32();
4461 TCGv_i32 t3
= tcg_temp_new_i32();
4463 tcg_gen_trunc_tl_i32(t2
, t0
);
4464 tcg_gen_trunc_tl_i32(t3
, t1
);
4465 tcg_gen_andi_i32(t2
, t2
, 0x1f);
4466 tcg_gen_rotr_i32(t2
, t3
, t2
);
4467 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4468 tcg_temp_free_i32(t2
);
4469 tcg_temp_free_i32(t3
);
4472 #if defined(TARGET_MIPS64)
4474 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4475 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
4478 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4479 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4482 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4483 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
4486 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4487 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
4495 #if defined(TARGET_MIPS64)
4496 /* Copy GPR to and from TX79 HI1/LO1 register. */
4497 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
4499 if (reg
== 0 && (opc
== MMI_OPC_MFHI1
|| opc
== MMI_OPC_MFLO1
)) {
4506 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[1]);
4509 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[1]);
4513 tcg_gen_mov_tl(cpu_HI
[1], cpu_gpr
[reg
]);
4515 tcg_gen_movi_tl(cpu_HI
[1], 0);
4520 tcg_gen_mov_tl(cpu_LO
[1], cpu_gpr
[reg
]);
4522 tcg_gen_movi_tl(cpu_LO
[1], 0);
4526 MIPS_INVAL("mfthilo1 TX79");
4527 generate_exception_end(ctx
, EXCP_RI
);
4533 /* Arithmetic on HI/LO registers */
4534 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
4536 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
4547 #if defined(TARGET_MIPS64)
4549 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4553 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4557 #if defined(TARGET_MIPS64)
4559 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4563 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4568 #if defined(TARGET_MIPS64)
4570 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4574 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4577 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
4582 #if defined(TARGET_MIPS64)
4584 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4588 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4591 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4597 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4600 TCGv t0
= tcg_const_tl(addr
);
4601 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4602 gen_store_gpr(t0
, reg
);
4606 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4612 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4615 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4616 addr
= addr_add(ctx
, pc
, offset
);
4617 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4621 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4622 addr
= addr_add(ctx
, pc
, offset
);
4623 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4625 #if defined(TARGET_MIPS64)
4628 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4629 addr
= addr_add(ctx
, pc
, offset
);
4630 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4634 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4637 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4638 addr
= addr_add(ctx
, pc
, offset
);
4639 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4644 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4645 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4646 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4649 #if defined(TARGET_MIPS64)
4650 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4651 case R6_OPC_LDPC
+ (1 << 16):
4652 case R6_OPC_LDPC
+ (2 << 16):
4653 case R6_OPC_LDPC
+ (3 << 16):
4655 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4656 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4657 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4661 MIPS_INVAL("OPC_PCREL");
4662 generate_exception_end(ctx
, EXCP_RI
);
4669 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4678 t0
= tcg_temp_new();
4679 t1
= tcg_temp_new();
4681 gen_load_gpr(t0
, rs
);
4682 gen_load_gpr(t1
, rt
);
4687 TCGv t2
= tcg_temp_new();
4688 TCGv t3
= tcg_temp_new();
4689 tcg_gen_ext32s_tl(t0
, t0
);
4690 tcg_gen_ext32s_tl(t1
, t1
);
4691 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4692 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4693 tcg_gen_and_tl(t2
, t2
, t3
);
4694 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4695 tcg_gen_or_tl(t2
, t2
, t3
);
4696 tcg_gen_movi_tl(t3
, 0);
4697 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4698 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4699 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4706 TCGv t2
= tcg_temp_new();
4707 TCGv t3
= tcg_temp_new();
4708 tcg_gen_ext32s_tl(t0
, t0
);
4709 tcg_gen_ext32s_tl(t1
, t1
);
4710 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4711 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4712 tcg_gen_and_tl(t2
, t2
, t3
);
4713 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4714 tcg_gen_or_tl(t2
, t2
, t3
);
4715 tcg_gen_movi_tl(t3
, 0);
4716 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4717 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4718 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4725 TCGv t2
= tcg_const_tl(0);
4726 TCGv t3
= tcg_const_tl(1);
4727 tcg_gen_ext32u_tl(t0
, t0
);
4728 tcg_gen_ext32u_tl(t1
, t1
);
4729 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4730 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4731 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4738 TCGv t2
= tcg_const_tl(0);
4739 TCGv t3
= tcg_const_tl(1);
4740 tcg_gen_ext32u_tl(t0
, t0
);
4741 tcg_gen_ext32u_tl(t1
, t1
);
4742 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4743 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4744 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4751 TCGv_i32 t2
= tcg_temp_new_i32();
4752 TCGv_i32 t3
= tcg_temp_new_i32();
4753 tcg_gen_trunc_tl_i32(t2
, t0
);
4754 tcg_gen_trunc_tl_i32(t3
, t1
);
4755 tcg_gen_mul_i32(t2
, t2
, t3
);
4756 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4757 tcg_temp_free_i32(t2
);
4758 tcg_temp_free_i32(t3
);
4763 TCGv_i32 t2
= tcg_temp_new_i32();
4764 TCGv_i32 t3
= tcg_temp_new_i32();
4765 tcg_gen_trunc_tl_i32(t2
, t0
);
4766 tcg_gen_trunc_tl_i32(t3
, t1
);
4767 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4768 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4769 tcg_temp_free_i32(t2
);
4770 tcg_temp_free_i32(t3
);
4775 TCGv_i32 t2
= tcg_temp_new_i32();
4776 TCGv_i32 t3
= tcg_temp_new_i32();
4777 tcg_gen_trunc_tl_i32(t2
, t0
);
4778 tcg_gen_trunc_tl_i32(t3
, t1
);
4779 tcg_gen_mul_i32(t2
, t2
, t3
);
4780 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4781 tcg_temp_free_i32(t2
);
4782 tcg_temp_free_i32(t3
);
4787 TCGv_i32 t2
= tcg_temp_new_i32();
4788 TCGv_i32 t3
= tcg_temp_new_i32();
4789 tcg_gen_trunc_tl_i32(t2
, t0
);
4790 tcg_gen_trunc_tl_i32(t3
, t1
);
4791 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4792 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4793 tcg_temp_free_i32(t2
);
4794 tcg_temp_free_i32(t3
);
4797 #if defined(TARGET_MIPS64)
4800 TCGv t2
= tcg_temp_new();
4801 TCGv t3
= tcg_temp_new();
4802 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4803 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4804 tcg_gen_and_tl(t2
, t2
, t3
);
4805 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4806 tcg_gen_or_tl(t2
, t2
, t3
);
4807 tcg_gen_movi_tl(t3
, 0);
4808 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4809 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4816 TCGv t2
= tcg_temp_new();
4817 TCGv t3
= tcg_temp_new();
4818 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4819 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4820 tcg_gen_and_tl(t2
, t2
, t3
);
4821 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4822 tcg_gen_or_tl(t2
, t2
, t3
);
4823 tcg_gen_movi_tl(t3
, 0);
4824 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4825 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4832 TCGv t2
= tcg_const_tl(0);
4833 TCGv t3
= tcg_const_tl(1);
4834 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4835 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4842 TCGv t2
= tcg_const_tl(0);
4843 TCGv t3
= tcg_const_tl(1);
4844 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4845 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4851 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4855 TCGv t2
= tcg_temp_new();
4856 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4861 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4865 TCGv t2
= tcg_temp_new();
4866 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4872 MIPS_INVAL("r6 mul/div");
4873 generate_exception_end(ctx
, EXCP_RI
);
4881 #if defined(TARGET_MIPS64)
4882 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4886 t0
= tcg_temp_new();
4887 t1
= tcg_temp_new();
4889 gen_load_gpr(t0
, rs
);
4890 gen_load_gpr(t1
, rt
);
4895 TCGv t2
= tcg_temp_new();
4896 TCGv t3
= tcg_temp_new();
4897 tcg_gen_ext32s_tl(t0
, t0
);
4898 tcg_gen_ext32s_tl(t1
, t1
);
4899 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4900 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4901 tcg_gen_and_tl(t2
, t2
, t3
);
4902 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4903 tcg_gen_or_tl(t2
, t2
, t3
);
4904 tcg_gen_movi_tl(t3
, 0);
4905 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4906 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4907 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4908 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4909 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4916 TCGv t2
= tcg_const_tl(0);
4917 TCGv t3
= tcg_const_tl(1);
4918 tcg_gen_ext32u_tl(t0
, t0
);
4919 tcg_gen_ext32u_tl(t1
, t1
);
4920 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4921 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4922 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4923 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4924 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4930 MIPS_INVAL("div1 TX79");
4931 generate_exception_end(ctx
, EXCP_RI
);
4940 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4941 int acc
, int rs
, int rt
)
4945 t0
= tcg_temp_new();
4946 t1
= tcg_temp_new();
4948 gen_load_gpr(t0
, rs
);
4949 gen_load_gpr(t1
, rt
);
4958 TCGv t2
= tcg_temp_new();
4959 TCGv t3
= tcg_temp_new();
4960 tcg_gen_ext32s_tl(t0
, t0
);
4961 tcg_gen_ext32s_tl(t1
, t1
);
4962 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4963 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4964 tcg_gen_and_tl(t2
, t2
, t3
);
4965 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4966 tcg_gen_or_tl(t2
, t2
, t3
);
4967 tcg_gen_movi_tl(t3
, 0);
4968 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4969 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4970 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4971 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4972 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4979 TCGv t2
= tcg_const_tl(0);
4980 TCGv t3
= tcg_const_tl(1);
4981 tcg_gen_ext32u_tl(t0
, t0
);
4982 tcg_gen_ext32u_tl(t1
, t1
);
4983 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4984 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4985 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4986 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4987 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4994 TCGv_i32 t2
= tcg_temp_new_i32();
4995 TCGv_i32 t3
= tcg_temp_new_i32();
4996 tcg_gen_trunc_tl_i32(t2
, t0
);
4997 tcg_gen_trunc_tl_i32(t3
, t1
);
4998 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4999 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5000 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5001 tcg_temp_free_i32(t2
);
5002 tcg_temp_free_i32(t3
);
5007 TCGv_i32 t2
= tcg_temp_new_i32();
5008 TCGv_i32 t3
= tcg_temp_new_i32();
5009 tcg_gen_trunc_tl_i32(t2
, t0
);
5010 tcg_gen_trunc_tl_i32(t3
, t1
);
5011 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
5012 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5013 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5014 tcg_temp_free_i32(t2
);
5015 tcg_temp_free_i32(t3
);
5018 #if defined(TARGET_MIPS64)
5021 TCGv t2
= tcg_temp_new();
5022 TCGv t3
= tcg_temp_new();
5023 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
5024 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
5025 tcg_gen_and_tl(t2
, t2
, t3
);
5026 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
5027 tcg_gen_or_tl(t2
, t2
, t3
);
5028 tcg_gen_movi_tl(t3
, 0);
5029 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
5030 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
5031 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
5038 TCGv t2
= tcg_const_tl(0);
5039 TCGv t3
= tcg_const_tl(1);
5040 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
5041 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
5042 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
5048 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
5051 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
5056 TCGv_i64 t2
= tcg_temp_new_i64();
5057 TCGv_i64 t3
= tcg_temp_new_i64();
5059 tcg_gen_ext_tl_i64(t2
, t0
);
5060 tcg_gen_ext_tl_i64(t3
, t1
);
5061 tcg_gen_mul_i64(t2
, t2
, t3
);
5062 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5063 tcg_gen_add_i64(t2
, t2
, t3
);
5064 tcg_temp_free_i64(t3
);
5065 gen_move_low32(cpu_LO
[acc
], t2
);
5066 gen_move_high32(cpu_HI
[acc
], t2
);
5067 tcg_temp_free_i64(t2
);
5072 TCGv_i64 t2
= tcg_temp_new_i64();
5073 TCGv_i64 t3
= tcg_temp_new_i64();
5075 tcg_gen_ext32u_tl(t0
, t0
);
5076 tcg_gen_ext32u_tl(t1
, t1
);
5077 tcg_gen_extu_tl_i64(t2
, t0
);
5078 tcg_gen_extu_tl_i64(t3
, t1
);
5079 tcg_gen_mul_i64(t2
, t2
, t3
);
5080 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5081 tcg_gen_add_i64(t2
, t2
, t3
);
5082 tcg_temp_free_i64(t3
);
5083 gen_move_low32(cpu_LO
[acc
], t2
);
5084 gen_move_high32(cpu_HI
[acc
], t2
);
5085 tcg_temp_free_i64(t2
);
5090 TCGv_i64 t2
= tcg_temp_new_i64();
5091 TCGv_i64 t3
= tcg_temp_new_i64();
5093 tcg_gen_ext_tl_i64(t2
, t0
);
5094 tcg_gen_ext_tl_i64(t3
, t1
);
5095 tcg_gen_mul_i64(t2
, t2
, t3
);
5096 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5097 tcg_gen_sub_i64(t2
, t3
, t2
);
5098 tcg_temp_free_i64(t3
);
5099 gen_move_low32(cpu_LO
[acc
], t2
);
5100 gen_move_high32(cpu_HI
[acc
], t2
);
5101 tcg_temp_free_i64(t2
);
5106 TCGv_i64 t2
= tcg_temp_new_i64();
5107 TCGv_i64 t3
= tcg_temp_new_i64();
5109 tcg_gen_ext32u_tl(t0
, t0
);
5110 tcg_gen_ext32u_tl(t1
, t1
);
5111 tcg_gen_extu_tl_i64(t2
, t0
);
5112 tcg_gen_extu_tl_i64(t3
, t1
);
5113 tcg_gen_mul_i64(t2
, t2
, t3
);
5114 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5115 tcg_gen_sub_i64(t2
, t3
, t2
);
5116 tcg_temp_free_i64(t3
);
5117 gen_move_low32(cpu_LO
[acc
], t2
);
5118 gen_move_high32(cpu_HI
[acc
], t2
);
5119 tcg_temp_free_i64(t2
);
5123 MIPS_INVAL("mul/div");
5124 generate_exception_end(ctx
, EXCP_RI
);
5133 * These MULT[U] and MADD[U] instructions implemented in for example
5134 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5135 * architectures are special three-operand variants with the syntax
5137 * MULT[U][1] rd, rs, rt
5141 * (rd, LO, HI) <- rs * rt
5145 * MADD[U][1] rd, rs, rt
5149 * (rd, LO, HI) <- (LO, HI) + rs * rt
5151 * where the low-order 32-bits of the result is placed into both the
5152 * GPR rd and the special register LO. The high-order 32-bits of the
5153 * result is placed into the special register HI.
5155 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5156 * which is the zero register that always reads as 0.
5158 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
5159 int rd
, int rs
, int rt
)
5161 TCGv t0
= tcg_temp_new();
5162 TCGv t1
= tcg_temp_new();
5165 gen_load_gpr(t0
, rs
);
5166 gen_load_gpr(t1
, rt
);
5174 TCGv_i32 t2
= tcg_temp_new_i32();
5175 TCGv_i32 t3
= tcg_temp_new_i32();
5176 tcg_gen_trunc_tl_i32(t2
, t0
);
5177 tcg_gen_trunc_tl_i32(t3
, t1
);
5178 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
5180 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5182 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5183 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5184 tcg_temp_free_i32(t2
);
5185 tcg_temp_free_i32(t3
);
5188 case MMI_OPC_MULTU1
:
5193 TCGv_i32 t2
= tcg_temp_new_i32();
5194 TCGv_i32 t3
= tcg_temp_new_i32();
5195 tcg_gen_trunc_tl_i32(t2
, t0
);
5196 tcg_gen_trunc_tl_i32(t3
, t1
);
5197 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
5199 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5201 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5202 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5203 tcg_temp_free_i32(t2
);
5204 tcg_temp_free_i32(t3
);
5212 TCGv_i64 t2
= tcg_temp_new_i64();
5213 TCGv_i64 t3
= tcg_temp_new_i64();
5215 tcg_gen_ext_tl_i64(t2
, t0
);
5216 tcg_gen_ext_tl_i64(t3
, t1
);
5217 tcg_gen_mul_i64(t2
, t2
, t3
);
5218 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5219 tcg_gen_add_i64(t2
, t2
, t3
);
5220 tcg_temp_free_i64(t3
);
5221 gen_move_low32(cpu_LO
[acc
], t2
);
5222 gen_move_high32(cpu_HI
[acc
], t2
);
5224 gen_move_low32(cpu_gpr
[rd
], t2
);
5226 tcg_temp_free_i64(t2
);
5229 case MMI_OPC_MADDU1
:
5234 TCGv_i64 t2
= tcg_temp_new_i64();
5235 TCGv_i64 t3
= tcg_temp_new_i64();
5237 tcg_gen_ext32u_tl(t0
, t0
);
5238 tcg_gen_ext32u_tl(t1
, t1
);
5239 tcg_gen_extu_tl_i64(t2
, t0
);
5240 tcg_gen_extu_tl_i64(t3
, t1
);
5241 tcg_gen_mul_i64(t2
, t2
, t3
);
5242 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5243 tcg_gen_add_i64(t2
, t2
, t3
);
5244 tcg_temp_free_i64(t3
);
5245 gen_move_low32(cpu_LO
[acc
], t2
);
5246 gen_move_high32(cpu_HI
[acc
], t2
);
5248 gen_move_low32(cpu_gpr
[rd
], t2
);
5250 tcg_temp_free_i64(t2
);
5254 MIPS_INVAL("mul/madd TXx9");
5255 generate_exception_end(ctx
, EXCP_RI
);
5264 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
5265 int rd
, int rs
, int rt
)
5267 TCGv t0
= tcg_temp_new();
5268 TCGv t1
= tcg_temp_new();
5270 gen_load_gpr(t0
, rs
);
5271 gen_load_gpr(t1
, rt
);
5274 case OPC_VR54XX_MULS
:
5275 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
5277 case OPC_VR54XX_MULSU
:
5278 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
5280 case OPC_VR54XX_MACC
:
5281 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
5283 case OPC_VR54XX_MACCU
:
5284 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
5286 case OPC_VR54XX_MSAC
:
5287 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
5289 case OPC_VR54XX_MSACU
:
5290 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
5292 case OPC_VR54XX_MULHI
:
5293 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
5295 case OPC_VR54XX_MULHIU
:
5296 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
5298 case OPC_VR54XX_MULSHI
:
5299 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
5301 case OPC_VR54XX_MULSHIU
:
5302 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
5304 case OPC_VR54XX_MACCHI
:
5305 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
5307 case OPC_VR54XX_MACCHIU
:
5308 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
5310 case OPC_VR54XX_MSACHI
:
5311 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
5313 case OPC_VR54XX_MSACHIU
:
5314 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
5317 MIPS_INVAL("mul vr54xx");
5318 generate_exception_end(ctx
, EXCP_RI
);
5321 gen_store_gpr(t0
, rd
);
5328 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
5338 gen_load_gpr(t0
, rs
);
5343 #if defined(TARGET_MIPS64)
5347 tcg_gen_not_tl(t0
, t0
);
5356 tcg_gen_ext32u_tl(t0
, t0
);
5357 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
5358 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
5360 #if defined(TARGET_MIPS64)
5365 tcg_gen_clzi_i64(t0
, t0
, 64);
5371 /* Godson integer instructions */
5372 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
5373 int rd
, int rs
, int rt
)
5385 case OPC_MULTU_G_2E
:
5386 case OPC_MULTU_G_2F
:
5387 #if defined(TARGET_MIPS64)
5388 case OPC_DMULT_G_2E
:
5389 case OPC_DMULT_G_2F
:
5390 case OPC_DMULTU_G_2E
:
5391 case OPC_DMULTU_G_2F
:
5393 t0
= tcg_temp_new();
5394 t1
= tcg_temp_new();
5397 t0
= tcg_temp_local_new();
5398 t1
= tcg_temp_local_new();
5402 gen_load_gpr(t0
, rs
);
5403 gen_load_gpr(t1
, rt
);
5408 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5409 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5411 case OPC_MULTU_G_2E
:
5412 case OPC_MULTU_G_2F
:
5413 tcg_gen_ext32u_tl(t0
, t0
);
5414 tcg_gen_ext32u_tl(t1
, t1
);
5415 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5416 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5421 TCGLabel
*l1
= gen_new_label();
5422 TCGLabel
*l2
= gen_new_label();
5423 TCGLabel
*l3
= gen_new_label();
5424 tcg_gen_ext32s_tl(t0
, t0
);
5425 tcg_gen_ext32s_tl(t1
, t1
);
5426 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5427 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5430 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5431 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5432 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5435 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5436 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5443 TCGLabel
*l1
= gen_new_label();
5444 TCGLabel
*l2
= gen_new_label();
5445 tcg_gen_ext32u_tl(t0
, t0
);
5446 tcg_gen_ext32u_tl(t1
, t1
);
5447 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5448 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5451 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5452 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5459 TCGLabel
*l1
= gen_new_label();
5460 TCGLabel
*l2
= gen_new_label();
5461 TCGLabel
*l3
= gen_new_label();
5462 tcg_gen_ext32u_tl(t0
, t0
);
5463 tcg_gen_ext32u_tl(t1
, t1
);
5464 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5465 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5466 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5468 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5471 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5472 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5479 TCGLabel
*l1
= gen_new_label();
5480 TCGLabel
*l2
= gen_new_label();
5481 tcg_gen_ext32u_tl(t0
, t0
);
5482 tcg_gen_ext32u_tl(t1
, t1
);
5483 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5484 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5487 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5488 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5492 #if defined(TARGET_MIPS64)
5493 case OPC_DMULT_G_2E
:
5494 case OPC_DMULT_G_2F
:
5495 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5497 case OPC_DMULTU_G_2E
:
5498 case OPC_DMULTU_G_2F
:
5499 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5504 TCGLabel
*l1
= gen_new_label();
5505 TCGLabel
*l2
= gen_new_label();
5506 TCGLabel
*l3
= gen_new_label();
5507 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5508 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5511 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5512 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5513 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5516 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5520 case OPC_DDIVU_G_2E
:
5521 case OPC_DDIVU_G_2F
:
5523 TCGLabel
*l1
= gen_new_label();
5524 TCGLabel
*l2
= gen_new_label();
5525 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5526 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5529 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5536 TCGLabel
*l1
= gen_new_label();
5537 TCGLabel
*l2
= gen_new_label();
5538 TCGLabel
*l3
= gen_new_label();
5539 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5540 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5541 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5543 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5546 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5550 case OPC_DMODU_G_2E
:
5551 case OPC_DMODU_G_2F
:
5553 TCGLabel
*l1
= gen_new_label();
5554 TCGLabel
*l2
= gen_new_label();
5555 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5556 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5559 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5570 /* Loongson multimedia instructions */
5571 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
5573 uint32_t opc
, shift_max
;
5577 opc
= MASK_LMMI(ctx
->opcode
);
5583 t0
= tcg_temp_local_new_i64();
5584 t1
= tcg_temp_local_new_i64();
5587 t0
= tcg_temp_new_i64();
5588 t1
= tcg_temp_new_i64();
5592 check_cp1_enabled(ctx
);
5593 gen_load_fpr64(ctx
, t0
, rs
);
5594 gen_load_fpr64(ctx
, t1
, rt
);
5598 gen_helper_paddsh(t0
, t0
, t1
);
5601 gen_helper_paddush(t0
, t0
, t1
);
5604 gen_helper_paddh(t0
, t0
, t1
);
5607 gen_helper_paddw(t0
, t0
, t1
);
5610 gen_helper_paddsb(t0
, t0
, t1
);
5613 gen_helper_paddusb(t0
, t0
, t1
);
5616 gen_helper_paddb(t0
, t0
, t1
);
5620 gen_helper_psubsh(t0
, t0
, t1
);
5623 gen_helper_psubush(t0
, t0
, t1
);
5626 gen_helper_psubh(t0
, t0
, t1
);
5629 gen_helper_psubw(t0
, t0
, t1
);
5632 gen_helper_psubsb(t0
, t0
, t1
);
5635 gen_helper_psubusb(t0
, t0
, t1
);
5638 gen_helper_psubb(t0
, t0
, t1
);
5642 gen_helper_pshufh(t0
, t0
, t1
);
5645 gen_helper_packsswh(t0
, t0
, t1
);
5648 gen_helper_packsshb(t0
, t0
, t1
);
5651 gen_helper_packushb(t0
, t0
, t1
);
5655 gen_helper_punpcklhw(t0
, t0
, t1
);
5658 gen_helper_punpckhhw(t0
, t0
, t1
);
5661 gen_helper_punpcklbh(t0
, t0
, t1
);
5664 gen_helper_punpckhbh(t0
, t0
, t1
);
5667 gen_helper_punpcklwd(t0
, t0
, t1
);
5670 gen_helper_punpckhwd(t0
, t0
, t1
);
5674 gen_helper_pavgh(t0
, t0
, t1
);
5677 gen_helper_pavgb(t0
, t0
, t1
);
5680 gen_helper_pmaxsh(t0
, t0
, t1
);
5683 gen_helper_pminsh(t0
, t0
, t1
);
5686 gen_helper_pmaxub(t0
, t0
, t1
);
5689 gen_helper_pminub(t0
, t0
, t1
);
5693 gen_helper_pcmpeqw(t0
, t0
, t1
);
5696 gen_helper_pcmpgtw(t0
, t0
, t1
);
5699 gen_helper_pcmpeqh(t0
, t0
, t1
);
5702 gen_helper_pcmpgth(t0
, t0
, t1
);
5705 gen_helper_pcmpeqb(t0
, t0
, t1
);
5708 gen_helper_pcmpgtb(t0
, t0
, t1
);
5712 gen_helper_psllw(t0
, t0
, t1
);
5715 gen_helper_psllh(t0
, t0
, t1
);
5718 gen_helper_psrlw(t0
, t0
, t1
);
5721 gen_helper_psrlh(t0
, t0
, t1
);
5724 gen_helper_psraw(t0
, t0
, t1
);
5727 gen_helper_psrah(t0
, t0
, t1
);
5731 gen_helper_pmullh(t0
, t0
, t1
);
5734 gen_helper_pmulhh(t0
, t0
, t1
);
5737 gen_helper_pmulhuh(t0
, t0
, t1
);
5740 gen_helper_pmaddhw(t0
, t0
, t1
);
5744 gen_helper_pasubub(t0
, t0
, t1
);
5747 gen_helper_biadd(t0
, t0
);
5750 gen_helper_pmovmskb(t0
, t0
);
5754 tcg_gen_add_i64(t0
, t0
, t1
);
5757 tcg_gen_sub_i64(t0
, t0
, t1
);
5760 tcg_gen_xor_i64(t0
, t0
, t1
);
5763 tcg_gen_nor_i64(t0
, t0
, t1
);
5766 tcg_gen_and_i64(t0
, t0
, t1
);
5769 tcg_gen_or_i64(t0
, t0
, t1
);
5773 tcg_gen_andc_i64(t0
, t1
, t0
);
5777 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5780 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5783 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5786 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5790 tcg_gen_andi_i64(t1
, t1
, 3);
5791 tcg_gen_shli_i64(t1
, t1
, 4);
5792 tcg_gen_shr_i64(t0
, t0
, t1
);
5793 tcg_gen_ext16u_i64(t0
, t0
);
5797 tcg_gen_add_i64(t0
, t0
, t1
);
5798 tcg_gen_ext32s_i64(t0
, t0
);
5801 tcg_gen_sub_i64(t0
, t0
, t1
);
5802 tcg_gen_ext32s_i64(t0
, t0
);
5824 /* Make sure shift count isn't TCG undefined behaviour. */
5825 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5830 tcg_gen_shl_i64(t0
, t0
, t1
);
5835 * Since SRA is UndefinedResult without sign-extended inputs,
5836 * we can treat SRA and DSRA the same.
5838 tcg_gen_sar_i64(t0
, t0
, t1
);
5841 /* We want to shift in zeros for SRL; zero-extend first. */
5842 tcg_gen_ext32u_i64(t0
, t0
);
5845 tcg_gen_shr_i64(t0
, t0
, t1
);
5849 if (shift_max
== 32) {
5850 tcg_gen_ext32s_i64(t0
, t0
);
5853 /* Shifts larger than MAX produce zero. */
5854 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5855 tcg_gen_neg_i64(t1
, t1
);
5856 tcg_gen_and_i64(t0
, t0
, t1
);
5862 TCGv_i64 t2
= tcg_temp_new_i64();
5863 TCGLabel
*lab
= gen_new_label();
5865 tcg_gen_mov_i64(t2
, t0
);
5866 tcg_gen_add_i64(t0
, t1
, t2
);
5867 if (opc
== OPC_ADD_CP2
) {
5868 tcg_gen_ext32s_i64(t0
, t0
);
5870 tcg_gen_xor_i64(t1
, t1
, t2
);
5871 tcg_gen_xor_i64(t2
, t2
, t0
);
5872 tcg_gen_andc_i64(t1
, t2
, t1
);
5873 tcg_temp_free_i64(t2
);
5874 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5875 generate_exception(ctx
, EXCP_OVERFLOW
);
5883 TCGv_i64 t2
= tcg_temp_new_i64();
5884 TCGLabel
*lab
= gen_new_label();
5886 tcg_gen_mov_i64(t2
, t0
);
5887 tcg_gen_sub_i64(t0
, t1
, t2
);
5888 if (opc
== OPC_SUB_CP2
) {
5889 tcg_gen_ext32s_i64(t0
, t0
);
5891 tcg_gen_xor_i64(t1
, t1
, t2
);
5892 tcg_gen_xor_i64(t2
, t2
, t0
);
5893 tcg_gen_and_i64(t1
, t1
, t2
);
5894 tcg_temp_free_i64(t2
);
5895 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5896 generate_exception(ctx
, EXCP_OVERFLOW
);
5902 tcg_gen_ext32u_i64(t0
, t0
);
5903 tcg_gen_ext32u_i64(t1
, t1
);
5904 tcg_gen_mul_i64(t0
, t0
, t1
);
5913 cond
= TCG_COND_LTU
;
5921 cond
= TCG_COND_LEU
;
5928 int cc
= (ctx
->opcode
>> 8) & 0x7;
5929 TCGv_i64 t64
= tcg_temp_new_i64();
5930 TCGv_i32 t32
= tcg_temp_new_i32();
5932 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
5933 tcg_gen_extrl_i64_i32(t32
, t64
);
5934 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
5937 tcg_temp_free_i32(t32
);
5938 tcg_temp_free_i64(t64
);
5943 MIPS_INVAL("loongson_cp2");
5944 generate_exception_end(ctx
, EXCP_RI
);
5948 gen_store_fpr64(ctx
, t0
, rd
);
5951 tcg_temp_free_i64(t0
);
5952 tcg_temp_free_i64(t1
);
5955 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
5960 #if defined(TARGET_MIPS64)
5961 int lsq_rt1
= ctx
->opcode
& 0x1f;
5962 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
5964 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
5966 t0
= tcg_temp_new();
5968 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
5969 #if defined(TARGET_MIPS64)
5971 t1
= tcg_temp_new();
5972 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5973 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5974 ctx
->default_tcg_memop_mask
);
5975 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5976 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5977 ctx
->default_tcg_memop_mask
);
5978 gen_store_gpr(t1
, rt
);
5979 gen_store_gpr(t0
, lsq_rt1
);
5983 check_cp1_enabled(ctx
);
5984 t1
= tcg_temp_new();
5985 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5986 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5987 ctx
->default_tcg_memop_mask
);
5988 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5989 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5990 ctx
->default_tcg_memop_mask
);
5991 gen_store_fpr64(ctx
, t1
, rt
);
5992 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
5996 t1
= tcg_temp_new();
5997 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5998 gen_load_gpr(t1
, rt
);
5999 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6000 ctx
->default_tcg_memop_mask
);
6001 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
6002 gen_load_gpr(t1
, lsq_rt1
);
6003 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6004 ctx
->default_tcg_memop_mask
);
6008 check_cp1_enabled(ctx
);
6009 t1
= tcg_temp_new();
6010 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
6011 gen_load_fpr64(ctx
, t1
, rt
);
6012 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6013 ctx
->default_tcg_memop_mask
);
6014 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
6015 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
6016 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6017 ctx
->default_tcg_memop_mask
);
6022 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
6024 check_cp1_enabled(ctx
);
6025 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6026 t1
= tcg_temp_new();
6027 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6028 tcg_gen_andi_tl(t1
, t0
, 3);
6029 #ifndef TARGET_WORDS_BIGENDIAN
6030 tcg_gen_xori_tl(t1
, t1
, 3);
6032 tcg_gen_shli_tl(t1
, t1
, 3);
6033 tcg_gen_andi_tl(t0
, t0
, ~3);
6034 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
6035 tcg_gen_shl_tl(t0
, t0
, t1
);
6036 t2
= tcg_const_tl(-1);
6037 tcg_gen_shl_tl(t2
, t2
, t1
);
6038 fp0
= tcg_temp_new_i32();
6039 gen_load_fpr32(ctx
, fp0
, rt
);
6040 tcg_gen_ext_i32_tl(t1
, fp0
);
6041 tcg_gen_andc_tl(t1
, t1
, t2
);
6043 tcg_gen_or_tl(t0
, t0
, t1
);
6045 #if defined(TARGET_MIPS64)
6046 tcg_gen_extrl_i64_i32(fp0
, t0
);
6048 tcg_gen_ext32s_tl(fp0
, t0
);
6050 gen_store_fpr32(ctx
, fp0
, rt
);
6051 tcg_temp_free_i32(fp0
);
6054 check_cp1_enabled(ctx
);
6055 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6056 t1
= tcg_temp_new();
6057 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6058 tcg_gen_andi_tl(t1
, t0
, 3);
6059 #ifdef TARGET_WORDS_BIGENDIAN
6060 tcg_gen_xori_tl(t1
, t1
, 3);
6062 tcg_gen_shli_tl(t1
, t1
, 3);
6063 tcg_gen_andi_tl(t0
, t0
, ~3);
6064 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
6065 tcg_gen_shr_tl(t0
, t0
, t1
);
6066 tcg_gen_xori_tl(t1
, t1
, 31);
6067 t2
= tcg_const_tl(0xfffffffeull
);
6068 tcg_gen_shl_tl(t2
, t2
, t1
);
6069 fp0
= tcg_temp_new_i32();
6070 gen_load_fpr32(ctx
, fp0
, rt
);
6071 tcg_gen_ext_i32_tl(t1
, fp0
);
6072 tcg_gen_and_tl(t1
, t1
, t2
);
6074 tcg_gen_or_tl(t0
, t0
, t1
);
6076 #if defined(TARGET_MIPS64)
6077 tcg_gen_extrl_i64_i32(fp0
, t0
);
6079 tcg_gen_ext32s_tl(fp0
, t0
);
6081 gen_store_fpr32(ctx
, fp0
, rt
);
6082 tcg_temp_free_i32(fp0
);
6084 #if defined(TARGET_MIPS64)
6086 check_cp1_enabled(ctx
);
6087 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6088 t1
= tcg_temp_new();
6089 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6090 tcg_gen_andi_tl(t1
, t0
, 7);
6091 #ifndef TARGET_WORDS_BIGENDIAN
6092 tcg_gen_xori_tl(t1
, t1
, 7);
6094 tcg_gen_shli_tl(t1
, t1
, 3);
6095 tcg_gen_andi_tl(t0
, t0
, ~7);
6096 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
6097 tcg_gen_shl_tl(t0
, t0
, t1
);
6098 t2
= tcg_const_tl(-1);
6099 tcg_gen_shl_tl(t2
, t2
, t1
);
6100 gen_load_fpr64(ctx
, t1
, rt
);
6101 tcg_gen_andc_tl(t1
, t1
, t2
);
6103 tcg_gen_or_tl(t0
, t0
, t1
);
6105 gen_store_fpr64(ctx
, t0
, rt
);
6108 check_cp1_enabled(ctx
);
6109 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6110 t1
= tcg_temp_new();
6111 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6112 tcg_gen_andi_tl(t1
, t0
, 7);
6113 #ifdef TARGET_WORDS_BIGENDIAN
6114 tcg_gen_xori_tl(t1
, t1
, 7);
6116 tcg_gen_shli_tl(t1
, t1
, 3);
6117 tcg_gen_andi_tl(t0
, t0
, ~7);
6118 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
6119 tcg_gen_shr_tl(t0
, t0
, t1
);
6120 tcg_gen_xori_tl(t1
, t1
, 63);
6121 t2
= tcg_const_tl(0xfffffffffffffffeull
);
6122 tcg_gen_shl_tl(t2
, t2
, t1
);
6123 gen_load_fpr64(ctx
, t1
, rt
);
6124 tcg_gen_and_tl(t1
, t1
, t2
);
6126 tcg_gen_or_tl(t0
, t0
, t1
);
6128 gen_store_fpr64(ctx
, t0
, rt
);
6132 MIPS_INVAL("loongson_gsshfl");
6133 generate_exception_end(ctx
, EXCP_RI
);
6138 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
6140 check_cp1_enabled(ctx
);
6141 t1
= tcg_temp_new();
6142 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6143 fp0
= tcg_temp_new_i32();
6144 gen_load_fpr32(ctx
, fp0
, rt
);
6145 tcg_gen_ext_i32_tl(t1
, fp0
);
6146 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
6147 tcg_temp_free_i32(fp0
);
6151 check_cp1_enabled(ctx
);
6152 t1
= tcg_temp_new();
6153 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6154 fp0
= tcg_temp_new_i32();
6155 gen_load_fpr32(ctx
, fp0
, rt
);
6156 tcg_gen_ext_i32_tl(t1
, fp0
);
6157 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
6158 tcg_temp_free_i32(fp0
);
6161 #if defined(TARGET_MIPS64)
6163 check_cp1_enabled(ctx
);
6164 t1
= tcg_temp_new();
6165 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6166 gen_load_fpr64(ctx
, t1
, rt
);
6167 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
6171 check_cp1_enabled(ctx
);
6172 t1
= tcg_temp_new();
6173 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6174 gen_load_fpr64(ctx
, t1
, rt
);
6175 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
6180 MIPS_INVAL("loongson_gsshfs");
6181 generate_exception_end(ctx
, EXCP_RI
);
6186 MIPS_INVAL("loongson_gslsq");
6187 generate_exception_end(ctx
, EXCP_RI
);
6193 /* Loongson EXT LDC2/SDC2 */
6194 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
6197 int offset
= sextract32(ctx
->opcode
, 3, 8);
6198 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
6202 /* Pre-conditions */
6208 /* prefetch, implement as NOP */
6219 #if defined(TARGET_MIPS64)
6222 check_cp1_enabled(ctx
);
6223 /* prefetch, implement as NOP */
6229 #if defined(TARGET_MIPS64)
6232 check_cp1_enabled(ctx
);
6235 MIPS_INVAL("loongson_lsdc2");
6236 generate_exception_end(ctx
, EXCP_RI
);
6241 t0
= tcg_temp_new();
6243 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6244 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6248 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
6249 gen_store_gpr(t0
, rt
);
6252 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
6253 ctx
->default_tcg_memop_mask
);
6254 gen_store_gpr(t0
, rt
);
6257 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6259 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6261 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
6262 ctx
->default_tcg_memop_mask
);
6263 gen_store_gpr(t0
, rt
);
6265 #if defined(TARGET_MIPS64)
6267 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6269 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6271 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
6272 ctx
->default_tcg_memop_mask
);
6273 gen_store_gpr(t0
, rt
);
6277 check_cp1_enabled(ctx
);
6278 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6280 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6282 fp0
= tcg_temp_new_i32();
6283 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
6284 ctx
->default_tcg_memop_mask
);
6285 gen_store_fpr32(ctx
, fp0
, rt
);
6286 tcg_temp_free_i32(fp0
);
6288 #if defined(TARGET_MIPS64)
6290 check_cp1_enabled(ctx
);
6291 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6293 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6295 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
6296 ctx
->default_tcg_memop_mask
);
6297 gen_store_fpr64(ctx
, t0
, rt
);
6301 t1
= tcg_temp_new();
6302 gen_load_gpr(t1
, rt
);
6303 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
6307 t1
= tcg_temp_new();
6308 gen_load_gpr(t1
, rt
);
6309 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
6310 ctx
->default_tcg_memop_mask
);
6314 t1
= tcg_temp_new();
6315 gen_load_gpr(t1
, rt
);
6316 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
6317 ctx
->default_tcg_memop_mask
);
6320 #if defined(TARGET_MIPS64)
6322 t1
= tcg_temp_new();
6323 gen_load_gpr(t1
, rt
);
6324 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6325 ctx
->default_tcg_memop_mask
);
6330 fp0
= tcg_temp_new_i32();
6331 gen_load_fpr32(ctx
, fp0
, rt
);
6332 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
6333 ctx
->default_tcg_memop_mask
);
6334 tcg_temp_free_i32(fp0
);
6336 #if defined(TARGET_MIPS64)
6338 t1
= tcg_temp_new();
6339 gen_load_fpr64(ctx
, t1
, rt
);
6340 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6341 ctx
->default_tcg_memop_mask
);
6353 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
6354 int rs
, int rt
, int16_t imm
)
6357 TCGv t0
= tcg_temp_new();
6358 TCGv t1
= tcg_temp_new();
6361 /* Load needed operands */
6369 /* Compare two registers */
6371 gen_load_gpr(t0
, rs
);
6372 gen_load_gpr(t1
, rt
);
6382 /* Compare register to immediate */
6383 if (rs
!= 0 || imm
!= 0) {
6384 gen_load_gpr(t0
, rs
);
6385 tcg_gen_movi_tl(t1
, (int32_t)imm
);
6392 case OPC_TEQ
: /* rs == rs */
6393 case OPC_TEQI
: /* r0 == 0 */
6394 case OPC_TGE
: /* rs >= rs */
6395 case OPC_TGEI
: /* r0 >= 0 */
6396 case OPC_TGEU
: /* rs >= rs unsigned */
6397 case OPC_TGEIU
: /* r0 >= 0 unsigned */
6399 generate_exception_end(ctx
, EXCP_TRAP
);
6401 case OPC_TLT
: /* rs < rs */
6402 case OPC_TLTI
: /* r0 < 0 */
6403 case OPC_TLTU
: /* rs < rs unsigned */
6404 case OPC_TLTIU
: /* r0 < 0 unsigned */
6405 case OPC_TNE
: /* rs != rs */
6406 case OPC_TNEI
: /* r0 != 0 */
6407 /* Never trap: treat as NOP. */
6411 TCGLabel
*l1
= gen_new_label();
6416 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
6420 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
6424 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
6428 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
6432 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
6436 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
6439 generate_exception(ctx
, EXCP_TRAP
);
6446 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
6448 if (unlikely(ctx
->base
.singlestep_enabled
)) {
6452 #ifndef CONFIG_USER_ONLY
6453 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
6459 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
6461 if (use_goto_tb(ctx
, dest
)) {
6464 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
6467 if (ctx
->base
.singlestep_enabled
) {
6468 save_cpu_state(ctx
, 0);
6469 gen_helper_raise_exception_debug(cpu_env
);
6471 tcg_gen_lookup_and_goto_ptr();
6475 /* Branches (before delay slot) */
6476 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
6478 int rs
, int rt
, int32_t offset
,
6481 target_ulong btgt
= -1;
6483 int bcond_compute
= 0;
6484 TCGv t0
= tcg_temp_new();
6485 TCGv t1
= tcg_temp_new();
6487 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
6488 #ifdef MIPS_DEBUG_DISAS
6489 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6490 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
6492 generate_exception_end(ctx
, EXCP_RI
);
6496 /* Load needed operands */
6502 /* Compare two registers */
6504 gen_load_gpr(t0
, rs
);
6505 gen_load_gpr(t1
, rt
);
6508 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6522 /* Compare to zero */
6524 gen_load_gpr(t0
, rs
);
6527 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6530 #if defined(TARGET_MIPS64)
6532 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
6534 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6537 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6542 /* Jump to immediate */
6543 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
6548 /* Jump to register */
6549 if (offset
!= 0 && offset
!= 16) {
6551 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6552 * others are reserved.
6554 MIPS_INVAL("jump hint");
6555 generate_exception_end(ctx
, EXCP_RI
);
6558 gen_load_gpr(btarget
, rs
);
6561 MIPS_INVAL("branch/jump");
6562 generate_exception_end(ctx
, EXCP_RI
);
6565 if (bcond_compute
== 0) {
6566 /* No condition to be computed */
6568 case OPC_BEQ
: /* rx == rx */
6569 case OPC_BEQL
: /* rx == rx likely */
6570 case OPC_BGEZ
: /* 0 >= 0 */
6571 case OPC_BGEZL
: /* 0 >= 0 likely */
6572 case OPC_BLEZ
: /* 0 <= 0 */
6573 case OPC_BLEZL
: /* 0 <= 0 likely */
6575 ctx
->hflags
|= MIPS_HFLAG_B
;
6577 case OPC_BGEZAL
: /* 0 >= 0 */
6578 case OPC_BGEZALL
: /* 0 >= 0 likely */
6579 /* Always take and link */
6581 ctx
->hflags
|= MIPS_HFLAG_B
;
6583 case OPC_BNE
: /* rx != rx */
6584 case OPC_BGTZ
: /* 0 > 0 */
6585 case OPC_BLTZ
: /* 0 < 0 */
6588 case OPC_BLTZAL
: /* 0 < 0 */
6590 * Handle as an unconditional branch to get correct delay
6594 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6595 ctx
->hflags
|= MIPS_HFLAG_B
;
6597 case OPC_BLTZALL
: /* 0 < 0 likely */
6598 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6599 /* Skip the instruction in the delay slot */
6600 ctx
->base
.pc_next
+= 4;
6602 case OPC_BNEL
: /* rx != rx likely */
6603 case OPC_BGTZL
: /* 0 > 0 likely */
6604 case OPC_BLTZL
: /* 0 < 0 likely */
6605 /* Skip the instruction in the delay slot */
6606 ctx
->base
.pc_next
+= 4;
6609 ctx
->hflags
|= MIPS_HFLAG_B
;
6612 ctx
->hflags
|= MIPS_HFLAG_BX
;
6616 ctx
->hflags
|= MIPS_HFLAG_B
;
6619 ctx
->hflags
|= MIPS_HFLAG_BR
;
6623 ctx
->hflags
|= MIPS_HFLAG_BR
;
6626 MIPS_INVAL("branch/jump");
6627 generate_exception_end(ctx
, EXCP_RI
);
6633 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6636 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6639 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6642 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6645 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6648 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6651 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6655 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6659 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6662 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6665 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6668 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6671 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6674 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6677 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6679 #if defined(TARGET_MIPS64)
6681 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6685 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6688 ctx
->hflags
|= MIPS_HFLAG_BC
;
6691 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6694 ctx
->hflags
|= MIPS_HFLAG_BL
;
6697 MIPS_INVAL("conditional branch/jump");
6698 generate_exception_end(ctx
, EXCP_RI
);
6703 ctx
->btarget
= btgt
;
6705 switch (delayslot_size
) {
6707 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6710 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6715 int post_delay
= insn_bytes
+ delayslot_size
;
6716 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6718 tcg_gen_movi_tl(cpu_gpr
[blink
],
6719 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6723 if (insn_bytes
== 2) {
6724 ctx
->hflags
|= MIPS_HFLAG_B16
;
6731 /* nanoMIPS Branches */
6732 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6734 int rs
, int rt
, int32_t offset
)
6736 target_ulong btgt
= -1;
6737 int bcond_compute
= 0;
6738 TCGv t0
= tcg_temp_new();
6739 TCGv t1
= tcg_temp_new();
6741 /* Load needed operands */
6745 /* Compare two registers */
6747 gen_load_gpr(t0
, rs
);
6748 gen_load_gpr(t1
, rt
);
6751 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6754 /* Compare to zero */
6756 gen_load_gpr(t0
, rs
);
6759 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6762 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6764 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6768 /* Jump to register */
6769 if (offset
!= 0 && offset
!= 16) {
6771 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6772 * others are reserved.
6774 MIPS_INVAL("jump hint");
6775 generate_exception_end(ctx
, EXCP_RI
);
6778 gen_load_gpr(btarget
, rs
);
6781 MIPS_INVAL("branch/jump");
6782 generate_exception_end(ctx
, EXCP_RI
);
6785 if (bcond_compute
== 0) {
6786 /* No condition to be computed */
6788 case OPC_BEQ
: /* rx == rx */
6790 ctx
->hflags
|= MIPS_HFLAG_B
;
6792 case OPC_BGEZAL
: /* 0 >= 0 */
6793 /* Always take and link */
6794 tcg_gen_movi_tl(cpu_gpr
[31],
6795 ctx
->base
.pc_next
+ insn_bytes
);
6796 ctx
->hflags
|= MIPS_HFLAG_B
;
6798 case OPC_BNE
: /* rx != rx */
6799 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6800 /* Skip the instruction in the delay slot */
6801 ctx
->base
.pc_next
+= 4;
6804 ctx
->hflags
|= MIPS_HFLAG_BR
;
6808 tcg_gen_movi_tl(cpu_gpr
[rt
],
6809 ctx
->base
.pc_next
+ insn_bytes
);
6811 ctx
->hflags
|= MIPS_HFLAG_BR
;
6814 MIPS_INVAL("branch/jump");
6815 generate_exception_end(ctx
, EXCP_RI
);
6821 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6824 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6827 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6828 tcg_gen_movi_tl(cpu_gpr
[31],
6829 ctx
->base
.pc_next
+ insn_bytes
);
6832 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6834 ctx
->hflags
|= MIPS_HFLAG_BC
;
6837 MIPS_INVAL("conditional branch/jump");
6838 generate_exception_end(ctx
, EXCP_RI
);
6843 ctx
->btarget
= btgt
;
6846 if (insn_bytes
== 2) {
6847 ctx
->hflags
|= MIPS_HFLAG_B16
;
6854 /* special3 bitfield operations */
6855 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6856 int rs
, int lsb
, int msb
)
6858 TCGv t0
= tcg_temp_new();
6859 TCGv t1
= tcg_temp_new();
6861 gen_load_gpr(t1
, rs
);
6864 if (lsb
+ msb
> 31) {
6868 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6871 * The two checks together imply that lsb == 0,
6872 * so this is a simple sign-extension.
6874 tcg_gen_ext32s_tl(t0
, t1
);
6877 #if defined(TARGET_MIPS64)
6886 if (lsb
+ msb
> 63) {
6889 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6896 gen_load_gpr(t0
, rt
);
6897 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6898 tcg_gen_ext32s_tl(t0
, t0
);
6900 #if defined(TARGET_MIPS64)
6911 gen_load_gpr(t0
, rt
);
6912 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6917 MIPS_INVAL("bitops");
6918 generate_exception_end(ctx
, EXCP_RI
);
6923 gen_store_gpr(t0
, rt
);
6928 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6933 /* If no destination, treat it as a NOP. */
6937 t0
= tcg_temp_new();
6938 gen_load_gpr(t0
, rt
);
6942 TCGv t1
= tcg_temp_new();
6943 TCGv t2
= tcg_const_tl(0x00FF00FF);
6945 tcg_gen_shri_tl(t1
, t0
, 8);
6946 tcg_gen_and_tl(t1
, t1
, t2
);
6947 tcg_gen_and_tl(t0
, t0
, t2
);
6948 tcg_gen_shli_tl(t0
, t0
, 8);
6949 tcg_gen_or_tl(t0
, t0
, t1
);
6952 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6956 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6959 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6961 #if defined(TARGET_MIPS64)
6964 TCGv t1
= tcg_temp_new();
6965 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6967 tcg_gen_shri_tl(t1
, t0
, 8);
6968 tcg_gen_and_tl(t1
, t1
, t2
);
6969 tcg_gen_and_tl(t0
, t0
, t2
);
6970 tcg_gen_shli_tl(t0
, t0
, 8);
6971 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6978 TCGv t1
= tcg_temp_new();
6979 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6981 tcg_gen_shri_tl(t1
, t0
, 16);
6982 tcg_gen_and_tl(t1
, t1
, t2
);
6983 tcg_gen_and_tl(t0
, t0
, t2
);
6984 tcg_gen_shli_tl(t0
, t0
, 16);
6985 tcg_gen_or_tl(t0
, t0
, t1
);
6986 tcg_gen_shri_tl(t1
, t0
, 32);
6987 tcg_gen_shli_tl(t0
, t0
, 32);
6988 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6995 MIPS_INVAL("bsfhl");
6996 generate_exception_end(ctx
, EXCP_RI
);
7003 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
7012 t0
= tcg_temp_new();
7013 t1
= tcg_temp_new();
7014 gen_load_gpr(t0
, rs
);
7015 gen_load_gpr(t1
, rt
);
7016 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
7017 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
7018 if (opc
== OPC_LSA
) {
7019 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
7028 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
7036 t0
= tcg_temp_new();
7037 if (bits
== 0 || bits
== wordsz
) {
7039 gen_load_gpr(t0
, rt
);
7041 gen_load_gpr(t0
, rs
);
7045 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
7047 #if defined(TARGET_MIPS64)
7049 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
7054 TCGv t1
= tcg_temp_new();
7055 gen_load_gpr(t0
, rt
);
7056 gen_load_gpr(t1
, rs
);
7060 TCGv_i64 t2
= tcg_temp_new_i64();
7061 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
7062 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
7063 gen_move_low32(cpu_gpr
[rd
], t2
);
7064 tcg_temp_free_i64(t2
);
7067 #if defined(TARGET_MIPS64)
7069 tcg_gen_shli_tl(t0
, t0
, bits
);
7070 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
7071 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
7081 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
7084 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
7087 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
7090 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
7093 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
7100 t0
= tcg_temp_new();
7101 gen_load_gpr(t0
, rt
);
7104 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
7106 #if defined(TARGET_MIPS64)
7108 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
7115 #ifndef CONFIG_USER_ONLY
7116 /* CP0 (MMU and control) */
7117 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
7119 TCGv_i64 t0
= tcg_temp_new_i64();
7120 TCGv_i64 t1
= tcg_temp_new_i64();
7122 tcg_gen_ext_tl_i64(t0
, arg
);
7123 tcg_gen_ld_i64(t1
, cpu_env
, off
);
7124 #if defined(TARGET_MIPS64)
7125 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
7127 tcg_gen_concat32_i64(t1
, t1
, t0
);
7129 tcg_gen_st_i64(t1
, cpu_env
, off
);
7130 tcg_temp_free_i64(t1
);
7131 tcg_temp_free_i64(t0
);
7134 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
7136 TCGv_i64 t0
= tcg_temp_new_i64();
7137 TCGv_i64 t1
= tcg_temp_new_i64();
7139 tcg_gen_ext_tl_i64(t0
, arg
);
7140 tcg_gen_ld_i64(t1
, cpu_env
, off
);
7141 tcg_gen_concat32_i64(t1
, t1
, t0
);
7142 tcg_gen_st_i64(t1
, cpu_env
, off
);
7143 tcg_temp_free_i64(t1
);
7144 tcg_temp_free_i64(t0
);
7147 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
7149 TCGv_i64 t0
= tcg_temp_new_i64();
7151 tcg_gen_ld_i64(t0
, cpu_env
, off
);
7152 #if defined(TARGET_MIPS64)
7153 tcg_gen_shri_i64(t0
, t0
, 30);
7155 tcg_gen_shri_i64(t0
, t0
, 32);
7157 gen_move_low32(arg
, t0
);
7158 tcg_temp_free_i64(t0
);
7161 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
7163 TCGv_i64 t0
= tcg_temp_new_i64();
7165 tcg_gen_ld_i64(t0
, cpu_env
, off
);
7166 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
7167 gen_move_low32(arg
, t0
);
7168 tcg_temp_free_i64(t0
);
7171 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
7173 TCGv_i32 t0
= tcg_temp_new_i32();
7175 tcg_gen_ld_i32(t0
, cpu_env
, off
);
7176 tcg_gen_ext_i32_tl(arg
, t0
);
7177 tcg_temp_free_i32(t0
);
7180 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
7182 tcg_gen_ld_tl(arg
, cpu_env
, off
);
7183 tcg_gen_ext32s_tl(arg
, arg
);
7186 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
7188 TCGv_i32 t0
= tcg_temp_new_i32();
7190 tcg_gen_trunc_tl_i32(t0
, arg
);
7191 tcg_gen_st_i32(t0
, cpu_env
, off
);
7192 tcg_temp_free_i32(t0
);
7195 #define CP0_CHECK(c) \
7198 goto cp0_unimplemented; \
7202 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7204 const char *register_name
= "invalid";
7207 case CP0_REGISTER_02
:
7210 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7211 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
7212 register_name
= "EntryLo0";
7215 goto cp0_unimplemented
;
7218 case CP0_REGISTER_03
:
7220 case CP0_REG03__ENTRYLO1
:
7221 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7222 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7223 register_name
= "EntryLo1";
7226 goto cp0_unimplemented
;
7229 case CP0_REGISTER_09
:
7231 case CP0_REG09__SAAR
:
7232 CP0_CHECK(ctx
->saar
);
7233 gen_helper_mfhc0_saar(arg
, cpu_env
);
7234 register_name
= "SAAR";
7237 goto cp0_unimplemented
;
7240 case CP0_REGISTER_17
:
7242 case CP0_REG17__LLADDR
:
7243 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
7244 ctx
->CP0_LLAddr_shift
);
7245 register_name
= "LLAddr";
7247 case CP0_REG17__MAAR
:
7248 CP0_CHECK(ctx
->mrp
);
7249 gen_helper_mfhc0_maar(arg
, cpu_env
);
7250 register_name
= "MAAR";
7253 goto cp0_unimplemented
;
7256 case CP0_REGISTER_19
:
7258 case CP0_REG19__WATCHHI0
:
7259 case CP0_REG19__WATCHHI1
:
7260 case CP0_REG19__WATCHHI2
:
7261 case CP0_REG19__WATCHHI3
:
7262 case CP0_REG19__WATCHHI4
:
7263 case CP0_REG19__WATCHHI5
:
7264 case CP0_REG19__WATCHHI6
:
7265 case CP0_REG19__WATCHHI7
:
7266 /* upper 32 bits are only available when Config5MI != 0 */
7268 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
7269 register_name
= "WatchHi";
7272 goto cp0_unimplemented
;
7275 case CP0_REGISTER_28
:
7281 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
7282 register_name
= "TagLo";
7285 goto cp0_unimplemented
;
7289 goto cp0_unimplemented
;
7291 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
7295 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
7296 register_name
, reg
, sel
);
7297 tcg_gen_movi_tl(arg
, 0);
7300 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7302 const char *register_name
= "invalid";
7303 uint64_t mask
= ctx
->PAMask
>> 36;
7306 case CP0_REGISTER_02
:
7309 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7310 tcg_gen_andi_tl(arg
, arg
, mask
);
7311 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
7312 register_name
= "EntryLo0";
7315 goto cp0_unimplemented
;
7318 case CP0_REGISTER_03
:
7320 case CP0_REG03__ENTRYLO1
:
7321 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7322 tcg_gen_andi_tl(arg
, arg
, mask
);
7323 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7324 register_name
= "EntryLo1";
7327 goto cp0_unimplemented
;
7330 case CP0_REGISTER_09
:
7332 case CP0_REG09__SAAR
:
7333 CP0_CHECK(ctx
->saar
);
7334 gen_helper_mthc0_saar(cpu_env
, arg
);
7335 register_name
= "SAAR";
7338 goto cp0_unimplemented
;
7341 case CP0_REGISTER_17
:
7343 case CP0_REG17__LLADDR
:
7345 * LLAddr is read-only (the only exception is bit 0 if LLB is
7346 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
7347 * relevant for modern MIPS cores supporting MTHC0, therefore
7348 * treating MTHC0 to LLAddr as NOP.
7350 register_name
= "LLAddr";
7352 case CP0_REG17__MAAR
:
7353 CP0_CHECK(ctx
->mrp
);
7354 gen_helper_mthc0_maar(cpu_env
, arg
);
7355 register_name
= "MAAR";
7358 goto cp0_unimplemented
;
7361 case CP0_REGISTER_19
:
7363 case CP0_REG19__WATCHHI0
:
7364 case CP0_REG19__WATCHHI1
:
7365 case CP0_REG19__WATCHHI2
:
7366 case CP0_REG19__WATCHHI3
:
7367 case CP0_REG19__WATCHHI4
:
7368 case CP0_REG19__WATCHHI5
:
7369 case CP0_REG19__WATCHHI6
:
7370 case CP0_REG19__WATCHHI7
:
7371 /* upper 32 bits are only available when Config5MI != 0 */
7373 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
7374 register_name
= "WatchHi";
7377 goto cp0_unimplemented
;
7380 case CP0_REGISTER_28
:
7386 tcg_gen_andi_tl(arg
, arg
, mask
);
7387 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
7388 register_name
= "TagLo";
7391 goto cp0_unimplemented
;
7395 goto cp0_unimplemented
;
7397 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
7400 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
7401 register_name
, reg
, sel
);
7404 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
7406 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
7407 tcg_gen_movi_tl(arg
, 0);
7409 tcg_gen_movi_tl(arg
, ~0);
7413 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7415 const char *register_name
= "invalid";
7418 check_insn(ctx
, ISA_MIPS32
);
7422 case CP0_REGISTER_00
:
7424 case CP0_REG00__INDEX
:
7425 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7426 register_name
= "Index";
7428 case CP0_REG00__MVPCONTROL
:
7429 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7430 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7431 register_name
= "MVPControl";
7433 case CP0_REG00__MVPCONF0
:
7434 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7435 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7436 register_name
= "MVPConf0";
7438 case CP0_REG00__MVPCONF1
:
7439 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7440 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7441 register_name
= "MVPConf1";
7443 case CP0_REG00__VPCONTROL
:
7445 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7446 register_name
= "VPControl";
7449 goto cp0_unimplemented
;
7452 case CP0_REGISTER_01
:
7454 case CP0_REG01__RANDOM
:
7455 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7456 gen_helper_mfc0_random(arg
, cpu_env
);
7457 register_name
= "Random";
7459 case CP0_REG01__VPECONTROL
:
7460 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7461 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7462 register_name
= "VPEControl";
7464 case CP0_REG01__VPECONF0
:
7465 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7466 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7467 register_name
= "VPEConf0";
7469 case CP0_REG01__VPECONF1
:
7470 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7471 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7472 register_name
= "VPEConf1";
7474 case CP0_REG01__YQMASK
:
7475 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7476 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
7477 register_name
= "YQMask";
7479 case CP0_REG01__VPESCHEDULE
:
7480 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7481 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7482 register_name
= "VPESchedule";
7484 case CP0_REG01__VPESCHEFBACK
:
7485 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7486 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7487 register_name
= "VPEScheFBack";
7489 case CP0_REG01__VPEOPT
:
7490 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7491 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7492 register_name
= "VPEOpt";
7495 goto cp0_unimplemented
;
7498 case CP0_REGISTER_02
:
7500 case CP0_REG02__ENTRYLO0
:
7502 TCGv_i64 tmp
= tcg_temp_new_i64();
7503 tcg_gen_ld_i64(tmp
, cpu_env
,
7504 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7505 #if defined(TARGET_MIPS64)
7507 /* Move RI/XI fields to bits 31:30 */
7508 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7509 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7512 gen_move_low32(arg
, tmp
);
7513 tcg_temp_free_i64(tmp
);
7515 register_name
= "EntryLo0";
7517 case CP0_REG02__TCSTATUS
:
7518 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7519 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7520 register_name
= "TCStatus";
7522 case CP0_REG02__TCBIND
:
7523 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7524 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7525 register_name
= "TCBind";
7527 case CP0_REG02__TCRESTART
:
7528 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7529 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
7530 register_name
= "TCRestart";
7532 case CP0_REG02__TCHALT
:
7533 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7534 gen_helper_mfc0_tchalt(arg
, cpu_env
);
7535 register_name
= "TCHalt";
7537 case CP0_REG02__TCCONTEXT
:
7538 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7539 gen_helper_mfc0_tccontext(arg
, cpu_env
);
7540 register_name
= "TCContext";
7542 case CP0_REG02__TCSCHEDULE
:
7543 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7544 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
7545 register_name
= "TCSchedule";
7547 case CP0_REG02__TCSCHEFBACK
:
7548 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7549 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
7550 register_name
= "TCScheFBack";
7553 goto cp0_unimplemented
;
7556 case CP0_REGISTER_03
:
7558 case CP0_REG03__ENTRYLO1
:
7560 TCGv_i64 tmp
= tcg_temp_new_i64();
7561 tcg_gen_ld_i64(tmp
, cpu_env
,
7562 offsetof(CPUMIPSState
, CP0_EntryLo1
));
7563 #if defined(TARGET_MIPS64)
7565 /* Move RI/XI fields to bits 31:30 */
7566 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7567 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7570 gen_move_low32(arg
, tmp
);
7571 tcg_temp_free_i64(tmp
);
7573 register_name
= "EntryLo1";
7575 case CP0_REG03__GLOBALNUM
:
7577 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7578 register_name
= "GlobalNumber";
7581 goto cp0_unimplemented
;
7584 case CP0_REGISTER_04
:
7586 case CP0_REG04__CONTEXT
:
7587 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7588 tcg_gen_ext32s_tl(arg
, arg
);
7589 register_name
= "Context";
7591 case CP0_REG04__CONTEXTCONFIG
:
7593 /* gen_helper_mfc0_contextconfig(arg); */
7594 register_name
= "ContextConfig";
7595 goto cp0_unimplemented
;
7596 case CP0_REG04__USERLOCAL
:
7597 CP0_CHECK(ctx
->ulri
);
7598 tcg_gen_ld_tl(arg
, cpu_env
,
7599 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7600 tcg_gen_ext32s_tl(arg
, arg
);
7601 register_name
= "UserLocal";
7603 case CP0_REG04__MMID
:
7605 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7606 register_name
= "MMID";
7609 goto cp0_unimplemented
;
7612 case CP0_REGISTER_05
:
7614 case CP0_REG05__PAGEMASK
:
7615 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7616 register_name
= "PageMask";
7618 case CP0_REG05__PAGEGRAIN
:
7619 check_insn(ctx
, ISA_MIPS32R2
);
7620 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7621 register_name
= "PageGrain";
7623 case CP0_REG05__SEGCTL0
:
7625 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7626 tcg_gen_ext32s_tl(arg
, arg
);
7627 register_name
= "SegCtl0";
7629 case CP0_REG05__SEGCTL1
:
7631 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7632 tcg_gen_ext32s_tl(arg
, arg
);
7633 register_name
= "SegCtl1";
7635 case CP0_REG05__SEGCTL2
:
7637 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7638 tcg_gen_ext32s_tl(arg
, arg
);
7639 register_name
= "SegCtl2";
7641 case CP0_REG05__PWBASE
:
7643 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7644 register_name
= "PWBase";
7646 case CP0_REG05__PWFIELD
:
7648 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7649 register_name
= "PWField";
7651 case CP0_REG05__PWSIZE
:
7653 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7654 register_name
= "PWSize";
7657 goto cp0_unimplemented
;
7660 case CP0_REGISTER_06
:
7662 case CP0_REG06__WIRED
:
7663 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7664 register_name
= "Wired";
7666 case CP0_REG06__SRSCONF0
:
7667 check_insn(ctx
, ISA_MIPS32R2
);
7668 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7669 register_name
= "SRSConf0";
7671 case CP0_REG06__SRSCONF1
:
7672 check_insn(ctx
, ISA_MIPS32R2
);
7673 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7674 register_name
= "SRSConf1";
7676 case CP0_REG06__SRSCONF2
:
7677 check_insn(ctx
, ISA_MIPS32R2
);
7678 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7679 register_name
= "SRSConf2";
7681 case CP0_REG06__SRSCONF3
:
7682 check_insn(ctx
, ISA_MIPS32R2
);
7683 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7684 register_name
= "SRSConf3";
7686 case CP0_REG06__SRSCONF4
:
7687 check_insn(ctx
, ISA_MIPS32R2
);
7688 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7689 register_name
= "SRSConf4";
7691 case CP0_REG06__PWCTL
:
7693 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7694 register_name
= "PWCtl";
7697 goto cp0_unimplemented
;
7700 case CP0_REGISTER_07
:
7702 case CP0_REG07__HWRENA
:
7703 check_insn(ctx
, ISA_MIPS32R2
);
7704 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7705 register_name
= "HWREna";
7708 goto cp0_unimplemented
;
7711 case CP0_REGISTER_08
:
7713 case CP0_REG08__BADVADDR
:
7714 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7715 tcg_gen_ext32s_tl(arg
, arg
);
7716 register_name
= "BadVAddr";
7718 case CP0_REG08__BADINSTR
:
7720 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7721 register_name
= "BadInstr";
7723 case CP0_REG08__BADINSTRP
:
7725 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7726 register_name
= "BadInstrP";
7728 case CP0_REG08__BADINSTRX
:
7730 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7731 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7732 register_name
= "BadInstrX";
7735 goto cp0_unimplemented
;
7738 case CP0_REGISTER_09
:
7740 case CP0_REG09__COUNT
:
7741 /* Mark as an IO operation because we read the time. */
7742 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7745 gen_helper_mfc0_count(arg
, cpu_env
);
7747 * Break the TB to be able to take timer interrupts immediately
7748 * after reading count. DISAS_STOP isn't sufficient, we need to
7749 * ensure we break completely out of translated code.
7751 gen_save_pc(ctx
->base
.pc_next
+ 4);
7752 ctx
->base
.is_jmp
= DISAS_EXIT
;
7753 register_name
= "Count";
7755 case CP0_REG09__SAARI
:
7756 CP0_CHECK(ctx
->saar
);
7757 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7758 register_name
= "SAARI";
7760 case CP0_REG09__SAAR
:
7761 CP0_CHECK(ctx
->saar
);
7762 gen_helper_mfc0_saar(arg
, cpu_env
);
7763 register_name
= "SAAR";
7766 goto cp0_unimplemented
;
7769 case CP0_REGISTER_10
:
7771 case CP0_REG10__ENTRYHI
:
7772 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7773 tcg_gen_ext32s_tl(arg
, arg
);
7774 register_name
= "EntryHi";
7777 goto cp0_unimplemented
;
7780 case CP0_REGISTER_11
:
7782 case CP0_REG11__COMPARE
:
7783 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7784 register_name
= "Compare";
7786 /* 6,7 are implementation dependent */
7788 goto cp0_unimplemented
;
7791 case CP0_REGISTER_12
:
7793 case CP0_REG12__STATUS
:
7794 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7795 register_name
= "Status";
7797 case CP0_REG12__INTCTL
:
7798 check_insn(ctx
, ISA_MIPS32R2
);
7799 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7800 register_name
= "IntCtl";
7802 case CP0_REG12__SRSCTL
:
7803 check_insn(ctx
, ISA_MIPS32R2
);
7804 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7805 register_name
= "SRSCtl";
7807 case CP0_REG12__SRSMAP
:
7808 check_insn(ctx
, ISA_MIPS32R2
);
7809 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7810 register_name
= "SRSMap";
7813 goto cp0_unimplemented
;
7816 case CP0_REGISTER_13
:
7818 case CP0_REG13__CAUSE
:
7819 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7820 register_name
= "Cause";
7823 goto cp0_unimplemented
;
7826 case CP0_REGISTER_14
:
7828 case CP0_REG14__EPC
:
7829 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7830 tcg_gen_ext32s_tl(arg
, arg
);
7831 register_name
= "EPC";
7834 goto cp0_unimplemented
;
7837 case CP0_REGISTER_15
:
7839 case CP0_REG15__PRID
:
7840 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7841 register_name
= "PRid";
7843 case CP0_REG15__EBASE
:
7844 check_insn(ctx
, ISA_MIPS32R2
);
7845 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7846 tcg_gen_ext32s_tl(arg
, arg
);
7847 register_name
= "EBase";
7849 case CP0_REG15__CMGCRBASE
:
7850 check_insn(ctx
, ISA_MIPS32R2
);
7851 CP0_CHECK(ctx
->cmgcr
);
7852 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7853 tcg_gen_ext32s_tl(arg
, arg
);
7854 register_name
= "CMGCRBase";
7857 goto cp0_unimplemented
;
7860 case CP0_REGISTER_16
:
7862 case CP0_REG16__CONFIG
:
7863 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7864 register_name
= "Config";
7866 case CP0_REG16__CONFIG1
:
7867 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7868 register_name
= "Config1";
7870 case CP0_REG16__CONFIG2
:
7871 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7872 register_name
= "Config2";
7874 case CP0_REG16__CONFIG3
:
7875 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7876 register_name
= "Config3";
7878 case CP0_REG16__CONFIG4
:
7879 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7880 register_name
= "Config4";
7882 case CP0_REG16__CONFIG5
:
7883 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7884 register_name
= "Config5";
7886 /* 6,7 are implementation dependent */
7887 case CP0_REG16__CONFIG6
:
7888 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7889 register_name
= "Config6";
7891 case CP0_REG16__CONFIG7
:
7892 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7893 register_name
= "Config7";
7896 goto cp0_unimplemented
;
7899 case CP0_REGISTER_17
:
7901 case CP0_REG17__LLADDR
:
7902 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7903 register_name
= "LLAddr";
7905 case CP0_REG17__MAAR
:
7906 CP0_CHECK(ctx
->mrp
);
7907 gen_helper_mfc0_maar(arg
, cpu_env
);
7908 register_name
= "MAAR";
7910 case CP0_REG17__MAARI
:
7911 CP0_CHECK(ctx
->mrp
);
7912 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7913 register_name
= "MAARI";
7916 goto cp0_unimplemented
;
7919 case CP0_REGISTER_18
:
7921 case CP0_REG18__WATCHLO0
:
7922 case CP0_REG18__WATCHLO1
:
7923 case CP0_REG18__WATCHLO2
:
7924 case CP0_REG18__WATCHLO3
:
7925 case CP0_REG18__WATCHLO4
:
7926 case CP0_REG18__WATCHLO5
:
7927 case CP0_REG18__WATCHLO6
:
7928 case CP0_REG18__WATCHLO7
:
7929 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7930 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7931 register_name
= "WatchLo";
7934 goto cp0_unimplemented
;
7937 case CP0_REGISTER_19
:
7939 case CP0_REG19__WATCHHI0
:
7940 case CP0_REG19__WATCHHI1
:
7941 case CP0_REG19__WATCHHI2
:
7942 case CP0_REG19__WATCHHI3
:
7943 case CP0_REG19__WATCHHI4
:
7944 case CP0_REG19__WATCHHI5
:
7945 case CP0_REG19__WATCHHI6
:
7946 case CP0_REG19__WATCHHI7
:
7947 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7948 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7949 register_name
= "WatchHi";
7952 goto cp0_unimplemented
;
7955 case CP0_REGISTER_20
:
7957 case CP0_REG20__XCONTEXT
:
7958 #if defined(TARGET_MIPS64)
7959 check_insn(ctx
, ISA_MIPS3
);
7960 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7961 tcg_gen_ext32s_tl(arg
, arg
);
7962 register_name
= "XContext";
7966 goto cp0_unimplemented
;
7969 case CP0_REGISTER_21
:
7970 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7971 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7974 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7975 register_name
= "Framemask";
7978 goto cp0_unimplemented
;
7981 case CP0_REGISTER_22
:
7982 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7983 register_name
= "'Diagnostic"; /* implementation dependent */
7985 case CP0_REGISTER_23
:
7987 case CP0_REG23__DEBUG
:
7988 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7989 register_name
= "Debug";
7991 case CP0_REG23__TRACECONTROL
:
7992 /* PDtrace support */
7993 /* gen_helper_mfc0_tracecontrol(arg); */
7994 register_name
= "TraceControl";
7995 goto cp0_unimplemented
;
7996 case CP0_REG23__TRACECONTROL2
:
7997 /* PDtrace support */
7998 /* gen_helper_mfc0_tracecontrol2(arg); */
7999 register_name
= "TraceControl2";
8000 goto cp0_unimplemented
;
8001 case CP0_REG23__USERTRACEDATA1
:
8002 /* PDtrace support */
8003 /* gen_helper_mfc0_usertracedata1(arg);*/
8004 register_name
= "UserTraceData1";
8005 goto cp0_unimplemented
;
8006 case CP0_REG23__TRACEIBPC
:
8007 /* PDtrace support */
8008 /* gen_helper_mfc0_traceibpc(arg); */
8009 register_name
= "TraceIBPC";
8010 goto cp0_unimplemented
;
8011 case CP0_REG23__TRACEDBPC
:
8012 /* PDtrace support */
8013 /* gen_helper_mfc0_tracedbpc(arg); */
8014 register_name
= "TraceDBPC";
8015 goto cp0_unimplemented
;
8017 goto cp0_unimplemented
;
8020 case CP0_REGISTER_24
:
8022 case CP0_REG24__DEPC
:
8024 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8025 tcg_gen_ext32s_tl(arg
, arg
);
8026 register_name
= "DEPC";
8029 goto cp0_unimplemented
;
8032 case CP0_REGISTER_25
:
8034 case CP0_REG25__PERFCTL0
:
8035 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8036 register_name
= "Performance0";
8038 case CP0_REG25__PERFCNT0
:
8039 /* gen_helper_mfc0_performance1(arg); */
8040 register_name
= "Performance1";
8041 goto cp0_unimplemented
;
8042 case CP0_REG25__PERFCTL1
:
8043 /* gen_helper_mfc0_performance2(arg); */
8044 register_name
= "Performance2";
8045 goto cp0_unimplemented
;
8046 case CP0_REG25__PERFCNT1
:
8047 /* gen_helper_mfc0_performance3(arg); */
8048 register_name
= "Performance3";
8049 goto cp0_unimplemented
;
8050 case CP0_REG25__PERFCTL2
:
8051 /* gen_helper_mfc0_performance4(arg); */
8052 register_name
= "Performance4";
8053 goto cp0_unimplemented
;
8054 case CP0_REG25__PERFCNT2
:
8055 /* gen_helper_mfc0_performance5(arg); */
8056 register_name
= "Performance5";
8057 goto cp0_unimplemented
;
8058 case CP0_REG25__PERFCTL3
:
8059 /* gen_helper_mfc0_performance6(arg); */
8060 register_name
= "Performance6";
8061 goto cp0_unimplemented
;
8062 case CP0_REG25__PERFCNT3
:
8063 /* gen_helper_mfc0_performance7(arg); */
8064 register_name
= "Performance7";
8065 goto cp0_unimplemented
;
8067 goto cp0_unimplemented
;
8070 case CP0_REGISTER_26
:
8072 case CP0_REG26__ERRCTL
:
8073 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8074 register_name
= "ErrCtl";
8077 goto cp0_unimplemented
;
8080 case CP0_REGISTER_27
:
8082 case CP0_REG27__CACHERR
:
8083 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8084 register_name
= "CacheErr";
8087 goto cp0_unimplemented
;
8090 case CP0_REGISTER_28
:
8092 case CP0_REG28__TAGLO
:
8093 case CP0_REG28__TAGLO1
:
8094 case CP0_REG28__TAGLO2
:
8095 case CP0_REG28__TAGLO3
:
8097 TCGv_i64 tmp
= tcg_temp_new_i64();
8098 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
8099 gen_move_low32(arg
, tmp
);
8100 tcg_temp_free_i64(tmp
);
8102 register_name
= "TagLo";
8104 case CP0_REG28__DATALO
:
8105 case CP0_REG28__DATALO1
:
8106 case CP0_REG28__DATALO2
:
8107 case CP0_REG28__DATALO3
:
8108 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8109 register_name
= "DataLo";
8112 goto cp0_unimplemented
;
8115 case CP0_REGISTER_29
:
8117 case CP0_REG29__TAGHI
:
8118 case CP0_REG29__TAGHI1
:
8119 case CP0_REG29__TAGHI2
:
8120 case CP0_REG29__TAGHI3
:
8121 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8122 register_name
= "TagHi";
8124 case CP0_REG29__DATAHI
:
8125 case CP0_REG29__DATAHI1
:
8126 case CP0_REG29__DATAHI2
:
8127 case CP0_REG29__DATAHI3
:
8128 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8129 register_name
= "DataHi";
8132 goto cp0_unimplemented
;
8135 case CP0_REGISTER_30
:
8137 case CP0_REG30__ERROREPC
:
8138 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8139 tcg_gen_ext32s_tl(arg
, arg
);
8140 register_name
= "ErrorEPC";
8143 goto cp0_unimplemented
;
8146 case CP0_REGISTER_31
:
8148 case CP0_REG31__DESAVE
:
8150 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8151 register_name
= "DESAVE";
8153 case CP0_REG31__KSCRATCH1
:
8154 case CP0_REG31__KSCRATCH2
:
8155 case CP0_REG31__KSCRATCH3
:
8156 case CP0_REG31__KSCRATCH4
:
8157 case CP0_REG31__KSCRATCH5
:
8158 case CP0_REG31__KSCRATCH6
:
8159 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8160 tcg_gen_ld_tl(arg
, cpu_env
,
8161 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8162 tcg_gen_ext32s_tl(arg
, arg
);
8163 register_name
= "KScratch";
8166 goto cp0_unimplemented
;
8170 goto cp0_unimplemented
;
8172 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
8176 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
8177 register_name
, reg
, sel
);
8178 gen_mfc0_unimplemented(ctx
, arg
);
8181 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8183 const char *register_name
= "invalid";
8186 check_insn(ctx
, ISA_MIPS32
);
8189 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8194 case CP0_REGISTER_00
:
8196 case CP0_REG00__INDEX
:
8197 gen_helper_mtc0_index(cpu_env
, arg
);
8198 register_name
= "Index";
8200 case CP0_REG00__MVPCONTROL
:
8201 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8202 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8203 register_name
= "MVPControl";
8205 case CP0_REG00__MVPCONF0
:
8206 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8208 register_name
= "MVPConf0";
8210 case CP0_REG00__MVPCONF1
:
8211 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8213 register_name
= "MVPConf1";
8215 case CP0_REG00__VPCONTROL
:
8218 register_name
= "VPControl";
8221 goto cp0_unimplemented
;
8224 case CP0_REGISTER_01
:
8226 case CP0_REG01__RANDOM
:
8228 register_name
= "Random";
8230 case CP0_REG01__VPECONTROL
:
8231 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8232 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8233 register_name
= "VPEControl";
8235 case CP0_REG01__VPECONF0
:
8236 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8237 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8238 register_name
= "VPEConf0";
8240 case CP0_REG01__VPECONF1
:
8241 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8242 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8243 register_name
= "VPEConf1";
8245 case CP0_REG01__YQMASK
:
8246 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8247 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8248 register_name
= "YQMask";
8250 case CP0_REG01__VPESCHEDULE
:
8251 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8252 tcg_gen_st_tl(arg
, cpu_env
,
8253 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8254 register_name
= "VPESchedule";
8256 case CP0_REG01__VPESCHEFBACK
:
8257 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8258 tcg_gen_st_tl(arg
, cpu_env
,
8259 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8260 register_name
= "VPEScheFBack";
8262 case CP0_REG01__VPEOPT
:
8263 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8264 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8265 register_name
= "VPEOpt";
8268 goto cp0_unimplemented
;
8271 case CP0_REGISTER_02
:
8273 case CP0_REG02__ENTRYLO0
:
8274 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
8275 register_name
= "EntryLo0";
8277 case CP0_REG02__TCSTATUS
:
8278 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8279 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8280 register_name
= "TCStatus";
8282 case CP0_REG02__TCBIND
:
8283 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8284 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8285 register_name
= "TCBind";
8287 case CP0_REG02__TCRESTART
:
8288 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8289 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8290 register_name
= "TCRestart";
8292 case CP0_REG02__TCHALT
:
8293 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8294 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8295 register_name
= "TCHalt";
8297 case CP0_REG02__TCCONTEXT
:
8298 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8299 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8300 register_name
= "TCContext";
8302 case CP0_REG02__TCSCHEDULE
:
8303 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8304 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8305 register_name
= "TCSchedule";
8307 case CP0_REG02__TCSCHEFBACK
:
8308 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8309 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8310 register_name
= "TCScheFBack";
8313 goto cp0_unimplemented
;
8316 case CP0_REGISTER_03
:
8318 case CP0_REG03__ENTRYLO1
:
8319 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
8320 register_name
= "EntryLo1";
8322 case CP0_REG03__GLOBALNUM
:
8325 register_name
= "GlobalNumber";
8328 goto cp0_unimplemented
;
8331 case CP0_REGISTER_04
:
8333 case CP0_REG04__CONTEXT
:
8334 gen_helper_mtc0_context(cpu_env
, arg
);
8335 register_name
= "Context";
8337 case CP0_REG04__CONTEXTCONFIG
:
8339 /* gen_helper_mtc0_contextconfig(arg); */
8340 register_name
= "ContextConfig";
8341 goto cp0_unimplemented
;
8342 case CP0_REG04__USERLOCAL
:
8343 CP0_CHECK(ctx
->ulri
);
8344 tcg_gen_st_tl(arg
, cpu_env
,
8345 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8346 register_name
= "UserLocal";
8348 case CP0_REG04__MMID
:
8350 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8351 register_name
= "MMID";
8354 goto cp0_unimplemented
;
8357 case CP0_REGISTER_05
:
8359 case CP0_REG05__PAGEMASK
:
8360 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8361 register_name
= "PageMask";
8363 case CP0_REG05__PAGEGRAIN
:
8364 check_insn(ctx
, ISA_MIPS32R2
);
8365 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8366 register_name
= "PageGrain";
8367 ctx
->base
.is_jmp
= DISAS_STOP
;
8369 case CP0_REG05__SEGCTL0
:
8371 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8372 register_name
= "SegCtl0";
8374 case CP0_REG05__SEGCTL1
:
8376 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8377 register_name
= "SegCtl1";
8379 case CP0_REG05__SEGCTL2
:
8381 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8382 register_name
= "SegCtl2";
8384 case CP0_REG05__PWBASE
:
8386 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
8387 register_name
= "PWBase";
8389 case CP0_REG05__PWFIELD
:
8391 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8392 register_name
= "PWField";
8394 case CP0_REG05__PWSIZE
:
8396 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8397 register_name
= "PWSize";
8400 goto cp0_unimplemented
;
8403 case CP0_REGISTER_06
:
8405 case CP0_REG06__WIRED
:
8406 gen_helper_mtc0_wired(cpu_env
, arg
);
8407 register_name
= "Wired";
8409 case CP0_REG06__SRSCONF0
:
8410 check_insn(ctx
, ISA_MIPS32R2
);
8411 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8412 register_name
= "SRSConf0";
8414 case CP0_REG06__SRSCONF1
:
8415 check_insn(ctx
, ISA_MIPS32R2
);
8416 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8417 register_name
= "SRSConf1";
8419 case CP0_REG06__SRSCONF2
:
8420 check_insn(ctx
, ISA_MIPS32R2
);
8421 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8422 register_name
= "SRSConf2";
8424 case CP0_REG06__SRSCONF3
:
8425 check_insn(ctx
, ISA_MIPS32R2
);
8426 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8427 register_name
= "SRSConf3";
8429 case CP0_REG06__SRSCONF4
:
8430 check_insn(ctx
, ISA_MIPS32R2
);
8431 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8432 register_name
= "SRSConf4";
8434 case CP0_REG06__PWCTL
:
8436 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8437 register_name
= "PWCtl";
8440 goto cp0_unimplemented
;
8443 case CP0_REGISTER_07
:
8445 case CP0_REG07__HWRENA
:
8446 check_insn(ctx
, ISA_MIPS32R2
);
8447 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8448 ctx
->base
.is_jmp
= DISAS_STOP
;
8449 register_name
= "HWREna";
8452 goto cp0_unimplemented
;
8455 case CP0_REGISTER_08
:
8457 case CP0_REG08__BADVADDR
:
8459 register_name
= "BadVAddr";
8461 case CP0_REG08__BADINSTR
:
8463 register_name
= "BadInstr";
8465 case CP0_REG08__BADINSTRP
:
8467 register_name
= "BadInstrP";
8469 case CP0_REG08__BADINSTRX
:
8471 register_name
= "BadInstrX";
8474 goto cp0_unimplemented
;
8477 case CP0_REGISTER_09
:
8479 case CP0_REG09__COUNT
:
8480 gen_helper_mtc0_count(cpu_env
, arg
);
8481 register_name
= "Count";
8483 case CP0_REG09__SAARI
:
8484 CP0_CHECK(ctx
->saar
);
8485 gen_helper_mtc0_saari(cpu_env
, arg
);
8486 register_name
= "SAARI";
8488 case CP0_REG09__SAAR
:
8489 CP0_CHECK(ctx
->saar
);
8490 gen_helper_mtc0_saar(cpu_env
, arg
);
8491 register_name
= "SAAR";
8494 goto cp0_unimplemented
;
8497 case CP0_REGISTER_10
:
8499 case CP0_REG10__ENTRYHI
:
8500 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8501 register_name
= "EntryHi";
8504 goto cp0_unimplemented
;
8507 case CP0_REGISTER_11
:
8509 case CP0_REG11__COMPARE
:
8510 gen_helper_mtc0_compare(cpu_env
, arg
);
8511 register_name
= "Compare";
8513 /* 6,7 are implementation dependent */
8515 goto cp0_unimplemented
;
8518 case CP0_REGISTER_12
:
8520 case CP0_REG12__STATUS
:
8521 save_cpu_state(ctx
, 1);
8522 gen_helper_mtc0_status(cpu_env
, arg
);
8523 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8524 gen_save_pc(ctx
->base
.pc_next
+ 4);
8525 ctx
->base
.is_jmp
= DISAS_EXIT
;
8526 register_name
= "Status";
8528 case CP0_REG12__INTCTL
:
8529 check_insn(ctx
, ISA_MIPS32R2
);
8530 gen_helper_mtc0_intctl(cpu_env
, arg
);
8531 /* Stop translation as we may have switched the execution mode */
8532 ctx
->base
.is_jmp
= DISAS_STOP
;
8533 register_name
= "IntCtl";
8535 case CP0_REG12__SRSCTL
:
8536 check_insn(ctx
, ISA_MIPS32R2
);
8537 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8538 /* Stop translation as we may have switched the execution mode */
8539 ctx
->base
.is_jmp
= DISAS_STOP
;
8540 register_name
= "SRSCtl";
8542 case CP0_REG12__SRSMAP
:
8543 check_insn(ctx
, ISA_MIPS32R2
);
8544 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8545 /* Stop translation as we may have switched the execution mode */
8546 ctx
->base
.is_jmp
= DISAS_STOP
;
8547 register_name
= "SRSMap";
8550 goto cp0_unimplemented
;
8553 case CP0_REGISTER_13
:
8555 case CP0_REG13__CAUSE
:
8556 save_cpu_state(ctx
, 1);
8557 gen_helper_mtc0_cause(cpu_env
, arg
);
8559 * Stop translation as we may have triggered an interrupt.
8560 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8561 * translated code to check for pending interrupts.
8563 gen_save_pc(ctx
->base
.pc_next
+ 4);
8564 ctx
->base
.is_jmp
= DISAS_EXIT
;
8565 register_name
= "Cause";
8568 goto cp0_unimplemented
;
8571 case CP0_REGISTER_14
:
8573 case CP0_REG14__EPC
:
8574 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8575 register_name
= "EPC";
8578 goto cp0_unimplemented
;
8581 case CP0_REGISTER_15
:
8583 case CP0_REG15__PRID
:
8585 register_name
= "PRid";
8587 case CP0_REG15__EBASE
:
8588 check_insn(ctx
, ISA_MIPS32R2
);
8589 gen_helper_mtc0_ebase(cpu_env
, arg
);
8590 register_name
= "EBase";
8593 goto cp0_unimplemented
;
8596 case CP0_REGISTER_16
:
8598 case CP0_REG16__CONFIG
:
8599 gen_helper_mtc0_config0(cpu_env
, arg
);
8600 register_name
= "Config";
8601 /* Stop translation as we may have switched the execution mode */
8602 ctx
->base
.is_jmp
= DISAS_STOP
;
8604 case CP0_REG16__CONFIG1
:
8605 /* ignored, read only */
8606 register_name
= "Config1";
8608 case CP0_REG16__CONFIG2
:
8609 gen_helper_mtc0_config2(cpu_env
, arg
);
8610 register_name
= "Config2";
8611 /* Stop translation as we may have switched the execution mode */
8612 ctx
->base
.is_jmp
= DISAS_STOP
;
8614 case CP0_REG16__CONFIG3
:
8615 gen_helper_mtc0_config3(cpu_env
, arg
);
8616 register_name
= "Config3";
8617 /* Stop translation as we may have switched the execution mode */
8618 ctx
->base
.is_jmp
= DISAS_STOP
;
8620 case CP0_REG16__CONFIG4
:
8621 gen_helper_mtc0_config4(cpu_env
, arg
);
8622 register_name
= "Config4";
8623 ctx
->base
.is_jmp
= DISAS_STOP
;
8625 case CP0_REG16__CONFIG5
:
8626 gen_helper_mtc0_config5(cpu_env
, arg
);
8627 register_name
= "Config5";
8628 /* Stop translation as we may have switched the execution mode */
8629 ctx
->base
.is_jmp
= DISAS_STOP
;
8631 /* 6,7 are implementation dependent */
8632 case CP0_REG16__CONFIG6
:
8634 register_name
= "Config6";
8636 case CP0_REG16__CONFIG7
:
8638 register_name
= "Config7";
8641 register_name
= "Invalid config selector";
8642 goto cp0_unimplemented
;
8645 case CP0_REGISTER_17
:
8647 case CP0_REG17__LLADDR
:
8648 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8649 register_name
= "LLAddr";
8651 case CP0_REG17__MAAR
:
8652 CP0_CHECK(ctx
->mrp
);
8653 gen_helper_mtc0_maar(cpu_env
, arg
);
8654 register_name
= "MAAR";
8656 case CP0_REG17__MAARI
:
8657 CP0_CHECK(ctx
->mrp
);
8658 gen_helper_mtc0_maari(cpu_env
, arg
);
8659 register_name
= "MAARI";
8662 goto cp0_unimplemented
;
8665 case CP0_REGISTER_18
:
8667 case CP0_REG18__WATCHLO0
:
8668 case CP0_REG18__WATCHLO1
:
8669 case CP0_REG18__WATCHLO2
:
8670 case CP0_REG18__WATCHLO3
:
8671 case CP0_REG18__WATCHLO4
:
8672 case CP0_REG18__WATCHLO5
:
8673 case CP0_REG18__WATCHLO6
:
8674 case CP0_REG18__WATCHLO7
:
8675 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8676 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8677 register_name
= "WatchLo";
8680 goto cp0_unimplemented
;
8683 case CP0_REGISTER_19
:
8685 case CP0_REG19__WATCHHI0
:
8686 case CP0_REG19__WATCHHI1
:
8687 case CP0_REG19__WATCHHI2
:
8688 case CP0_REG19__WATCHHI3
:
8689 case CP0_REG19__WATCHHI4
:
8690 case CP0_REG19__WATCHHI5
:
8691 case CP0_REG19__WATCHHI6
:
8692 case CP0_REG19__WATCHHI7
:
8693 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8694 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8695 register_name
= "WatchHi";
8698 goto cp0_unimplemented
;
8701 case CP0_REGISTER_20
:
8703 case CP0_REG20__XCONTEXT
:
8704 #if defined(TARGET_MIPS64)
8705 check_insn(ctx
, ISA_MIPS3
);
8706 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8707 register_name
= "XContext";
8711 goto cp0_unimplemented
;
8714 case CP0_REGISTER_21
:
8715 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8716 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8719 gen_helper_mtc0_framemask(cpu_env
, arg
);
8720 register_name
= "Framemask";
8723 goto cp0_unimplemented
;
8726 case CP0_REGISTER_22
:
8728 register_name
= "Diagnostic"; /* implementation dependent */
8730 case CP0_REGISTER_23
:
8732 case CP0_REG23__DEBUG
:
8733 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8734 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8735 gen_save_pc(ctx
->base
.pc_next
+ 4);
8736 ctx
->base
.is_jmp
= DISAS_EXIT
;
8737 register_name
= "Debug";
8739 case CP0_REG23__TRACECONTROL
:
8740 /* PDtrace support */
8741 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8742 register_name
= "TraceControl";
8743 /* Stop translation as we may have switched the execution mode */
8744 ctx
->base
.is_jmp
= DISAS_STOP
;
8745 goto cp0_unimplemented
;
8746 case CP0_REG23__TRACECONTROL2
:
8747 /* PDtrace support */
8748 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8749 register_name
= "TraceControl2";
8750 /* Stop translation as we may have switched the execution mode */
8751 ctx
->base
.is_jmp
= DISAS_STOP
;
8752 goto cp0_unimplemented
;
8753 case CP0_REG23__USERTRACEDATA1
:
8754 /* Stop translation as we may have switched the execution mode */
8755 ctx
->base
.is_jmp
= DISAS_STOP
;
8756 /* PDtrace support */
8757 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8758 register_name
= "UserTraceData";
8759 /* Stop translation as we may have switched the execution mode */
8760 ctx
->base
.is_jmp
= DISAS_STOP
;
8761 goto cp0_unimplemented
;
8762 case CP0_REG23__TRACEIBPC
:
8763 /* PDtrace support */
8764 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8765 /* Stop translation as we may have switched the execution mode */
8766 ctx
->base
.is_jmp
= DISAS_STOP
;
8767 register_name
= "TraceIBPC";
8768 goto cp0_unimplemented
;
8769 case CP0_REG23__TRACEDBPC
:
8770 /* PDtrace support */
8771 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8772 /* Stop translation as we may have switched the execution mode */
8773 ctx
->base
.is_jmp
= DISAS_STOP
;
8774 register_name
= "TraceDBPC";
8775 goto cp0_unimplemented
;
8777 goto cp0_unimplemented
;
8780 case CP0_REGISTER_24
:
8782 case CP0_REG24__DEPC
:
8784 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8785 register_name
= "DEPC";
8788 goto cp0_unimplemented
;
8791 case CP0_REGISTER_25
:
8793 case CP0_REG25__PERFCTL0
:
8794 gen_helper_mtc0_performance0(cpu_env
, arg
);
8795 register_name
= "Performance0";
8797 case CP0_REG25__PERFCNT0
:
8798 /* gen_helper_mtc0_performance1(arg); */
8799 register_name
= "Performance1";
8800 goto cp0_unimplemented
;
8801 case CP0_REG25__PERFCTL1
:
8802 /* gen_helper_mtc0_performance2(arg); */
8803 register_name
= "Performance2";
8804 goto cp0_unimplemented
;
8805 case CP0_REG25__PERFCNT1
:
8806 /* gen_helper_mtc0_performance3(arg); */
8807 register_name
= "Performance3";
8808 goto cp0_unimplemented
;
8809 case CP0_REG25__PERFCTL2
:
8810 /* gen_helper_mtc0_performance4(arg); */
8811 register_name
= "Performance4";
8812 goto cp0_unimplemented
;
8813 case CP0_REG25__PERFCNT2
:
8814 /* gen_helper_mtc0_performance5(arg); */
8815 register_name
= "Performance5";
8816 goto cp0_unimplemented
;
8817 case CP0_REG25__PERFCTL3
:
8818 /* gen_helper_mtc0_performance6(arg); */
8819 register_name
= "Performance6";
8820 goto cp0_unimplemented
;
8821 case CP0_REG25__PERFCNT3
:
8822 /* gen_helper_mtc0_performance7(arg); */
8823 register_name
= "Performance7";
8824 goto cp0_unimplemented
;
8826 goto cp0_unimplemented
;
8829 case CP0_REGISTER_26
:
8831 case CP0_REG26__ERRCTL
:
8832 gen_helper_mtc0_errctl(cpu_env
, arg
);
8833 ctx
->base
.is_jmp
= DISAS_STOP
;
8834 register_name
= "ErrCtl";
8837 goto cp0_unimplemented
;
8840 case CP0_REGISTER_27
:
8842 case CP0_REG27__CACHERR
:
8844 register_name
= "CacheErr";
8847 goto cp0_unimplemented
;
8850 case CP0_REGISTER_28
:
8852 case CP0_REG28__TAGLO
:
8853 case CP0_REG28__TAGLO1
:
8854 case CP0_REG28__TAGLO2
:
8855 case CP0_REG28__TAGLO3
:
8856 gen_helper_mtc0_taglo(cpu_env
, arg
);
8857 register_name
= "TagLo";
8859 case CP0_REG28__DATALO
:
8860 case CP0_REG28__DATALO1
:
8861 case CP0_REG28__DATALO2
:
8862 case CP0_REG28__DATALO3
:
8863 gen_helper_mtc0_datalo(cpu_env
, arg
);
8864 register_name
= "DataLo";
8867 goto cp0_unimplemented
;
8870 case CP0_REGISTER_29
:
8872 case CP0_REG29__TAGHI
:
8873 case CP0_REG29__TAGHI1
:
8874 case CP0_REG29__TAGHI2
:
8875 case CP0_REG29__TAGHI3
:
8876 gen_helper_mtc0_taghi(cpu_env
, arg
);
8877 register_name
= "TagHi";
8879 case CP0_REG29__DATAHI
:
8880 case CP0_REG29__DATAHI1
:
8881 case CP0_REG29__DATAHI2
:
8882 case CP0_REG29__DATAHI3
:
8883 gen_helper_mtc0_datahi(cpu_env
, arg
);
8884 register_name
= "DataHi";
8887 register_name
= "invalid sel";
8888 goto cp0_unimplemented
;
8891 case CP0_REGISTER_30
:
8893 case CP0_REG30__ERROREPC
:
8894 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8895 register_name
= "ErrorEPC";
8898 goto cp0_unimplemented
;
8901 case CP0_REGISTER_31
:
8903 case CP0_REG31__DESAVE
:
8905 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8906 register_name
= "DESAVE";
8908 case CP0_REG31__KSCRATCH1
:
8909 case CP0_REG31__KSCRATCH2
:
8910 case CP0_REG31__KSCRATCH3
:
8911 case CP0_REG31__KSCRATCH4
:
8912 case CP0_REG31__KSCRATCH5
:
8913 case CP0_REG31__KSCRATCH6
:
8914 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8915 tcg_gen_st_tl(arg
, cpu_env
,
8916 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8917 register_name
= "KScratch";
8920 goto cp0_unimplemented
;
8924 goto cp0_unimplemented
;
8926 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8928 /* For simplicity assume that all writes can cause interrupts. */
8929 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8931 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8932 * translated code to check for pending interrupts.
8934 gen_save_pc(ctx
->base
.pc_next
+ 4);
8935 ctx
->base
.is_jmp
= DISAS_EXIT
;
8940 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8941 register_name
, reg
, sel
);
8944 #if defined(TARGET_MIPS64)
8945 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8947 const char *register_name
= "invalid";
8950 check_insn(ctx
, ISA_MIPS64
);
8954 case CP0_REGISTER_00
:
8956 case CP0_REG00__INDEX
:
8957 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8958 register_name
= "Index";
8960 case CP0_REG00__MVPCONTROL
:
8961 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8962 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8963 register_name
= "MVPControl";
8965 case CP0_REG00__MVPCONF0
:
8966 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8967 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8968 register_name
= "MVPConf0";
8970 case CP0_REG00__MVPCONF1
:
8971 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8972 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8973 register_name
= "MVPConf1";
8975 case CP0_REG00__VPCONTROL
:
8977 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8978 register_name
= "VPControl";
8981 goto cp0_unimplemented
;
8984 case CP0_REGISTER_01
:
8986 case CP0_REG01__RANDOM
:
8987 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8988 gen_helper_mfc0_random(arg
, cpu_env
);
8989 register_name
= "Random";
8991 case CP0_REG01__VPECONTROL
:
8992 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8993 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8994 register_name
= "VPEControl";
8996 case CP0_REG01__VPECONF0
:
8997 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8998 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8999 register_name
= "VPEConf0";
9001 case CP0_REG01__VPECONF1
:
9002 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9003 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
9004 register_name
= "VPEConf1";
9006 case CP0_REG01__YQMASK
:
9007 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9008 tcg_gen_ld_tl(arg
, cpu_env
,
9009 offsetof(CPUMIPSState
, CP0_YQMask
));
9010 register_name
= "YQMask";
9012 case CP0_REG01__VPESCHEDULE
:
9013 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9014 tcg_gen_ld_tl(arg
, cpu_env
,
9015 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9016 register_name
= "VPESchedule";
9018 case CP0_REG01__VPESCHEFBACK
:
9019 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9020 tcg_gen_ld_tl(arg
, cpu_env
,
9021 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9022 register_name
= "VPEScheFBack";
9024 case CP0_REG01__VPEOPT
:
9025 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9026 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
9027 register_name
= "VPEOpt";
9030 goto cp0_unimplemented
;
9033 case CP0_REGISTER_02
:
9035 case CP0_REG02__ENTRYLO0
:
9036 tcg_gen_ld_tl(arg
, cpu_env
,
9037 offsetof(CPUMIPSState
, CP0_EntryLo0
));
9038 register_name
= "EntryLo0";
9040 case CP0_REG02__TCSTATUS
:
9041 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9042 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
9043 register_name
= "TCStatus";
9045 case CP0_REG02__TCBIND
:
9046 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9047 gen_helper_mfc0_tcbind(arg
, cpu_env
);
9048 register_name
= "TCBind";
9050 case CP0_REG02__TCRESTART
:
9051 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9052 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
9053 register_name
= "TCRestart";
9055 case CP0_REG02__TCHALT
:
9056 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9057 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
9058 register_name
= "TCHalt";
9060 case CP0_REG02__TCCONTEXT
:
9061 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9062 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
9063 register_name
= "TCContext";
9065 case CP0_REG02__TCSCHEDULE
:
9066 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9067 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
9068 register_name
= "TCSchedule";
9070 case CP0_REG02__TCSCHEFBACK
:
9071 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9072 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
9073 register_name
= "TCScheFBack";
9076 goto cp0_unimplemented
;
9079 case CP0_REGISTER_03
:
9081 case CP0_REG03__ENTRYLO1
:
9082 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
9083 register_name
= "EntryLo1";
9085 case CP0_REG03__GLOBALNUM
:
9087 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
9088 register_name
= "GlobalNumber";
9091 goto cp0_unimplemented
;
9094 case CP0_REGISTER_04
:
9096 case CP0_REG04__CONTEXT
:
9097 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
9098 register_name
= "Context";
9100 case CP0_REG04__CONTEXTCONFIG
:
9102 /* gen_helper_dmfc0_contextconfig(arg); */
9103 register_name
= "ContextConfig";
9104 goto cp0_unimplemented
;
9105 case CP0_REG04__USERLOCAL
:
9106 CP0_CHECK(ctx
->ulri
);
9107 tcg_gen_ld_tl(arg
, cpu_env
,
9108 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9109 register_name
= "UserLocal";
9111 case CP0_REG04__MMID
:
9113 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
9114 register_name
= "MMID";
9117 goto cp0_unimplemented
;
9120 case CP0_REGISTER_05
:
9122 case CP0_REG05__PAGEMASK
:
9123 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
9124 register_name
= "PageMask";
9126 case CP0_REG05__PAGEGRAIN
:
9127 check_insn(ctx
, ISA_MIPS32R2
);
9128 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
9129 register_name
= "PageGrain";
9131 case CP0_REG05__SEGCTL0
:
9133 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
9134 register_name
= "SegCtl0";
9136 case CP0_REG05__SEGCTL1
:
9138 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
9139 register_name
= "SegCtl1";
9141 case CP0_REG05__SEGCTL2
:
9143 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
9144 register_name
= "SegCtl2";
9146 case CP0_REG05__PWBASE
:
9148 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9149 register_name
= "PWBase";
9151 case CP0_REG05__PWFIELD
:
9153 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
9154 register_name
= "PWField";
9156 case CP0_REG05__PWSIZE
:
9158 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
9159 register_name
= "PWSize";
9162 goto cp0_unimplemented
;
9165 case CP0_REGISTER_06
:
9167 case CP0_REG06__WIRED
:
9168 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
9169 register_name
= "Wired";
9171 case CP0_REG06__SRSCONF0
:
9172 check_insn(ctx
, ISA_MIPS32R2
);
9173 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
9174 register_name
= "SRSConf0";
9176 case CP0_REG06__SRSCONF1
:
9177 check_insn(ctx
, ISA_MIPS32R2
);
9178 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
9179 register_name
= "SRSConf1";
9181 case CP0_REG06__SRSCONF2
:
9182 check_insn(ctx
, ISA_MIPS32R2
);
9183 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
9184 register_name
= "SRSConf2";
9186 case CP0_REG06__SRSCONF3
:
9187 check_insn(ctx
, ISA_MIPS32R2
);
9188 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
9189 register_name
= "SRSConf3";
9191 case CP0_REG06__SRSCONF4
:
9192 check_insn(ctx
, ISA_MIPS32R2
);
9193 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
9194 register_name
= "SRSConf4";
9196 case CP0_REG06__PWCTL
:
9198 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
9199 register_name
= "PWCtl";
9202 goto cp0_unimplemented
;
9205 case CP0_REGISTER_07
:
9207 case CP0_REG07__HWRENA
:
9208 check_insn(ctx
, ISA_MIPS32R2
);
9209 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
9210 register_name
= "HWREna";
9213 goto cp0_unimplemented
;
9216 case CP0_REGISTER_08
:
9218 case CP0_REG08__BADVADDR
:
9219 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
9220 register_name
= "BadVAddr";
9222 case CP0_REG08__BADINSTR
:
9224 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
9225 register_name
= "BadInstr";
9227 case CP0_REG08__BADINSTRP
:
9229 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
9230 register_name
= "BadInstrP";
9232 case CP0_REG08__BADINSTRX
:
9234 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
9235 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
9236 register_name
= "BadInstrX";
9239 goto cp0_unimplemented
;
9242 case CP0_REGISTER_09
:
9244 case CP0_REG09__COUNT
:
9245 /* Mark as an IO operation because we read the time. */
9246 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9249 gen_helper_mfc0_count(arg
, cpu_env
);
9251 * Break the TB to be able to take timer interrupts immediately
9252 * after reading count. DISAS_STOP isn't sufficient, we need to
9253 * ensure we break completely out of translated code.
9255 gen_save_pc(ctx
->base
.pc_next
+ 4);
9256 ctx
->base
.is_jmp
= DISAS_EXIT
;
9257 register_name
= "Count";
9259 case CP0_REG09__SAARI
:
9260 CP0_CHECK(ctx
->saar
);
9261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
9262 register_name
= "SAARI";
9264 case CP0_REG09__SAAR
:
9265 CP0_CHECK(ctx
->saar
);
9266 gen_helper_dmfc0_saar(arg
, cpu_env
);
9267 register_name
= "SAAR";
9270 goto cp0_unimplemented
;
9273 case CP0_REGISTER_10
:
9275 case CP0_REG10__ENTRYHI
:
9276 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
9277 register_name
= "EntryHi";
9280 goto cp0_unimplemented
;
9283 case CP0_REGISTER_11
:
9285 case CP0_REG11__COMPARE
:
9286 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
9287 register_name
= "Compare";
9289 /* 6,7 are implementation dependent */
9291 goto cp0_unimplemented
;
9294 case CP0_REGISTER_12
:
9296 case CP0_REG12__STATUS
:
9297 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
9298 register_name
= "Status";
9300 case CP0_REG12__INTCTL
:
9301 check_insn(ctx
, ISA_MIPS32R2
);
9302 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
9303 register_name
= "IntCtl";
9305 case CP0_REG12__SRSCTL
:
9306 check_insn(ctx
, ISA_MIPS32R2
);
9307 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
9308 register_name
= "SRSCtl";
9310 case CP0_REG12__SRSMAP
:
9311 check_insn(ctx
, ISA_MIPS32R2
);
9312 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9313 register_name
= "SRSMap";
9316 goto cp0_unimplemented
;
9319 case CP0_REGISTER_13
:
9321 case CP0_REG13__CAUSE
:
9322 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
9323 register_name
= "Cause";
9326 goto cp0_unimplemented
;
9329 case CP0_REGISTER_14
:
9331 case CP0_REG14__EPC
:
9332 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9333 register_name
= "EPC";
9336 goto cp0_unimplemented
;
9339 case CP0_REGISTER_15
:
9341 case CP0_REG15__PRID
:
9342 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
9343 register_name
= "PRid";
9345 case CP0_REG15__EBASE
:
9346 check_insn(ctx
, ISA_MIPS32R2
);
9347 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
9348 register_name
= "EBase";
9350 case CP0_REG15__CMGCRBASE
:
9351 check_insn(ctx
, ISA_MIPS32R2
);
9352 CP0_CHECK(ctx
->cmgcr
);
9353 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
9354 register_name
= "CMGCRBase";
9357 goto cp0_unimplemented
;
9360 case CP0_REGISTER_16
:
9362 case CP0_REG16__CONFIG
:
9363 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
9364 register_name
= "Config";
9366 case CP0_REG16__CONFIG1
:
9367 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
9368 register_name
= "Config1";
9370 case CP0_REG16__CONFIG2
:
9371 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
9372 register_name
= "Config2";
9374 case CP0_REG16__CONFIG3
:
9375 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
9376 register_name
= "Config3";
9378 case CP0_REG16__CONFIG4
:
9379 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
9380 register_name
= "Config4";
9382 case CP0_REG16__CONFIG5
:
9383 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
9384 register_name
= "Config5";
9386 /* 6,7 are implementation dependent */
9387 case CP0_REG16__CONFIG6
:
9388 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
9389 register_name
= "Config6";
9391 case CP0_REG16__CONFIG7
:
9392 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
9393 register_name
= "Config7";
9396 goto cp0_unimplemented
;
9399 case CP0_REGISTER_17
:
9401 case CP0_REG17__LLADDR
:
9402 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
9403 register_name
= "LLAddr";
9405 case CP0_REG17__MAAR
:
9406 CP0_CHECK(ctx
->mrp
);
9407 gen_helper_dmfc0_maar(arg
, cpu_env
);
9408 register_name
= "MAAR";
9410 case CP0_REG17__MAARI
:
9411 CP0_CHECK(ctx
->mrp
);
9412 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
9413 register_name
= "MAARI";
9416 goto cp0_unimplemented
;
9419 case CP0_REGISTER_18
:
9421 case CP0_REG18__WATCHLO0
:
9422 case CP0_REG18__WATCHLO1
:
9423 case CP0_REG18__WATCHLO2
:
9424 case CP0_REG18__WATCHLO3
:
9425 case CP0_REG18__WATCHLO4
:
9426 case CP0_REG18__WATCHLO5
:
9427 case CP0_REG18__WATCHLO6
:
9428 case CP0_REG18__WATCHLO7
:
9429 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9430 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
9431 register_name
= "WatchLo";
9434 goto cp0_unimplemented
;
9437 case CP0_REGISTER_19
:
9439 case CP0_REG19__WATCHHI0
:
9440 case CP0_REG19__WATCHHI1
:
9441 case CP0_REG19__WATCHHI2
:
9442 case CP0_REG19__WATCHHI3
:
9443 case CP0_REG19__WATCHHI4
:
9444 case CP0_REG19__WATCHHI5
:
9445 case CP0_REG19__WATCHHI6
:
9446 case CP0_REG19__WATCHHI7
:
9447 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9448 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
9449 register_name
= "WatchHi";
9452 goto cp0_unimplemented
;
9455 case CP0_REGISTER_20
:
9457 case CP0_REG20__XCONTEXT
:
9458 check_insn(ctx
, ISA_MIPS3
);
9459 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
9460 register_name
= "XContext";
9463 goto cp0_unimplemented
;
9466 case CP0_REGISTER_21
:
9467 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9468 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
9471 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
9472 register_name
= "Framemask";
9475 goto cp0_unimplemented
;
9478 case CP0_REGISTER_22
:
9479 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9480 register_name
= "'Diagnostic"; /* implementation dependent */
9482 case CP0_REGISTER_23
:
9484 case CP0_REG23__DEBUG
:
9485 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
9486 register_name
= "Debug";
9488 case CP0_REG23__TRACECONTROL
:
9489 /* PDtrace support */
9490 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
9491 register_name
= "TraceControl";
9492 goto cp0_unimplemented
;
9493 case CP0_REG23__TRACECONTROL2
:
9494 /* PDtrace support */
9495 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9496 register_name
= "TraceControl2";
9497 goto cp0_unimplemented
;
9498 case CP0_REG23__USERTRACEDATA1
:
9499 /* PDtrace support */
9500 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9501 register_name
= "UserTraceData1";
9502 goto cp0_unimplemented
;
9503 case CP0_REG23__TRACEIBPC
:
9504 /* PDtrace support */
9505 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9506 register_name
= "TraceIBPC";
9507 goto cp0_unimplemented
;
9508 case CP0_REG23__TRACEDBPC
:
9509 /* PDtrace support */
9510 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9511 register_name
= "TraceDBPC";
9512 goto cp0_unimplemented
;
9514 goto cp0_unimplemented
;
9517 case CP0_REGISTER_24
:
9519 case CP0_REG24__DEPC
:
9521 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9522 register_name
= "DEPC";
9525 goto cp0_unimplemented
;
9528 case CP0_REGISTER_25
:
9530 case CP0_REG25__PERFCTL0
:
9531 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
9532 register_name
= "Performance0";
9534 case CP0_REG25__PERFCNT0
:
9535 /* gen_helper_dmfc0_performance1(arg); */
9536 register_name
= "Performance1";
9537 goto cp0_unimplemented
;
9538 case CP0_REG25__PERFCTL1
:
9539 /* gen_helper_dmfc0_performance2(arg); */
9540 register_name
= "Performance2";
9541 goto cp0_unimplemented
;
9542 case CP0_REG25__PERFCNT1
:
9543 /* gen_helper_dmfc0_performance3(arg); */
9544 register_name
= "Performance3";
9545 goto cp0_unimplemented
;
9546 case CP0_REG25__PERFCTL2
:
9547 /* gen_helper_dmfc0_performance4(arg); */
9548 register_name
= "Performance4";
9549 goto cp0_unimplemented
;
9550 case CP0_REG25__PERFCNT2
:
9551 /* gen_helper_dmfc0_performance5(arg); */
9552 register_name
= "Performance5";
9553 goto cp0_unimplemented
;
9554 case CP0_REG25__PERFCTL3
:
9555 /* gen_helper_dmfc0_performance6(arg); */
9556 register_name
= "Performance6";
9557 goto cp0_unimplemented
;
9558 case CP0_REG25__PERFCNT3
:
9559 /* gen_helper_dmfc0_performance7(arg); */
9560 register_name
= "Performance7";
9561 goto cp0_unimplemented
;
9563 goto cp0_unimplemented
;
9566 case CP0_REGISTER_26
:
9568 case CP0_REG26__ERRCTL
:
9569 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
9570 register_name
= "ErrCtl";
9573 goto cp0_unimplemented
;
9576 case CP0_REGISTER_27
:
9579 case CP0_REG27__CACHERR
:
9580 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9581 register_name
= "CacheErr";
9584 goto cp0_unimplemented
;
9587 case CP0_REGISTER_28
:
9589 case CP0_REG28__TAGLO
:
9590 case CP0_REG28__TAGLO1
:
9591 case CP0_REG28__TAGLO2
:
9592 case CP0_REG28__TAGLO3
:
9593 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
9594 register_name
= "TagLo";
9596 case CP0_REG28__DATALO
:
9597 case CP0_REG28__DATALO1
:
9598 case CP0_REG28__DATALO2
:
9599 case CP0_REG28__DATALO3
:
9600 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
9601 register_name
= "DataLo";
9604 goto cp0_unimplemented
;
9607 case CP0_REGISTER_29
:
9609 case CP0_REG29__TAGHI
:
9610 case CP0_REG29__TAGHI1
:
9611 case CP0_REG29__TAGHI2
:
9612 case CP0_REG29__TAGHI3
:
9613 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
9614 register_name
= "TagHi";
9616 case CP0_REG29__DATAHI
:
9617 case CP0_REG29__DATAHI1
:
9618 case CP0_REG29__DATAHI2
:
9619 case CP0_REG29__DATAHI3
:
9620 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
9621 register_name
= "DataHi";
9624 goto cp0_unimplemented
;
9627 case CP0_REGISTER_30
:
9629 case CP0_REG30__ERROREPC
:
9630 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9631 register_name
= "ErrorEPC";
9634 goto cp0_unimplemented
;
9637 case CP0_REGISTER_31
:
9639 case CP0_REG31__DESAVE
:
9641 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9642 register_name
= "DESAVE";
9644 case CP0_REG31__KSCRATCH1
:
9645 case CP0_REG31__KSCRATCH2
:
9646 case CP0_REG31__KSCRATCH3
:
9647 case CP0_REG31__KSCRATCH4
:
9648 case CP0_REG31__KSCRATCH5
:
9649 case CP0_REG31__KSCRATCH6
:
9650 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9651 tcg_gen_ld_tl(arg
, cpu_env
,
9652 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9653 register_name
= "KScratch";
9656 goto cp0_unimplemented
;
9660 goto cp0_unimplemented
;
9662 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9666 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9667 register_name
, reg
, sel
);
9668 gen_mfc0_unimplemented(ctx
, arg
);
9671 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9673 const char *register_name
= "invalid";
9676 check_insn(ctx
, ISA_MIPS64
);
9679 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9684 case CP0_REGISTER_00
:
9686 case CP0_REG00__INDEX
:
9687 gen_helper_mtc0_index(cpu_env
, arg
);
9688 register_name
= "Index";
9690 case CP0_REG00__MVPCONTROL
:
9691 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9692 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9693 register_name
= "MVPControl";
9695 case CP0_REG00__MVPCONF0
:
9696 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9698 register_name
= "MVPConf0";
9700 case CP0_REG00__MVPCONF1
:
9701 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9703 register_name
= "MVPConf1";
9705 case CP0_REG00__VPCONTROL
:
9708 register_name
= "VPControl";
9711 goto cp0_unimplemented
;
9714 case CP0_REGISTER_01
:
9716 case CP0_REG01__RANDOM
:
9718 register_name
= "Random";
9720 case CP0_REG01__VPECONTROL
:
9721 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9722 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9723 register_name
= "VPEControl";
9725 case CP0_REG01__VPECONF0
:
9726 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9727 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9728 register_name
= "VPEConf0";
9730 case CP0_REG01__VPECONF1
:
9731 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9732 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9733 register_name
= "VPEConf1";
9735 case CP0_REG01__YQMASK
:
9736 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9737 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9738 register_name
= "YQMask";
9740 case CP0_REG01__VPESCHEDULE
:
9741 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9742 tcg_gen_st_tl(arg
, cpu_env
,
9743 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9744 register_name
= "VPESchedule";
9746 case CP0_REG01__VPESCHEFBACK
:
9747 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9748 tcg_gen_st_tl(arg
, cpu_env
,
9749 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9750 register_name
= "VPEScheFBack";
9752 case CP0_REG01__VPEOPT
:
9753 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9754 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9755 register_name
= "VPEOpt";
9758 goto cp0_unimplemented
;
9761 case CP0_REGISTER_02
:
9763 case CP0_REG02__ENTRYLO0
:
9764 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9765 register_name
= "EntryLo0";
9767 case CP0_REG02__TCSTATUS
:
9768 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9769 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9770 register_name
= "TCStatus";
9772 case CP0_REG02__TCBIND
:
9773 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9774 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9775 register_name
= "TCBind";
9777 case CP0_REG02__TCRESTART
:
9778 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9779 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9780 register_name
= "TCRestart";
9782 case CP0_REG02__TCHALT
:
9783 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9784 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9785 register_name
= "TCHalt";
9787 case CP0_REG02__TCCONTEXT
:
9788 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9789 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9790 register_name
= "TCContext";
9792 case CP0_REG02__TCSCHEDULE
:
9793 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9794 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9795 register_name
= "TCSchedule";
9797 case CP0_REG02__TCSCHEFBACK
:
9798 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9799 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9800 register_name
= "TCScheFBack";
9803 goto cp0_unimplemented
;
9806 case CP0_REGISTER_03
:
9808 case CP0_REG03__ENTRYLO1
:
9809 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9810 register_name
= "EntryLo1";
9812 case CP0_REG03__GLOBALNUM
:
9815 register_name
= "GlobalNumber";
9818 goto cp0_unimplemented
;
9821 case CP0_REGISTER_04
:
9823 case CP0_REG04__CONTEXT
:
9824 gen_helper_mtc0_context(cpu_env
, arg
);
9825 register_name
= "Context";
9827 case CP0_REG04__CONTEXTCONFIG
:
9829 /* gen_helper_dmtc0_contextconfig(arg); */
9830 register_name
= "ContextConfig";
9831 goto cp0_unimplemented
;
9832 case CP0_REG04__USERLOCAL
:
9833 CP0_CHECK(ctx
->ulri
);
9834 tcg_gen_st_tl(arg
, cpu_env
,
9835 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9836 register_name
= "UserLocal";
9838 case CP0_REG04__MMID
:
9840 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9841 register_name
= "MMID";
9844 goto cp0_unimplemented
;
9847 case CP0_REGISTER_05
:
9849 case CP0_REG05__PAGEMASK
:
9850 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9851 register_name
= "PageMask";
9853 case CP0_REG05__PAGEGRAIN
:
9854 check_insn(ctx
, ISA_MIPS32R2
);
9855 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9856 register_name
= "PageGrain";
9858 case CP0_REG05__SEGCTL0
:
9860 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9861 register_name
= "SegCtl0";
9863 case CP0_REG05__SEGCTL1
:
9865 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9866 register_name
= "SegCtl1";
9868 case CP0_REG05__SEGCTL2
:
9870 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9871 register_name
= "SegCtl2";
9873 case CP0_REG05__PWBASE
:
9875 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9876 register_name
= "PWBase";
9878 case CP0_REG05__PWFIELD
:
9880 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9881 register_name
= "PWField";
9883 case CP0_REG05__PWSIZE
:
9885 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9886 register_name
= "PWSize";
9889 goto cp0_unimplemented
;
9892 case CP0_REGISTER_06
:
9894 case CP0_REG06__WIRED
:
9895 gen_helper_mtc0_wired(cpu_env
, arg
);
9896 register_name
= "Wired";
9898 case CP0_REG06__SRSCONF0
:
9899 check_insn(ctx
, ISA_MIPS32R2
);
9900 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9901 register_name
= "SRSConf0";
9903 case CP0_REG06__SRSCONF1
:
9904 check_insn(ctx
, ISA_MIPS32R2
);
9905 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9906 register_name
= "SRSConf1";
9908 case CP0_REG06__SRSCONF2
:
9909 check_insn(ctx
, ISA_MIPS32R2
);
9910 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9911 register_name
= "SRSConf2";
9913 case CP0_REG06__SRSCONF3
:
9914 check_insn(ctx
, ISA_MIPS32R2
);
9915 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9916 register_name
= "SRSConf3";
9918 case CP0_REG06__SRSCONF4
:
9919 check_insn(ctx
, ISA_MIPS32R2
);
9920 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9921 register_name
= "SRSConf4";
9923 case CP0_REG06__PWCTL
:
9925 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9926 register_name
= "PWCtl";
9929 goto cp0_unimplemented
;
9932 case CP0_REGISTER_07
:
9934 case CP0_REG07__HWRENA
:
9935 check_insn(ctx
, ISA_MIPS32R2
);
9936 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9937 ctx
->base
.is_jmp
= DISAS_STOP
;
9938 register_name
= "HWREna";
9941 goto cp0_unimplemented
;
9944 case CP0_REGISTER_08
:
9946 case CP0_REG08__BADVADDR
:
9948 register_name
= "BadVAddr";
9950 case CP0_REG08__BADINSTR
:
9952 register_name
= "BadInstr";
9954 case CP0_REG08__BADINSTRP
:
9956 register_name
= "BadInstrP";
9958 case CP0_REG08__BADINSTRX
:
9960 register_name
= "BadInstrX";
9963 goto cp0_unimplemented
;
9966 case CP0_REGISTER_09
:
9968 case CP0_REG09__COUNT
:
9969 gen_helper_mtc0_count(cpu_env
, arg
);
9970 register_name
= "Count";
9972 case CP0_REG09__SAARI
:
9973 CP0_CHECK(ctx
->saar
);
9974 gen_helper_mtc0_saari(cpu_env
, arg
);
9975 register_name
= "SAARI";
9977 case CP0_REG09__SAAR
:
9978 CP0_CHECK(ctx
->saar
);
9979 gen_helper_mtc0_saar(cpu_env
, arg
);
9980 register_name
= "SAAR";
9983 goto cp0_unimplemented
;
9985 /* Stop translation as we may have switched the execution mode */
9986 ctx
->base
.is_jmp
= DISAS_STOP
;
9988 case CP0_REGISTER_10
:
9990 case CP0_REG10__ENTRYHI
:
9991 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9992 register_name
= "EntryHi";
9995 goto cp0_unimplemented
;
9998 case CP0_REGISTER_11
:
10000 case CP0_REG11__COMPARE
:
10001 gen_helper_mtc0_compare(cpu_env
, arg
);
10002 register_name
= "Compare";
10004 /* 6,7 are implementation dependent */
10006 goto cp0_unimplemented
;
10008 /* Stop translation as we may have switched the execution mode */
10009 ctx
->base
.is_jmp
= DISAS_STOP
;
10011 case CP0_REGISTER_12
:
10013 case CP0_REG12__STATUS
:
10014 save_cpu_state(ctx
, 1);
10015 gen_helper_mtc0_status(cpu_env
, arg
);
10016 /* DISAS_STOP isn't good enough here, hflags may have changed. */
10017 gen_save_pc(ctx
->base
.pc_next
+ 4);
10018 ctx
->base
.is_jmp
= DISAS_EXIT
;
10019 register_name
= "Status";
10021 case CP0_REG12__INTCTL
:
10022 check_insn(ctx
, ISA_MIPS32R2
);
10023 gen_helper_mtc0_intctl(cpu_env
, arg
);
10024 /* Stop translation as we may have switched the execution mode */
10025 ctx
->base
.is_jmp
= DISAS_STOP
;
10026 register_name
= "IntCtl";
10028 case CP0_REG12__SRSCTL
:
10029 check_insn(ctx
, ISA_MIPS32R2
);
10030 gen_helper_mtc0_srsctl(cpu_env
, arg
);
10031 /* Stop translation as we may have switched the execution mode */
10032 ctx
->base
.is_jmp
= DISAS_STOP
;
10033 register_name
= "SRSCtl";
10035 case CP0_REG12__SRSMAP
:
10036 check_insn(ctx
, ISA_MIPS32R2
);
10037 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
10038 /* Stop translation as we may have switched the execution mode */
10039 ctx
->base
.is_jmp
= DISAS_STOP
;
10040 register_name
= "SRSMap";
10043 goto cp0_unimplemented
;
10046 case CP0_REGISTER_13
:
10048 case CP0_REG13__CAUSE
:
10049 save_cpu_state(ctx
, 1);
10050 gen_helper_mtc0_cause(cpu_env
, arg
);
10052 * Stop translation as we may have triggered an interrupt.
10053 * DISAS_STOP isn't sufficient, we need to ensure we break out of
10054 * translated code to check for pending interrupts.
10056 gen_save_pc(ctx
->base
.pc_next
+ 4);
10057 ctx
->base
.is_jmp
= DISAS_EXIT
;
10058 register_name
= "Cause";
10061 goto cp0_unimplemented
;
10064 case CP0_REGISTER_14
:
10066 case CP0_REG14__EPC
:
10067 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
10068 register_name
= "EPC";
10071 goto cp0_unimplemented
;
10074 case CP0_REGISTER_15
:
10076 case CP0_REG15__PRID
:
10078 register_name
= "PRid";
10080 case CP0_REG15__EBASE
:
10081 check_insn(ctx
, ISA_MIPS32R2
);
10082 gen_helper_mtc0_ebase(cpu_env
, arg
);
10083 register_name
= "EBase";
10086 goto cp0_unimplemented
;
10089 case CP0_REGISTER_16
:
10091 case CP0_REG16__CONFIG
:
10092 gen_helper_mtc0_config0(cpu_env
, arg
);
10093 register_name
= "Config";
10094 /* Stop translation as we may have switched the execution mode */
10095 ctx
->base
.is_jmp
= DISAS_STOP
;
10097 case CP0_REG16__CONFIG1
:
10098 /* ignored, read only */
10099 register_name
= "Config1";
10101 case CP0_REG16__CONFIG2
:
10102 gen_helper_mtc0_config2(cpu_env
, arg
);
10103 register_name
= "Config2";
10104 /* Stop translation as we may have switched the execution mode */
10105 ctx
->base
.is_jmp
= DISAS_STOP
;
10107 case CP0_REG16__CONFIG3
:
10108 gen_helper_mtc0_config3(cpu_env
, arg
);
10109 register_name
= "Config3";
10110 /* Stop translation as we may have switched the execution mode */
10111 ctx
->base
.is_jmp
= DISAS_STOP
;
10113 case CP0_REG16__CONFIG4
:
10114 /* currently ignored */
10115 register_name
= "Config4";
10117 case CP0_REG16__CONFIG5
:
10118 gen_helper_mtc0_config5(cpu_env
, arg
);
10119 register_name
= "Config5";
10120 /* Stop translation as we may have switched the execution mode */
10121 ctx
->base
.is_jmp
= DISAS_STOP
;
10123 /* 6,7 are implementation dependent */
10125 register_name
= "Invalid config selector";
10126 goto cp0_unimplemented
;
10129 case CP0_REGISTER_17
:
10131 case CP0_REG17__LLADDR
:
10132 gen_helper_mtc0_lladdr(cpu_env
, arg
);
10133 register_name
= "LLAddr";
10135 case CP0_REG17__MAAR
:
10136 CP0_CHECK(ctx
->mrp
);
10137 gen_helper_mtc0_maar(cpu_env
, arg
);
10138 register_name
= "MAAR";
10140 case CP0_REG17__MAARI
:
10141 CP0_CHECK(ctx
->mrp
);
10142 gen_helper_mtc0_maari(cpu_env
, arg
);
10143 register_name
= "MAARI";
10146 goto cp0_unimplemented
;
10149 case CP0_REGISTER_18
:
10151 case CP0_REG18__WATCHLO0
:
10152 case CP0_REG18__WATCHLO1
:
10153 case CP0_REG18__WATCHLO2
:
10154 case CP0_REG18__WATCHLO3
:
10155 case CP0_REG18__WATCHLO4
:
10156 case CP0_REG18__WATCHLO5
:
10157 case CP0_REG18__WATCHLO6
:
10158 case CP0_REG18__WATCHLO7
:
10159 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
10160 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
10161 register_name
= "WatchLo";
10164 goto cp0_unimplemented
;
10167 case CP0_REGISTER_19
:
10169 case CP0_REG19__WATCHHI0
:
10170 case CP0_REG19__WATCHHI1
:
10171 case CP0_REG19__WATCHHI2
:
10172 case CP0_REG19__WATCHHI3
:
10173 case CP0_REG19__WATCHHI4
:
10174 case CP0_REG19__WATCHHI5
:
10175 case CP0_REG19__WATCHHI6
:
10176 case CP0_REG19__WATCHHI7
:
10177 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
10178 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
10179 register_name
= "WatchHi";
10182 goto cp0_unimplemented
;
10185 case CP0_REGISTER_20
:
10187 case CP0_REG20__XCONTEXT
:
10188 check_insn(ctx
, ISA_MIPS3
);
10189 gen_helper_mtc0_xcontext(cpu_env
, arg
);
10190 register_name
= "XContext";
10193 goto cp0_unimplemented
;
10196 case CP0_REGISTER_21
:
10197 /* Officially reserved, but sel 0 is used for R1x000 framemask */
10198 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
10201 gen_helper_mtc0_framemask(cpu_env
, arg
);
10202 register_name
= "Framemask";
10205 goto cp0_unimplemented
;
10208 case CP0_REGISTER_22
:
10210 register_name
= "Diagnostic"; /* implementation dependent */
10212 case CP0_REGISTER_23
:
10214 case CP0_REG23__DEBUG
:
10215 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
10216 /* DISAS_STOP isn't good enough here, hflags may have changed. */
10217 gen_save_pc(ctx
->base
.pc_next
+ 4);
10218 ctx
->base
.is_jmp
= DISAS_EXIT
;
10219 register_name
= "Debug";
10221 case CP0_REG23__TRACECONTROL
:
10222 /* PDtrace support */
10223 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
10224 /* Stop translation as we may have switched the execution mode */
10225 ctx
->base
.is_jmp
= DISAS_STOP
;
10226 register_name
= "TraceControl";
10227 goto cp0_unimplemented
;
10228 case CP0_REG23__TRACECONTROL2
:
10229 /* PDtrace support */
10230 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
10231 /* Stop translation as we may have switched the execution mode */
10232 ctx
->base
.is_jmp
= DISAS_STOP
;
10233 register_name
= "TraceControl2";
10234 goto cp0_unimplemented
;
10235 case CP0_REG23__USERTRACEDATA1
:
10236 /* PDtrace support */
10237 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
10238 /* Stop translation as we may have switched the execution mode */
10239 ctx
->base
.is_jmp
= DISAS_STOP
;
10240 register_name
= "UserTraceData1";
10241 goto cp0_unimplemented
;
10242 case CP0_REG23__TRACEIBPC
:
10243 /* PDtrace support */
10244 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
10245 /* Stop translation as we may have switched the execution mode */
10246 ctx
->base
.is_jmp
= DISAS_STOP
;
10247 register_name
= "TraceIBPC";
10248 goto cp0_unimplemented
;
10249 case CP0_REG23__TRACEDBPC
:
10250 /* PDtrace support */
10251 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
10252 /* Stop translation as we may have switched the execution mode */
10253 ctx
->base
.is_jmp
= DISAS_STOP
;
10254 register_name
= "TraceDBPC";
10255 goto cp0_unimplemented
;
10257 goto cp0_unimplemented
;
10260 case CP0_REGISTER_24
:
10262 case CP0_REG24__DEPC
:
10263 /* EJTAG support */
10264 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
10265 register_name
= "DEPC";
10268 goto cp0_unimplemented
;
10271 case CP0_REGISTER_25
:
10273 case CP0_REG25__PERFCTL0
:
10274 gen_helper_mtc0_performance0(cpu_env
, arg
);
10275 register_name
= "Performance0";
10277 case CP0_REG25__PERFCNT0
:
10278 /* gen_helper_mtc0_performance1(cpu_env, arg); */
10279 register_name
= "Performance1";
10280 goto cp0_unimplemented
;
10281 case CP0_REG25__PERFCTL1
:
10282 /* gen_helper_mtc0_performance2(cpu_env, arg); */
10283 register_name
= "Performance2";
10284 goto cp0_unimplemented
;
10285 case CP0_REG25__PERFCNT1
:
10286 /* gen_helper_mtc0_performance3(cpu_env, arg); */
10287 register_name
= "Performance3";
10288 goto cp0_unimplemented
;
10289 case CP0_REG25__PERFCTL2
:
10290 /* gen_helper_mtc0_performance4(cpu_env, arg); */
10291 register_name
= "Performance4";
10292 goto cp0_unimplemented
;
10293 case CP0_REG25__PERFCNT2
:
10294 /* gen_helper_mtc0_performance5(cpu_env, arg); */
10295 register_name
= "Performance5";
10296 goto cp0_unimplemented
;
10297 case CP0_REG25__PERFCTL3
:
10298 /* gen_helper_mtc0_performance6(cpu_env, arg); */
10299 register_name
= "Performance6";
10300 goto cp0_unimplemented
;
10301 case CP0_REG25__PERFCNT3
:
10302 /* gen_helper_mtc0_performance7(cpu_env, arg); */
10303 register_name
= "Performance7";
10304 goto cp0_unimplemented
;
10306 goto cp0_unimplemented
;
10309 case CP0_REGISTER_26
:
10311 case CP0_REG26__ERRCTL
:
10312 gen_helper_mtc0_errctl(cpu_env
, arg
);
10313 ctx
->base
.is_jmp
= DISAS_STOP
;
10314 register_name
= "ErrCtl";
10317 goto cp0_unimplemented
;
10320 case CP0_REGISTER_27
:
10322 case CP0_REG27__CACHERR
:
10324 register_name
= "CacheErr";
10327 goto cp0_unimplemented
;
10330 case CP0_REGISTER_28
:
10332 case CP0_REG28__TAGLO
:
10333 case CP0_REG28__TAGLO1
:
10334 case CP0_REG28__TAGLO2
:
10335 case CP0_REG28__TAGLO3
:
10336 gen_helper_mtc0_taglo(cpu_env
, arg
);
10337 register_name
= "TagLo";
10339 case CP0_REG28__DATALO
:
10340 case CP0_REG28__DATALO1
:
10341 case CP0_REG28__DATALO2
:
10342 case CP0_REG28__DATALO3
:
10343 gen_helper_mtc0_datalo(cpu_env
, arg
);
10344 register_name
= "DataLo";
10347 goto cp0_unimplemented
;
10350 case CP0_REGISTER_29
:
10352 case CP0_REG29__TAGHI
:
10353 case CP0_REG29__TAGHI1
:
10354 case CP0_REG29__TAGHI2
:
10355 case CP0_REG29__TAGHI3
:
10356 gen_helper_mtc0_taghi(cpu_env
, arg
);
10357 register_name
= "TagHi";
10359 case CP0_REG29__DATAHI
:
10360 case CP0_REG29__DATAHI1
:
10361 case CP0_REG29__DATAHI2
:
10362 case CP0_REG29__DATAHI3
:
10363 gen_helper_mtc0_datahi(cpu_env
, arg
);
10364 register_name
= "DataHi";
10367 register_name
= "invalid sel";
10368 goto cp0_unimplemented
;
10371 case CP0_REGISTER_30
:
10373 case CP0_REG30__ERROREPC
:
10374 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
10375 register_name
= "ErrorEPC";
10378 goto cp0_unimplemented
;
10381 case CP0_REGISTER_31
:
10383 case CP0_REG31__DESAVE
:
10384 /* EJTAG support */
10385 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
10386 register_name
= "DESAVE";
10388 case CP0_REG31__KSCRATCH1
:
10389 case CP0_REG31__KSCRATCH2
:
10390 case CP0_REG31__KSCRATCH3
:
10391 case CP0_REG31__KSCRATCH4
:
10392 case CP0_REG31__KSCRATCH5
:
10393 case CP0_REG31__KSCRATCH6
:
10394 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
10395 tcg_gen_st_tl(arg
, cpu_env
,
10396 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
10397 register_name
= "KScratch";
10400 goto cp0_unimplemented
;
10404 goto cp0_unimplemented
;
10406 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
10408 /* For simplicity assume that all writes can cause interrupts. */
10409 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
10411 * DISAS_STOP isn't sufficient, we need to ensure we break out of
10412 * translated code to check for pending interrupts.
10414 gen_save_pc(ctx
->base
.pc_next
+ 4);
10415 ctx
->base
.is_jmp
= DISAS_EXIT
;
10420 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
10421 register_name
, reg
, sel
);
10423 #endif /* TARGET_MIPS64 */
10425 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
10426 int u
, int sel
, int h
)
10428 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10429 TCGv t0
= tcg_temp_local_new();
10431 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10432 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10433 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10434 tcg_gen_movi_tl(t0
, -1);
10435 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10436 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10437 tcg_gen_movi_tl(t0
, -1);
10438 } else if (u
== 0) {
10443 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
10446 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
10456 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
10459 gen_helper_mftc0_tcbind(t0
, cpu_env
);
10462 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
10465 gen_helper_mftc0_tchalt(t0
, cpu_env
);
10468 gen_helper_mftc0_tccontext(t0
, cpu_env
);
10471 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
10474 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
10477 gen_mfc0(ctx
, t0
, rt
, sel
);
10484 gen_helper_mftc0_entryhi(t0
, cpu_env
);
10487 gen_mfc0(ctx
, t0
, rt
, sel
);
10494 gen_helper_mftc0_status(t0
, cpu_env
);
10497 gen_mfc0(ctx
, t0
, rt
, sel
);
10504 gen_helper_mftc0_cause(t0
, cpu_env
);
10514 gen_helper_mftc0_epc(t0
, cpu_env
);
10524 gen_helper_mftc0_ebase(t0
, cpu_env
);
10541 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
10551 gen_helper_mftc0_debug(t0
, cpu_env
);
10554 gen_mfc0(ctx
, t0
, rt
, sel
);
10559 gen_mfc0(ctx
, t0
, rt
, sel
);
10563 /* GPR registers. */
10565 gen_helper_1e0i(mftgpr
, t0
, rt
);
10567 /* Auxiliary CPU registers */
10571 gen_helper_1e0i(mftlo
, t0
, 0);
10574 gen_helper_1e0i(mfthi
, t0
, 0);
10577 gen_helper_1e0i(mftacx
, t0
, 0);
10580 gen_helper_1e0i(mftlo
, t0
, 1);
10583 gen_helper_1e0i(mfthi
, t0
, 1);
10586 gen_helper_1e0i(mftacx
, t0
, 1);
10589 gen_helper_1e0i(mftlo
, t0
, 2);
10592 gen_helper_1e0i(mfthi
, t0
, 2);
10595 gen_helper_1e0i(mftacx
, t0
, 2);
10598 gen_helper_1e0i(mftlo
, t0
, 3);
10601 gen_helper_1e0i(mfthi
, t0
, 3);
10604 gen_helper_1e0i(mftacx
, t0
, 3);
10607 gen_helper_mftdsp(t0
, cpu_env
);
10613 /* Floating point (COP1). */
10615 /* XXX: For now we support only a single FPU context. */
10617 TCGv_i32 fp0
= tcg_temp_new_i32();
10619 gen_load_fpr32(ctx
, fp0
, rt
);
10620 tcg_gen_ext_i32_tl(t0
, fp0
);
10621 tcg_temp_free_i32(fp0
);
10623 TCGv_i32 fp0
= tcg_temp_new_i32();
10625 gen_load_fpr32h(ctx
, fp0
, rt
);
10626 tcg_gen_ext_i32_tl(t0
, fp0
);
10627 tcg_temp_free_i32(fp0
);
10631 /* XXX: For now we support only a single FPU context. */
10632 gen_helper_1e0i(cfc1
, t0
, rt
);
10634 /* COP2: Not implemented. */
10642 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10643 gen_store_gpr(t0
, rd
);
10649 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10650 generate_exception_end(ctx
, EXCP_RI
);
10653 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10654 int u
, int sel
, int h
)
10656 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10657 TCGv t0
= tcg_temp_local_new();
10659 gen_load_gpr(t0
, rt
);
10660 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10661 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10662 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10665 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10666 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10669 } else if (u
== 0) {
10674 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10677 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10687 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10690 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10693 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10696 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10699 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10702 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10705 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10708 gen_mtc0(ctx
, t0
, rd
, sel
);
10715 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10718 gen_mtc0(ctx
, t0
, rd
, sel
);
10725 gen_helper_mttc0_status(cpu_env
, t0
);
10728 gen_mtc0(ctx
, t0
, rd
, sel
);
10735 gen_helper_mttc0_cause(cpu_env
, t0
);
10745 gen_helper_mttc0_ebase(cpu_env
, t0
);
10755 gen_helper_mttc0_debug(cpu_env
, t0
);
10758 gen_mtc0(ctx
, t0
, rd
, sel
);
10763 gen_mtc0(ctx
, t0
, rd
, sel
);
10767 /* GPR registers. */
10769 gen_helper_0e1i(mttgpr
, t0
, rd
);
10771 /* Auxiliary CPU registers */
10775 gen_helper_0e1i(mttlo
, t0
, 0);
10778 gen_helper_0e1i(mtthi
, t0
, 0);
10781 gen_helper_0e1i(mttacx
, t0
, 0);
10784 gen_helper_0e1i(mttlo
, t0
, 1);
10787 gen_helper_0e1i(mtthi
, t0
, 1);
10790 gen_helper_0e1i(mttacx
, t0
, 1);
10793 gen_helper_0e1i(mttlo
, t0
, 2);
10796 gen_helper_0e1i(mtthi
, t0
, 2);
10799 gen_helper_0e1i(mttacx
, t0
, 2);
10802 gen_helper_0e1i(mttlo
, t0
, 3);
10805 gen_helper_0e1i(mtthi
, t0
, 3);
10808 gen_helper_0e1i(mttacx
, t0
, 3);
10811 gen_helper_mttdsp(cpu_env
, t0
);
10817 /* Floating point (COP1). */
10819 /* XXX: For now we support only a single FPU context. */
10821 TCGv_i32 fp0
= tcg_temp_new_i32();
10823 tcg_gen_trunc_tl_i32(fp0
, t0
);
10824 gen_store_fpr32(ctx
, fp0
, rd
);
10825 tcg_temp_free_i32(fp0
);
10827 TCGv_i32 fp0
= tcg_temp_new_i32();
10829 tcg_gen_trunc_tl_i32(fp0
, t0
);
10830 gen_store_fpr32h(ctx
, fp0
, rd
);
10831 tcg_temp_free_i32(fp0
);
10835 /* XXX: For now we support only a single FPU context. */
10837 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10839 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10840 tcg_temp_free_i32(fs_tmp
);
10842 /* Stop translation as we may have changed hflags */
10843 ctx
->base
.is_jmp
= DISAS_STOP
;
10845 /* COP2: Not implemented. */
10853 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10859 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10860 generate_exception_end(ctx
, EXCP_RI
);
10863 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10866 const char *opn
= "ldst";
10868 check_cp0_enabled(ctx
);
10872 /* Treat as NOP. */
10875 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10880 TCGv t0
= tcg_temp_new();
10882 gen_load_gpr(t0
, rt
);
10883 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10888 #if defined(TARGET_MIPS64)
10890 check_insn(ctx
, ISA_MIPS3
);
10892 /* Treat as NOP. */
10895 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10899 check_insn(ctx
, ISA_MIPS3
);
10901 TCGv t0
= tcg_temp_new();
10903 gen_load_gpr(t0
, rt
);
10904 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10913 /* Treat as NOP. */
10916 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10922 TCGv t0
= tcg_temp_new();
10923 gen_load_gpr(t0
, rt
);
10924 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10930 check_cp0_enabled(ctx
);
10932 /* Treat as NOP. */
10935 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10936 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10940 check_cp0_enabled(ctx
);
10941 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10942 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10947 if (!env
->tlb
->helper_tlbwi
) {
10950 gen_helper_tlbwi(cpu_env
);
10954 if (ctx
->ie
>= 2) {
10955 if (!env
->tlb
->helper_tlbinv
) {
10958 gen_helper_tlbinv(cpu_env
);
10959 } /* treat as nop if TLBINV not supported */
10963 if (ctx
->ie
>= 2) {
10964 if (!env
->tlb
->helper_tlbinvf
) {
10967 gen_helper_tlbinvf(cpu_env
);
10968 } /* treat as nop if TLBINV not supported */
10972 if (!env
->tlb
->helper_tlbwr
) {
10975 gen_helper_tlbwr(cpu_env
);
10979 if (!env
->tlb
->helper_tlbp
) {
10982 gen_helper_tlbp(cpu_env
);
10986 if (!env
->tlb
->helper_tlbr
) {
10989 gen_helper_tlbr(cpu_env
);
10991 case OPC_ERET
: /* OPC_ERETNC */
10992 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10993 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10996 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10997 if (ctx
->opcode
& (1 << bit_shift
)) {
11000 check_insn(ctx
, ISA_MIPS32R5
);
11001 gen_helper_eretnc(cpu_env
);
11005 check_insn(ctx
, ISA_MIPS2
);
11006 gen_helper_eret(cpu_env
);
11008 ctx
->base
.is_jmp
= DISAS_EXIT
;
11013 check_insn(ctx
, ISA_MIPS32
);
11014 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
11015 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11018 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11020 generate_exception_end(ctx
, EXCP_RI
);
11022 gen_helper_deret(cpu_env
);
11023 ctx
->base
.is_jmp
= DISAS_EXIT
;
11028 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
11029 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
11030 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11033 /* If we get an exception, we want to restart at next instruction */
11034 ctx
->base
.pc_next
+= 4;
11035 save_cpu_state(ctx
, 1);
11036 ctx
->base
.pc_next
-= 4;
11037 gen_helper_wait(cpu_env
);
11038 ctx
->base
.is_jmp
= DISAS_NORETURN
;
11043 generate_exception_end(ctx
, EXCP_RI
);
11046 (void)opn
; /* avoid a compiler warning */
11048 #endif /* !CONFIG_USER_ONLY */
11050 /* CP1 Branches (before delay slot) */
11051 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
11052 int32_t cc
, int32_t offset
)
11054 target_ulong btarget
;
11055 TCGv_i32 t0
= tcg_temp_new_i32();
11057 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11058 generate_exception_end(ctx
, EXCP_RI
);
11063 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
11066 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
11070 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11071 tcg_gen_not_i32(t0
, t0
);
11072 tcg_gen_andi_i32(t0
, t0
, 1);
11073 tcg_gen_extu_i32_tl(bcond
, t0
);
11076 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11077 tcg_gen_not_i32(t0
, t0
);
11078 tcg_gen_andi_i32(t0
, t0
, 1);
11079 tcg_gen_extu_i32_tl(bcond
, t0
);
11082 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11083 tcg_gen_andi_i32(t0
, t0
, 1);
11084 tcg_gen_extu_i32_tl(bcond
, t0
);
11087 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11088 tcg_gen_andi_i32(t0
, t0
, 1);
11089 tcg_gen_extu_i32_tl(bcond
, t0
);
11091 ctx
->hflags
|= MIPS_HFLAG_BL
;
11095 TCGv_i32 t1
= tcg_temp_new_i32();
11096 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11097 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11098 tcg_gen_nand_i32(t0
, t0
, t1
);
11099 tcg_temp_free_i32(t1
);
11100 tcg_gen_andi_i32(t0
, t0
, 1);
11101 tcg_gen_extu_i32_tl(bcond
, t0
);
11106 TCGv_i32 t1
= tcg_temp_new_i32();
11107 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11108 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11109 tcg_gen_or_i32(t0
, t0
, t1
);
11110 tcg_temp_free_i32(t1
);
11111 tcg_gen_andi_i32(t0
, t0
, 1);
11112 tcg_gen_extu_i32_tl(bcond
, t0
);
11117 TCGv_i32 t1
= tcg_temp_new_i32();
11118 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11119 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11120 tcg_gen_and_i32(t0
, t0
, t1
);
11121 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
11122 tcg_gen_and_i32(t0
, t0
, t1
);
11123 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
11124 tcg_gen_nand_i32(t0
, t0
, t1
);
11125 tcg_temp_free_i32(t1
);
11126 tcg_gen_andi_i32(t0
, t0
, 1);
11127 tcg_gen_extu_i32_tl(bcond
, t0
);
11132 TCGv_i32 t1
= tcg_temp_new_i32();
11133 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11134 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11135 tcg_gen_or_i32(t0
, t0
, t1
);
11136 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
11137 tcg_gen_or_i32(t0
, t0
, t1
);
11138 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
11139 tcg_gen_or_i32(t0
, t0
, t1
);
11140 tcg_temp_free_i32(t1
);
11141 tcg_gen_andi_i32(t0
, t0
, 1);
11142 tcg_gen_extu_i32_tl(bcond
, t0
);
11145 ctx
->hflags
|= MIPS_HFLAG_BC
;
11148 MIPS_INVAL("cp1 cond branch");
11149 generate_exception_end(ctx
, EXCP_RI
);
11152 ctx
->btarget
= btarget
;
11153 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
11155 tcg_temp_free_i32(t0
);
11158 /* R6 CP1 Branches */
11159 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
11160 int32_t ft
, int32_t offset
,
11161 int delayslot_size
)
11163 target_ulong btarget
;
11164 TCGv_i64 t0
= tcg_temp_new_i64();
11166 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11167 #ifdef MIPS_DEBUG_DISAS
11168 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11169 "\n", ctx
->base
.pc_next
);
11171 generate_exception_end(ctx
, EXCP_RI
);
11175 gen_load_fpr64(ctx
, t0
, ft
);
11176 tcg_gen_andi_i64(t0
, t0
, 1);
11178 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
11182 tcg_gen_xori_i64(t0
, t0
, 1);
11183 ctx
->hflags
|= MIPS_HFLAG_BC
;
11186 /* t0 already set */
11187 ctx
->hflags
|= MIPS_HFLAG_BC
;
11190 MIPS_INVAL("cp1 cond branch");
11191 generate_exception_end(ctx
, EXCP_RI
);
11195 tcg_gen_trunc_i64_tl(bcond
, t0
);
11197 ctx
->btarget
= btarget
;
11199 switch (delayslot_size
) {
11201 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
11204 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
11209 tcg_temp_free_i64(t0
);
11212 /* Coprocessor 1 (FPU) */
11214 #define FOP(func, fmt) (((fmt) << 21) | (func))
11217 OPC_ADD_S
= FOP(0, FMT_S
),
11218 OPC_SUB_S
= FOP(1, FMT_S
),
11219 OPC_MUL_S
= FOP(2, FMT_S
),
11220 OPC_DIV_S
= FOP(3, FMT_S
),
11221 OPC_SQRT_S
= FOP(4, FMT_S
),
11222 OPC_ABS_S
= FOP(5, FMT_S
),
11223 OPC_MOV_S
= FOP(6, FMT_S
),
11224 OPC_NEG_S
= FOP(7, FMT_S
),
11225 OPC_ROUND_L_S
= FOP(8, FMT_S
),
11226 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
11227 OPC_CEIL_L_S
= FOP(10, FMT_S
),
11228 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
11229 OPC_ROUND_W_S
= FOP(12, FMT_S
),
11230 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
11231 OPC_CEIL_W_S
= FOP(14, FMT_S
),
11232 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
11233 OPC_SEL_S
= FOP(16, FMT_S
),
11234 OPC_MOVCF_S
= FOP(17, FMT_S
),
11235 OPC_MOVZ_S
= FOP(18, FMT_S
),
11236 OPC_MOVN_S
= FOP(19, FMT_S
),
11237 OPC_SELEQZ_S
= FOP(20, FMT_S
),
11238 OPC_RECIP_S
= FOP(21, FMT_S
),
11239 OPC_RSQRT_S
= FOP(22, FMT_S
),
11240 OPC_SELNEZ_S
= FOP(23, FMT_S
),
11241 OPC_MADDF_S
= FOP(24, FMT_S
),
11242 OPC_MSUBF_S
= FOP(25, FMT_S
),
11243 OPC_RINT_S
= FOP(26, FMT_S
),
11244 OPC_CLASS_S
= FOP(27, FMT_S
),
11245 OPC_MIN_S
= FOP(28, FMT_S
),
11246 OPC_RECIP2_S
= FOP(28, FMT_S
),
11247 OPC_MINA_S
= FOP(29, FMT_S
),
11248 OPC_RECIP1_S
= FOP(29, FMT_S
),
11249 OPC_MAX_S
= FOP(30, FMT_S
),
11250 OPC_RSQRT1_S
= FOP(30, FMT_S
),
11251 OPC_MAXA_S
= FOP(31, FMT_S
),
11252 OPC_RSQRT2_S
= FOP(31, FMT_S
),
11253 OPC_CVT_D_S
= FOP(33, FMT_S
),
11254 OPC_CVT_W_S
= FOP(36, FMT_S
),
11255 OPC_CVT_L_S
= FOP(37, FMT_S
),
11256 OPC_CVT_PS_S
= FOP(38, FMT_S
),
11257 OPC_CMP_F_S
= FOP(48, FMT_S
),
11258 OPC_CMP_UN_S
= FOP(49, FMT_S
),
11259 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
11260 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
11261 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
11262 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
11263 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
11264 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
11265 OPC_CMP_SF_S
= FOP(56, FMT_S
),
11266 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
11267 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
11268 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
11269 OPC_CMP_LT_S
= FOP(60, FMT_S
),
11270 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
11271 OPC_CMP_LE_S
= FOP(62, FMT_S
),
11272 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
11274 OPC_ADD_D
= FOP(0, FMT_D
),
11275 OPC_SUB_D
= FOP(1, FMT_D
),
11276 OPC_MUL_D
= FOP(2, FMT_D
),
11277 OPC_DIV_D
= FOP(3, FMT_D
),
11278 OPC_SQRT_D
= FOP(4, FMT_D
),
11279 OPC_ABS_D
= FOP(5, FMT_D
),
11280 OPC_MOV_D
= FOP(6, FMT_D
),
11281 OPC_NEG_D
= FOP(7, FMT_D
),
11282 OPC_ROUND_L_D
= FOP(8, FMT_D
),
11283 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
11284 OPC_CEIL_L_D
= FOP(10, FMT_D
),
11285 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
11286 OPC_ROUND_W_D
= FOP(12, FMT_D
),
11287 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
11288 OPC_CEIL_W_D
= FOP(14, FMT_D
),
11289 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
11290 OPC_SEL_D
= FOP(16, FMT_D
),
11291 OPC_MOVCF_D
= FOP(17, FMT_D
),
11292 OPC_MOVZ_D
= FOP(18, FMT_D
),
11293 OPC_MOVN_D
= FOP(19, FMT_D
),
11294 OPC_SELEQZ_D
= FOP(20, FMT_D
),
11295 OPC_RECIP_D
= FOP(21, FMT_D
),
11296 OPC_RSQRT_D
= FOP(22, FMT_D
),
11297 OPC_SELNEZ_D
= FOP(23, FMT_D
),
11298 OPC_MADDF_D
= FOP(24, FMT_D
),
11299 OPC_MSUBF_D
= FOP(25, FMT_D
),
11300 OPC_RINT_D
= FOP(26, FMT_D
),
11301 OPC_CLASS_D
= FOP(27, FMT_D
),
11302 OPC_MIN_D
= FOP(28, FMT_D
),
11303 OPC_RECIP2_D
= FOP(28, FMT_D
),
11304 OPC_MINA_D
= FOP(29, FMT_D
),
11305 OPC_RECIP1_D
= FOP(29, FMT_D
),
11306 OPC_MAX_D
= FOP(30, FMT_D
),
11307 OPC_RSQRT1_D
= FOP(30, FMT_D
),
11308 OPC_MAXA_D
= FOP(31, FMT_D
),
11309 OPC_RSQRT2_D
= FOP(31, FMT_D
),
11310 OPC_CVT_S_D
= FOP(32, FMT_D
),
11311 OPC_CVT_W_D
= FOP(36, FMT_D
),
11312 OPC_CVT_L_D
= FOP(37, FMT_D
),
11313 OPC_CMP_F_D
= FOP(48, FMT_D
),
11314 OPC_CMP_UN_D
= FOP(49, FMT_D
),
11315 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
11316 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
11317 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
11318 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
11319 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
11320 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
11321 OPC_CMP_SF_D
= FOP(56, FMT_D
),
11322 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
11323 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
11324 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
11325 OPC_CMP_LT_D
= FOP(60, FMT_D
),
11326 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
11327 OPC_CMP_LE_D
= FOP(62, FMT_D
),
11328 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
11330 OPC_CVT_S_W
= FOP(32, FMT_W
),
11331 OPC_CVT_D_W
= FOP(33, FMT_W
),
11332 OPC_CVT_S_L
= FOP(32, FMT_L
),
11333 OPC_CVT_D_L
= FOP(33, FMT_L
),
11334 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
11336 OPC_ADD_PS
= FOP(0, FMT_PS
),
11337 OPC_SUB_PS
= FOP(1, FMT_PS
),
11338 OPC_MUL_PS
= FOP(2, FMT_PS
),
11339 OPC_DIV_PS
= FOP(3, FMT_PS
),
11340 OPC_ABS_PS
= FOP(5, FMT_PS
),
11341 OPC_MOV_PS
= FOP(6, FMT_PS
),
11342 OPC_NEG_PS
= FOP(7, FMT_PS
),
11343 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
11344 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
11345 OPC_MOVN_PS
= FOP(19, FMT_PS
),
11346 OPC_ADDR_PS
= FOP(24, FMT_PS
),
11347 OPC_MULR_PS
= FOP(26, FMT_PS
),
11348 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
11349 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
11350 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
11351 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
11353 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
11354 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
11355 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
11356 OPC_PLL_PS
= FOP(44, FMT_PS
),
11357 OPC_PLU_PS
= FOP(45, FMT_PS
),
11358 OPC_PUL_PS
= FOP(46, FMT_PS
),
11359 OPC_PUU_PS
= FOP(47, FMT_PS
),
11360 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
11361 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
11362 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
11363 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
11364 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
11365 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
11366 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
11367 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
11368 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
11369 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
11370 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
11371 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
11372 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
11373 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
11374 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
11375 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
11379 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
11380 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
11381 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
11382 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
11383 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
11384 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
11385 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
11386 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
11387 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
11388 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
11389 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
11390 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
11391 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
11392 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
11393 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
11394 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
11395 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
11396 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
11397 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
11398 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
11399 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
11400 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
11402 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
11403 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
11404 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
11405 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
11406 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
11407 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
11408 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
11409 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
11410 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
11411 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
11412 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
11413 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
11414 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
11415 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
11416 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
11417 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
11418 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
11419 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
11420 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
11421 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
11422 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
11423 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
11426 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
11428 TCGv t0
= tcg_temp_new();
11433 TCGv_i32 fp0
= tcg_temp_new_i32();
11435 gen_load_fpr32(ctx
, fp0
, fs
);
11436 tcg_gen_ext_i32_tl(t0
, fp0
);
11437 tcg_temp_free_i32(fp0
);
11439 gen_store_gpr(t0
, rt
);
11442 gen_load_gpr(t0
, rt
);
11444 TCGv_i32 fp0
= tcg_temp_new_i32();
11446 tcg_gen_trunc_tl_i32(fp0
, t0
);
11447 gen_store_fpr32(ctx
, fp0
, fs
);
11448 tcg_temp_free_i32(fp0
);
11452 gen_helper_1e0i(cfc1
, t0
, fs
);
11453 gen_store_gpr(t0
, rt
);
11456 gen_load_gpr(t0
, rt
);
11457 save_cpu_state(ctx
, 0);
11459 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
11461 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
11462 tcg_temp_free_i32(fs_tmp
);
11464 /* Stop translation as we may have changed hflags */
11465 ctx
->base
.is_jmp
= DISAS_STOP
;
11467 #if defined(TARGET_MIPS64)
11469 gen_load_fpr64(ctx
, t0
, fs
);
11470 gen_store_gpr(t0
, rt
);
11473 gen_load_gpr(t0
, rt
);
11474 gen_store_fpr64(ctx
, t0
, fs
);
11479 TCGv_i32 fp0
= tcg_temp_new_i32();
11481 gen_load_fpr32h(ctx
, fp0
, fs
);
11482 tcg_gen_ext_i32_tl(t0
, fp0
);
11483 tcg_temp_free_i32(fp0
);
11485 gen_store_gpr(t0
, rt
);
11488 gen_load_gpr(t0
, rt
);
11490 TCGv_i32 fp0
= tcg_temp_new_i32();
11492 tcg_gen_trunc_tl_i32(fp0
, t0
);
11493 gen_store_fpr32h(ctx
, fp0
, fs
);
11494 tcg_temp_free_i32(fp0
);
11498 MIPS_INVAL("cp1 move");
11499 generate_exception_end(ctx
, EXCP_RI
);
11507 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
11514 /* Treat as NOP. */
11519 cond
= TCG_COND_EQ
;
11521 cond
= TCG_COND_NE
;
11524 l1
= gen_new_label();
11525 t0
= tcg_temp_new_i32();
11526 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11527 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11528 tcg_temp_free_i32(t0
);
11530 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
11532 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
11537 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11541 TCGv_i32 t0
= tcg_temp_new_i32();
11542 TCGLabel
*l1
= gen_new_label();
11545 cond
= TCG_COND_EQ
;
11547 cond
= TCG_COND_NE
;
11550 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11551 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11552 gen_load_fpr32(ctx
, t0
, fs
);
11553 gen_store_fpr32(ctx
, t0
, fd
);
11555 tcg_temp_free_i32(t0
);
11558 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11562 TCGv_i32 t0
= tcg_temp_new_i32();
11564 TCGLabel
*l1
= gen_new_label();
11567 cond
= TCG_COND_EQ
;
11569 cond
= TCG_COND_NE
;
11572 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11573 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11574 tcg_temp_free_i32(t0
);
11575 fp0
= tcg_temp_new_i64();
11576 gen_load_fpr64(ctx
, fp0
, fs
);
11577 gen_store_fpr64(ctx
, fp0
, fd
);
11578 tcg_temp_free_i64(fp0
);
11582 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
11586 TCGv_i32 t0
= tcg_temp_new_i32();
11587 TCGLabel
*l1
= gen_new_label();
11588 TCGLabel
*l2
= gen_new_label();
11591 cond
= TCG_COND_EQ
;
11593 cond
= TCG_COND_NE
;
11596 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11597 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11598 gen_load_fpr32(ctx
, t0
, fs
);
11599 gen_store_fpr32(ctx
, t0
, fd
);
11602 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
11603 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
11604 gen_load_fpr32h(ctx
, t0
, fs
);
11605 gen_store_fpr32h(ctx
, t0
, fd
);
11606 tcg_temp_free_i32(t0
);
11610 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11613 TCGv_i32 t1
= tcg_const_i32(0);
11614 TCGv_i32 fp0
= tcg_temp_new_i32();
11615 TCGv_i32 fp1
= tcg_temp_new_i32();
11616 TCGv_i32 fp2
= tcg_temp_new_i32();
11617 gen_load_fpr32(ctx
, fp0
, fd
);
11618 gen_load_fpr32(ctx
, fp1
, ft
);
11619 gen_load_fpr32(ctx
, fp2
, fs
);
11623 tcg_gen_andi_i32(fp0
, fp0
, 1);
11624 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11627 tcg_gen_andi_i32(fp1
, fp1
, 1);
11628 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11631 tcg_gen_andi_i32(fp1
, fp1
, 1);
11632 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11635 MIPS_INVAL("gen_sel_s");
11636 generate_exception_end(ctx
, EXCP_RI
);
11640 gen_store_fpr32(ctx
, fp0
, fd
);
11641 tcg_temp_free_i32(fp2
);
11642 tcg_temp_free_i32(fp1
);
11643 tcg_temp_free_i32(fp0
);
11644 tcg_temp_free_i32(t1
);
11647 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11650 TCGv_i64 t1
= tcg_const_i64(0);
11651 TCGv_i64 fp0
= tcg_temp_new_i64();
11652 TCGv_i64 fp1
= tcg_temp_new_i64();
11653 TCGv_i64 fp2
= tcg_temp_new_i64();
11654 gen_load_fpr64(ctx
, fp0
, fd
);
11655 gen_load_fpr64(ctx
, fp1
, ft
);
11656 gen_load_fpr64(ctx
, fp2
, fs
);
11660 tcg_gen_andi_i64(fp0
, fp0
, 1);
11661 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11664 tcg_gen_andi_i64(fp1
, fp1
, 1);
11665 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11668 tcg_gen_andi_i64(fp1
, fp1
, 1);
11669 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11672 MIPS_INVAL("gen_sel_d");
11673 generate_exception_end(ctx
, EXCP_RI
);
11677 gen_store_fpr64(ctx
, fp0
, fd
);
11678 tcg_temp_free_i64(fp2
);
11679 tcg_temp_free_i64(fp1
);
11680 tcg_temp_free_i64(fp0
);
11681 tcg_temp_free_i64(t1
);
11684 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11685 int ft
, int fs
, int fd
, int cc
)
11687 uint32_t func
= ctx
->opcode
& 0x3f;
11691 TCGv_i32 fp0
= tcg_temp_new_i32();
11692 TCGv_i32 fp1
= tcg_temp_new_i32();
11694 gen_load_fpr32(ctx
, fp0
, fs
);
11695 gen_load_fpr32(ctx
, fp1
, ft
);
11696 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11697 tcg_temp_free_i32(fp1
);
11698 gen_store_fpr32(ctx
, fp0
, fd
);
11699 tcg_temp_free_i32(fp0
);
11704 TCGv_i32 fp0
= tcg_temp_new_i32();
11705 TCGv_i32 fp1
= tcg_temp_new_i32();
11707 gen_load_fpr32(ctx
, fp0
, fs
);
11708 gen_load_fpr32(ctx
, fp1
, ft
);
11709 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11710 tcg_temp_free_i32(fp1
);
11711 gen_store_fpr32(ctx
, fp0
, fd
);
11712 tcg_temp_free_i32(fp0
);
11717 TCGv_i32 fp0
= tcg_temp_new_i32();
11718 TCGv_i32 fp1
= tcg_temp_new_i32();
11720 gen_load_fpr32(ctx
, fp0
, fs
);
11721 gen_load_fpr32(ctx
, fp1
, ft
);
11722 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11723 tcg_temp_free_i32(fp1
);
11724 gen_store_fpr32(ctx
, fp0
, fd
);
11725 tcg_temp_free_i32(fp0
);
11730 TCGv_i32 fp0
= tcg_temp_new_i32();
11731 TCGv_i32 fp1
= tcg_temp_new_i32();
11733 gen_load_fpr32(ctx
, fp0
, fs
);
11734 gen_load_fpr32(ctx
, fp1
, ft
);
11735 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11736 tcg_temp_free_i32(fp1
);
11737 gen_store_fpr32(ctx
, fp0
, fd
);
11738 tcg_temp_free_i32(fp0
);
11743 TCGv_i32 fp0
= tcg_temp_new_i32();
11745 gen_load_fpr32(ctx
, fp0
, fs
);
11746 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11747 gen_store_fpr32(ctx
, fp0
, fd
);
11748 tcg_temp_free_i32(fp0
);
11753 TCGv_i32 fp0
= tcg_temp_new_i32();
11755 gen_load_fpr32(ctx
, fp0
, fs
);
11756 if (ctx
->abs2008
) {
11757 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11759 gen_helper_float_abs_s(fp0
, fp0
);
11761 gen_store_fpr32(ctx
, fp0
, fd
);
11762 tcg_temp_free_i32(fp0
);
11767 TCGv_i32 fp0
= tcg_temp_new_i32();
11769 gen_load_fpr32(ctx
, fp0
, fs
);
11770 gen_store_fpr32(ctx
, fp0
, fd
);
11771 tcg_temp_free_i32(fp0
);
11776 TCGv_i32 fp0
= tcg_temp_new_i32();
11778 gen_load_fpr32(ctx
, fp0
, fs
);
11779 if (ctx
->abs2008
) {
11780 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11782 gen_helper_float_chs_s(fp0
, fp0
);
11784 gen_store_fpr32(ctx
, fp0
, fd
);
11785 tcg_temp_free_i32(fp0
);
11788 case OPC_ROUND_L_S
:
11789 check_cp1_64bitmode(ctx
);
11791 TCGv_i32 fp32
= tcg_temp_new_i32();
11792 TCGv_i64 fp64
= tcg_temp_new_i64();
11794 gen_load_fpr32(ctx
, fp32
, fs
);
11795 if (ctx
->nan2008
) {
11796 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11798 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11800 tcg_temp_free_i32(fp32
);
11801 gen_store_fpr64(ctx
, fp64
, fd
);
11802 tcg_temp_free_i64(fp64
);
11805 case OPC_TRUNC_L_S
:
11806 check_cp1_64bitmode(ctx
);
11808 TCGv_i32 fp32
= tcg_temp_new_i32();
11809 TCGv_i64 fp64
= tcg_temp_new_i64();
11811 gen_load_fpr32(ctx
, fp32
, fs
);
11812 if (ctx
->nan2008
) {
11813 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11815 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11817 tcg_temp_free_i32(fp32
);
11818 gen_store_fpr64(ctx
, fp64
, fd
);
11819 tcg_temp_free_i64(fp64
);
11823 check_cp1_64bitmode(ctx
);
11825 TCGv_i32 fp32
= tcg_temp_new_i32();
11826 TCGv_i64 fp64
= tcg_temp_new_i64();
11828 gen_load_fpr32(ctx
, fp32
, fs
);
11829 if (ctx
->nan2008
) {
11830 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11832 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11834 tcg_temp_free_i32(fp32
);
11835 gen_store_fpr64(ctx
, fp64
, fd
);
11836 tcg_temp_free_i64(fp64
);
11839 case OPC_FLOOR_L_S
:
11840 check_cp1_64bitmode(ctx
);
11842 TCGv_i32 fp32
= tcg_temp_new_i32();
11843 TCGv_i64 fp64
= tcg_temp_new_i64();
11845 gen_load_fpr32(ctx
, fp32
, fs
);
11846 if (ctx
->nan2008
) {
11847 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11849 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11851 tcg_temp_free_i32(fp32
);
11852 gen_store_fpr64(ctx
, fp64
, fd
);
11853 tcg_temp_free_i64(fp64
);
11856 case OPC_ROUND_W_S
:
11858 TCGv_i32 fp0
= tcg_temp_new_i32();
11860 gen_load_fpr32(ctx
, fp0
, fs
);
11861 if (ctx
->nan2008
) {
11862 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11864 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11866 gen_store_fpr32(ctx
, fp0
, fd
);
11867 tcg_temp_free_i32(fp0
);
11870 case OPC_TRUNC_W_S
:
11872 TCGv_i32 fp0
= tcg_temp_new_i32();
11874 gen_load_fpr32(ctx
, fp0
, fs
);
11875 if (ctx
->nan2008
) {
11876 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11878 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11880 gen_store_fpr32(ctx
, fp0
, fd
);
11881 tcg_temp_free_i32(fp0
);
11886 TCGv_i32 fp0
= tcg_temp_new_i32();
11888 gen_load_fpr32(ctx
, fp0
, fs
);
11889 if (ctx
->nan2008
) {
11890 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11892 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11894 gen_store_fpr32(ctx
, fp0
, fd
);
11895 tcg_temp_free_i32(fp0
);
11898 case OPC_FLOOR_W_S
:
11900 TCGv_i32 fp0
= tcg_temp_new_i32();
11902 gen_load_fpr32(ctx
, fp0
, fs
);
11903 if (ctx
->nan2008
) {
11904 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11906 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11908 gen_store_fpr32(ctx
, fp0
, fd
);
11909 tcg_temp_free_i32(fp0
);
11913 check_insn(ctx
, ISA_MIPS32R6
);
11914 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11917 check_insn(ctx
, ISA_MIPS32R6
);
11918 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11921 check_insn(ctx
, ISA_MIPS32R6
);
11922 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11925 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11926 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11929 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11931 TCGLabel
*l1
= gen_new_label();
11935 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11937 fp0
= tcg_temp_new_i32();
11938 gen_load_fpr32(ctx
, fp0
, fs
);
11939 gen_store_fpr32(ctx
, fp0
, fd
);
11940 tcg_temp_free_i32(fp0
);
11945 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11947 TCGLabel
*l1
= gen_new_label();
11951 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11952 fp0
= tcg_temp_new_i32();
11953 gen_load_fpr32(ctx
, fp0
, fs
);
11954 gen_store_fpr32(ctx
, fp0
, fd
);
11955 tcg_temp_free_i32(fp0
);
11962 TCGv_i32 fp0
= tcg_temp_new_i32();
11964 gen_load_fpr32(ctx
, fp0
, fs
);
11965 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11966 gen_store_fpr32(ctx
, fp0
, fd
);
11967 tcg_temp_free_i32(fp0
);
11972 TCGv_i32 fp0
= tcg_temp_new_i32();
11974 gen_load_fpr32(ctx
, fp0
, fs
);
11975 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11976 gen_store_fpr32(ctx
, fp0
, fd
);
11977 tcg_temp_free_i32(fp0
);
11981 check_insn(ctx
, ISA_MIPS32R6
);
11983 TCGv_i32 fp0
= tcg_temp_new_i32();
11984 TCGv_i32 fp1
= tcg_temp_new_i32();
11985 TCGv_i32 fp2
= tcg_temp_new_i32();
11986 gen_load_fpr32(ctx
, fp0
, fs
);
11987 gen_load_fpr32(ctx
, fp1
, ft
);
11988 gen_load_fpr32(ctx
, fp2
, fd
);
11989 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11990 gen_store_fpr32(ctx
, fp2
, fd
);
11991 tcg_temp_free_i32(fp2
);
11992 tcg_temp_free_i32(fp1
);
11993 tcg_temp_free_i32(fp0
);
11997 check_insn(ctx
, ISA_MIPS32R6
);
11999 TCGv_i32 fp0
= tcg_temp_new_i32();
12000 TCGv_i32 fp1
= tcg_temp_new_i32();
12001 TCGv_i32 fp2
= tcg_temp_new_i32();
12002 gen_load_fpr32(ctx
, fp0
, fs
);
12003 gen_load_fpr32(ctx
, fp1
, ft
);
12004 gen_load_fpr32(ctx
, fp2
, fd
);
12005 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12006 gen_store_fpr32(ctx
, fp2
, fd
);
12007 tcg_temp_free_i32(fp2
);
12008 tcg_temp_free_i32(fp1
);
12009 tcg_temp_free_i32(fp0
);
12013 check_insn(ctx
, ISA_MIPS32R6
);
12015 TCGv_i32 fp0
= tcg_temp_new_i32();
12016 gen_load_fpr32(ctx
, fp0
, fs
);
12017 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
12018 gen_store_fpr32(ctx
, fp0
, fd
);
12019 tcg_temp_free_i32(fp0
);
12023 check_insn(ctx
, ISA_MIPS32R6
);
12025 TCGv_i32 fp0
= tcg_temp_new_i32();
12026 gen_load_fpr32(ctx
, fp0
, fs
);
12027 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
12028 gen_store_fpr32(ctx
, fp0
, fd
);
12029 tcg_temp_free_i32(fp0
);
12032 case OPC_MIN_S
: /* OPC_RECIP2_S */
12033 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12035 TCGv_i32 fp0
= tcg_temp_new_i32();
12036 TCGv_i32 fp1
= tcg_temp_new_i32();
12037 TCGv_i32 fp2
= tcg_temp_new_i32();
12038 gen_load_fpr32(ctx
, fp0
, fs
);
12039 gen_load_fpr32(ctx
, fp1
, ft
);
12040 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
12041 gen_store_fpr32(ctx
, fp2
, fd
);
12042 tcg_temp_free_i32(fp2
);
12043 tcg_temp_free_i32(fp1
);
12044 tcg_temp_free_i32(fp0
);
12047 check_cp1_64bitmode(ctx
);
12049 TCGv_i32 fp0
= tcg_temp_new_i32();
12050 TCGv_i32 fp1
= tcg_temp_new_i32();
12052 gen_load_fpr32(ctx
, fp0
, fs
);
12053 gen_load_fpr32(ctx
, fp1
, ft
);
12054 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
12055 tcg_temp_free_i32(fp1
);
12056 gen_store_fpr32(ctx
, fp0
, fd
);
12057 tcg_temp_free_i32(fp0
);
12061 case OPC_MINA_S
: /* OPC_RECIP1_S */
12062 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12064 TCGv_i32 fp0
= tcg_temp_new_i32();
12065 TCGv_i32 fp1
= tcg_temp_new_i32();
12066 TCGv_i32 fp2
= tcg_temp_new_i32();
12067 gen_load_fpr32(ctx
, fp0
, fs
);
12068 gen_load_fpr32(ctx
, fp1
, ft
);
12069 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
12070 gen_store_fpr32(ctx
, fp2
, fd
);
12071 tcg_temp_free_i32(fp2
);
12072 tcg_temp_free_i32(fp1
);
12073 tcg_temp_free_i32(fp0
);
12076 check_cp1_64bitmode(ctx
);
12078 TCGv_i32 fp0
= tcg_temp_new_i32();
12080 gen_load_fpr32(ctx
, fp0
, fs
);
12081 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
12082 gen_store_fpr32(ctx
, fp0
, fd
);
12083 tcg_temp_free_i32(fp0
);
12087 case OPC_MAX_S
: /* OPC_RSQRT1_S */
12088 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12090 TCGv_i32 fp0
= tcg_temp_new_i32();
12091 TCGv_i32 fp1
= tcg_temp_new_i32();
12092 gen_load_fpr32(ctx
, fp0
, fs
);
12093 gen_load_fpr32(ctx
, fp1
, ft
);
12094 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
12095 gen_store_fpr32(ctx
, fp1
, fd
);
12096 tcg_temp_free_i32(fp1
);
12097 tcg_temp_free_i32(fp0
);
12100 check_cp1_64bitmode(ctx
);
12102 TCGv_i32 fp0
= tcg_temp_new_i32();
12104 gen_load_fpr32(ctx
, fp0
, fs
);
12105 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
12106 gen_store_fpr32(ctx
, fp0
, fd
);
12107 tcg_temp_free_i32(fp0
);
12111 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
12112 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12114 TCGv_i32 fp0
= tcg_temp_new_i32();
12115 TCGv_i32 fp1
= tcg_temp_new_i32();
12116 gen_load_fpr32(ctx
, fp0
, fs
);
12117 gen_load_fpr32(ctx
, fp1
, ft
);
12118 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
12119 gen_store_fpr32(ctx
, fp1
, fd
);
12120 tcg_temp_free_i32(fp1
);
12121 tcg_temp_free_i32(fp0
);
12124 check_cp1_64bitmode(ctx
);
12126 TCGv_i32 fp0
= tcg_temp_new_i32();
12127 TCGv_i32 fp1
= tcg_temp_new_i32();
12129 gen_load_fpr32(ctx
, fp0
, fs
);
12130 gen_load_fpr32(ctx
, fp1
, ft
);
12131 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
12132 tcg_temp_free_i32(fp1
);
12133 gen_store_fpr32(ctx
, fp0
, fd
);
12134 tcg_temp_free_i32(fp0
);
12139 check_cp1_registers(ctx
, fd
);
12141 TCGv_i32 fp32
= tcg_temp_new_i32();
12142 TCGv_i64 fp64
= tcg_temp_new_i64();
12144 gen_load_fpr32(ctx
, fp32
, fs
);
12145 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
12146 tcg_temp_free_i32(fp32
);
12147 gen_store_fpr64(ctx
, fp64
, fd
);
12148 tcg_temp_free_i64(fp64
);
12153 TCGv_i32 fp0
= tcg_temp_new_i32();
12155 gen_load_fpr32(ctx
, fp0
, fs
);
12156 if (ctx
->nan2008
) {
12157 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
12159 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
12161 gen_store_fpr32(ctx
, fp0
, fd
);
12162 tcg_temp_free_i32(fp0
);
12166 check_cp1_64bitmode(ctx
);
12168 TCGv_i32 fp32
= tcg_temp_new_i32();
12169 TCGv_i64 fp64
= tcg_temp_new_i64();
12171 gen_load_fpr32(ctx
, fp32
, fs
);
12172 if (ctx
->nan2008
) {
12173 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
12175 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
12177 tcg_temp_free_i32(fp32
);
12178 gen_store_fpr64(ctx
, fp64
, fd
);
12179 tcg_temp_free_i64(fp64
);
12185 TCGv_i64 fp64
= tcg_temp_new_i64();
12186 TCGv_i32 fp32_0
= tcg_temp_new_i32();
12187 TCGv_i32 fp32_1
= tcg_temp_new_i32();
12189 gen_load_fpr32(ctx
, fp32_0
, fs
);
12190 gen_load_fpr32(ctx
, fp32_1
, ft
);
12191 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
12192 tcg_temp_free_i32(fp32_1
);
12193 tcg_temp_free_i32(fp32_0
);
12194 gen_store_fpr64(ctx
, fp64
, fd
);
12195 tcg_temp_free_i64(fp64
);
12201 case OPC_CMP_UEQ_S
:
12202 case OPC_CMP_OLT_S
:
12203 case OPC_CMP_ULT_S
:
12204 case OPC_CMP_OLE_S
:
12205 case OPC_CMP_ULE_S
:
12207 case OPC_CMP_NGLE_S
:
12208 case OPC_CMP_SEQ_S
:
12209 case OPC_CMP_NGL_S
:
12211 case OPC_CMP_NGE_S
:
12213 case OPC_CMP_NGT_S
:
12214 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12215 if (ctx
->opcode
& (1 << 6)) {
12216 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
12218 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
12222 check_cp1_registers(ctx
, fs
| ft
| fd
);
12224 TCGv_i64 fp0
= tcg_temp_new_i64();
12225 TCGv_i64 fp1
= tcg_temp_new_i64();
12227 gen_load_fpr64(ctx
, fp0
, fs
);
12228 gen_load_fpr64(ctx
, fp1
, ft
);
12229 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
12230 tcg_temp_free_i64(fp1
);
12231 gen_store_fpr64(ctx
, fp0
, fd
);
12232 tcg_temp_free_i64(fp0
);
12236 check_cp1_registers(ctx
, fs
| ft
| fd
);
12238 TCGv_i64 fp0
= tcg_temp_new_i64();
12239 TCGv_i64 fp1
= tcg_temp_new_i64();
12241 gen_load_fpr64(ctx
, fp0
, fs
);
12242 gen_load_fpr64(ctx
, fp1
, ft
);
12243 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
12244 tcg_temp_free_i64(fp1
);
12245 gen_store_fpr64(ctx
, fp0
, fd
);
12246 tcg_temp_free_i64(fp0
);
12250 check_cp1_registers(ctx
, fs
| ft
| fd
);
12252 TCGv_i64 fp0
= tcg_temp_new_i64();
12253 TCGv_i64 fp1
= tcg_temp_new_i64();
12255 gen_load_fpr64(ctx
, fp0
, fs
);
12256 gen_load_fpr64(ctx
, fp1
, ft
);
12257 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
12258 tcg_temp_free_i64(fp1
);
12259 gen_store_fpr64(ctx
, fp0
, fd
);
12260 tcg_temp_free_i64(fp0
);
12264 check_cp1_registers(ctx
, fs
| ft
| fd
);
12266 TCGv_i64 fp0
= tcg_temp_new_i64();
12267 TCGv_i64 fp1
= tcg_temp_new_i64();
12269 gen_load_fpr64(ctx
, fp0
, fs
);
12270 gen_load_fpr64(ctx
, fp1
, ft
);
12271 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
12272 tcg_temp_free_i64(fp1
);
12273 gen_store_fpr64(ctx
, fp0
, fd
);
12274 tcg_temp_free_i64(fp0
);
12278 check_cp1_registers(ctx
, fs
| fd
);
12280 TCGv_i64 fp0
= tcg_temp_new_i64();
12282 gen_load_fpr64(ctx
, fp0
, fs
);
12283 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
12284 gen_store_fpr64(ctx
, fp0
, fd
);
12285 tcg_temp_free_i64(fp0
);
12289 check_cp1_registers(ctx
, fs
| fd
);
12291 TCGv_i64 fp0
= tcg_temp_new_i64();
12293 gen_load_fpr64(ctx
, fp0
, fs
);
12294 if (ctx
->abs2008
) {
12295 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
12297 gen_helper_float_abs_d(fp0
, fp0
);
12299 gen_store_fpr64(ctx
, fp0
, fd
);
12300 tcg_temp_free_i64(fp0
);
12304 check_cp1_registers(ctx
, fs
| fd
);
12306 TCGv_i64 fp0
= tcg_temp_new_i64();
12308 gen_load_fpr64(ctx
, fp0
, fs
);
12309 gen_store_fpr64(ctx
, fp0
, fd
);
12310 tcg_temp_free_i64(fp0
);
12314 check_cp1_registers(ctx
, fs
| fd
);
12316 TCGv_i64 fp0
= tcg_temp_new_i64();
12318 gen_load_fpr64(ctx
, fp0
, fs
);
12319 if (ctx
->abs2008
) {
12320 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
12322 gen_helper_float_chs_d(fp0
, fp0
);
12324 gen_store_fpr64(ctx
, fp0
, fd
);
12325 tcg_temp_free_i64(fp0
);
12328 case OPC_ROUND_L_D
:
12329 check_cp1_64bitmode(ctx
);
12331 TCGv_i64 fp0
= tcg_temp_new_i64();
12333 gen_load_fpr64(ctx
, fp0
, fs
);
12334 if (ctx
->nan2008
) {
12335 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
12337 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
12339 gen_store_fpr64(ctx
, fp0
, fd
);
12340 tcg_temp_free_i64(fp0
);
12343 case OPC_TRUNC_L_D
:
12344 check_cp1_64bitmode(ctx
);
12346 TCGv_i64 fp0
= tcg_temp_new_i64();
12348 gen_load_fpr64(ctx
, fp0
, fs
);
12349 if (ctx
->nan2008
) {
12350 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
12352 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
12354 gen_store_fpr64(ctx
, fp0
, fd
);
12355 tcg_temp_free_i64(fp0
);
12359 check_cp1_64bitmode(ctx
);
12361 TCGv_i64 fp0
= tcg_temp_new_i64();
12363 gen_load_fpr64(ctx
, fp0
, fs
);
12364 if (ctx
->nan2008
) {
12365 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
12367 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
12369 gen_store_fpr64(ctx
, fp0
, fd
);
12370 tcg_temp_free_i64(fp0
);
12373 case OPC_FLOOR_L_D
:
12374 check_cp1_64bitmode(ctx
);
12376 TCGv_i64 fp0
= tcg_temp_new_i64();
12378 gen_load_fpr64(ctx
, fp0
, fs
);
12379 if (ctx
->nan2008
) {
12380 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
12382 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
12384 gen_store_fpr64(ctx
, fp0
, fd
);
12385 tcg_temp_free_i64(fp0
);
12388 case OPC_ROUND_W_D
:
12389 check_cp1_registers(ctx
, fs
);
12391 TCGv_i32 fp32
= tcg_temp_new_i32();
12392 TCGv_i64 fp64
= tcg_temp_new_i64();
12394 gen_load_fpr64(ctx
, fp64
, fs
);
12395 if (ctx
->nan2008
) {
12396 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
12398 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
12400 tcg_temp_free_i64(fp64
);
12401 gen_store_fpr32(ctx
, fp32
, fd
);
12402 tcg_temp_free_i32(fp32
);
12405 case OPC_TRUNC_W_D
:
12406 check_cp1_registers(ctx
, fs
);
12408 TCGv_i32 fp32
= tcg_temp_new_i32();
12409 TCGv_i64 fp64
= tcg_temp_new_i64();
12411 gen_load_fpr64(ctx
, fp64
, fs
);
12412 if (ctx
->nan2008
) {
12413 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
12415 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
12417 tcg_temp_free_i64(fp64
);
12418 gen_store_fpr32(ctx
, fp32
, fd
);
12419 tcg_temp_free_i32(fp32
);
12423 check_cp1_registers(ctx
, fs
);
12425 TCGv_i32 fp32
= tcg_temp_new_i32();
12426 TCGv_i64 fp64
= tcg_temp_new_i64();
12428 gen_load_fpr64(ctx
, fp64
, fs
);
12429 if (ctx
->nan2008
) {
12430 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
12432 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
12434 tcg_temp_free_i64(fp64
);
12435 gen_store_fpr32(ctx
, fp32
, fd
);
12436 tcg_temp_free_i32(fp32
);
12439 case OPC_FLOOR_W_D
:
12440 check_cp1_registers(ctx
, fs
);
12442 TCGv_i32 fp32
= tcg_temp_new_i32();
12443 TCGv_i64 fp64
= tcg_temp_new_i64();
12445 gen_load_fpr64(ctx
, fp64
, fs
);
12446 if (ctx
->nan2008
) {
12447 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
12449 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
12451 tcg_temp_free_i64(fp64
);
12452 gen_store_fpr32(ctx
, fp32
, fd
);
12453 tcg_temp_free_i32(fp32
);
12457 check_insn(ctx
, ISA_MIPS32R6
);
12458 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12461 check_insn(ctx
, ISA_MIPS32R6
);
12462 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12465 check_insn(ctx
, ISA_MIPS32R6
);
12466 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12469 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12470 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12473 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12475 TCGLabel
*l1
= gen_new_label();
12479 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12481 fp0
= tcg_temp_new_i64();
12482 gen_load_fpr64(ctx
, fp0
, fs
);
12483 gen_store_fpr64(ctx
, fp0
, fd
);
12484 tcg_temp_free_i64(fp0
);
12489 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12491 TCGLabel
*l1
= gen_new_label();
12495 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12496 fp0
= tcg_temp_new_i64();
12497 gen_load_fpr64(ctx
, fp0
, fs
);
12498 gen_store_fpr64(ctx
, fp0
, fd
);
12499 tcg_temp_free_i64(fp0
);
12505 check_cp1_registers(ctx
, fs
| fd
);
12507 TCGv_i64 fp0
= tcg_temp_new_i64();
12509 gen_load_fpr64(ctx
, fp0
, fs
);
12510 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
12511 gen_store_fpr64(ctx
, fp0
, fd
);
12512 tcg_temp_free_i64(fp0
);
12516 check_cp1_registers(ctx
, fs
| fd
);
12518 TCGv_i64 fp0
= tcg_temp_new_i64();
12520 gen_load_fpr64(ctx
, fp0
, fs
);
12521 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
12522 gen_store_fpr64(ctx
, fp0
, fd
);
12523 tcg_temp_free_i64(fp0
);
12527 check_insn(ctx
, ISA_MIPS32R6
);
12529 TCGv_i64 fp0
= tcg_temp_new_i64();
12530 TCGv_i64 fp1
= tcg_temp_new_i64();
12531 TCGv_i64 fp2
= tcg_temp_new_i64();
12532 gen_load_fpr64(ctx
, fp0
, fs
);
12533 gen_load_fpr64(ctx
, fp1
, ft
);
12534 gen_load_fpr64(ctx
, fp2
, fd
);
12535 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12536 gen_store_fpr64(ctx
, fp2
, fd
);
12537 tcg_temp_free_i64(fp2
);
12538 tcg_temp_free_i64(fp1
);
12539 tcg_temp_free_i64(fp0
);
12543 check_insn(ctx
, ISA_MIPS32R6
);
12545 TCGv_i64 fp0
= tcg_temp_new_i64();
12546 TCGv_i64 fp1
= tcg_temp_new_i64();
12547 TCGv_i64 fp2
= tcg_temp_new_i64();
12548 gen_load_fpr64(ctx
, fp0
, fs
);
12549 gen_load_fpr64(ctx
, fp1
, ft
);
12550 gen_load_fpr64(ctx
, fp2
, fd
);
12551 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12552 gen_store_fpr64(ctx
, fp2
, fd
);
12553 tcg_temp_free_i64(fp2
);
12554 tcg_temp_free_i64(fp1
);
12555 tcg_temp_free_i64(fp0
);
12559 check_insn(ctx
, ISA_MIPS32R6
);
12561 TCGv_i64 fp0
= tcg_temp_new_i64();
12562 gen_load_fpr64(ctx
, fp0
, fs
);
12563 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
12564 gen_store_fpr64(ctx
, fp0
, fd
);
12565 tcg_temp_free_i64(fp0
);
12569 check_insn(ctx
, ISA_MIPS32R6
);
12571 TCGv_i64 fp0
= tcg_temp_new_i64();
12572 gen_load_fpr64(ctx
, fp0
, fs
);
12573 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
12574 gen_store_fpr64(ctx
, fp0
, fd
);
12575 tcg_temp_free_i64(fp0
);
12578 case OPC_MIN_D
: /* OPC_RECIP2_D */
12579 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12581 TCGv_i64 fp0
= tcg_temp_new_i64();
12582 TCGv_i64 fp1
= tcg_temp_new_i64();
12583 gen_load_fpr64(ctx
, fp0
, fs
);
12584 gen_load_fpr64(ctx
, fp1
, ft
);
12585 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
12586 gen_store_fpr64(ctx
, fp1
, fd
);
12587 tcg_temp_free_i64(fp1
);
12588 tcg_temp_free_i64(fp0
);
12591 check_cp1_64bitmode(ctx
);
12593 TCGv_i64 fp0
= tcg_temp_new_i64();
12594 TCGv_i64 fp1
= tcg_temp_new_i64();
12596 gen_load_fpr64(ctx
, fp0
, fs
);
12597 gen_load_fpr64(ctx
, fp1
, ft
);
12598 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
12599 tcg_temp_free_i64(fp1
);
12600 gen_store_fpr64(ctx
, fp0
, fd
);
12601 tcg_temp_free_i64(fp0
);
12605 case OPC_MINA_D
: /* OPC_RECIP1_D */
12606 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12608 TCGv_i64 fp0
= tcg_temp_new_i64();
12609 TCGv_i64 fp1
= tcg_temp_new_i64();
12610 gen_load_fpr64(ctx
, fp0
, fs
);
12611 gen_load_fpr64(ctx
, fp1
, ft
);
12612 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
12613 gen_store_fpr64(ctx
, fp1
, fd
);
12614 tcg_temp_free_i64(fp1
);
12615 tcg_temp_free_i64(fp0
);
12618 check_cp1_64bitmode(ctx
);
12620 TCGv_i64 fp0
= tcg_temp_new_i64();
12622 gen_load_fpr64(ctx
, fp0
, fs
);
12623 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12624 gen_store_fpr64(ctx
, fp0
, fd
);
12625 tcg_temp_free_i64(fp0
);
12629 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12630 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12632 TCGv_i64 fp0
= tcg_temp_new_i64();
12633 TCGv_i64 fp1
= tcg_temp_new_i64();
12634 gen_load_fpr64(ctx
, fp0
, fs
);
12635 gen_load_fpr64(ctx
, fp1
, ft
);
12636 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12637 gen_store_fpr64(ctx
, fp1
, fd
);
12638 tcg_temp_free_i64(fp1
);
12639 tcg_temp_free_i64(fp0
);
12642 check_cp1_64bitmode(ctx
);
12644 TCGv_i64 fp0
= tcg_temp_new_i64();
12646 gen_load_fpr64(ctx
, fp0
, fs
);
12647 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12648 gen_store_fpr64(ctx
, fp0
, fd
);
12649 tcg_temp_free_i64(fp0
);
12653 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12654 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12656 TCGv_i64 fp0
= tcg_temp_new_i64();
12657 TCGv_i64 fp1
= tcg_temp_new_i64();
12658 gen_load_fpr64(ctx
, fp0
, fs
);
12659 gen_load_fpr64(ctx
, fp1
, ft
);
12660 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12661 gen_store_fpr64(ctx
, fp1
, fd
);
12662 tcg_temp_free_i64(fp1
);
12663 tcg_temp_free_i64(fp0
);
12666 check_cp1_64bitmode(ctx
);
12668 TCGv_i64 fp0
= tcg_temp_new_i64();
12669 TCGv_i64 fp1
= tcg_temp_new_i64();
12671 gen_load_fpr64(ctx
, fp0
, fs
);
12672 gen_load_fpr64(ctx
, fp1
, ft
);
12673 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12674 tcg_temp_free_i64(fp1
);
12675 gen_store_fpr64(ctx
, fp0
, fd
);
12676 tcg_temp_free_i64(fp0
);
12683 case OPC_CMP_UEQ_D
:
12684 case OPC_CMP_OLT_D
:
12685 case OPC_CMP_ULT_D
:
12686 case OPC_CMP_OLE_D
:
12687 case OPC_CMP_ULE_D
:
12689 case OPC_CMP_NGLE_D
:
12690 case OPC_CMP_SEQ_D
:
12691 case OPC_CMP_NGL_D
:
12693 case OPC_CMP_NGE_D
:
12695 case OPC_CMP_NGT_D
:
12696 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12697 if (ctx
->opcode
& (1 << 6)) {
12698 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12700 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12704 check_cp1_registers(ctx
, fs
);
12706 TCGv_i32 fp32
= tcg_temp_new_i32();
12707 TCGv_i64 fp64
= tcg_temp_new_i64();
12709 gen_load_fpr64(ctx
, fp64
, fs
);
12710 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12711 tcg_temp_free_i64(fp64
);
12712 gen_store_fpr32(ctx
, fp32
, fd
);
12713 tcg_temp_free_i32(fp32
);
12717 check_cp1_registers(ctx
, fs
);
12719 TCGv_i32 fp32
= tcg_temp_new_i32();
12720 TCGv_i64 fp64
= tcg_temp_new_i64();
12722 gen_load_fpr64(ctx
, fp64
, fs
);
12723 if (ctx
->nan2008
) {
12724 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12726 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12728 tcg_temp_free_i64(fp64
);
12729 gen_store_fpr32(ctx
, fp32
, fd
);
12730 tcg_temp_free_i32(fp32
);
12734 check_cp1_64bitmode(ctx
);
12736 TCGv_i64 fp0
= tcg_temp_new_i64();
12738 gen_load_fpr64(ctx
, fp0
, fs
);
12739 if (ctx
->nan2008
) {
12740 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12742 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12744 gen_store_fpr64(ctx
, fp0
, fd
);
12745 tcg_temp_free_i64(fp0
);
12750 TCGv_i32 fp0
= tcg_temp_new_i32();
12752 gen_load_fpr32(ctx
, fp0
, fs
);
12753 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12754 gen_store_fpr32(ctx
, fp0
, fd
);
12755 tcg_temp_free_i32(fp0
);
12759 check_cp1_registers(ctx
, fd
);
12761 TCGv_i32 fp32
= tcg_temp_new_i32();
12762 TCGv_i64 fp64
= tcg_temp_new_i64();
12764 gen_load_fpr32(ctx
, fp32
, fs
);
12765 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12766 tcg_temp_free_i32(fp32
);
12767 gen_store_fpr64(ctx
, fp64
, fd
);
12768 tcg_temp_free_i64(fp64
);
12772 check_cp1_64bitmode(ctx
);
12774 TCGv_i32 fp32
= tcg_temp_new_i32();
12775 TCGv_i64 fp64
= tcg_temp_new_i64();
12777 gen_load_fpr64(ctx
, fp64
, fs
);
12778 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12779 tcg_temp_free_i64(fp64
);
12780 gen_store_fpr32(ctx
, fp32
, fd
);
12781 tcg_temp_free_i32(fp32
);
12785 check_cp1_64bitmode(ctx
);
12787 TCGv_i64 fp0
= tcg_temp_new_i64();
12789 gen_load_fpr64(ctx
, fp0
, fs
);
12790 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12791 gen_store_fpr64(ctx
, fp0
, fd
);
12792 tcg_temp_free_i64(fp0
);
12795 case OPC_CVT_PS_PW
:
12798 TCGv_i64 fp0
= tcg_temp_new_i64();
12800 gen_load_fpr64(ctx
, fp0
, fs
);
12801 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12802 gen_store_fpr64(ctx
, fp0
, fd
);
12803 tcg_temp_free_i64(fp0
);
12809 TCGv_i64 fp0
= tcg_temp_new_i64();
12810 TCGv_i64 fp1
= tcg_temp_new_i64();
12812 gen_load_fpr64(ctx
, fp0
, fs
);
12813 gen_load_fpr64(ctx
, fp1
, ft
);
12814 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12815 tcg_temp_free_i64(fp1
);
12816 gen_store_fpr64(ctx
, fp0
, fd
);
12817 tcg_temp_free_i64(fp0
);
12823 TCGv_i64 fp0
= tcg_temp_new_i64();
12824 TCGv_i64 fp1
= tcg_temp_new_i64();
12826 gen_load_fpr64(ctx
, fp0
, fs
);
12827 gen_load_fpr64(ctx
, fp1
, ft
);
12828 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12829 tcg_temp_free_i64(fp1
);
12830 gen_store_fpr64(ctx
, fp0
, fd
);
12831 tcg_temp_free_i64(fp0
);
12837 TCGv_i64 fp0
= tcg_temp_new_i64();
12838 TCGv_i64 fp1
= tcg_temp_new_i64();
12840 gen_load_fpr64(ctx
, fp0
, fs
);
12841 gen_load_fpr64(ctx
, fp1
, ft
);
12842 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12843 tcg_temp_free_i64(fp1
);
12844 gen_store_fpr64(ctx
, fp0
, fd
);
12845 tcg_temp_free_i64(fp0
);
12851 TCGv_i64 fp0
= tcg_temp_new_i64();
12853 gen_load_fpr64(ctx
, fp0
, fs
);
12854 gen_helper_float_abs_ps(fp0
, fp0
);
12855 gen_store_fpr64(ctx
, fp0
, fd
);
12856 tcg_temp_free_i64(fp0
);
12862 TCGv_i64 fp0
= tcg_temp_new_i64();
12864 gen_load_fpr64(ctx
, fp0
, fs
);
12865 gen_store_fpr64(ctx
, fp0
, fd
);
12866 tcg_temp_free_i64(fp0
);
12872 TCGv_i64 fp0
= tcg_temp_new_i64();
12874 gen_load_fpr64(ctx
, fp0
, fs
);
12875 gen_helper_float_chs_ps(fp0
, fp0
);
12876 gen_store_fpr64(ctx
, fp0
, fd
);
12877 tcg_temp_free_i64(fp0
);
12882 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12887 TCGLabel
*l1
= gen_new_label();
12891 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12893 fp0
= tcg_temp_new_i64();
12894 gen_load_fpr64(ctx
, fp0
, fs
);
12895 gen_store_fpr64(ctx
, fp0
, fd
);
12896 tcg_temp_free_i64(fp0
);
12903 TCGLabel
*l1
= gen_new_label();
12907 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12908 fp0
= tcg_temp_new_i64();
12909 gen_load_fpr64(ctx
, fp0
, fs
);
12910 gen_store_fpr64(ctx
, fp0
, fd
);
12911 tcg_temp_free_i64(fp0
);
12919 TCGv_i64 fp0
= tcg_temp_new_i64();
12920 TCGv_i64 fp1
= tcg_temp_new_i64();
12922 gen_load_fpr64(ctx
, fp0
, ft
);
12923 gen_load_fpr64(ctx
, fp1
, fs
);
12924 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12925 tcg_temp_free_i64(fp1
);
12926 gen_store_fpr64(ctx
, fp0
, fd
);
12927 tcg_temp_free_i64(fp0
);
12933 TCGv_i64 fp0
= tcg_temp_new_i64();
12934 TCGv_i64 fp1
= tcg_temp_new_i64();
12936 gen_load_fpr64(ctx
, fp0
, ft
);
12937 gen_load_fpr64(ctx
, fp1
, fs
);
12938 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12939 tcg_temp_free_i64(fp1
);
12940 gen_store_fpr64(ctx
, fp0
, fd
);
12941 tcg_temp_free_i64(fp0
);
12944 case OPC_RECIP2_PS
:
12947 TCGv_i64 fp0
= tcg_temp_new_i64();
12948 TCGv_i64 fp1
= tcg_temp_new_i64();
12950 gen_load_fpr64(ctx
, fp0
, fs
);
12951 gen_load_fpr64(ctx
, fp1
, ft
);
12952 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12953 tcg_temp_free_i64(fp1
);
12954 gen_store_fpr64(ctx
, fp0
, fd
);
12955 tcg_temp_free_i64(fp0
);
12958 case OPC_RECIP1_PS
:
12961 TCGv_i64 fp0
= tcg_temp_new_i64();
12963 gen_load_fpr64(ctx
, fp0
, fs
);
12964 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12965 gen_store_fpr64(ctx
, fp0
, fd
);
12966 tcg_temp_free_i64(fp0
);
12969 case OPC_RSQRT1_PS
:
12972 TCGv_i64 fp0
= tcg_temp_new_i64();
12974 gen_load_fpr64(ctx
, fp0
, fs
);
12975 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12976 gen_store_fpr64(ctx
, fp0
, fd
);
12977 tcg_temp_free_i64(fp0
);
12980 case OPC_RSQRT2_PS
:
12983 TCGv_i64 fp0
= tcg_temp_new_i64();
12984 TCGv_i64 fp1
= tcg_temp_new_i64();
12986 gen_load_fpr64(ctx
, fp0
, fs
);
12987 gen_load_fpr64(ctx
, fp1
, ft
);
12988 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12989 tcg_temp_free_i64(fp1
);
12990 gen_store_fpr64(ctx
, fp0
, fd
);
12991 tcg_temp_free_i64(fp0
);
12995 check_cp1_64bitmode(ctx
);
12997 TCGv_i32 fp0
= tcg_temp_new_i32();
12999 gen_load_fpr32h(ctx
, fp0
, fs
);
13000 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
13001 gen_store_fpr32(ctx
, fp0
, fd
);
13002 tcg_temp_free_i32(fp0
);
13005 case OPC_CVT_PW_PS
:
13008 TCGv_i64 fp0
= tcg_temp_new_i64();
13010 gen_load_fpr64(ctx
, fp0
, fs
);
13011 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
13012 gen_store_fpr64(ctx
, fp0
, fd
);
13013 tcg_temp_free_i64(fp0
);
13017 check_cp1_64bitmode(ctx
);
13019 TCGv_i32 fp0
= tcg_temp_new_i32();
13021 gen_load_fpr32(ctx
, fp0
, fs
);
13022 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
13023 gen_store_fpr32(ctx
, fp0
, fd
);
13024 tcg_temp_free_i32(fp0
);
13030 TCGv_i32 fp0
= tcg_temp_new_i32();
13031 TCGv_i32 fp1
= tcg_temp_new_i32();
13033 gen_load_fpr32(ctx
, fp0
, fs
);
13034 gen_load_fpr32(ctx
, fp1
, ft
);
13035 gen_store_fpr32h(ctx
, fp0
, fd
);
13036 gen_store_fpr32(ctx
, fp1
, fd
);
13037 tcg_temp_free_i32(fp0
);
13038 tcg_temp_free_i32(fp1
);
13044 TCGv_i32 fp0
= tcg_temp_new_i32();
13045 TCGv_i32 fp1
= tcg_temp_new_i32();
13047 gen_load_fpr32(ctx
, fp0
, fs
);
13048 gen_load_fpr32h(ctx
, fp1
, ft
);
13049 gen_store_fpr32(ctx
, fp1
, fd
);
13050 gen_store_fpr32h(ctx
, fp0
, fd
);
13051 tcg_temp_free_i32(fp0
);
13052 tcg_temp_free_i32(fp1
);
13058 TCGv_i32 fp0
= tcg_temp_new_i32();
13059 TCGv_i32 fp1
= tcg_temp_new_i32();
13061 gen_load_fpr32h(ctx
, fp0
, fs
);
13062 gen_load_fpr32(ctx
, fp1
, ft
);
13063 gen_store_fpr32(ctx
, fp1
, fd
);
13064 gen_store_fpr32h(ctx
, fp0
, fd
);
13065 tcg_temp_free_i32(fp0
);
13066 tcg_temp_free_i32(fp1
);
13072 TCGv_i32 fp0
= tcg_temp_new_i32();
13073 TCGv_i32 fp1
= tcg_temp_new_i32();
13075 gen_load_fpr32h(ctx
, fp0
, fs
);
13076 gen_load_fpr32h(ctx
, fp1
, ft
);
13077 gen_store_fpr32(ctx
, fp1
, fd
);
13078 gen_store_fpr32h(ctx
, fp0
, fd
);
13079 tcg_temp_free_i32(fp0
);
13080 tcg_temp_free_i32(fp1
);
13084 case OPC_CMP_UN_PS
:
13085 case OPC_CMP_EQ_PS
:
13086 case OPC_CMP_UEQ_PS
:
13087 case OPC_CMP_OLT_PS
:
13088 case OPC_CMP_ULT_PS
:
13089 case OPC_CMP_OLE_PS
:
13090 case OPC_CMP_ULE_PS
:
13091 case OPC_CMP_SF_PS
:
13092 case OPC_CMP_NGLE_PS
:
13093 case OPC_CMP_SEQ_PS
:
13094 case OPC_CMP_NGL_PS
:
13095 case OPC_CMP_LT_PS
:
13096 case OPC_CMP_NGE_PS
:
13097 case OPC_CMP_LE_PS
:
13098 case OPC_CMP_NGT_PS
:
13099 if (ctx
->opcode
& (1 << 6)) {
13100 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
13102 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
13106 MIPS_INVAL("farith");
13107 generate_exception_end(ctx
, EXCP_RI
);
13112 /* Coprocessor 3 (FPU) */
13113 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
13114 int fd
, int fs
, int base
, int index
)
13116 TCGv t0
= tcg_temp_new();
13119 gen_load_gpr(t0
, index
);
13120 } else if (index
== 0) {
13121 gen_load_gpr(t0
, base
);
13123 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
13126 * Don't do NOP if destination is zero: we must perform the actual
13133 TCGv_i32 fp0
= tcg_temp_new_i32();
13135 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
13136 tcg_gen_trunc_tl_i32(fp0
, t0
);
13137 gen_store_fpr32(ctx
, fp0
, fd
);
13138 tcg_temp_free_i32(fp0
);
13143 check_cp1_registers(ctx
, fd
);
13145 TCGv_i64 fp0
= tcg_temp_new_i64();
13146 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13147 gen_store_fpr64(ctx
, fp0
, fd
);
13148 tcg_temp_free_i64(fp0
);
13152 check_cp1_64bitmode(ctx
);
13153 tcg_gen_andi_tl(t0
, t0
, ~0x7);
13155 TCGv_i64 fp0
= tcg_temp_new_i64();
13157 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13158 gen_store_fpr64(ctx
, fp0
, fd
);
13159 tcg_temp_free_i64(fp0
);
13165 TCGv_i32 fp0
= tcg_temp_new_i32();
13166 gen_load_fpr32(ctx
, fp0
, fs
);
13167 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
13168 tcg_temp_free_i32(fp0
);
13173 check_cp1_registers(ctx
, fs
);
13175 TCGv_i64 fp0
= tcg_temp_new_i64();
13176 gen_load_fpr64(ctx
, fp0
, fs
);
13177 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13178 tcg_temp_free_i64(fp0
);
13182 check_cp1_64bitmode(ctx
);
13183 tcg_gen_andi_tl(t0
, t0
, ~0x7);
13185 TCGv_i64 fp0
= tcg_temp_new_i64();
13186 gen_load_fpr64(ctx
, fp0
, fs
);
13187 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13188 tcg_temp_free_i64(fp0
);
13195 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
13196 int fd
, int fr
, int fs
, int ft
)
13202 TCGv t0
= tcg_temp_local_new();
13203 TCGv_i32 fp
= tcg_temp_new_i32();
13204 TCGv_i32 fph
= tcg_temp_new_i32();
13205 TCGLabel
*l1
= gen_new_label();
13206 TCGLabel
*l2
= gen_new_label();
13208 gen_load_gpr(t0
, fr
);
13209 tcg_gen_andi_tl(t0
, t0
, 0x7);
13211 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
13212 gen_load_fpr32(ctx
, fp
, fs
);
13213 gen_load_fpr32h(ctx
, fph
, fs
);
13214 gen_store_fpr32(ctx
, fp
, fd
);
13215 gen_store_fpr32h(ctx
, fph
, fd
);
13218 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
13220 #ifdef TARGET_WORDS_BIGENDIAN
13221 gen_load_fpr32(ctx
, fp
, fs
);
13222 gen_load_fpr32h(ctx
, fph
, ft
);
13223 gen_store_fpr32h(ctx
, fp
, fd
);
13224 gen_store_fpr32(ctx
, fph
, fd
);
13226 gen_load_fpr32h(ctx
, fph
, fs
);
13227 gen_load_fpr32(ctx
, fp
, ft
);
13228 gen_store_fpr32(ctx
, fph
, fd
);
13229 gen_store_fpr32h(ctx
, fp
, fd
);
13232 tcg_temp_free_i32(fp
);
13233 tcg_temp_free_i32(fph
);
13239 TCGv_i32 fp0
= tcg_temp_new_i32();
13240 TCGv_i32 fp1
= tcg_temp_new_i32();
13241 TCGv_i32 fp2
= tcg_temp_new_i32();
13243 gen_load_fpr32(ctx
, fp0
, fs
);
13244 gen_load_fpr32(ctx
, fp1
, ft
);
13245 gen_load_fpr32(ctx
, fp2
, fr
);
13246 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13247 tcg_temp_free_i32(fp0
);
13248 tcg_temp_free_i32(fp1
);
13249 gen_store_fpr32(ctx
, fp2
, fd
);
13250 tcg_temp_free_i32(fp2
);
13255 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13257 TCGv_i64 fp0
= tcg_temp_new_i64();
13258 TCGv_i64 fp1
= tcg_temp_new_i64();
13259 TCGv_i64 fp2
= tcg_temp_new_i64();
13261 gen_load_fpr64(ctx
, fp0
, fs
);
13262 gen_load_fpr64(ctx
, fp1
, ft
);
13263 gen_load_fpr64(ctx
, fp2
, fr
);
13264 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13265 tcg_temp_free_i64(fp0
);
13266 tcg_temp_free_i64(fp1
);
13267 gen_store_fpr64(ctx
, fp2
, fd
);
13268 tcg_temp_free_i64(fp2
);
13274 TCGv_i64 fp0
= tcg_temp_new_i64();
13275 TCGv_i64 fp1
= tcg_temp_new_i64();
13276 TCGv_i64 fp2
= tcg_temp_new_i64();
13278 gen_load_fpr64(ctx
, fp0
, fs
);
13279 gen_load_fpr64(ctx
, fp1
, ft
);
13280 gen_load_fpr64(ctx
, fp2
, fr
);
13281 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13282 tcg_temp_free_i64(fp0
);
13283 tcg_temp_free_i64(fp1
);
13284 gen_store_fpr64(ctx
, fp2
, fd
);
13285 tcg_temp_free_i64(fp2
);
13291 TCGv_i32 fp0
= tcg_temp_new_i32();
13292 TCGv_i32 fp1
= tcg_temp_new_i32();
13293 TCGv_i32 fp2
= tcg_temp_new_i32();
13295 gen_load_fpr32(ctx
, fp0
, fs
);
13296 gen_load_fpr32(ctx
, fp1
, ft
);
13297 gen_load_fpr32(ctx
, fp2
, fr
);
13298 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13299 tcg_temp_free_i32(fp0
);
13300 tcg_temp_free_i32(fp1
);
13301 gen_store_fpr32(ctx
, fp2
, fd
);
13302 tcg_temp_free_i32(fp2
);
13307 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13309 TCGv_i64 fp0
= tcg_temp_new_i64();
13310 TCGv_i64 fp1
= tcg_temp_new_i64();
13311 TCGv_i64 fp2
= tcg_temp_new_i64();
13313 gen_load_fpr64(ctx
, fp0
, fs
);
13314 gen_load_fpr64(ctx
, fp1
, ft
);
13315 gen_load_fpr64(ctx
, fp2
, fr
);
13316 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13317 tcg_temp_free_i64(fp0
);
13318 tcg_temp_free_i64(fp1
);
13319 gen_store_fpr64(ctx
, fp2
, fd
);
13320 tcg_temp_free_i64(fp2
);
13326 TCGv_i64 fp0
= tcg_temp_new_i64();
13327 TCGv_i64 fp1
= tcg_temp_new_i64();
13328 TCGv_i64 fp2
= tcg_temp_new_i64();
13330 gen_load_fpr64(ctx
, fp0
, fs
);
13331 gen_load_fpr64(ctx
, fp1
, ft
);
13332 gen_load_fpr64(ctx
, fp2
, fr
);
13333 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13334 tcg_temp_free_i64(fp0
);
13335 tcg_temp_free_i64(fp1
);
13336 gen_store_fpr64(ctx
, fp2
, fd
);
13337 tcg_temp_free_i64(fp2
);
13343 TCGv_i32 fp0
= tcg_temp_new_i32();
13344 TCGv_i32 fp1
= tcg_temp_new_i32();
13345 TCGv_i32 fp2
= tcg_temp_new_i32();
13347 gen_load_fpr32(ctx
, fp0
, fs
);
13348 gen_load_fpr32(ctx
, fp1
, ft
);
13349 gen_load_fpr32(ctx
, fp2
, fr
);
13350 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13351 tcg_temp_free_i32(fp0
);
13352 tcg_temp_free_i32(fp1
);
13353 gen_store_fpr32(ctx
, fp2
, fd
);
13354 tcg_temp_free_i32(fp2
);
13359 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13361 TCGv_i64 fp0
= tcg_temp_new_i64();
13362 TCGv_i64 fp1
= tcg_temp_new_i64();
13363 TCGv_i64 fp2
= tcg_temp_new_i64();
13365 gen_load_fpr64(ctx
, fp0
, fs
);
13366 gen_load_fpr64(ctx
, fp1
, ft
);
13367 gen_load_fpr64(ctx
, fp2
, fr
);
13368 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13369 tcg_temp_free_i64(fp0
);
13370 tcg_temp_free_i64(fp1
);
13371 gen_store_fpr64(ctx
, fp2
, fd
);
13372 tcg_temp_free_i64(fp2
);
13378 TCGv_i64 fp0
= tcg_temp_new_i64();
13379 TCGv_i64 fp1
= tcg_temp_new_i64();
13380 TCGv_i64 fp2
= tcg_temp_new_i64();
13382 gen_load_fpr64(ctx
, fp0
, fs
);
13383 gen_load_fpr64(ctx
, fp1
, ft
);
13384 gen_load_fpr64(ctx
, fp2
, fr
);
13385 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13386 tcg_temp_free_i64(fp0
);
13387 tcg_temp_free_i64(fp1
);
13388 gen_store_fpr64(ctx
, fp2
, fd
);
13389 tcg_temp_free_i64(fp2
);
13395 TCGv_i32 fp0
= tcg_temp_new_i32();
13396 TCGv_i32 fp1
= tcg_temp_new_i32();
13397 TCGv_i32 fp2
= tcg_temp_new_i32();
13399 gen_load_fpr32(ctx
, fp0
, fs
);
13400 gen_load_fpr32(ctx
, fp1
, ft
);
13401 gen_load_fpr32(ctx
, fp2
, fr
);
13402 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13403 tcg_temp_free_i32(fp0
);
13404 tcg_temp_free_i32(fp1
);
13405 gen_store_fpr32(ctx
, fp2
, fd
);
13406 tcg_temp_free_i32(fp2
);
13411 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13413 TCGv_i64 fp0
= tcg_temp_new_i64();
13414 TCGv_i64 fp1
= tcg_temp_new_i64();
13415 TCGv_i64 fp2
= tcg_temp_new_i64();
13417 gen_load_fpr64(ctx
, fp0
, fs
);
13418 gen_load_fpr64(ctx
, fp1
, ft
);
13419 gen_load_fpr64(ctx
, fp2
, fr
);
13420 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13421 tcg_temp_free_i64(fp0
);
13422 tcg_temp_free_i64(fp1
);
13423 gen_store_fpr64(ctx
, fp2
, fd
);
13424 tcg_temp_free_i64(fp2
);
13430 TCGv_i64 fp0
= tcg_temp_new_i64();
13431 TCGv_i64 fp1
= tcg_temp_new_i64();
13432 TCGv_i64 fp2
= tcg_temp_new_i64();
13434 gen_load_fpr64(ctx
, fp0
, fs
);
13435 gen_load_fpr64(ctx
, fp1
, ft
);
13436 gen_load_fpr64(ctx
, fp2
, fr
);
13437 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13438 tcg_temp_free_i64(fp0
);
13439 tcg_temp_free_i64(fp1
);
13440 gen_store_fpr64(ctx
, fp2
, fd
);
13441 tcg_temp_free_i64(fp2
);
13445 MIPS_INVAL("flt3_arith");
13446 generate_exception_end(ctx
, EXCP_RI
);
13451 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
13455 #if !defined(CONFIG_USER_ONLY)
13457 * The Linux kernel will emulate rdhwr if it's not supported natively.
13458 * Therefore only check the ISA in system mode.
13460 check_insn(ctx
, ISA_MIPS32R2
);
13462 t0
= tcg_temp_new();
13466 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
13467 gen_store_gpr(t0
, rt
);
13470 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
13471 gen_store_gpr(t0
, rt
);
13474 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
13477 gen_helper_rdhwr_cc(t0
, cpu_env
);
13478 gen_store_gpr(t0
, rt
);
13480 * Break the TB to be able to take timer interrupts immediately
13481 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13482 * we break completely out of translated code.
13484 gen_save_pc(ctx
->base
.pc_next
+ 4);
13485 ctx
->base
.is_jmp
= DISAS_EXIT
;
13488 gen_helper_rdhwr_ccres(t0
, cpu_env
);
13489 gen_store_gpr(t0
, rt
);
13492 check_insn(ctx
, ISA_MIPS32R6
);
13495 * Performance counter registers are not implemented other than
13496 * control register 0.
13498 generate_exception(ctx
, EXCP_RI
);
13500 gen_helper_rdhwr_performance(t0
, cpu_env
);
13501 gen_store_gpr(t0
, rt
);
13504 check_insn(ctx
, ISA_MIPS32R6
);
13505 gen_helper_rdhwr_xnp(t0
, cpu_env
);
13506 gen_store_gpr(t0
, rt
);
13509 #if defined(CONFIG_USER_ONLY)
13510 tcg_gen_ld_tl(t0
, cpu_env
,
13511 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13512 gen_store_gpr(t0
, rt
);
13515 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
13516 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
13517 tcg_gen_ld_tl(t0
, cpu_env
,
13518 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13519 gen_store_gpr(t0
, rt
);
13521 generate_exception_end(ctx
, EXCP_RI
);
13525 default: /* Invalid */
13526 MIPS_INVAL("rdhwr");
13527 generate_exception_end(ctx
, EXCP_RI
);
13533 static inline void clear_branch_hflags(DisasContext
*ctx
)
13535 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
13536 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
13537 save_cpu_state(ctx
, 0);
13540 * It is not safe to save ctx->hflags as hflags may be changed
13541 * in execution time by the instruction in delay / forbidden slot.
13543 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
13547 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
13549 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13550 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
13551 /* Branches completion */
13552 clear_branch_hflags(ctx
);
13553 ctx
->base
.is_jmp
= DISAS_NORETURN
;
13554 /* FIXME: Need to clear can_do_io. */
13555 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
13556 case MIPS_HFLAG_FBNSLOT
:
13557 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
13560 /* unconditional branch */
13561 if (proc_hflags
& MIPS_HFLAG_BX
) {
13562 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
13564 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13566 case MIPS_HFLAG_BL
:
13567 /* blikely taken case */
13568 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13570 case MIPS_HFLAG_BC
:
13571 /* Conditional branch */
13573 TCGLabel
*l1
= gen_new_label();
13575 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
13576 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
13578 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13581 case MIPS_HFLAG_BR
:
13582 /* unconditional branch to register */
13583 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
13584 TCGv t0
= tcg_temp_new();
13585 TCGv_i32 t1
= tcg_temp_new_i32();
13587 tcg_gen_andi_tl(t0
, btarget
, 0x1);
13588 tcg_gen_trunc_tl_i32(t1
, t0
);
13590 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
13591 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
13592 tcg_gen_or_i32(hflags
, hflags
, t1
);
13593 tcg_temp_free_i32(t1
);
13595 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
13597 tcg_gen_mov_tl(cpu_PC
, btarget
);
13599 if (ctx
->base
.singlestep_enabled
) {
13600 save_cpu_state(ctx
, 0);
13601 gen_helper_raise_exception_debug(cpu_env
);
13603 tcg_gen_lookup_and_goto_ptr();
13606 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
13612 /* Compact Branches */
13613 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
13614 int rs
, int rt
, int32_t offset
)
13616 int bcond_compute
= 0;
13617 TCGv t0
= tcg_temp_new();
13618 TCGv t1
= tcg_temp_new();
13619 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
13621 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13622 #ifdef MIPS_DEBUG_DISAS
13623 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13624 "\n", ctx
->base
.pc_next
);
13626 generate_exception_end(ctx
, EXCP_RI
);
13630 /* Load needed operands and calculate btarget */
13632 /* compact branch */
13633 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13634 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13635 gen_load_gpr(t0
, rs
);
13636 gen_load_gpr(t1
, rt
);
13638 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13639 if (rs
<= rt
&& rs
== 0) {
13640 /* OPC_BEQZALC, OPC_BNEZALC */
13641 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13644 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13645 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13646 gen_load_gpr(t0
, rs
);
13647 gen_load_gpr(t1
, rt
);
13649 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13651 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13652 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13653 if (rs
== 0 || rs
== rt
) {
13654 /* OPC_BLEZALC, OPC_BGEZALC */
13655 /* OPC_BGTZALC, OPC_BLTZALC */
13656 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13658 gen_load_gpr(t0
, rs
);
13659 gen_load_gpr(t1
, rt
);
13661 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13665 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13670 /* OPC_BEQZC, OPC_BNEZC */
13671 gen_load_gpr(t0
, rs
);
13673 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13675 /* OPC_JIC, OPC_JIALC */
13676 TCGv tbase
= tcg_temp_new();
13677 TCGv toffset
= tcg_temp_new();
13679 gen_load_gpr(tbase
, rt
);
13680 tcg_gen_movi_tl(toffset
, offset
);
13681 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13682 tcg_temp_free(tbase
);
13683 tcg_temp_free(toffset
);
13687 MIPS_INVAL("Compact branch/jump");
13688 generate_exception_end(ctx
, EXCP_RI
);
13692 if (bcond_compute
== 0) {
13693 /* Uncoditional compact branch */
13696 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13699 ctx
->hflags
|= MIPS_HFLAG_BR
;
13702 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13705 ctx
->hflags
|= MIPS_HFLAG_B
;
13708 MIPS_INVAL("Compact branch/jump");
13709 generate_exception_end(ctx
, EXCP_RI
);
13713 /* Generating branch here as compact branches don't have delay slot */
13714 gen_branch(ctx
, 4);
13716 /* Conditional compact branch */
13717 TCGLabel
*fs
= gen_new_label();
13718 save_cpu_state(ctx
, 0);
13721 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13722 if (rs
== 0 && rt
!= 0) {
13724 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13725 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13727 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13730 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13733 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13734 if (rs
== 0 && rt
!= 0) {
13736 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13737 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13739 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13742 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13745 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13746 if (rs
== 0 && rt
!= 0) {
13748 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13749 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13751 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13754 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13757 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13758 if (rs
== 0 && rt
!= 0) {
13760 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13761 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13763 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13766 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13769 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13770 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13772 /* OPC_BOVC, OPC_BNVC */
13773 TCGv t2
= tcg_temp_new();
13774 TCGv t3
= tcg_temp_new();
13775 TCGv t4
= tcg_temp_new();
13776 TCGv input_overflow
= tcg_temp_new();
13778 gen_load_gpr(t0
, rs
);
13779 gen_load_gpr(t1
, rt
);
13780 tcg_gen_ext32s_tl(t2
, t0
);
13781 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13782 tcg_gen_ext32s_tl(t3
, t1
);
13783 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13784 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13786 tcg_gen_add_tl(t4
, t2
, t3
);
13787 tcg_gen_ext32s_tl(t4
, t4
);
13788 tcg_gen_xor_tl(t2
, t2
, t3
);
13789 tcg_gen_xor_tl(t3
, t4
, t3
);
13790 tcg_gen_andc_tl(t2
, t3
, t2
);
13791 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13792 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13793 if (opc
== OPC_BOVC
) {
13795 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13798 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13800 tcg_temp_free(input_overflow
);
13804 } else if (rs
< rt
&& rs
== 0) {
13805 /* OPC_BEQZALC, OPC_BNEZALC */
13806 if (opc
== OPC_BEQZALC
) {
13808 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13811 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13814 /* OPC_BEQC, OPC_BNEC */
13815 if (opc
== OPC_BEQC
) {
13817 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13820 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13825 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13828 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13831 MIPS_INVAL("Compact conditional branch/jump");
13832 generate_exception_end(ctx
, EXCP_RI
);
13836 /* Generating branch here as compact branches don't have delay slot */
13837 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13840 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13848 /* ISA extensions (ASEs) */
13849 /* MIPS16 extension to MIPS32 */
13851 /* MIPS16 major opcodes */
13853 M16_OPC_ADDIUSP
= 0x00,
13854 M16_OPC_ADDIUPC
= 0x01,
13856 M16_OPC_JAL
= 0x03,
13857 M16_OPC_BEQZ
= 0x04,
13858 M16_OPC_BNEQZ
= 0x05,
13859 M16_OPC_SHIFT
= 0x06,
13861 M16_OPC_RRIA
= 0x08,
13862 M16_OPC_ADDIU8
= 0x09,
13863 M16_OPC_SLTI
= 0x0a,
13864 M16_OPC_SLTIU
= 0x0b,
13867 M16_OPC_CMPI
= 0x0e,
13871 M16_OPC_LWSP
= 0x12,
13873 M16_OPC_LBU
= 0x14,
13874 M16_OPC_LHU
= 0x15,
13875 M16_OPC_LWPC
= 0x16,
13876 M16_OPC_LWU
= 0x17,
13879 M16_OPC_SWSP
= 0x1a,
13881 M16_OPC_RRR
= 0x1c,
13883 M16_OPC_EXTEND
= 0x1e,
13887 /* I8 funct field */
13906 /* RR funct field */
13940 /* I64 funct field */
13948 I64_DADDIUPC
= 0x6,
13952 /* RR ry field for CNVT */
13954 RR_RY_CNVT_ZEB
= 0x0,
13955 RR_RY_CNVT_ZEH
= 0x1,
13956 RR_RY_CNVT_ZEW
= 0x2,
13957 RR_RY_CNVT_SEB
= 0x4,
13958 RR_RY_CNVT_SEH
= 0x5,
13959 RR_RY_CNVT_SEW
= 0x6,
13962 static int xlat(int r
)
13964 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13969 static void gen_mips16_save(DisasContext
*ctx
,
13970 int xsregs
, int aregs
,
13971 int do_ra
, int do_s0
, int do_s1
,
13974 TCGv t0
= tcg_temp_new();
13975 TCGv t1
= tcg_temp_new();
13976 TCGv t2
= tcg_temp_new();
14006 generate_exception_end(ctx
, EXCP_RI
);
14012 gen_base_offset_addr(ctx
, t0
, 29, 12);
14013 gen_load_gpr(t1
, 7);
14014 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14017 gen_base_offset_addr(ctx
, t0
, 29, 8);
14018 gen_load_gpr(t1
, 6);
14019 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14022 gen_base_offset_addr(ctx
, t0
, 29, 4);
14023 gen_load_gpr(t1
, 5);
14024 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14027 gen_base_offset_addr(ctx
, t0
, 29, 0);
14028 gen_load_gpr(t1
, 4);
14029 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
14032 gen_load_gpr(t0
, 29);
14034 #define DECR_AND_STORE(reg) do { \
14035 tcg_gen_movi_tl(t2, -4); \
14036 gen_op_addr_add(ctx, t0, t0, t2); \
14037 gen_load_gpr(t1, reg); \
14038 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
14042 DECR_AND_STORE(31);
14047 DECR_AND_STORE(30);
14050 DECR_AND_STORE(23);
14053 DECR_AND_STORE(22);
14056 DECR_AND_STORE(21);
14059 DECR_AND_STORE(20);
14062 DECR_AND_STORE(19);
14065 DECR_AND_STORE(18);
14069 DECR_AND_STORE(17);
14072 DECR_AND_STORE(16);
14102 generate_exception_end(ctx
, EXCP_RI
);
14118 #undef DECR_AND_STORE
14120 tcg_gen_movi_tl(t2
, -framesize
);
14121 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
14127 static void gen_mips16_restore(DisasContext
*ctx
,
14128 int xsregs
, int aregs
,
14129 int do_ra
, int do_s0
, int do_s1
,
14133 TCGv t0
= tcg_temp_new();
14134 TCGv t1
= tcg_temp_new();
14135 TCGv t2
= tcg_temp_new();
14137 tcg_gen_movi_tl(t2
, framesize
);
14138 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
14140 #define DECR_AND_LOAD(reg) do { \
14141 tcg_gen_movi_tl(t2, -4); \
14142 gen_op_addr_add(ctx, t0, t0, t2); \
14143 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
14144 gen_store_gpr(t1, reg); \
14208 generate_exception_end(ctx
, EXCP_RI
);
14224 #undef DECR_AND_LOAD
14226 tcg_gen_movi_tl(t2
, framesize
);
14227 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
14233 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
14234 int is_64_bit
, int extended
)
14238 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
14239 generate_exception_end(ctx
, EXCP_RI
);
14243 t0
= tcg_temp_new();
14245 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
14246 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
14248 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14254 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
14257 TCGv_i32 t0
= tcg_const_i32(op
);
14258 TCGv t1
= tcg_temp_new();
14259 gen_base_offset_addr(ctx
, t1
, base
, offset
);
14260 gen_helper_cache(cpu_env
, t1
, t0
);
14263 #if defined(TARGET_MIPS64)
14264 static void decode_i64_mips16(DisasContext
*ctx
,
14265 int ry
, int funct
, int16_t offset
,
14270 check_insn(ctx
, ISA_MIPS3
);
14271 check_mips_64(ctx
);
14272 offset
= extended
? offset
: offset
<< 3;
14273 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
14276 check_insn(ctx
, ISA_MIPS3
);
14277 check_mips_64(ctx
);
14278 offset
= extended
? offset
: offset
<< 3;
14279 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
14282 check_insn(ctx
, ISA_MIPS3
);
14283 check_mips_64(ctx
);
14284 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
14285 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
14288 check_insn(ctx
, ISA_MIPS3
);
14289 check_mips_64(ctx
);
14290 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
14291 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
14294 check_insn(ctx
, ISA_MIPS3
);
14295 check_mips_64(ctx
);
14296 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
14297 generate_exception_end(ctx
, EXCP_RI
);
14299 offset
= extended
? offset
: offset
<< 3;
14300 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
14304 check_insn(ctx
, ISA_MIPS3
);
14305 check_mips_64(ctx
);
14306 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
14307 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
14310 check_insn(ctx
, ISA_MIPS3
);
14311 check_mips_64(ctx
);
14312 offset
= extended
? offset
: offset
<< 2;
14313 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
14316 check_insn(ctx
, ISA_MIPS3
);
14317 check_mips_64(ctx
);
14318 offset
= extended
? offset
: offset
<< 2;
14319 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
14325 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14327 int extend
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14328 int op
, rx
, ry
, funct
, sa
;
14329 int16_t imm
, offset
;
14331 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
14332 op
= (ctx
->opcode
>> 11) & 0x1f;
14333 sa
= (ctx
->opcode
>> 22) & 0x1f;
14334 funct
= (ctx
->opcode
>> 8) & 0x7;
14335 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14336 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14337 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
14338 | ((ctx
->opcode
>> 21) & 0x3f) << 5
14339 | (ctx
->opcode
& 0x1f));
14342 * The extended opcodes cleverly reuse the opcodes from their 16-bit
14346 case M16_OPC_ADDIUSP
:
14347 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14349 case M16_OPC_ADDIUPC
:
14350 gen_addiupc(ctx
, rx
, imm
, 0, 1);
14353 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
14354 /* No delay slot, so just process as a normal instruction */
14357 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
14358 /* No delay slot, so just process as a normal instruction */
14360 case M16_OPC_BNEQZ
:
14361 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
14362 /* No delay slot, so just process as a normal instruction */
14364 case M16_OPC_SHIFT
:
14365 switch (ctx
->opcode
& 0x3) {
14367 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14370 #if defined(TARGET_MIPS64)
14371 check_mips_64(ctx
);
14372 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14374 generate_exception_end(ctx
, EXCP_RI
);
14378 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14381 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14385 #if defined(TARGET_MIPS64)
14387 check_insn(ctx
, ISA_MIPS3
);
14388 check_mips_64(ctx
);
14389 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
14393 imm
= ctx
->opcode
& 0xf;
14394 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
14395 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
14396 imm
= (int16_t) (imm
<< 1) >> 1;
14397 if ((ctx
->opcode
>> 4) & 0x1) {
14398 #if defined(TARGET_MIPS64)
14399 check_mips_64(ctx
);
14400 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14402 generate_exception_end(ctx
, EXCP_RI
);
14405 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14408 case M16_OPC_ADDIU8
:
14409 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14412 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14414 case M16_OPC_SLTIU
:
14415 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14420 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
14423 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
14426 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
14429 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
14432 check_insn(ctx
, ISA_MIPS32
);
14434 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
14435 int aregs
= (ctx
->opcode
>> 16) & 0xf;
14436 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
14437 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
14438 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
14439 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
14440 | (ctx
->opcode
& 0xf)) << 3;
14442 if (ctx
->opcode
& (1 << 7)) {
14443 gen_mips16_save(ctx
, xsregs
, aregs
,
14444 do_ra
, do_s0
, do_s1
,
14447 gen_mips16_restore(ctx
, xsregs
, aregs
,
14448 do_ra
, do_s0
, do_s1
,
14454 generate_exception_end(ctx
, EXCP_RI
);
14459 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
14462 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
14464 #if defined(TARGET_MIPS64)
14466 check_insn(ctx
, ISA_MIPS3
);
14467 check_mips_64(ctx
);
14468 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
14472 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14475 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
14478 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
14481 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
14484 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14487 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
14490 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
14492 #if defined(TARGET_MIPS64)
14494 check_insn(ctx
, ISA_MIPS3
);
14495 check_mips_64(ctx
);
14496 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
14500 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14503 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
14506 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
14509 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
14511 #if defined(TARGET_MIPS64)
14513 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
14517 generate_exception_end(ctx
, EXCP_RI
);
14524 static inline bool is_uhi(int sdbbp_code
)
14526 #ifdef CONFIG_USER_ONLY
14529 return semihosting_enabled() && sdbbp_code
== 1;
14533 #ifdef CONFIG_USER_ONLY
14534 /* The above should dead-code away any calls to this..*/
14535 static inline void gen_helper_do_semihosting(void *env
)
14537 g_assert_not_reached();
14541 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14545 int op
, cnvt_op
, op1
, offset
;
14549 op
= (ctx
->opcode
>> 11) & 0x1f;
14550 sa
= (ctx
->opcode
>> 2) & 0x7;
14551 sa
= sa
== 0 ? 8 : sa
;
14552 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14553 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
14554 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14555 op1
= offset
= ctx
->opcode
& 0x1f;
14560 case M16_OPC_ADDIUSP
:
14562 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
14564 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14567 case M16_OPC_ADDIUPC
:
14568 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
14571 offset
= (ctx
->opcode
& 0x7ff) << 1;
14572 offset
= (int16_t)(offset
<< 4) >> 4;
14573 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
14574 /* No delay slot, so just process as a normal instruction */
14577 offset
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14578 offset
= (((ctx
->opcode
& 0x1f) << 21)
14579 | ((ctx
->opcode
>> 5) & 0x1f) << 16
14581 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
14582 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
14586 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
14587 ((int8_t)ctx
->opcode
) << 1, 0);
14588 /* No delay slot, so just process as a normal instruction */
14590 case M16_OPC_BNEQZ
:
14591 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
14592 ((int8_t)ctx
->opcode
) << 1, 0);
14593 /* No delay slot, so just process as a normal instruction */
14595 case M16_OPC_SHIFT
:
14596 switch (ctx
->opcode
& 0x3) {
14598 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14601 #if defined(TARGET_MIPS64)
14602 check_insn(ctx
, ISA_MIPS3
);
14603 check_mips_64(ctx
);
14604 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14606 generate_exception_end(ctx
, EXCP_RI
);
14610 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14613 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14617 #if defined(TARGET_MIPS64)
14619 check_insn(ctx
, ISA_MIPS3
);
14620 check_mips_64(ctx
);
14621 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14626 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14628 if ((ctx
->opcode
>> 4) & 1) {
14629 #if defined(TARGET_MIPS64)
14630 check_insn(ctx
, ISA_MIPS3
);
14631 check_mips_64(ctx
);
14632 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14634 generate_exception_end(ctx
, EXCP_RI
);
14637 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14641 case M16_OPC_ADDIU8
:
14643 int16_t imm
= (int8_t) ctx
->opcode
;
14645 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14650 int16_t imm
= (uint8_t) ctx
->opcode
;
14651 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14654 case M16_OPC_SLTIU
:
14656 int16_t imm
= (uint8_t) ctx
->opcode
;
14657 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14664 funct
= (ctx
->opcode
>> 8) & 0x7;
14667 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14668 ((int8_t)ctx
->opcode
) << 1, 0);
14671 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14672 ((int8_t)ctx
->opcode
) << 1, 0);
14675 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14678 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14679 ((int8_t)ctx
->opcode
) << 3);
14682 check_insn(ctx
, ISA_MIPS32
);
14684 int do_ra
= ctx
->opcode
& (1 << 6);
14685 int do_s0
= ctx
->opcode
& (1 << 5);
14686 int do_s1
= ctx
->opcode
& (1 << 4);
14687 int framesize
= ctx
->opcode
& 0xf;
14689 if (framesize
== 0) {
14692 framesize
= framesize
<< 3;
14695 if (ctx
->opcode
& (1 << 7)) {
14696 gen_mips16_save(ctx
, 0, 0,
14697 do_ra
, do_s0
, do_s1
, framesize
);
14699 gen_mips16_restore(ctx
, 0, 0,
14700 do_ra
, do_s0
, do_s1
, framesize
);
14706 int rz
= xlat(ctx
->opcode
& 0x7);
14708 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14709 ((ctx
->opcode
>> 5) & 0x7);
14710 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14714 reg32
= ctx
->opcode
& 0x1f;
14715 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14718 generate_exception_end(ctx
, EXCP_RI
);
14725 int16_t imm
= (uint8_t) ctx
->opcode
;
14727 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14732 int16_t imm
= (uint8_t) ctx
->opcode
;
14733 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14736 #if defined(TARGET_MIPS64)
14738 check_insn(ctx
, ISA_MIPS3
);
14739 check_mips_64(ctx
);
14740 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14744 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14747 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14750 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14753 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14756 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14759 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14762 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14764 #if defined(TARGET_MIPS64)
14766 check_insn(ctx
, ISA_MIPS3
);
14767 check_mips_64(ctx
);
14768 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14772 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14775 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14778 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14781 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14785 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14788 switch (ctx
->opcode
& 0x3) {
14790 mips32_op
= OPC_ADDU
;
14793 mips32_op
= OPC_SUBU
;
14795 #if defined(TARGET_MIPS64)
14797 mips32_op
= OPC_DADDU
;
14798 check_insn(ctx
, ISA_MIPS3
);
14799 check_mips_64(ctx
);
14802 mips32_op
= OPC_DSUBU
;
14803 check_insn(ctx
, ISA_MIPS3
);
14804 check_mips_64(ctx
);
14808 generate_exception_end(ctx
, EXCP_RI
);
14812 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14821 int nd
= (ctx
->opcode
>> 7) & 0x1;
14822 int link
= (ctx
->opcode
>> 6) & 0x1;
14823 int ra
= (ctx
->opcode
>> 5) & 0x1;
14826 check_insn(ctx
, ISA_MIPS32
);
14835 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14840 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14841 gen_helper_do_semihosting(cpu_env
);
14844 * XXX: not clear which exception should be raised
14845 * when in debug mode...
14847 check_insn(ctx
, ISA_MIPS32
);
14848 generate_exception_end(ctx
, EXCP_DBp
);
14852 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14855 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14858 generate_exception_end(ctx
, EXCP_BREAK
);
14861 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14864 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14867 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14869 #if defined(TARGET_MIPS64)
14871 check_insn(ctx
, ISA_MIPS3
);
14872 check_mips_64(ctx
);
14873 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14877 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14880 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14883 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14886 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14889 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14892 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14895 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14898 check_insn(ctx
, ISA_MIPS32
);
14900 case RR_RY_CNVT_ZEB
:
14901 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14903 case RR_RY_CNVT_ZEH
:
14904 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14906 case RR_RY_CNVT_SEB
:
14907 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14909 case RR_RY_CNVT_SEH
:
14910 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14912 #if defined(TARGET_MIPS64)
14913 case RR_RY_CNVT_ZEW
:
14914 check_insn(ctx
, ISA_MIPS64
);
14915 check_mips_64(ctx
);
14916 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14918 case RR_RY_CNVT_SEW
:
14919 check_insn(ctx
, ISA_MIPS64
);
14920 check_mips_64(ctx
);
14921 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14925 generate_exception_end(ctx
, EXCP_RI
);
14930 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14932 #if defined(TARGET_MIPS64)
14934 check_insn(ctx
, ISA_MIPS3
);
14935 check_mips_64(ctx
);
14936 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14939 check_insn(ctx
, ISA_MIPS3
);
14940 check_mips_64(ctx
);
14941 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14944 check_insn(ctx
, ISA_MIPS3
);
14945 check_mips_64(ctx
);
14946 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14949 check_insn(ctx
, ISA_MIPS3
);
14950 check_mips_64(ctx
);
14951 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14955 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14958 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14961 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14964 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14966 #if defined(TARGET_MIPS64)
14968 check_insn(ctx
, ISA_MIPS3
);
14969 check_mips_64(ctx
);
14970 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14973 check_insn(ctx
, ISA_MIPS3
);
14974 check_mips_64(ctx
);
14975 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14978 check_insn(ctx
, ISA_MIPS3
);
14979 check_mips_64(ctx
);
14980 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14983 check_insn(ctx
, ISA_MIPS3
);
14984 check_mips_64(ctx
);
14985 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14989 generate_exception_end(ctx
, EXCP_RI
);
14993 case M16_OPC_EXTEND
:
14994 decode_extended_mips16_opc(env
, ctx
);
14997 #if defined(TARGET_MIPS64)
14999 funct
= (ctx
->opcode
>> 8) & 0x7;
15000 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
15004 generate_exception_end(ctx
, EXCP_RI
);
15011 /* microMIPS extension to MIPS32/MIPS64 */
15014 * microMIPS32/microMIPS64 major opcodes
15016 * 1. MIPS Architecture for Programmers Volume II-B:
15017 * The microMIPS32 Instruction Set (Revision 3.05)
15019 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
15021 * 2. MIPS Architecture For Programmers Volume II-A:
15022 * The MIPS64 Instruction Set (Revision 3.51)
15052 POOL32S
= 0x16, /* MIPS64 */
15053 DADDIU32
= 0x17, /* MIPS64 */
15082 /* 0x29 is reserved */
15095 /* 0x31 is reserved */
15108 SD32
= 0x36, /* MIPS64 */
15109 LD32
= 0x37, /* MIPS64 */
15111 /* 0x39 is reserved */
15127 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
15149 /* POOL32A encoding of minor opcode field */
15153 * These opcodes are distinguished only by bits 9..6; those bits are
15154 * what are recorded below.
15192 /* The following can be distinguished by their lower 6 bits. */
15202 /* POOL32AXF encoding of minor opcode field extension */
15205 * 1. MIPS Architecture for Programmers Volume II-B:
15206 * The microMIPS32 Instruction Set (Revision 3.05)
15208 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
15210 * 2. MIPS Architecture for Programmers VolumeIV-e:
15211 * The MIPS DSP Application-Specific Extension
15212 * to the microMIPS32 Architecture (Revision 2.34)
15214 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
15229 /* begin of microMIPS32 DSP */
15231 /* bits 13..12 for 0x01 */
15237 /* bits 13..12 for 0x2a */
15243 /* bits 13..12 for 0x32 */
15247 /* end of microMIPS32 DSP */
15249 /* bits 15..12 for 0x2c */
15266 /* bits 15..12 for 0x34 */
15274 /* bits 15..12 for 0x3c */
15276 JR
= 0x0, /* alias */
15284 /* bits 15..12 for 0x05 */
15288 /* bits 15..12 for 0x0d */
15300 /* bits 15..12 for 0x15 */
15306 /* bits 15..12 for 0x1d */
15310 /* bits 15..12 for 0x2d */
15315 /* bits 15..12 for 0x35 */
15322 /* POOL32B encoding of minor opcode field (bits 15..12) */
15338 /* POOL32C encoding of minor opcode field (bits 15..12) */
15359 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
15372 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
15385 /* POOL32F encoding of minor opcode field (bits 5..0) */
15388 /* These are the bit 7..6 values */
15397 /* These are the bit 8..6 values */
15422 MOVZ_FMT_05
= 0x05,
15456 CABS_COND_FMT
= 0x1c, /* MIPS3D */
15463 /* POOL32Fxf encoding of minor opcode extension field */
15501 /* POOL32I encoding of minor opcode field (bits 25..21) */
15531 /* These overlap and are distinguished by bit16 of the instruction */
15540 /* POOL16A encoding of minor opcode field */
15547 /* POOL16B encoding of minor opcode field */
15554 /* POOL16C encoding of minor opcode field */
15574 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15598 /* POOL16D encoding of minor opcode field */
15605 /* POOL16E encoding of minor opcode field */
15612 static int mmreg(int r
)
15614 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15619 /* Used for 16-bit store instructions. */
15620 static int mmreg2(int r
)
15622 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15627 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15628 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15629 #define uMIPS_RS2(op) uMIPS_RS(op)
15630 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15631 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15632 #define uMIPS_RS5(op) (op & 0x1f)
15634 /* Signed immediate */
15635 #define SIMM(op, start, width) \
15636 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15639 /* Zero-extended immediate */
15640 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15642 static void gen_addiur1sp(DisasContext
*ctx
)
15644 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15646 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15649 static void gen_addiur2(DisasContext
*ctx
)
15651 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15652 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15653 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15655 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15658 static void gen_addiusp(DisasContext
*ctx
)
15660 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15663 if (encoded
<= 1) {
15664 decoded
= 256 + encoded
;
15665 } else if (encoded
<= 255) {
15667 } else if (encoded
<= 509) {
15668 decoded
= encoded
- 512;
15670 decoded
= encoded
- 768;
15673 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15676 static void gen_addius5(DisasContext
*ctx
)
15678 int imm
= SIMM(ctx
->opcode
, 1, 4);
15679 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15681 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15684 static void gen_andi16(DisasContext
*ctx
)
15686 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15687 31, 32, 63, 64, 255, 32768, 65535 };
15688 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15689 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15690 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15692 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15695 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15696 int base
, int16_t offset
)
15701 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15702 generate_exception_end(ctx
, EXCP_RI
);
15706 t0
= tcg_temp_new();
15708 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15710 t1
= tcg_const_tl(reglist
);
15711 t2
= tcg_const_i32(ctx
->mem_idx
);
15713 save_cpu_state(ctx
, 1);
15716 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15719 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15721 #ifdef TARGET_MIPS64
15723 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15726 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15732 tcg_temp_free_i32(t2
);
15736 static void gen_pool16c_insn(DisasContext
*ctx
)
15738 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15739 int rs
= mmreg(ctx
->opcode
& 0x7);
15741 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15746 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15752 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15758 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15764 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15771 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15772 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15774 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15783 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15784 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15786 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15793 int reg
= ctx
->opcode
& 0x1f;
15795 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15801 int reg
= ctx
->opcode
& 0x1f;
15802 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15804 * Let normal delay slot handling in our caller take us
15805 * to the branch target.
15811 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15812 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15816 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15817 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15821 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15825 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15828 generate_exception_end(ctx
, EXCP_BREAK
);
15831 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15832 gen_helper_do_semihosting(cpu_env
);
15835 * XXX: not clear which exception should be raised
15836 * when in debug mode...
15838 check_insn(ctx
, ISA_MIPS32
);
15839 generate_exception_end(ctx
, EXCP_DBp
);
15842 case JRADDIUSP
+ 0:
15843 case JRADDIUSP
+ 1:
15845 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15846 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15847 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15849 * Let normal delay slot handling in our caller take us
15850 * to the branch target.
15855 generate_exception_end(ctx
, EXCP_RI
);
15860 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15863 int rd
, rs
, re
, rt
;
15864 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15865 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15866 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15867 rd
= rd_enc
[enc_dest
];
15868 re
= re_enc
[enc_dest
];
15869 rs
= rs_rt_enc
[enc_rs
];
15870 rt
= rs_rt_enc
[enc_rt
];
15872 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15874 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15877 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15879 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15883 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15885 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15886 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15888 switch (ctx
->opcode
& 0xf) {
15890 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15893 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15897 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15898 int offset
= extract32(ctx
->opcode
, 4, 4);
15899 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15902 case R6_JRC16
: /* JRCADDIUSP */
15903 if ((ctx
->opcode
>> 4) & 1) {
15905 int imm
= extract32(ctx
->opcode
, 5, 5);
15906 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15907 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15910 rs
= extract32(ctx
->opcode
, 5, 5);
15911 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15923 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15924 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15925 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15926 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15930 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15933 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15937 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15938 int offset
= extract32(ctx
->opcode
, 4, 4);
15939 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15942 case JALRC16
: /* BREAK16, SDBBP16 */
15943 switch (ctx
->opcode
& 0x3f) {
15945 case JALRC16
+ 0x20:
15947 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15952 generate_exception(ctx
, EXCP_BREAK
);
15956 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15957 gen_helper_do_semihosting(cpu_env
);
15959 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15960 generate_exception(ctx
, EXCP_RI
);
15962 generate_exception(ctx
, EXCP_DBp
);
15969 generate_exception(ctx
, EXCP_RI
);
15974 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15976 TCGv t0
= tcg_temp_new();
15977 TCGv t1
= tcg_temp_new();
15979 gen_load_gpr(t0
, base
);
15982 gen_load_gpr(t1
, index
);
15983 tcg_gen_shli_tl(t1
, t1
, 2);
15984 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15987 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15988 gen_store_gpr(t1
, rd
);
15994 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15995 int base
, int16_t offset
)
15999 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
16000 generate_exception_end(ctx
, EXCP_RI
);
16004 t0
= tcg_temp_new();
16005 t1
= tcg_temp_new();
16007 gen_base_offset_addr(ctx
, t0
, base
, offset
);
16012 generate_exception_end(ctx
, EXCP_RI
);
16015 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
16016 gen_store_gpr(t1
, rd
);
16017 tcg_gen_movi_tl(t1
, 4);
16018 gen_op_addr_add(ctx
, t0
, t0
, t1
);
16019 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
16020 gen_store_gpr(t1
, rd
+ 1);
16023 gen_load_gpr(t1
, rd
);
16024 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
16025 tcg_gen_movi_tl(t1
, 4);
16026 gen_op_addr_add(ctx
, t0
, t0
, t1
);
16027 gen_load_gpr(t1
, rd
+ 1);
16028 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
16030 #ifdef TARGET_MIPS64
16033 generate_exception_end(ctx
, EXCP_RI
);
16036 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
16037 gen_store_gpr(t1
, rd
);
16038 tcg_gen_movi_tl(t1
, 8);
16039 gen_op_addr_add(ctx
, t0
, t0
, t1
);
16040 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
16041 gen_store_gpr(t1
, rd
+ 1);
16044 gen_load_gpr(t1
, rd
);
16045 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
16046 tcg_gen_movi_tl(t1
, 8);
16047 gen_op_addr_add(ctx
, t0
, t0
, t1
);
16048 gen_load_gpr(t1
, rd
+ 1);
16049 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
16057 static void gen_sync(int stype
)
16059 TCGBar tcg_mo
= TCG_BAR_SC
;
16062 case 0x4: /* SYNC_WMB */
16063 tcg_mo
|= TCG_MO_ST_ST
;
16065 case 0x10: /* SYNC_MB */
16066 tcg_mo
|= TCG_MO_ALL
;
16068 case 0x11: /* SYNC_ACQUIRE */
16069 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
16071 case 0x12: /* SYNC_RELEASE */
16072 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
16074 case 0x13: /* SYNC_RMB */
16075 tcg_mo
|= TCG_MO_LD_LD
;
16078 tcg_mo
|= TCG_MO_ALL
;
16082 tcg_gen_mb(tcg_mo
);
16085 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
16087 int extension
= (ctx
->opcode
>> 6) & 0x3f;
16088 int minor
= (ctx
->opcode
>> 12) & 0xf;
16089 uint32_t mips32_op
;
16091 switch (extension
) {
16093 mips32_op
= OPC_TEQ
;
16096 mips32_op
= OPC_TGE
;
16099 mips32_op
= OPC_TGEU
;
16102 mips32_op
= OPC_TLT
;
16105 mips32_op
= OPC_TLTU
;
16108 mips32_op
= OPC_TNE
;
16110 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
16112 #ifndef CONFIG_USER_ONLY
16115 check_cp0_enabled(ctx
);
16117 /* Treat as NOP. */
16120 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
16124 check_cp0_enabled(ctx
);
16126 TCGv t0
= tcg_temp_new();
16128 gen_load_gpr(t0
, rt
);
16129 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
16135 switch (minor
& 3) {
16137 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16140 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16143 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16146 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16149 goto pool32axf_invalid
;
16153 switch (minor
& 3) {
16155 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16158 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16161 goto pool32axf_invalid
;
16167 check_insn(ctx
, ISA_MIPS32R6
);
16168 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
16171 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
16174 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
16177 mips32_op
= OPC_CLO
;
16180 mips32_op
= OPC_CLZ
;
16182 check_insn(ctx
, ISA_MIPS32
);
16183 gen_cl(ctx
, mips32_op
, rt
, rs
);
16186 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16187 gen_rdhwr(ctx
, rt
, rs
, 0);
16190 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
16193 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16194 mips32_op
= OPC_MULT
;
16197 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16198 mips32_op
= OPC_MULTU
;
16201 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16202 mips32_op
= OPC_DIV
;
16205 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16206 mips32_op
= OPC_DIVU
;
16209 check_insn(ctx
, ISA_MIPS32
);
16210 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
16213 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16214 mips32_op
= OPC_MADD
;
16217 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16218 mips32_op
= OPC_MADDU
;
16221 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16222 mips32_op
= OPC_MSUB
;
16225 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16226 mips32_op
= OPC_MSUBU
;
16228 check_insn(ctx
, ISA_MIPS32
);
16229 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
16232 goto pool32axf_invalid
;
16243 generate_exception_err(ctx
, EXCP_CpU
, 2);
16246 goto pool32axf_invalid
;
16251 case JALR
: /* JALRC */
16252 case JALR_HB
: /* JALRC_HB */
16253 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16254 /* JALRC, JALRC_HB */
16255 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
16257 /* JALR, JALR_HB */
16258 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
16259 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16264 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16265 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
16266 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16269 goto pool32axf_invalid
;
16275 check_cp0_enabled(ctx
);
16276 check_insn(ctx
, ISA_MIPS32R2
);
16277 gen_load_srsgpr(rs
, rt
);
16280 check_cp0_enabled(ctx
);
16281 check_insn(ctx
, ISA_MIPS32R2
);
16282 gen_store_srsgpr(rs
, rt
);
16285 goto pool32axf_invalid
;
16288 #ifndef CONFIG_USER_ONLY
16292 mips32_op
= OPC_TLBP
;
16295 mips32_op
= OPC_TLBR
;
16298 mips32_op
= OPC_TLBWI
;
16301 mips32_op
= OPC_TLBWR
;
16304 mips32_op
= OPC_TLBINV
;
16307 mips32_op
= OPC_TLBINVF
;
16310 mips32_op
= OPC_WAIT
;
16313 mips32_op
= OPC_DERET
;
16316 mips32_op
= OPC_ERET
;
16318 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
16321 goto pool32axf_invalid
;
16327 check_cp0_enabled(ctx
);
16329 TCGv t0
= tcg_temp_new();
16331 save_cpu_state(ctx
, 1);
16332 gen_helper_di(t0
, cpu_env
);
16333 gen_store_gpr(t0
, rs
);
16335 * Stop translation as we may have switched the execution
16338 ctx
->base
.is_jmp
= DISAS_STOP
;
16343 check_cp0_enabled(ctx
);
16345 TCGv t0
= tcg_temp_new();
16347 save_cpu_state(ctx
, 1);
16348 gen_helper_ei(t0
, cpu_env
);
16349 gen_store_gpr(t0
, rs
);
16351 * DISAS_STOP isn't sufficient, we need to ensure we break out
16352 * of translated code to check for pending interrupts.
16354 gen_save_pc(ctx
->base
.pc_next
+ 4);
16355 ctx
->base
.is_jmp
= DISAS_EXIT
;
16360 goto pool32axf_invalid
;
16367 gen_sync(extract32(ctx
->opcode
, 16, 5));
16370 generate_exception_end(ctx
, EXCP_SYSCALL
);
16373 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
16374 gen_helper_do_semihosting(cpu_env
);
16376 check_insn(ctx
, ISA_MIPS32
);
16377 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
16378 generate_exception_end(ctx
, EXCP_RI
);
16380 generate_exception_end(ctx
, EXCP_DBp
);
16385 goto pool32axf_invalid
;
16389 switch (minor
& 3) {
16391 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
16394 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
16397 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
16400 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
16403 goto pool32axf_invalid
;
16407 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16410 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
16413 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
16416 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
16419 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
16422 goto pool32axf_invalid
;
16427 MIPS_INVAL("pool32axf");
16428 generate_exception_end(ctx
, EXCP_RI
);
16434 * Values for microMIPS fmt field. Variable-width, depending on which
16435 * formats the instruction supports.
16454 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
16456 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
16457 uint32_t mips32_op
;
16459 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
16460 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
16461 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
16463 switch (extension
) {
16464 case FLOAT_1BIT_FMT(CFC1
, 0):
16465 mips32_op
= OPC_CFC1
;
16467 case FLOAT_1BIT_FMT(CTC1
, 0):
16468 mips32_op
= OPC_CTC1
;
16470 case FLOAT_1BIT_FMT(MFC1
, 0):
16471 mips32_op
= OPC_MFC1
;
16473 case FLOAT_1BIT_FMT(MTC1
, 0):
16474 mips32_op
= OPC_MTC1
;
16476 case FLOAT_1BIT_FMT(MFHC1
, 0):
16477 mips32_op
= OPC_MFHC1
;
16479 case FLOAT_1BIT_FMT(MTHC1
, 0):
16480 mips32_op
= OPC_MTHC1
;
16482 gen_cp1(ctx
, mips32_op
, rt
, rs
);
16485 /* Reciprocal square root */
16486 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
16487 mips32_op
= OPC_RSQRT_S
;
16489 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
16490 mips32_op
= OPC_RSQRT_D
;
16494 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
16495 mips32_op
= OPC_SQRT_S
;
16497 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
16498 mips32_op
= OPC_SQRT_D
;
16502 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
16503 mips32_op
= OPC_RECIP_S
;
16505 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
16506 mips32_op
= OPC_RECIP_D
;
16510 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
16511 mips32_op
= OPC_FLOOR_L_S
;
16513 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
16514 mips32_op
= OPC_FLOOR_L_D
;
16516 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
16517 mips32_op
= OPC_FLOOR_W_S
;
16519 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
16520 mips32_op
= OPC_FLOOR_W_D
;
16524 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
16525 mips32_op
= OPC_CEIL_L_S
;
16527 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
16528 mips32_op
= OPC_CEIL_L_D
;
16530 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
16531 mips32_op
= OPC_CEIL_W_S
;
16533 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
16534 mips32_op
= OPC_CEIL_W_D
;
16538 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
16539 mips32_op
= OPC_TRUNC_L_S
;
16541 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
16542 mips32_op
= OPC_TRUNC_L_D
;
16544 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
16545 mips32_op
= OPC_TRUNC_W_S
;
16547 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
16548 mips32_op
= OPC_TRUNC_W_D
;
16552 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
16553 mips32_op
= OPC_ROUND_L_S
;
16555 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
16556 mips32_op
= OPC_ROUND_L_D
;
16558 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
16559 mips32_op
= OPC_ROUND_W_S
;
16561 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
16562 mips32_op
= OPC_ROUND_W_D
;
16565 /* Integer to floating-point conversion */
16566 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
16567 mips32_op
= OPC_CVT_L_S
;
16569 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
16570 mips32_op
= OPC_CVT_L_D
;
16572 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
16573 mips32_op
= OPC_CVT_W_S
;
16575 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
16576 mips32_op
= OPC_CVT_W_D
;
16579 /* Paired-foo conversions */
16580 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
16581 mips32_op
= OPC_CVT_S_PL
;
16583 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
16584 mips32_op
= OPC_CVT_S_PU
;
16586 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
16587 mips32_op
= OPC_CVT_PW_PS
;
16589 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
16590 mips32_op
= OPC_CVT_PS_PW
;
16593 /* Floating-point moves */
16594 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
16595 mips32_op
= OPC_MOV_S
;
16597 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
16598 mips32_op
= OPC_MOV_D
;
16600 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
16601 mips32_op
= OPC_MOV_PS
;
16604 /* Absolute value */
16605 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
16606 mips32_op
= OPC_ABS_S
;
16608 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
16609 mips32_op
= OPC_ABS_D
;
16611 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
16612 mips32_op
= OPC_ABS_PS
;
16616 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
16617 mips32_op
= OPC_NEG_S
;
16619 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
16620 mips32_op
= OPC_NEG_D
;
16622 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16623 mips32_op
= OPC_NEG_PS
;
16626 /* Reciprocal square root step */
16627 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16628 mips32_op
= OPC_RSQRT1_S
;
16630 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16631 mips32_op
= OPC_RSQRT1_D
;
16633 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16634 mips32_op
= OPC_RSQRT1_PS
;
16637 /* Reciprocal step */
16638 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16639 mips32_op
= OPC_RECIP1_S
;
16641 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16642 mips32_op
= OPC_RECIP1_S
;
16644 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16645 mips32_op
= OPC_RECIP1_PS
;
16648 /* Conversions from double */
16649 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16650 mips32_op
= OPC_CVT_D_S
;
16652 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16653 mips32_op
= OPC_CVT_D_W
;
16655 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16656 mips32_op
= OPC_CVT_D_L
;
16659 /* Conversions from single */
16660 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16661 mips32_op
= OPC_CVT_S_D
;
16663 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16664 mips32_op
= OPC_CVT_S_W
;
16666 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16667 mips32_op
= OPC_CVT_S_L
;
16669 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16672 /* Conditional moves on floating-point codes */
16673 case COND_FLOAT_MOV(MOVT
, 0):
16674 case COND_FLOAT_MOV(MOVT
, 1):
16675 case COND_FLOAT_MOV(MOVT
, 2):
16676 case COND_FLOAT_MOV(MOVT
, 3):
16677 case COND_FLOAT_MOV(MOVT
, 4):
16678 case COND_FLOAT_MOV(MOVT
, 5):
16679 case COND_FLOAT_MOV(MOVT
, 6):
16680 case COND_FLOAT_MOV(MOVT
, 7):
16681 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16682 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16684 case COND_FLOAT_MOV(MOVF
, 0):
16685 case COND_FLOAT_MOV(MOVF
, 1):
16686 case COND_FLOAT_MOV(MOVF
, 2):
16687 case COND_FLOAT_MOV(MOVF
, 3):
16688 case COND_FLOAT_MOV(MOVF
, 4):
16689 case COND_FLOAT_MOV(MOVF
, 5):
16690 case COND_FLOAT_MOV(MOVF
, 6):
16691 case COND_FLOAT_MOV(MOVF
, 7):
16692 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16693 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16696 MIPS_INVAL("pool32fxf");
16697 generate_exception_end(ctx
, EXCP_RI
);
16702 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16706 int rt
, rs
, rd
, rr
;
16708 uint32_t op
, minor
, minor2
, mips32_op
;
16709 uint32_t cond
, fmt
, cc
;
16711 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
16712 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16714 rt
= (ctx
->opcode
>> 21) & 0x1f;
16715 rs
= (ctx
->opcode
>> 16) & 0x1f;
16716 rd
= (ctx
->opcode
>> 11) & 0x1f;
16717 rr
= (ctx
->opcode
>> 6) & 0x1f;
16718 imm
= (int16_t) ctx
->opcode
;
16720 op
= (ctx
->opcode
>> 26) & 0x3f;
16723 minor
= ctx
->opcode
& 0x3f;
16726 minor
= (ctx
->opcode
>> 6) & 0xf;
16729 mips32_op
= OPC_SLL
;
16732 mips32_op
= OPC_SRA
;
16735 mips32_op
= OPC_SRL
;
16738 mips32_op
= OPC_ROTR
;
16740 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16743 check_insn(ctx
, ISA_MIPS32R6
);
16744 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16747 check_insn(ctx
, ISA_MIPS32R6
);
16748 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16751 check_insn(ctx
, ISA_MIPS32R6
);
16752 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16755 goto pool32a_invalid
;
16759 minor
= (ctx
->opcode
>> 6) & 0xf;
16763 mips32_op
= OPC_ADD
;
16766 mips32_op
= OPC_ADDU
;
16769 mips32_op
= OPC_SUB
;
16772 mips32_op
= OPC_SUBU
;
16775 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16776 mips32_op
= OPC_MUL
;
16778 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16782 mips32_op
= OPC_SLLV
;
16785 mips32_op
= OPC_SRLV
;
16788 mips32_op
= OPC_SRAV
;
16791 mips32_op
= OPC_ROTRV
;
16793 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16795 /* Logical operations */
16797 mips32_op
= OPC_AND
;
16800 mips32_op
= OPC_OR
;
16803 mips32_op
= OPC_NOR
;
16806 mips32_op
= OPC_XOR
;
16808 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16810 /* Set less than */
16812 mips32_op
= OPC_SLT
;
16815 mips32_op
= OPC_SLTU
;
16817 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16820 goto pool32a_invalid
;
16824 minor
= (ctx
->opcode
>> 6) & 0xf;
16826 /* Conditional moves */
16827 case MOVN
: /* MUL */
16828 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16830 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16833 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16836 case MOVZ
: /* MUH */
16837 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16839 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16842 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16846 check_insn(ctx
, ISA_MIPS32R6
);
16847 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16850 check_insn(ctx
, ISA_MIPS32R6
);
16851 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16853 case LWXS
: /* DIV */
16854 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16856 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16859 gen_ldxs(ctx
, rs
, rt
, rd
);
16863 check_insn(ctx
, ISA_MIPS32R6
);
16864 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16867 check_insn(ctx
, ISA_MIPS32R6
);
16868 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16871 check_insn(ctx
, ISA_MIPS32R6
);
16872 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16875 goto pool32a_invalid
;
16879 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16882 check_insn(ctx
, ISA_MIPS32R6
);
16883 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
16884 extract32(ctx
->opcode
, 9, 2));
16887 check_insn(ctx
, ISA_MIPS32R6
);
16888 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16891 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16894 gen_pool32axf(env
, ctx
, rt
, rs
);
16897 generate_exception_end(ctx
, EXCP_BREAK
);
16900 check_insn(ctx
, ISA_MIPS32R6
);
16901 generate_exception_end(ctx
, EXCP_RI
);
16905 MIPS_INVAL("pool32a");
16906 generate_exception_end(ctx
, EXCP_RI
);
16911 minor
= (ctx
->opcode
>> 12) & 0xf;
16914 check_cp0_enabled(ctx
);
16915 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16916 gen_cache_operation(ctx
, rt
, rs
, imm
);
16921 /* COP2: Not implemented. */
16922 generate_exception_err(ctx
, EXCP_CpU
, 2);
16924 #ifdef TARGET_MIPS64
16927 check_insn(ctx
, ISA_MIPS3
);
16928 check_mips_64(ctx
);
16933 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16935 #ifdef TARGET_MIPS64
16938 check_insn(ctx
, ISA_MIPS3
);
16939 check_mips_64(ctx
);
16944 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16947 MIPS_INVAL("pool32b");
16948 generate_exception_end(ctx
, EXCP_RI
);
16953 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16954 minor
= ctx
->opcode
& 0x3f;
16955 check_cp1_enabled(ctx
);
16958 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16959 mips32_op
= OPC_ALNV_PS
;
16962 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16963 mips32_op
= OPC_MADD_S
;
16966 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16967 mips32_op
= OPC_MADD_D
;
16970 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16971 mips32_op
= OPC_MADD_PS
;
16974 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16975 mips32_op
= OPC_MSUB_S
;
16978 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16979 mips32_op
= OPC_MSUB_D
;
16982 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16983 mips32_op
= OPC_MSUB_PS
;
16986 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16987 mips32_op
= OPC_NMADD_S
;
16990 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16991 mips32_op
= OPC_NMADD_D
;
16994 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16995 mips32_op
= OPC_NMADD_PS
;
16998 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16999 mips32_op
= OPC_NMSUB_S
;
17002 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17003 mips32_op
= OPC_NMSUB_D
;
17006 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17007 mips32_op
= OPC_NMSUB_PS
;
17009 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
17011 case CABS_COND_FMT
:
17012 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17013 cond
= (ctx
->opcode
>> 6) & 0xf;
17014 cc
= (ctx
->opcode
>> 13) & 0x7;
17015 fmt
= (ctx
->opcode
>> 10) & 0x3;
17018 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
17021 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
17024 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
17027 goto pool32f_invalid
;
17031 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17032 cond
= (ctx
->opcode
>> 6) & 0xf;
17033 cc
= (ctx
->opcode
>> 13) & 0x7;
17034 fmt
= (ctx
->opcode
>> 10) & 0x3;
17037 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
17040 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
17043 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
17046 goto pool32f_invalid
;
17050 check_insn(ctx
, ISA_MIPS32R6
);
17051 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
17054 check_insn(ctx
, ISA_MIPS32R6
);
17055 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
17058 gen_pool32fxf(ctx
, rt
, rs
);
17062 switch ((ctx
->opcode
>> 6) & 0x7) {
17064 mips32_op
= OPC_PLL_PS
;
17067 mips32_op
= OPC_PLU_PS
;
17070 mips32_op
= OPC_PUL_PS
;
17073 mips32_op
= OPC_PUU_PS
;
17076 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17077 mips32_op
= OPC_CVT_PS_S
;
17079 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17082 goto pool32f_invalid
;
17086 check_insn(ctx
, ISA_MIPS32R6
);
17087 switch ((ctx
->opcode
>> 9) & 0x3) {
17089 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
17092 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
17095 goto pool32f_invalid
;
17100 switch ((ctx
->opcode
>> 6) & 0x7) {
17102 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17103 mips32_op
= OPC_LWXC1
;
17106 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17107 mips32_op
= OPC_SWXC1
;
17110 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17111 mips32_op
= OPC_LDXC1
;
17114 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17115 mips32_op
= OPC_SDXC1
;
17118 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17119 mips32_op
= OPC_LUXC1
;
17122 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17123 mips32_op
= OPC_SUXC1
;
17125 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
17128 goto pool32f_invalid
;
17132 check_insn(ctx
, ISA_MIPS32R6
);
17133 switch ((ctx
->opcode
>> 9) & 0x3) {
17135 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
17138 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
17141 goto pool32f_invalid
;
17146 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17147 fmt
= (ctx
->opcode
>> 9) & 0x3;
17148 switch ((ctx
->opcode
>> 6) & 0x7) {
17152 mips32_op
= OPC_RSQRT2_S
;
17155 mips32_op
= OPC_RSQRT2_D
;
17158 mips32_op
= OPC_RSQRT2_PS
;
17161 goto pool32f_invalid
;
17167 mips32_op
= OPC_RECIP2_S
;
17170 mips32_op
= OPC_RECIP2_D
;
17173 mips32_op
= OPC_RECIP2_PS
;
17176 goto pool32f_invalid
;
17180 mips32_op
= OPC_ADDR_PS
;
17183 mips32_op
= OPC_MULR_PS
;
17185 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17188 goto pool32f_invalid
;
17192 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
17193 cc
= (ctx
->opcode
>> 13) & 0x7;
17194 fmt
= (ctx
->opcode
>> 9) & 0x3;
17195 switch ((ctx
->opcode
>> 6) & 0x7) {
17196 case MOVF_FMT
: /* RINT_FMT */
17197 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17201 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
17204 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
17207 goto pool32f_invalid
;
17213 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
17216 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
17220 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
17223 goto pool32f_invalid
;
17227 case MOVT_FMT
: /* CLASS_FMT */
17228 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17232 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
17235 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
17238 goto pool32f_invalid
;
17244 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
17247 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
17251 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
17254 goto pool32f_invalid
;
17259 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17262 goto pool32f_invalid
;
17265 #define FINSN_3ARG_SDPS(prfx) \
17266 switch ((ctx->opcode >> 8) & 0x3) { \
17268 mips32_op = OPC_##prfx##_S; \
17271 mips32_op = OPC_##prfx##_D; \
17273 case FMT_SDPS_PS: \
17275 mips32_op = OPC_##prfx##_PS; \
17278 goto pool32f_invalid; \
17281 check_insn(ctx
, ISA_MIPS32R6
);
17282 switch ((ctx
->opcode
>> 9) & 0x3) {
17284 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
17287 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
17290 goto pool32f_invalid
;
17294 check_insn(ctx
, ISA_MIPS32R6
);
17295 switch ((ctx
->opcode
>> 9) & 0x3) {
17297 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
17300 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
17303 goto pool32f_invalid
;
17307 /* regular FP ops */
17308 switch ((ctx
->opcode
>> 6) & 0x3) {
17310 FINSN_3ARG_SDPS(ADD
);
17313 FINSN_3ARG_SDPS(SUB
);
17316 FINSN_3ARG_SDPS(MUL
);
17319 fmt
= (ctx
->opcode
>> 8) & 0x3;
17321 mips32_op
= OPC_DIV_D
;
17322 } else if (fmt
== 0) {
17323 mips32_op
= OPC_DIV_S
;
17325 goto pool32f_invalid
;
17329 goto pool32f_invalid
;
17334 switch ((ctx
->opcode
>> 6) & 0x7) {
17335 case MOVN_FMT
: /* SELEQZ_FMT */
17336 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17338 switch ((ctx
->opcode
>> 9) & 0x3) {
17340 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
17343 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
17346 goto pool32f_invalid
;
17350 FINSN_3ARG_SDPS(MOVN
);
17354 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17355 FINSN_3ARG_SDPS(MOVN
);
17357 case MOVZ_FMT
: /* SELNEZ_FMT */
17358 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17360 switch ((ctx
->opcode
>> 9) & 0x3) {
17362 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
17365 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
17368 goto pool32f_invalid
;
17372 FINSN_3ARG_SDPS(MOVZ
);
17376 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17377 FINSN_3ARG_SDPS(MOVZ
);
17380 check_insn(ctx
, ISA_MIPS32R6
);
17381 switch ((ctx
->opcode
>> 9) & 0x3) {
17383 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
17386 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
17389 goto pool32f_invalid
;
17393 check_insn(ctx
, ISA_MIPS32R6
);
17394 switch ((ctx
->opcode
>> 9) & 0x3) {
17396 mips32_op
= OPC_MADDF_S
;
17399 mips32_op
= OPC_MADDF_D
;
17402 goto pool32f_invalid
;
17406 check_insn(ctx
, ISA_MIPS32R6
);
17407 switch ((ctx
->opcode
>> 9) & 0x3) {
17409 mips32_op
= OPC_MSUBF_S
;
17412 mips32_op
= OPC_MSUBF_D
;
17415 goto pool32f_invalid
;
17419 goto pool32f_invalid
;
17423 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17427 MIPS_INVAL("pool32f");
17428 generate_exception_end(ctx
, EXCP_RI
);
17432 generate_exception_err(ctx
, EXCP_CpU
, 1);
17436 minor
= (ctx
->opcode
>> 21) & 0x1f;
17439 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17440 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
17443 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17444 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
17445 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17448 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17449 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
17450 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17453 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17454 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
17457 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17458 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
17459 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17462 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17463 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
17464 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17467 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17468 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
17471 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17472 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
17476 case TLTI
: /* BC1EQZC */
17477 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17479 check_cp1_enabled(ctx
);
17480 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
17483 mips32_op
= OPC_TLTI
;
17487 case TGEI
: /* BC1NEZC */
17488 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17490 check_cp1_enabled(ctx
);
17491 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
17494 mips32_op
= OPC_TGEI
;
17499 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17500 mips32_op
= OPC_TLTIU
;
17503 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17504 mips32_op
= OPC_TGEIU
;
17506 case TNEI
: /* SYNCI */
17507 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17510 * Break the TB to be able to sync copied instructions
17513 ctx
->base
.is_jmp
= DISAS_STOP
;
17516 mips32_op
= OPC_TNEI
;
17521 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17522 mips32_op
= OPC_TEQI
;
17524 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
17529 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17530 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
17531 4, rs
, 0, imm
<< 1, 0);
17533 * Compact branches don't have a delay slot, so just let
17534 * the normal delay slot handling take us to the branch
17539 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17540 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
17543 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17545 * Break the TB to be able to sync copied instructions
17548 ctx
->base
.is_jmp
= DISAS_STOP
;
17552 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17553 /* COP2: Not implemented. */
17554 generate_exception_err(ctx
, EXCP_CpU
, 2);
17557 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17558 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
17561 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17562 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
17565 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17566 mips32_op
= OPC_BC1FANY4
;
17569 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17570 mips32_op
= OPC_BC1TANY4
;
17573 check_insn(ctx
, ASE_MIPS3D
);
17576 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17577 check_cp1_enabled(ctx
);
17578 gen_compute_branch1(ctx
, mips32_op
,
17579 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
17581 generate_exception_err(ctx
, EXCP_CpU
, 1);
17586 /* MIPS DSP: not implemented */
17589 MIPS_INVAL("pool32i");
17590 generate_exception_end(ctx
, EXCP_RI
);
17595 minor
= (ctx
->opcode
>> 12) & 0xf;
17596 offset
= sextract32(ctx
->opcode
, 0,
17597 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
17600 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17601 mips32_op
= OPC_LWL
;
17604 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17605 mips32_op
= OPC_SWL
;
17608 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17609 mips32_op
= OPC_LWR
;
17612 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17613 mips32_op
= OPC_SWR
;
17615 #if defined(TARGET_MIPS64)
17617 check_insn(ctx
, ISA_MIPS3
);
17618 check_mips_64(ctx
);
17619 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17620 mips32_op
= OPC_LDL
;
17623 check_insn(ctx
, ISA_MIPS3
);
17624 check_mips_64(ctx
);
17625 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17626 mips32_op
= OPC_SDL
;
17629 check_insn(ctx
, ISA_MIPS3
);
17630 check_mips_64(ctx
);
17631 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17632 mips32_op
= OPC_LDR
;
17635 check_insn(ctx
, ISA_MIPS3
);
17636 check_mips_64(ctx
);
17637 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17638 mips32_op
= OPC_SDR
;
17641 check_insn(ctx
, ISA_MIPS3
);
17642 check_mips_64(ctx
);
17643 mips32_op
= OPC_LWU
;
17646 check_insn(ctx
, ISA_MIPS3
);
17647 check_mips_64(ctx
);
17648 mips32_op
= OPC_LLD
;
17652 mips32_op
= OPC_LL
;
17655 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17658 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17661 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17663 #if defined(TARGET_MIPS64)
17665 check_insn(ctx
, ISA_MIPS3
);
17666 check_mips_64(ctx
);
17667 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17672 MIPS_INVAL("pool32c ld-eva");
17673 generate_exception_end(ctx
, EXCP_RI
);
17676 check_cp0_enabled(ctx
);
17678 minor2
= (ctx
->opcode
>> 9) & 0x7;
17679 offset
= sextract32(ctx
->opcode
, 0, 9);
17682 mips32_op
= OPC_LBUE
;
17685 mips32_op
= OPC_LHUE
;
17688 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17689 mips32_op
= OPC_LWLE
;
17692 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17693 mips32_op
= OPC_LWRE
;
17696 mips32_op
= OPC_LBE
;
17699 mips32_op
= OPC_LHE
;
17702 mips32_op
= OPC_LLE
;
17705 mips32_op
= OPC_LWE
;
17711 MIPS_INVAL("pool32c st-eva");
17712 generate_exception_end(ctx
, EXCP_RI
);
17715 check_cp0_enabled(ctx
);
17717 minor2
= (ctx
->opcode
>> 9) & 0x7;
17718 offset
= sextract32(ctx
->opcode
, 0, 9);
17721 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17722 mips32_op
= OPC_SWLE
;
17725 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17726 mips32_op
= OPC_SWRE
;
17729 /* Treat as no-op */
17730 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17731 /* hint codes 24-31 are reserved and signal RI */
17732 generate_exception(ctx
, EXCP_RI
);
17736 /* Treat as no-op */
17737 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17738 gen_cache_operation(ctx
, rt
, rs
, offset
);
17742 mips32_op
= OPC_SBE
;
17745 mips32_op
= OPC_SHE
;
17748 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17751 mips32_op
= OPC_SWE
;
17756 /* Treat as no-op */
17757 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17758 /* hint codes 24-31 are reserved and signal RI */
17759 generate_exception(ctx
, EXCP_RI
);
17763 MIPS_INVAL("pool32c");
17764 generate_exception_end(ctx
, EXCP_RI
);
17768 case ADDI32
: /* AUI, LUI */
17769 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17771 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17774 mips32_op
= OPC_ADDI
;
17779 mips32_op
= OPC_ADDIU
;
17781 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17784 /* Logical operations */
17786 mips32_op
= OPC_ORI
;
17789 mips32_op
= OPC_XORI
;
17792 mips32_op
= OPC_ANDI
;
17794 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17797 /* Set less than immediate */
17799 mips32_op
= OPC_SLTI
;
17802 mips32_op
= OPC_SLTIU
;
17804 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17807 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17808 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17809 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17810 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17812 case JALS32
: /* BOVC, BEQC, BEQZALC */
17813 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17816 mips32_op
= OPC_BOVC
;
17817 } else if (rs
< rt
&& rs
== 0) {
17819 mips32_op
= OPC_BEQZALC
;
17822 mips32_op
= OPC_BEQC
;
17824 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17827 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17828 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17829 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17832 case BEQ32
: /* BC */
17833 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17835 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17836 sextract32(ctx
->opcode
<< 1, 0, 27));
17839 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17842 case BNE32
: /* BALC */
17843 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17845 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17846 sextract32(ctx
->opcode
<< 1, 0, 27));
17849 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17852 case J32
: /* BGTZC, BLTZC, BLTC */
17853 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17854 if (rs
== 0 && rt
!= 0) {
17856 mips32_op
= OPC_BGTZC
;
17857 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17859 mips32_op
= OPC_BLTZC
;
17862 mips32_op
= OPC_BLTC
;
17864 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17867 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17868 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17871 case JAL32
: /* BLEZC, BGEZC, BGEC */
17872 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17873 if (rs
== 0 && rt
!= 0) {
17875 mips32_op
= OPC_BLEZC
;
17876 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17878 mips32_op
= OPC_BGEZC
;
17881 mips32_op
= OPC_BGEC
;
17883 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17886 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17887 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17888 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17891 /* Floating point (COP1) */
17893 mips32_op
= OPC_LWC1
;
17896 mips32_op
= OPC_LDC1
;
17899 mips32_op
= OPC_SWC1
;
17902 mips32_op
= OPC_SDC1
;
17904 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17906 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17907 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17908 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17909 switch ((ctx
->opcode
>> 16) & 0x1f) {
17918 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17921 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17924 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17934 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17937 generate_exception(ctx
, EXCP_RI
);
17942 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17943 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17945 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17948 case BNVC
: /* BNEC, BNEZALC */
17949 check_insn(ctx
, ISA_MIPS32R6
);
17952 mips32_op
= OPC_BNVC
;
17953 } else if (rs
< rt
&& rs
== 0) {
17955 mips32_op
= OPC_BNEZALC
;
17958 mips32_op
= OPC_BNEC
;
17960 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17962 case R6_BNEZC
: /* JIALC */
17963 check_insn(ctx
, ISA_MIPS32R6
);
17966 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17967 sextract32(ctx
->opcode
<< 1, 0, 22));
17970 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17973 case R6_BEQZC
: /* JIC */
17974 check_insn(ctx
, ISA_MIPS32R6
);
17977 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17978 sextract32(ctx
->opcode
<< 1, 0, 22));
17981 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17984 case BLEZALC
: /* BGEZALC, BGEUC */
17985 check_insn(ctx
, ISA_MIPS32R6
);
17986 if (rs
== 0 && rt
!= 0) {
17988 mips32_op
= OPC_BLEZALC
;
17989 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17991 mips32_op
= OPC_BGEZALC
;
17994 mips32_op
= OPC_BGEUC
;
17996 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17998 case BGTZALC
: /* BLTZALC, BLTUC */
17999 check_insn(ctx
, ISA_MIPS32R6
);
18000 if (rs
== 0 && rt
!= 0) {
18002 mips32_op
= OPC_BGTZALC
;
18003 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
18005 mips32_op
= OPC_BLTZALC
;
18008 mips32_op
= OPC_BLTUC
;
18010 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
18012 /* Loads and stores */
18014 mips32_op
= OPC_LB
;
18017 mips32_op
= OPC_LBU
;
18020 mips32_op
= OPC_LH
;
18023 mips32_op
= OPC_LHU
;
18026 mips32_op
= OPC_LW
;
18028 #ifdef TARGET_MIPS64
18030 check_insn(ctx
, ISA_MIPS3
);
18031 check_mips_64(ctx
);
18032 mips32_op
= OPC_LD
;
18035 check_insn(ctx
, ISA_MIPS3
);
18036 check_mips_64(ctx
);
18037 mips32_op
= OPC_SD
;
18041 mips32_op
= OPC_SB
;
18044 mips32_op
= OPC_SH
;
18047 mips32_op
= OPC_SW
;
18050 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
18053 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
18056 generate_exception_end(ctx
, EXCP_RI
);
18061 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
18065 /* make sure instructions are on a halfword boundary */
18066 if (ctx
->base
.pc_next
& 0x1) {
18067 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
18068 generate_exception_end(ctx
, EXCP_AdEL
);
18072 op
= (ctx
->opcode
>> 10) & 0x3f;
18073 /* Enforce properly-sized instructions in a delay slot */
18074 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
18075 switch (op
& 0x7) { /* MSB-3..MSB-5 */
18077 /* POOL32A, POOL32B, POOL32I, POOL32C */
18079 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
18081 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
18083 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
18085 /* LB32, LH32, LWC132, LDC132, LW32 */
18086 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
18087 generate_exception_end(ctx
, EXCP_RI
);
18092 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
18094 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
18096 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
18097 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
18098 generate_exception_end(ctx
, EXCP_RI
);
18108 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18109 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
18110 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
18113 switch (ctx
->opcode
& 0x1) {
18121 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18123 * In the Release 6, the register number location in
18124 * the instruction encoding has changed.
18126 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
18128 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
18134 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18135 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
18136 int amount
= (ctx
->opcode
>> 1) & 0x7;
18138 amount
= amount
== 0 ? 8 : amount
;
18140 switch (ctx
->opcode
& 0x1) {
18149 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
18153 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18154 gen_pool16c_r6_insn(ctx
);
18156 gen_pool16c_insn(ctx
);
18161 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18162 int rb
= 28; /* GP */
18163 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
18165 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18169 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18170 if (ctx
->opcode
& 1) {
18171 generate_exception_end(ctx
, EXCP_RI
);
18174 int enc_dest
= uMIPS_RD(ctx
->opcode
);
18175 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
18176 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
18177 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
18182 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18183 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18184 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
18185 offset
= (offset
== 0xf ? -1 : offset
);
18187 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
18192 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18193 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18194 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
18196 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
18201 int rd
= (ctx
->opcode
>> 5) & 0x1f;
18202 int rb
= 29; /* SP */
18203 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
18205 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18210 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18211 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18212 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
18214 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18219 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18220 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18221 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
18223 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
18228 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18229 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18230 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
18232 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
18237 int rd
= (ctx
->opcode
>> 5) & 0x1f;
18238 int rb
= 29; /* SP */
18239 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
18241 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
18246 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18247 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18248 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
18250 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
18255 int rd
= uMIPS_RD5(ctx
->opcode
);
18256 int rs
= uMIPS_RS5(ctx
->opcode
);
18258 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
18265 switch (ctx
->opcode
& 0x1) {
18275 switch (ctx
->opcode
& 0x1) {
18280 gen_addiur1sp(ctx
);
18284 case B16
: /* BC16 */
18285 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
18286 sextract32(ctx
->opcode
, 0, 10) << 1,
18287 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
18289 case BNEZ16
: /* BNEZC16 */
18290 case BEQZ16
: /* BEQZC16 */
18291 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
18292 mmreg(uMIPS_RD(ctx
->opcode
)),
18293 0, sextract32(ctx
->opcode
, 0, 7) << 1,
18294 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
18299 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
18300 int imm
= ZIMM(ctx
->opcode
, 0, 7);
18302 imm
= (imm
== 0x7f ? -1 : imm
);
18303 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
18309 generate_exception_end(ctx
, EXCP_RI
);
18312 decode_micromips32_opc(env
, ctx
);
18325 /* MAJOR, P16, and P32 pools opcodes */
18329 NM_MOVE_BALC
= 0x02,
18337 NM_P16_SHIFT
= 0x0c,
18355 NM_P_LS_U12
= 0x21,
18365 NM_P16_ADDU
= 0x2c,
18379 NM_MOVEPREV
= 0x3f,
18382 /* POOL32A instruction pool */
18384 NM_POOL32A0
= 0x00,
18385 NM_SPECIAL2
= 0x01,
18388 NM_POOL32A5
= 0x05,
18389 NM_POOL32A7
= 0x07,
18392 /* P.GP.W instruction pool */
18394 NM_ADDIUGP_W
= 0x00,
18399 /* P48I instruction pool */
18403 NM_ADDIUGP48
= 0x02,
18404 NM_ADDIUPC48
= 0x03,
18409 /* P.U12 instruction pool */
18418 NM_ADDIUNEG
= 0x08,
18425 /* POOL32F instruction pool */
18427 NM_POOL32F_0
= 0x00,
18428 NM_POOL32F_3
= 0x03,
18429 NM_POOL32F_5
= 0x05,
18432 /* POOL32S instruction pool */
18434 NM_POOL32S_0
= 0x00,
18435 NM_POOL32S_4
= 0x04,
18438 /* P.LUI instruction pool */
18444 /* P.GP.BH instruction pool */
18449 NM_ADDIUGP_B
= 0x03,
18452 NM_P_GP_CP1
= 0x06,
18455 /* P.LS.U12 instruction pool */
18460 NM_P_PREFU12
= 0x03,
18473 /* P.LS.S9 instruction pool */
18479 NM_P_LS_UAWM
= 0x05,
18482 /* P.BAL instruction pool */
18488 /* P.J instruction pool */
18491 NM_JALRC_HB
= 0x01,
18492 NM_P_BALRSC
= 0x08,
18495 /* P.BR1 instruction pool */
18503 /* P.BR2 instruction pool */
18510 /* P.BRI instruction pool */
18522 /* P16.SHIFT instruction pool */
18528 /* POOL16C instruction pool */
18530 NM_POOL16C_0
= 0x00,
18534 /* P16.A1 instruction pool */
18536 NM_ADDIUR1SP
= 0x01,
18539 /* P16.A2 instruction pool */
18542 NM_P_ADDIURS5
= 0x01,
18545 /* P16.ADDU instruction pool */
18551 /* P16.SR instruction pool */
18554 NM_RESTORE_JRC16
= 0x01,
18557 /* P16.4X4 instruction pool */
18563 /* P16.LB instruction pool */
18570 /* P16.LH instruction pool */
18577 /* P.RI instruction pool */
18580 NM_P_SYSCALL
= 0x01,
18585 /* POOL32A0 instruction pool */
18620 NM_D_E_MT_VPE
= 0x56,
18628 /* CRC32 instruction pool */
18638 /* POOL32A5 instruction pool */
18640 NM_CMP_EQ_PH
= 0x00,
18641 NM_CMP_LT_PH
= 0x08,
18642 NM_CMP_LE_PH
= 0x10,
18643 NM_CMPGU_EQ_QB
= 0x18,
18644 NM_CMPGU_LT_QB
= 0x20,
18645 NM_CMPGU_LE_QB
= 0x28,
18646 NM_CMPGDU_EQ_QB
= 0x30,
18647 NM_CMPGDU_LT_QB
= 0x38,
18648 NM_CMPGDU_LE_QB
= 0x40,
18649 NM_CMPU_EQ_QB
= 0x48,
18650 NM_CMPU_LT_QB
= 0x50,
18651 NM_CMPU_LE_QB
= 0x58,
18652 NM_ADDQ_S_W
= 0x60,
18653 NM_SUBQ_S_W
= 0x68,
18657 NM_ADDQ_S_PH
= 0x01,
18658 NM_ADDQH_R_PH
= 0x09,
18659 NM_ADDQH_R_W
= 0x11,
18660 NM_ADDU_S_QB
= 0x19,
18661 NM_ADDU_S_PH
= 0x21,
18662 NM_ADDUH_R_QB
= 0x29,
18663 NM_SHRAV_R_PH
= 0x31,
18664 NM_SHRAV_R_QB
= 0x39,
18665 NM_SUBQ_S_PH
= 0x41,
18666 NM_SUBQH_R_PH
= 0x49,
18667 NM_SUBQH_R_W
= 0x51,
18668 NM_SUBU_S_QB
= 0x59,
18669 NM_SUBU_S_PH
= 0x61,
18670 NM_SUBUH_R_QB
= 0x69,
18671 NM_SHLLV_S_PH
= 0x71,
18672 NM_PRECR_SRA_R_PH_W
= 0x79,
18674 NM_MULEU_S_PH_QBL
= 0x12,
18675 NM_MULEU_S_PH_QBR
= 0x1a,
18676 NM_MULQ_RS_PH
= 0x22,
18677 NM_MULQ_S_PH
= 0x2a,
18678 NM_MULQ_RS_W
= 0x32,
18679 NM_MULQ_S_W
= 0x3a,
18682 NM_SHRAV_R_W
= 0x5a,
18683 NM_SHRLV_PH
= 0x62,
18684 NM_SHRLV_QB
= 0x6a,
18685 NM_SHLLV_QB
= 0x72,
18686 NM_SHLLV_S_W
= 0x7a,
18690 NM_MULEQ_S_W_PHL
= 0x04,
18691 NM_MULEQ_S_W_PHR
= 0x0c,
18693 NM_MUL_S_PH
= 0x05,
18694 NM_PRECR_QB_PH
= 0x0d,
18695 NM_PRECRQ_QB_PH
= 0x15,
18696 NM_PRECRQ_PH_W
= 0x1d,
18697 NM_PRECRQ_RS_PH_W
= 0x25,
18698 NM_PRECRQU_S_QB_PH
= 0x2d,
18699 NM_PACKRL_PH
= 0x35,
18703 NM_SHRA_R_W
= 0x5e,
18704 NM_SHRA_R_PH
= 0x66,
18705 NM_SHLL_S_PH
= 0x76,
18706 NM_SHLL_S_W
= 0x7e,
18711 /* POOL32A7 instruction pool */
18716 NM_POOL32AXF
= 0x07,
18719 /* P.SR instruction pool */
18725 /* P.SHIFT instruction pool */
18733 /* P.ROTX instruction pool */
18738 /* P.INS instruction pool */
18743 /* P.EXT instruction pool */
18748 /* POOL32F_0 (fmt) instruction pool */
18753 NM_SELEQZ_S
= 0x07,
18754 NM_SELEQZ_D
= 0x47,
18758 NM_SELNEZ_S
= 0x0f,
18759 NM_SELNEZ_D
= 0x4f,
18774 /* POOL32F_3 instruction pool */
18778 NM_MINA_FMT
= 0x04,
18779 NM_MAXA_FMT
= 0x05,
18780 NM_POOL32FXF
= 0x07,
18783 /* POOL32F_5 instruction pool */
18785 NM_CMP_CONDN_S
= 0x00,
18786 NM_CMP_CONDN_D
= 0x02,
18789 /* P.GP.LH instruction pool */
18795 /* P.GP.SH instruction pool */
18800 /* P.GP.CP1 instruction pool */
18808 /* P.LS.S0 instruction pool */
18825 NM_P_PREFS9
= 0x03,
18831 /* P.LS.S1 instruction pool */
18833 NM_ASET_ACLR
= 0x02,
18841 /* P.LS.E0 instruction pool */
18857 /* P.PREFE instruction pool */
18863 /* P.LLE instruction pool */
18869 /* P.SCE instruction pool */
18875 /* P.LS.WM instruction pool */
18881 /* P.LS.UAWM instruction pool */
18887 /* P.BR3A instruction pool */
18893 NM_BPOSGE32C
= 0x04,
18896 /* P16.RI instruction pool */
18898 NM_P16_SYSCALL
= 0x01,
18903 /* POOL16C_0 instruction pool */
18905 NM_POOL16C_00
= 0x00,
18908 /* P16.JRC instruction pool */
18914 /* P.SYSCALL instruction pool */
18920 /* P.TRAP instruction pool */
18926 /* P.CMOVE instruction pool */
18932 /* POOL32Axf instruction pool */
18934 NM_POOL32AXF_1
= 0x01,
18935 NM_POOL32AXF_2
= 0x02,
18936 NM_POOL32AXF_4
= 0x04,
18937 NM_POOL32AXF_5
= 0x05,
18938 NM_POOL32AXF_7
= 0x07,
18941 /* POOL32Axf_1 instruction pool */
18943 NM_POOL32AXF_1_0
= 0x00,
18944 NM_POOL32AXF_1_1
= 0x01,
18945 NM_POOL32AXF_1_3
= 0x03,
18946 NM_POOL32AXF_1_4
= 0x04,
18947 NM_POOL32AXF_1_5
= 0x05,
18948 NM_POOL32AXF_1_7
= 0x07,
18951 /* POOL32Axf_2 instruction pool */
18953 NM_POOL32AXF_2_0_7
= 0x00,
18954 NM_POOL32AXF_2_8_15
= 0x01,
18955 NM_POOL32AXF_2_16_23
= 0x02,
18956 NM_POOL32AXF_2_24_31
= 0x03,
18959 /* POOL32Axf_7 instruction pool */
18961 NM_SHRA_R_QB
= 0x0,
18966 /* POOL32Axf_1_0 instruction pool */
18974 /* POOL32Axf_1_1 instruction pool */
18980 /* POOL32Axf_1_3 instruction pool */
18988 /* POOL32Axf_1_4 instruction pool */
18994 /* POOL32Axf_1_5 instruction pool */
18996 NM_MAQ_S_W_PHR
= 0x0,
18997 NM_MAQ_S_W_PHL
= 0x1,
18998 NM_MAQ_SA_W_PHR
= 0x2,
18999 NM_MAQ_SA_W_PHL
= 0x3,
19002 /* POOL32Axf_1_7 instruction pool */
19006 NM_EXTR_RS_W
= 0x2,
19010 /* POOL32Axf_2_0_7 instruction pool */
19013 NM_DPAQ_S_W_PH
= 0x1,
19015 NM_DPSQ_S_W_PH
= 0x3,
19022 /* POOL32Axf_2_8_15 instruction pool */
19024 NM_DPAX_W_PH
= 0x0,
19025 NM_DPAQ_SA_L_W
= 0x1,
19026 NM_DPSX_W_PH
= 0x2,
19027 NM_DPSQ_SA_L_W
= 0x3,
19030 NM_EXTRV_R_W
= 0x7,
19033 /* POOL32Axf_2_16_23 instruction pool */
19035 NM_DPAU_H_QBL
= 0x0,
19036 NM_DPAQX_S_W_PH
= 0x1,
19037 NM_DPSU_H_QBL
= 0x2,
19038 NM_DPSQX_S_W_PH
= 0x3,
19041 NM_MULSA_W_PH
= 0x6,
19042 NM_EXTRV_RS_W
= 0x7,
19045 /* POOL32Axf_2_24_31 instruction pool */
19047 NM_DPAU_H_QBR
= 0x0,
19048 NM_DPAQX_SA_W_PH
= 0x1,
19049 NM_DPSU_H_QBR
= 0x2,
19050 NM_DPSQX_SA_W_PH
= 0x3,
19053 NM_MULSAQ_S_W_PH
= 0x6,
19054 NM_EXTRV_S_H
= 0x7,
19057 /* POOL32Axf_{4, 5} instruction pool */
19076 /* nanoMIPS DSP instructions */
19077 NM_ABSQ_S_QB
= 0x00,
19078 NM_ABSQ_S_PH
= 0x08,
19079 NM_ABSQ_S_W
= 0x10,
19080 NM_PRECEQ_W_PHL
= 0x28,
19081 NM_PRECEQ_W_PHR
= 0x30,
19082 NM_PRECEQU_PH_QBL
= 0x38,
19083 NM_PRECEQU_PH_QBR
= 0x48,
19084 NM_PRECEU_PH_QBL
= 0x58,
19085 NM_PRECEU_PH_QBR
= 0x68,
19086 NM_PRECEQU_PH_QBLA
= 0x39,
19087 NM_PRECEQU_PH_QBRA
= 0x49,
19088 NM_PRECEU_PH_QBLA
= 0x59,
19089 NM_PRECEU_PH_QBRA
= 0x69,
19090 NM_REPLV_PH
= 0x01,
19091 NM_REPLV_QB
= 0x09,
19094 NM_RADDU_W_QB
= 0x78,
19100 /* PP.SR instruction pool */
19104 NM_RESTORE_JRC
= 0x03,
19107 /* P.SR.F instruction pool */
19110 NM_RESTOREF
= 0x01,
19113 /* P16.SYSCALL instruction pool */
19115 NM_SYSCALL16
= 0x00,
19116 NM_HYPCALL16
= 0x01,
19119 /* POOL16C_00 instruction pool */
19127 /* PP.LSX and PP.LSXS instruction pool */
19165 /* ERETx instruction pool */
19171 /* POOL32FxF_{0, 1} insturction pool */
19180 NM_CVT_S_PL
= 0x84,
19181 NM_CVT_S_PU
= 0xa4,
19183 NM_CVT_L_S
= 0x004,
19184 NM_CVT_L_D
= 0x104,
19185 NM_CVT_W_S
= 0x024,
19186 NM_CVT_W_D
= 0x124,
19188 NM_RSQRT_S
= 0x008,
19189 NM_RSQRT_D
= 0x108,
19194 NM_RECIP_S
= 0x048,
19195 NM_RECIP_D
= 0x148,
19197 NM_FLOOR_L_S
= 0x00c,
19198 NM_FLOOR_L_D
= 0x10c,
19200 NM_FLOOR_W_S
= 0x02c,
19201 NM_FLOOR_W_D
= 0x12c,
19203 NM_CEIL_L_S
= 0x04c,
19204 NM_CEIL_L_D
= 0x14c,
19205 NM_CEIL_W_S
= 0x06c,
19206 NM_CEIL_W_D
= 0x16c,
19207 NM_TRUNC_L_S
= 0x08c,
19208 NM_TRUNC_L_D
= 0x18c,
19209 NM_TRUNC_W_S
= 0x0ac,
19210 NM_TRUNC_W_D
= 0x1ac,
19211 NM_ROUND_L_S
= 0x0cc,
19212 NM_ROUND_L_D
= 0x1cc,
19213 NM_ROUND_W_S
= 0x0ec,
19214 NM_ROUND_W_D
= 0x1ec,
19222 NM_CVT_D_S
= 0x04d,
19223 NM_CVT_D_W
= 0x0cd,
19224 NM_CVT_D_L
= 0x14d,
19225 NM_CVT_S_D
= 0x06d,
19226 NM_CVT_S_W
= 0x0ed,
19227 NM_CVT_S_L
= 0x16d,
19230 /* P.LL instruction pool */
19236 /* P.SC instruction pool */
19242 /* P.DVP instruction pool */
19251 * nanoMIPS decoding engine
19256 /* extraction utilities */
19258 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
19259 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
19260 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
19261 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
19262 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
19264 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
19265 static inline int decode_gpr_gpr3(int r
)
19267 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
19269 return map
[r
& 0x7];
19272 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
19273 static inline int decode_gpr_gpr3_src_store(int r
)
19275 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
19277 return map
[r
& 0x7];
19280 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
19281 static inline int decode_gpr_gpr4(int r
)
19283 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
19284 16, 17, 18, 19, 20, 21, 22, 23 };
19286 return map
[r
& 0xf];
19289 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
19290 static inline int decode_gpr_gpr4_zero(int r
)
19292 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
19293 16, 17, 18, 19, 20, 21, 22, 23 };
19295 return map
[r
& 0xf];
19299 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
19301 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
19304 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
19305 uint8_t gp
, uint16_t u
)
19308 TCGv va
= tcg_temp_new();
19309 TCGv t0
= tcg_temp_new();
19311 while (counter
!= count
) {
19312 bool use_gp
= gp
&& (counter
== count
- 1);
19313 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
19314 int this_offset
= -((counter
+ 1) << 2);
19315 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
19316 gen_load_gpr(t0
, this_rt
);
19317 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
19318 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
19322 /* adjust stack pointer */
19323 gen_adjust_sp(ctx
, -u
);
19329 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
19330 uint8_t gp
, uint16_t u
)
19333 TCGv va
= tcg_temp_new();
19334 TCGv t0
= tcg_temp_new();
19336 while (counter
!= count
) {
19337 bool use_gp
= gp
&& (counter
== count
- 1);
19338 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
19339 int this_offset
= u
- ((counter
+ 1) << 2);
19340 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
19341 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
19342 ctx
->default_tcg_memop_mask
);
19343 tcg_gen_ext32s_tl(t0
, t0
);
19344 gen_store_gpr(t0
, this_rt
);
19348 /* adjust stack pointer */
19349 gen_adjust_sp(ctx
, u
);
19355 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
19357 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
19358 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
19360 switch (extract32(ctx
->opcode
, 2, 2)) {
19362 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
19365 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
19368 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
19371 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
19376 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19378 int rt
= extract32(ctx
->opcode
, 21, 5);
19379 int rs
= extract32(ctx
->opcode
, 16, 5);
19380 int rd
= extract32(ctx
->opcode
, 11, 5);
19382 switch (extract32(ctx
->opcode
, 3, 7)) {
19384 switch (extract32(ctx
->opcode
, 10, 1)) {
19387 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
19391 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
19397 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
19401 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
19404 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
19407 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
19410 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
19413 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
19416 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
19419 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
19422 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
19426 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
19429 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
19432 switch (extract32(ctx
->opcode
, 10, 1)) {
19434 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
19437 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
19442 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
19445 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
19448 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
19451 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
19454 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
19459 #ifndef CONFIG_USER_ONLY
19460 TCGv t0
= tcg_temp_new();
19461 switch (extract32(ctx
->opcode
, 10, 1)) {
19464 check_cp0_enabled(ctx
);
19465 gen_helper_dvp(t0
, cpu_env
);
19466 gen_store_gpr(t0
, rt
);
19471 check_cp0_enabled(ctx
);
19472 gen_helper_evp(t0
, cpu_env
);
19473 gen_store_gpr(t0
, rt
);
19480 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
19485 TCGv t0
= tcg_temp_new();
19486 TCGv t1
= tcg_temp_new();
19487 TCGv t2
= tcg_temp_new();
19489 gen_load_gpr(t1
, rs
);
19490 gen_load_gpr(t2
, rt
);
19491 tcg_gen_add_tl(t0
, t1
, t2
);
19492 tcg_gen_ext32s_tl(t0
, t0
);
19493 tcg_gen_xor_tl(t1
, t1
, t2
);
19494 tcg_gen_xor_tl(t2
, t0
, t2
);
19495 tcg_gen_andc_tl(t1
, t2
, t1
);
19497 /* operands of same sign, result different sign */
19498 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
19499 gen_store_gpr(t0
, rd
);
19507 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
19510 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
19513 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
19516 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
19519 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
19522 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
19525 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
19528 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
19530 #ifndef CONFIG_USER_ONLY
19532 check_cp0_enabled(ctx
);
19534 /* Treat as NOP. */
19537 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
19540 check_cp0_enabled(ctx
);
19542 TCGv t0
= tcg_temp_new();
19544 gen_load_gpr(t0
, rt
);
19545 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
19549 case NM_D_E_MT_VPE
:
19551 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
19552 TCGv t0
= tcg_temp_new();
19559 gen_helper_dmt(t0
);
19560 gen_store_gpr(t0
, rt
);
19561 } else if (rs
== 0) {
19564 gen_helper_dvpe(t0
, cpu_env
);
19565 gen_store_gpr(t0
, rt
);
19567 generate_exception_end(ctx
, EXCP_RI
);
19574 gen_helper_emt(t0
);
19575 gen_store_gpr(t0
, rt
);
19576 } else if (rs
== 0) {
19579 gen_helper_evpe(t0
, cpu_env
);
19580 gen_store_gpr(t0
, rt
);
19582 generate_exception_end(ctx
, EXCP_RI
);
19593 TCGv t0
= tcg_temp_new();
19594 TCGv t1
= tcg_temp_new();
19596 gen_load_gpr(t0
, rt
);
19597 gen_load_gpr(t1
, rs
);
19598 gen_helper_fork(t0
, t1
);
19605 check_cp0_enabled(ctx
);
19607 /* Treat as NOP. */
19610 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19611 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19615 check_cp0_enabled(ctx
);
19616 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19617 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19622 TCGv t0
= tcg_temp_new();
19624 gen_load_gpr(t0
, rs
);
19625 gen_helper_yield(t0
, cpu_env
, t0
);
19626 gen_store_gpr(t0
, rt
);
19632 generate_exception_end(ctx
, EXCP_RI
);
19638 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19639 int ret
, int v1
, int v2
)
19645 t0
= tcg_temp_new_i32();
19647 v0_t
= tcg_temp_new();
19648 v1_t
= tcg_temp_new();
19650 tcg_gen_movi_i32(t0
, v2
>> 3);
19652 gen_load_gpr(v0_t
, ret
);
19653 gen_load_gpr(v1_t
, v1
);
19656 case NM_MAQ_S_W_PHR
:
19658 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19660 case NM_MAQ_S_W_PHL
:
19662 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19664 case NM_MAQ_SA_W_PHR
:
19666 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19668 case NM_MAQ_SA_W_PHL
:
19670 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19673 generate_exception_end(ctx
, EXCP_RI
);
19677 tcg_temp_free_i32(t0
);
19679 tcg_temp_free(v0_t
);
19680 tcg_temp_free(v1_t
);
19684 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19685 int ret
, int v1
, int v2
)
19688 TCGv t0
= tcg_temp_new();
19689 TCGv t1
= tcg_temp_new();
19690 TCGv v0_t
= tcg_temp_new();
19692 gen_load_gpr(v0_t
, v1
);
19695 case NM_POOL32AXF_1_0
:
19697 switch (extract32(ctx
->opcode
, 12, 2)) {
19699 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19702 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19705 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19708 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19712 case NM_POOL32AXF_1_1
:
19714 switch (extract32(ctx
->opcode
, 12, 2)) {
19716 tcg_gen_movi_tl(t0
, v2
);
19717 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19720 tcg_gen_movi_tl(t0
, v2
>> 3);
19721 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19724 generate_exception_end(ctx
, EXCP_RI
);
19728 case NM_POOL32AXF_1_3
:
19730 imm
= extract32(ctx
->opcode
, 14, 7);
19731 switch (extract32(ctx
->opcode
, 12, 2)) {
19733 tcg_gen_movi_tl(t0
, imm
);
19734 gen_helper_rddsp(t0
, t0
, cpu_env
);
19735 gen_store_gpr(t0
, ret
);
19738 gen_load_gpr(t0
, ret
);
19739 tcg_gen_movi_tl(t1
, imm
);
19740 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19743 tcg_gen_movi_tl(t0
, v2
>> 3);
19744 tcg_gen_movi_tl(t1
, v1
);
19745 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19746 gen_store_gpr(t0
, ret
);
19749 tcg_gen_movi_tl(t0
, v2
>> 3);
19750 tcg_gen_movi_tl(t1
, v1
);
19751 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19752 gen_store_gpr(t0
, ret
);
19756 case NM_POOL32AXF_1_4
:
19758 tcg_gen_movi_tl(t0
, v2
>> 2);
19759 switch (extract32(ctx
->opcode
, 12, 1)) {
19761 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19762 gen_store_gpr(t0
, ret
);
19765 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19766 gen_store_gpr(t0
, ret
);
19770 case NM_POOL32AXF_1_5
:
19771 opc
= extract32(ctx
->opcode
, 12, 2);
19772 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19774 case NM_POOL32AXF_1_7
:
19776 tcg_gen_movi_tl(t0
, v2
>> 3);
19777 tcg_gen_movi_tl(t1
, v1
);
19778 switch (extract32(ctx
->opcode
, 12, 2)) {
19780 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19781 gen_store_gpr(t0
, ret
);
19784 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19785 gen_store_gpr(t0
, ret
);
19788 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19789 gen_store_gpr(t0
, ret
);
19792 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19793 gen_store_gpr(t0
, ret
);
19798 generate_exception_end(ctx
, EXCP_RI
);
19804 tcg_temp_free(v0_t
);
19807 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19808 TCGv v0
, TCGv v1
, int rd
)
19812 t0
= tcg_temp_new_i32();
19814 tcg_gen_movi_i32(t0
, rd
>> 3);
19817 case NM_POOL32AXF_2_0_7
:
19818 switch (extract32(ctx
->opcode
, 9, 3)) {
19821 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19823 case NM_DPAQ_S_W_PH
:
19825 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19829 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19831 case NM_DPSQ_S_W_PH
:
19833 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19836 generate_exception_end(ctx
, EXCP_RI
);
19840 case NM_POOL32AXF_2_8_15
:
19841 switch (extract32(ctx
->opcode
, 9, 3)) {
19844 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19846 case NM_DPAQ_SA_L_W
:
19848 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19852 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19854 case NM_DPSQ_SA_L_W
:
19856 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19859 generate_exception_end(ctx
, EXCP_RI
);
19863 case NM_POOL32AXF_2_16_23
:
19864 switch (extract32(ctx
->opcode
, 9, 3)) {
19865 case NM_DPAU_H_QBL
:
19867 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19869 case NM_DPAQX_S_W_PH
:
19871 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19873 case NM_DPSU_H_QBL
:
19875 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19877 case NM_DPSQX_S_W_PH
:
19879 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19881 case NM_MULSA_W_PH
:
19883 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19886 generate_exception_end(ctx
, EXCP_RI
);
19890 case NM_POOL32AXF_2_24_31
:
19891 switch (extract32(ctx
->opcode
, 9, 3)) {
19892 case NM_DPAU_H_QBR
:
19894 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19896 case NM_DPAQX_SA_W_PH
:
19898 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19900 case NM_DPSU_H_QBR
:
19902 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19904 case NM_DPSQX_SA_W_PH
:
19906 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19908 case NM_MULSAQ_S_W_PH
:
19910 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19913 generate_exception_end(ctx
, EXCP_RI
);
19918 generate_exception_end(ctx
, EXCP_RI
);
19922 tcg_temp_free_i32(t0
);
19925 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19926 int rt
, int rs
, int rd
)
19929 TCGv t0
= tcg_temp_new();
19930 TCGv t1
= tcg_temp_new();
19931 TCGv v0_t
= tcg_temp_new();
19932 TCGv v1_t
= tcg_temp_new();
19934 gen_load_gpr(v0_t
, rt
);
19935 gen_load_gpr(v1_t
, rs
);
19938 case NM_POOL32AXF_2_0_7
:
19939 switch (extract32(ctx
->opcode
, 9, 3)) {
19941 case NM_DPAQ_S_W_PH
:
19943 case NM_DPSQ_S_W_PH
:
19944 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19949 gen_load_gpr(t0
, rs
);
19951 if (rd
!= 0 && rd
!= 2) {
19952 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19953 tcg_gen_ext32u_tl(t0
, t0
);
19954 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19955 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19957 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19963 int acc
= extract32(ctx
->opcode
, 14, 2);
19964 TCGv_i64 t2
= tcg_temp_new_i64();
19965 TCGv_i64 t3
= tcg_temp_new_i64();
19967 gen_load_gpr(t0
, rt
);
19968 gen_load_gpr(t1
, rs
);
19969 tcg_gen_ext_tl_i64(t2
, t0
);
19970 tcg_gen_ext_tl_i64(t3
, t1
);
19971 tcg_gen_mul_i64(t2
, t2
, t3
);
19972 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19973 tcg_gen_add_i64(t2
, t2
, t3
);
19974 tcg_temp_free_i64(t3
);
19975 gen_move_low32(cpu_LO
[acc
], t2
);
19976 gen_move_high32(cpu_HI
[acc
], t2
);
19977 tcg_temp_free_i64(t2
);
19983 int acc
= extract32(ctx
->opcode
, 14, 2);
19984 TCGv_i32 t2
= tcg_temp_new_i32();
19985 TCGv_i32 t3
= tcg_temp_new_i32();
19987 gen_load_gpr(t0
, rs
);
19988 gen_load_gpr(t1
, rt
);
19989 tcg_gen_trunc_tl_i32(t2
, t0
);
19990 tcg_gen_trunc_tl_i32(t3
, t1
);
19991 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19992 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19993 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19994 tcg_temp_free_i32(t2
);
19995 tcg_temp_free_i32(t3
);
20000 gen_load_gpr(v1_t
, rs
);
20001 tcg_gen_movi_tl(t0
, rd
>> 3);
20002 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
20003 gen_store_gpr(t0
, ret
);
20007 case NM_POOL32AXF_2_8_15
:
20008 switch (extract32(ctx
->opcode
, 9, 3)) {
20010 case NM_DPAQ_SA_L_W
:
20012 case NM_DPSQ_SA_L_W
:
20013 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
20018 int acc
= extract32(ctx
->opcode
, 14, 2);
20019 TCGv_i64 t2
= tcg_temp_new_i64();
20020 TCGv_i64 t3
= tcg_temp_new_i64();
20022 gen_load_gpr(t0
, rs
);
20023 gen_load_gpr(t1
, rt
);
20024 tcg_gen_ext32u_tl(t0
, t0
);
20025 tcg_gen_ext32u_tl(t1
, t1
);
20026 tcg_gen_extu_tl_i64(t2
, t0
);
20027 tcg_gen_extu_tl_i64(t3
, t1
);
20028 tcg_gen_mul_i64(t2
, t2
, t3
);
20029 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
20030 tcg_gen_add_i64(t2
, t2
, t3
);
20031 tcg_temp_free_i64(t3
);
20032 gen_move_low32(cpu_LO
[acc
], t2
);
20033 gen_move_high32(cpu_HI
[acc
], t2
);
20034 tcg_temp_free_i64(t2
);
20040 int acc
= extract32(ctx
->opcode
, 14, 2);
20041 TCGv_i32 t2
= tcg_temp_new_i32();
20042 TCGv_i32 t3
= tcg_temp_new_i32();
20044 gen_load_gpr(t0
, rs
);
20045 gen_load_gpr(t1
, rt
);
20046 tcg_gen_trunc_tl_i32(t2
, t0
);
20047 tcg_gen_trunc_tl_i32(t3
, t1
);
20048 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
20049 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
20050 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
20051 tcg_temp_free_i32(t2
);
20052 tcg_temp_free_i32(t3
);
20057 tcg_gen_movi_tl(t0
, rd
>> 3);
20058 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
20059 gen_store_gpr(t0
, ret
);
20062 generate_exception_end(ctx
, EXCP_RI
);
20066 case NM_POOL32AXF_2_16_23
:
20067 switch (extract32(ctx
->opcode
, 9, 3)) {
20068 case NM_DPAU_H_QBL
:
20069 case NM_DPAQX_S_W_PH
:
20070 case NM_DPSU_H_QBL
:
20071 case NM_DPSQX_S_W_PH
:
20072 case NM_MULSA_W_PH
:
20073 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
20077 tcg_gen_movi_tl(t0
, rd
>> 3);
20078 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
20079 gen_store_gpr(t0
, ret
);
20084 int acc
= extract32(ctx
->opcode
, 14, 2);
20085 TCGv_i64 t2
= tcg_temp_new_i64();
20086 TCGv_i64 t3
= tcg_temp_new_i64();
20088 gen_load_gpr(t0
, rs
);
20089 gen_load_gpr(t1
, rt
);
20090 tcg_gen_ext_tl_i64(t2
, t0
);
20091 tcg_gen_ext_tl_i64(t3
, t1
);
20092 tcg_gen_mul_i64(t2
, t2
, t3
);
20093 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
20094 tcg_gen_sub_i64(t2
, t3
, t2
);
20095 tcg_temp_free_i64(t3
);
20096 gen_move_low32(cpu_LO
[acc
], t2
);
20097 gen_move_high32(cpu_HI
[acc
], t2
);
20098 tcg_temp_free_i64(t2
);
20101 case NM_EXTRV_RS_W
:
20103 tcg_gen_movi_tl(t0
, rd
>> 3);
20104 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
20105 gen_store_gpr(t0
, ret
);
20109 case NM_POOL32AXF_2_24_31
:
20110 switch (extract32(ctx
->opcode
, 9, 3)) {
20111 case NM_DPAU_H_QBR
:
20112 case NM_DPAQX_SA_W_PH
:
20113 case NM_DPSU_H_QBR
:
20114 case NM_DPSQX_SA_W_PH
:
20115 case NM_MULSAQ_S_W_PH
:
20116 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
20120 tcg_gen_movi_tl(t0
, rd
>> 3);
20121 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
20122 gen_store_gpr(t0
, ret
);
20127 int acc
= extract32(ctx
->opcode
, 14, 2);
20128 TCGv_i64 t2
= tcg_temp_new_i64();
20129 TCGv_i64 t3
= tcg_temp_new_i64();
20131 gen_load_gpr(t0
, rs
);
20132 gen_load_gpr(t1
, rt
);
20133 tcg_gen_ext32u_tl(t0
, t0
);
20134 tcg_gen_ext32u_tl(t1
, t1
);
20135 tcg_gen_extu_tl_i64(t2
, t0
);
20136 tcg_gen_extu_tl_i64(t3
, t1
);
20137 tcg_gen_mul_i64(t2
, t2
, t3
);
20138 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
20139 tcg_gen_sub_i64(t2
, t3
, t2
);
20140 tcg_temp_free_i64(t3
);
20141 gen_move_low32(cpu_LO
[acc
], t2
);
20142 gen_move_high32(cpu_HI
[acc
], t2
);
20143 tcg_temp_free_i64(t2
);
20148 tcg_gen_movi_tl(t0
, rd
>> 3);
20149 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
20150 gen_store_gpr(t0
, ret
);
20155 generate_exception_end(ctx
, EXCP_RI
);
20162 tcg_temp_free(v0_t
);
20163 tcg_temp_free(v1_t
);
20166 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
20170 TCGv t0
= tcg_temp_new();
20171 TCGv v0_t
= tcg_temp_new();
20173 gen_load_gpr(v0_t
, rs
);
20178 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
20179 gen_store_gpr(v0_t
, ret
);
20183 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
20184 gen_store_gpr(v0_t
, ret
);
20188 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
20189 gen_store_gpr(v0_t
, ret
);
20191 case NM_PRECEQ_W_PHL
:
20193 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
20194 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20195 gen_store_gpr(v0_t
, ret
);
20197 case NM_PRECEQ_W_PHR
:
20199 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
20200 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
20201 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20202 gen_store_gpr(v0_t
, ret
);
20204 case NM_PRECEQU_PH_QBL
:
20206 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
20207 gen_store_gpr(v0_t
, ret
);
20209 case NM_PRECEQU_PH_QBR
:
20211 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
20212 gen_store_gpr(v0_t
, ret
);
20214 case NM_PRECEQU_PH_QBLA
:
20216 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
20217 gen_store_gpr(v0_t
, ret
);
20219 case NM_PRECEQU_PH_QBRA
:
20221 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
20222 gen_store_gpr(v0_t
, ret
);
20224 case NM_PRECEU_PH_QBL
:
20226 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
20227 gen_store_gpr(v0_t
, ret
);
20229 case NM_PRECEU_PH_QBR
:
20231 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
20232 gen_store_gpr(v0_t
, ret
);
20234 case NM_PRECEU_PH_QBLA
:
20236 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
20237 gen_store_gpr(v0_t
, ret
);
20239 case NM_PRECEU_PH_QBRA
:
20241 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
20242 gen_store_gpr(v0_t
, ret
);
20246 tcg_gen_ext16u_tl(v0_t
, v0_t
);
20247 tcg_gen_shli_tl(t0
, v0_t
, 16);
20248 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20249 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20250 gen_store_gpr(v0_t
, ret
);
20254 tcg_gen_ext8u_tl(v0_t
, v0_t
);
20255 tcg_gen_shli_tl(t0
, v0_t
, 8);
20256 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20257 tcg_gen_shli_tl(t0
, v0_t
, 16);
20258 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20259 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20260 gen_store_gpr(v0_t
, ret
);
20264 gen_helper_bitrev(v0_t
, v0_t
);
20265 gen_store_gpr(v0_t
, ret
);
20270 TCGv tv0
= tcg_temp_new();
20272 gen_load_gpr(tv0
, rt
);
20273 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
20274 gen_store_gpr(v0_t
, ret
);
20275 tcg_temp_free(tv0
);
20278 case NM_RADDU_W_QB
:
20280 gen_helper_raddu_w_qb(v0_t
, v0_t
);
20281 gen_store_gpr(v0_t
, ret
);
20284 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
20288 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
20292 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
20295 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
20298 generate_exception_end(ctx
, EXCP_RI
);
20302 tcg_temp_free(v0_t
);
20306 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
20307 int rt
, int rs
, int rd
)
20309 TCGv t0
= tcg_temp_new();
20310 TCGv rs_t
= tcg_temp_new();
20312 gen_load_gpr(rs_t
, rs
);
20317 tcg_gen_movi_tl(t0
, rd
>> 2);
20318 switch (extract32(ctx
->opcode
, 12, 1)) {
20321 gen_helper_shra_qb(t0
, t0
, rs_t
);
20322 gen_store_gpr(t0
, rt
);
20326 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
20327 gen_store_gpr(t0
, rt
);
20333 tcg_gen_movi_tl(t0
, rd
>> 1);
20334 gen_helper_shrl_ph(t0
, t0
, rs_t
);
20335 gen_store_gpr(t0
, rt
);
20341 target_long result
;
20342 imm
= extract32(ctx
->opcode
, 13, 8);
20343 result
= (uint32_t)imm
<< 24 |
20344 (uint32_t)imm
<< 16 |
20345 (uint32_t)imm
<< 8 |
20347 result
= (int32_t)result
;
20348 tcg_gen_movi_tl(t0
, result
);
20349 gen_store_gpr(t0
, rt
);
20353 generate_exception_end(ctx
, EXCP_RI
);
20357 tcg_temp_free(rs_t
);
20361 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
20363 int rt
= extract32(ctx
->opcode
, 21, 5);
20364 int rs
= extract32(ctx
->opcode
, 16, 5);
20365 int rd
= extract32(ctx
->opcode
, 11, 5);
20367 switch (extract32(ctx
->opcode
, 6, 3)) {
20368 case NM_POOL32AXF_1
:
20370 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20371 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20374 case NM_POOL32AXF_2
:
20376 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
20377 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20380 case NM_POOL32AXF_4
:
20382 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
20383 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
20386 case NM_POOL32AXF_5
:
20387 switch (extract32(ctx
->opcode
, 9, 7)) {
20388 #ifndef CONFIG_USER_ONLY
20390 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
20393 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
20396 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
20399 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
20402 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
20405 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
20408 check_cp0_enabled(ctx
);
20410 TCGv t0
= tcg_temp_new();
20412 save_cpu_state(ctx
, 1);
20413 gen_helper_di(t0
, cpu_env
);
20414 gen_store_gpr(t0
, rt
);
20415 /* Stop translation as we may have switched the execution mode */
20416 ctx
->base
.is_jmp
= DISAS_STOP
;
20421 check_cp0_enabled(ctx
);
20423 TCGv t0
= tcg_temp_new();
20425 save_cpu_state(ctx
, 1);
20426 gen_helper_ei(t0
, cpu_env
);
20427 gen_store_gpr(t0
, rt
);
20428 /* Stop translation as we may have switched the execution mode */
20429 ctx
->base
.is_jmp
= DISAS_STOP
;
20434 gen_load_srsgpr(rs
, rt
);
20437 gen_store_srsgpr(rs
, rt
);
20440 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
20443 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
20446 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
20450 generate_exception_end(ctx
, EXCP_RI
);
20454 case NM_POOL32AXF_7
:
20456 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20457 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20461 generate_exception_end(ctx
, EXCP_RI
);
20466 /* Immediate Value Compact Branches */
20467 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
20468 int rt
, int32_t imm
, int32_t offset
)
20470 TCGCond cond
= TCG_COND_ALWAYS
;
20471 TCGv t0
= tcg_temp_new();
20472 TCGv t1
= tcg_temp_new();
20474 gen_load_gpr(t0
, rt
);
20475 tcg_gen_movi_tl(t1
, imm
);
20476 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20478 /* Load needed operands and calculate btarget */
20481 if (rt
== 0 && imm
== 0) {
20482 /* Unconditional branch */
20483 } else if (rt
== 0 && imm
!= 0) {
20487 cond
= TCG_COND_EQ
;
20493 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
20494 generate_exception_end(ctx
, EXCP_RI
);
20496 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
20497 /* Unconditional branch */
20498 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
20502 tcg_gen_shri_tl(t0
, t0
, imm
);
20503 tcg_gen_andi_tl(t0
, t0
, 1);
20504 tcg_gen_movi_tl(t1
, 0);
20505 if (opc
== NM_BBEQZC
) {
20506 cond
= TCG_COND_EQ
;
20508 cond
= TCG_COND_NE
;
20513 if (rt
== 0 && imm
== 0) {
20516 } else if (rt
== 0 && imm
!= 0) {
20517 /* Unconditional branch */
20519 cond
= TCG_COND_NE
;
20523 if (rt
== 0 && imm
== 0) {
20524 /* Unconditional branch */
20526 cond
= TCG_COND_GE
;
20530 cond
= TCG_COND_LT
;
20533 if (rt
== 0 && imm
== 0) {
20534 /* Unconditional branch */
20536 cond
= TCG_COND_GEU
;
20540 cond
= TCG_COND_LTU
;
20543 MIPS_INVAL("Immediate Value Compact branch");
20544 generate_exception_end(ctx
, EXCP_RI
);
20548 /* branch completion */
20549 clear_branch_hflags(ctx
);
20550 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20552 if (cond
== TCG_COND_ALWAYS
) {
20553 /* Uncoditional compact branch */
20554 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20556 /* Conditional compact branch */
20557 TCGLabel
*fs
= gen_new_label();
20559 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
20561 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20564 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20572 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20573 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
20576 TCGv t0
= tcg_temp_new();
20577 TCGv t1
= tcg_temp_new();
20580 gen_load_gpr(t0
, rs
);
20584 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
20587 /* calculate btarget */
20588 tcg_gen_shli_tl(t0
, t0
, 1);
20589 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
20590 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
20592 /* branch completion */
20593 clear_branch_hflags(ctx
);
20594 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20596 /* unconditional branch to register */
20597 tcg_gen_mov_tl(cpu_PC
, btarget
);
20598 tcg_gen_lookup_and_goto_ptr();
20604 /* nanoMIPS Branches */
20605 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
20606 int rs
, int rt
, int32_t offset
)
20608 int bcond_compute
= 0;
20609 TCGv t0
= tcg_temp_new();
20610 TCGv t1
= tcg_temp_new();
20612 /* Load needed operands and calculate btarget */
20614 /* compact branch */
20617 gen_load_gpr(t0
, rs
);
20618 gen_load_gpr(t1
, rt
);
20620 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20624 if (rs
== 0 || rs
== rt
) {
20625 /* OPC_BLEZALC, OPC_BGEZALC */
20626 /* OPC_BGTZALC, OPC_BLTZALC */
20627 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20629 gen_load_gpr(t0
, rs
);
20630 gen_load_gpr(t1
, rt
);
20632 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20635 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20639 /* OPC_BEQZC, OPC_BNEZC */
20640 gen_load_gpr(t0
, rs
);
20642 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20644 /* OPC_JIC, OPC_JIALC */
20645 TCGv tbase
= tcg_temp_new();
20646 TCGv toffset
= tcg_temp_new();
20648 gen_load_gpr(tbase
, rt
);
20649 tcg_gen_movi_tl(toffset
, offset
);
20650 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20651 tcg_temp_free(tbase
);
20652 tcg_temp_free(toffset
);
20656 MIPS_INVAL("Compact branch/jump");
20657 generate_exception_end(ctx
, EXCP_RI
);
20661 if (bcond_compute
== 0) {
20662 /* Uncoditional compact branch */
20665 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20668 MIPS_INVAL("Compact branch/jump");
20669 generate_exception_end(ctx
, EXCP_RI
);
20673 /* Conditional compact branch */
20674 TCGLabel
*fs
= gen_new_label();
20678 if (rs
== 0 && rt
!= 0) {
20680 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20681 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20683 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20686 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20690 if (rs
== 0 && rt
!= 0) {
20692 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20693 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20695 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20698 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20702 if (rs
== 0 && rt
!= 0) {
20704 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20705 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20707 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20710 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20714 if (rs
== 0 && rt
!= 0) {
20716 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20717 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20719 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20722 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20726 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20729 MIPS_INVAL("Compact conditional branch/jump");
20730 generate_exception_end(ctx
, EXCP_RI
);
20734 /* branch completion */
20735 clear_branch_hflags(ctx
);
20736 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20738 /* Generating branch here as compact branches don't have delay slot */
20739 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20742 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20751 /* nanoMIPS CP1 Branches */
20752 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20753 int32_t ft
, int32_t offset
)
20755 target_ulong btarget
;
20756 TCGv_i64 t0
= tcg_temp_new_i64();
20758 gen_load_fpr64(ctx
, t0
, ft
);
20759 tcg_gen_andi_i64(t0
, t0
, 1);
20761 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20765 tcg_gen_xori_i64(t0
, t0
, 1);
20766 ctx
->hflags
|= MIPS_HFLAG_BC
;
20769 /* t0 already set */
20770 ctx
->hflags
|= MIPS_HFLAG_BC
;
20773 MIPS_INVAL("cp1 cond branch");
20774 generate_exception_end(ctx
, EXCP_RI
);
20778 tcg_gen_trunc_i64_tl(bcond
, t0
);
20780 ctx
->btarget
= btarget
;
20783 tcg_temp_free_i64(t0
);
20787 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20790 t0
= tcg_temp_new();
20791 t1
= tcg_temp_new();
20793 gen_load_gpr(t0
, rs
);
20794 gen_load_gpr(t1
, rt
);
20796 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20797 /* PP.LSXS instructions require shifting */
20798 switch (extract32(ctx
->opcode
, 7, 4)) {
20804 tcg_gen_shli_tl(t0
, t0
, 1);
20812 tcg_gen_shli_tl(t0
, t0
, 2);
20816 tcg_gen_shli_tl(t0
, t0
, 3);
20820 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20822 switch (extract32(ctx
->opcode
, 7, 4)) {
20824 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20826 gen_store_gpr(t0
, rd
);
20830 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20832 gen_store_gpr(t0
, rd
);
20836 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20838 gen_store_gpr(t0
, rd
);
20841 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20843 gen_store_gpr(t0
, rd
);
20847 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20849 gen_store_gpr(t0
, rd
);
20853 gen_load_gpr(t1
, rd
);
20854 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20860 gen_load_gpr(t1
, rd
);
20861 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20867 gen_load_gpr(t1
, rd
);
20868 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20872 /*case NM_LWC1XS:*/
20874 /*case NM_LDC1XS:*/
20876 /*case NM_SWC1XS:*/
20878 /*case NM_SDC1XS:*/
20879 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20880 check_cp1_enabled(ctx
);
20881 switch (extract32(ctx
->opcode
, 7, 4)) {
20883 /*case NM_LWC1XS:*/
20884 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20887 /*case NM_LDC1XS:*/
20888 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20891 /*case NM_SWC1XS:*/
20892 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20895 /*case NM_SDC1XS:*/
20896 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20900 generate_exception_err(ctx
, EXCP_CpU
, 1);
20904 generate_exception_end(ctx
, EXCP_RI
);
20912 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20916 rt
= extract32(ctx
->opcode
, 21, 5);
20917 rs
= extract32(ctx
->opcode
, 16, 5);
20918 rd
= extract32(ctx
->opcode
, 11, 5);
20920 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20921 generate_exception_end(ctx
, EXCP_RI
);
20924 check_cp1_enabled(ctx
);
20925 switch (extract32(ctx
->opcode
, 0, 3)) {
20927 switch (extract32(ctx
->opcode
, 3, 7)) {
20929 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20932 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20935 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20938 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20941 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20944 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20947 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20950 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20953 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20956 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20959 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20962 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20965 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20968 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20971 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20974 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20977 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20980 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20983 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20986 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20989 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20992 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20995 generate_exception_end(ctx
, EXCP_RI
);
21000 switch (extract32(ctx
->opcode
, 3, 3)) {
21002 switch (extract32(ctx
->opcode
, 9, 1)) {
21004 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
21007 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
21012 switch (extract32(ctx
->opcode
, 9, 1)) {
21014 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
21017 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
21022 switch (extract32(ctx
->opcode
, 9, 1)) {
21024 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
21027 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
21032 switch (extract32(ctx
->opcode
, 9, 1)) {
21034 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
21037 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
21042 switch (extract32(ctx
->opcode
, 6, 8)) {
21044 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
21047 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
21050 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
21053 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
21056 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
21059 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
21062 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
21065 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
21068 switch (extract32(ctx
->opcode
, 6, 9)) {
21070 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
21073 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
21076 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
21079 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
21082 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
21085 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
21088 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
21091 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
21094 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
21097 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
21100 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
21103 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
21106 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
21109 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
21112 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
21115 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
21118 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
21121 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
21124 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
21127 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
21130 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
21133 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
21136 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
21139 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
21142 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
21145 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
21148 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
21151 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
21154 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
21157 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
21160 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
21163 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
21166 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
21169 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
21172 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
21175 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
21178 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
21181 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
21184 generate_exception_end(ctx
, EXCP_RI
);
21193 switch (extract32(ctx
->opcode
, 3, 3)) {
21194 case NM_CMP_CONDN_S
:
21195 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
21197 case NM_CMP_CONDN_D
:
21198 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
21201 generate_exception_end(ctx
, EXCP_RI
);
21206 generate_exception_end(ctx
, EXCP_RI
);
21211 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
21212 int rd
, int rs
, int rt
)
21215 TCGv t0
= tcg_temp_new();
21216 TCGv v1_t
= tcg_temp_new();
21217 TCGv v2_t
= tcg_temp_new();
21219 gen_load_gpr(v1_t
, rs
);
21220 gen_load_gpr(v2_t
, rt
);
21225 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
21229 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
21233 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
21235 case NM_CMPU_EQ_QB
:
21237 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
21239 case NM_CMPU_LT_QB
:
21241 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
21243 case NM_CMPU_LE_QB
:
21245 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
21247 case NM_CMPGU_EQ_QB
:
21249 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
21250 gen_store_gpr(v1_t
, ret
);
21252 case NM_CMPGU_LT_QB
:
21254 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
21255 gen_store_gpr(v1_t
, ret
);
21257 case NM_CMPGU_LE_QB
:
21259 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
21260 gen_store_gpr(v1_t
, ret
);
21262 case NM_CMPGDU_EQ_QB
:
21264 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
21265 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21266 gen_store_gpr(v1_t
, ret
);
21268 case NM_CMPGDU_LT_QB
:
21270 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
21271 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21272 gen_store_gpr(v1_t
, ret
);
21274 case NM_CMPGDU_LE_QB
:
21276 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
21277 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21278 gen_store_gpr(v1_t
, ret
);
21282 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
21283 gen_store_gpr(v1_t
, ret
);
21287 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21288 gen_store_gpr(v1_t
, ret
);
21292 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21293 gen_store_gpr(v1_t
, ret
);
21297 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21298 gen_store_gpr(v1_t
, ret
);
21302 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21303 gen_store_gpr(v1_t
, ret
);
21307 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
21308 gen_store_gpr(v1_t
, ret
);
21312 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
21313 gen_store_gpr(v1_t
, ret
);
21317 switch (extract32(ctx
->opcode
, 10, 1)) {
21320 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21321 gen_store_gpr(v1_t
, ret
);
21325 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21326 gen_store_gpr(v1_t
, ret
);
21330 case NM_ADDQH_R_PH
:
21332 switch (extract32(ctx
->opcode
, 10, 1)) {
21335 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
21336 gen_store_gpr(v1_t
, ret
);
21340 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
21341 gen_store_gpr(v1_t
, ret
);
21347 switch (extract32(ctx
->opcode
, 10, 1)) {
21350 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
21351 gen_store_gpr(v1_t
, ret
);
21355 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
21356 gen_store_gpr(v1_t
, ret
);
21362 switch (extract32(ctx
->opcode
, 10, 1)) {
21365 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21366 gen_store_gpr(v1_t
, ret
);
21370 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21371 gen_store_gpr(v1_t
, ret
);
21377 switch (extract32(ctx
->opcode
, 10, 1)) {
21380 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21381 gen_store_gpr(v1_t
, ret
);
21385 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21386 gen_store_gpr(v1_t
, ret
);
21390 case NM_ADDUH_R_QB
:
21392 switch (extract32(ctx
->opcode
, 10, 1)) {
21395 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
21396 gen_store_gpr(v1_t
, ret
);
21400 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
21401 gen_store_gpr(v1_t
, ret
);
21405 case NM_SHRAV_R_PH
:
21407 switch (extract32(ctx
->opcode
, 10, 1)) {
21410 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
21411 gen_store_gpr(v1_t
, ret
);
21415 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
21416 gen_store_gpr(v1_t
, ret
);
21420 case NM_SHRAV_R_QB
:
21422 switch (extract32(ctx
->opcode
, 10, 1)) {
21425 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
21426 gen_store_gpr(v1_t
, ret
);
21430 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
21431 gen_store_gpr(v1_t
, ret
);
21437 switch (extract32(ctx
->opcode
, 10, 1)) {
21440 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21441 gen_store_gpr(v1_t
, ret
);
21445 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21446 gen_store_gpr(v1_t
, ret
);
21450 case NM_SUBQH_R_PH
:
21452 switch (extract32(ctx
->opcode
, 10, 1)) {
21455 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
21456 gen_store_gpr(v1_t
, ret
);
21460 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
21461 gen_store_gpr(v1_t
, ret
);
21467 switch (extract32(ctx
->opcode
, 10, 1)) {
21470 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
21471 gen_store_gpr(v1_t
, ret
);
21475 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
21476 gen_store_gpr(v1_t
, ret
);
21482 switch (extract32(ctx
->opcode
, 10, 1)) {
21485 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21486 gen_store_gpr(v1_t
, ret
);
21490 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21491 gen_store_gpr(v1_t
, ret
);
21497 switch (extract32(ctx
->opcode
, 10, 1)) {
21500 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21501 gen_store_gpr(v1_t
, ret
);
21505 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21506 gen_store_gpr(v1_t
, ret
);
21510 case NM_SUBUH_R_QB
:
21512 switch (extract32(ctx
->opcode
, 10, 1)) {
21515 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
21516 gen_store_gpr(v1_t
, ret
);
21520 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
21521 gen_store_gpr(v1_t
, ret
);
21525 case NM_SHLLV_S_PH
:
21527 switch (extract32(ctx
->opcode
, 10, 1)) {
21530 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21531 gen_store_gpr(v1_t
, ret
);
21535 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21536 gen_store_gpr(v1_t
, ret
);
21540 case NM_PRECR_SRA_R_PH_W
:
21542 switch (extract32(ctx
->opcode
, 10, 1)) {
21544 /* PRECR_SRA_PH_W */
21546 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21547 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
21549 gen_store_gpr(v1_t
, rt
);
21550 tcg_temp_free_i32(sa_t
);
21554 /* PRECR_SRA_R_PH_W */
21556 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21557 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
21559 gen_store_gpr(v1_t
, rt
);
21560 tcg_temp_free_i32(sa_t
);
21565 case NM_MULEU_S_PH_QBL
:
21567 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
21568 gen_store_gpr(v1_t
, ret
);
21570 case NM_MULEU_S_PH_QBR
:
21572 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
21573 gen_store_gpr(v1_t
, ret
);
21575 case NM_MULQ_RS_PH
:
21577 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21578 gen_store_gpr(v1_t
, ret
);
21582 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21583 gen_store_gpr(v1_t
, ret
);
21587 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21588 gen_store_gpr(v1_t
, ret
);
21592 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21593 gen_store_gpr(v1_t
, ret
);
21597 gen_load_gpr(t0
, rs
);
21599 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
21601 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21605 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
21606 gen_store_gpr(v1_t
, ret
);
21610 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
21611 gen_store_gpr(v1_t
, ret
);
21615 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
21616 gen_store_gpr(v1_t
, ret
);
21620 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21621 gen_store_gpr(v1_t
, ret
);
21625 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21626 gen_store_gpr(v1_t
, ret
);
21630 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21631 gen_store_gpr(v1_t
, ret
);
21636 TCGv tv0
= tcg_temp_new();
21637 TCGv tv1
= tcg_temp_new();
21638 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21640 tcg_gen_movi_tl(tv0
, rd
>> 3);
21641 tcg_gen_movi_tl(tv1
, imm
);
21642 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21645 case NM_MULEQ_S_W_PHL
:
21647 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21648 gen_store_gpr(v1_t
, ret
);
21650 case NM_MULEQ_S_W_PHR
:
21652 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21653 gen_store_gpr(v1_t
, ret
);
21657 switch (extract32(ctx
->opcode
, 10, 1)) {
21660 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21661 gen_store_gpr(v1_t
, ret
);
21665 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21666 gen_store_gpr(v1_t
, ret
);
21670 case NM_PRECR_QB_PH
:
21672 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21673 gen_store_gpr(v1_t
, ret
);
21675 case NM_PRECRQ_QB_PH
:
21677 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21678 gen_store_gpr(v1_t
, ret
);
21680 case NM_PRECRQ_PH_W
:
21682 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21683 gen_store_gpr(v1_t
, ret
);
21685 case NM_PRECRQ_RS_PH_W
:
21687 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21688 gen_store_gpr(v1_t
, ret
);
21690 case NM_PRECRQU_S_QB_PH
:
21692 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21693 gen_store_gpr(v1_t
, ret
);
21697 tcg_gen_movi_tl(t0
, rd
);
21698 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21699 gen_store_gpr(v1_t
, rt
);
21703 tcg_gen_movi_tl(t0
, rd
>> 1);
21704 switch (extract32(ctx
->opcode
, 10, 1)) {
21707 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21708 gen_store_gpr(v1_t
, rt
);
21712 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21713 gen_store_gpr(v1_t
, rt
);
21719 tcg_gen_movi_tl(t0
, rd
>> 1);
21720 switch (extract32(ctx
->opcode
, 10, 2)) {
21723 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21724 gen_store_gpr(v1_t
, rt
);
21728 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21729 gen_store_gpr(v1_t
, rt
);
21732 generate_exception_end(ctx
, EXCP_RI
);
21738 tcg_gen_movi_tl(t0
, rd
);
21739 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21740 gen_store_gpr(v1_t
, rt
);
21746 imm
= sextract32(ctx
->opcode
, 11, 11);
21747 imm
= (int16_t)(imm
<< 6) >> 6;
21749 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21754 generate_exception_end(ctx
, EXCP_RI
);
21759 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21767 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
21768 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21770 rt
= extract32(ctx
->opcode
, 21, 5);
21771 rs
= extract32(ctx
->opcode
, 16, 5);
21772 rd
= extract32(ctx
->opcode
, 11, 5);
21774 op
= extract32(ctx
->opcode
, 26, 6);
21779 switch (extract32(ctx
->opcode
, 19, 2)) {
21782 generate_exception_end(ctx
, EXCP_RI
);
21785 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21786 generate_exception_end(ctx
, EXCP_SYSCALL
);
21788 generate_exception_end(ctx
, EXCP_RI
);
21792 generate_exception_end(ctx
, EXCP_BREAK
);
21795 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21796 gen_helper_do_semihosting(cpu_env
);
21798 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21799 generate_exception_end(ctx
, EXCP_RI
);
21801 generate_exception_end(ctx
, EXCP_DBp
);
21808 imm
= extract32(ctx
->opcode
, 0, 16);
21810 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21812 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21814 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21819 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21820 extract32(ctx
->opcode
, 1, 20) << 1;
21821 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21822 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21826 switch (ctx
->opcode
& 0x07) {
21828 gen_pool32a0_nanomips_insn(env
, ctx
);
21832 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21833 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21837 switch (extract32(ctx
->opcode
, 3, 3)) {
21839 gen_p_lsx(ctx
, rd
, rs
, rt
);
21843 * In nanoMIPS, the shift field directly encodes the shift
21844 * amount, meaning that the supported shift values are in
21845 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21847 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
21848 extract32(ctx
->opcode
, 9, 2) - 1);
21851 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21854 gen_pool32axf_nanomips_insn(env
, ctx
);
21857 generate_exception_end(ctx
, EXCP_RI
);
21862 generate_exception_end(ctx
, EXCP_RI
);
21867 switch (ctx
->opcode
& 0x03) {
21870 offset
= extract32(ctx
->opcode
, 0, 21);
21871 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21875 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21878 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21881 generate_exception_end(ctx
, EXCP_RI
);
21887 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 4);
21888 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21889 switch (extract32(ctx
->opcode
, 16, 5)) {
21893 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21899 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21900 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21906 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21912 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21915 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21922 t0
= tcg_temp_new();
21924 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21927 tcg_gen_movi_tl(t0
, addr
);
21928 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21936 t0
= tcg_temp_new();
21937 t1
= tcg_temp_new();
21939 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21942 tcg_gen_movi_tl(t0
, addr
);
21943 gen_load_gpr(t1
, rt
);
21945 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21952 generate_exception_end(ctx
, EXCP_RI
);
21958 switch (extract32(ctx
->opcode
, 12, 4)) {
21960 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21963 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21966 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21969 switch (extract32(ctx
->opcode
, 20, 1)) {
21971 switch (ctx
->opcode
& 3) {
21973 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21974 extract32(ctx
->opcode
, 2, 1),
21975 extract32(ctx
->opcode
, 3, 9) << 3);
21978 case NM_RESTORE_JRC
:
21979 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21980 extract32(ctx
->opcode
, 2, 1),
21981 extract32(ctx
->opcode
, 3, 9) << 3);
21982 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21983 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21987 generate_exception_end(ctx
, EXCP_RI
);
21992 generate_exception_end(ctx
, EXCP_RI
);
21997 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
22000 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
22004 TCGv t0
= tcg_temp_new();
22006 imm
= extract32(ctx
->opcode
, 0, 12);
22007 gen_load_gpr(t0
, rs
);
22008 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
22009 gen_store_gpr(t0
, rt
);
22015 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
22016 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
22020 int shift
= extract32(ctx
->opcode
, 0, 5);
22021 switch (extract32(ctx
->opcode
, 5, 4)) {
22023 if (rt
== 0 && shift
== 0) {
22025 } else if (rt
== 0 && shift
== 3) {
22026 /* EHB - treat as NOP */
22027 } else if (rt
== 0 && shift
== 5) {
22028 /* PAUSE - treat as NOP */
22029 } else if (rt
== 0 && shift
== 6) {
22031 gen_sync(extract32(ctx
->opcode
, 16, 5));
22034 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
22035 extract32(ctx
->opcode
, 0, 5));
22039 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
22040 extract32(ctx
->opcode
, 0, 5));
22043 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
22044 extract32(ctx
->opcode
, 0, 5));
22047 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
22048 extract32(ctx
->opcode
, 0, 5));
22056 TCGv t0
= tcg_temp_new();
22057 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
22058 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
22060 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
22062 gen_load_gpr(t0
, rs
);
22063 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
22066 tcg_temp_free_i32(shift
);
22067 tcg_temp_free_i32(shiftx
);
22068 tcg_temp_free_i32(stripe
);
22072 switch (((ctx
->opcode
>> 10) & 2) |
22073 (extract32(ctx
->opcode
, 5, 1))) {
22076 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
22077 extract32(ctx
->opcode
, 6, 5));
22080 generate_exception_end(ctx
, EXCP_RI
);
22085 switch (((ctx
->opcode
>> 10) & 2) |
22086 (extract32(ctx
->opcode
, 5, 1))) {
22089 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
22090 extract32(ctx
->opcode
, 6, 5));
22093 generate_exception_end(ctx
, EXCP_RI
);
22098 generate_exception_end(ctx
, EXCP_RI
);
22103 gen_pool32f_nanomips_insn(ctx
);
22108 switch (extract32(ctx
->opcode
, 1, 1)) {
22111 tcg_gen_movi_tl(cpu_gpr
[rt
],
22112 sextract32(ctx
->opcode
, 0, 1) << 31 |
22113 extract32(ctx
->opcode
, 2, 10) << 21 |
22114 extract32(ctx
->opcode
, 12, 9) << 12);
22119 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
22120 extract32(ctx
->opcode
, 2, 10) << 21 |
22121 extract32(ctx
->opcode
, 12, 9) << 12;
22123 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
22124 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
22131 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
22133 switch (extract32(ctx
->opcode
, 18, 3)) {
22135 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
22138 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
22141 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
22145 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
22150 switch (ctx
->opcode
& 1) {
22152 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
22155 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
22161 switch (ctx
->opcode
& 1) {
22163 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
22166 generate_exception_end(ctx
, EXCP_RI
);
22172 switch (ctx
->opcode
& 0x3) {
22174 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
22177 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
22180 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
22183 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
22188 generate_exception_end(ctx
, EXCP_RI
);
22195 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
22197 switch (extract32(ctx
->opcode
, 12, 4)) {
22202 * Break the TB to be able to sync copied instructions
22205 ctx
->base
.is_jmp
= DISAS_STOP
;
22208 /* Treat as NOP. */
22212 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
22215 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
22218 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
22221 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
22224 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
22227 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
22230 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
22233 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
22236 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
22239 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
22242 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
22245 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
22248 generate_exception_end(ctx
, EXCP_RI
);
22255 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
22256 extract32(ctx
->opcode
, 0, 8);
22258 switch (extract32(ctx
->opcode
, 8, 3)) {
22260 switch (extract32(ctx
->opcode
, 11, 4)) {
22262 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
22265 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
22268 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
22271 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
22274 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
22277 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
22280 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
22283 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
22286 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
22289 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
22292 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
22295 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
22301 * Break the TB to be able to sync copied instructions
22304 ctx
->base
.is_jmp
= DISAS_STOP
;
22307 /* Treat as NOP. */
22311 generate_exception_end(ctx
, EXCP_RI
);
22316 switch (extract32(ctx
->opcode
, 11, 4)) {
22321 TCGv t0
= tcg_temp_new();
22322 TCGv t1
= tcg_temp_new();
22324 gen_base_offset_addr(ctx
, t0
, rs
, s
);
22326 switch (extract32(ctx
->opcode
, 11, 4)) {
22328 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
22330 gen_store_gpr(t0
, rt
);
22333 gen_load_gpr(t1
, rt
);
22334 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
22343 switch (ctx
->opcode
& 0x03) {
22345 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
22349 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22354 switch (ctx
->opcode
& 0x03) {
22356 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
22360 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22366 check_cp0_enabled(ctx
);
22367 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
22368 gen_cache_operation(ctx
, rt
, rs
, s
);
22374 switch (extract32(ctx
->opcode
, 11, 4)) {
22377 check_cp0_enabled(ctx
);
22378 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
22382 check_cp0_enabled(ctx
);
22383 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
22387 check_cp0_enabled(ctx
);
22388 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
22392 /* case NM_SYNCIE */
22394 check_cp0_enabled(ctx
);
22396 * Break the TB to be able to sync copied instructions
22399 ctx
->base
.is_jmp
= DISAS_STOP
;
22401 /* case NM_PREFE */
22403 check_cp0_enabled(ctx
);
22404 /* Treat as NOP. */
22409 check_cp0_enabled(ctx
);
22410 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
22414 check_cp0_enabled(ctx
);
22415 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
22419 check_cp0_enabled(ctx
);
22420 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
22423 check_nms_dl_il_sl_tl_l2c(ctx
);
22424 gen_cache_operation(ctx
, rt
, rs
, s
);
22428 check_cp0_enabled(ctx
);
22429 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
22433 check_cp0_enabled(ctx
);
22434 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
22437 switch (extract32(ctx
->opcode
, 2, 2)) {
22441 check_cp0_enabled(ctx
);
22442 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
22447 check_cp0_enabled(ctx
);
22448 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22451 generate_exception_end(ctx
, EXCP_RI
);
22456 switch (extract32(ctx
->opcode
, 2, 2)) {
22460 check_cp0_enabled(ctx
);
22461 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
22466 check_cp0_enabled(ctx
);
22467 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22471 generate_exception_end(ctx
, EXCP_RI
);
22481 int count
= extract32(ctx
->opcode
, 12, 3);
22484 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
22485 extract32(ctx
->opcode
, 0, 8);
22486 TCGv va
= tcg_temp_new();
22487 TCGv t1
= tcg_temp_new();
22488 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
22489 NM_P_LS_UAWM
? MO_UNALN
: 0;
22491 count
= (count
== 0) ? 8 : count
;
22492 while (counter
!= count
) {
22493 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
22494 int this_offset
= offset
+ (counter
<< 2);
22496 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
22498 switch (extract32(ctx
->opcode
, 11, 1)) {
22500 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
22502 gen_store_gpr(t1
, this_rt
);
22503 if ((this_rt
== rs
) &&
22504 (counter
!= (count
- 1))) {
22505 /* UNPREDICTABLE */
22509 this_rt
= (rt
== 0) ? 0 : this_rt
;
22510 gen_load_gpr(t1
, this_rt
);
22511 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
22522 generate_exception_end(ctx
, EXCP_RI
);
22530 TCGv t0
= tcg_temp_new();
22531 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
22532 extract32(ctx
->opcode
, 1, 20) << 1;
22533 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
22534 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
22535 extract32(ctx
->opcode
, 21, 3));
22536 gen_load_gpr(t0
, rt
);
22537 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22538 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22544 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
22545 extract32(ctx
->opcode
, 1, 24) << 1;
22547 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
22549 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
22552 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22557 switch (extract32(ctx
->opcode
, 12, 4)) {
22560 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
22563 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
22566 generate_exception_end(ctx
, EXCP_RI
);
22572 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22573 extract32(ctx
->opcode
, 1, 13) << 1;
22574 switch (extract32(ctx
->opcode
, 14, 2)) {
22577 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
22580 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22581 extract32(ctx
->opcode
, 1, 13) << 1;
22582 check_cp1_enabled(ctx
);
22583 switch (extract32(ctx
->opcode
, 16, 5)) {
22585 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
22588 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
22593 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
22594 extract32(ctx
->opcode
, 0, 1) << 13;
22596 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
22601 generate_exception_end(ctx
, EXCP_RI
);
22607 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
22609 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
22613 if (rs
== rt
|| rt
== 0) {
22614 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
22615 } else if (rs
== 0) {
22616 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
22618 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22626 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22627 extract32(ctx
->opcode
, 1, 13) << 1;
22628 switch (extract32(ctx
->opcode
, 14, 2)) {
22631 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22634 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22636 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22638 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22642 if (rs
== 0 || rs
== rt
) {
22644 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22646 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22650 generate_exception_end(ctx
, EXCP_RI
);
22657 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22658 extract32(ctx
->opcode
, 1, 10) << 1;
22659 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22661 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22666 generate_exception_end(ctx
, EXCP_RI
);
22672 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22675 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22676 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22677 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22681 /* make sure instructions are on a halfword boundary */
22682 if (ctx
->base
.pc_next
& 0x1) {
22683 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22684 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22685 tcg_temp_free(tmp
);
22686 generate_exception_end(ctx
, EXCP_AdEL
);
22690 op
= extract32(ctx
->opcode
, 10, 6);
22693 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22696 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22697 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22700 switch (extract32(ctx
->opcode
, 3, 2)) {
22701 case NM_P16_SYSCALL
:
22702 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22703 generate_exception_end(ctx
, EXCP_SYSCALL
);
22705 generate_exception_end(ctx
, EXCP_RI
);
22709 generate_exception_end(ctx
, EXCP_BREAK
);
22712 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22713 gen_helper_do_semihosting(cpu_env
);
22715 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22716 generate_exception_end(ctx
, EXCP_RI
);
22718 generate_exception_end(ctx
, EXCP_DBp
);
22723 generate_exception_end(ctx
, EXCP_RI
);
22730 int shift
= extract32(ctx
->opcode
, 0, 3);
22732 shift
= (shift
== 0) ? 8 : shift
;
22734 switch (extract32(ctx
->opcode
, 3, 1)) {
22742 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22746 switch (ctx
->opcode
& 1) {
22748 gen_pool16c_nanomips_insn(ctx
);
22751 gen_ldxs(ctx
, rt
, rs
, rd
);
22756 switch (extract32(ctx
->opcode
, 6, 1)) {
22758 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22759 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22762 generate_exception_end(ctx
, EXCP_RI
);
22767 switch (extract32(ctx
->opcode
, 3, 1)) {
22769 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22770 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22772 case NM_P_ADDIURS5
:
22773 rt
= extract32(ctx
->opcode
, 5, 5);
22775 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22776 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22777 (extract32(ctx
->opcode
, 0, 3));
22778 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22784 switch (ctx
->opcode
& 0x1) {
22786 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22789 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22794 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22795 extract32(ctx
->opcode
, 5, 3);
22796 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22797 extract32(ctx
->opcode
, 0, 3);
22798 rt
= decode_gpr_gpr4(rt
);
22799 rs
= decode_gpr_gpr4(rs
);
22800 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22801 (extract32(ctx
->opcode
, 3, 1))) {
22804 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22808 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22811 generate_exception_end(ctx
, EXCP_RI
);
22817 int imm
= extract32(ctx
->opcode
, 0, 7);
22818 imm
= (imm
== 0x7f ? -1 : imm
);
22820 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22826 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22827 u
= (u
== 12) ? 0xff :
22828 (u
== 13) ? 0xffff : u
;
22829 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22833 offset
= extract32(ctx
->opcode
, 0, 2);
22834 switch (extract32(ctx
->opcode
, 2, 2)) {
22836 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22839 rt
= decode_gpr_gpr3_src_store(
22840 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22841 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22844 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22847 generate_exception_end(ctx
, EXCP_RI
);
22852 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22853 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22855 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22858 rt
= decode_gpr_gpr3_src_store(
22859 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22860 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22863 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22866 generate_exception_end(ctx
, EXCP_RI
);
22871 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22872 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22875 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22876 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22877 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22881 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22882 extract32(ctx
->opcode
, 5, 3);
22883 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22884 extract32(ctx
->opcode
, 0, 3);
22885 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22886 (extract32(ctx
->opcode
, 8, 1) << 2);
22887 rt
= decode_gpr_gpr4(rt
);
22888 rs
= decode_gpr_gpr4(rs
);
22889 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22893 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22894 extract32(ctx
->opcode
, 5, 3);
22895 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22896 extract32(ctx
->opcode
, 0, 3);
22897 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22898 (extract32(ctx
->opcode
, 8, 1) << 2);
22899 rt
= decode_gpr_gpr4_zero(rt
);
22900 rs
= decode_gpr_gpr4(rs
);
22901 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22904 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22905 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22908 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22909 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22910 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22913 rt
= decode_gpr_gpr3_src_store(
22914 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22915 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22916 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22917 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22920 rt
= decode_gpr_gpr3_src_store(
22921 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22922 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22923 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22926 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22927 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22928 (extract32(ctx
->opcode
, 1, 9) << 1));
22931 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22932 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22933 (extract32(ctx
->opcode
, 1, 9) << 1));
22936 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22937 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22938 (extract32(ctx
->opcode
, 1, 6) << 1));
22941 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22942 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22943 (extract32(ctx
->opcode
, 1, 6) << 1));
22946 switch (ctx
->opcode
& 0xf) {
22949 switch (extract32(ctx
->opcode
, 4, 1)) {
22951 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22952 extract32(ctx
->opcode
, 5, 5), 0, 0);
22955 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22956 extract32(ctx
->opcode
, 5, 5), 31, 0);
22963 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22964 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22965 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22966 extract32(ctx
->opcode
, 0, 4) << 1);
22973 int count
= extract32(ctx
->opcode
, 0, 4);
22974 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22976 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22977 switch (extract32(ctx
->opcode
, 8, 1)) {
22979 gen_save(ctx
, rt
, count
, 0, u
);
22981 case NM_RESTORE_JRC16
:
22982 gen_restore(ctx
, rt
, count
, 0, u
);
22983 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22992 static const int gpr2reg1
[] = {4, 5, 6, 7};
22993 static const int gpr2reg2
[] = {5, 6, 7, 8};
22995 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22996 extract32(ctx
->opcode
, 8, 1);
22997 int r1
= gpr2reg1
[rd2
];
22998 int r2
= gpr2reg2
[rd2
];
22999 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
23000 extract32(ctx
->opcode
, 0, 3);
23001 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
23002 extract32(ctx
->opcode
, 5, 3);
23003 TCGv t0
= tcg_temp_new();
23004 TCGv t1
= tcg_temp_new();
23005 if (op
== NM_MOVEP
) {
23008 rs
= decode_gpr_gpr4_zero(r3
);
23009 rt
= decode_gpr_gpr4_zero(r4
);
23011 rd
= decode_gpr_gpr4(r3
);
23012 re
= decode_gpr_gpr4(r4
);
23016 gen_load_gpr(t0
, rs
);
23017 gen_load_gpr(t1
, rt
);
23018 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
23019 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
23025 return decode_nanomips_32_48_opc(env
, ctx
);
23032 /* SmartMIPS extension to MIPS32 */
23034 #if defined(TARGET_MIPS64)
23036 /* MDMX extension to MIPS64 */
23040 /* MIPSDSP functions. */
23041 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
23042 int rd
, int base
, int offset
)
23047 t0
= tcg_temp_new();
23050 gen_load_gpr(t0
, offset
);
23051 } else if (offset
== 0) {
23052 gen_load_gpr(t0
, base
);
23054 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
23059 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
23060 gen_store_gpr(t0
, rd
);
23063 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
23064 gen_store_gpr(t0
, rd
);
23067 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
23068 gen_store_gpr(t0
, rd
);
23070 #if defined(TARGET_MIPS64)
23072 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
23073 gen_store_gpr(t0
, rd
);
23080 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23081 int ret
, int v1
, int v2
)
23087 /* Treat as NOP. */
23091 v1_t
= tcg_temp_new();
23092 v2_t
= tcg_temp_new();
23094 gen_load_gpr(v1_t
, v1
);
23095 gen_load_gpr(v2_t
, v2
);
23098 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
23099 case OPC_MULT_G_2E
:
23103 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23105 case OPC_ADDUH_R_QB
:
23106 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23109 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23111 case OPC_ADDQH_R_PH
:
23112 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23115 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23117 case OPC_ADDQH_R_W
:
23118 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23121 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23123 case OPC_SUBUH_R_QB
:
23124 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23127 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23129 case OPC_SUBQH_R_PH
:
23130 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23133 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23135 case OPC_SUBQH_R_W
:
23136 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23140 case OPC_ABSQ_S_PH_DSP
:
23142 case OPC_ABSQ_S_QB
:
23144 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
23146 case OPC_ABSQ_S_PH
:
23148 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
23152 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
23154 case OPC_PRECEQ_W_PHL
:
23156 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
23157 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23159 case OPC_PRECEQ_W_PHR
:
23161 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
23162 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
23163 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23165 case OPC_PRECEQU_PH_QBL
:
23167 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
23169 case OPC_PRECEQU_PH_QBR
:
23171 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
23173 case OPC_PRECEQU_PH_QBLA
:
23175 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
23177 case OPC_PRECEQU_PH_QBRA
:
23179 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
23181 case OPC_PRECEU_PH_QBL
:
23183 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
23185 case OPC_PRECEU_PH_QBR
:
23187 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
23189 case OPC_PRECEU_PH_QBLA
:
23191 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
23193 case OPC_PRECEU_PH_QBRA
:
23195 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
23199 case OPC_ADDU_QB_DSP
:
23203 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23205 case OPC_ADDQ_S_PH
:
23207 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23211 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23215 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23217 case OPC_ADDU_S_QB
:
23219 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23223 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23225 case OPC_ADDU_S_PH
:
23227 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23231 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23233 case OPC_SUBQ_S_PH
:
23235 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23239 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23243 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23245 case OPC_SUBU_S_QB
:
23247 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23251 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23253 case OPC_SUBU_S_PH
:
23255 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23259 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23263 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23267 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
23269 case OPC_RADDU_W_QB
:
23271 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
23275 case OPC_CMPU_EQ_QB_DSP
:
23277 case OPC_PRECR_QB_PH
:
23279 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23281 case OPC_PRECRQ_QB_PH
:
23283 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23285 case OPC_PRECR_SRA_PH_W
:
23288 TCGv_i32 sa_t
= tcg_const_i32(v2
);
23289 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
23291 tcg_temp_free_i32(sa_t
);
23294 case OPC_PRECR_SRA_R_PH_W
:
23297 TCGv_i32 sa_t
= tcg_const_i32(v2
);
23298 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
23300 tcg_temp_free_i32(sa_t
);
23303 case OPC_PRECRQ_PH_W
:
23305 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23307 case OPC_PRECRQ_RS_PH_W
:
23309 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23311 case OPC_PRECRQU_S_QB_PH
:
23313 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23317 #ifdef TARGET_MIPS64
23318 case OPC_ABSQ_S_QH_DSP
:
23320 case OPC_PRECEQ_L_PWL
:
23322 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
23324 case OPC_PRECEQ_L_PWR
:
23326 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
23328 case OPC_PRECEQ_PW_QHL
:
23330 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
23332 case OPC_PRECEQ_PW_QHR
:
23334 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
23336 case OPC_PRECEQ_PW_QHLA
:
23338 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
23340 case OPC_PRECEQ_PW_QHRA
:
23342 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
23344 case OPC_PRECEQU_QH_OBL
:
23346 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
23348 case OPC_PRECEQU_QH_OBR
:
23350 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
23352 case OPC_PRECEQU_QH_OBLA
:
23354 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
23356 case OPC_PRECEQU_QH_OBRA
:
23358 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
23360 case OPC_PRECEU_QH_OBL
:
23362 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
23364 case OPC_PRECEU_QH_OBR
:
23366 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
23368 case OPC_PRECEU_QH_OBLA
:
23370 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
23372 case OPC_PRECEU_QH_OBRA
:
23374 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
23376 case OPC_ABSQ_S_OB
:
23378 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
23380 case OPC_ABSQ_S_PW
:
23382 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
23384 case OPC_ABSQ_S_QH
:
23386 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
23390 case OPC_ADDU_OB_DSP
:
23392 case OPC_RADDU_L_OB
:
23394 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
23398 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23400 case OPC_SUBQ_S_PW
:
23402 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23406 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23408 case OPC_SUBQ_S_QH
:
23410 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23414 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23416 case OPC_SUBU_S_OB
:
23418 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23422 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23424 case OPC_SUBU_S_QH
:
23426 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23430 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23432 case OPC_SUBUH_R_OB
:
23434 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23438 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23440 case OPC_ADDQ_S_PW
:
23442 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23446 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23448 case OPC_ADDQ_S_QH
:
23450 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23454 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23456 case OPC_ADDU_S_OB
:
23458 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23462 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23464 case OPC_ADDU_S_QH
:
23466 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23470 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23472 case OPC_ADDUH_R_OB
:
23474 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23478 case OPC_CMPU_EQ_OB_DSP
:
23480 case OPC_PRECR_OB_QH
:
23482 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23484 case OPC_PRECR_SRA_QH_PW
:
23487 TCGv_i32 ret_t
= tcg_const_i32(ret
);
23488 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
23489 tcg_temp_free_i32(ret_t
);
23492 case OPC_PRECR_SRA_R_QH_PW
:
23495 TCGv_i32 sa_v
= tcg_const_i32(ret
);
23496 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
23497 tcg_temp_free_i32(sa_v
);
23500 case OPC_PRECRQ_OB_QH
:
23502 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23504 case OPC_PRECRQ_PW_L
:
23506 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
23508 case OPC_PRECRQ_QH_PW
:
23510 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23512 case OPC_PRECRQ_RS_QH_PW
:
23514 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23516 case OPC_PRECRQU_S_OB_QH
:
23518 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23525 tcg_temp_free(v1_t
);
23526 tcg_temp_free(v2_t
);
23529 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
23530 int ret
, int v1
, int v2
)
23538 /* Treat as NOP. */
23542 t0
= tcg_temp_new();
23543 v1_t
= tcg_temp_new();
23544 v2_t
= tcg_temp_new();
23546 tcg_gen_movi_tl(t0
, v1
);
23547 gen_load_gpr(v1_t
, v1
);
23548 gen_load_gpr(v2_t
, v2
);
23551 case OPC_SHLL_QB_DSP
:
23553 op2
= MASK_SHLL_QB(ctx
->opcode
);
23557 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23561 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23565 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23569 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23571 case OPC_SHLL_S_PH
:
23573 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23575 case OPC_SHLLV_S_PH
:
23577 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23581 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23583 case OPC_SHLLV_S_W
:
23585 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23589 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
23593 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23597 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
23601 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23605 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
23607 case OPC_SHRA_R_QB
:
23609 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
23613 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23615 case OPC_SHRAV_R_QB
:
23617 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23621 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23623 case OPC_SHRA_R_PH
:
23625 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23629 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23631 case OPC_SHRAV_R_PH
:
23633 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23637 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23639 case OPC_SHRAV_R_W
:
23641 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23643 default: /* Invalid */
23644 MIPS_INVAL("MASK SHLL.QB");
23645 generate_exception_end(ctx
, EXCP_RI
);
23650 #ifdef TARGET_MIPS64
23651 case OPC_SHLL_OB_DSP
:
23652 op2
= MASK_SHLL_OB(ctx
->opcode
);
23656 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23660 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23662 case OPC_SHLL_S_PW
:
23664 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23666 case OPC_SHLLV_S_PW
:
23668 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23672 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23676 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23680 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23684 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23686 case OPC_SHLL_S_QH
:
23688 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23690 case OPC_SHLLV_S_QH
:
23692 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23696 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23700 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23702 case OPC_SHRA_R_OB
:
23704 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23706 case OPC_SHRAV_R_OB
:
23708 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23712 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23716 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23718 case OPC_SHRA_R_PW
:
23720 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23722 case OPC_SHRAV_R_PW
:
23724 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23728 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23732 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23734 case OPC_SHRA_R_QH
:
23736 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23738 case OPC_SHRAV_R_QH
:
23740 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23744 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23748 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23752 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23756 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23758 default: /* Invalid */
23759 MIPS_INVAL("MASK SHLL.OB");
23760 generate_exception_end(ctx
, EXCP_RI
);
23768 tcg_temp_free(v1_t
);
23769 tcg_temp_free(v2_t
);
23772 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23773 int ret
, int v1
, int v2
, int check_ret
)
23779 if ((ret
== 0) && (check_ret
== 1)) {
23780 /* Treat as NOP. */
23784 t0
= tcg_temp_new_i32();
23785 v1_t
= tcg_temp_new();
23786 v2_t
= tcg_temp_new();
23788 tcg_gen_movi_i32(t0
, ret
);
23789 gen_load_gpr(v1_t
, v1
);
23790 gen_load_gpr(v2_t
, v2
);
23794 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23795 * the same mask and op1.
23797 case OPC_MULT_G_2E
:
23801 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23804 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23807 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23809 case OPC_MULQ_RS_W
:
23810 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23814 case OPC_DPA_W_PH_DSP
:
23816 case OPC_DPAU_H_QBL
:
23818 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23820 case OPC_DPAU_H_QBR
:
23822 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23824 case OPC_DPSU_H_QBL
:
23826 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23828 case OPC_DPSU_H_QBR
:
23830 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23834 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23836 case OPC_DPAX_W_PH
:
23838 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23840 case OPC_DPAQ_S_W_PH
:
23842 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23844 case OPC_DPAQX_S_W_PH
:
23846 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23848 case OPC_DPAQX_SA_W_PH
:
23850 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23854 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23856 case OPC_DPSX_W_PH
:
23858 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23860 case OPC_DPSQ_S_W_PH
:
23862 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23864 case OPC_DPSQX_S_W_PH
:
23866 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23868 case OPC_DPSQX_SA_W_PH
:
23870 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23872 case OPC_MULSAQ_S_W_PH
:
23874 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23876 case OPC_DPAQ_SA_L_W
:
23878 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23880 case OPC_DPSQ_SA_L_W
:
23882 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23884 case OPC_MAQ_S_W_PHL
:
23886 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23888 case OPC_MAQ_S_W_PHR
:
23890 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23892 case OPC_MAQ_SA_W_PHL
:
23894 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23896 case OPC_MAQ_SA_W_PHR
:
23898 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23900 case OPC_MULSA_W_PH
:
23902 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23906 #ifdef TARGET_MIPS64
23907 case OPC_DPAQ_W_QH_DSP
:
23909 int ac
= ret
& 0x03;
23910 tcg_gen_movi_i32(t0
, ac
);
23915 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23919 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23923 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23927 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23931 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23933 case OPC_DPAQ_S_W_QH
:
23935 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23937 case OPC_DPAQ_SA_L_PW
:
23939 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23941 case OPC_DPAU_H_OBL
:
23943 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23945 case OPC_DPAU_H_OBR
:
23947 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23951 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23953 case OPC_DPSQ_S_W_QH
:
23955 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23957 case OPC_DPSQ_SA_L_PW
:
23959 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23961 case OPC_DPSU_H_OBL
:
23963 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23965 case OPC_DPSU_H_OBR
:
23967 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23969 case OPC_MAQ_S_L_PWL
:
23971 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23973 case OPC_MAQ_S_L_PWR
:
23975 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23977 case OPC_MAQ_S_W_QHLL
:
23979 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23981 case OPC_MAQ_SA_W_QHLL
:
23983 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23985 case OPC_MAQ_S_W_QHLR
:
23987 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23989 case OPC_MAQ_SA_W_QHLR
:
23991 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23993 case OPC_MAQ_S_W_QHRL
:
23995 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23997 case OPC_MAQ_SA_W_QHRL
:
23999 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
24001 case OPC_MAQ_S_W_QHRR
:
24003 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
24005 case OPC_MAQ_SA_W_QHRR
:
24007 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
24009 case OPC_MULSAQ_S_L_PW
:
24011 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
24013 case OPC_MULSAQ_S_W_QH
:
24015 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
24021 case OPC_ADDU_QB_DSP
:
24023 case OPC_MULEU_S_PH_QBL
:
24025 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24027 case OPC_MULEU_S_PH_QBR
:
24029 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24031 case OPC_MULQ_RS_PH
:
24033 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24035 case OPC_MULEQ_S_W_PHL
:
24037 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24039 case OPC_MULEQ_S_W_PHR
:
24041 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24043 case OPC_MULQ_S_PH
:
24045 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24049 #ifdef TARGET_MIPS64
24050 case OPC_ADDU_OB_DSP
:
24052 case OPC_MULEQ_S_PW_QHL
:
24054 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24056 case OPC_MULEQ_S_PW_QHR
:
24058 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24060 case OPC_MULEU_S_QH_OBL
:
24062 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24064 case OPC_MULEU_S_QH_OBR
:
24066 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24068 case OPC_MULQ_RS_QH
:
24070 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24077 tcg_temp_free_i32(t0
);
24078 tcg_temp_free(v1_t
);
24079 tcg_temp_free(v2_t
);
24082 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24090 /* Treat as NOP. */
24094 t0
= tcg_temp_new();
24095 val_t
= tcg_temp_new();
24096 gen_load_gpr(val_t
, val
);
24099 case OPC_ABSQ_S_PH_DSP
:
24103 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
24108 target_long result
;
24109 imm
= (ctx
->opcode
>> 16) & 0xFF;
24110 result
= (uint32_t)imm
<< 24 |
24111 (uint32_t)imm
<< 16 |
24112 (uint32_t)imm
<< 8 |
24114 result
= (int32_t)result
;
24115 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
24120 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
24121 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
24122 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24123 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24124 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24125 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
24130 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24131 imm
= (int16_t)(imm
<< 6) >> 6;
24132 tcg_gen_movi_tl(cpu_gpr
[ret
], \
24133 (target_long
)((int32_t)imm
<< 16 | \
24139 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
24140 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24141 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24142 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
24146 #ifdef TARGET_MIPS64
24147 case OPC_ABSQ_S_QH_DSP
:
24154 imm
= (ctx
->opcode
>> 16) & 0xFF;
24155 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
24156 temp
= (temp
<< 16) | temp
;
24157 temp
= (temp
<< 32) | temp
;
24158 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24166 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24167 imm
= (int16_t)(imm
<< 6) >> 6;
24168 temp
= ((target_long
)imm
<< 32) \
24169 | ((target_long
)imm
& 0xFFFFFFFF);
24170 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24178 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24179 imm
= (int16_t)(imm
<< 6) >> 6;
24181 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
24182 ((uint64_t)(uint16_t)imm
<< 32) |
24183 ((uint64_t)(uint16_t)imm
<< 16) |
24184 (uint64_t)(uint16_t)imm
;
24185 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24190 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
24191 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
24192 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24193 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24194 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24195 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24196 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24200 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
24201 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24202 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24206 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
24207 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24208 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24209 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24210 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24217 tcg_temp_free(val_t
);
24220 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
24221 uint32_t op1
, uint32_t op2
,
24222 int ret
, int v1
, int v2
, int check_ret
)
24228 if ((ret
== 0) && (check_ret
== 1)) {
24229 /* Treat as NOP. */
24233 t1
= tcg_temp_new();
24234 v1_t
= tcg_temp_new();
24235 v2_t
= tcg_temp_new();
24237 gen_load_gpr(v1_t
, v1
);
24238 gen_load_gpr(v2_t
, v2
);
24241 case OPC_CMPU_EQ_QB_DSP
:
24243 case OPC_CMPU_EQ_QB
:
24245 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
24247 case OPC_CMPU_LT_QB
:
24249 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
24251 case OPC_CMPU_LE_QB
:
24253 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
24255 case OPC_CMPGU_EQ_QB
:
24257 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24259 case OPC_CMPGU_LT_QB
:
24261 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24263 case OPC_CMPGU_LE_QB
:
24265 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24267 case OPC_CMPGDU_EQ_QB
:
24269 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
24270 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24271 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24272 tcg_gen_shli_tl(t1
, t1
, 24);
24273 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24275 case OPC_CMPGDU_LT_QB
:
24277 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
24278 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24279 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24280 tcg_gen_shli_tl(t1
, t1
, 24);
24281 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24283 case OPC_CMPGDU_LE_QB
:
24285 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
24286 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24287 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24288 tcg_gen_shli_tl(t1
, t1
, 24);
24289 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24291 case OPC_CMP_EQ_PH
:
24293 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
24295 case OPC_CMP_LT_PH
:
24297 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
24299 case OPC_CMP_LE_PH
:
24301 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
24305 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24309 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24311 case OPC_PACKRL_PH
:
24313 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
24317 #ifdef TARGET_MIPS64
24318 case OPC_CMPU_EQ_OB_DSP
:
24320 case OPC_CMP_EQ_PW
:
24322 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
24324 case OPC_CMP_LT_PW
:
24326 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
24328 case OPC_CMP_LE_PW
:
24330 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
24332 case OPC_CMP_EQ_QH
:
24334 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
24336 case OPC_CMP_LT_QH
:
24338 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
24340 case OPC_CMP_LE_QH
:
24342 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
24344 case OPC_CMPGDU_EQ_OB
:
24346 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24348 case OPC_CMPGDU_LT_OB
:
24350 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24352 case OPC_CMPGDU_LE_OB
:
24354 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24356 case OPC_CMPGU_EQ_OB
:
24358 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24360 case OPC_CMPGU_LT_OB
:
24362 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24364 case OPC_CMPGU_LE_OB
:
24366 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24368 case OPC_CMPU_EQ_OB
:
24370 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
24372 case OPC_CMPU_LT_OB
:
24374 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
24376 case OPC_CMPU_LE_OB
:
24378 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
24380 case OPC_PACKRL_PW
:
24382 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
24386 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24390 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24394 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24402 tcg_temp_free(v1_t
);
24403 tcg_temp_free(v2_t
);
24406 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
24407 uint32_t op1
, int rt
, int rs
, int sa
)
24414 /* Treat as NOP. */
24418 t0
= tcg_temp_new();
24419 gen_load_gpr(t0
, rs
);
24422 case OPC_APPEND_DSP
:
24423 switch (MASK_APPEND(ctx
->opcode
)) {
24426 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
24428 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24432 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24433 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24434 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
24435 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24437 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24441 if (sa
!= 0 && sa
!= 2) {
24442 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24443 tcg_gen_ext32u_tl(t0
, t0
);
24444 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
24445 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24447 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24449 default: /* Invalid */
24450 MIPS_INVAL("MASK APPEND");
24451 generate_exception_end(ctx
, EXCP_RI
);
24455 #ifdef TARGET_MIPS64
24456 case OPC_DAPPEND_DSP
:
24457 switch (MASK_DAPPEND(ctx
->opcode
)) {
24460 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
24464 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
24465 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
24466 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
24470 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24471 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
24472 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24477 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
24478 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24479 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
24480 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24483 default: /* Invalid */
24484 MIPS_INVAL("MASK DAPPEND");
24485 generate_exception_end(ctx
, EXCP_RI
);
24494 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24495 int ret
, int v1
, int v2
, int check_ret
)
24504 if ((ret
== 0) && (check_ret
== 1)) {
24505 /* Treat as NOP. */
24509 t0
= tcg_temp_new();
24510 t1
= tcg_temp_new();
24511 v1_t
= tcg_temp_new();
24512 v2_t
= tcg_temp_new();
24514 gen_load_gpr(v1_t
, v1
);
24515 gen_load_gpr(v2_t
, v2
);
24518 case OPC_EXTR_W_DSP
:
24522 tcg_gen_movi_tl(t0
, v2
);
24523 tcg_gen_movi_tl(t1
, v1
);
24524 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24527 tcg_gen_movi_tl(t0
, v2
);
24528 tcg_gen_movi_tl(t1
, v1
);
24529 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24531 case OPC_EXTR_RS_W
:
24532 tcg_gen_movi_tl(t0
, v2
);
24533 tcg_gen_movi_tl(t1
, v1
);
24534 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24537 tcg_gen_movi_tl(t0
, v2
);
24538 tcg_gen_movi_tl(t1
, v1
);
24539 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24541 case OPC_EXTRV_S_H
:
24542 tcg_gen_movi_tl(t0
, v2
);
24543 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24546 tcg_gen_movi_tl(t0
, v2
);
24547 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24549 case OPC_EXTRV_R_W
:
24550 tcg_gen_movi_tl(t0
, v2
);
24551 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24553 case OPC_EXTRV_RS_W
:
24554 tcg_gen_movi_tl(t0
, v2
);
24555 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24558 tcg_gen_movi_tl(t0
, v2
);
24559 tcg_gen_movi_tl(t1
, v1
);
24560 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24563 tcg_gen_movi_tl(t0
, v2
);
24564 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24567 tcg_gen_movi_tl(t0
, v2
);
24568 tcg_gen_movi_tl(t1
, v1
);
24569 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24572 tcg_gen_movi_tl(t0
, v2
);
24573 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24576 imm
= (ctx
->opcode
>> 20) & 0x3F;
24577 tcg_gen_movi_tl(t0
, ret
);
24578 tcg_gen_movi_tl(t1
, imm
);
24579 gen_helper_shilo(t0
, t1
, cpu_env
);
24582 tcg_gen_movi_tl(t0
, ret
);
24583 gen_helper_shilo(t0
, v1_t
, cpu_env
);
24586 tcg_gen_movi_tl(t0
, ret
);
24587 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
24590 imm
= (ctx
->opcode
>> 11) & 0x3FF;
24591 tcg_gen_movi_tl(t0
, imm
);
24592 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
24595 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24596 tcg_gen_movi_tl(t0
, imm
);
24597 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
24601 #ifdef TARGET_MIPS64
24602 case OPC_DEXTR_W_DSP
:
24606 tcg_gen_movi_tl(t0
, ret
);
24607 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
24611 int shift
= (ctx
->opcode
>> 19) & 0x7F;
24612 int ac
= (ctx
->opcode
>> 11) & 0x03;
24613 tcg_gen_movi_tl(t0
, shift
);
24614 tcg_gen_movi_tl(t1
, ac
);
24615 gen_helper_dshilo(t0
, t1
, cpu_env
);
24620 int ac
= (ctx
->opcode
>> 11) & 0x03;
24621 tcg_gen_movi_tl(t0
, ac
);
24622 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24626 tcg_gen_movi_tl(t0
, v2
);
24627 tcg_gen_movi_tl(t1
, v1
);
24629 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24632 tcg_gen_movi_tl(t0
, v2
);
24633 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24636 tcg_gen_movi_tl(t0
, v2
);
24637 tcg_gen_movi_tl(t1
, v1
);
24638 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24641 tcg_gen_movi_tl(t0
, v2
);
24642 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24645 tcg_gen_movi_tl(t0
, v2
);
24646 tcg_gen_movi_tl(t1
, v1
);
24647 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24649 case OPC_DEXTR_R_L
:
24650 tcg_gen_movi_tl(t0
, v2
);
24651 tcg_gen_movi_tl(t1
, v1
);
24652 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24654 case OPC_DEXTR_RS_L
:
24655 tcg_gen_movi_tl(t0
, v2
);
24656 tcg_gen_movi_tl(t1
, v1
);
24657 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24660 tcg_gen_movi_tl(t0
, v2
);
24661 tcg_gen_movi_tl(t1
, v1
);
24662 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24664 case OPC_DEXTR_R_W
:
24665 tcg_gen_movi_tl(t0
, v2
);
24666 tcg_gen_movi_tl(t1
, v1
);
24667 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24669 case OPC_DEXTR_RS_W
:
24670 tcg_gen_movi_tl(t0
, v2
);
24671 tcg_gen_movi_tl(t1
, v1
);
24672 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24674 case OPC_DEXTR_S_H
:
24675 tcg_gen_movi_tl(t0
, v2
);
24676 tcg_gen_movi_tl(t1
, v1
);
24677 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24679 case OPC_DEXTRV_S_H
:
24680 tcg_gen_movi_tl(t0
, v2
);
24681 tcg_gen_movi_tl(t1
, v1
);
24682 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24685 tcg_gen_movi_tl(t0
, v2
);
24686 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24688 case OPC_DEXTRV_R_L
:
24689 tcg_gen_movi_tl(t0
, v2
);
24690 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24692 case OPC_DEXTRV_RS_L
:
24693 tcg_gen_movi_tl(t0
, v2
);
24694 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24697 tcg_gen_movi_tl(t0
, v2
);
24698 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24700 case OPC_DEXTRV_R_W
:
24701 tcg_gen_movi_tl(t0
, v2
);
24702 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24704 case OPC_DEXTRV_RS_W
:
24705 tcg_gen_movi_tl(t0
, v2
);
24706 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24715 tcg_temp_free(v1_t
);
24716 tcg_temp_free(v2_t
);
24719 /* End MIPSDSP functions. */
24721 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24723 int rs
, rt
, rd
, sa
;
24726 rs
= (ctx
->opcode
>> 21) & 0x1f;
24727 rt
= (ctx
->opcode
>> 16) & 0x1f;
24728 rd
= (ctx
->opcode
>> 11) & 0x1f;
24729 sa
= (ctx
->opcode
>> 6) & 0x1f;
24731 op1
= MASK_SPECIAL(ctx
->opcode
);
24734 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24740 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24750 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24753 MIPS_INVAL("special_r6 muldiv");
24754 generate_exception_end(ctx
, EXCP_RI
);
24760 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24764 if (rt
== 0 && sa
== 1) {
24766 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24767 * We need additionally to check other fields.
24769 gen_cl(ctx
, op1
, rd
, rs
);
24771 generate_exception_end(ctx
, EXCP_RI
);
24775 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24776 gen_helper_do_semihosting(cpu_env
);
24778 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24779 generate_exception_end(ctx
, EXCP_RI
);
24781 generate_exception_end(ctx
, EXCP_DBp
);
24785 #if defined(TARGET_MIPS64)
24787 check_mips_64(ctx
);
24788 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24792 if (rt
== 0 && sa
== 1) {
24794 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24795 * We need additionally to check other fields.
24797 check_mips_64(ctx
);
24798 gen_cl(ctx
, op1
, rd
, rs
);
24800 generate_exception_end(ctx
, EXCP_RI
);
24808 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24818 check_mips_64(ctx
);
24819 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24822 MIPS_INVAL("special_r6 muldiv");
24823 generate_exception_end(ctx
, EXCP_RI
);
24828 default: /* Invalid */
24829 MIPS_INVAL("special_r6");
24830 generate_exception_end(ctx
, EXCP_RI
);
24835 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24837 int rs
= extract32(ctx
->opcode
, 21, 5);
24838 int rt
= extract32(ctx
->opcode
, 16, 5);
24839 int rd
= extract32(ctx
->opcode
, 11, 5);
24840 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24843 case OPC_MOVN
: /* Conditional move */
24845 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24847 case OPC_MFHI
: /* Move from HI/LO */
24849 gen_HILO(ctx
, op1
, 0, rd
);
24852 case OPC_MTLO
: /* Move to HI/LO */
24853 gen_HILO(ctx
, op1
, 0, rs
);
24857 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24861 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24863 #if defined(TARGET_MIPS64)
24868 check_insn_opc_user_only(ctx
, INSN_R5900
);
24869 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24873 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24875 default: /* Invalid */
24876 MIPS_INVAL("special_tx79");
24877 generate_exception_end(ctx
, EXCP_RI
);
24882 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24884 int rs
, rt
, rd
, sa
;
24887 rs
= (ctx
->opcode
>> 21) & 0x1f;
24888 rt
= (ctx
->opcode
>> 16) & 0x1f;
24889 rd
= (ctx
->opcode
>> 11) & 0x1f;
24890 sa
= (ctx
->opcode
>> 6) & 0x1f;
24892 op1
= MASK_SPECIAL(ctx
->opcode
);
24894 case OPC_MOVN
: /* Conditional move */
24896 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
24897 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24898 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24900 case OPC_MFHI
: /* Move from HI/LO */
24902 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24905 case OPC_MTLO
: /* Move to HI/LO */
24906 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24909 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
24910 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24911 check_cp1_enabled(ctx
);
24912 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24913 (ctx
->opcode
>> 16) & 1);
24915 generate_exception_err(ctx
, EXCP_CpU
, 1);
24921 check_insn(ctx
, INSN_VR54XX
);
24922 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24923 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24925 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24930 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24932 #if defined(TARGET_MIPS64)
24937 check_insn(ctx
, ISA_MIPS3
);
24938 check_mips_64(ctx
);
24939 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24943 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24946 #ifdef MIPS_STRICT_STANDARD
24947 MIPS_INVAL("SPIM");
24948 generate_exception_end(ctx
, EXCP_RI
);
24950 /* Implemented as RI exception for now. */
24951 MIPS_INVAL("spim (unofficial)");
24952 generate_exception_end(ctx
, EXCP_RI
);
24955 default: /* Invalid */
24956 MIPS_INVAL("special_legacy");
24957 generate_exception_end(ctx
, EXCP_RI
);
24962 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24964 int rs
, rt
, rd
, sa
;
24967 rs
= (ctx
->opcode
>> 21) & 0x1f;
24968 rt
= (ctx
->opcode
>> 16) & 0x1f;
24969 rd
= (ctx
->opcode
>> 11) & 0x1f;
24970 sa
= (ctx
->opcode
>> 6) & 0x1f;
24972 op1
= MASK_SPECIAL(ctx
->opcode
);
24974 case OPC_SLL
: /* Shift with immediate */
24975 if (sa
== 5 && rd
== 0 &&
24976 rs
== 0 && rt
== 0) { /* PAUSE */
24977 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
24978 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24979 generate_exception_end(ctx
, EXCP_RI
);
24985 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24988 switch ((ctx
->opcode
>> 21) & 0x1f) {
24990 /* rotr is decoded as srl on non-R2 CPUs */
24991 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24996 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24999 generate_exception_end(ctx
, EXCP_RI
);
25007 gen_arith(ctx
, op1
, rd
, rs
, rt
);
25009 case OPC_SLLV
: /* Shifts */
25011 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25014 switch ((ctx
->opcode
>> 6) & 0x1f) {
25016 /* rotrv is decoded as srlv on non-R2 CPUs */
25017 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
25022 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25025 generate_exception_end(ctx
, EXCP_RI
);
25029 case OPC_SLT
: /* Set on less than */
25031 gen_slt(ctx
, op1
, rd
, rs
, rt
);
25033 case OPC_AND
: /* Logic*/
25037 gen_logic(ctx
, op1
, rd
, rs
, rt
);
25040 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
25042 case OPC_TGE
: /* Traps */
25048 check_insn(ctx
, ISA_MIPS2
);
25049 gen_trap(ctx
, op1
, rs
, rt
, -1);
25051 case OPC_LSA
: /* OPC_PMON */
25052 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
25053 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
25054 decode_opc_special_r6(env
, ctx
);
25056 /* Pmon entry point, also R4010 selsl */
25057 #ifdef MIPS_STRICT_STANDARD
25058 MIPS_INVAL("PMON / selsl");
25059 generate_exception_end(ctx
, EXCP_RI
);
25061 gen_helper_0e0i(pmon
, sa
);
25066 generate_exception_end(ctx
, EXCP_SYSCALL
);
25069 generate_exception_end(ctx
, EXCP_BREAK
);
25072 check_insn(ctx
, ISA_MIPS2
);
25073 gen_sync(extract32(ctx
->opcode
, 6, 5));
25076 #if defined(TARGET_MIPS64)
25077 /* MIPS64 specific opcodes */
25082 check_insn(ctx
, ISA_MIPS3
);
25083 check_mips_64(ctx
);
25084 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
25087 switch ((ctx
->opcode
>> 21) & 0x1f) {
25089 /* drotr is decoded as dsrl on non-R2 CPUs */
25090 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
25095 check_insn(ctx
, ISA_MIPS3
);
25096 check_mips_64(ctx
);
25097 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
25100 generate_exception_end(ctx
, EXCP_RI
);
25105 switch ((ctx
->opcode
>> 21) & 0x1f) {
25107 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
25108 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
25113 check_insn(ctx
, ISA_MIPS3
);
25114 check_mips_64(ctx
);
25115 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
25118 generate_exception_end(ctx
, EXCP_RI
);
25126 check_insn(ctx
, ISA_MIPS3
);
25127 check_mips_64(ctx
);
25128 gen_arith(ctx
, op1
, rd
, rs
, rt
);
25132 check_insn(ctx
, ISA_MIPS3
);
25133 check_mips_64(ctx
);
25134 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25137 switch ((ctx
->opcode
>> 6) & 0x1f) {
25139 /* drotrv is decoded as dsrlv on non-R2 CPUs */
25140 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
25145 check_insn(ctx
, ISA_MIPS3
);
25146 check_mips_64(ctx
);
25147 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25150 generate_exception_end(ctx
, EXCP_RI
);
25155 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
25156 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
25157 decode_opc_special_r6(env
, ctx
);
25162 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
25163 decode_opc_special_r6(env
, ctx
);
25164 } else if (ctx
->insn_flags
& INSN_R5900
) {
25165 decode_opc_special_tx79(env
, ctx
);
25167 decode_opc_special_legacy(env
, ctx
);
25173 #if defined(TARGET_MIPS64)
25177 * MMI (MultiMedia Interface) ASE instructions
25178 * ===========================================
25182 * MMI instructions category: data communication
25183 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25185 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
25186 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
25187 * PCPYUD PEXEH PEXTLW PPACW
25196 * Parallel Copy Halfword
25198 * 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
25199 * +-----------+---------+---------+---------+---------+-----------+
25200 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
25201 * +-----------+---------+---------+---------+---------+-----------+
25203 static void gen_mmi_pcpyh(DisasContext
*ctx
)
25205 uint32_t pd
, rt
, rd
;
25208 opcode
= ctx
->opcode
;
25210 pd
= extract32(opcode
, 21, 5);
25211 rt
= extract32(opcode
, 16, 5);
25212 rd
= extract32(opcode
, 11, 5);
25214 if (unlikely(pd
!= 0)) {
25215 generate_exception_end(ctx
, EXCP_RI
);
25216 } else if (rd
== 0) {
25218 } else if (rt
== 0) {
25219 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25220 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25222 TCGv_i64 t0
= tcg_temp_new();
25223 TCGv_i64 t1
= tcg_temp_new();
25224 uint64_t mask
= (1ULL << 16) - 1;
25226 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
25227 tcg_gen_movi_i64(t1
, 0);
25228 tcg_gen_or_i64(t1
, t0
, t1
);
25229 tcg_gen_shli_i64(t0
, t0
, 16);
25230 tcg_gen_or_i64(t1
, t0
, t1
);
25231 tcg_gen_shli_i64(t0
, t0
, 16);
25232 tcg_gen_or_i64(t1
, t0
, t1
);
25233 tcg_gen_shli_i64(t0
, t0
, 16);
25234 tcg_gen_or_i64(t1
, t0
, t1
);
25236 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
25238 tcg_gen_andi_i64(t0
, cpu_mmr
[rt
], mask
);
25239 tcg_gen_movi_i64(t1
, 0);
25240 tcg_gen_or_i64(t1
, t0
, t1
);
25241 tcg_gen_shli_i64(t0
, t0
, 16);
25242 tcg_gen_or_i64(t1
, t0
, t1
);
25243 tcg_gen_shli_i64(t0
, t0
, 16);
25244 tcg_gen_or_i64(t1
, t0
, t1
);
25245 tcg_gen_shli_i64(t0
, t0
, 16);
25246 tcg_gen_or_i64(t1
, t0
, t1
);
25248 tcg_gen_mov_i64(cpu_mmr
[rd
], t1
);
25256 * PCPYLD rd, rs, rt
25258 * Parallel Copy Lower Doubleword
25260 * 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
25261 * +-----------+---------+---------+---------+---------+-----------+
25262 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
25263 * +-----------+---------+---------+---------+---------+-----------+
25265 static void gen_mmi_pcpyld(DisasContext
*ctx
)
25267 uint32_t rs
, rt
, rd
;
25270 opcode
= ctx
->opcode
;
25272 rs
= extract32(opcode
, 21, 5);
25273 rt
= extract32(opcode
, 16, 5);
25274 rd
= extract32(opcode
, 11, 5);
25280 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25282 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_gpr
[rs
]);
25285 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25288 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
25295 * PCPYUD rd, rs, rt
25297 * Parallel Copy Upper Doubleword
25299 * 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
25300 * +-----------+---------+---------+---------+---------+-----------+
25301 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
25302 * +-----------+---------+---------+---------+---------+-----------+
25304 static void gen_mmi_pcpyud(DisasContext
*ctx
)
25306 uint32_t rs
, rt
, rd
;
25309 opcode
= ctx
->opcode
;
25311 rs
= extract32(opcode
, 21, 5);
25312 rt
= extract32(opcode
, 16, 5);
25313 rd
= extract32(opcode
, 11, 5);
25319 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25321 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_mmr
[rs
]);
25324 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25327 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_mmr
[rt
]);
25336 #if !defined(TARGET_MIPS64)
25338 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
25339 #define MXU_APTN1_A 0
25340 #define MXU_APTN1_S 1
25342 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
25343 #define MXU_APTN2_AA 0
25344 #define MXU_APTN2_AS 1
25345 #define MXU_APTN2_SA 2
25346 #define MXU_APTN2_SS 3
25348 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
25349 #define MXU_EPTN2_AA 0
25350 #define MXU_EPTN2_AS 1
25351 #define MXU_EPTN2_SA 2
25352 #define MXU_EPTN2_SS 3
25354 /* MXU operand getting pattern 'optn2' */
25355 #define MXU_OPTN2_PTN0 0
25356 #define MXU_OPTN2_PTN1 1
25357 #define MXU_OPTN2_PTN2 2
25358 #define MXU_OPTN2_PTN3 3
25359 /* alternative naming scheme for 'optn2' */
25360 #define MXU_OPTN2_WW 0
25361 #define MXU_OPTN2_LW 1
25362 #define MXU_OPTN2_HW 2
25363 #define MXU_OPTN2_XW 3
25365 /* MXU operand getting pattern 'optn3' */
25366 #define MXU_OPTN3_PTN0 0
25367 #define MXU_OPTN3_PTN1 1
25368 #define MXU_OPTN3_PTN2 2
25369 #define MXU_OPTN3_PTN3 3
25370 #define MXU_OPTN3_PTN4 4
25371 #define MXU_OPTN3_PTN5 5
25372 #define MXU_OPTN3_PTN6 6
25373 #define MXU_OPTN3_PTN7 7
25377 * S32I2M XRa, rb - Register move from GRF to XRF
25379 static void gen_mxu_s32i2m(DisasContext
*ctx
)
25384 t0
= tcg_temp_new();
25386 XRa
= extract32(ctx
->opcode
, 6, 5);
25387 Rb
= extract32(ctx
->opcode
, 16, 5);
25389 gen_load_gpr(t0
, Rb
);
25391 gen_store_mxu_gpr(t0
, XRa
);
25392 } else if (XRa
== 16) {
25393 gen_store_mxu_cr(t0
);
25400 * S32M2I XRa, rb - Register move from XRF to GRF
25402 static void gen_mxu_s32m2i(DisasContext
*ctx
)
25407 t0
= tcg_temp_new();
25409 XRa
= extract32(ctx
->opcode
, 6, 5);
25410 Rb
= extract32(ctx
->opcode
, 16, 5);
25413 gen_load_mxu_gpr(t0
, XRa
);
25414 } else if (XRa
== 16) {
25415 gen_load_mxu_cr(t0
);
25418 gen_store_gpr(t0
, Rb
);
25424 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
25426 static void gen_mxu_s8ldd(DisasContext
*ctx
)
25429 uint32_t XRa
, Rb
, s8
, optn3
;
25431 t0
= tcg_temp_new();
25432 t1
= tcg_temp_new();
25434 XRa
= extract32(ctx
->opcode
, 6, 4);
25435 s8
= extract32(ctx
->opcode
, 10, 8);
25436 optn3
= extract32(ctx
->opcode
, 18, 3);
25437 Rb
= extract32(ctx
->opcode
, 21, 5);
25439 gen_load_gpr(t0
, Rb
);
25440 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
25443 /* XRa[7:0] = tmp8 */
25444 case MXU_OPTN3_PTN0
:
25445 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25446 gen_load_mxu_gpr(t0
, XRa
);
25447 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
25449 /* XRa[15:8] = tmp8 */
25450 case MXU_OPTN3_PTN1
:
25451 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25452 gen_load_mxu_gpr(t0
, XRa
);
25453 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
25455 /* XRa[23:16] = tmp8 */
25456 case MXU_OPTN3_PTN2
:
25457 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25458 gen_load_mxu_gpr(t0
, XRa
);
25459 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
25461 /* XRa[31:24] = tmp8 */
25462 case MXU_OPTN3_PTN3
:
25463 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25464 gen_load_mxu_gpr(t0
, XRa
);
25465 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
25467 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25468 case MXU_OPTN3_PTN4
:
25469 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25470 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25472 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25473 case MXU_OPTN3_PTN5
:
25474 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25475 tcg_gen_shli_tl(t1
, t1
, 8);
25476 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25478 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25479 case MXU_OPTN3_PTN6
:
25480 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
25481 tcg_gen_mov_tl(t0
, t1
);
25482 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
25483 tcg_gen_shli_tl(t1
, t1
, 16);
25484 tcg_gen_or_tl(t0
, t0
, t1
);
25486 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25487 case MXU_OPTN3_PTN7
:
25488 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25489 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
25490 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25494 gen_store_mxu_gpr(t0
, XRa
);
25501 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25503 static void gen_mxu_d16mul(DisasContext
*ctx
)
25505 TCGv t0
, t1
, t2
, t3
;
25506 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
25508 t0
= tcg_temp_new();
25509 t1
= tcg_temp_new();
25510 t2
= tcg_temp_new();
25511 t3
= tcg_temp_new();
25513 XRa
= extract32(ctx
->opcode
, 6, 4);
25514 XRb
= extract32(ctx
->opcode
, 10, 4);
25515 XRc
= extract32(ctx
->opcode
, 14, 4);
25516 XRd
= extract32(ctx
->opcode
, 18, 4);
25517 optn2
= extract32(ctx
->opcode
, 22, 2);
25519 gen_load_mxu_gpr(t1
, XRb
);
25520 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25521 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25522 gen_load_mxu_gpr(t3
, XRc
);
25523 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25524 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25527 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25528 tcg_gen_mul_tl(t3
, t1
, t3
);
25529 tcg_gen_mul_tl(t2
, t0
, t2
);
25531 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25532 tcg_gen_mul_tl(t3
, t0
, t3
);
25533 tcg_gen_mul_tl(t2
, t0
, t2
);
25535 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25536 tcg_gen_mul_tl(t3
, t1
, t3
);
25537 tcg_gen_mul_tl(t2
, t1
, t2
);
25539 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25540 tcg_gen_mul_tl(t3
, t0
, t3
);
25541 tcg_gen_mul_tl(t2
, t1
, t2
);
25544 gen_store_mxu_gpr(t3
, XRa
);
25545 gen_store_mxu_gpr(t2
, XRd
);
25554 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25557 static void gen_mxu_d16mac(DisasContext
*ctx
)
25559 TCGv t0
, t1
, t2
, t3
;
25560 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
25562 t0
= tcg_temp_new();
25563 t1
= tcg_temp_new();
25564 t2
= tcg_temp_new();
25565 t3
= tcg_temp_new();
25567 XRa
= extract32(ctx
->opcode
, 6, 4);
25568 XRb
= extract32(ctx
->opcode
, 10, 4);
25569 XRc
= extract32(ctx
->opcode
, 14, 4);
25570 XRd
= extract32(ctx
->opcode
, 18, 4);
25571 optn2
= extract32(ctx
->opcode
, 22, 2);
25572 aptn2
= extract32(ctx
->opcode
, 24, 2);
25574 gen_load_mxu_gpr(t1
, XRb
);
25575 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25576 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25578 gen_load_mxu_gpr(t3
, XRc
);
25579 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25580 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25583 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25584 tcg_gen_mul_tl(t3
, t1
, t3
);
25585 tcg_gen_mul_tl(t2
, t0
, t2
);
25587 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25588 tcg_gen_mul_tl(t3
, t0
, t3
);
25589 tcg_gen_mul_tl(t2
, t0
, t2
);
25591 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25592 tcg_gen_mul_tl(t3
, t1
, t3
);
25593 tcg_gen_mul_tl(t2
, t1
, t2
);
25595 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25596 tcg_gen_mul_tl(t3
, t0
, t3
);
25597 tcg_gen_mul_tl(t2
, t1
, t2
);
25600 gen_load_mxu_gpr(t0
, XRa
);
25601 gen_load_mxu_gpr(t1
, XRd
);
25605 tcg_gen_add_tl(t3
, t0
, t3
);
25606 tcg_gen_add_tl(t2
, t1
, t2
);
25609 tcg_gen_add_tl(t3
, t0
, t3
);
25610 tcg_gen_sub_tl(t2
, t1
, t2
);
25613 tcg_gen_sub_tl(t3
, t0
, t3
);
25614 tcg_gen_add_tl(t2
, t1
, t2
);
25617 tcg_gen_sub_tl(t3
, t0
, t3
);
25618 tcg_gen_sub_tl(t2
, t1
, t2
);
25621 gen_store_mxu_gpr(t3
, XRa
);
25622 gen_store_mxu_gpr(t2
, XRd
);
25631 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25632 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25634 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25636 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25637 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25639 t0
= tcg_temp_new();
25640 t1
= tcg_temp_new();
25641 t2
= tcg_temp_new();
25642 t3
= tcg_temp_new();
25643 t4
= tcg_temp_new();
25644 t5
= tcg_temp_new();
25645 t6
= tcg_temp_new();
25646 t7
= tcg_temp_new();
25648 XRa
= extract32(ctx
->opcode
, 6, 4);
25649 XRb
= extract32(ctx
->opcode
, 10, 4);
25650 XRc
= extract32(ctx
->opcode
, 14, 4);
25651 XRd
= extract32(ctx
->opcode
, 18, 4);
25652 sel
= extract32(ctx
->opcode
, 22, 2);
25654 gen_load_mxu_gpr(t3
, XRb
);
25655 gen_load_mxu_gpr(t7
, XRc
);
25659 tcg_gen_ext8s_tl(t0
, t3
);
25660 tcg_gen_shri_tl(t3
, t3
, 8);
25661 tcg_gen_ext8s_tl(t1
, t3
);
25662 tcg_gen_shri_tl(t3
, t3
, 8);
25663 tcg_gen_ext8s_tl(t2
, t3
);
25664 tcg_gen_shri_tl(t3
, t3
, 8);
25665 tcg_gen_ext8s_tl(t3
, t3
);
25668 tcg_gen_ext8u_tl(t0
, t3
);
25669 tcg_gen_shri_tl(t3
, t3
, 8);
25670 tcg_gen_ext8u_tl(t1
, t3
);
25671 tcg_gen_shri_tl(t3
, t3
, 8);
25672 tcg_gen_ext8u_tl(t2
, t3
);
25673 tcg_gen_shri_tl(t3
, t3
, 8);
25674 tcg_gen_ext8u_tl(t3
, t3
);
25677 tcg_gen_ext8u_tl(t4
, t7
);
25678 tcg_gen_shri_tl(t7
, t7
, 8);
25679 tcg_gen_ext8u_tl(t5
, t7
);
25680 tcg_gen_shri_tl(t7
, t7
, 8);
25681 tcg_gen_ext8u_tl(t6
, t7
);
25682 tcg_gen_shri_tl(t7
, t7
, 8);
25683 tcg_gen_ext8u_tl(t7
, t7
);
25685 tcg_gen_mul_tl(t0
, t0
, t4
);
25686 tcg_gen_mul_tl(t1
, t1
, t5
);
25687 tcg_gen_mul_tl(t2
, t2
, t6
);
25688 tcg_gen_mul_tl(t3
, t3
, t7
);
25690 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25691 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25692 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25693 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25695 tcg_gen_shli_tl(t1
, t1
, 16);
25696 tcg_gen_shli_tl(t3
, t3
, 16);
25698 tcg_gen_or_tl(t0
, t0
, t1
);
25699 tcg_gen_or_tl(t1
, t2
, t3
);
25701 gen_store_mxu_gpr(t0
, XRd
);
25702 gen_store_mxu_gpr(t1
, XRa
);
25715 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25716 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25718 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25721 uint32_t XRa
, Rb
, s12
, sel
;
25723 t0
= tcg_temp_new();
25724 t1
= tcg_temp_new();
25726 XRa
= extract32(ctx
->opcode
, 6, 4);
25727 s12
= extract32(ctx
->opcode
, 10, 10);
25728 sel
= extract32(ctx
->opcode
, 20, 1);
25729 Rb
= extract32(ctx
->opcode
, 21, 5);
25731 gen_load_gpr(t0
, Rb
);
25733 tcg_gen_movi_tl(t1
, s12
);
25734 tcg_gen_shli_tl(t1
, t1
, 2);
25736 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25738 tcg_gen_add_tl(t1
, t0
, t1
);
25739 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25743 tcg_gen_bswap32_tl(t1
, t1
);
25745 gen_store_mxu_gpr(t1
, XRa
);
25753 * MXU instruction category: logic
25754 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25756 * S32NOR S32AND S32OR S32XOR
25760 * S32NOR XRa, XRb, XRc
25761 * Update XRa with the result of logical bitwise 'nor' operation
25762 * applied to the content of XRb and XRc.
25764 * 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
25765 * +-----------+---------+-----+-------+-------+-------+-----------+
25766 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25767 * +-----------+---------+-----+-------+-------+-------+-----------+
25769 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25771 uint32_t pad
, XRc
, XRb
, XRa
;
25773 pad
= extract32(ctx
->opcode
, 21, 5);
25774 XRc
= extract32(ctx
->opcode
, 14, 4);
25775 XRb
= extract32(ctx
->opcode
, 10, 4);
25776 XRa
= extract32(ctx
->opcode
, 6, 4);
25778 if (unlikely(pad
!= 0)) {
25779 /* opcode padding incorrect -> do nothing */
25780 } else if (unlikely(XRa
== 0)) {
25781 /* destination is zero register -> do nothing */
25782 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25783 /* both operands zero registers -> just set destination to all 1s */
25784 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25785 } else if (unlikely(XRb
== 0)) {
25786 /* XRb zero register -> just set destination to the negation of XRc */
25787 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25788 } else if (unlikely(XRc
== 0)) {
25789 /* XRa zero register -> just set destination to the negation of XRb */
25790 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25791 } else if (unlikely(XRb
== XRc
)) {
25792 /* both operands same -> just set destination to the negation of XRb */
25793 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25795 /* the most general case */
25796 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25801 * S32AND XRa, XRb, XRc
25802 * Update XRa with the result of logical bitwise 'and' operation
25803 * applied to the content of XRb and XRc.
25805 * 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
25806 * +-----------+---------+-----+-------+-------+-------+-----------+
25807 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25808 * +-----------+---------+-----+-------+-------+-------+-----------+
25810 static void gen_mxu_S32AND(DisasContext
*ctx
)
25812 uint32_t pad
, XRc
, XRb
, XRa
;
25814 pad
= extract32(ctx
->opcode
, 21, 5);
25815 XRc
= extract32(ctx
->opcode
, 14, 4);
25816 XRb
= extract32(ctx
->opcode
, 10, 4);
25817 XRa
= extract32(ctx
->opcode
, 6, 4);
25819 if (unlikely(pad
!= 0)) {
25820 /* opcode padding incorrect -> do nothing */
25821 } else if (unlikely(XRa
== 0)) {
25822 /* destination is zero register -> do nothing */
25823 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25824 /* one of operands zero register -> just set destination to all 0s */
25825 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25826 } else if (unlikely(XRb
== XRc
)) {
25827 /* both operands same -> just set destination to one of them */
25828 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25830 /* the most general case */
25831 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25836 * S32OR XRa, XRb, XRc
25837 * Update XRa with the result of logical bitwise 'or' operation
25838 * applied to the content of XRb and XRc.
25840 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25841 * +-----------+---------+-----+-------+-------+-------+-----------+
25842 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25843 * +-----------+---------+-----+-------+-------+-------+-----------+
25845 static void gen_mxu_S32OR(DisasContext
*ctx
)
25847 uint32_t pad
, XRc
, XRb
, XRa
;
25849 pad
= extract32(ctx
->opcode
, 21, 5);
25850 XRc
= extract32(ctx
->opcode
, 14, 4);
25851 XRb
= extract32(ctx
->opcode
, 10, 4);
25852 XRa
= extract32(ctx
->opcode
, 6, 4);
25854 if (unlikely(pad
!= 0)) {
25855 /* opcode padding incorrect -> do nothing */
25856 } else if (unlikely(XRa
== 0)) {
25857 /* destination is zero register -> do nothing */
25858 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25859 /* both operands zero registers -> just set destination to all 0s */
25860 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25861 } else if (unlikely(XRb
== 0)) {
25862 /* XRb zero register -> just set destination to the content of XRc */
25863 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25864 } else if (unlikely(XRc
== 0)) {
25865 /* XRc zero register -> just set destination to the content of XRb */
25866 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25867 } else if (unlikely(XRb
== XRc
)) {
25868 /* both operands same -> just set destination to one of them */
25869 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25871 /* the most general case */
25872 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25877 * S32XOR XRa, XRb, XRc
25878 * Update XRa with the result of logical bitwise 'xor' operation
25879 * applied to the content of XRb and XRc.
25881 * 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
25882 * +-----------+---------+-----+-------+-------+-------+-----------+
25883 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25884 * +-----------+---------+-----+-------+-------+-------+-----------+
25886 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25888 uint32_t pad
, XRc
, XRb
, XRa
;
25890 pad
= extract32(ctx
->opcode
, 21, 5);
25891 XRc
= extract32(ctx
->opcode
, 14, 4);
25892 XRb
= extract32(ctx
->opcode
, 10, 4);
25893 XRa
= extract32(ctx
->opcode
, 6, 4);
25895 if (unlikely(pad
!= 0)) {
25896 /* opcode padding incorrect -> do nothing */
25897 } else if (unlikely(XRa
== 0)) {
25898 /* destination is zero register -> do nothing */
25899 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25900 /* both operands zero registers -> just set destination to all 0s */
25901 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25902 } else if (unlikely(XRb
== 0)) {
25903 /* XRb zero register -> just set destination to the content of XRc */
25904 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25905 } else if (unlikely(XRc
== 0)) {
25906 /* XRc zero register -> just set destination to the content of XRb */
25907 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25908 } else if (unlikely(XRb
== XRc
)) {
25909 /* both operands same -> just set destination to all 0s */
25910 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25912 /* the most general case */
25913 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25919 * MXU instruction category max/min
25920 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25922 * S32MAX D16MAX Q8MAX
25923 * S32MIN D16MIN Q8MIN
25927 * S32MAX XRa, XRb, XRc
25928 * Update XRa with the maximum of signed 32-bit integers contained
25931 * S32MIN XRa, XRb, XRc
25932 * Update XRa with the minimum of signed 32-bit integers contained
25935 * 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
25936 * +-----------+---------+-----+-------+-------+-------+-----------+
25937 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25938 * +-----------+---------+-----+-------+-------+-------+-----------+
25940 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25942 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25944 pad
= extract32(ctx
->opcode
, 21, 5);
25945 opc
= extract32(ctx
->opcode
, 18, 3);
25946 XRc
= extract32(ctx
->opcode
, 14, 4);
25947 XRb
= extract32(ctx
->opcode
, 10, 4);
25948 XRa
= extract32(ctx
->opcode
, 6, 4);
25950 if (unlikely(pad
!= 0)) {
25951 /* opcode padding incorrect -> do nothing */
25952 } else if (unlikely(XRa
== 0)) {
25953 /* destination is zero register -> do nothing */
25954 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25955 /* both operands zero registers -> just set destination to zero */
25956 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25957 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25958 /* exactly one operand is zero register - find which one is not...*/
25959 uint32_t XRx
= XRb
? XRb
: XRc
;
25960 /* ...and do max/min operation with one operand 0 */
25961 if (opc
== OPC_MXU_S32MAX
) {
25962 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25964 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25966 } else if (unlikely(XRb
== XRc
)) {
25967 /* both operands same -> just set destination to one of them */
25968 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25970 /* the most general case */
25971 if (opc
== OPC_MXU_S32MAX
) {
25972 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25975 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25983 * Update XRa with the 16-bit-wise maximums of signed integers
25984 * contained in XRb and XRc.
25987 * Update XRa with the 16-bit-wise minimums of signed integers
25988 * contained in XRb and XRc.
25990 * 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
25991 * +-----------+---------+-----+-------+-------+-------+-----------+
25992 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25993 * +-----------+---------+-----+-------+-------+-------+-----------+
25995 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25997 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25999 pad
= extract32(ctx
->opcode
, 21, 5);
26000 opc
= extract32(ctx
->opcode
, 18, 3);
26001 XRc
= extract32(ctx
->opcode
, 14, 4);
26002 XRb
= extract32(ctx
->opcode
, 10, 4);
26003 XRa
= extract32(ctx
->opcode
, 6, 4);
26005 if (unlikely(pad
!= 0)) {
26006 /* opcode padding incorrect -> do nothing */
26007 } else if (unlikely(XRc
== 0)) {
26008 /* destination is zero register -> do nothing */
26009 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
26010 /* both operands zero registers -> just set destination to zero */
26011 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
26012 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
26013 /* exactly one operand is zero register - find which one is not...*/
26014 uint32_t XRx
= XRb
? XRb
: XRc
;
26015 /* ...and do half-word-wise max/min with one operand 0 */
26016 TCGv_i32 t0
= tcg_temp_new();
26017 TCGv_i32 t1
= tcg_const_i32(0);
26019 /* the left half-word first */
26020 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
26021 if (opc
== OPC_MXU_D16MAX
) {
26022 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26024 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26027 /* the right half-word */
26028 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
26029 /* move half-words to the leftmost position */
26030 tcg_gen_shli_i32(t0
, t0
, 16);
26031 /* t0 will be max/min of t0 and t1 */
26032 if (opc
== OPC_MXU_D16MAX
) {
26033 tcg_gen_smax_i32(t0
, t0
, t1
);
26035 tcg_gen_smin_i32(t0
, t0
, t1
);
26037 /* return resulting half-words to its original position */
26038 tcg_gen_shri_i32(t0
, t0
, 16);
26039 /* finally update the destination */
26040 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26044 } else if (unlikely(XRb
== XRc
)) {
26045 /* both operands same -> just set destination to one of them */
26046 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26048 /* the most general case */
26049 TCGv_i32 t0
= tcg_temp_new();
26050 TCGv_i32 t1
= tcg_temp_new();
26052 /* the left half-word first */
26053 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
26054 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
26055 if (opc
== OPC_MXU_D16MAX
) {
26056 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26058 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26061 /* the right half-word */
26062 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
26063 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
26064 /* move half-words to the leftmost position */
26065 tcg_gen_shli_i32(t0
, t0
, 16);
26066 tcg_gen_shli_i32(t1
, t1
, 16);
26067 /* t0 will be max/min of t0 and t1 */
26068 if (opc
== OPC_MXU_D16MAX
) {
26069 tcg_gen_smax_i32(t0
, t0
, t1
);
26071 tcg_gen_smin_i32(t0
, t0
, t1
);
26073 /* return resulting half-words to its original position */
26074 tcg_gen_shri_i32(t0
, t0
, 16);
26075 /* finally update the destination */
26076 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26085 * Update XRa with the 8-bit-wise maximums of signed integers
26086 * contained in XRb and XRc.
26089 * Update XRa with the 8-bit-wise minimums of signed integers
26090 * contained in XRb and XRc.
26092 * 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
26093 * +-----------+---------+-----+-------+-------+-------+-----------+
26094 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
26095 * +-----------+---------+-----+-------+-------+-------+-----------+
26097 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
26099 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
26101 pad
= extract32(ctx
->opcode
, 21, 5);
26102 opc
= extract32(ctx
->opcode
, 18, 3);
26103 XRc
= extract32(ctx
->opcode
, 14, 4);
26104 XRb
= extract32(ctx
->opcode
, 10, 4);
26105 XRa
= extract32(ctx
->opcode
, 6, 4);
26107 if (unlikely(pad
!= 0)) {
26108 /* opcode padding incorrect -> do nothing */
26109 } else if (unlikely(XRa
== 0)) {
26110 /* destination is zero register -> do nothing */
26111 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
26112 /* both operands zero registers -> just set destination to zero */
26113 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26114 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
26115 /* exactly one operand is zero register - make it be the first...*/
26116 uint32_t XRx
= XRb
? XRb
: XRc
;
26117 /* ...and do byte-wise max/min with one operand 0 */
26118 TCGv_i32 t0
= tcg_temp_new();
26119 TCGv_i32 t1
= tcg_const_i32(0);
26122 /* the leftmost byte (byte 3) first */
26123 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
26124 if (opc
== OPC_MXU_Q8MAX
) {
26125 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26127 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26130 /* bytes 2, 1, 0 */
26131 for (i
= 2; i
>= 0; i
--) {
26132 /* extract the byte */
26133 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
26134 /* move the byte to the leftmost position */
26135 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
26136 /* t0 will be max/min of t0 and t1 */
26137 if (opc
== OPC_MXU_Q8MAX
) {
26138 tcg_gen_smax_i32(t0
, t0
, t1
);
26140 tcg_gen_smin_i32(t0
, t0
, t1
);
26142 /* return resulting byte to its original position */
26143 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
26144 /* finally update the destination */
26145 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26150 } else if (unlikely(XRb
== XRc
)) {
26151 /* both operands same -> just set destination to one of them */
26152 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26154 /* the most general case */
26155 TCGv_i32 t0
= tcg_temp_new();
26156 TCGv_i32 t1
= tcg_temp_new();
26159 /* the leftmost bytes (bytes 3) first */
26160 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
26161 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
26162 if (opc
== OPC_MXU_Q8MAX
) {
26163 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26165 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26168 /* bytes 2, 1, 0 */
26169 for (i
= 2; i
>= 0; i
--) {
26170 /* extract corresponding bytes */
26171 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
26172 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
26173 /* move the bytes to the leftmost position */
26174 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
26175 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
26176 /* t0 will be max/min of t0 and t1 */
26177 if (opc
== OPC_MXU_Q8MAX
) {
26178 tcg_gen_smax_i32(t0
, t0
, t1
);
26180 tcg_gen_smin_i32(t0
, t0
, t1
);
26182 /* return resulting byte to its original position */
26183 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
26184 /* finally update the destination */
26185 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26195 * MXU instruction category: align
26196 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26202 * S32ALNI XRc, XRb, XRa, optn3
26203 * Arrange bytes from XRb and XRc according to one of five sets of
26204 * rules determined by optn3, and place the result in XRa.
26206 * 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
26207 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26208 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26209 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26212 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
26214 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
26216 optn3
= extract32(ctx
->opcode
, 23, 3);
26217 pad
= extract32(ctx
->opcode
, 21, 2);
26218 XRc
= extract32(ctx
->opcode
, 14, 4);
26219 XRb
= extract32(ctx
->opcode
, 10, 4);
26220 XRa
= extract32(ctx
->opcode
, 6, 4);
26222 if (unlikely(pad
!= 0)) {
26223 /* opcode padding incorrect -> do nothing */
26224 } else if (unlikely(XRa
== 0)) {
26225 /* destination is zero register -> do nothing */
26226 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
26227 /* both operands zero registers -> just set destination to all 0s */
26228 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26229 } else if (unlikely(XRb
== 0)) {
26230 /* XRb zero register -> just appropriatelly shift XRc into XRa */
26232 case MXU_OPTN3_PTN0
:
26233 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26235 case MXU_OPTN3_PTN1
:
26236 case MXU_OPTN3_PTN2
:
26237 case MXU_OPTN3_PTN3
:
26238 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
26241 case MXU_OPTN3_PTN4
:
26242 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
26245 } else if (unlikely(XRc
== 0)) {
26246 /* XRc zero register -> just appropriatelly shift XRb into XRa */
26248 case MXU_OPTN3_PTN0
:
26249 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26251 case MXU_OPTN3_PTN1
:
26252 case MXU_OPTN3_PTN2
:
26253 case MXU_OPTN3_PTN3
:
26254 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
26256 case MXU_OPTN3_PTN4
:
26257 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26260 } else if (unlikely(XRb
== XRc
)) {
26261 /* both operands same -> just rotation or moving from any of them */
26263 case MXU_OPTN3_PTN0
:
26264 case MXU_OPTN3_PTN4
:
26265 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26267 case MXU_OPTN3_PTN1
:
26268 case MXU_OPTN3_PTN2
:
26269 case MXU_OPTN3_PTN3
:
26270 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
26274 /* the most general case */
26276 case MXU_OPTN3_PTN0
:
26280 /* +---------------+ */
26281 /* | A B C D | E F G H */
26282 /* +-------+-------+ */
26287 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26290 case MXU_OPTN3_PTN1
:
26294 /* +-------------------+ */
26295 /* A | B C D E | F G H */
26296 /* +---------+---------+ */
26301 TCGv_i32 t0
= tcg_temp_new();
26302 TCGv_i32 t1
= tcg_temp_new();
26304 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
26305 tcg_gen_shli_i32(t0
, t0
, 8);
26307 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
26308 tcg_gen_shri_i32(t1
, t1
, 24);
26310 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26316 case MXU_OPTN3_PTN2
:
26320 /* +-------------------+ */
26321 /* A B | C D E F | G H */
26322 /* +---------+---------+ */
26327 TCGv_i32 t0
= tcg_temp_new();
26328 TCGv_i32 t1
= tcg_temp_new();
26330 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
26331 tcg_gen_shli_i32(t0
, t0
, 16);
26333 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
26334 tcg_gen_shri_i32(t1
, t1
, 16);
26336 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26342 case MXU_OPTN3_PTN3
:
26346 /* +-------------------+ */
26347 /* A B C | D E F G | H */
26348 /* +---------+---------+ */
26353 TCGv_i32 t0
= tcg_temp_new();
26354 TCGv_i32 t1
= tcg_temp_new();
26356 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
26357 tcg_gen_shli_i32(t0
, t0
, 24);
26359 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
26360 tcg_gen_shri_i32(t1
, t1
, 8);
26362 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26368 case MXU_OPTN3_PTN4
:
26372 /* +---------------+ */
26373 /* A B C D | E F G H | */
26374 /* +-------+-------+ */
26379 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
26388 * Decoding engine for MXU
26389 * =======================
26394 * Decode MXU pool00
26396 * 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
26397 * +-----------+---------+-----+-------+-------+-------+-----------+
26398 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
26399 * +-----------+---------+-----+-------+-------+-------+-----------+
26402 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
26404 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26407 case OPC_MXU_S32MAX
:
26408 case OPC_MXU_S32MIN
:
26409 gen_mxu_S32MAX_S32MIN(ctx
);
26411 case OPC_MXU_D16MAX
:
26412 case OPC_MXU_D16MIN
:
26413 gen_mxu_D16MAX_D16MIN(ctx
);
26415 case OPC_MXU_Q8MAX
:
26416 case OPC_MXU_Q8MIN
:
26417 gen_mxu_Q8MAX_Q8MIN(ctx
);
26419 case OPC_MXU_Q8SLT
:
26420 /* TODO: Implement emulation of Q8SLT instruction. */
26421 MIPS_INVAL("OPC_MXU_Q8SLT");
26422 generate_exception_end(ctx
, EXCP_RI
);
26424 case OPC_MXU_Q8SLTU
:
26425 /* TODO: Implement emulation of Q8SLTU instruction. */
26426 MIPS_INVAL("OPC_MXU_Q8SLTU");
26427 generate_exception_end(ctx
, EXCP_RI
);
26430 MIPS_INVAL("decode_opc_mxu");
26431 generate_exception_end(ctx
, EXCP_RI
);
26438 * Decode MXU pool01
26440 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
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 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26444 * +-----------+---------+-----+-------+-------+-------+-----------+
26447 * 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
26448 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26449 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26450 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26453 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
26455 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26458 case OPC_MXU_S32SLT
:
26459 /* TODO: Implement emulation of S32SLT instruction. */
26460 MIPS_INVAL("OPC_MXU_S32SLT");
26461 generate_exception_end(ctx
, EXCP_RI
);
26463 case OPC_MXU_D16SLT
:
26464 /* TODO: Implement emulation of D16SLT instruction. */
26465 MIPS_INVAL("OPC_MXU_D16SLT");
26466 generate_exception_end(ctx
, EXCP_RI
);
26468 case OPC_MXU_D16AVG
:
26469 /* TODO: Implement emulation of D16AVG instruction. */
26470 MIPS_INVAL("OPC_MXU_D16AVG");
26471 generate_exception_end(ctx
, EXCP_RI
);
26473 case OPC_MXU_D16AVGR
:
26474 /* TODO: Implement emulation of D16AVGR instruction. */
26475 MIPS_INVAL("OPC_MXU_D16AVGR");
26476 generate_exception_end(ctx
, EXCP_RI
);
26478 case OPC_MXU_Q8AVG
:
26479 /* TODO: Implement emulation of Q8AVG instruction. */
26480 MIPS_INVAL("OPC_MXU_Q8AVG");
26481 generate_exception_end(ctx
, EXCP_RI
);
26483 case OPC_MXU_Q8AVGR
:
26484 /* TODO: Implement emulation of Q8AVGR instruction. */
26485 MIPS_INVAL("OPC_MXU_Q8AVGR");
26486 generate_exception_end(ctx
, EXCP_RI
);
26488 case OPC_MXU_Q8ADD
:
26489 /* TODO: Implement emulation of Q8ADD instruction. */
26490 MIPS_INVAL("OPC_MXU_Q8ADD");
26491 generate_exception_end(ctx
, EXCP_RI
);
26494 MIPS_INVAL("decode_opc_mxu");
26495 generate_exception_end(ctx
, EXCP_RI
);
26502 * Decode MXU pool02
26504 * 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
26505 * +-----------+---------+-----+-------+-------+-------+-----------+
26506 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26507 * +-----------+---------+-----+-------+-------+-------+-----------+
26510 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
26512 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26515 case OPC_MXU_S32CPS
:
26516 /* TODO: Implement emulation of S32CPS instruction. */
26517 MIPS_INVAL("OPC_MXU_S32CPS");
26518 generate_exception_end(ctx
, EXCP_RI
);
26520 case OPC_MXU_D16CPS
:
26521 /* TODO: Implement emulation of D16CPS instruction. */
26522 MIPS_INVAL("OPC_MXU_D16CPS");
26523 generate_exception_end(ctx
, EXCP_RI
);
26525 case OPC_MXU_Q8ABD
:
26526 /* TODO: Implement emulation of Q8ABD instruction. */
26527 MIPS_INVAL("OPC_MXU_Q8ABD");
26528 generate_exception_end(ctx
, EXCP_RI
);
26530 case OPC_MXU_Q16SAT
:
26531 /* TODO: Implement emulation of Q16SAT instruction. */
26532 MIPS_INVAL("OPC_MXU_Q16SAT");
26533 generate_exception_end(ctx
, EXCP_RI
);
26536 MIPS_INVAL("decode_opc_mxu");
26537 generate_exception_end(ctx
, EXCP_RI
);
26544 * Decode MXU pool03
26547 * 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
26548 * +-----------+---+---+-------+-------+-------+-------+-----------+
26549 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26550 * +-----------+---+---+-------+-------+-------+-------+-----------+
26553 * 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
26554 * +-----------+---+---+-------+-------+-------+-------+-----------+
26555 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26556 * +-----------+---+---+-------+-------+-------+-------+-----------+
26559 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
26561 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
26564 case OPC_MXU_D16MULF
:
26565 /* TODO: Implement emulation of D16MULF instruction. */
26566 MIPS_INVAL("OPC_MXU_D16MULF");
26567 generate_exception_end(ctx
, EXCP_RI
);
26569 case OPC_MXU_D16MULE
:
26570 /* TODO: Implement emulation of D16MULE instruction. */
26571 MIPS_INVAL("OPC_MXU_D16MULE");
26572 generate_exception_end(ctx
, EXCP_RI
);
26575 MIPS_INVAL("decode_opc_mxu");
26576 generate_exception_end(ctx
, EXCP_RI
);
26583 * Decode MXU pool04
26585 * 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
26586 * +-----------+---------+-+-------------------+-------+-----------+
26587 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26588 * +-----------+---------+-+-------------------+-------+-----------+
26591 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
26593 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26596 case OPC_MXU_S32LDD
:
26597 case OPC_MXU_S32LDDR
:
26598 gen_mxu_s32ldd_s32lddr(ctx
);
26601 MIPS_INVAL("decode_opc_mxu");
26602 generate_exception_end(ctx
, EXCP_RI
);
26609 * Decode MXU pool05
26611 * 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
26612 * +-----------+---------+-+-------------------+-------+-----------+
26613 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26614 * +-----------+---------+-+-------------------+-------+-----------+
26617 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
26619 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26622 case OPC_MXU_S32STD
:
26623 /* TODO: Implement emulation of S32STD instruction. */
26624 MIPS_INVAL("OPC_MXU_S32STD");
26625 generate_exception_end(ctx
, EXCP_RI
);
26627 case OPC_MXU_S32STDR
:
26628 /* TODO: Implement emulation of S32STDR instruction. */
26629 MIPS_INVAL("OPC_MXU_S32STDR");
26630 generate_exception_end(ctx
, EXCP_RI
);
26633 MIPS_INVAL("decode_opc_mxu");
26634 generate_exception_end(ctx
, EXCP_RI
);
26641 * Decode MXU pool06
26643 * 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
26644 * +-----------+---------+---------+---+-------+-------+-----------+
26645 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26646 * +-----------+---------+---------+---+-------+-------+-----------+
26649 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26651 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26654 case OPC_MXU_S32LDDV
:
26655 /* TODO: Implement emulation of S32LDDV instruction. */
26656 MIPS_INVAL("OPC_MXU_S32LDDV");
26657 generate_exception_end(ctx
, EXCP_RI
);
26659 case OPC_MXU_S32LDDVR
:
26660 /* TODO: Implement emulation of S32LDDVR instruction. */
26661 MIPS_INVAL("OPC_MXU_S32LDDVR");
26662 generate_exception_end(ctx
, EXCP_RI
);
26665 MIPS_INVAL("decode_opc_mxu");
26666 generate_exception_end(ctx
, EXCP_RI
);
26673 * Decode MXU pool07
26675 * 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
26676 * +-----------+---------+---------+---+-------+-------+-----------+
26677 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26678 * +-----------+---------+---------+---+-------+-------+-----------+
26681 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26683 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26686 case OPC_MXU_S32STDV
:
26687 /* TODO: Implement emulation of S32TDV instruction. */
26688 MIPS_INVAL("OPC_MXU_S32TDV");
26689 generate_exception_end(ctx
, EXCP_RI
);
26691 case OPC_MXU_S32STDVR
:
26692 /* TODO: Implement emulation of S32TDVR instruction. */
26693 MIPS_INVAL("OPC_MXU_S32TDVR");
26694 generate_exception_end(ctx
, EXCP_RI
);
26697 MIPS_INVAL("decode_opc_mxu");
26698 generate_exception_end(ctx
, EXCP_RI
);
26705 * Decode MXU pool08
26707 * 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
26708 * +-----------+---------+-+-------------------+-------+-----------+
26709 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26710 * +-----------+---------+-+-------------------+-------+-----------+
26713 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26715 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26718 case OPC_MXU_S32LDI
:
26719 /* TODO: Implement emulation of S32LDI instruction. */
26720 MIPS_INVAL("OPC_MXU_S32LDI");
26721 generate_exception_end(ctx
, EXCP_RI
);
26723 case OPC_MXU_S32LDIR
:
26724 /* TODO: Implement emulation of S32LDIR instruction. */
26725 MIPS_INVAL("OPC_MXU_S32LDIR");
26726 generate_exception_end(ctx
, EXCP_RI
);
26729 MIPS_INVAL("decode_opc_mxu");
26730 generate_exception_end(ctx
, EXCP_RI
);
26737 * Decode MXU pool09
26739 * 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
26740 * +-----------+---------+-+-------------------+-------+-----------+
26741 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26742 * +-----------+---------+-+-------------------+-------+-----------+
26745 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26747 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26750 case OPC_MXU_S32SDI
:
26751 /* TODO: Implement emulation of S32SDI instruction. */
26752 MIPS_INVAL("OPC_MXU_S32SDI");
26753 generate_exception_end(ctx
, EXCP_RI
);
26755 case OPC_MXU_S32SDIR
:
26756 /* TODO: Implement emulation of S32SDIR instruction. */
26757 MIPS_INVAL("OPC_MXU_S32SDIR");
26758 generate_exception_end(ctx
, EXCP_RI
);
26761 MIPS_INVAL("decode_opc_mxu");
26762 generate_exception_end(ctx
, EXCP_RI
);
26769 * Decode MXU pool10
26771 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26772 * +-----------+---------+---------+---+-------+-------+-----------+
26773 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26774 * +-----------+---------+---------+---+-------+-------+-----------+
26777 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26779 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26782 case OPC_MXU_S32LDIV
:
26783 /* TODO: Implement emulation of S32LDIV instruction. */
26784 MIPS_INVAL("OPC_MXU_S32LDIV");
26785 generate_exception_end(ctx
, EXCP_RI
);
26787 case OPC_MXU_S32LDIVR
:
26788 /* TODO: Implement emulation of S32LDIVR instruction. */
26789 MIPS_INVAL("OPC_MXU_S32LDIVR");
26790 generate_exception_end(ctx
, EXCP_RI
);
26793 MIPS_INVAL("decode_opc_mxu");
26794 generate_exception_end(ctx
, EXCP_RI
);
26801 * Decode MXU pool11
26803 * 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
26804 * +-----------+---------+---------+---+-------+-------+-----------+
26805 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26806 * +-----------+---------+---------+---+-------+-------+-----------+
26809 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26811 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26814 case OPC_MXU_S32SDIV
:
26815 /* TODO: Implement emulation of S32SDIV instruction. */
26816 MIPS_INVAL("OPC_MXU_S32SDIV");
26817 generate_exception_end(ctx
, EXCP_RI
);
26819 case OPC_MXU_S32SDIVR
:
26820 /* TODO: Implement emulation of S32SDIVR instruction. */
26821 MIPS_INVAL("OPC_MXU_S32SDIVR");
26822 generate_exception_end(ctx
, EXCP_RI
);
26825 MIPS_INVAL("decode_opc_mxu");
26826 generate_exception_end(ctx
, EXCP_RI
);
26833 * Decode MXU pool12
26835 * 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
26836 * +-----------+---+---+-------+-------+-------+-------+-----------+
26837 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26838 * +-----------+---+---+-------+-------+-------+-------+-----------+
26841 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26843 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26846 case OPC_MXU_D32ACC
:
26847 /* TODO: Implement emulation of D32ACC instruction. */
26848 MIPS_INVAL("OPC_MXU_D32ACC");
26849 generate_exception_end(ctx
, EXCP_RI
);
26851 case OPC_MXU_D32ACCM
:
26852 /* TODO: Implement emulation of D32ACCM instruction. */
26853 MIPS_INVAL("OPC_MXU_D32ACCM");
26854 generate_exception_end(ctx
, EXCP_RI
);
26856 case OPC_MXU_D32ASUM
:
26857 /* TODO: Implement emulation of D32ASUM instruction. */
26858 MIPS_INVAL("OPC_MXU_D32ASUM");
26859 generate_exception_end(ctx
, EXCP_RI
);
26862 MIPS_INVAL("decode_opc_mxu");
26863 generate_exception_end(ctx
, EXCP_RI
);
26870 * Decode MXU pool13
26872 * 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
26873 * +-----------+---+---+-------+-------+-------+-------+-----------+
26874 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26875 * +-----------+---+---+-------+-------+-------+-------+-----------+
26878 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26880 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26883 case OPC_MXU_Q16ACC
:
26884 /* TODO: Implement emulation of Q16ACC instruction. */
26885 MIPS_INVAL("OPC_MXU_Q16ACC");
26886 generate_exception_end(ctx
, EXCP_RI
);
26888 case OPC_MXU_Q16ACCM
:
26889 /* TODO: Implement emulation of Q16ACCM instruction. */
26890 MIPS_INVAL("OPC_MXU_Q16ACCM");
26891 generate_exception_end(ctx
, EXCP_RI
);
26893 case OPC_MXU_Q16ASUM
:
26894 /* TODO: Implement emulation of Q16ASUM instruction. */
26895 MIPS_INVAL("OPC_MXU_Q16ASUM");
26896 generate_exception_end(ctx
, EXCP_RI
);
26899 MIPS_INVAL("decode_opc_mxu");
26900 generate_exception_end(ctx
, EXCP_RI
);
26907 * Decode MXU pool14
26910 * 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
26911 * +-----------+---+---+-------+-------+-------+-------+-----------+
26912 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26913 * +-----------+---+---+-------+-------+-------+-------+-----------+
26916 * 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
26917 * +-----------+---+---+-------+-------+-------+-------+-----------+
26918 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26919 * +-----------+---+---+-------+-------+-------+-------+-----------+
26922 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26924 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26927 case OPC_MXU_Q8ADDE
:
26928 /* TODO: Implement emulation of Q8ADDE instruction. */
26929 MIPS_INVAL("OPC_MXU_Q8ADDE");
26930 generate_exception_end(ctx
, EXCP_RI
);
26932 case OPC_MXU_D8SUM
:
26933 /* TODO: Implement emulation of D8SUM instruction. */
26934 MIPS_INVAL("OPC_MXU_D8SUM");
26935 generate_exception_end(ctx
, EXCP_RI
);
26937 case OPC_MXU_D8SUMC
:
26938 /* TODO: Implement emulation of D8SUMC instruction. */
26939 MIPS_INVAL("OPC_MXU_D8SUMC");
26940 generate_exception_end(ctx
, EXCP_RI
);
26943 MIPS_INVAL("decode_opc_mxu");
26944 generate_exception_end(ctx
, EXCP_RI
);
26951 * Decode MXU pool15
26953 * S32MUL, S32MULU, S32EXTRV:
26954 * 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
26955 * +-----------+---------+---------+---+-------+-------+-----------+
26956 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26957 * +-----------+---------+---------+---+-------+-------+-----------+
26960 * 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
26961 * +-----------+---------+---------+---+-------+-------+-----------+
26962 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26963 * +-----------+---------+---------+---+-------+-------+-----------+
26966 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26968 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26971 case OPC_MXU_S32MUL
:
26972 /* TODO: Implement emulation of S32MUL instruction. */
26973 MIPS_INVAL("OPC_MXU_S32MUL");
26974 generate_exception_end(ctx
, EXCP_RI
);
26976 case OPC_MXU_S32MULU
:
26977 /* TODO: Implement emulation of S32MULU instruction. */
26978 MIPS_INVAL("OPC_MXU_S32MULU");
26979 generate_exception_end(ctx
, EXCP_RI
);
26981 case OPC_MXU_S32EXTR
:
26982 /* TODO: Implement emulation of S32EXTR instruction. */
26983 MIPS_INVAL("OPC_MXU_S32EXTR");
26984 generate_exception_end(ctx
, EXCP_RI
);
26986 case OPC_MXU_S32EXTRV
:
26987 /* TODO: Implement emulation of S32EXTRV instruction. */
26988 MIPS_INVAL("OPC_MXU_S32EXTRV");
26989 generate_exception_end(ctx
, EXCP_RI
);
26992 MIPS_INVAL("decode_opc_mxu");
26993 generate_exception_end(ctx
, EXCP_RI
);
27000 * Decode MXU pool16
27003 * 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
27004 * +-----------+---------+-----+-------+-------+-------+-----------+
27005 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
27006 * +-----------+---------+-----+-------+-------+-------+-----------+
27009 * 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
27010 * +-----------+---------+-----+-------+-------+-------+-----------+
27011 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
27012 * +-----------+---------+-----+-------+-------+-------+-----------+
27015 * 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
27016 * +-----------+-----+---+-----+-------+-------+-------+-----------+
27017 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
27018 * +-----------+-----+---+-----+-------+-------+-------+-----------+
27021 * 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
27022 * +-----------+-----+---+-----+-------+---------------+-----------+
27023 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
27024 * +-----------+-----+---+-----+-------+---------------+-----------+
27026 * S32NOR, S32AND, S32OR, S32XOR:
27027 * 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
27028 * +-----------+---------+-----+-------+-------+-------+-----------+
27029 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
27030 * +-----------+---------+-----+-------+-------+-------+-----------+
27033 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
27035 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27038 case OPC_MXU_D32SARW
:
27039 /* TODO: Implement emulation of D32SARW instruction. */
27040 MIPS_INVAL("OPC_MXU_D32SARW");
27041 generate_exception_end(ctx
, EXCP_RI
);
27043 case OPC_MXU_S32ALN
:
27044 /* TODO: Implement emulation of S32ALN instruction. */
27045 MIPS_INVAL("OPC_MXU_S32ALN");
27046 generate_exception_end(ctx
, EXCP_RI
);
27048 case OPC_MXU_S32ALNI
:
27049 gen_mxu_S32ALNI(ctx
);
27051 case OPC_MXU_S32LUI
:
27052 /* TODO: Implement emulation of S32LUI instruction. */
27053 MIPS_INVAL("OPC_MXU_S32LUI");
27054 generate_exception_end(ctx
, EXCP_RI
);
27056 case OPC_MXU_S32NOR
:
27057 gen_mxu_S32NOR(ctx
);
27059 case OPC_MXU_S32AND
:
27060 gen_mxu_S32AND(ctx
);
27062 case OPC_MXU_S32OR
:
27063 gen_mxu_S32OR(ctx
);
27065 case OPC_MXU_S32XOR
:
27066 gen_mxu_S32XOR(ctx
);
27069 MIPS_INVAL("decode_opc_mxu");
27070 generate_exception_end(ctx
, EXCP_RI
);
27077 * Decode MXU pool17
27079 * 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
27080 * +-----------+---------+---------+---+---------+-----+-----------+
27081 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
27082 * +-----------+---------+---------+---+---------+-----+-----------+
27085 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
27087 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
27091 /* TODO: Implement emulation of LXW instruction. */
27092 MIPS_INVAL("OPC_MXU_LXW");
27093 generate_exception_end(ctx
, EXCP_RI
);
27096 /* TODO: Implement emulation of LXH instruction. */
27097 MIPS_INVAL("OPC_MXU_LXH");
27098 generate_exception_end(ctx
, EXCP_RI
);
27101 /* TODO: Implement emulation of LXHU instruction. */
27102 MIPS_INVAL("OPC_MXU_LXHU");
27103 generate_exception_end(ctx
, EXCP_RI
);
27106 /* TODO: Implement emulation of LXB instruction. */
27107 MIPS_INVAL("OPC_MXU_LXB");
27108 generate_exception_end(ctx
, EXCP_RI
);
27111 /* TODO: Implement emulation of LXBU instruction. */
27112 MIPS_INVAL("OPC_MXU_LXBU");
27113 generate_exception_end(ctx
, EXCP_RI
);
27116 MIPS_INVAL("decode_opc_mxu");
27117 generate_exception_end(ctx
, EXCP_RI
);
27123 * Decode MXU pool18
27125 * 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
27126 * +-----------+---------+-----+-------+-------+-------+-----------+
27127 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
27128 * +-----------+---------+-----+-------+-------+-------+-----------+
27131 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
27133 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27136 case OPC_MXU_D32SLLV
:
27137 /* TODO: Implement emulation of D32SLLV instruction. */
27138 MIPS_INVAL("OPC_MXU_D32SLLV");
27139 generate_exception_end(ctx
, EXCP_RI
);
27141 case OPC_MXU_D32SLRV
:
27142 /* TODO: Implement emulation of D32SLRV instruction. */
27143 MIPS_INVAL("OPC_MXU_D32SLRV");
27144 generate_exception_end(ctx
, EXCP_RI
);
27146 case OPC_MXU_D32SARV
:
27147 /* TODO: Implement emulation of D32SARV instruction. */
27148 MIPS_INVAL("OPC_MXU_D32SARV");
27149 generate_exception_end(ctx
, EXCP_RI
);
27151 case OPC_MXU_Q16SLLV
:
27152 /* TODO: Implement emulation of Q16SLLV instruction. */
27153 MIPS_INVAL("OPC_MXU_Q16SLLV");
27154 generate_exception_end(ctx
, EXCP_RI
);
27156 case OPC_MXU_Q16SLRV
:
27157 /* TODO: Implement emulation of Q16SLRV instruction. */
27158 MIPS_INVAL("OPC_MXU_Q16SLRV");
27159 generate_exception_end(ctx
, EXCP_RI
);
27161 case OPC_MXU_Q16SARV
:
27162 /* TODO: Implement emulation of Q16SARV instruction. */
27163 MIPS_INVAL("OPC_MXU_Q16SARV");
27164 generate_exception_end(ctx
, EXCP_RI
);
27167 MIPS_INVAL("decode_opc_mxu");
27168 generate_exception_end(ctx
, EXCP_RI
);
27175 * Decode MXU pool19
27177 * 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
27178 * +-----------+---+---+-------+-------+-------+-------+-----------+
27179 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
27180 * +-----------+---+---+-------+-------+-------+-------+-----------+
27183 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
27185 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
27188 case OPC_MXU_Q8MUL
:
27189 case OPC_MXU_Q8MULSU
:
27190 gen_mxu_q8mul_q8mulsu(ctx
);
27193 MIPS_INVAL("decode_opc_mxu");
27194 generate_exception_end(ctx
, EXCP_RI
);
27201 * Decode MXU pool20
27203 * 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
27204 * +-----------+---------+-----+-------+-------+-------+-----------+
27205 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
27206 * +-----------+---------+-----+-------+-------+-------+-----------+
27209 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
27211 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27214 case OPC_MXU_Q8MOVZ
:
27215 /* TODO: Implement emulation of Q8MOVZ instruction. */
27216 MIPS_INVAL("OPC_MXU_Q8MOVZ");
27217 generate_exception_end(ctx
, EXCP_RI
);
27219 case OPC_MXU_Q8MOVN
:
27220 /* TODO: Implement emulation of Q8MOVN instruction. */
27221 MIPS_INVAL("OPC_MXU_Q8MOVN");
27222 generate_exception_end(ctx
, EXCP_RI
);
27224 case OPC_MXU_D16MOVZ
:
27225 /* TODO: Implement emulation of D16MOVZ instruction. */
27226 MIPS_INVAL("OPC_MXU_D16MOVZ");
27227 generate_exception_end(ctx
, EXCP_RI
);
27229 case OPC_MXU_D16MOVN
:
27230 /* TODO: Implement emulation of D16MOVN instruction. */
27231 MIPS_INVAL("OPC_MXU_D16MOVN");
27232 generate_exception_end(ctx
, EXCP_RI
);
27234 case OPC_MXU_S32MOVZ
:
27235 /* TODO: Implement emulation of S32MOVZ instruction. */
27236 MIPS_INVAL("OPC_MXU_S32MOVZ");
27237 generate_exception_end(ctx
, EXCP_RI
);
27239 case OPC_MXU_S32MOVN
:
27240 /* TODO: Implement emulation of S32MOVN instruction. */
27241 MIPS_INVAL("OPC_MXU_S32MOVN");
27242 generate_exception_end(ctx
, EXCP_RI
);
27245 MIPS_INVAL("decode_opc_mxu");
27246 generate_exception_end(ctx
, EXCP_RI
);
27253 * Decode MXU pool21
27255 * 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
27256 * +-----------+---+---+-------+-------+-------+-------+-----------+
27257 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
27258 * +-----------+---+---+-------+-------+-------+-------+-----------+
27261 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
27263 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
27266 case OPC_MXU_Q8MAC
:
27267 /* TODO: Implement emulation of Q8MAC instruction. */
27268 MIPS_INVAL("OPC_MXU_Q8MAC");
27269 generate_exception_end(ctx
, EXCP_RI
);
27271 case OPC_MXU_Q8MACSU
:
27272 /* TODO: Implement emulation of Q8MACSU instruction. */
27273 MIPS_INVAL("OPC_MXU_Q8MACSU");
27274 generate_exception_end(ctx
, EXCP_RI
);
27277 MIPS_INVAL("decode_opc_mxu");
27278 generate_exception_end(ctx
, EXCP_RI
);
27285 * Main MXU decoding function
27287 * 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
27288 * +-----------+---------------------------------------+-----------+
27289 * | SPECIAL2 | |x x x x x x|
27290 * +-----------+---------------------------------------+-----------+
27293 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
27296 * TODO: Investigate necessity of including handling of
27297 * CLZ, CLO, SDBB in this function, as they belong to
27298 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
27300 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
27302 if (opcode
== OPC__MXU_MUL
) {
27303 uint32_t rs
, rt
, rd
, op1
;
27305 rs
= extract32(ctx
->opcode
, 21, 5);
27306 rt
= extract32(ctx
->opcode
, 16, 5);
27307 rd
= extract32(ctx
->opcode
, 11, 5);
27308 op1
= MASK_SPECIAL2(ctx
->opcode
);
27310 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27315 if (opcode
== OPC_MXU_S32M2I
) {
27316 gen_mxu_s32m2i(ctx
);
27320 if (opcode
== OPC_MXU_S32I2M
) {
27321 gen_mxu_s32i2m(ctx
);
27326 TCGv t_mxu_cr
= tcg_temp_new();
27327 TCGLabel
*l_exit
= gen_new_label();
27329 gen_load_mxu_cr(t_mxu_cr
);
27330 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
27331 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
27334 case OPC_MXU_S32MADD
:
27335 /* TODO: Implement emulation of S32MADD instruction. */
27336 MIPS_INVAL("OPC_MXU_S32MADD");
27337 generate_exception_end(ctx
, EXCP_RI
);
27339 case OPC_MXU_S32MADDU
:
27340 /* TODO: Implement emulation of S32MADDU instruction. */
27341 MIPS_INVAL("OPC_MXU_S32MADDU");
27342 generate_exception_end(ctx
, EXCP_RI
);
27344 case OPC_MXU__POOL00
:
27345 decode_opc_mxu__pool00(env
, ctx
);
27347 case OPC_MXU_S32MSUB
:
27348 /* TODO: Implement emulation of S32MSUB instruction. */
27349 MIPS_INVAL("OPC_MXU_S32MSUB");
27350 generate_exception_end(ctx
, EXCP_RI
);
27352 case OPC_MXU_S32MSUBU
:
27353 /* TODO: Implement emulation of S32MSUBU instruction. */
27354 MIPS_INVAL("OPC_MXU_S32MSUBU");
27355 generate_exception_end(ctx
, EXCP_RI
);
27357 case OPC_MXU__POOL01
:
27358 decode_opc_mxu__pool01(env
, ctx
);
27360 case OPC_MXU__POOL02
:
27361 decode_opc_mxu__pool02(env
, ctx
);
27363 case OPC_MXU_D16MUL
:
27364 gen_mxu_d16mul(ctx
);
27366 case OPC_MXU__POOL03
:
27367 decode_opc_mxu__pool03(env
, ctx
);
27369 case OPC_MXU_D16MAC
:
27370 gen_mxu_d16mac(ctx
);
27372 case OPC_MXU_D16MACF
:
27373 /* TODO: Implement emulation of D16MACF instruction. */
27374 MIPS_INVAL("OPC_MXU_D16MACF");
27375 generate_exception_end(ctx
, EXCP_RI
);
27377 case OPC_MXU_D16MADL
:
27378 /* TODO: Implement emulation of D16MADL instruction. */
27379 MIPS_INVAL("OPC_MXU_D16MADL");
27380 generate_exception_end(ctx
, EXCP_RI
);
27382 case OPC_MXU_S16MAD
:
27383 /* TODO: Implement emulation of S16MAD instruction. */
27384 MIPS_INVAL("OPC_MXU_S16MAD");
27385 generate_exception_end(ctx
, EXCP_RI
);
27387 case OPC_MXU_Q16ADD
:
27388 /* TODO: Implement emulation of Q16ADD instruction. */
27389 MIPS_INVAL("OPC_MXU_Q16ADD");
27390 generate_exception_end(ctx
, EXCP_RI
);
27392 case OPC_MXU_D16MACE
:
27393 /* TODO: Implement emulation of D16MACE instruction. */
27394 MIPS_INVAL("OPC_MXU_D16MACE");
27395 generate_exception_end(ctx
, EXCP_RI
);
27397 case OPC_MXU__POOL04
:
27398 decode_opc_mxu__pool04(env
, ctx
);
27400 case OPC_MXU__POOL05
:
27401 decode_opc_mxu__pool05(env
, ctx
);
27403 case OPC_MXU__POOL06
:
27404 decode_opc_mxu__pool06(env
, ctx
);
27406 case OPC_MXU__POOL07
:
27407 decode_opc_mxu__pool07(env
, ctx
);
27409 case OPC_MXU__POOL08
:
27410 decode_opc_mxu__pool08(env
, ctx
);
27412 case OPC_MXU__POOL09
:
27413 decode_opc_mxu__pool09(env
, ctx
);
27415 case OPC_MXU__POOL10
:
27416 decode_opc_mxu__pool10(env
, ctx
);
27418 case OPC_MXU__POOL11
:
27419 decode_opc_mxu__pool11(env
, ctx
);
27421 case OPC_MXU_D32ADD
:
27422 /* TODO: Implement emulation of D32ADD instruction. */
27423 MIPS_INVAL("OPC_MXU_D32ADD");
27424 generate_exception_end(ctx
, EXCP_RI
);
27426 case OPC_MXU__POOL12
:
27427 decode_opc_mxu__pool12(env
, ctx
);
27429 case OPC_MXU__POOL13
:
27430 decode_opc_mxu__pool13(env
, ctx
);
27432 case OPC_MXU__POOL14
:
27433 decode_opc_mxu__pool14(env
, ctx
);
27435 case OPC_MXU_Q8ACCE
:
27436 /* TODO: Implement emulation of Q8ACCE instruction. */
27437 MIPS_INVAL("OPC_MXU_Q8ACCE");
27438 generate_exception_end(ctx
, EXCP_RI
);
27440 case OPC_MXU_S8LDD
:
27441 gen_mxu_s8ldd(ctx
);
27443 case OPC_MXU_S8STD
:
27444 /* TODO: Implement emulation of S8STD instruction. */
27445 MIPS_INVAL("OPC_MXU_S8STD");
27446 generate_exception_end(ctx
, EXCP_RI
);
27448 case OPC_MXU_S8LDI
:
27449 /* TODO: Implement emulation of S8LDI instruction. */
27450 MIPS_INVAL("OPC_MXU_S8LDI");
27451 generate_exception_end(ctx
, EXCP_RI
);
27453 case OPC_MXU_S8SDI
:
27454 /* TODO: Implement emulation of S8SDI instruction. */
27455 MIPS_INVAL("OPC_MXU_S8SDI");
27456 generate_exception_end(ctx
, EXCP_RI
);
27458 case OPC_MXU__POOL15
:
27459 decode_opc_mxu__pool15(env
, ctx
);
27461 case OPC_MXU__POOL16
:
27462 decode_opc_mxu__pool16(env
, ctx
);
27464 case OPC_MXU__POOL17
:
27465 decode_opc_mxu__pool17(env
, ctx
);
27467 case OPC_MXU_S16LDD
:
27468 /* TODO: Implement emulation of S16LDD instruction. */
27469 MIPS_INVAL("OPC_MXU_S16LDD");
27470 generate_exception_end(ctx
, EXCP_RI
);
27472 case OPC_MXU_S16STD
:
27473 /* TODO: Implement emulation of S16STD instruction. */
27474 MIPS_INVAL("OPC_MXU_S16STD");
27475 generate_exception_end(ctx
, EXCP_RI
);
27477 case OPC_MXU_S16LDI
:
27478 /* TODO: Implement emulation of S16LDI instruction. */
27479 MIPS_INVAL("OPC_MXU_S16LDI");
27480 generate_exception_end(ctx
, EXCP_RI
);
27482 case OPC_MXU_S16SDI
:
27483 /* TODO: Implement emulation of S16SDI instruction. */
27484 MIPS_INVAL("OPC_MXU_S16SDI");
27485 generate_exception_end(ctx
, EXCP_RI
);
27487 case OPC_MXU_D32SLL
:
27488 /* TODO: Implement emulation of D32SLL instruction. */
27489 MIPS_INVAL("OPC_MXU_D32SLL");
27490 generate_exception_end(ctx
, EXCP_RI
);
27492 case OPC_MXU_D32SLR
:
27493 /* TODO: Implement emulation of D32SLR instruction. */
27494 MIPS_INVAL("OPC_MXU_D32SLR");
27495 generate_exception_end(ctx
, EXCP_RI
);
27497 case OPC_MXU_D32SARL
:
27498 /* TODO: Implement emulation of D32SARL instruction. */
27499 MIPS_INVAL("OPC_MXU_D32SARL");
27500 generate_exception_end(ctx
, EXCP_RI
);
27502 case OPC_MXU_D32SAR
:
27503 /* TODO: Implement emulation of D32SAR instruction. */
27504 MIPS_INVAL("OPC_MXU_D32SAR");
27505 generate_exception_end(ctx
, EXCP_RI
);
27507 case OPC_MXU_Q16SLL
:
27508 /* TODO: Implement emulation of Q16SLL instruction. */
27509 MIPS_INVAL("OPC_MXU_Q16SLL");
27510 generate_exception_end(ctx
, EXCP_RI
);
27512 case OPC_MXU_Q16SLR
:
27513 /* TODO: Implement emulation of Q16SLR instruction. */
27514 MIPS_INVAL("OPC_MXU_Q16SLR");
27515 generate_exception_end(ctx
, EXCP_RI
);
27517 case OPC_MXU__POOL18
:
27518 decode_opc_mxu__pool18(env
, ctx
);
27520 case OPC_MXU_Q16SAR
:
27521 /* TODO: Implement emulation of Q16SAR instruction. */
27522 MIPS_INVAL("OPC_MXU_Q16SAR");
27523 generate_exception_end(ctx
, EXCP_RI
);
27525 case OPC_MXU__POOL19
:
27526 decode_opc_mxu__pool19(env
, ctx
);
27528 case OPC_MXU__POOL20
:
27529 decode_opc_mxu__pool20(env
, ctx
);
27531 case OPC_MXU__POOL21
:
27532 decode_opc_mxu__pool21(env
, ctx
);
27534 case OPC_MXU_Q16SCOP
:
27535 /* TODO: Implement emulation of Q16SCOP instruction. */
27536 MIPS_INVAL("OPC_MXU_Q16SCOP");
27537 generate_exception_end(ctx
, EXCP_RI
);
27539 case OPC_MXU_Q8MADL
:
27540 /* TODO: Implement emulation of Q8MADL instruction. */
27541 MIPS_INVAL("OPC_MXU_Q8MADL");
27542 generate_exception_end(ctx
, EXCP_RI
);
27544 case OPC_MXU_S32SFL
:
27545 /* TODO: Implement emulation of S32SFL instruction. */
27546 MIPS_INVAL("OPC_MXU_S32SFL");
27547 generate_exception_end(ctx
, EXCP_RI
);
27549 case OPC_MXU_Q8SAD
:
27550 /* TODO: Implement emulation of Q8SAD instruction. */
27551 MIPS_INVAL("OPC_MXU_Q8SAD");
27552 generate_exception_end(ctx
, EXCP_RI
);
27555 MIPS_INVAL("decode_opc_mxu");
27556 generate_exception_end(ctx
, EXCP_RI
);
27559 gen_set_label(l_exit
);
27560 tcg_temp_free(t_mxu_cr
);
27564 #endif /* !defined(TARGET_MIPS64) */
27567 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27572 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
27574 rs
= (ctx
->opcode
>> 21) & 0x1f;
27575 rt
= (ctx
->opcode
>> 16) & 0x1f;
27576 rd
= (ctx
->opcode
>> 11) & 0x1f;
27578 op1
= MASK_SPECIAL2(ctx
->opcode
);
27580 case OPC_MADD
: /* Multiply and add/sub */
27584 check_insn(ctx
, ISA_MIPS32
);
27585 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
27588 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27591 case OPC_DIVU_G_2F
:
27592 case OPC_MULT_G_2F
:
27593 case OPC_MULTU_G_2F
:
27595 case OPC_MODU_G_2F
:
27596 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27597 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27601 check_insn(ctx
, ISA_MIPS32
);
27602 gen_cl(ctx
, op1
, rd
, rs
);
27605 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
27606 gen_helper_do_semihosting(cpu_env
);
27609 * XXX: not clear which exception should be raised
27610 * when in debug mode...
27612 check_insn(ctx
, ISA_MIPS32
);
27613 generate_exception_end(ctx
, EXCP_DBp
);
27616 #if defined(TARGET_MIPS64)
27619 check_insn(ctx
, ISA_MIPS64
);
27620 check_mips_64(ctx
);
27621 gen_cl(ctx
, op1
, rd
, rs
);
27623 case OPC_DMULT_G_2F
:
27624 case OPC_DMULTU_G_2F
:
27625 case OPC_DDIV_G_2F
:
27626 case OPC_DDIVU_G_2F
:
27627 case OPC_DMOD_G_2F
:
27628 case OPC_DMODU_G_2F
:
27629 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27630 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27633 default: /* Invalid */
27634 MIPS_INVAL("special2_legacy");
27635 generate_exception_end(ctx
, EXCP_RI
);
27640 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27642 int rs
, rt
, rd
, sa
;
27646 rs
= (ctx
->opcode
>> 21) & 0x1f;
27647 rt
= (ctx
->opcode
>> 16) & 0x1f;
27648 rd
= (ctx
->opcode
>> 11) & 0x1f;
27649 sa
= (ctx
->opcode
>> 6) & 0x1f;
27650 imm
= (int16_t)ctx
->opcode
>> 7;
27652 op1
= MASK_SPECIAL3(ctx
->opcode
);
27656 /* hint codes 24-31 are reserved and signal RI */
27657 generate_exception_end(ctx
, EXCP_RI
);
27659 /* Treat as NOP. */
27662 check_cp0_enabled(ctx
);
27663 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27664 gen_cache_operation(ctx
, rt
, rs
, imm
);
27668 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27671 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27676 /* Treat as NOP. */
27679 op2
= MASK_BSHFL(ctx
->opcode
);
27685 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27688 gen_bitswap(ctx
, op2
, rd
, rt
);
27693 #ifndef CONFIG_USER_ONLY
27695 if (unlikely(ctx
->gi
<= 1)) {
27696 generate_exception_end(ctx
, EXCP_RI
);
27698 check_cp0_enabled(ctx
);
27699 switch ((ctx
->opcode
>> 6) & 3) {
27700 case 0: /* GINVI */
27701 /* Treat as NOP. */
27703 case 2: /* GINVT */
27704 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
27707 generate_exception_end(ctx
, EXCP_RI
);
27712 #if defined(TARGET_MIPS64)
27714 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27717 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27720 check_mips_64(ctx
);
27723 /* Treat as NOP. */
27726 op2
= MASK_DBSHFL(ctx
->opcode
);
27736 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27739 gen_bitswap(ctx
, op2
, rd
, rt
);
27746 default: /* Invalid */
27747 MIPS_INVAL("special3_r6");
27748 generate_exception_end(ctx
, EXCP_RI
);
27753 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27758 rs
= (ctx
->opcode
>> 21) & 0x1f;
27759 rt
= (ctx
->opcode
>> 16) & 0x1f;
27760 rd
= (ctx
->opcode
>> 11) & 0x1f;
27762 op1
= MASK_SPECIAL3(ctx
->opcode
);
27765 case OPC_DIVU_G_2E
:
27767 case OPC_MODU_G_2E
:
27768 case OPC_MULT_G_2E
:
27769 case OPC_MULTU_G_2E
:
27771 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27772 * the same mask and op1.
27774 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27775 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27778 case OPC_ADDUH_R_QB
:
27780 case OPC_ADDQH_R_PH
:
27782 case OPC_ADDQH_R_W
:
27784 case OPC_SUBUH_R_QB
:
27786 case OPC_SUBQH_R_PH
:
27788 case OPC_SUBQH_R_W
:
27789 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27794 case OPC_MULQ_RS_W
:
27795 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27798 MIPS_INVAL("MASK ADDUH.QB");
27799 generate_exception_end(ctx
, EXCP_RI
);
27802 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27803 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27805 generate_exception_end(ctx
, EXCP_RI
);
27809 op2
= MASK_LX(ctx
->opcode
);
27811 #if defined(TARGET_MIPS64)
27817 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27819 default: /* Invalid */
27820 MIPS_INVAL("MASK LX");
27821 generate_exception_end(ctx
, EXCP_RI
);
27825 case OPC_ABSQ_S_PH_DSP
:
27826 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27828 case OPC_ABSQ_S_QB
:
27829 case OPC_ABSQ_S_PH
:
27831 case OPC_PRECEQ_W_PHL
:
27832 case OPC_PRECEQ_W_PHR
:
27833 case OPC_PRECEQU_PH_QBL
:
27834 case OPC_PRECEQU_PH_QBR
:
27835 case OPC_PRECEQU_PH_QBLA
:
27836 case OPC_PRECEQU_PH_QBRA
:
27837 case OPC_PRECEU_PH_QBL
:
27838 case OPC_PRECEU_PH_QBR
:
27839 case OPC_PRECEU_PH_QBLA
:
27840 case OPC_PRECEU_PH_QBRA
:
27841 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27848 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27851 MIPS_INVAL("MASK ABSQ_S.PH");
27852 generate_exception_end(ctx
, EXCP_RI
);
27856 case OPC_ADDU_QB_DSP
:
27857 op2
= MASK_ADDU_QB(ctx
->opcode
);
27860 case OPC_ADDQ_S_PH
:
27863 case OPC_ADDU_S_QB
:
27865 case OPC_ADDU_S_PH
:
27867 case OPC_SUBQ_S_PH
:
27870 case OPC_SUBU_S_QB
:
27872 case OPC_SUBU_S_PH
:
27876 case OPC_RADDU_W_QB
:
27877 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27879 case OPC_MULEU_S_PH_QBL
:
27880 case OPC_MULEU_S_PH_QBR
:
27881 case OPC_MULQ_RS_PH
:
27882 case OPC_MULEQ_S_W_PHL
:
27883 case OPC_MULEQ_S_W_PHR
:
27884 case OPC_MULQ_S_PH
:
27885 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27887 default: /* Invalid */
27888 MIPS_INVAL("MASK ADDU.QB");
27889 generate_exception_end(ctx
, EXCP_RI
);
27894 case OPC_CMPU_EQ_QB_DSP
:
27895 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27897 case OPC_PRECR_SRA_PH_W
:
27898 case OPC_PRECR_SRA_R_PH_W
:
27899 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27901 case OPC_PRECR_QB_PH
:
27902 case OPC_PRECRQ_QB_PH
:
27903 case OPC_PRECRQ_PH_W
:
27904 case OPC_PRECRQ_RS_PH_W
:
27905 case OPC_PRECRQU_S_QB_PH
:
27906 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27908 case OPC_CMPU_EQ_QB
:
27909 case OPC_CMPU_LT_QB
:
27910 case OPC_CMPU_LE_QB
:
27911 case OPC_CMP_EQ_PH
:
27912 case OPC_CMP_LT_PH
:
27913 case OPC_CMP_LE_PH
:
27914 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27916 case OPC_CMPGU_EQ_QB
:
27917 case OPC_CMPGU_LT_QB
:
27918 case OPC_CMPGU_LE_QB
:
27919 case OPC_CMPGDU_EQ_QB
:
27920 case OPC_CMPGDU_LT_QB
:
27921 case OPC_CMPGDU_LE_QB
:
27924 case OPC_PACKRL_PH
:
27925 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27927 default: /* Invalid */
27928 MIPS_INVAL("MASK CMPU.EQ.QB");
27929 generate_exception_end(ctx
, EXCP_RI
);
27933 case OPC_SHLL_QB_DSP
:
27934 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27936 case OPC_DPA_W_PH_DSP
:
27937 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27939 case OPC_DPAU_H_QBL
:
27940 case OPC_DPAU_H_QBR
:
27941 case OPC_DPSU_H_QBL
:
27942 case OPC_DPSU_H_QBR
:
27944 case OPC_DPAX_W_PH
:
27945 case OPC_DPAQ_S_W_PH
:
27946 case OPC_DPAQX_S_W_PH
:
27947 case OPC_DPAQX_SA_W_PH
:
27949 case OPC_DPSX_W_PH
:
27950 case OPC_DPSQ_S_W_PH
:
27951 case OPC_DPSQX_S_W_PH
:
27952 case OPC_DPSQX_SA_W_PH
:
27953 case OPC_MULSAQ_S_W_PH
:
27954 case OPC_DPAQ_SA_L_W
:
27955 case OPC_DPSQ_SA_L_W
:
27956 case OPC_MAQ_S_W_PHL
:
27957 case OPC_MAQ_S_W_PHR
:
27958 case OPC_MAQ_SA_W_PHL
:
27959 case OPC_MAQ_SA_W_PHR
:
27960 case OPC_MULSA_W_PH
:
27961 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27963 default: /* Invalid */
27964 MIPS_INVAL("MASK DPAW.PH");
27965 generate_exception_end(ctx
, EXCP_RI
);
27970 op2
= MASK_INSV(ctx
->opcode
);
27981 t0
= tcg_temp_new();
27982 t1
= tcg_temp_new();
27984 gen_load_gpr(t0
, rt
);
27985 gen_load_gpr(t1
, rs
);
27987 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27993 default: /* Invalid */
27994 MIPS_INVAL("MASK INSV");
27995 generate_exception_end(ctx
, EXCP_RI
);
27999 case OPC_APPEND_DSP
:
28000 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
28002 case OPC_EXTR_W_DSP
:
28003 op2
= MASK_EXTR_W(ctx
->opcode
);
28007 case OPC_EXTR_RS_W
:
28009 case OPC_EXTRV_S_H
:
28011 case OPC_EXTRV_R_W
:
28012 case OPC_EXTRV_RS_W
:
28017 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
28020 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
28026 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28028 default: /* Invalid */
28029 MIPS_INVAL("MASK EXTR.W");
28030 generate_exception_end(ctx
, EXCP_RI
);
28034 #if defined(TARGET_MIPS64)
28035 case OPC_DDIV_G_2E
:
28036 case OPC_DDIVU_G_2E
:
28037 case OPC_DMULT_G_2E
:
28038 case OPC_DMULTU_G_2E
:
28039 case OPC_DMOD_G_2E
:
28040 case OPC_DMODU_G_2E
:
28041 check_insn(ctx
, INSN_LOONGSON2E
);
28042 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
28044 case OPC_ABSQ_S_QH_DSP
:
28045 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
28047 case OPC_PRECEQ_L_PWL
:
28048 case OPC_PRECEQ_L_PWR
:
28049 case OPC_PRECEQ_PW_QHL
:
28050 case OPC_PRECEQ_PW_QHR
:
28051 case OPC_PRECEQ_PW_QHLA
:
28052 case OPC_PRECEQ_PW_QHRA
:
28053 case OPC_PRECEQU_QH_OBL
:
28054 case OPC_PRECEQU_QH_OBR
:
28055 case OPC_PRECEQU_QH_OBLA
:
28056 case OPC_PRECEQU_QH_OBRA
:
28057 case OPC_PRECEU_QH_OBL
:
28058 case OPC_PRECEU_QH_OBR
:
28059 case OPC_PRECEU_QH_OBLA
:
28060 case OPC_PRECEU_QH_OBRA
:
28061 case OPC_ABSQ_S_OB
:
28062 case OPC_ABSQ_S_PW
:
28063 case OPC_ABSQ_S_QH
:
28064 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28072 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
28074 default: /* Invalid */
28075 MIPS_INVAL("MASK ABSQ_S.QH");
28076 generate_exception_end(ctx
, EXCP_RI
);
28080 case OPC_ADDU_OB_DSP
:
28081 op2
= MASK_ADDU_OB(ctx
->opcode
);
28083 case OPC_RADDU_L_OB
:
28085 case OPC_SUBQ_S_PW
:
28087 case OPC_SUBQ_S_QH
:
28089 case OPC_SUBU_S_OB
:
28091 case OPC_SUBU_S_QH
:
28093 case OPC_SUBUH_R_OB
:
28095 case OPC_ADDQ_S_PW
:
28097 case OPC_ADDQ_S_QH
:
28099 case OPC_ADDU_S_OB
:
28101 case OPC_ADDU_S_QH
:
28103 case OPC_ADDUH_R_OB
:
28104 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28106 case OPC_MULEQ_S_PW_QHL
:
28107 case OPC_MULEQ_S_PW_QHR
:
28108 case OPC_MULEU_S_QH_OBL
:
28109 case OPC_MULEU_S_QH_OBR
:
28110 case OPC_MULQ_RS_QH
:
28111 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
28113 default: /* Invalid */
28114 MIPS_INVAL("MASK ADDU.OB");
28115 generate_exception_end(ctx
, EXCP_RI
);
28119 case OPC_CMPU_EQ_OB_DSP
:
28120 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
28122 case OPC_PRECR_SRA_QH_PW
:
28123 case OPC_PRECR_SRA_R_QH_PW
:
28124 /* Return value is rt. */
28125 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
28127 case OPC_PRECR_OB_QH
:
28128 case OPC_PRECRQ_OB_QH
:
28129 case OPC_PRECRQ_PW_L
:
28130 case OPC_PRECRQ_QH_PW
:
28131 case OPC_PRECRQ_RS_QH_PW
:
28132 case OPC_PRECRQU_S_OB_QH
:
28133 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28135 case OPC_CMPU_EQ_OB
:
28136 case OPC_CMPU_LT_OB
:
28137 case OPC_CMPU_LE_OB
:
28138 case OPC_CMP_EQ_QH
:
28139 case OPC_CMP_LT_QH
:
28140 case OPC_CMP_LE_QH
:
28141 case OPC_CMP_EQ_PW
:
28142 case OPC_CMP_LT_PW
:
28143 case OPC_CMP_LE_PW
:
28144 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28146 case OPC_CMPGDU_EQ_OB
:
28147 case OPC_CMPGDU_LT_OB
:
28148 case OPC_CMPGDU_LE_OB
:
28149 case OPC_CMPGU_EQ_OB
:
28150 case OPC_CMPGU_LT_OB
:
28151 case OPC_CMPGU_LE_OB
:
28152 case OPC_PACKRL_PW
:
28156 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
28158 default: /* Invalid */
28159 MIPS_INVAL("MASK CMPU_EQ.OB");
28160 generate_exception_end(ctx
, EXCP_RI
);
28164 case OPC_DAPPEND_DSP
:
28165 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
28167 case OPC_DEXTR_W_DSP
:
28168 op2
= MASK_DEXTR_W(ctx
->opcode
);
28175 case OPC_DEXTR_R_L
:
28176 case OPC_DEXTR_RS_L
:
28178 case OPC_DEXTR_R_W
:
28179 case OPC_DEXTR_RS_W
:
28180 case OPC_DEXTR_S_H
:
28182 case OPC_DEXTRV_R_L
:
28183 case OPC_DEXTRV_RS_L
:
28184 case OPC_DEXTRV_S_H
:
28186 case OPC_DEXTRV_R_W
:
28187 case OPC_DEXTRV_RS_W
:
28188 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
28193 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28195 default: /* Invalid */
28196 MIPS_INVAL("MASK EXTR.W");
28197 generate_exception_end(ctx
, EXCP_RI
);
28201 case OPC_DPAQ_W_QH_DSP
:
28202 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
28204 case OPC_DPAU_H_OBL
:
28205 case OPC_DPAU_H_OBR
:
28206 case OPC_DPSU_H_OBL
:
28207 case OPC_DPSU_H_OBR
:
28209 case OPC_DPAQ_S_W_QH
:
28211 case OPC_DPSQ_S_W_QH
:
28212 case OPC_MULSAQ_S_W_QH
:
28213 case OPC_DPAQ_SA_L_PW
:
28214 case OPC_DPSQ_SA_L_PW
:
28215 case OPC_MULSAQ_S_L_PW
:
28216 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28218 case OPC_MAQ_S_W_QHLL
:
28219 case OPC_MAQ_S_W_QHLR
:
28220 case OPC_MAQ_S_W_QHRL
:
28221 case OPC_MAQ_S_W_QHRR
:
28222 case OPC_MAQ_SA_W_QHLL
:
28223 case OPC_MAQ_SA_W_QHLR
:
28224 case OPC_MAQ_SA_W_QHRL
:
28225 case OPC_MAQ_SA_W_QHRR
:
28226 case OPC_MAQ_S_L_PWL
:
28227 case OPC_MAQ_S_L_PWR
:
28232 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28234 default: /* Invalid */
28235 MIPS_INVAL("MASK DPAQ.W.QH");
28236 generate_exception_end(ctx
, EXCP_RI
);
28240 case OPC_DINSV_DSP
:
28241 op2
= MASK_INSV(ctx
->opcode
);
28252 t0
= tcg_temp_new();
28253 t1
= tcg_temp_new();
28255 gen_load_gpr(t0
, rt
);
28256 gen_load_gpr(t1
, rs
);
28258 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
28264 default: /* Invalid */
28265 MIPS_INVAL("MASK DINSV");
28266 generate_exception_end(ctx
, EXCP_RI
);
28270 case OPC_SHLL_OB_DSP
:
28271 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
28274 default: /* Invalid */
28275 MIPS_INVAL("special3_legacy");
28276 generate_exception_end(ctx
, EXCP_RI
);
28282 #if defined(TARGET_MIPS64)
28284 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
28286 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
28289 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
28290 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
28291 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
28292 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
28293 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
28294 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
28295 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
28296 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
28297 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
28298 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
28299 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
28300 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
28301 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
28302 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
28303 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
28304 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
28305 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
28306 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
28307 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
28308 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
28309 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
28310 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
28311 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
28312 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
28313 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
28314 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI0 */
28317 MIPS_INVAL("TX79 MMI class MMI0");
28318 generate_exception_end(ctx
, EXCP_RI
);
28323 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
28325 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
28328 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
28329 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
28330 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
28331 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
28332 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
28333 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
28334 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
28335 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
28336 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
28337 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
28338 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
28339 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
28340 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
28341 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
28342 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
28343 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
28344 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
28345 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
28346 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI1 */
28349 MIPS_INVAL("TX79 MMI class MMI1");
28350 generate_exception_end(ctx
, EXCP_RI
);
28355 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
28357 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
28360 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
28361 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
28362 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
28363 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
28364 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
28365 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
28366 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
28367 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
28368 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
28369 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
28370 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
28371 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
28372 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
28373 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
28374 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
28375 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
28376 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
28377 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
28378 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
28379 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
28380 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
28381 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI2 */
28383 case MMI_OPC_2_PCPYLD
:
28384 gen_mmi_pcpyld(ctx
);
28387 MIPS_INVAL("TX79 MMI class MMI2");
28388 generate_exception_end(ctx
, EXCP_RI
);
28393 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
28395 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
28398 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
28399 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
28400 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
28401 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
28402 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
28403 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
28404 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
28405 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
28406 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
28407 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
28408 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
28409 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI3 */
28411 case MMI_OPC_3_PCPYH
:
28412 gen_mmi_pcpyh(ctx
);
28414 case MMI_OPC_3_PCPYUD
:
28415 gen_mmi_pcpyud(ctx
);
28418 MIPS_INVAL("TX79 MMI class MMI3");
28419 generate_exception_end(ctx
, EXCP_RI
);
28424 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
28426 uint32_t opc
= MASK_MMI(ctx
->opcode
);
28427 int rs
= extract32(ctx
->opcode
, 21, 5);
28428 int rt
= extract32(ctx
->opcode
, 16, 5);
28429 int rd
= extract32(ctx
->opcode
, 11, 5);
28432 case MMI_OPC_CLASS_MMI0
:
28433 decode_mmi0(env
, ctx
);
28435 case MMI_OPC_CLASS_MMI1
:
28436 decode_mmi1(env
, ctx
);
28438 case MMI_OPC_CLASS_MMI2
:
28439 decode_mmi2(env
, ctx
);
28441 case MMI_OPC_CLASS_MMI3
:
28442 decode_mmi3(env
, ctx
);
28444 case MMI_OPC_MULT1
:
28445 case MMI_OPC_MULTU1
:
28447 case MMI_OPC_MADDU
:
28448 case MMI_OPC_MADD1
:
28449 case MMI_OPC_MADDU1
:
28450 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
28453 case MMI_OPC_DIVU1
:
28454 gen_div1_tx79(ctx
, opc
, rs
, rt
);
28456 case MMI_OPC_MTLO1
:
28457 case MMI_OPC_MTHI1
:
28458 gen_HILO1_tx79(ctx
, opc
, rs
);
28460 case MMI_OPC_MFLO1
:
28461 case MMI_OPC_MFHI1
:
28462 gen_HILO1_tx79(ctx
, opc
, rd
);
28464 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
28465 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
28466 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
28467 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
28468 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
28469 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
28470 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
28471 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
28472 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
28473 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI */
28476 MIPS_INVAL("TX79 MMI class");
28477 generate_exception_end(ctx
, EXCP_RI
);
28482 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
28484 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_LQ */
28487 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
28489 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_SQ */
28493 * The TX79-specific instruction Store Quadword
28495 * +--------+-------+-------+------------------------+
28496 * | 011111 | base | rt | offset | SQ
28497 * +--------+-------+-------+------------------------+
28500 * has the same opcode as the Read Hardware Register instruction
28502 * +--------+-------+-------+-------+-------+--------+
28503 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28504 * +--------+-------+-------+-------+-------+--------+
28507 * that is required, trapped and emulated by the Linux kernel. However, all
28508 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28509 * offset is odd. Therefore all valid SQ instructions can execute normally.
28510 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28511 * between SQ and RDHWR, as the Linux kernel does.
28513 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
28515 int base
= extract32(ctx
->opcode
, 21, 5);
28516 int rt
= extract32(ctx
->opcode
, 16, 5);
28517 int offset
= extract32(ctx
->opcode
, 0, 16);
28519 #ifdef CONFIG_USER_ONLY
28520 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
28521 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
28523 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
28524 int rd
= extract32(ctx
->opcode
, 11, 5);
28526 gen_rdhwr(ctx
, rt
, rd
, 0);
28531 gen_mmi_sq(ctx
, base
, rt
, offset
);
28536 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
28538 int rs
, rt
, rd
, sa
;
28542 rs
= (ctx
->opcode
>> 21) & 0x1f;
28543 rt
= (ctx
->opcode
>> 16) & 0x1f;
28544 rd
= (ctx
->opcode
>> 11) & 0x1f;
28545 sa
= (ctx
->opcode
>> 6) & 0x1f;
28546 imm
= sextract32(ctx
->opcode
, 7, 9);
28548 op1
= MASK_SPECIAL3(ctx
->opcode
);
28551 * EVA loads and stores overlap Loongson 2E instructions decoded by
28552 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28559 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
28567 check_cp0_enabled(ctx
);
28568 gen_ld(ctx
, op1
, rt
, rs
, imm
);
28572 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
28577 check_cp0_enabled(ctx
);
28578 gen_st(ctx
, op1
, rt
, rs
, imm
);
28581 check_cp0_enabled(ctx
);
28582 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
28585 check_cp0_enabled(ctx
);
28586 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28587 gen_cache_operation(ctx
, rt
, rs
, imm
);
28589 /* Treat as NOP. */
28592 check_cp0_enabled(ctx
);
28593 /* Treat as NOP. */
28601 check_insn(ctx
, ISA_MIPS32R2
);
28602 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28605 op2
= MASK_BSHFL(ctx
->opcode
);
28612 check_insn(ctx
, ISA_MIPS32R6
);
28613 decode_opc_special3_r6(env
, ctx
);
28616 check_insn(ctx
, ISA_MIPS32R2
);
28617 gen_bshfl(ctx
, op2
, rt
, rd
);
28621 #if defined(TARGET_MIPS64)
28628 check_insn(ctx
, ISA_MIPS64R2
);
28629 check_mips_64(ctx
);
28630 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28633 op2
= MASK_DBSHFL(ctx
->opcode
);
28644 check_insn(ctx
, ISA_MIPS32R6
);
28645 decode_opc_special3_r6(env
, ctx
);
28648 check_insn(ctx
, ISA_MIPS64R2
);
28649 check_mips_64(ctx
);
28650 op2
= MASK_DBSHFL(ctx
->opcode
);
28651 gen_bshfl(ctx
, op2
, rt
, rd
);
28657 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28662 TCGv t0
= tcg_temp_new();
28663 TCGv t1
= tcg_temp_new();
28665 gen_load_gpr(t0
, rt
);
28666 gen_load_gpr(t1
, rs
);
28667 gen_helper_fork(t0
, t1
);
28675 TCGv t0
= tcg_temp_new();
28677 gen_load_gpr(t0
, rs
);
28678 gen_helper_yield(t0
, cpu_env
, t0
);
28679 gen_store_gpr(t0
, rd
);
28684 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
28685 decode_opc_special3_r6(env
, ctx
);
28687 decode_opc_special3_legacy(env
, ctx
);
28692 /* MIPS SIMD Architecture (MSA) */
28693 static inline int check_msa_access(DisasContext
*ctx
)
28695 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
28696 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
28697 generate_exception_end(ctx
, EXCP_RI
);
28701 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
28702 if (ctx
->insn_flags
& ASE_MSA
) {
28703 generate_exception_end(ctx
, EXCP_MSADIS
);
28706 generate_exception_end(ctx
, EXCP_RI
);
28713 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
28715 /* generates tcg ops to check if any element is 0 */
28716 /* Note this function only works with MSA_WRLEN = 128 */
28717 uint64_t eval_zero_or_big
= 0;
28718 uint64_t eval_big
= 0;
28719 TCGv_i64 t0
= tcg_temp_new_i64();
28720 TCGv_i64 t1
= tcg_temp_new_i64();
28723 eval_zero_or_big
= 0x0101010101010101ULL
;
28724 eval_big
= 0x8080808080808080ULL
;
28727 eval_zero_or_big
= 0x0001000100010001ULL
;
28728 eval_big
= 0x8000800080008000ULL
;
28731 eval_zero_or_big
= 0x0000000100000001ULL
;
28732 eval_big
= 0x8000000080000000ULL
;
28735 eval_zero_or_big
= 0x0000000000000001ULL
;
28736 eval_big
= 0x8000000000000000ULL
;
28739 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<< 1], eval_zero_or_big
);
28740 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<< 1]);
28741 tcg_gen_andi_i64(t0
, t0
, eval_big
);
28742 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<< 1) + 1], eval_zero_or_big
);
28743 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<< 1) + 1]);
28744 tcg_gen_andi_i64(t1
, t1
, eval_big
);
28745 tcg_gen_or_i64(t0
, t0
, t1
);
28746 /* if all bits are zero then all elements are not zero */
28747 /* if some bit is non-zero then some element is zero */
28748 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
28749 tcg_gen_trunc_i64_tl(tresult
, t0
);
28750 tcg_temp_free_i64(t0
);
28751 tcg_temp_free_i64(t1
);
28754 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
28756 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28757 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28758 int64_t s16
= (int16_t)ctx
->opcode
;
28760 check_msa_access(ctx
);
28762 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
28763 generate_exception_end(ctx
, EXCP_RI
);
28770 TCGv_i64 t0
= tcg_temp_new_i64();
28771 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<< 1], msa_wr_d
[(wt
<< 1) + 1]);
28772 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
28773 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
28774 tcg_gen_trunc_i64_tl(bcond
, t0
);
28775 tcg_temp_free_i64(t0
);
28782 gen_check_zero_element(bcond
, df
, wt
);
28788 gen_check_zero_element(bcond
, df
, wt
);
28789 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
28793 ctx
->btarget
= ctx
->base
.pc_next
+ (s16
<< 2) + 4;
28795 ctx
->hflags
|= MIPS_HFLAG_BC
;
28796 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
28799 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
28801 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28802 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
28803 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28804 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28806 TCGv_i32 twd
= tcg_const_i32(wd
);
28807 TCGv_i32 tws
= tcg_const_i32(ws
);
28808 TCGv_i32 ti8
= tcg_const_i32(i8
);
28810 switch (MASK_MSA_I8(ctx
->opcode
)) {
28812 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
28815 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
28818 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
28821 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
28824 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
28827 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
28830 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
28836 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
28837 if (df
== DF_DOUBLE
) {
28838 generate_exception_end(ctx
, EXCP_RI
);
28840 TCGv_i32 tdf
= tcg_const_i32(df
);
28841 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
28842 tcg_temp_free_i32(tdf
);
28847 MIPS_INVAL("MSA instruction");
28848 generate_exception_end(ctx
, EXCP_RI
);
28852 tcg_temp_free_i32(twd
);
28853 tcg_temp_free_i32(tws
);
28854 tcg_temp_free_i32(ti8
);
28857 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
28859 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28860 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28861 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
28862 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
28863 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28864 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28866 TCGv_i32 tdf
= tcg_const_i32(df
);
28867 TCGv_i32 twd
= tcg_const_i32(wd
);
28868 TCGv_i32 tws
= tcg_const_i32(ws
);
28869 TCGv_i32 timm
= tcg_temp_new_i32();
28870 tcg_gen_movi_i32(timm
, u5
);
28872 switch (MASK_MSA_I5(ctx
->opcode
)) {
28874 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28877 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28879 case OPC_MAXI_S_df
:
28880 tcg_gen_movi_i32(timm
, s5
);
28881 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28883 case OPC_MAXI_U_df
:
28884 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28886 case OPC_MINI_S_df
:
28887 tcg_gen_movi_i32(timm
, s5
);
28888 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28890 case OPC_MINI_U_df
:
28891 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28894 tcg_gen_movi_i32(timm
, s5
);
28895 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28897 case OPC_CLTI_S_df
:
28898 tcg_gen_movi_i32(timm
, s5
);
28899 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28901 case OPC_CLTI_U_df
:
28902 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28904 case OPC_CLEI_S_df
:
28905 tcg_gen_movi_i32(timm
, s5
);
28906 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28908 case OPC_CLEI_U_df
:
28909 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28913 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
28914 tcg_gen_movi_i32(timm
, s10
);
28915 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
28919 MIPS_INVAL("MSA instruction");
28920 generate_exception_end(ctx
, EXCP_RI
);
28924 tcg_temp_free_i32(tdf
);
28925 tcg_temp_free_i32(twd
);
28926 tcg_temp_free_i32(tws
);
28927 tcg_temp_free_i32(timm
);
28930 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
28932 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28933 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
28934 uint32_t df
= 0, m
= 0;
28935 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28936 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28943 if ((dfm
& 0x40) == 0x00) {
28946 } else if ((dfm
& 0x60) == 0x40) {
28949 } else if ((dfm
& 0x70) == 0x60) {
28952 } else if ((dfm
& 0x78) == 0x70) {
28956 generate_exception_end(ctx
, EXCP_RI
);
28960 tdf
= tcg_const_i32(df
);
28961 tm
= tcg_const_i32(m
);
28962 twd
= tcg_const_i32(wd
);
28963 tws
= tcg_const_i32(ws
);
28965 switch (MASK_MSA_BIT(ctx
->opcode
)) {
28967 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28970 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
28973 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28976 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28979 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
28982 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
28984 case OPC_BINSLI_df
:
28985 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28987 case OPC_BINSRI_df
:
28988 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28991 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
28994 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
28997 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
29000 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
29003 MIPS_INVAL("MSA instruction");
29004 generate_exception_end(ctx
, EXCP_RI
);
29008 tcg_temp_free_i32(tdf
);
29009 tcg_temp_free_i32(tm
);
29010 tcg_temp_free_i32(twd
);
29011 tcg_temp_free_i32(tws
);
29014 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
29016 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
29017 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
29018 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29019 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29020 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29022 TCGv_i32 tdf
= tcg_const_i32(df
);
29023 TCGv_i32 twd
= tcg_const_i32(wd
);
29024 TCGv_i32 tws
= tcg_const_i32(ws
);
29025 TCGv_i32 twt
= tcg_const_i32(wt
);
29027 switch (MASK_MSA_3R(ctx
->opcode
)) {
29031 gen_helper_msa_binsl_b(cpu_env
, twd
, tws
, twt
);
29034 gen_helper_msa_binsl_h(cpu_env
, twd
, tws
, twt
);
29037 gen_helper_msa_binsl_w(cpu_env
, twd
, tws
, twt
);
29040 gen_helper_msa_binsl_d(cpu_env
, twd
, tws
, twt
);
29047 gen_helper_msa_binsr_b(cpu_env
, twd
, tws
, twt
);
29050 gen_helper_msa_binsr_h(cpu_env
, twd
, tws
, twt
);
29053 gen_helper_msa_binsr_w(cpu_env
, twd
, tws
, twt
);
29056 gen_helper_msa_binsr_d(cpu_env
, twd
, tws
, twt
);
29063 gen_helper_msa_bclr_b(cpu_env
, twd
, tws
, twt
);
29066 gen_helper_msa_bclr_h(cpu_env
, twd
, tws
, twt
);
29069 gen_helper_msa_bclr_w(cpu_env
, twd
, tws
, twt
);
29072 gen_helper_msa_bclr_d(cpu_env
, twd
, tws
, twt
);
29079 gen_helper_msa_bneg_b(cpu_env
, twd
, tws
, twt
);
29082 gen_helper_msa_bneg_h(cpu_env
, twd
, tws
, twt
);
29085 gen_helper_msa_bneg_w(cpu_env
, twd
, tws
, twt
);
29088 gen_helper_msa_bneg_d(cpu_env
, twd
, tws
, twt
);
29095 gen_helper_msa_bset_b(cpu_env
, twd
, tws
, twt
);
29098 gen_helper_msa_bset_h(cpu_env
, twd
, tws
, twt
);
29101 gen_helper_msa_bset_w(cpu_env
, twd
, tws
, twt
);
29104 gen_helper_msa_bset_d(cpu_env
, twd
, tws
, twt
);
29111 gen_helper_msa_add_a_b(cpu_env
, twd
, tws
, twt
);
29114 gen_helper_msa_add_a_h(cpu_env
, twd
, tws
, twt
);
29117 gen_helper_msa_add_a_w(cpu_env
, twd
, tws
, twt
);
29120 gen_helper_msa_add_a_d(cpu_env
, twd
, tws
, twt
);
29124 case OPC_ADDS_A_df
:
29127 gen_helper_msa_adds_a_b(cpu_env
, twd
, tws
, twt
);
29130 gen_helper_msa_adds_a_h(cpu_env
, twd
, tws
, twt
);
29133 gen_helper_msa_adds_a_w(cpu_env
, twd
, tws
, twt
);
29136 gen_helper_msa_adds_a_d(cpu_env
, twd
, tws
, twt
);
29140 case OPC_ADDS_S_df
:
29143 gen_helper_msa_adds_s_b(cpu_env
, twd
, tws
, twt
);
29146 gen_helper_msa_adds_s_h(cpu_env
, twd
, tws
, twt
);
29149 gen_helper_msa_adds_s_w(cpu_env
, twd
, tws
, twt
);
29152 gen_helper_msa_adds_s_d(cpu_env
, twd
, tws
, twt
);
29156 case OPC_ADDS_U_df
:
29159 gen_helper_msa_adds_u_b(cpu_env
, twd
, tws
, twt
);
29162 gen_helper_msa_adds_u_h(cpu_env
, twd
, tws
, twt
);
29165 gen_helper_msa_adds_u_w(cpu_env
, twd
, tws
, twt
);
29168 gen_helper_msa_adds_u_d(cpu_env
, twd
, tws
, twt
);
29175 gen_helper_msa_addv_b(cpu_env
, twd
, tws
, twt
);
29178 gen_helper_msa_addv_h(cpu_env
, twd
, tws
, twt
);
29181 gen_helper_msa_addv_w(cpu_env
, twd
, tws
, twt
);
29184 gen_helper_msa_addv_d(cpu_env
, twd
, tws
, twt
);
29191 gen_helper_msa_ave_s_b(cpu_env
, twd
, tws
, twt
);
29194 gen_helper_msa_ave_s_h(cpu_env
, twd
, tws
, twt
);
29197 gen_helper_msa_ave_s_w(cpu_env
, twd
, tws
, twt
);
29200 gen_helper_msa_ave_s_d(cpu_env
, twd
, tws
, twt
);
29207 gen_helper_msa_ave_u_b(cpu_env
, twd
, tws
, twt
);
29210 gen_helper_msa_ave_u_h(cpu_env
, twd
, tws
, twt
);
29213 gen_helper_msa_ave_u_w(cpu_env
, twd
, tws
, twt
);
29216 gen_helper_msa_ave_u_d(cpu_env
, twd
, tws
, twt
);
29220 case OPC_AVER_S_df
:
29223 gen_helper_msa_aver_s_b(cpu_env
, twd
, tws
, twt
);
29226 gen_helper_msa_aver_s_h(cpu_env
, twd
, tws
, twt
);
29229 gen_helper_msa_aver_s_w(cpu_env
, twd
, tws
, twt
);
29232 gen_helper_msa_aver_s_d(cpu_env
, twd
, tws
, twt
);
29236 case OPC_AVER_U_df
:
29239 gen_helper_msa_aver_u_b(cpu_env
, twd
, tws
, twt
);
29242 gen_helper_msa_aver_u_h(cpu_env
, twd
, tws
, twt
);
29245 gen_helper_msa_aver_u_w(cpu_env
, twd
, tws
, twt
);
29248 gen_helper_msa_aver_u_d(cpu_env
, twd
, tws
, twt
);
29255 gen_helper_msa_ceq_b(cpu_env
, twd
, tws
, twt
);
29258 gen_helper_msa_ceq_h(cpu_env
, twd
, tws
, twt
);
29261 gen_helper_msa_ceq_w(cpu_env
, twd
, tws
, twt
);
29264 gen_helper_msa_ceq_d(cpu_env
, twd
, tws
, twt
);
29271 gen_helper_msa_cle_s_b(cpu_env
, twd
, tws
, twt
);
29274 gen_helper_msa_cle_s_h(cpu_env
, twd
, tws
, twt
);
29277 gen_helper_msa_cle_s_w(cpu_env
, twd
, tws
, twt
);
29280 gen_helper_msa_cle_s_d(cpu_env
, twd
, tws
, twt
);
29287 gen_helper_msa_cle_u_b(cpu_env
, twd
, tws
, twt
);
29290 gen_helper_msa_cle_u_h(cpu_env
, twd
, tws
, twt
);
29293 gen_helper_msa_cle_u_w(cpu_env
, twd
, tws
, twt
);
29296 gen_helper_msa_cle_u_d(cpu_env
, twd
, tws
, twt
);
29303 gen_helper_msa_clt_s_b(cpu_env
, twd
, tws
, twt
);
29306 gen_helper_msa_clt_s_h(cpu_env
, twd
, tws
, twt
);
29309 gen_helper_msa_clt_s_w(cpu_env
, twd
, tws
, twt
);
29312 gen_helper_msa_clt_s_d(cpu_env
, twd
, tws
, twt
);
29319 gen_helper_msa_clt_u_b(cpu_env
, twd
, tws
, twt
);
29322 gen_helper_msa_clt_u_h(cpu_env
, twd
, tws
, twt
);
29325 gen_helper_msa_clt_u_w(cpu_env
, twd
, tws
, twt
);
29328 gen_helper_msa_clt_u_d(cpu_env
, twd
, tws
, twt
);
29335 gen_helper_msa_div_s_b(cpu_env
, twd
, tws
, twt
);
29338 gen_helper_msa_div_s_h(cpu_env
, twd
, tws
, twt
);
29341 gen_helper_msa_div_s_w(cpu_env
, twd
, tws
, twt
);
29344 gen_helper_msa_div_s_d(cpu_env
, twd
, tws
, twt
);
29351 gen_helper_msa_div_u_b(cpu_env
, twd
, tws
, twt
);
29354 gen_helper_msa_div_u_h(cpu_env
, twd
, tws
, twt
);
29357 gen_helper_msa_div_u_w(cpu_env
, twd
, tws
, twt
);
29360 gen_helper_msa_div_u_d(cpu_env
, twd
, tws
, twt
);
29367 gen_helper_msa_max_a_b(cpu_env
, twd
, tws
, twt
);
29370 gen_helper_msa_max_a_h(cpu_env
, twd
, tws
, twt
);
29373 gen_helper_msa_max_a_w(cpu_env
, twd
, tws
, twt
);
29376 gen_helper_msa_max_a_d(cpu_env
, twd
, tws
, twt
);
29383 gen_helper_msa_max_s_b(cpu_env
, twd
, tws
, twt
);
29386 gen_helper_msa_max_s_h(cpu_env
, twd
, tws
, twt
);
29389 gen_helper_msa_max_s_w(cpu_env
, twd
, tws
, twt
);
29392 gen_helper_msa_max_s_d(cpu_env
, twd
, tws
, twt
);
29399 gen_helper_msa_max_u_b(cpu_env
, twd
, tws
, twt
);
29402 gen_helper_msa_max_u_h(cpu_env
, twd
, tws
, twt
);
29405 gen_helper_msa_max_u_w(cpu_env
, twd
, tws
, twt
);
29408 gen_helper_msa_max_u_d(cpu_env
, twd
, tws
, twt
);
29415 gen_helper_msa_min_a_b(cpu_env
, twd
, tws
, twt
);
29418 gen_helper_msa_min_a_h(cpu_env
, twd
, tws
, twt
);
29421 gen_helper_msa_min_a_w(cpu_env
, twd
, tws
, twt
);
29424 gen_helper_msa_min_a_d(cpu_env
, twd
, tws
, twt
);
29431 gen_helper_msa_min_s_b(cpu_env
, twd
, tws
, twt
);
29434 gen_helper_msa_min_s_h(cpu_env
, twd
, tws
, twt
);
29437 gen_helper_msa_min_s_w(cpu_env
, twd
, tws
, twt
);
29440 gen_helper_msa_min_s_d(cpu_env
, twd
, tws
, twt
);
29447 gen_helper_msa_min_u_b(cpu_env
, twd
, tws
, twt
);
29450 gen_helper_msa_min_u_h(cpu_env
, twd
, tws
, twt
);
29453 gen_helper_msa_min_u_w(cpu_env
, twd
, tws
, twt
);
29456 gen_helper_msa_min_u_d(cpu_env
, twd
, tws
, twt
);
29463 gen_helper_msa_mod_s_b(cpu_env
, twd
, tws
, twt
);
29466 gen_helper_msa_mod_s_h(cpu_env
, twd
, tws
, twt
);
29469 gen_helper_msa_mod_s_w(cpu_env
, twd
, tws
, twt
);
29472 gen_helper_msa_mod_s_d(cpu_env
, twd
, tws
, twt
);
29479 gen_helper_msa_mod_u_b(cpu_env
, twd
, tws
, twt
);
29482 gen_helper_msa_mod_u_h(cpu_env
, twd
, tws
, twt
);
29485 gen_helper_msa_mod_u_w(cpu_env
, twd
, tws
, twt
);
29488 gen_helper_msa_mod_u_d(cpu_env
, twd
, tws
, twt
);
29495 gen_helper_msa_maddv_b(cpu_env
, twd
, tws
, twt
);
29498 gen_helper_msa_maddv_h(cpu_env
, twd
, tws
, twt
);
29501 gen_helper_msa_maddv_w(cpu_env
, twd
, tws
, twt
);
29504 gen_helper_msa_maddv_d(cpu_env
, twd
, tws
, twt
);
29511 gen_helper_msa_msubv_b(cpu_env
, twd
, tws
, twt
);
29514 gen_helper_msa_msubv_h(cpu_env
, twd
, tws
, twt
);
29517 gen_helper_msa_msubv_w(cpu_env
, twd
, tws
, twt
);
29520 gen_helper_msa_msubv_d(cpu_env
, twd
, tws
, twt
);
29524 case OPC_ASUB_S_df
:
29527 gen_helper_msa_asub_s_b(cpu_env
, twd
, tws
, twt
);
29530 gen_helper_msa_asub_s_h(cpu_env
, twd
, tws
, twt
);
29533 gen_helper_msa_asub_s_w(cpu_env
, twd
, tws
, twt
);
29536 gen_helper_msa_asub_s_d(cpu_env
, twd
, tws
, twt
);
29540 case OPC_ASUB_U_df
:
29543 gen_helper_msa_asub_u_b(cpu_env
, twd
, tws
, twt
);
29546 gen_helper_msa_asub_u_h(cpu_env
, twd
, tws
, twt
);
29549 gen_helper_msa_asub_u_w(cpu_env
, twd
, tws
, twt
);
29552 gen_helper_msa_asub_u_d(cpu_env
, twd
, tws
, twt
);
29559 gen_helper_msa_ilvev_b(cpu_env
, twd
, tws
, twt
);
29562 gen_helper_msa_ilvev_h(cpu_env
, twd
, tws
, twt
);
29565 gen_helper_msa_ilvev_w(cpu_env
, twd
, tws
, twt
);
29568 gen_helper_msa_ilvev_d(cpu_env
, twd
, tws
, twt
);
29575 gen_helper_msa_ilvod_b(cpu_env
, twd
, tws
, twt
);
29578 gen_helper_msa_ilvod_h(cpu_env
, twd
, tws
, twt
);
29581 gen_helper_msa_ilvod_w(cpu_env
, twd
, tws
, twt
);
29584 gen_helper_msa_ilvod_d(cpu_env
, twd
, tws
, twt
);
29591 gen_helper_msa_ilvl_b(cpu_env
, twd
, tws
, twt
);
29594 gen_helper_msa_ilvl_h(cpu_env
, twd
, tws
, twt
);
29597 gen_helper_msa_ilvl_w(cpu_env
, twd
, tws
, twt
);
29600 gen_helper_msa_ilvl_d(cpu_env
, twd
, tws
, twt
);
29607 gen_helper_msa_ilvr_b(cpu_env
, twd
, tws
, twt
);
29610 gen_helper_msa_ilvr_h(cpu_env
, twd
, tws
, twt
);
29613 gen_helper_msa_ilvr_w(cpu_env
, twd
, tws
, twt
);
29616 gen_helper_msa_ilvr_d(cpu_env
, twd
, tws
, twt
);
29623 gen_helper_msa_pckev_b(cpu_env
, twd
, tws
, twt
);
29626 gen_helper_msa_pckev_h(cpu_env
, twd
, tws
, twt
);
29629 gen_helper_msa_pckev_w(cpu_env
, twd
, tws
, twt
);
29632 gen_helper_msa_pckev_d(cpu_env
, twd
, tws
, twt
);
29639 gen_helper_msa_pckod_b(cpu_env
, twd
, tws
, twt
);
29642 gen_helper_msa_pckod_h(cpu_env
, twd
, tws
, twt
);
29645 gen_helper_msa_pckod_w(cpu_env
, twd
, tws
, twt
);
29648 gen_helper_msa_pckod_d(cpu_env
, twd
, tws
, twt
);
29655 gen_helper_msa_sll_b(cpu_env
, twd
, tws
, twt
);
29658 gen_helper_msa_sll_h(cpu_env
, twd
, tws
, twt
);
29661 gen_helper_msa_sll_w(cpu_env
, twd
, tws
, twt
);
29664 gen_helper_msa_sll_d(cpu_env
, twd
, tws
, twt
);
29671 gen_helper_msa_sra_b(cpu_env
, twd
, tws
, twt
);
29674 gen_helper_msa_sra_h(cpu_env
, twd
, tws
, twt
);
29677 gen_helper_msa_sra_w(cpu_env
, twd
, tws
, twt
);
29680 gen_helper_msa_sra_d(cpu_env
, twd
, tws
, twt
);
29687 gen_helper_msa_srar_b(cpu_env
, twd
, tws
, twt
);
29690 gen_helper_msa_srar_h(cpu_env
, twd
, tws
, twt
);
29693 gen_helper_msa_srar_w(cpu_env
, twd
, tws
, twt
);
29696 gen_helper_msa_srar_d(cpu_env
, twd
, tws
, twt
);
29703 gen_helper_msa_srl_b(cpu_env
, twd
, tws
, twt
);
29706 gen_helper_msa_srl_h(cpu_env
, twd
, tws
, twt
);
29709 gen_helper_msa_srl_w(cpu_env
, twd
, tws
, twt
);
29712 gen_helper_msa_srl_d(cpu_env
, twd
, tws
, twt
);
29719 gen_helper_msa_srlr_b(cpu_env
, twd
, tws
, twt
);
29722 gen_helper_msa_srlr_h(cpu_env
, twd
, tws
, twt
);
29725 gen_helper_msa_srlr_w(cpu_env
, twd
, tws
, twt
);
29728 gen_helper_msa_srlr_d(cpu_env
, twd
, tws
, twt
);
29732 case OPC_SUBS_S_df
:
29735 gen_helper_msa_subs_s_b(cpu_env
, twd
, tws
, twt
);
29738 gen_helper_msa_subs_s_h(cpu_env
, twd
, tws
, twt
);
29741 gen_helper_msa_subs_s_w(cpu_env
, twd
, tws
, twt
);
29744 gen_helper_msa_subs_s_d(cpu_env
, twd
, tws
, twt
);
29751 gen_helper_msa_mulv_b(cpu_env
, twd
, tws
, twt
);
29754 gen_helper_msa_mulv_h(cpu_env
, twd
, tws
, twt
);
29757 gen_helper_msa_mulv_w(cpu_env
, twd
, tws
, twt
);
29760 gen_helper_msa_mulv_d(cpu_env
, twd
, tws
, twt
);
29765 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
29768 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29773 gen_helper_msa_subv_b(cpu_env
, twd
, tws
, twt
);
29776 gen_helper_msa_subv_h(cpu_env
, twd
, tws
, twt
);
29779 gen_helper_msa_subv_w(cpu_env
, twd
, tws
, twt
);
29782 gen_helper_msa_subv_d(cpu_env
, twd
, tws
, twt
);
29786 case OPC_SUBS_U_df
:
29789 gen_helper_msa_subs_u_b(cpu_env
, twd
, tws
, twt
);
29792 gen_helper_msa_subs_u_h(cpu_env
, twd
, tws
, twt
);
29795 gen_helper_msa_subs_u_w(cpu_env
, twd
, tws
, twt
);
29798 gen_helper_msa_subs_u_d(cpu_env
, twd
, tws
, twt
);
29803 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
29805 case OPC_SUBSUS_U_df
:
29808 gen_helper_msa_subsus_u_b(cpu_env
, twd
, tws
, twt
);
29811 gen_helper_msa_subsus_u_h(cpu_env
, twd
, tws
, twt
);
29814 gen_helper_msa_subsus_u_w(cpu_env
, twd
, tws
, twt
);
29817 gen_helper_msa_subsus_u_d(cpu_env
, twd
, tws
, twt
);
29821 case OPC_SUBSUU_S_df
:
29824 gen_helper_msa_subsuu_s_b(cpu_env
, twd
, tws
, twt
);
29827 gen_helper_msa_subsuu_s_h(cpu_env
, twd
, tws
, twt
);
29830 gen_helper_msa_subsuu_s_w(cpu_env
, twd
, tws
, twt
);
29833 gen_helper_msa_subsuu_s_d(cpu_env
, twd
, tws
, twt
);
29838 case OPC_DOTP_S_df
:
29839 case OPC_DOTP_U_df
:
29840 case OPC_DPADD_S_df
:
29841 case OPC_DPADD_U_df
:
29842 case OPC_DPSUB_S_df
:
29843 case OPC_HADD_S_df
:
29844 case OPC_DPSUB_U_df
:
29845 case OPC_HADD_U_df
:
29846 case OPC_HSUB_S_df
:
29847 case OPC_HSUB_U_df
:
29848 if (df
== DF_BYTE
) {
29849 generate_exception_end(ctx
, EXCP_RI
);
29852 switch (MASK_MSA_3R(ctx
->opcode
)) {
29853 case OPC_HADD_S_df
:
29856 gen_helper_msa_hadd_s_h(cpu_env
, twd
, tws
, twt
);
29859 gen_helper_msa_hadd_s_w(cpu_env
, twd
, tws
, twt
);
29862 gen_helper_msa_hadd_s_d(cpu_env
, twd
, tws
, twt
);
29866 case OPC_HADD_U_df
:
29869 gen_helper_msa_hadd_u_h(cpu_env
, twd
, tws
, twt
);
29872 gen_helper_msa_hadd_u_w(cpu_env
, twd
, tws
, twt
);
29875 gen_helper_msa_hadd_u_d(cpu_env
, twd
, tws
, twt
);
29879 case OPC_HSUB_S_df
:
29882 gen_helper_msa_hsub_s_h(cpu_env
, twd
, tws
, twt
);
29885 gen_helper_msa_hsub_s_w(cpu_env
, twd
, tws
, twt
);
29888 gen_helper_msa_hsub_s_d(cpu_env
, twd
, tws
, twt
);
29892 case OPC_HSUB_U_df
:
29895 gen_helper_msa_hsub_u_h(cpu_env
, twd
, tws
, twt
);
29898 gen_helper_msa_hsub_u_w(cpu_env
, twd
, tws
, twt
);
29901 gen_helper_msa_hsub_u_d(cpu_env
, twd
, tws
, twt
);
29905 case OPC_DOTP_S_df
:
29908 gen_helper_msa_dotp_s_h(cpu_env
, twd
, tws
, twt
);
29911 gen_helper_msa_dotp_s_w(cpu_env
, twd
, tws
, twt
);
29914 gen_helper_msa_dotp_s_d(cpu_env
, twd
, tws
, twt
);
29918 case OPC_DOTP_U_df
:
29921 gen_helper_msa_dotp_u_h(cpu_env
, twd
, tws
, twt
);
29924 gen_helper_msa_dotp_u_w(cpu_env
, twd
, tws
, twt
);
29927 gen_helper_msa_dotp_u_d(cpu_env
, twd
, tws
, twt
);
29931 case OPC_DPADD_S_df
:
29934 gen_helper_msa_dpadd_s_h(cpu_env
, twd
, tws
, twt
);
29937 gen_helper_msa_dpadd_s_w(cpu_env
, twd
, tws
, twt
);
29940 gen_helper_msa_dpadd_s_d(cpu_env
, twd
, tws
, twt
);
29944 case OPC_DPADD_U_df
:
29947 gen_helper_msa_dpadd_u_h(cpu_env
, twd
, tws
, twt
);
29950 gen_helper_msa_dpadd_u_w(cpu_env
, twd
, tws
, twt
);
29953 gen_helper_msa_dpadd_u_d(cpu_env
, twd
, tws
, twt
);
29957 case OPC_DPSUB_S_df
:
29960 gen_helper_msa_dpsub_s_h(cpu_env
, twd
, tws
, twt
);
29963 gen_helper_msa_dpsub_s_w(cpu_env
, twd
, tws
, twt
);
29966 gen_helper_msa_dpsub_s_d(cpu_env
, twd
, tws
, twt
);
29970 case OPC_DPSUB_U_df
:
29973 gen_helper_msa_dpsub_u_h(cpu_env
, twd
, tws
, twt
);
29976 gen_helper_msa_dpsub_u_w(cpu_env
, twd
, tws
, twt
);
29979 gen_helper_msa_dpsub_u_d(cpu_env
, twd
, tws
, twt
);
29986 MIPS_INVAL("MSA instruction");
29987 generate_exception_end(ctx
, EXCP_RI
);
29990 tcg_temp_free_i32(twd
);
29991 tcg_temp_free_i32(tws
);
29992 tcg_temp_free_i32(twt
);
29993 tcg_temp_free_i32(tdf
);
29996 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
29998 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29999 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
30000 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
30001 TCGv telm
= tcg_temp_new();
30002 TCGv_i32 tsr
= tcg_const_i32(source
);
30003 TCGv_i32 tdt
= tcg_const_i32(dest
);
30005 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
30007 gen_load_gpr(telm
, source
);
30008 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
30011 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
30012 gen_store_gpr(telm
, dest
);
30015 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
30018 MIPS_INVAL("MSA instruction");
30019 generate_exception_end(ctx
, EXCP_RI
);
30023 tcg_temp_free(telm
);
30024 tcg_temp_free_i32(tdt
);
30025 tcg_temp_free_i32(tsr
);
30028 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
30031 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
30032 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30033 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30035 TCGv_i32 tws
= tcg_const_i32(ws
);
30036 TCGv_i32 twd
= tcg_const_i32(wd
);
30037 TCGv_i32 tn
= tcg_const_i32(n
);
30038 TCGv_i32 tdf
= tcg_const_i32(df
);
30040 switch (MASK_MSA_ELM(ctx
->opcode
)) {
30042 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
30044 case OPC_SPLATI_df
:
30045 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
30048 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
30050 case OPC_COPY_S_df
:
30051 case OPC_COPY_U_df
:
30052 case OPC_INSERT_df
:
30053 #if !defined(TARGET_MIPS64)
30054 /* Double format valid only for MIPS64 */
30055 if (df
== DF_DOUBLE
) {
30056 generate_exception_end(ctx
, EXCP_RI
);
30059 if ((MASK_MSA_ELM(ctx
->opcode
) == OPC_COPY_U_df
) &&
30061 generate_exception_end(ctx
, EXCP_RI
);
30065 switch (MASK_MSA_ELM(ctx
->opcode
)) {
30066 case OPC_COPY_S_df
:
30067 if (likely(wd
!= 0)) {
30070 gen_helper_msa_copy_s_b(cpu_env
, twd
, tws
, tn
);
30073 gen_helper_msa_copy_s_h(cpu_env
, twd
, tws
, tn
);
30076 gen_helper_msa_copy_s_w(cpu_env
, twd
, tws
, tn
);
30078 #if defined(TARGET_MIPS64)
30080 gen_helper_msa_copy_s_d(cpu_env
, twd
, tws
, tn
);
30088 case OPC_COPY_U_df
:
30089 if (likely(wd
!= 0)) {
30092 gen_helper_msa_copy_u_b(cpu_env
, twd
, tws
, tn
);
30095 gen_helper_msa_copy_u_h(cpu_env
, twd
, tws
, tn
);
30097 #if defined(TARGET_MIPS64)
30099 gen_helper_msa_copy_u_w(cpu_env
, twd
, tws
, tn
);
30107 case OPC_INSERT_df
:
30110 gen_helper_msa_insert_b(cpu_env
, twd
, tws
, tn
);
30113 gen_helper_msa_insert_h(cpu_env
, twd
, tws
, tn
);
30116 gen_helper_msa_insert_w(cpu_env
, twd
, tws
, tn
);
30118 #if defined(TARGET_MIPS64)
30120 gen_helper_msa_insert_d(cpu_env
, twd
, tws
, tn
);
30130 MIPS_INVAL("MSA instruction");
30131 generate_exception_end(ctx
, EXCP_RI
);
30133 tcg_temp_free_i32(twd
);
30134 tcg_temp_free_i32(tws
);
30135 tcg_temp_free_i32(tn
);
30136 tcg_temp_free_i32(tdf
);
30139 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
30141 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
30142 uint32_t df
= 0, n
= 0;
30144 if ((dfn
& 0x30) == 0x00) {
30147 } else if ((dfn
& 0x38) == 0x20) {
30150 } else if ((dfn
& 0x3c) == 0x30) {
30153 } else if ((dfn
& 0x3e) == 0x38) {
30156 } else if (dfn
== 0x3E) {
30157 /* CTCMSA, CFCMSA, MOVE.V */
30158 gen_msa_elm_3e(env
, ctx
);
30161 generate_exception_end(ctx
, EXCP_RI
);
30165 gen_msa_elm_df(env
, ctx
, df
, n
);
30168 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
30170 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
30171 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
30172 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30173 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30174 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30176 TCGv_i32 twd
= tcg_const_i32(wd
);
30177 TCGv_i32 tws
= tcg_const_i32(ws
);
30178 TCGv_i32 twt
= tcg_const_i32(wt
);
30179 TCGv_i32 tdf
= tcg_temp_new_i32();
30181 /* adjust df value for floating-point instruction */
30182 tcg_gen_movi_i32(tdf
, df
+ 2);
30184 switch (MASK_MSA_3RF(ctx
->opcode
)) {
30186 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
30189 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
30192 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
30195 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
30198 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
30201 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30204 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
30207 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
30210 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30213 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
30216 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
30219 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
30222 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
30225 tcg_gen_movi_i32(tdf
, df
+ 1);
30226 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30229 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
30232 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
30234 case OPC_MADD_Q_df
:
30235 tcg_gen_movi_i32(tdf
, df
+ 1);
30236 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30239 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
30241 case OPC_MSUB_Q_df
:
30242 tcg_gen_movi_i32(tdf
, df
+ 1);
30243 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30246 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
30249 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
30252 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
30255 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
30258 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
30261 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
30264 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30267 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30270 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
30273 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30276 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
30279 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
30282 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
30284 case OPC_MULR_Q_df
:
30285 tcg_gen_movi_i32(tdf
, df
+ 1);
30286 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30289 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
30291 case OPC_FMIN_A_df
:
30292 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
30294 case OPC_MADDR_Q_df
:
30295 tcg_gen_movi_i32(tdf
, df
+ 1);
30296 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30299 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
30302 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
30304 case OPC_MSUBR_Q_df
:
30305 tcg_gen_movi_i32(tdf
, df
+ 1);
30306 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30309 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
30311 case OPC_FMAX_A_df
:
30312 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
30315 MIPS_INVAL("MSA instruction");
30316 generate_exception_end(ctx
, EXCP_RI
);
30320 tcg_temp_free_i32(twd
);
30321 tcg_temp_free_i32(tws
);
30322 tcg_temp_free_i32(twt
);
30323 tcg_temp_free_i32(tdf
);
30326 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
30328 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30329 (op & (0x7 << 18)))
30330 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30331 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30332 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30333 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
30334 TCGv_i32 twd
= tcg_const_i32(wd
);
30335 TCGv_i32 tws
= tcg_const_i32(ws
);
30336 TCGv_i32 twt
= tcg_const_i32(wt
);
30337 TCGv_i32 tdf
= tcg_const_i32(df
);
30339 switch (MASK_MSA_2R(ctx
->opcode
)) {
30341 #if !defined(TARGET_MIPS64)
30342 /* Double format valid only for MIPS64 */
30343 if (df
== DF_DOUBLE
) {
30344 generate_exception_end(ctx
, EXCP_RI
);
30348 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
30353 gen_helper_msa_nloc_b(cpu_env
, twd
, tws
);
30356 gen_helper_msa_nloc_h(cpu_env
, twd
, tws
);
30359 gen_helper_msa_nloc_w(cpu_env
, twd
, tws
);
30362 gen_helper_msa_nloc_d(cpu_env
, twd
, tws
);
30369 gen_helper_msa_nlzc_b(cpu_env
, twd
, tws
);
30372 gen_helper_msa_nlzc_h(cpu_env
, twd
, tws
);
30375 gen_helper_msa_nlzc_w(cpu_env
, twd
, tws
);
30378 gen_helper_msa_nlzc_d(cpu_env
, twd
, tws
);
30385 gen_helper_msa_pcnt_b(cpu_env
, twd
, tws
);
30388 gen_helper_msa_pcnt_h(cpu_env
, twd
, tws
);
30391 gen_helper_msa_pcnt_w(cpu_env
, twd
, tws
);
30394 gen_helper_msa_pcnt_d(cpu_env
, twd
, tws
);
30399 MIPS_INVAL("MSA instruction");
30400 generate_exception_end(ctx
, EXCP_RI
);
30404 tcg_temp_free_i32(twd
);
30405 tcg_temp_free_i32(tws
);
30406 tcg_temp_free_i32(twt
);
30407 tcg_temp_free_i32(tdf
);
30410 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
30412 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30413 (op & (0xf << 17)))
30414 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30415 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30416 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30417 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
30418 TCGv_i32 twd
= tcg_const_i32(wd
);
30419 TCGv_i32 tws
= tcg_const_i32(ws
);
30420 TCGv_i32 twt
= tcg_const_i32(wt
);
30421 /* adjust df value for floating-point instruction */
30422 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
30424 switch (MASK_MSA_2RF(ctx
->opcode
)) {
30425 case OPC_FCLASS_df
:
30426 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
30428 case OPC_FTRUNC_S_df
:
30429 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
30431 case OPC_FTRUNC_U_df
:
30432 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
30435 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
30437 case OPC_FRSQRT_df
:
30438 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
30441 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
30444 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
30447 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
30449 case OPC_FEXUPL_df
:
30450 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
30452 case OPC_FEXUPR_df
:
30453 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
30456 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
30459 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
30461 case OPC_FTINT_S_df
:
30462 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
30464 case OPC_FTINT_U_df
:
30465 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
30467 case OPC_FFINT_S_df
:
30468 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
30470 case OPC_FFINT_U_df
:
30471 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
30475 tcg_temp_free_i32(twd
);
30476 tcg_temp_free_i32(tws
);
30477 tcg_temp_free_i32(twt
);
30478 tcg_temp_free_i32(tdf
);
30481 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
30483 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
30484 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30485 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30486 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30487 TCGv_i32 twd
= tcg_const_i32(wd
);
30488 TCGv_i32 tws
= tcg_const_i32(ws
);
30489 TCGv_i32 twt
= tcg_const_i32(wt
);
30491 switch (MASK_MSA_VEC(ctx
->opcode
)) {
30493 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
30496 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
30499 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
30502 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
30505 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
30508 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
30511 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
30514 MIPS_INVAL("MSA instruction");
30515 generate_exception_end(ctx
, EXCP_RI
);
30519 tcg_temp_free_i32(twd
);
30520 tcg_temp_free_i32(tws
);
30521 tcg_temp_free_i32(twt
);
30524 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
30526 switch (MASK_MSA_VEC(ctx
->opcode
)) {
30534 gen_msa_vec_v(env
, ctx
);
30537 gen_msa_2r(env
, ctx
);
30540 gen_msa_2rf(env
, ctx
);
30543 MIPS_INVAL("MSA instruction");
30544 generate_exception_end(ctx
, EXCP_RI
);
30549 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
30551 uint32_t opcode
= ctx
->opcode
;
30552 check_insn(ctx
, ASE_MSA
);
30553 check_msa_access(ctx
);
30555 switch (MASK_MSA_MINOR(opcode
)) {
30556 case OPC_MSA_I8_00
:
30557 case OPC_MSA_I8_01
:
30558 case OPC_MSA_I8_02
:
30559 gen_msa_i8(env
, ctx
);
30561 case OPC_MSA_I5_06
:
30562 case OPC_MSA_I5_07
:
30563 gen_msa_i5(env
, ctx
);
30565 case OPC_MSA_BIT_09
:
30566 case OPC_MSA_BIT_0A
:
30567 gen_msa_bit(env
, ctx
);
30569 case OPC_MSA_3R_0D
:
30570 case OPC_MSA_3R_0E
:
30571 case OPC_MSA_3R_0F
:
30572 case OPC_MSA_3R_10
:
30573 case OPC_MSA_3R_11
:
30574 case OPC_MSA_3R_12
:
30575 case OPC_MSA_3R_13
:
30576 case OPC_MSA_3R_14
:
30577 case OPC_MSA_3R_15
:
30578 gen_msa_3r(env
, ctx
);
30581 gen_msa_elm(env
, ctx
);
30583 case OPC_MSA_3RF_1A
:
30584 case OPC_MSA_3RF_1B
:
30585 case OPC_MSA_3RF_1C
:
30586 gen_msa_3rf(env
, ctx
);
30589 gen_msa_vec(env
, ctx
);
30600 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
30601 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
30602 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30603 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
30605 TCGv_i32 twd
= tcg_const_i32(wd
);
30606 TCGv taddr
= tcg_temp_new();
30607 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
30609 switch (MASK_MSA_MINOR(opcode
)) {
30611 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
30614 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
30617 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
30620 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
30623 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
30626 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
30629 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
30632 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
30636 tcg_temp_free_i32(twd
);
30637 tcg_temp_free(taddr
);
30641 MIPS_INVAL("MSA instruction");
30642 generate_exception_end(ctx
, EXCP_RI
);
30648 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
30651 int rs
, rt
, rd
, sa
;
30655 /* make sure instructions are on a word boundary */
30656 if (ctx
->base
.pc_next
& 0x3) {
30657 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
30658 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
30662 /* Handle blikely not taken case */
30663 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
30664 TCGLabel
*l1
= gen_new_label();
30666 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
30667 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
30668 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
30672 op
= MASK_OP_MAJOR(ctx
->opcode
);
30673 rs
= (ctx
->opcode
>> 21) & 0x1f;
30674 rt
= (ctx
->opcode
>> 16) & 0x1f;
30675 rd
= (ctx
->opcode
>> 11) & 0x1f;
30676 sa
= (ctx
->opcode
>> 6) & 0x1f;
30677 imm
= (int16_t)ctx
->opcode
;
30680 decode_opc_special(env
, ctx
);
30683 #if defined(TARGET_MIPS64)
30684 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
30685 decode_mmi(env
, ctx
);
30687 if (ctx
->insn_flags
& ASE_MXU
) {
30688 decode_opc_mxu(env
, ctx
);
30691 decode_opc_special2_legacy(env
, ctx
);
30695 #if defined(TARGET_MIPS64)
30696 if (ctx
->insn_flags
& INSN_R5900
) {
30697 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
30699 decode_opc_special3(env
, ctx
);
30702 decode_opc_special3(env
, ctx
);
30706 op1
= MASK_REGIMM(ctx
->opcode
);
30708 case OPC_BLTZL
: /* REGIMM branches */
30712 check_insn(ctx
, ISA_MIPS2
);
30713 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30717 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30721 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30723 /* OPC_NAL, OPC_BAL */
30724 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
30726 generate_exception_end(ctx
, EXCP_RI
);
30729 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30732 case OPC_TGEI
: /* REGIMM traps */
30739 check_insn(ctx
, ISA_MIPS2
);
30740 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30741 gen_trap(ctx
, op1
, rs
, -1, imm
);
30744 check_insn(ctx
, ISA_MIPS32R6
);
30745 generate_exception_end(ctx
, EXCP_RI
);
30748 check_insn(ctx
, ISA_MIPS32R2
);
30750 * Break the TB to be able to sync copied instructions
30753 ctx
->base
.is_jmp
= DISAS_STOP
;
30755 case OPC_BPOSGE32
: /* MIPS DSP branch */
30756 #if defined(TARGET_MIPS64)
30760 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
30762 #if defined(TARGET_MIPS64)
30764 check_insn(ctx
, ISA_MIPS32R6
);
30765 check_mips_64(ctx
);
30767 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
30771 check_insn(ctx
, ISA_MIPS32R6
);
30772 check_mips_64(ctx
);
30774 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
30778 default: /* Invalid */
30779 MIPS_INVAL("regimm");
30780 generate_exception_end(ctx
, EXCP_RI
);
30785 check_cp0_enabled(ctx
);
30786 op1
= MASK_CP0(ctx
->opcode
);
30794 #if defined(TARGET_MIPS64)
30798 #ifndef CONFIG_USER_ONLY
30799 gen_cp0(env
, ctx
, op1
, rt
, rd
);
30800 #endif /* !CONFIG_USER_ONLY */
30818 #ifndef CONFIG_USER_ONLY
30819 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
30820 #endif /* !CONFIG_USER_ONLY */
30823 #ifndef CONFIG_USER_ONLY
30826 TCGv t0
= tcg_temp_new();
30828 op2
= MASK_MFMC0(ctx
->opcode
);
30832 gen_helper_dmt(t0
);
30833 gen_store_gpr(t0
, rt
);
30837 gen_helper_emt(t0
);
30838 gen_store_gpr(t0
, rt
);
30842 gen_helper_dvpe(t0
, cpu_env
);
30843 gen_store_gpr(t0
, rt
);
30847 gen_helper_evpe(t0
, cpu_env
);
30848 gen_store_gpr(t0
, rt
);
30851 check_insn(ctx
, ISA_MIPS32R6
);
30853 gen_helper_dvp(t0
, cpu_env
);
30854 gen_store_gpr(t0
, rt
);
30858 check_insn(ctx
, ISA_MIPS32R6
);
30860 gen_helper_evp(t0
, cpu_env
);
30861 gen_store_gpr(t0
, rt
);
30865 check_insn(ctx
, ISA_MIPS32R2
);
30866 save_cpu_state(ctx
, 1);
30867 gen_helper_di(t0
, cpu_env
);
30868 gen_store_gpr(t0
, rt
);
30870 * Stop translation as we may have switched
30871 * the execution mode.
30873 ctx
->base
.is_jmp
= DISAS_STOP
;
30876 check_insn(ctx
, ISA_MIPS32R2
);
30877 save_cpu_state(ctx
, 1);
30878 gen_helper_ei(t0
, cpu_env
);
30879 gen_store_gpr(t0
, rt
);
30881 * DISAS_STOP isn't sufficient, we need to ensure we break
30882 * out of translated code to check for pending interrupts.
30884 gen_save_pc(ctx
->base
.pc_next
+ 4);
30885 ctx
->base
.is_jmp
= DISAS_EXIT
;
30887 default: /* Invalid */
30888 MIPS_INVAL("mfmc0");
30889 generate_exception_end(ctx
, EXCP_RI
);
30894 #endif /* !CONFIG_USER_ONLY */
30897 check_insn(ctx
, ISA_MIPS32R2
);
30898 gen_load_srsgpr(rt
, rd
);
30901 check_insn(ctx
, ISA_MIPS32R2
);
30902 gen_store_srsgpr(rt
, rd
);
30906 generate_exception_end(ctx
, EXCP_RI
);
30910 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30911 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30912 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30913 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30916 /* Arithmetic with immediate opcode */
30917 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30921 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30923 case OPC_SLTI
: /* Set on less than with immediate opcode */
30925 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
30927 case OPC_ANDI
: /* Arithmetic with immediate opcode */
30928 case OPC_LUI
: /* OPC_AUI */
30931 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
30933 case OPC_J
: /* Jump */
30935 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30936 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30939 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30940 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30942 generate_exception_end(ctx
, EXCP_RI
);
30945 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30946 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30949 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30952 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30953 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30955 generate_exception_end(ctx
, EXCP_RI
);
30958 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30959 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30962 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30965 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30968 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30970 check_insn(ctx
, ISA_MIPS32R6
);
30971 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30972 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30975 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30978 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30980 check_insn(ctx
, ISA_MIPS32R6
);
30981 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30982 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30987 check_insn(ctx
, ISA_MIPS2
);
30988 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30992 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30994 case OPC_LL
: /* Load and stores */
30995 check_insn(ctx
, ISA_MIPS2
);
30996 if (ctx
->insn_flags
& INSN_R5900
) {
30997 check_insn_opc_user_only(ctx
, INSN_R5900
);
31002 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31010 gen_ld(ctx
, op
, rt
, rs
, imm
);
31014 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31019 gen_st(ctx
, op
, rt
, rs
, imm
);
31022 check_insn(ctx
, ISA_MIPS2
);
31023 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31024 if (ctx
->insn_flags
& INSN_R5900
) {
31025 check_insn_opc_user_only(ctx
, INSN_R5900
);
31027 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
31030 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31031 check_cp0_enabled(ctx
);
31032 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
31033 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
31034 gen_cache_operation(ctx
, rt
, rs
, imm
);
31036 /* Treat as NOP. */
31039 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31040 if (ctx
->insn_flags
& INSN_R5900
) {
31041 /* Treat as NOP. */
31043 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
31044 /* Treat as NOP. */
31048 /* Floating point (COP1). */
31053 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
31057 op1
= MASK_CP1(ctx
->opcode
);
31062 check_cp1_enabled(ctx
);
31063 check_insn(ctx
, ISA_MIPS32R2
);
31069 check_cp1_enabled(ctx
);
31070 gen_cp1(ctx
, op1
, rt
, rd
);
31072 #if defined(TARGET_MIPS64)
31075 check_cp1_enabled(ctx
);
31076 check_insn(ctx
, ISA_MIPS3
);
31077 check_mips_64(ctx
);
31078 gen_cp1(ctx
, op1
, rt
, rd
);
31081 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
31082 check_cp1_enabled(ctx
);
31083 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31085 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
31090 check_insn(ctx
, ASE_MIPS3D
);
31091 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
31092 (rt
>> 2) & 0x7, imm
<< 2);
31096 check_cp1_enabled(ctx
);
31097 check_insn(ctx
, ISA_MIPS32R6
);
31098 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
31102 check_cp1_enabled(ctx
);
31103 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31105 check_insn(ctx
, ASE_MIPS3D
);
31108 check_cp1_enabled(ctx
);
31109 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31110 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
31111 (rt
>> 2) & 0x7, imm
<< 2);
31118 check_cp1_enabled(ctx
);
31119 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
31125 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
31126 check_cp1_enabled(ctx
);
31127 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31129 case R6_OPC_CMP_AF_S
:
31130 case R6_OPC_CMP_UN_S
:
31131 case R6_OPC_CMP_EQ_S
:
31132 case R6_OPC_CMP_UEQ_S
:
31133 case R6_OPC_CMP_LT_S
:
31134 case R6_OPC_CMP_ULT_S
:
31135 case R6_OPC_CMP_LE_S
:
31136 case R6_OPC_CMP_ULE_S
:
31137 case R6_OPC_CMP_SAF_S
:
31138 case R6_OPC_CMP_SUN_S
:
31139 case R6_OPC_CMP_SEQ_S
:
31140 case R6_OPC_CMP_SEUQ_S
:
31141 case R6_OPC_CMP_SLT_S
:
31142 case R6_OPC_CMP_SULT_S
:
31143 case R6_OPC_CMP_SLE_S
:
31144 case R6_OPC_CMP_SULE_S
:
31145 case R6_OPC_CMP_OR_S
:
31146 case R6_OPC_CMP_UNE_S
:
31147 case R6_OPC_CMP_NE_S
:
31148 case R6_OPC_CMP_SOR_S
:
31149 case R6_OPC_CMP_SUNE_S
:
31150 case R6_OPC_CMP_SNE_S
:
31151 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
31153 case R6_OPC_CMP_AF_D
:
31154 case R6_OPC_CMP_UN_D
:
31155 case R6_OPC_CMP_EQ_D
:
31156 case R6_OPC_CMP_UEQ_D
:
31157 case R6_OPC_CMP_LT_D
:
31158 case R6_OPC_CMP_ULT_D
:
31159 case R6_OPC_CMP_LE_D
:
31160 case R6_OPC_CMP_ULE_D
:
31161 case R6_OPC_CMP_SAF_D
:
31162 case R6_OPC_CMP_SUN_D
:
31163 case R6_OPC_CMP_SEQ_D
:
31164 case R6_OPC_CMP_SEUQ_D
:
31165 case R6_OPC_CMP_SLT_D
:
31166 case R6_OPC_CMP_SULT_D
:
31167 case R6_OPC_CMP_SLE_D
:
31168 case R6_OPC_CMP_SULE_D
:
31169 case R6_OPC_CMP_OR_D
:
31170 case R6_OPC_CMP_UNE_D
:
31171 case R6_OPC_CMP_NE_D
:
31172 case R6_OPC_CMP_SOR_D
:
31173 case R6_OPC_CMP_SUNE_D
:
31174 case R6_OPC_CMP_SNE_D
:
31175 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
31178 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
31179 rt
, rd
, sa
, (imm
>> 8) & 0x7);
31184 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
31199 check_insn(ctx
, ASE_MSA
);
31200 gen_msa_branch(env
, ctx
, op1
);
31204 generate_exception_end(ctx
, EXCP_RI
);
31209 /* Compact branches [R6] and COP2 [non-R6] */
31210 case OPC_BC
: /* OPC_LWC2 */
31211 case OPC_BALC
: /* OPC_SWC2 */
31212 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31213 /* OPC_BC, OPC_BALC */
31214 gen_compute_compact_branch(ctx
, op
, 0, 0,
31215 sextract32(ctx
->opcode
<< 2, 0, 28));
31216 } else if (ctx
->insn_flags
& ASE_LEXT
) {
31217 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
31219 /* OPC_LWC2, OPC_SWC2 */
31220 /* COP2: Not implemented. */
31221 generate_exception_err(ctx
, EXCP_CpU
, 2);
31224 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
31225 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
31226 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31228 /* OPC_BEQZC, OPC_BNEZC */
31229 gen_compute_compact_branch(ctx
, op
, rs
, 0,
31230 sextract32(ctx
->opcode
<< 2, 0, 23));
31232 /* OPC_JIC, OPC_JIALC */
31233 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
31235 } else if (ctx
->insn_flags
& ASE_LEXT
) {
31236 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
31238 /* OPC_LWC2, OPC_SWC2 */
31239 /* COP2: Not implemented. */
31240 generate_exception_err(ctx
, EXCP_CpU
, 2);
31244 check_insn(ctx
, ASE_LMMI
);
31245 /* Note that these instructions use different fields. */
31246 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
31250 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31251 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
31252 check_cp1_enabled(ctx
);
31253 op1
= MASK_CP3(ctx
->opcode
);
31257 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
31263 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
31264 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
31267 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
31268 /* Treat as NOP. */
31271 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
31285 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
31286 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
31290 generate_exception_end(ctx
, EXCP_RI
);
31294 generate_exception_err(ctx
, EXCP_CpU
, 1);
31298 #if defined(TARGET_MIPS64)
31299 /* MIPS64 opcodes */
31301 if (ctx
->insn_flags
& INSN_R5900
) {
31302 check_insn_opc_user_only(ctx
, INSN_R5900
);
31307 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31311 check_insn(ctx
, ISA_MIPS3
);
31312 check_mips_64(ctx
);
31313 gen_ld(ctx
, op
, rt
, rs
, imm
);
31317 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31320 check_insn(ctx
, ISA_MIPS3
);
31321 check_mips_64(ctx
);
31322 gen_st(ctx
, op
, rt
, rs
, imm
);
31325 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
31326 check_insn(ctx
, ISA_MIPS3
);
31327 if (ctx
->insn_flags
& INSN_R5900
) {
31328 check_insn_opc_user_only(ctx
, INSN_R5900
);
31330 check_mips_64(ctx
);
31331 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
31333 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
31334 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31335 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
31336 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
31339 check_insn(ctx
, ISA_MIPS3
);
31340 check_mips_64(ctx
);
31341 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
31345 check_insn(ctx
, ISA_MIPS3
);
31346 check_mips_64(ctx
);
31347 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
31350 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
31351 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31352 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
31354 MIPS_INVAL("major opcode");
31355 generate_exception_end(ctx
, EXCP_RI
);
31359 case OPC_DAUI
: /* OPC_JALX */
31360 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
31361 #if defined(TARGET_MIPS64)
31363 check_mips_64(ctx
);
31365 generate_exception(ctx
, EXCP_RI
);
31366 } else if (rt
!= 0) {
31367 TCGv t0
= tcg_temp_new();
31368 gen_load_gpr(t0
, rs
);
31369 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
31373 generate_exception_end(ctx
, EXCP_RI
);
31374 MIPS_INVAL("major opcode");
31378 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
31379 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
31380 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
31383 case OPC_MSA
: /* OPC_MDMX */
31384 if (ctx
->insn_flags
& INSN_R5900
) {
31385 #if defined(TARGET_MIPS64)
31386 gen_mmi_lq(env
, ctx
); /* MMI_OPC_LQ */
31389 /* MDMX: Not implemented. */
31394 check_insn(ctx
, ISA_MIPS32R6
);
31395 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
31397 default: /* Invalid */
31398 MIPS_INVAL("major opcode");
31399 generate_exception_end(ctx
, EXCP_RI
);
31404 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
31406 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31407 CPUMIPSState
*env
= cs
->env_ptr
;
31409 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
31410 ctx
->saved_pc
= -1;
31411 ctx
->insn_flags
= env
->insn_flags
;
31412 ctx
->CP0_Config1
= env
->CP0_Config1
;
31413 ctx
->CP0_Config2
= env
->CP0_Config2
;
31414 ctx
->CP0_Config3
= env
->CP0_Config3
;
31415 ctx
->CP0_Config5
= env
->CP0_Config5
;
31417 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
31418 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
31419 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
31420 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
31421 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
31422 ctx
->PAMask
= env
->PAMask
;
31423 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
31424 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
31425 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
31426 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
31427 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
31428 /* Restore delay slot state from the tb context. */
31429 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
31430 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
31431 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
31432 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
31433 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
31434 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
31435 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
31436 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
31437 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
31438 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
31439 restore_cpu_state(env
, ctx
);
31440 #ifdef CONFIG_USER_ONLY
31441 ctx
->mem_idx
= MIPS_HFLAG_UM
;
31443 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
31445 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& ISA_MIPS32R6
) ?
31446 MO_UNALN
: MO_ALIGN
;
31448 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
31452 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
31456 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
31458 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31460 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
31464 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
31465 const CPUBreakpoint
*bp
)
31467 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31469 save_cpu_state(ctx
, 1);
31470 ctx
->base
.is_jmp
= DISAS_NORETURN
;
31471 gen_helper_raise_exception_debug(cpu_env
);
31473 * The address covered by the breakpoint must be included in
31474 * [tb->pc, tb->pc + tb->size) in order to for it to be
31475 * properly cleared -- thus we increment the PC here so that
31476 * the logic setting tb->size below does the right thing.
31478 ctx
->base
.pc_next
+= 4;
31482 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
31484 CPUMIPSState
*env
= cs
->env_ptr
;
31485 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31489 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
31490 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
31491 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31492 insn_bytes
= decode_nanomips_opc(env
, ctx
);
31493 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
31494 ctx
->opcode
= cpu_ldl_code(env
, ctx
->base
.pc_next
);
31496 decode_opc(env
, ctx
);
31497 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
31498 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31499 insn_bytes
= decode_micromips_opc(env
, ctx
);
31500 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
31501 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31502 insn_bytes
= decode_mips16_opc(env
, ctx
);
31504 generate_exception_end(ctx
, EXCP_RI
);
31505 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
31509 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
31510 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
31511 MIPS_HFLAG_FBNSLOT
))) {
31513 * Force to generate branch as there is neither delay nor
31518 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
31519 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
31521 * Force to generate branch as microMIPS R6 doesn't restrict
31522 * branches in the forbidden slot.
31528 gen_branch(ctx
, insn_bytes
);
31530 ctx
->base
.pc_next
+= insn_bytes
;
31532 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
31536 * Execute a branch and its delay slot as a single instruction.
31537 * This is what GDB expects and is consistent with what the
31538 * hardware does (e.g. if a delay slot instruction faults, the
31539 * reported PC is the PC of the branch).
31541 if (ctx
->base
.singlestep_enabled
&&
31542 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
31543 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
31545 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
31546 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
31550 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
31552 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31554 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
31555 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
31556 gen_helper_raise_exception_debug(cpu_env
);
31558 switch (ctx
->base
.is_jmp
) {
31560 gen_save_pc(ctx
->base
.pc_next
);
31561 tcg_gen_lookup_and_goto_ptr();
31564 case DISAS_TOO_MANY
:
31565 save_cpu_state(ctx
, 0);
31566 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
31569 tcg_gen_exit_tb(NULL
, 0);
31571 case DISAS_NORETURN
:
31574 g_assert_not_reached();
31579 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
31581 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
31582 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
31585 static const TranslatorOps mips_tr_ops
= {
31586 .init_disas_context
= mips_tr_init_disas_context
,
31587 .tb_start
= mips_tr_tb_start
,
31588 .insn_start
= mips_tr_insn_start
,
31589 .breakpoint_check
= mips_tr_breakpoint_check
,
31590 .translate_insn
= mips_tr_translate_insn
,
31591 .tb_stop
= mips_tr_tb_stop
,
31592 .disas_log
= mips_tr_disas_log
,
31595 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
31599 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
31602 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
31605 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
31607 #define printfpr(fp) \
31610 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31611 " fd:%13g fs:%13g psu: %13g\n", \
31612 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
31613 (double)(fp)->fd, \
31614 (double)(fp)->fs[FP_ENDIAN_IDX], \
31615 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
31618 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
31619 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
31620 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31621 " fd:%13g fs:%13g psu:%13g\n", \
31622 tmp.w[FP_ENDIAN_IDX], tmp.d, \
31624 (double)tmp.fs[FP_ENDIAN_IDX], \
31625 (double)tmp.fs[!FP_ENDIAN_IDX]); \
31631 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
31632 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
31633 get_float_exception_flags(&env
->active_fpu
.fp_status
));
31634 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
31635 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
31636 printfpr(&env
->active_fpu
.fpr
[i
]);
31642 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
31644 MIPSCPU
*cpu
= MIPS_CPU(cs
);
31645 CPUMIPSState
*env
= &cpu
->env
;
31648 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
31649 " LO=0x" TARGET_FMT_lx
" ds %04x "
31650 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
31651 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
31652 env
->hflags
, env
->btarget
, env
->bcond
);
31653 for (i
= 0; i
< 32; i
++) {
31654 if ((i
& 3) == 0) {
31655 qemu_fprintf(f
, "GPR%02d:", i
);
31657 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
31658 regnames
[i
], env
->active_tc
.gpr
[i
]);
31659 if ((i
& 3) == 3) {
31660 qemu_fprintf(f
, "\n");
31664 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
31665 TARGET_FMT_lx
"\n",
31666 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
31667 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
31669 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
31670 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
31671 env
->CP0_Config2
, env
->CP0_Config3
);
31672 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
31673 env
->CP0_Config4
, env
->CP0_Config5
);
31674 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
31675 fpu_dump_state(env
, f
, flags
);
31679 void mips_tcg_init(void)
31684 for (i
= 1; i
< 32; i
++)
31685 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31686 offsetof(CPUMIPSState
,
31690 for (i
= 0; i
< 32; i
++) {
31691 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
31693 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
31695 * The scalar floating-point unit (FPU) registers are mapped on
31696 * the MSA vector registers.
31698 fpu_f64
[i
] = msa_wr_d
[i
* 2];
31699 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
31700 msa_wr_d
[i
* 2 + 1] =
31701 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
31704 cpu_PC
= tcg_global_mem_new(cpu_env
,
31705 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
31706 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
31707 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
31708 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
31710 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
31711 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
31714 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
31715 offsetof(CPUMIPSState
,
31716 active_tc
.DSPControl
),
31718 bcond
= tcg_global_mem_new(cpu_env
,
31719 offsetof(CPUMIPSState
, bcond
), "bcond");
31720 btarget
= tcg_global_mem_new(cpu_env
,
31721 offsetof(CPUMIPSState
, btarget
), "btarget");
31722 hflags
= tcg_global_mem_new_i32(cpu_env
,
31723 offsetof(CPUMIPSState
, hflags
), "hflags");
31725 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
31726 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
31728 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
31729 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
31731 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
31733 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
31736 #if defined(TARGET_MIPS64)
31738 for (i
= 1; i
< 32; i
++) {
31739 cpu_mmr
[i
] = tcg_global_mem_new_i64(cpu_env
,
31740 offsetof(CPUMIPSState
,
31746 #if !defined(TARGET_MIPS64)
31747 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
31748 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31749 offsetof(CPUMIPSState
,
31750 active_tc
.mxu_gpr
[i
]),
31754 mxu_CR
= tcg_global_mem_new(cpu_env
,
31755 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
31756 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
31760 #include "translate_init.c.inc"
31762 void cpu_mips_realize_env(CPUMIPSState
*env
)
31764 env
->exception_base
= (int32_t)0xBFC00000;
31766 #ifndef CONFIG_USER_ONLY
31767 mmu_init(env
, env
->cpu_model
);
31769 fpu_init(env
, env
->cpu_model
);
31770 mvp_init(env
, env
->cpu_model
);
31773 bool cpu_supports_cps_smp(const char *cpu_type
)
31775 const MIPSCPUClass
*mcc
= MIPS_CPU_CLASS(object_class_by_name(cpu_type
));
31776 return (mcc
->cpu_def
->CP0_Config3
& (1 << CP0C3_CMGCR
)) != 0;
31779 bool cpu_supports_isa(const char *cpu_type
, uint64_t isa
)
31781 const MIPSCPUClass
*mcc
= MIPS_CPU_CLASS(object_class_by_name(cpu_type
));
31782 return (mcc
->cpu_def
->insn_flags
& isa
) != 0;
31785 void cpu_set_exception_base(int vp_index
, target_ulong address
)
31787 MIPSCPU
*vp
= MIPS_CPU(qemu_get_cpu(vp_index
));
31788 vp
->env
.exception_base
= address
;
31791 void cpu_state_reset(CPUMIPSState
*env
)
31793 CPUState
*cs
= env_cpu(env
);
31795 /* Reset registers to their default values */
31796 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
31797 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
31798 #ifdef TARGET_WORDS_BIGENDIAN
31799 env
->CP0_Config0
|= (1 << CP0C0_BE
);
31801 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
31802 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
31803 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
31804 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
31805 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
31806 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
31807 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
31808 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
31809 env
->CP0_Config6_rw_bitmask
= env
->cpu_model
->CP0_Config6_rw_bitmask
;
31810 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
31811 env
->CP0_Config7_rw_bitmask
= env
->cpu_model
->CP0_Config7_rw_bitmask
;
31812 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
31813 << env
->cpu_model
->CP0_LLAddr_shift
;
31814 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
31815 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
31816 env
->CCRes
= env
->cpu_model
->CCRes
;
31817 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
31818 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
31819 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
31820 env
->current_tc
= 0;
31821 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
31822 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
31823 #if defined(TARGET_MIPS64)
31824 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
31825 env
->SEGMask
|= 3ULL << 62;
31828 env
->PABITS
= env
->cpu_model
->PABITS
;
31829 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
31830 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
31831 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
31832 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
31833 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
31834 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
31835 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
31836 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
31837 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
31838 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
31839 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
31840 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
31841 env
->CP0_EBaseWG_rw_bitmask
= env
->cpu_model
->CP0_EBaseWG_rw_bitmask
;
31842 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
31843 env
->active_fpu
.fcr31_rw_bitmask
= env
->cpu_model
->CP1_fcr31_rw_bitmask
;
31844 env
->active_fpu
.fcr31
= env
->cpu_model
->CP1_fcr31
;
31845 env
->msair
= env
->cpu_model
->MSAIR
;
31846 env
->insn_flags
= env
->cpu_model
->insn_flags
;
31848 #if defined(CONFIG_USER_ONLY)
31849 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
31850 # ifdef TARGET_MIPS64
31851 /* Enable 64-bit register mode. */
31852 env
->CP0_Status
|= (1 << CP0St_PX
);
31854 # ifdef TARGET_ABI_MIPSN64
31855 /* Enable 64-bit address mode. */
31856 env
->CP0_Status
|= (1 << CP0St_UX
);
31859 * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
31860 * hardware registers.
31862 env
->CP0_HWREna
|= 0x0000000F;
31863 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
31864 env
->CP0_Status
|= (1 << CP0St_CU1
);
31866 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
31867 env
->CP0_Status
|= (1 << CP0St_MX
);
31869 # if defined(TARGET_MIPS64)
31870 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
31871 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
31872 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
31873 env
->CP0_Status
|= (1 << CP0St_FR
);
31877 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
31879 * If the exception was raised from a delay slot,
31880 * come back to the jump.
31882 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
31883 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
31885 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
31887 env
->active_tc
.PC
= env
->exception_base
;
31888 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
31889 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
31890 env
->CP0_Wired
= 0;
31891 env
->CP0_GlobalNumber
= (cs
->cpu_index
& 0xFF) << CP0GN_VPId
;
31892 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
31893 if (mips_um_ksegs_enabled()) {
31894 env
->CP0_EBase
|= 0x40000000;
31896 env
->CP0_EBase
|= (int32_t)0x80000000;
31898 if (env
->CP0_Config3
& (1 << CP0C3_CMGCR
)) {
31899 env
->CP0_CMGCRBase
= 0x1fbf8000 >> 4;
31901 env
->CP0_EntryHi_ASID_mask
= (env
->CP0_Config5
& (1 << CP0C5_MI
)) ?
31902 0x0 : (env
->CP0_Config4
& (1 << CP0C4_AE
)) ? 0x3ff : 0xff;
31903 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
31905 * Vectored interrupts not implemented, timer on int 7,
31906 * no performance counters.
31908 env
->CP0_IntCtl
= 0xe0000000;
31912 for (i
= 0; i
< 7; i
++) {
31913 env
->CP0_WatchLo
[i
] = 0;
31914 env
->CP0_WatchHi
[i
] = 0x80000000;
31916 env
->CP0_WatchLo
[7] = 0;
31917 env
->CP0_WatchHi
[7] = 0;
31919 /* Count register increments in debug mode, EJTAG version 1 */
31920 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
31922 cpu_mips_store_count(env
, 1);
31924 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
31927 /* Only TC0 on VPE 0 starts as active. */
31928 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
31929 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
31930 env
->tcs
[i
].CP0_TCHalt
= 1;
31932 env
->active_tc
.CP0_TCHalt
= 1;
31935 if (cs
->cpu_index
== 0) {
31936 /* VPE0 starts up enabled. */
31937 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
31938 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
31940 /* TC0 starts up unhalted. */
31942 env
->active_tc
.CP0_TCHalt
= 0;
31943 env
->tcs
[0].CP0_TCHalt
= 0;
31944 /* With thread 0 active. */
31945 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
31946 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
31951 * Configure default legacy segmentation control. We use this regardless of
31952 * whether segmentation control is presented to the guest.
31954 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
31955 env
->CP0_SegCtl0
= (CP0SC_AM_MK
<< CP0SC_AM
);
31956 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
31957 env
->CP0_SegCtl0
|= ((CP0SC_AM_MSK
<< CP0SC_AM
)) << 16;
31958 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
31959 env
->CP0_SegCtl1
= (0 << CP0SC_PA
) | (CP0SC_AM_UK
<< CP0SC_AM
) |
31961 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
31962 env
->CP0_SegCtl1
|= ((0 << CP0SC_PA
) | (CP0SC_AM_UK
<< CP0SC_AM
) |
31963 (3 << CP0SC_C
)) << 16;
31964 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
31965 env
->CP0_SegCtl2
= (2 << CP0SC_PA
) | (CP0SC_AM_MUSK
<< CP0SC_AM
) |
31966 (1 << CP0SC_EU
) | (2 << CP0SC_C
);
31967 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
31968 env
->CP0_SegCtl2
|= ((0 << CP0SC_PA
) | (CP0SC_AM_MUSK
<< CP0SC_AM
) |
31969 (1 << CP0SC_EU
) | (2 << CP0SC_C
)) << 16;
31970 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
31971 env
->CP0_SegCtl1
|= (CP0SC_AM_UK
<< CP0SC1_XAM
);
31973 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
31974 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
31975 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
31976 env
->CP0_Status
|= (1 << CP0St_FR
);
31979 if (env
->insn_flags
& ISA_MIPS32R6
) {
31981 env
->CP0_PWSize
= 0x40;
31987 env
->CP0_PWField
= 0x0C30C302;
31994 env
->CP0_PWField
= 0x02;
31997 if (env
->CP0_Config3
& (1 << CP0C3_ISA
) & (1 << (CP0C3_ISA
+ 1))) {
31998 /* microMIPS on reset when Config3.ISA is 3 */
31999 env
->hflags
|= MIPS_HFLAG_M16
;
32003 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
32007 compute_hflags(env
);
32008 restore_fp_status(env
);
32009 restore_pamask(env
);
32010 cs
->exception_index
= EXCP_NONE
;
32012 if (semihosting_get_argc()) {
32013 /* UHI interface can be used to obtain argc and argv */
32014 env
->active_tc
.gpr
[4] = -1;
32018 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
32019 target_ulong
*data
)
32021 env
->active_tc
.PC
= data
[0];
32022 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
32023 env
->hflags
|= data
[1];
32024 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
32025 case MIPS_HFLAG_BR
:
32027 case MIPS_HFLAG_BC
:
32028 case MIPS_HFLAG_BL
:
32030 env
->btarget
= data
[2];